+` element.
+ * @var string $erase_field The name of the erase checkbox `` element.
+ * @var bool $uploads_disabled Whether the uploads system has been disabled completely..
+ * @var bool $can_upload Whether the currently active user can upload files.
+ * @var bool $has_local_avatar Whether a local avatar has been uploaded.
+ * @var int $size The width/height of the avatar preview image (in pixels).
+ * @var bool $show_description Whether the field description should be shown.
+ */
+
+?>
+
+` element.
+ * @var string $erase_field The name of the erase checkbox `` element.
+ * @var bool $uploads_disabled Whether the uploads system has been disabled completely..
+ * @var bool $can_upload Whether the currently active user can upload files.
+ * @var bool $has_local_avatar Whether a local avatar has been uploaded.
+ * @var int $size The width/height of the avatar preview image (in pixels).
+ * @var bool $show_description Whether the field description should be shown.
+ */
+
+?>
+
+
+
+
+display_name
+);
+?>
+
+
+
+` element.
+ * @var string $value The checkbox value.
+ * @var string $show_description True if the long description should be displayed.
+ */
+?>
+
+
+
+ />
+
+
+
+
+
+
+
+` element.
+ * @var string $value The checkbox value.
+ * @var string $show_description True if the long description should be displayed.
+*/
+?>
+
+
+
+ />
+
+
+
+
+
+
+
+
+` element.
+ * @var string $erase_field The name of the erase checkbox `` element.
+ * @var bool $uploads_disabled Whether the uploads system has been disabled completely..
+ * @var bool $can_upload Whether the currently active user can upload files.
+ * @var bool $has_local_avatar Whether a local avatar has been uploaded.
+ * @var int $size The width/height of the avatar preview image (in pixels).
+ * @var bool $show_description Whether the field description should be shown.
+ */
+
+?>
+
+
+ * Copyright (c) 2015 Grummfy
+ * Copyright (c) 2016, 2017 Lucas Michot
+ * Copyright (c) 2019 Arjen van der Meijden
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * ***
+ *
+ * @package mundschenk-at/avatar-privacy
+ * @license http://www.gnu.org/licenses/gpl-2.0.html
+ */
+
+/**
+ * Retro SVG image.
+ *
+ * Required template variables:
+ *
+ * @var int $rows The number of rows.
+ * @var int $columns The number of columns.
+ * @var string $path The path to draw.
+ * @var string $color The robot body color as CSS color string (e.g. `#ff9800`).
+ * @var string $bg_color The background color as a CSS color string (e.g. `#80d8ff`).
+ */
+?>
+
+
+
+
+
+` element.
+ * @var string $value The checkbox value.
+ * @var string $show_description True if the long description should be displayed.
+ */
+?>
+
+
+/>
+
+
+
+
+
+
+` element.
+ * @var string $value The checkbox value.
+ * @var string $show_description True if the long description should be displayed.
+*/
+?>
+
+
+/>
+
+
+
+
+
+
+
+` element.
+ * @var string $erase_field The name of the erase checkbox `` element.
+ * @var bool $uploads_disabled Whether the uploads system has been disabled completely..
+ * @var bool $can_upload Whether the currently active user can upload files.
+ * @var bool $has_local_avatar Whether a local avatar has been uploaded.
+ * @var int $size The width/height of the avatar preview image (in pixels).
+ * @var bool $show_description Whether the field description should be shown.
+ */
+
+?>
+
+
+
+
+`
+
+= What happens if I disable the plugin? Are any of the data altered? =
+
+The plugin saves additional data about whether commenters and users want to display a gravatar or not (if you select that mode in the settings). These data are deleted when you properly uninstall the plugin.
+
+Apart from that, the plugin only filters data, but does not permanently change them. Especially, if you deactivate the plugin und have gravatars turned on, they will again show up for everybody, even those commenters and users who opted out of displaying gravatars. You do have to change the default gravatar back manually, though.
+
+= Can this plugin be used together with cache plugins? =
+
+Yes, it certainly can. You have to be careful though which plugin options you select and how you cache your content. The first plugin option checks if a gravatar exists for a given e-mail address and, if not, displays the default image directly. If you cache the output of this check, the gravatar will not be displayed if the user later decides to sign up with Gravatar.com. If you're using this option, you should invalidate cached pages with gravatars on them (mostly the single view of entries) regularly.
+
+= Can this plugin be used on a multisite installation? =
+
+Yes, the plugin can be used on a multisite installation. You can either activate it on individual blogs or do a network activation. As users are global to a multisite installation, their choice regarding Gravatar.com use will affect all sites in the network. So if a user comments on blog A and chooses to display gravatars, this decision will be followed on blog B and C too. On new installations, comment author (i.e. non-user) opt-in is recorded per site, not per network. If you first installed Avatar Privacy 0.4 or earlier, the global table `wp_avatar_privacy` continues to be used for all sites in the multisite network. This behavior can be overriden by the network admin via the filter hook `avatar_privacy_enable_global_table`.
+
+= Won't spam comments flood the database table with useless entries for the checkbox in the comment form? =
+
+The plugin doesn't save the value of the "use gravatar" checkbox for comments by registered users (see below), trackbacks/pingbacks (there is no e-mail address) and comments that are marked as spam when they are saved. If you mark a comment as spam later, the table entry is not removed, since the same e-mail address might also be used by non-spam comments. If a comment is marked as spam by Akismet or similar plugins and you later manually mark it as non-spam, what the user selected when submitting the comment will already be lost. This only happens with spam comments, not comments who just need to be moderated, e.g. because of the 'needs at least one published comment' rule.
+
+= Will the avatar caching make my disk space run out? =
+
+While storing the cached avatar images on your own server will take some extra disk space, the plugin makes sure that it does not grow out of bounds by deleting cached gravatars every other day and all other images once a week. When the cached file is accessed again, it is automatically regenerated.
+
+If you don't have to worry about the amount of disk space consumed, you can extend the maximum age of cached files via the filter hooks `avatar_privacy_gravatars_max_age` and `avatar_privacy_all_images_max_age`. The cron job intervals can also be adjusted via hooks (`avatar_privacy_gravatars_cleanup_interval` and `avatar_privacy_all_images_cleanup_interval`, respectively).
+
+= Can commenters override a registered user's choice whether to display a gravatar by creating fake comments? =
+
+No, for registered users the user profile is checked, not the table for the commenter's choices. Commenters can not override this value, not even the user themselves if they post a comment when not signed-in.
+
+= Which plugins are known to work with Avatar Privacy? =
+
+These plugins have been tested successfully in conjunction with Avatar Privacy:
+
+* [AntiSpam Bee](https://wordpress.org/plugins/antispam-bee/)
+* [bbPress](https://wordpress.org/plugins/bbpress/)
+* [BuddyPress](https://wordpress.org/plugins/buddypress/)
+* [Comments – wpDiscuz](https://wordpress.org/plugins/wpdiscuz/)
+* [EWWW Image Optimizer](https://wordpress.org/plugins/ewww-image-optimizer/)
+* [Simple Author Box](https://wordpress.org/plugins/simple-author-box/)
+* [Simple Local Avatars](https://wordpress.org/plugins/simple-local-avatars/)
+* [Simple User Avatar](https://wordpress.org/plugins/simple-user-avatar/)
+* [Theme My Login](https://wordpress.org/plugins/theme-my-login/)
+* [Ultimate Member](https://wordpress.org/plugins/ultimate-member/)
+* [Webmention](https://wordpress.org/plugins/webmention/)
+* [WP User Manager – User Profile Builder & Membership](https://wordpress.org/plugins/wp-user-manager/)
+
+Please note that several [Jetpack by WordPress.com modules](https://wordpress.org/plugins/jetpack/) do not work well with Avatar Privacy because they generate their HTML markup on the WordPress.com servers.
+
+If you find any problems with particular plugins, please tell me!
+
+= What happens if I remove the plugin? =
+
+There is a difference between deactivating the plugin and uninstalling it. The plugin gets deactivated if you do so on the plugins page or if you simply delete the plugin files via FTP. No uninstallation tasks are performed then, so you can activate and deactivate the plugin as you want without losing the plugin's settings.
+
+If you deactivate the plugin und have gravatars turned on, they will again show up for everybody, even those commenters and users who opted out of displaying gravatars. If you changed the default avatar to one of the new local avatar images, the gravatars will not be displayed until you change the default avatar image back.
+
+= OK, but I really want to get rid of everything. How do I that? =
+
+If you want to completely uninstall the plugin and get rid of any data in the database, you should properly uninstall it: Deactivate the plugin first via the WordPress plugins page and then click 'delete' (same page, next to the plugin). For multisite installations, this has to be done by the network administrator on the network plugins page.
+
+The plugin saves additional data about whether commenters and users want to display a gravatar or not (if you select that mode in the settings). The following data are stored by the plugin and deleted upon uninstallation:
+
+* custom table(s) `[prefix]_avatar_privacy` (global or per blog on new multisite installations)
+* `usermeta` values per user: `use_gravatar`, `avatar_privacy_hash`, `avatar_privacy_user_avatar`
+* `option` per blog: `avatar_privacy_settings`
+* option per network (`sitemeta`) on multisite installations: `avatar_privacy_salt`
+* `transient` per commenter: `avapr_check_[mail hash]`
+
+The default avatar image is set to the mystery man if you selected one of the new local default avatar images.
+
+
+== Changelog ==
+
+= 2.7.0 (2023-05-01) =
+* _Feature_: Avatar Privacy is now compatible with PHP 8.2.
+* _Feature_: The plugin now honors the `wp_delete_file` filter when deleting files.
+* _Change_: Requires at least PHP 7.4.
+* _Change_: Upgrades `identifier` column of `avatar_privacy_hashes` table to 256 characters on supported MySQL/MariaDB versions (as it was in 2.4.0).
+* _Change_: The library `yzalis/identicon` has been removed as a dependency.
+* _Change_: Avatar Privacy now honors the `wp_delete_file` filter hook.
+* _Bugfix_: Icons from Webmentions using Gravatar will get cached now.
+* _Bugfix_: Uploading avatars for users with no role on the primary site of a Multsite network now works as expected.
+
+= 2.6.0 (2022-04-18) =
+* _Feature_: The size of uploaded images is now checked to make sure processing does not overload the server. By default, all uploaded images have to be smaller than 2000Ă—2000 pixels. The constraints can be adjusted with these new filter hooks:
+ - `avatar_privacy_upload_min_width`
+ - `avatar_privacy_upload_min_height`
+ - `avatar_privacy_upload_max_width`
+ - `avatar_privacy_upload_max_height`
+* _Feature_: Improved caching to reduce the number of database queries.
+* _Change_: Requires at least WordPress 5.6 and PHP 7.2.
+* _Change_: Support for Internet Explorer (all extant versions, i.e. 9, 10, and 11) has been dropped.
+* _Change_: A fabulous new plugin icon designed by [Johanna Amann](https://www.instagram.com/_jo_am/).
+
+= 2.5.2 (2021-04-30) =
+* _Bugfix_: When a user is deleted, their local avatar image is removed as well.
+* _Bugfix_: The dependency version for JS and CSS files is properly calculated. (This also fixes the apparently empty PHP warning when `WP_DEBUG` is enabled.)
+
+= 2.5.1 (2021-03-13) =
+* _Bugfix_: Fixes PHP 8.0 deprecation warning in the `level-2/dice` package.
+
+= 2.5.0 (2021-03-11) =
+* _Feature_: Avatar Privacy is now compatible with PHP 8.0.
+* _Feature_: Integration for the following plugins had been added:
+ - [Simple Local Avatars](https://wordpress.org/plugins/simple-local-avatars/)
+ - [Simple User Avatar](https://wordpress.org/plugins/simple-user-avatar/)
+* _Change_: The library `scripturadesign/color` has been removed as a dependency.
+* _Change_: Additional hardening.
+
+= 2.4.6 (2021-02-21) =
+* _Bugfix_: Unchecking the Gravatar opt-in and anonymous commenting checkboxes in a user's profile screen works again.
+
+= 2.4.5 (2021-02-07) =
+* _Bugfix_: Gravatar opt-ins by anonymous commenters are now properly saved on WordPress 5.5 and later.
+
+= 2.4.4 (2021-02-03) =
+* _Bugfix_: Gracefully handle changes to WordPress' default DB collation (no more `Illegal mix of collations` errors).
+
+= 2.4.3 (2021-01-15) =
+* _Bugfix_: Don't break stuff (another build process fix, for real this time).
+
+= 2.4.2 (2021-01-15) =
+* _Bugfix_: An unfortunate oversight in the build process led to crashes instead of the intended graceful failure when the installation requirements were not met.
+
+= 2.4.1 (2021-01-10) =
+* _Bugfix_: Don't break the site when the options value in the DB has become corrupted.
+* _Bugfix_: Workaround for maximum database key length when using MySQL < 5.7.7 or MariaDB < 10.2.2.
+
+= 2.4.0 (2021-01-10) =
+* _Feature_: Legacy (default) avatars are now properly cached and resized.
+* _Feature_: There are now API methods to get and set a user's (local) avatar (and their Gravatar and anonymous commenting policies).
+* _Feature_: New WP-CLI commands relating to local avatars added.
+* _Feature_: Integration for the [Simple Author Box](https://wordpress.org/plugins/simple-author-box/) plugin has been added.
+* _Change_: Requires at least WordPress 5.2 and PHP 7.0.
+* _Change_: The `yzalis/identicon` package has been updated to version 2.0.
+* _Change_: Some unused files have been removed from the `vendor-scoped` directory.
+* _Change_: A new per-site database table for fast hash lookup has been introduced (base name `avatar_privacy_hashes`).
+* _Change_: General code clean-up and removal of PHP 5.6 workarounds.
+* _Bugfix_: Gravatars will be properly regenerated for comment authors that have not set a policy (when the site-admin has switched the default to "opt-out").
+* _Bugfix_: When a user requests deletion of their personal data, this now includes the uploaded avatar image files.
+* _Bugfix_: A timestamp is added to uploaded avatar images for better browser caching in the Profile screen.
+
+= 2.3.4 (2020-03-22) =
+* _Bugfix_: Allow plain URLs as default avatars. Use the filter hook `avatar_privacy_allow_remote_default_icon_url` to allow third-party domains and `avatar_privacy_validate_default_icon_url` if you want to implement your own image URL validation.
+* _Bugfix_: Properly handle trackback/linkback avatars. This includes a workaround for avatars provided by the [Webmention](https://wordpress.org/plugins/webmention/) plugin. You can use `avatar_privacy_allow_remote_avatar_url` to prohibit third-party domains (the default is to allow them for webmentions) and `avatar_privacy_validate_avatar_url` if you want to implement your own image URL validation.
+* _Change_: Due to the trackback/linkback bug fix, the priority for `pre_get_avatar_data` filter can now be adjusted using the `avatar_privacy_pre_get_avatar_data_filter_priority` hook instead of being hardcoded.
+
+= 2.3.3 (2019-12-27) =
+* _Bugfix_: Timestamps in WP-CLI commands now always use GMT.
+
+= 2.3.2 (2019-11-09) =
+* _Bugfix_: Some error messages were not getting translated because of a [WP.org infrastructure change](https://make.wordpress.org/core/2018/11/09/new-javascript-i18n-support-in-wordpress/).
+
+= 2.3.1 (2019-09-29) =
+* _Bugfix_: Will not crash on WordPress 4.9 anymore when the Gutenberg plugin is not activated.
+* _Bugfix_: The label for the block settings panel of the Avatar block was incorrect.
+
+= 2.3.0 (2019-09-28) =
+* _Feature_: New shortcode `[avatar-privacy-form]` (optional parameter: `avatar-size`) to allow changing Avatar Privacy's user settings on the frontend of the site.
+* _Feature_: Two blocks have been added to the Block Editor to allow displaying a user's avatar and to change the settings related Avatar Privacy on the frontend.
+* _Feature_: Three new generated default avatars:
+ - Bird Avatars,
+ - Cat Avatars (both designed by David Revoy), and
+ - RoboHash (designed by Zikri Kader).
+* _Feature_: Integration for the following plugins had been added:
+ - [BuddyPress](https://wordpress.org/plugins/buddypress/)
+ - [Theme My Login](https://wordpress.org/plugins/theme-my-login/)
+ - [Ultimate Member](https://wordpress.org/plugins/ultimate-member/)
+* _Feature_: New template function `\Avatar_Privacy\gravatar_checkbox()` for legacy themes added.
+* _Feature_: There is a CLI interface to some parts of Avatar Privacy:
+ - `wp avatar-privacy db show`: Show information about the custom database table(s).
+ - `wp avatar-privacy db list`: List entries in the custom database table(s).
+ - `wp avatar-privacy db create`: Create the custom database table.
+ - `wp avatar-privacy db upgrade`: Upgrade the structure of the custom database table.
+ - `wp avatar-privacy uninstall`: Remove data added by Avatar Privacy.
+ - `wp avatar-privacy cron list`: List active cron jobs created by the plugin.
+ - `wp avatar-privacy cron delete`: Delete cron jobs created by the plugin.
+* _Change_: `avapr_get_avatar_checkbox()` has been deprecated in favor of `\Avatar_Privacy\get_gravatar_checkbox()`.
+* _Change_: The ID and name of the `use_gravatar` comment form checkbox has been changed to `avatar-privacy-use-gravatar`. Please update custom CSS rules accordingly.
+* _Change_: Additional inline styling is added to the `avatar-privacy-use-gravatar` comment form checkbox to work around common theme limitations. Styling can be disabled using the `avatar_privacy_comment_checkbox_disable_inline_style` filter hook.
+* _Change_: All external PHP dependencies have been moved to the namespace `Avatar_Privacy\Vendor` to reduce the chance of conflicts with other plugins.
+* _Bugfix_: Gravatars are only cached if they are actually images to prevent issues with temporary Varnish errors on Gravatar.com.
+
+= 2.2.2 (2019-06-23) =
+* _Bugfix_: Re-allow installation on 4.9.x for increased compatibility with possible future WordPress Core changes. The 2.2.x branch of Avatar Privacy is the last that will support WordPress < 5.2.
+
+= 2.2.1 (2019-06-08) =
+* _Bugfix_: Compatibility with Windows servers.
+
+= 2.2.0 (2019-05-12) =
+* _Feature_: Integration for the following plugins had been added:
+ - [wpDiscuz](https://wordpress.org/plugins/wpdiscuz/)
+ - [WP User Manager](https://wordpress.org/plugins/wp-user-manager/)
+
+= 2.1.0 (2019-04-14) =
+* _Feature_: Improved compatibility with multisite installations. Plugin data will be properly deleted on uninstallation or when a site is removed. ("Large Networks" will still have to take manual action to prevent timeouts.)
+* _Feature_: Network settings for enabling/disabling global table use on multisite. Existing global data will be migrated to the site-specific tables when global table use is disabled (but not in the other direction).
+* _Change_: `usermeta` keys are now prefixed (`avatar_privacy_use_gravatar` instead of `use_gravatar`).
+* _Change_: Generally improved code quality through unit tests.
+* _Bugfix_: New multisite installations were incorrectly detected as "legacy", making them use the global table (instead of per-site tables). Affected installations can be switched via the new network settings page.
+
+= 2.0.5 (2019-02-23) =
+* _Bugfix_: Fixed a previously undiscovered compatibility issue with recent versions of EWWW Image Optimizer.
+
+= 2.0.4 (2019-02-22) =
+* _Bugfix_: Updated included libraries for improved compatibility with other plugins.
+
+= 2.0.3 (2018-11-30) =
+* _Bugfix_: Prevent warnings when trying to retrieve the avatar for an invalid user ID.
+
+= 2.0.2 (2018-09-09) =
+* _Bugfix_: Updated included libraries for improved compatibility with other plugins.
+
+= 2.0.1 (2018-08-16) =
+* _Bugfix_: The plugin no longer fails with a fatal error on PHP 5.6 (accidentally introduced in 2.0.0).
+
+= 2.0.0 (2018-08-11) =
+* _Feature_: Administrators can now upload site-specific default avatar images.
+* _Feature_: The default policy previously only accessible via the `avatar_privacy_gravatar_use_default` hook can now be set from the `Discussion` settings page.
+* _Feature_: New filter hooks `avatar_privacy_gravatar_link_rel` and `avatar_privacy_gravatar_link_target` to filter the `rel` and `target` attributes of all links to Gravatar.com.
+* _Bugfix_: The REST API returned incorrect avatar URLs for registered users (workaround for [trac ticket #40030](https://core.trac.wordpress.org/ticket/40030)).
+* _Bugfix_: The gravatar use cookie is only set when the comment author has given consent.
+* _Change_: Internal restructuring to make maintenance easier.
+
+= 1.1.1 (2018-06-11) =
+* _Bugfix_: Changing the default gravatar policy via `avatar_privacy_gravatar_use_default` works again for registered users.
+
+= 1.1.0 (2018-06-10) =
+* _Feature_: Supports the new privacy tools on WordPress >= 4.9.6 (export and deletion of personal data, suggested privacy notice text).
+* _Feature_: Registered users can opt into allowing logged-out comments with the same mail address to user their profile pictures.
+* _Feature_: The plugin is now compatible with bbPress.
+* _Feature_: The position of the `use_gravatar` checkbox can be adjusted via the new filter hook `avatar_privacy_use_gravatar_position`.
+* _Change_: Trashed comments and comments marked as spam do not trigger a validation request to Gravatar.com if the admin has set the default gravatar use policy to "enabled" via the filter hook `avatar_privacy_gravatar_use_default`.
+
+= 1.0.7 (2018-06-06) =
+* _Bugfix_: The `use_gravatar` is actually checked when the cookie has been set.
+* _Bugfix_: A (harmless) PHP warning has been fixed.
+
+= 1.0.6 (2018-05-29) =
+* _Bugfix_: Only valid response codes from Gravatar.com are cached (200 and 404).
+* _Bugfix_: Plugin transients are cleared on plugin upgrades.
+* _Bugfix_: The workaround for [trac ticket #42663](https://core.trac.wordpress.org/ticket/42663) introduced in 1.0.5 is expanded to all uses of `wp_get_image_editor()`.
+
+= 1.0.5 (2018-05-22) =
+* _Bugfix_: Prefer GD-based implementations of `WP_Image_Editor` to work around [trac ticket #42663](https://core.trac.wordpress.org/ticket/42663).
+* _Bugfix_: The `rel` and `target` attributes are allowed in `use_gravatar` checkbox labels and by the default, the `noopener` and `nofollow` values for the `rel` attribute are added to the Gravatar.com link.
+* _Bugfix_: Invalid 0-byte image files are not saved anymore.
+
+= 1.0.4 (2018-05-20) =
+* _Bugfix_: When the plugin is uninstalled, the default avatar image is really reset to `mystery` if necessary.
+* _Bugfix_: The `use_gravatar` checkbox is compatible with more themes now.
+
+= 1.0.3 (2018-05-17) =
+* _Bugfix_: The plugin no longer fails with a fatal error on PHP 5.6.
+
+= 1.0.2 (2018-05-16) =
+* _Bugfix_: PNG avatars were not created correctly when EWWW Image Optimizer was enabled.
+
+= 1.0.1 (2018-05-14) =
+* _Bugfix_: Non-multisite installations triggered an SQL error in some situations.
+
+= 1.0 (2018-05-13) =
+* _Feature_: All default avatars are generated on your server.
+* _Feature_: Gravatar.com avatars are cached locally. (The cache is cleaned regularly via a cron job to prevent unlimited growth.)
+* _Feature_: Registered users can upload their own avatar images to your server.
+* _Change_: Refactored according to modern development principles.
+* _Change_: Removed settings in favor of sensible default values and filter hooks:
+ - Gravatar.com usage is opt-in and gravatars are only displayed if the exist.
+ - The default behavior for legacy comments can be customized via the `avatar_privacy_gravatar_use_default` filter hook.
+* _Change_: All static default icons are now SVG images.
diff --git a/uninstall.php b/uninstall.php
new file mode 100644
index 0000000..4ddb380
--- /dev/null
+++ b/uninstall.php
@@ -0,0 +1,63 @@
+create( Uninstallation::class );
+ $uninstaller->run();
+}
+uninstall_avatar_privacy();
diff --git a/vendor-scoped/autoload.php b/vendor-scoped/autoload.php
new file mode 100644
index 0000000..d0fdb60
--- /dev/null
+++ b/vendor-scoped/autoload.php
@@ -0,0 +1,25 @@
+
+ * Jordi Boggiano
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\AutoloadAvatarPrivacy;
+
+/**
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
+ *
+ * $loader = new \Composer\AutoloadAvatarPrivacy\ClassLoader();
+ *
+ * // register classes with namespaces
+ * $loader->add('Symfony\Component', __DIR__.'/component');
+ * $loader->add('Symfony', __DIR__.'/framework');
+ *
+ * // activate the autoloader
+ * $loader->register();
+ *
+ * // to enable searching the include path (eg. for PEAR packages)
+ * $loader->setUseIncludePath(true);
+ *
+ * In this example, if you try to use a class in the Symfony\Component
+ * namespace or one of its children (Symfony\Component\Console for instance),
+ * the autoloader will first look for the class under the component/
+ * directory, and it will then fallback to the framework/ directory if not
+ * found before giving up.
+ *
+ * This class is loosely based on the Symfony UniversalClassLoader.
+ *
+ * @author Fabien Potencier
+ * @author Jordi Boggiano
+ * @see https://www.php-fig.org/psr/psr-0/
+ * @see https://www.php-fig.org/psr/psr-4/
+ */
+class ClassLoader
+{
+ /** @var \Closure(string):void */
+ private static $includeFile;
+
+ /** @var ?string */
+ private $vendorDir;
+
+ // PSR-4
+ /**
+ * @var array[]
+ * @psalm-var array>
+ */
+ private $prefixLengthsPsr4 = array();
+ /**
+ * @var array[]
+ * @psalm-var array>
+ */
+ private $prefixDirsPsr4 = array();
+ /**
+ * @var array[]
+ * @psalm-var array
+ */
+ private $fallbackDirsPsr4 = array();
+
+ // PSR-0
+ /**
+ * @var array[]
+ * @psalm-var array>
+ */
+ private $prefixesPsr0 = array();
+ /**
+ * @var array[]
+ * @psalm-var array
+ */
+ private $fallbackDirsPsr0 = array();
+
+ /** @var bool */
+ private $useIncludePath = false;
+
+ /**
+ * @var string[]
+ * @psalm-var array
+ */
+ private $classMap = array();
+
+ /** @var bool */
+ private $classMapAuthoritative = false;
+
+ /**
+ * @var bool[]
+ * @psalm-var array
+ */
+ private $missingClasses = array();
+
+ /** @var ?string */
+ private $apcuPrefix;
+
+ /**
+ * @var self[]
+ */
+ private static $registeredLoaders = array();
+
+ /**
+ * @param ?string $vendorDir
+ */
+ public function __construct($vendorDir = null)
+ {
+ $this->vendorDir = $vendorDir;
+ self::initializeIncludeClosure();
+ }
+
+ /**
+ * @return string[]
+ */
+ public function getPrefixes()
+ {
+ if (!empty($this->prefixesPsr0)) {
+ return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
+ }
+
+ return array();
+ }
+
+ /**
+ * @return array[]
+ * @psalm-return array>
+ */
+ public function getPrefixesPsr4()
+ {
+ return $this->prefixDirsPsr4;
+ }
+
+ /**
+ * @return array[]
+ * @psalm-return array
+ */
+ public function getFallbackDirs()
+ {
+ return $this->fallbackDirsPsr0;
+ }
+
+ /**
+ * @return array[]
+ * @psalm-return array
+ */
+ public function getFallbackDirsPsr4()
+ {
+ return $this->fallbackDirsPsr4;
+ }
+
+ /**
+ * @return string[] Array of classname => path
+ * @psalm-return array
+ */
+ public function getClassMap()
+ {
+ return $this->classMap;
+ }
+
+ /**
+ * @param string[] $classMap Class to filename map
+ * @psalm-param array $classMap
+ *
+ * @return void
+ */
+ public function addClassMap(array $classMap)
+ {
+ if ($this->classMap) {
+ $this->classMap = array_merge($this->classMap, $classMap);
+ } else {
+ $this->classMap = $classMap;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix, either
+ * appending or prepending to the ones previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param string[]|string $paths The PSR-0 root directories
+ * @param bool $prepend Whether to prepend the directories
+ *
+ * @return void
+ */
+ public function add($prefix, $paths, $prepend = false)
+ {
+ if (!$prefix) {
+ if ($prepend) {
+ $this->fallbackDirsPsr0 = array_merge(
+ (array) $paths,
+ $this->fallbackDirsPsr0
+ );
+ } else {
+ $this->fallbackDirsPsr0 = array_merge(
+ $this->fallbackDirsPsr0,
+ (array) $paths
+ );
+ }
+
+ return;
+ }
+
+ $first = $prefix[0];
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
+ $this->prefixesPsr0[$first][$prefix] = (array) $paths;
+
+ return;
+ }
+ if ($prepend) {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ (array) $paths,
+ $this->prefixesPsr0[$first][$prefix]
+ );
+ } else {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ $this->prefixesPsr0[$first][$prefix],
+ (array) $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace, either
+ * appending or prepending to the ones previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param string[]|string $paths The PSR-4 base directories
+ * @param bool $prepend Whether to prepend the directories
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @return void
+ */
+ public function addPsr4($prefix, $paths, $prepend = false)
+ {
+ if (!$prefix) {
+ // Register directories for the root namespace.
+ if ($prepend) {
+ $this->fallbackDirsPsr4 = array_merge(
+ (array) $paths,
+ $this->fallbackDirsPsr4
+ );
+ } else {
+ $this->fallbackDirsPsr4 = array_merge(
+ $this->fallbackDirsPsr4,
+ (array) $paths
+ );
+ }
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
+ // Register directories for a new namespace.
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ } elseif ($prepend) {
+ // Prepend directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ (array) $paths,
+ $this->prefixDirsPsr4[$prefix]
+ );
+ } else {
+ // Append directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ $this->prefixDirsPsr4[$prefix],
+ (array) $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix,
+ * replacing any others previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param string[]|string $paths The PSR-0 base directories
+ *
+ * @return void
+ */
+ public function set($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr0 = (array) $paths;
+ } else {
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace,
+ * replacing any others previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param string[]|string $paths The PSR-4 base directories
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @return void
+ */
+ public function setPsr4($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr4 = (array) $paths;
+ } else {
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Turns on searching the include path for class files.
+ *
+ * @param bool $useIncludePath
+ *
+ * @return void
+ */
+ public function setUseIncludePath($useIncludePath)
+ {
+ $this->useIncludePath = $useIncludePath;
+ }
+
+ /**
+ * Can be used to check if the autoloader uses the include path to check
+ * for classes.
+ *
+ * @return bool
+ */
+ public function getUseIncludePath()
+ {
+ return $this->useIncludePath;
+ }
+
+ /**
+ * Turns off searching the prefix and fallback directories for classes
+ * that have not been registered with the class map.
+ *
+ * @param bool $classMapAuthoritative
+ *
+ * @return void
+ */
+ public function setClassMapAuthoritative($classMapAuthoritative)
+ {
+ $this->classMapAuthoritative = $classMapAuthoritative;
+ }
+
+ /**
+ * Should class lookup fail if not found in the current class map?
+ *
+ * @return bool
+ */
+ public function isClassMapAuthoritative()
+ {
+ return $this->classMapAuthoritative;
+ }
+
+ /**
+ * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
+ *
+ * @param string|null $apcuPrefix
+ *
+ * @return void
+ */
+ public function setApcuPrefix($apcuPrefix)
+ {
+ $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
+ }
+
+ /**
+ * The APCu prefix in use, or null if APCu caching is not enabled.
+ *
+ * @return string|null
+ */
+ public function getApcuPrefix()
+ {
+ return $this->apcuPrefix;
+ }
+
+ /**
+ * Registers this instance as an autoloader.
+ *
+ * @param bool $prepend Whether to prepend the autoloader or not
+ *
+ * @return void
+ */
+ public function register($prepend = false)
+ {
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+
+ if (null === $this->vendorDir) {
+ return;
+ }
+
+ if ($prepend) {
+ self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
+ } else {
+ unset(self::$registeredLoaders[$this->vendorDir]);
+ self::$registeredLoaders[$this->vendorDir] = $this;
+ }
+ }
+
+ /**
+ * Unregisters this instance as an autoloader.
+ *
+ * @return void
+ */
+ public function unregister()
+ {
+ spl_autoload_unregister(array($this, 'loadClass'));
+
+ if (null !== $this->vendorDir) {
+ unset(self::$registeredLoaders[$this->vendorDir]);
+ }
+ }
+
+ /**
+ * Loads the given class or interface.
+ *
+ * @param string $class The name of the class
+ * @return true|null True if loaded, null otherwise
+ */
+ public function loadClass($class)
+ {
+ if ($file = $this->findFile($class)) {
+ $includeFile = self::$includeFile;
+ $includeFile($file);
+
+ return true;
+ }
+
+ return null;
+ }
+
+ /**
+ * Finds the path to the file where the class is defined.
+ *
+ * @param string $class The name of the class
+ *
+ * @return string|false The path if found, false otherwise
+ */
+ public function findFile($class)
+ {
+ // class map lookup
+ if (isset($this->classMap[$class])) {
+ return $this->classMap[$class];
+ }
+ if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
+ return false;
+ }
+ if (null !== $this->apcuPrefix) {
+ $file = apcu_fetch($this->apcuPrefix.$class, $hit);
+ if ($hit) {
+ return $file;
+ }
+ }
+
+ $file = $this->findFileWithExtension($class, '.php');
+
+ // Search for Hack files if we are running on HHVM
+ if (false === $file && defined('HHVM_VERSION')) {
+ $file = $this->findFileWithExtension($class, '.hh');
+ }
+
+ if (null !== $this->apcuPrefix) {
+ apcu_add($this->apcuPrefix.$class, $file);
+ }
+
+ if (false === $file) {
+ // Remember that this class does not exist.
+ $this->missingClasses[$class] = true;
+ }
+
+ return $file;
+ }
+
+ /**
+ * Returns the currently registered loaders indexed by their corresponding vendor directories.
+ *
+ * @return self[]
+ */
+ public static function getRegisteredLoaders()
+ {
+ return self::$registeredLoaders;
+ }
+
+ /**
+ * @param string $class
+ * @param string $ext
+ * @return string|false
+ */
+ private function findFileWithExtension($class, $ext)
+ {
+ // PSR-4 lookup
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
+
+ $first = $class[0];
+ if (isset($this->prefixLengthsPsr4[$first])) {
+ $subPath = $class;
+ while (false !== $lastPos = strrpos($subPath, '\\')) {
+ $subPath = substr($subPath, 0, $lastPos);
+ $search = $subPath . '\\';
+ if (isset($this->prefixDirsPsr4[$search])) {
+ $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
+ foreach ($this->prefixDirsPsr4[$search] as $dir) {
+ if (file_exists($file = $dir . $pathEnd)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-4 fallback dirs
+ foreach ($this->fallbackDirsPsr4 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 lookup
+ if (false !== $pos = strrpos($class, '\\')) {
+ // namespaced class name
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
+ } else {
+ // PEAR-like class name
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
+ }
+
+ if (isset($this->prefixesPsr0[$first])) {
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
+ if (0 === strpos($class, $prefix)) {
+ foreach ($dirs as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-0 fallback dirs
+ foreach ($this->fallbackDirsPsr0 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 include paths.
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
+ return $file;
+ }
+
+ return false;
+ }
+
+ /**
+ * @return void
+ */
+ private static function initializeIncludeClosure()
+ {
+ if (self::$includeFile !== null) {
+ return;
+ }
+
+ /**
+ * Scope isolated include.
+ *
+ * Prevents access to $this/self from included files.
+ *
+ * @param string $file
+ * @return void
+ */
+ self::$includeFile = \Closure::bind(static function($file) {
+ include $file;
+ }, null, null);
+ }
+}
diff --git a/vendor-scoped/composer/LICENSE b/vendor-scoped/composer/LICENSE
new file mode 100644
index 0000000..f27399a
--- /dev/null
+++ b/vendor-scoped/composer/LICENSE
@@ -0,0 +1,21 @@
+
+Copyright (c) Nils Adermann, Jordi Boggiano
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/vendor-scoped/composer/autoload_classmap.php b/vendor-scoped/composer/autoload_classmap.php
new file mode 100644
index 0000000..fe56c30
--- /dev/null
+++ b/vendor-scoped/composer/autoload_classmap.php
@@ -0,0 +1,181 @@
+ $baseDir . '/includes/avatar-privacy/avatar-handlers/class-avatar-handler.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Abstract_Icon_Provider' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/class-abstract-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Custom_Icon_Provider' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/class-custom-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generated_Icons\\Bird_Avatar_Icon_Provider' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/generated-icons/class-bird-avatar-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generated_Icons\\Cat_Avatar_Icon_Provider' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/generated-icons/class-cat-avatar-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generated_Icons\\Identicon_Icon_Provider' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/generated-icons/class-identicon-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generated_Icons\\Monster_ID_Icon_Provider' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/generated-icons/class-monster-id-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generated_Icons\\Retro_Icon_Provider' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/generated-icons/class-retro-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generated_Icons\\Rings_Icon_Provider' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/generated-icons/class-rings-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generated_Icons\\Robohash_Icon_Provider' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/generated-icons/class-robohash-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generated_Icons\\Wavatar_Icon_Provider' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/generated-icons/class-wavatar-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generating_Icon_Provider' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/class-generating-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generator' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/class-generator.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\Bird_Avatar' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-bird-avatar.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\Cat_Avatar' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-cat-avatar.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\Jdenticon' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-jdenticon.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\Monster_ID' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-monster-id.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\PNG_Parts_Generator' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-png-parts-generator.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\Parts_Generator' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-parts-generator.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\Retro' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-retro.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\Rings' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-rings.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\Robohash' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-robohash.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\Wavatar' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-wavatar.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Icon_Provider' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/class-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\SVG_Icon_Provider' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/class-svg-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Static_Icon_Provider' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/class-static-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Static_Icons\\Bowling_Pin_Icon_Provider' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/static-icons/class-bowling-pin-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Static_Icons\\Mystery_Icon_Provider' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/static-icons/class-mystery-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Static_Icons\\Silhouette_Icon_Provider' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/static-icons/class-silhouette-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Static_Icons\\Speech_Bubble_Icon_Provider' => $baseDir . '/includes/avatar-privacy/avatar-handlers/default-icons/static-icons/class-speech-bubble-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons_Handler' => $baseDir . '/includes/avatar-privacy/avatar-handlers/class-default-icons-handler.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Gravatar_Cache_Handler' => $baseDir . '/includes/avatar-privacy/avatar-handlers/class-gravatar-cache-handler.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Legacy_Icon_Handler' => $baseDir . '/includes/avatar-privacy/avatar-handlers/class-legacy-icon-handler.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\User_Avatar_Handler' => $baseDir . '/includes/avatar-privacy/avatar-handlers/class-user-avatar-handler.php',
+ 'Avatar_Privacy\\CLI\\Abstract_Command' => $baseDir . '/includes/avatar-privacy/cli/class-abstract-command.php',
+ 'Avatar_Privacy\\CLI\\Command' => $baseDir . '/includes/avatar-privacy/cli/class-command.php',
+ 'Avatar_Privacy\\CLI\\Cron_Command' => $baseDir . '/includes/avatar-privacy/cli/class-cron-command.php',
+ 'Avatar_Privacy\\CLI\\Database_Command' => $baseDir . '/includes/avatar-privacy/cli/class-database-command.php',
+ 'Avatar_Privacy\\CLI\\Default_Command' => $baseDir . '/includes/avatar-privacy/cli/class-default-command.php',
+ 'Avatar_Privacy\\CLI\\Uninstall_Command' => $baseDir . '/includes/avatar-privacy/cli/class-uninstall-command.php',
+ 'Avatar_Privacy\\CLI\\User_Command' => $baseDir . '/includes/avatar-privacy/cli/class-user-command.php',
+ 'Avatar_Privacy\\Component' => $baseDir . '/includes/avatar-privacy/class-component.php',
+ 'Avatar_Privacy\\Components\\Avatar_Handling' => $baseDir . '/includes/avatar-privacy/components/class-avatar-handling.php',
+ 'Avatar_Privacy\\Components\\Block_Editor' => $baseDir . '/includes/avatar-privacy/components/class-block-editor.php',
+ 'Avatar_Privacy\\Components\\Command_Line_Interface' => $baseDir . '/includes/avatar-privacy/components/class-command-line-interface.php',
+ 'Avatar_Privacy\\Components\\Comments' => $baseDir . '/includes/avatar-privacy/components/class-comments.php',
+ 'Avatar_Privacy\\Components\\Image_Proxy' => $baseDir . '/includes/avatar-privacy/components/class-image-proxy.php',
+ 'Avatar_Privacy\\Components\\Integrations' => $baseDir . '/includes/avatar-privacy/components/class-integrations.php',
+ 'Avatar_Privacy\\Components\\Network_Settings_Page' => $baseDir . '/includes/avatar-privacy/components/class-network-settings-page.php',
+ 'Avatar_Privacy\\Components\\Privacy_Tools' => $baseDir . '/includes/avatar-privacy/components/class-privacy-tools.php',
+ 'Avatar_Privacy\\Components\\Settings_Page' => $baseDir . '/includes/avatar-privacy/components/class-settings-page.php',
+ 'Avatar_Privacy\\Components\\Setup' => $baseDir . '/includes/avatar-privacy/components/class-setup.php',
+ 'Avatar_Privacy\\Components\\Shortcodes' => $baseDir . '/includes/avatar-privacy/components/class-shortcodes.php',
+ 'Avatar_Privacy\\Components\\Uninstallation' => $baseDir . '/includes/avatar-privacy/components/class-uninstallation.php',
+ 'Avatar_Privacy\\Components\\User_Profile' => $baseDir . '/includes/avatar-privacy/components/class-user-profile.php',
+ 'Avatar_Privacy\\Controller' => $baseDir . '/includes/avatar-privacy/class-controller.php',
+ 'Avatar_Privacy\\Core' => $baseDir . '/includes/avatar-privacy/class-core.php',
+ 'Avatar_Privacy\\Core\\API' => $baseDir . '/includes/avatar-privacy/core/class-api.php',
+ 'Avatar_Privacy\\Core\\Comment_Author_Fields' => $baseDir . '/includes/avatar-privacy/core/class-comment-author-fields.php',
+ 'Avatar_Privacy\\Core\\Default_Avatars' => $baseDir . '/includes/avatar-privacy/core/class-default-avatars.php',
+ 'Avatar_Privacy\\Core\\Settings' => $baseDir . '/includes/avatar-privacy/core/class-settings.php',
+ 'Avatar_Privacy\\Core\\User_Fields' => $baseDir . '/includes/avatar-privacy/core/class-user-fields.php',
+ 'Avatar_Privacy\\Data_Storage\\Cache' => $baseDir . '/includes/avatar-privacy/data-storage/class-cache.php',
+ 'Avatar_Privacy\\Data_Storage\\Database\\Comment_Author_Table' => $baseDir . '/includes/avatar-privacy/data-storage/database/class-comment-author-table.php',
+ 'Avatar_Privacy\\Data_Storage\\Database\\Hashes_Table' => $baseDir . '/includes/avatar-privacy/data-storage/database/class-hashes-table.php',
+ 'Avatar_Privacy\\Data_Storage\\Database\\Table' => $baseDir . '/includes/avatar-privacy/data-storage/database/class-table.php',
+ 'Avatar_Privacy\\Data_Storage\\Filesystem_Cache' => $baseDir . '/includes/avatar-privacy/data-storage/class-filesystem-cache.php',
+ 'Avatar_Privacy\\Data_Storage\\Network_Options' => $baseDir . '/includes/avatar-privacy/data-storage/class-network-options.php',
+ 'Avatar_Privacy\\Data_Storage\\Options' => $baseDir . '/includes/avatar-privacy/data-storage/class-options.php',
+ 'Avatar_Privacy\\Data_Storage\\Site_Transients' => $baseDir . '/includes/avatar-privacy/data-storage/class-site-transients.php',
+ 'Avatar_Privacy\\Data_Storage\\Transients' => $baseDir . '/includes/avatar-privacy/data-storage/class-transients.php',
+ 'Avatar_Privacy\\Exceptions\\Avatar_Comment_Type_Exception' => $baseDir . '/includes/avatar-privacy/exceptions/class-avatar-comment-type-exception.php',
+ 'Avatar_Privacy\\Exceptions\\Database_Exception' => $baseDir . '/includes/avatar-privacy/exceptions/class-database-exception.php',
+ 'Avatar_Privacy\\Exceptions\\File_Deletion_Exception' => $baseDir . '/includes/avatar-privacy/exceptions/class-file-deletion-exception.php',
+ 'Avatar_Privacy\\Exceptions\\Filesystem_Exception' => $baseDir . '/includes/avatar-privacy/exceptions/class-filesystem-exception.php',
+ 'Avatar_Privacy\\Exceptions\\Form_Field_Not_Found_Exception' => $baseDir . '/includes/avatar-privacy/exceptions/class-form-field-not-found-exception.php',
+ 'Avatar_Privacy\\Exceptions\\Invalid_Nonce_Exception' => $baseDir . '/includes/avatar-privacy/exceptions/class-invalid-nonce-exception.php',
+ 'Avatar_Privacy\\Exceptions\\Object_Factory_Exception' => $baseDir . '/includes/avatar-privacy/exceptions/class-object-factory-exception.php',
+ 'Avatar_Privacy\\Exceptions\\PNG_Image_Exception' => $baseDir . '/includes/avatar-privacy/exceptions/class-png-image-exception.php',
+ 'Avatar_Privacy\\Exceptions\\Part_Files_Not_Found_Exception' => $baseDir . '/includes/avatar-privacy/exceptions/class-part-files-not-found-exception.php',
+ 'Avatar_Privacy\\Exceptions\\Upload_Handling_Exception' => $baseDir . '/includes/avatar-privacy/exceptions/class-upload-handling-exception.php',
+ 'Avatar_Privacy\\Factory' => $baseDir . '/includes/avatar-privacy/class-factory.php',
+ 'Avatar_Privacy\\Integrations\\BBPress_Integration' => $baseDir . '/includes/avatar-privacy/integrations/class-bbpress-integration.php',
+ 'Avatar_Privacy\\Integrations\\BuddyPress_Integration' => $baseDir . '/includes/avatar-privacy/integrations/class-buddypress-integration.php',
+ 'Avatar_Privacy\\Integrations\\Plugin_Integration' => $baseDir . '/includes/avatar-privacy/integrations/class-plugin-integration.php',
+ 'Avatar_Privacy\\Integrations\\Simple_Author_Box_Integration' => $baseDir . '/includes/avatar-privacy/integrations/class-simple-author-box-integration.php',
+ 'Avatar_Privacy\\Integrations\\Simple_Local_Avatars_Integration' => $baseDir . '/includes/avatar-privacy/integrations/class-simple-local-avatars-integration.php',
+ 'Avatar_Privacy\\Integrations\\Simple_User_Avatar_Integration' => $baseDir . '/includes/avatar-privacy/integrations/class-simple-user-avatar-integration.php',
+ 'Avatar_Privacy\\Integrations\\Theme_My_Login_Profiles_Integration' => $baseDir . '/includes/avatar-privacy/integrations/class-theme-my-login-profiles-integration.php',
+ 'Avatar_Privacy\\Integrations\\Ultimate_Member_Integration' => $baseDir . '/includes/avatar-privacy/integrations/class-ultimate-member-integration.php',
+ 'Avatar_Privacy\\Integrations\\WPDiscuz_Integration' => $baseDir . '/includes/avatar-privacy/integrations/class-wpdiscuz-integration.php',
+ 'Avatar_Privacy\\Integrations\\WP_User_Manager_Integration' => $baseDir . '/includes/avatar-privacy/integrations/class-wp-user-manager-integration.php',
+ 'Avatar_Privacy\\Requirements' => $baseDir . '/includes/avatar-privacy/class-requirements.php',
+ 'Avatar_Privacy\\Tools\\HTML\\Dependencies' => $baseDir . '/includes/avatar-privacy/tools/html/class-dependencies.php',
+ 'Avatar_Privacy\\Tools\\HTML\\User_Form' => $baseDir . '/includes/avatar-privacy/tools/html/class-user-form.php',
+ 'Avatar_Privacy\\Tools\\Hasher' => $baseDir . '/includes/avatar-privacy/tools/class-hasher.php',
+ 'Avatar_Privacy\\Tools\\Images\\Color' => $baseDir . '/includes/avatar-privacy/tools/images/class-color.php',
+ 'Avatar_Privacy\\Tools\\Images\\Editor' => $baseDir . '/includes/avatar-privacy/tools/images/class-editor.php',
+ 'Avatar_Privacy\\Tools\\Images\\Image_File' => $baseDir . '/includes/avatar-privacy/tools/images/class-image-file.php',
+ 'Avatar_Privacy\\Tools\\Images\\Image_Stream' => $baseDir . '/includes/avatar-privacy/tools/images/class-image-stream.php',
+ 'Avatar_Privacy\\Tools\\Images\\PNG' => $baseDir . '/includes/avatar-privacy/tools/images/class-png.php',
+ 'Avatar_Privacy\\Tools\\Images\\SVG' => $baseDir . '/includes/avatar-privacy/tools/images/class-svg.php',
+ 'Avatar_Privacy\\Tools\\Images\\Type' => $baseDir . '/includes/avatar-privacy/tools/images/class-type.php',
+ 'Avatar_Privacy\\Tools\\Multisite' => $baseDir . '/includes/avatar-privacy/tools/class-multisite.php',
+ 'Avatar_Privacy\\Tools\\Network\\Gravatar_Service' => $baseDir . '/includes/avatar-privacy/tools/network/class-gravatar-service.php',
+ 'Avatar_Privacy\\Tools\\Network\\Remote_Image_Service' => $baseDir . '/includes/avatar-privacy/tools/network/class-remote-image-service.php',
+ 'Avatar_Privacy\\Tools\\Number_Generator' => $baseDir . '/includes/avatar-privacy/tools/class-number-generator.php',
+ 'Avatar_Privacy\\Tools\\Template' => $baseDir . '/includes/avatar-privacy/tools/class-template.php',
+ 'Avatar_Privacy\\Upload_Handlers\\Custom_Default_Icon_Upload_Handler' => $baseDir . '/includes/avatar-privacy/upload-handlers/class-custom-default-icon-upload-handler.php',
+ 'Avatar_Privacy\\Upload_Handlers\\UI\\File_Upload_Input' => $baseDir . '/includes/avatar-privacy/upload-handlers/ui/class-file-upload-input.php',
+ 'Avatar_Privacy\\Upload_Handlers\\Upload_Handler' => $baseDir . '/includes/avatar-privacy/upload-handlers/class-upload-handler.php',
+ 'Avatar_Privacy\\Upload_Handlers\\User_Avatar_Upload_Handler' => $baseDir . '/includes/avatar-privacy/upload-handlers/class-user-avatar-upload-handler.php',
+ 'Avatar_Privacy\\Vendor\\Colors\\RandomColor' => $vendorDir . '/mistic100/randomcolor/src/RandomColor.php',
+ 'Avatar_Privacy\\Vendor\\Dice\\Dice' => $vendorDir . '/level-2/dice/Dice.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Canvas' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Canvas.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\CanvasContext' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/CanvasContext.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\ColorUtils' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/ColorUtils.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Matrix' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Matrix.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Png\\PngBuffer' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Png/PngBuffer.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Png\\PngEncoder' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Png/PngEncoder.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Png\\PngPalette' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Png/PngPalette.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Point' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Point.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Rasterization\\Edge' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Rasterization/Edge.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Rasterization\\EdgeIntersection' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Rasterization/EdgeIntersection.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Rasterization\\EdgeSuperSampleIntersection' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Rasterization/EdgeSuperSampleIntersection.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Rasterization\\EdgeTable' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Rasterization/EdgeTable.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Rasterization\\Layer' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Rasterization/Layer.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Rasterization\\LayerManager' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Rasterization/LayerManager.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Rasterization\\Rasterizer' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Rasterization/Rasterizer.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Rasterization\\SuperSampleBuffer' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Rasterization/SuperSampleBuffer.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Rasterization\\SuperSampleRange' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Rasterization/SuperSampleRange.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Color' => $vendorDir . '/jdenticon/jdenticon/src/Color.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Identicon' => $vendorDir . '/jdenticon/jdenticon/src/Identicon.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\IdenticonStyle' => $vendorDir . '/jdenticon/jdenticon/src/IdenticonStyle.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\AbstractRenderer' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/AbstractRenderer.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\ColorTheme' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/ColorTheme.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\IconGenerator' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/IconGenerator.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\ImagickRenderer' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/ImagickRenderer.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\InternalPngRenderer' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/InternalPngRenderer.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\Point' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/Point.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\Rectangle' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/Rectangle.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\RendererInterface' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/RendererInterface.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\SvgPath' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/SvgPath.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\SvgRenderer' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/SvgRenderer.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\Transform' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/Transform.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\TriangleDirection' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/TriangleDirection.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Shapes\\Shape' => $vendorDir . '/jdenticon/jdenticon/src/Shapes/Shape.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Shapes\\ShapeCategory' => $vendorDir . '/jdenticon/jdenticon/src/Shapes/ShapeCategory.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Shapes\\ShapeDefinitions' => $vendorDir . '/jdenticon/jdenticon/src/Shapes/ShapeDefinitions.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Shapes\\ShapePosition' => $vendorDir . '/jdenticon/jdenticon/src/Shapes/ShapePosition.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\Data_Storage\\Abstract_Cache' => $vendorDir . '/mundschenk-at/wp-data-storage/src/class-abstract-cache.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\Data_Storage\\Cache' => $vendorDir . '/mundschenk-at/wp-data-storage/src/class-cache.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\Data_Storage\\Network_Options' => $vendorDir . '/mundschenk-at/wp-data-storage/src/class-network-options.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\Data_Storage\\Options' => $vendorDir . '/mundschenk-at/wp-data-storage/src/class-options.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\Data_Storage\\Site_Transients' => $vendorDir . '/mundschenk-at/wp-data-storage/src/class-site-transients.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\Data_Storage\\Transients' => $vendorDir . '/mundschenk-at/wp-data-storage/src/class-transients.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Abstract_Control' => $vendorDir . '/mundschenk-at/wp-settings-ui/src/ui/class-abstract-control.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Control' => $vendorDir . '/mundschenk-at/wp-settings-ui/src/ui/class-control.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Control_Factory' => $vendorDir . '/mundschenk-at/wp-settings-ui/src/ui/class-control-factory.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Controls\\Checkbox_Input' => $vendorDir . '/mundschenk-at/wp-settings-ui/src/ui/controls/class-checkbox-input.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Controls\\Display_Text' => $vendorDir . '/mundschenk-at/wp-settings-ui/src/ui/controls/class-display-text.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Controls\\Hidden_Input' => $vendorDir . '/mundschenk-at/wp-settings-ui/src/ui/controls/class-hidden-input.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Controls\\Input' => $vendorDir . '/mundschenk-at/wp-settings-ui/src/ui/controls/class-input.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Controls\\Number_Input' => $vendorDir . '/mundschenk-at/wp-settings-ui/src/ui/controls/class-number-input.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Controls\\Select' => $vendorDir . '/mundschenk-at/wp-settings-ui/src/ui/controls/class-select.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Controls\\Submit_Input' => $vendorDir . '/mundschenk-at/wp-settings-ui/src/ui/controls/class-submit-input.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Controls\\Text_Input' => $vendorDir . '/mundschenk-at/wp-settings-ui/src/ui/controls/class-text-input.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Controls\\Textarea' => $vendorDir . '/mundschenk-at/wp-settings-ui/src/ui/controls/class-textarea.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\WP_Requirements' => $vendorDir . '/mundschenk-at/check-wp-requirements/class-wp-requirements.php',
+ 'Avatar_Privacy\\Vendor\\splitbrain\\RingIcon\\AbstractRingIcon' => $vendorDir . '/splitbrain/php-ringicon/src/AbstractRingIcon.php',
+ 'Avatar_Privacy\\Vendor\\splitbrain\\RingIcon\\RingIcon' => $vendorDir . '/splitbrain/php-ringicon/src/RingIcon.php',
+ 'Avatar_Privacy\\Vendor\\splitbrain\\RingIcon\\RingIconSVG' => $vendorDir . '/splitbrain/php-ringicon/src/RingIconSVG.php',
+);
diff --git a/vendor-scoped/composer/autoload_files.php b/vendor-scoped/composer/autoload_files.php
new file mode 100644
index 0000000..5515576
--- /dev/null
+++ b/vendor-scoped/composer/autoload_files.php
@@ -0,0 +1,12 @@
+ $baseDir . '/includes/avatar-privacy-functions.php',
+ '96cc9366f0f8a682f3b272c65c21b84f' => $baseDir . '/includes/avatar-privacy/functions.php',
+ '664e375fee598657b31fb4bcd80b6963' => $baseDir . '/includes/avatar-privacy/tools/functions.php',
+);
diff --git a/vendor-scoped/composer/autoload_namespaces.php b/vendor-scoped/composer/autoload_namespaces.php
new file mode 100644
index 0000000..15a2ff3
--- /dev/null
+++ b/vendor-scoped/composer/autoload_namespaces.php
@@ -0,0 +1,9 @@
+setClassMapAuthoritative(true);
+ $loader->register(true);
+
+ $filesToLoad = \Composer\Autoload\ComposerStaticInitAvatarPrivacy::$files;
+ $requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
+ if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
+ $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
+
+ require $file;
+ }
+ }, null, null);
+ foreach ($filesToLoad as $fileIdentifier => $file) {
+ $requireFile($fileIdentifier, $file);
+ }
+
+ return $loader;
+ }
+}
diff --git a/vendor-scoped/composer/autoload_static.php b/vendor-scoped/composer/autoload_static.php
new file mode 100644
index 0000000..6f03f6c
--- /dev/null
+++ b/vendor-scoped/composer/autoload_static.php
@@ -0,0 +1,234 @@
+ __DIR__ . '/../..' . '/includes/avatar-privacy-functions.php',
+ '96cc9366f0f8a682f3b272c65c21b84f' => __DIR__ . '/../..' . '/includes/avatar-privacy/functions.php',
+ '664e375fee598657b31fb4bcd80b6963' => __DIR__ . '/../..' . '/includes/avatar-privacy/tools/functions.php',
+ );
+
+ public static $prefixLengthsPsr4 = array (
+ 'D' =>
+ array (
+ ),
+ 'A' =>
+ array (
+ 'Avatar_Privacy\\Vendor\\splitbrain\\RingIcon\\' => 42,
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\' => 32,
+ 'Avatar_Privacy\\Vendor\\Dice\\' => 27,
+ 'Avatar_Privacy\\Vendor\\Colors\\' => 29,
+ ),
+ );
+
+ public static $prefixDirsPsr4 = array (
+ 'Avatar_Privacy\\Vendor\\splitbrain\\RingIcon\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/splitbrain/php-ringicon/src',
+ ),
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/jdenticon/jdenticon/src',
+ ),
+ 'Avatar_Privacy\\Vendor\\Dice\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/level-2/dice',
+ ),
+ 'Avatar_Privacy\\Vendor\\Colors\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/mistic100/randomcolor/src',
+ ),
+ );
+
+ public static $classMap = array (
+ 'Avatar_Privacy\\Avatar_Handlers\\Avatar_Handler' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/class-avatar-handler.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Abstract_Icon_Provider' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/class-abstract-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Custom_Icon_Provider' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/class-custom-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generated_Icons\\Bird_Avatar_Icon_Provider' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/generated-icons/class-bird-avatar-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generated_Icons\\Cat_Avatar_Icon_Provider' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/generated-icons/class-cat-avatar-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generated_Icons\\Identicon_Icon_Provider' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/generated-icons/class-identicon-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generated_Icons\\Monster_ID_Icon_Provider' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/generated-icons/class-monster-id-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generated_Icons\\Retro_Icon_Provider' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/generated-icons/class-retro-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generated_Icons\\Rings_Icon_Provider' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/generated-icons/class-rings-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generated_Icons\\Robohash_Icon_Provider' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/generated-icons/class-robohash-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generated_Icons\\Wavatar_Icon_Provider' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/generated-icons/class-wavatar-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generating_Icon_Provider' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/class-generating-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generator' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/class-generator.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\Bird_Avatar' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-bird-avatar.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\Cat_Avatar' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-cat-avatar.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\Jdenticon' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-jdenticon.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\Monster_ID' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-monster-id.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\PNG_Parts_Generator' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-png-parts-generator.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\Parts_Generator' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-parts-generator.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\Retro' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-retro.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\Rings' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-rings.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\Robohash' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-robohash.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Generators\\Wavatar' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/generators/class-wavatar.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Icon_Provider' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/class-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\SVG_Icon_Provider' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/class-svg-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Static_Icon_Provider' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/class-static-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Static_Icons\\Bowling_Pin_Icon_Provider' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/static-icons/class-bowling-pin-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Static_Icons\\Mystery_Icon_Provider' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/static-icons/class-mystery-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Static_Icons\\Silhouette_Icon_Provider' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/static-icons/class-silhouette-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons\\Static_Icons\\Speech_Bubble_Icon_Provider' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/default-icons/static-icons/class-speech-bubble-icon-provider.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Default_Icons_Handler' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/class-default-icons-handler.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Gravatar_Cache_Handler' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/class-gravatar-cache-handler.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\Legacy_Icon_Handler' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/class-legacy-icon-handler.php',
+ 'Avatar_Privacy\\Avatar_Handlers\\User_Avatar_Handler' => __DIR__ . '/../..' . '/includes/avatar-privacy/avatar-handlers/class-user-avatar-handler.php',
+ 'Avatar_Privacy\\CLI\\Abstract_Command' => __DIR__ . '/../..' . '/includes/avatar-privacy/cli/class-abstract-command.php',
+ 'Avatar_Privacy\\CLI\\Command' => __DIR__ . '/../..' . '/includes/avatar-privacy/cli/class-command.php',
+ 'Avatar_Privacy\\CLI\\Cron_Command' => __DIR__ . '/../..' . '/includes/avatar-privacy/cli/class-cron-command.php',
+ 'Avatar_Privacy\\CLI\\Database_Command' => __DIR__ . '/../..' . '/includes/avatar-privacy/cli/class-database-command.php',
+ 'Avatar_Privacy\\CLI\\Default_Command' => __DIR__ . '/../..' . '/includes/avatar-privacy/cli/class-default-command.php',
+ 'Avatar_Privacy\\CLI\\Uninstall_Command' => __DIR__ . '/../..' . '/includes/avatar-privacy/cli/class-uninstall-command.php',
+ 'Avatar_Privacy\\CLI\\User_Command' => __DIR__ . '/../..' . '/includes/avatar-privacy/cli/class-user-command.php',
+ 'Avatar_Privacy\\Component' => __DIR__ . '/../..' . '/includes/avatar-privacy/class-component.php',
+ 'Avatar_Privacy\\Components\\Avatar_Handling' => __DIR__ . '/../..' . '/includes/avatar-privacy/components/class-avatar-handling.php',
+ 'Avatar_Privacy\\Components\\Block_Editor' => __DIR__ . '/../..' . '/includes/avatar-privacy/components/class-block-editor.php',
+ 'Avatar_Privacy\\Components\\Command_Line_Interface' => __DIR__ . '/../..' . '/includes/avatar-privacy/components/class-command-line-interface.php',
+ 'Avatar_Privacy\\Components\\Comments' => __DIR__ . '/../..' . '/includes/avatar-privacy/components/class-comments.php',
+ 'Avatar_Privacy\\Components\\Image_Proxy' => __DIR__ . '/../..' . '/includes/avatar-privacy/components/class-image-proxy.php',
+ 'Avatar_Privacy\\Components\\Integrations' => __DIR__ . '/../..' . '/includes/avatar-privacy/components/class-integrations.php',
+ 'Avatar_Privacy\\Components\\Network_Settings_Page' => __DIR__ . '/../..' . '/includes/avatar-privacy/components/class-network-settings-page.php',
+ 'Avatar_Privacy\\Components\\Privacy_Tools' => __DIR__ . '/../..' . '/includes/avatar-privacy/components/class-privacy-tools.php',
+ 'Avatar_Privacy\\Components\\Settings_Page' => __DIR__ . '/../..' . '/includes/avatar-privacy/components/class-settings-page.php',
+ 'Avatar_Privacy\\Components\\Setup' => __DIR__ . '/../..' . '/includes/avatar-privacy/components/class-setup.php',
+ 'Avatar_Privacy\\Components\\Shortcodes' => __DIR__ . '/../..' . '/includes/avatar-privacy/components/class-shortcodes.php',
+ 'Avatar_Privacy\\Components\\Uninstallation' => __DIR__ . '/../..' . '/includes/avatar-privacy/components/class-uninstallation.php',
+ 'Avatar_Privacy\\Components\\User_Profile' => __DIR__ . '/../..' . '/includes/avatar-privacy/components/class-user-profile.php',
+ 'Avatar_Privacy\\Controller' => __DIR__ . '/../..' . '/includes/avatar-privacy/class-controller.php',
+ 'Avatar_Privacy\\Core' => __DIR__ . '/../..' . '/includes/avatar-privacy/class-core.php',
+ 'Avatar_Privacy\\Core\\API' => __DIR__ . '/../..' . '/includes/avatar-privacy/core/class-api.php',
+ 'Avatar_Privacy\\Core\\Comment_Author_Fields' => __DIR__ . '/../..' . '/includes/avatar-privacy/core/class-comment-author-fields.php',
+ 'Avatar_Privacy\\Core\\Default_Avatars' => __DIR__ . '/../..' . '/includes/avatar-privacy/core/class-default-avatars.php',
+ 'Avatar_Privacy\\Core\\Settings' => __DIR__ . '/../..' . '/includes/avatar-privacy/core/class-settings.php',
+ 'Avatar_Privacy\\Core\\User_Fields' => __DIR__ . '/../..' . '/includes/avatar-privacy/core/class-user-fields.php',
+ 'Avatar_Privacy\\Data_Storage\\Cache' => __DIR__ . '/../..' . '/includes/avatar-privacy/data-storage/class-cache.php',
+ 'Avatar_Privacy\\Data_Storage\\Database\\Comment_Author_Table' => __DIR__ . '/../..' . '/includes/avatar-privacy/data-storage/database/class-comment-author-table.php',
+ 'Avatar_Privacy\\Data_Storage\\Database\\Hashes_Table' => __DIR__ . '/../..' . '/includes/avatar-privacy/data-storage/database/class-hashes-table.php',
+ 'Avatar_Privacy\\Data_Storage\\Database\\Table' => __DIR__ . '/../..' . '/includes/avatar-privacy/data-storage/database/class-table.php',
+ 'Avatar_Privacy\\Data_Storage\\Filesystem_Cache' => __DIR__ . '/../..' . '/includes/avatar-privacy/data-storage/class-filesystem-cache.php',
+ 'Avatar_Privacy\\Data_Storage\\Network_Options' => __DIR__ . '/../..' . '/includes/avatar-privacy/data-storage/class-network-options.php',
+ 'Avatar_Privacy\\Data_Storage\\Options' => __DIR__ . '/../..' . '/includes/avatar-privacy/data-storage/class-options.php',
+ 'Avatar_Privacy\\Data_Storage\\Site_Transients' => __DIR__ . '/../..' . '/includes/avatar-privacy/data-storage/class-site-transients.php',
+ 'Avatar_Privacy\\Data_Storage\\Transients' => __DIR__ . '/../..' . '/includes/avatar-privacy/data-storage/class-transients.php',
+ 'Avatar_Privacy\\Exceptions\\Avatar_Comment_Type_Exception' => __DIR__ . '/../..' . '/includes/avatar-privacy/exceptions/class-avatar-comment-type-exception.php',
+ 'Avatar_Privacy\\Exceptions\\Database_Exception' => __DIR__ . '/../..' . '/includes/avatar-privacy/exceptions/class-database-exception.php',
+ 'Avatar_Privacy\\Exceptions\\File_Deletion_Exception' => __DIR__ . '/../..' . '/includes/avatar-privacy/exceptions/class-file-deletion-exception.php',
+ 'Avatar_Privacy\\Exceptions\\Filesystem_Exception' => __DIR__ . '/../..' . '/includes/avatar-privacy/exceptions/class-filesystem-exception.php',
+ 'Avatar_Privacy\\Exceptions\\Form_Field_Not_Found_Exception' => __DIR__ . '/../..' . '/includes/avatar-privacy/exceptions/class-form-field-not-found-exception.php',
+ 'Avatar_Privacy\\Exceptions\\Invalid_Nonce_Exception' => __DIR__ . '/../..' . '/includes/avatar-privacy/exceptions/class-invalid-nonce-exception.php',
+ 'Avatar_Privacy\\Exceptions\\Object_Factory_Exception' => __DIR__ . '/../..' . '/includes/avatar-privacy/exceptions/class-object-factory-exception.php',
+ 'Avatar_Privacy\\Exceptions\\PNG_Image_Exception' => __DIR__ . '/../..' . '/includes/avatar-privacy/exceptions/class-png-image-exception.php',
+ 'Avatar_Privacy\\Exceptions\\Part_Files_Not_Found_Exception' => __DIR__ . '/../..' . '/includes/avatar-privacy/exceptions/class-part-files-not-found-exception.php',
+ 'Avatar_Privacy\\Exceptions\\Upload_Handling_Exception' => __DIR__ . '/../..' . '/includes/avatar-privacy/exceptions/class-upload-handling-exception.php',
+ 'Avatar_Privacy\\Factory' => __DIR__ . '/../..' . '/includes/avatar-privacy/class-factory.php',
+ 'Avatar_Privacy\\Integrations\\BBPress_Integration' => __DIR__ . '/../..' . '/includes/avatar-privacy/integrations/class-bbpress-integration.php',
+ 'Avatar_Privacy\\Integrations\\BuddyPress_Integration' => __DIR__ . '/../..' . '/includes/avatar-privacy/integrations/class-buddypress-integration.php',
+ 'Avatar_Privacy\\Integrations\\Plugin_Integration' => __DIR__ . '/../..' . '/includes/avatar-privacy/integrations/class-plugin-integration.php',
+ 'Avatar_Privacy\\Integrations\\Simple_Author_Box_Integration' => __DIR__ . '/../..' . '/includes/avatar-privacy/integrations/class-simple-author-box-integration.php',
+ 'Avatar_Privacy\\Integrations\\Simple_Local_Avatars_Integration' => __DIR__ . '/../..' . '/includes/avatar-privacy/integrations/class-simple-local-avatars-integration.php',
+ 'Avatar_Privacy\\Integrations\\Simple_User_Avatar_Integration' => __DIR__ . '/../..' . '/includes/avatar-privacy/integrations/class-simple-user-avatar-integration.php',
+ 'Avatar_Privacy\\Integrations\\Theme_My_Login_Profiles_Integration' => __DIR__ . '/../..' . '/includes/avatar-privacy/integrations/class-theme-my-login-profiles-integration.php',
+ 'Avatar_Privacy\\Integrations\\Ultimate_Member_Integration' => __DIR__ . '/../..' . '/includes/avatar-privacy/integrations/class-ultimate-member-integration.php',
+ 'Avatar_Privacy\\Integrations\\WPDiscuz_Integration' => __DIR__ . '/../..' . '/includes/avatar-privacy/integrations/class-wpdiscuz-integration.php',
+ 'Avatar_Privacy\\Integrations\\WP_User_Manager_Integration' => __DIR__ . '/../..' . '/includes/avatar-privacy/integrations/class-wp-user-manager-integration.php',
+ 'Avatar_Privacy\\Requirements' => __DIR__ . '/../..' . '/includes/avatar-privacy/class-requirements.php',
+ 'Avatar_Privacy\\Tools\\HTML\\Dependencies' => __DIR__ . '/../..' . '/includes/avatar-privacy/tools/html/class-dependencies.php',
+ 'Avatar_Privacy\\Tools\\HTML\\User_Form' => __DIR__ . '/../..' . '/includes/avatar-privacy/tools/html/class-user-form.php',
+ 'Avatar_Privacy\\Tools\\Hasher' => __DIR__ . '/../..' . '/includes/avatar-privacy/tools/class-hasher.php',
+ 'Avatar_Privacy\\Tools\\Images\\Color' => __DIR__ . '/../..' . '/includes/avatar-privacy/tools/images/class-color.php',
+ 'Avatar_Privacy\\Tools\\Images\\Editor' => __DIR__ . '/../..' . '/includes/avatar-privacy/tools/images/class-editor.php',
+ 'Avatar_Privacy\\Tools\\Images\\Image_File' => __DIR__ . '/../..' . '/includes/avatar-privacy/tools/images/class-image-file.php',
+ 'Avatar_Privacy\\Tools\\Images\\Image_Stream' => __DIR__ . '/../..' . '/includes/avatar-privacy/tools/images/class-image-stream.php',
+ 'Avatar_Privacy\\Tools\\Images\\PNG' => __DIR__ . '/../..' . '/includes/avatar-privacy/tools/images/class-png.php',
+ 'Avatar_Privacy\\Tools\\Images\\SVG' => __DIR__ . '/../..' . '/includes/avatar-privacy/tools/images/class-svg.php',
+ 'Avatar_Privacy\\Tools\\Images\\Type' => __DIR__ . '/../..' . '/includes/avatar-privacy/tools/images/class-type.php',
+ 'Avatar_Privacy\\Tools\\Multisite' => __DIR__ . '/../..' . '/includes/avatar-privacy/tools/class-multisite.php',
+ 'Avatar_Privacy\\Tools\\Network\\Gravatar_Service' => __DIR__ . '/../..' . '/includes/avatar-privacy/tools/network/class-gravatar-service.php',
+ 'Avatar_Privacy\\Tools\\Network\\Remote_Image_Service' => __DIR__ . '/../..' . '/includes/avatar-privacy/tools/network/class-remote-image-service.php',
+ 'Avatar_Privacy\\Tools\\Number_Generator' => __DIR__ . '/../..' . '/includes/avatar-privacy/tools/class-number-generator.php',
+ 'Avatar_Privacy\\Tools\\Template' => __DIR__ . '/../..' . '/includes/avatar-privacy/tools/class-template.php',
+ 'Avatar_Privacy\\Upload_Handlers\\Custom_Default_Icon_Upload_Handler' => __DIR__ . '/../..' . '/includes/avatar-privacy/upload-handlers/class-custom-default-icon-upload-handler.php',
+ 'Avatar_Privacy\\Upload_Handlers\\UI\\File_Upload_Input' => __DIR__ . '/../..' . '/includes/avatar-privacy/upload-handlers/ui/class-file-upload-input.php',
+ 'Avatar_Privacy\\Upload_Handlers\\Upload_Handler' => __DIR__ . '/../..' . '/includes/avatar-privacy/upload-handlers/class-upload-handler.php',
+ 'Avatar_Privacy\\Upload_Handlers\\User_Avatar_Upload_Handler' => __DIR__ . '/../..' . '/includes/avatar-privacy/upload-handlers/class-user-avatar-upload-handler.php',
+ 'Avatar_Privacy\\Vendor\\Colors\\RandomColor' => __DIR__ . '/..' . '/mistic100/randomcolor/src/RandomColor.php',
+ 'Avatar_Privacy\\Vendor\\Dice\\Dice' => __DIR__ . '/..' . '/level-2/dice/Dice.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Canvas' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Canvas.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\CanvasContext' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/CanvasContext.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\ColorUtils' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/ColorUtils.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Matrix' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Matrix.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Png\\PngBuffer' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Png/PngBuffer.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Png\\PngEncoder' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Png/PngEncoder.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Png\\PngPalette' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Png/PngPalette.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Point' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Point.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Rasterization\\Edge' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Rasterization/Edge.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Rasterization\\EdgeIntersection' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Rasterization/EdgeIntersection.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Rasterization\\EdgeSuperSampleIntersection' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Rasterization/EdgeSuperSampleIntersection.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Rasterization\\EdgeTable' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Rasterization/EdgeTable.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Rasterization\\Layer' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Rasterization/Layer.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Rasterization\\LayerManager' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Rasterization/LayerManager.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Rasterization\\Rasterizer' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Rasterization/Rasterizer.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Rasterization\\SuperSampleBuffer' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Rasterization/SuperSampleBuffer.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Canvas\\Rasterization\\SuperSampleRange' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Rasterization/SuperSampleRange.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Color' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Color.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Identicon' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Identicon.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\IdenticonStyle' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/IdenticonStyle.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\AbstractRenderer' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/AbstractRenderer.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\ColorTheme' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/ColorTheme.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\IconGenerator' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/IconGenerator.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\ImagickRenderer' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/ImagickRenderer.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\InternalPngRenderer' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/InternalPngRenderer.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\Point' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/Point.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\Rectangle' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/Rectangle.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\RendererInterface' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/RendererInterface.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\SvgPath' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/SvgPath.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\SvgRenderer' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/SvgRenderer.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\Transform' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/Transform.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Rendering\\TriangleDirection' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/TriangleDirection.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Shapes\\Shape' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Shapes/Shape.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Shapes\\ShapeCategory' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Shapes/ShapeCategory.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Shapes\\ShapeDefinitions' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Shapes/ShapeDefinitions.php',
+ 'Avatar_Privacy\\Vendor\\Jdenticon\\Shapes\\ShapePosition' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Shapes/ShapePosition.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\Data_Storage\\Abstract_Cache' => __DIR__ . '/..' . '/mundschenk-at/wp-data-storage/src/class-abstract-cache.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\Data_Storage\\Cache' => __DIR__ . '/..' . '/mundschenk-at/wp-data-storage/src/class-cache.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\Data_Storage\\Network_Options' => __DIR__ . '/..' . '/mundschenk-at/wp-data-storage/src/class-network-options.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\Data_Storage\\Options' => __DIR__ . '/..' . '/mundschenk-at/wp-data-storage/src/class-options.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\Data_Storage\\Site_Transients' => __DIR__ . '/..' . '/mundschenk-at/wp-data-storage/src/class-site-transients.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\Data_Storage\\Transients' => __DIR__ . '/..' . '/mundschenk-at/wp-data-storage/src/class-transients.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Abstract_Control' => __DIR__ . '/..' . '/mundschenk-at/wp-settings-ui/src/ui/class-abstract-control.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Control' => __DIR__ . '/..' . '/mundschenk-at/wp-settings-ui/src/ui/class-control.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Control_Factory' => __DIR__ . '/..' . '/mundschenk-at/wp-settings-ui/src/ui/class-control-factory.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Controls\\Checkbox_Input' => __DIR__ . '/..' . '/mundschenk-at/wp-settings-ui/src/ui/controls/class-checkbox-input.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Controls\\Display_Text' => __DIR__ . '/..' . '/mundschenk-at/wp-settings-ui/src/ui/controls/class-display-text.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Controls\\Hidden_Input' => __DIR__ . '/..' . '/mundschenk-at/wp-settings-ui/src/ui/controls/class-hidden-input.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Controls\\Input' => __DIR__ . '/..' . '/mundschenk-at/wp-settings-ui/src/ui/controls/class-input.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Controls\\Number_Input' => __DIR__ . '/..' . '/mundschenk-at/wp-settings-ui/src/ui/controls/class-number-input.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Controls\\Select' => __DIR__ . '/..' . '/mundschenk-at/wp-settings-ui/src/ui/controls/class-select.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Controls\\Submit_Input' => __DIR__ . '/..' . '/mundschenk-at/wp-settings-ui/src/ui/controls/class-submit-input.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Controls\\Text_Input' => __DIR__ . '/..' . '/mundschenk-at/wp-settings-ui/src/ui/controls/class-text-input.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\UI\\Controls\\Textarea' => __DIR__ . '/..' . '/mundschenk-at/wp-settings-ui/src/ui/controls/class-textarea.php',
+ 'Avatar_Privacy\\Vendor\\Mundschenk\\WP_Requirements' => __DIR__ . '/..' . '/mundschenk-at/check-wp-requirements/class-wp-requirements.php',
+ 'Avatar_Privacy\\Vendor\\splitbrain\\RingIcon\\AbstractRingIcon' => __DIR__ . '/..' . '/splitbrain/php-ringicon/src/AbstractRingIcon.php',
+ 'Avatar_Privacy\\Vendor\\splitbrain\\RingIcon\\RingIcon' => __DIR__ . '/..' . '/splitbrain/php-ringicon/src/RingIcon.php',
+ 'Avatar_Privacy\\Vendor\\splitbrain\\RingIcon\\RingIconSVG' => __DIR__ . '/..' . '/splitbrain/php-ringicon/src/RingIconSVG.php',
+ );
+
+ public static function getInitializer(ClassLoaderAvatarPrivacy $loader)
+ {
+ return \Closure::bind(function () use ($loader) {
+ $loader->prefixLengthsPsr4 = ComposerStaticInitAvatarPrivacy::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInitAvatarPrivacy::$prefixDirsPsr4;
+ $loader->classMap = ComposerStaticInitAvatarPrivacy::$classMap;
+
+ }, null, ClassLoaderAvatarPrivacy::class);
+ }
+}
diff --git a/vendor-scoped/jdenticon/jdenticon/LICENSE b/vendor-scoped/jdenticon/jdenticon/LICENSE
new file mode 100644
index 0000000..cc1d6da
--- /dev/null
+++ b/vendor-scoped/jdenticon/jdenticon/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 Daniel Mester Pirttijärvi
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor-scoped/jdenticon/jdenticon/README.md b/vendor-scoped/jdenticon/jdenticon/README.md
new file mode 100644
index 0000000..4954e03
--- /dev/null
+++ b/vendor-scoped/jdenticon/jdenticon/README.md
@@ -0,0 +1,60 @@
+# [Jdenticon-php](https://jdenticon.com)
+PHP library for generating highly recognizable identicons.
+
+![Sample identicons](https://jdenticon.com/hosted/github-samples.png)
+
+[![Test Status](https://github.com/dmester/jdenticon-php/workflows/Tests/badge.svg)](https://github.com/dmester/jdenticon-php/actions)
+[![Total Downloads](https://poser.pugx.org/jdenticon/jdenticon/downloads)](https://packagist.org/packages/jdenticon/jdenticon)
+
+## Features
+Jdenticon-php is a PHP port of the JavaScript library [Jdenticon](https://github.com/dmester/jdenticon).
+
+* Renders identicons as PNG or SVG with no extension requirements.
+* Runs on PHP 5.3 and later.
+
+## Live demo
+https://jdenticon.com
+
+## Getting started
+Using Jdenticon is simple. Follow the steps below to integrate Jdenticon into your website.
+
+### 1. Install the Jdenticon Composer package
+The easiest way to get started using Jdenticon for PHP is to install the Jdenticon Composer package.
+
+```
+composer require jdenticon/jdenticon
+```
+
+### 2. Create a php file that will serve an icon
+Now create a file that you call icon.php and place it in the root of your application. Add the following content to the file.
+
+```PHP
+setValue($value);
+$icon->setSize($size);
+$icon->displayImage('png');
+```
+
+### 3. Use icon.php
+Open up your favourite browser and navigate to http://localhost:PORT/icon.php?size=100&value=anything.
+An identicon should be displayed. Try to change the url parameters to see the difference in the generated icon.
+
+## Other resources
+### API documentation
+For more usage examples and API documentation, please see:
+
+https://jdenticon.com/php-api.html
+
+## License
+Jdenticon-php is released under the [MIT license](https://github.com/dmester/jdenticon-php/blob/master/LICENSE).
diff --git a/vendor-scoped/jdenticon/jdenticon/src/Color.php b/vendor-scoped/jdenticon/jdenticon/src/Color.php
new file mode 100644
index 0000000..b8369a3
--- /dev/null
+++ b/vendor-scoped/jdenticon/jdenticon/src/Color.php
@@ -0,0 +1,673 @@
+r = $red;
+ $color->g = $green;
+ $color->b = $blue;
+ $color->a = $alpha;
+ return $color;
+ }
+ /**
+ * Creates a Color instance from HSL color parameters.
+ *
+ * @param float $hue Hue in the range [0, 1]
+ * @param float $saturation Saturation in the range [0, 1]
+ * @param float $lightness Lightness in the range [0, 1]
+ * @param float $alpha Alpha channel value in the range [0, 1].
+ */
+ public static function fromHsl($hue, $saturation, $lightness, $alpha = 1.0)
+ {
+ if ($hue < 0) {
+ $hue = 0;
+ }
+ if ($hue > 1) {
+ $hue = 1;
+ }
+ if ($saturation < 0) {
+ $saturation = 0;
+ }
+ if ($saturation > 1) {
+ $saturation = 1;
+ }
+ if ($lightness < 0) {
+ $lightness = 0;
+ }
+ if ($lightness > 1) {
+ $lightness = 1;
+ }
+ if ($alpha < 0) {
+ $alpha = 0;
+ }
+ if ($alpha > 1) {
+ $alpha = 1;
+ }
+ // Based on http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color
+ if ($saturation == 0) {
+ $value = (int) ($lightness * 255);
+ return self::fromRgb($value, $value, $value, (int) ($alpha * 255));
+ } else {
+ if ($lightness <= 0.5) {
+ $m2 = $lightness * ($saturation + 1);
+ } else {
+ $m2 = $lightness + $saturation - $lightness * $saturation;
+ }
+ $m1 = $lightness * 2 - $m2;
+ return self::fromRgb(self::hueToRgb($m1, $m2, $hue * 6 + 2), self::hueToRgb($m1, $m2, $hue * 6), self::hueToRgb($m1, $m2, $hue * 6 - 2), (int) ($alpha * 255));
+ }
+ }
+ /**
+ * Creates a Color> instance from HSL color parameters and will compensate
+ * the lightness for hues that appear to be darker than others.
+ *
+ * @param float $hue Hue in the range [0, 1].
+ * @param float $saturation Saturation in the range [0, 1].
+ * @param float $lightness Lightness in the range [0, 1].
+ * @param float $alpha Alpha channel value in the range [0, 1].
+ */
+ public static function fromHslCompensated($hue, $saturation, $lightness, $alpha = 1.0)
+ {
+ if ($hue < 0) {
+ $hue = 0;
+ }
+ if ($hue > 1) {
+ $hue = 1;
+ }
+ $lightnessCompensation = self::$lightnessCompensations[(int) ($hue * 6 + 0.5)];
+ // Adjust the input lightness relative to the compensation
+ $lightness = $lightness < 0.5 ? $lightness * $lightnessCompensation * 2 : $lightnessCompensation + ($lightness - 0.5) * (1 - $lightnessCompensation) * 2;
+ return self::fromHsl($hue, $saturation, $lightness, $alpha);
+ }
+ // Helper method for FromHsl
+ private static function hueToRgb($m1, $m2, $h)
+ {
+ if ($h < 0) {
+ $h = $h + 6;
+ } elseif ($h > 6) {
+ $h = $h - 6;
+ }
+ if ($h < 1) {
+ $r = $m1 + ($m2 - $m1) * $h;
+ } elseif ($h < 3) {
+ $r = $m2;
+ } elseif ($h < 4) {
+ $r = $m1 + ($m2 - $m1) * (4 - $h);
+ } else {
+ $r = $m1;
+ }
+ return (int) (255 * $r);
+ }
+ /**
+ * Gets the argb value of this color.
+ *
+ * @return int
+ */
+ public function toRgba()
+ {
+ return $this->r << 24 | $this->g << 16 | $this->b << 8 | $this->a;
+ }
+ /**
+ * Gets a hexadecimal representation of this color on the format #rrggbbaa.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return '#' . \bin2hex(\pack('N', $this->toRgba()));
+ }
+ /**
+ * Gets a hexadecimal representation of this color on the format #rrggbbaa.
+ *
+ * @return string
+ */
+ public function toHexString($length = 8)
+ {
+ if ($length === 8) {
+ return $this->__toString();
+ }
+ return '#' . \substr(\bin2hex(\pack('N', $this->toRgba())), 0, 6);
+ }
+ /**
+ * Tries to parse a value as a Color.
+ *
+ * @param mixed $value Value to parse.
+ * @throws InvalidArgumentException
+ * @return \Jdenticon\Color
+ */
+ public static function parse($value)
+ {
+ if ($value instanceof Color) {
+ return $value;
+ }
+ $value = \strtolower("{$value}");
+ if (\preg_match('/^#?[0-9a-f]{3,8}$/', $value) && self::parseHexColor($value, $result)) {
+ return $result;
+ }
+ if (\preg_match('/^rgba?\\(([^,]+),([^,]+),([^,]+)(?:,([^,]+))?\\)$/', $value, $matches) && self::parseRgbComponent($matches[1], $r) && self::parseRgbComponent($matches[2], $g) && self::parseRgbComponent($matches[3], $b) && self::parseAlpha(isset($matches[4]) ? $matches[4] : null, $a)) {
+ return self::fromRgb($r, $g, $b, (int) (255 * $a));
+ }
+ if (\preg_match('/^hsla?\\(([^,]+),([^,]+),([^,]+)(?:,([^,]+))?\\)$/', $value, $matches) && self::parseHue($matches[1], $h) && self::parsePercent($matches[2], $s) && self::parsePercent($matches[3], $l) && self::parseAlpha(isset($matches[4]) ? $matches[4] : null, $a)) {
+ return self::fromHsl($h, $s, $l, $a);
+ }
+ $result = self::parseNamedColor($value);
+ if ($result !== null) {
+ return $result;
+ }
+ throw new \InvalidArgumentException("Cannot parse '{$value}' as a color.");
+ }
+ /**
+ * Parses a percent value.
+ *
+ * @param string $input Input string.
+ * @param float $result Resulting value in range [0, 1].
+ *
+ * @return boolean
+ */
+ private static function parsePercent($input, &$result)
+ {
+ // Detect and remove percent sign
+ if (\preg_match('/^\\s*(\\d*(?:\\.\\d*)?)%\\s*$/', $input, $matches)) {
+ $result = \floatval($matches[1]) / 100;
+ if ($result < 0) {
+ $result = 0;
+ }
+ if ($result > 1) {
+ $result = 1;
+ }
+ return \true;
+ }
+ return \false;
+ }
+ /**
+ * Parses an alpha value.
+ *
+ * @param string $input Input string.
+ * @param float $result Resulting alpha in range [0, 1].
+ *
+ * @return boolean
+ */
+ private static function parseAlpha($input, &$result)
+ {
+ if ($input === null || $input === '') {
+ $result = 1;
+ return \true;
+ }
+ if (\preg_match('/^\\s*(\\d*(?:\\.\\d*)?)(%?)\\s*$/', $input, $matches)) {
+ $result = \floatval($matches[1]);
+ // Percentage
+ if ($matches[2] !== '') {
+ $result = $result / 100;
+ }
+ if ($result < 0) {
+ $result = 0;
+ }
+ if ($result > 1) {
+ $result = 1;
+ }
+ return \true;
+ }
+ return \false;
+ }
+ /**
+ * Parses an RGB component.
+ *
+ * @param string $input Input string.
+ * @param float $result Hue in range [0, 255].
+ *
+ * @return boolean
+ */
+ private static function parseRgbComponent($input, &$result)
+ {
+ if (\preg_match('/^\\s*(\\d*(?:\\.\\d*)?)(%?)\\s*$/', $input, $matches)) {
+ $result = \floatval($matches[1]);
+ if ($matches[2] === '%') {
+ $result = 255 * $result / 100;
+ }
+ $result = (int) $result;
+ if ($result < 0) {
+ $result = 0;
+ }
+ if ($result > 255) {
+ $result = 255;
+ }
+ return \true;
+ }
+ return \false;
+ }
+ /**
+ * Parses a hue component.
+ *
+ * @param string $input Input string.
+ * @param float $result Hue in range [0, 1].
+ *
+ * @return boolean
+ */
+ private static function parseHue($input, &$result)
+ {
+ if (\preg_match('/^\\s*(\\d*(?:\\.\\d*)?)(deg|grad|rad|turn|)\\s*$/', $input, $matches)) {
+ $result = \floatval($matches[1]);
+ // Percentage
+ switch ($matches[2]) {
+ case "grad":
+ // Gradians: range 0 - 400
+ $result = $result / 400;
+ break;
+ case "rad":
+ // Radians: range 0 - 2pi
+ $result = $result / \M_PI / 2;
+ break;
+ case "turn":
+ // Turns: range 0 - 1
+ $result = $result;
+ break;
+ default:
+ // Degree: range 0 - 360
+ $result = $result / 360;
+ break;
+ }
+ $result = \fmod($result, 1);
+ if ($result < 0) {
+ $result += 1;
+ }
+ return \true;
+ }
+ return \false;
+ }
+ /**
+ * Parses a hex color string.
+ *
+ * @param string $input Input string.
+ * @param float $result Hue in range [0, 1].
+ *
+ * @return boolean
+ */
+ private static function parseHexColor($input, &$result)
+ {
+ if ($input[0] === '#') {
+ $input = \substr($input, 1);
+ }
+ // intval does not support unsigned 32-bit integers
+ // so we need to parse large numbers stepwise
+ $numeric24bit = \intval(\substr($input, 0, 6), 16);
+ $alpha8bit = \intval(\substr($input, 6, 2), 16);
+ switch (\strlen($input)) {
+ case 3:
+ $result = self::fromRgb(($numeric24bit & 0xf00) >> 8 | ($numeric24bit & 0xf00) >> 4, ($numeric24bit & 0xf0) >> 4 | $numeric24bit & 0xf0, ($numeric24bit & 0xf) << 4 | $numeric24bit & 0xf);
+ return \true;
+ case 4:
+ $result = self::fromRgb(($numeric24bit & 0xf000) >> 12 | ($numeric24bit & 0xf000) >> 8, ($numeric24bit & 0xf00) >> 8 | ($numeric24bit & 0xf00) >> 4, ($numeric24bit & 0xf0) >> 4 | $numeric24bit & 0xf0, ($numeric24bit & 0xf) << 4 | $numeric24bit & 0xf);
+ return \true;
+ case 6:
+ $result = self::fromRgb(0xff & $numeric24bit >> 16, 0xff & $numeric24bit >> 8, 0xff & $numeric24bit);
+ return \true;
+ case 8:
+ $result = self::fromRgb(0xff & $numeric24bit >> 16, 0xff & $numeric24bit >> 8, 0xff & $numeric24bit, 0xff & $alpha8bit);
+ return \true;
+ }
+ return \false;
+ }
+ /**
+ * Looks up a named color to a Color instance.
+ *
+ * @param string $input Input string.
+ *
+ * @return \Jdenticon\Color
+ */
+ private static function parseNamedColor($input)
+ {
+ // Source: https://www.w3.org/TR/css-color-4/#named-colors
+ switch ($input) {
+ case 'aliceblue':
+ return self::fromRgb(240, 248, 255);
+ case 'antiquewhite':
+ return self::fromRgb(250, 235, 215);
+ case 'aqua':
+ return self::fromRgb(0, 255, 255);
+ case 'aquamarine':
+ return self::fromRgb(127, 255, 212);
+ case 'azure':
+ return self::fromRgb(240, 255, 255);
+ case 'beige':
+ return self::fromRgb(245, 245, 220);
+ case 'bisque':
+ return self::fromRgb(255, 228, 196);
+ case 'black':
+ return self::fromRgb(0, 0, 0);
+ case 'blanchedalmond':
+ return self::fromRgb(255, 235, 205);
+ case 'blue':
+ return self::fromRgb(0, 0, 255);
+ case 'blueviolet':
+ return self::fromRgb(138, 43, 226);
+ case 'brown':
+ return self::fromRgb(165, 42, 42);
+ case 'burlywood':
+ return self::fromRgb(222, 184, 135);
+ case 'cadetblue':
+ return self::fromRgb(95, 158, 160);
+ case 'chartreuse':
+ return self::fromRgb(127, 255, 0);
+ case 'chocolate':
+ return self::fromRgb(210, 105, 30);
+ case 'coral':
+ return self::fromRgb(255, 127, 80);
+ case 'cornflowerblue':
+ return self::fromRgb(100, 149, 237);
+ case 'cornsilk':
+ return self::fromRgb(255, 248, 220);
+ case 'crimson':
+ return self::fromRgb(220, 20, 60);
+ case 'cyan':
+ return self::fromRgb(0, 255, 255);
+ case 'darkblue':
+ return self::fromRgb(0, 0, 139);
+ case 'darkcyan':
+ return self::fromRgb(0, 139, 139);
+ case 'darkgoldenrod':
+ return self::fromRgb(184, 134, 11);
+ case 'darkgray':
+ return self::fromRgb(169, 169, 169);
+ case 'darkgreen':
+ return self::fromRgb(0, 100, 0);
+ case 'darkgrey':
+ return self::fromRgb(169, 169, 169);
+ case 'darkkhaki':
+ return self::fromRgb(189, 183, 107);
+ case 'darkmagenta':
+ return self::fromRgb(139, 0, 139);
+ case 'darkolivegreen':
+ return self::fromRgb(85, 107, 47);
+ case 'darkorange':
+ return self::fromRgb(255, 140, 0);
+ case 'darkorchid':
+ return self::fromRgb(153, 50, 204);
+ case 'darkred':
+ return self::fromRgb(139, 0, 0);
+ case 'darksalmon':
+ return self::fromRgb(233, 150, 122);
+ case 'darkseagreen':
+ return self::fromRgb(143, 188, 143);
+ case 'darkslateblue':
+ return self::fromRgb(72, 61, 139);
+ case 'darkslategray':
+ return self::fromRgb(47, 79, 79);
+ case 'darkslategrey':
+ return self::fromRgb(47, 79, 79);
+ case 'darkturquoise':
+ return self::fromRgb(0, 206, 209);
+ case 'darkviolet':
+ return self::fromRgb(148, 0, 211);
+ case 'deeppink':
+ return self::fromRgb(255, 20, 147);
+ case 'deepskyblue':
+ return self::fromRgb(0, 191, 255);
+ case 'dimgray':
+ return self::fromRgb(105, 105, 105);
+ case 'dimgrey':
+ return self::fromRgb(105, 105, 105);
+ case 'dodgerblue':
+ return self::fromRgb(30, 144, 255);
+ case 'firebrick':
+ return self::fromRgb(178, 34, 34);
+ case 'floralwhite':
+ return self::fromRgb(255, 250, 240);
+ case 'forestgreen':
+ return self::fromRgb(34, 139, 34);
+ case 'fuchsia':
+ return self::fromRgb(255, 0, 255);
+ case 'gainsboro':
+ return self::fromRgb(220, 220, 220);
+ case 'ghostwhite':
+ return self::fromRgb(248, 248, 255);
+ case 'gold':
+ return self::fromRgb(255, 215, 0);
+ case 'goldenrod':
+ return self::fromRgb(218, 165, 32);
+ case 'gray':
+ return self::fromRgb(128, 128, 128);
+ case 'green':
+ return self::fromRgb(0, 128, 0);
+ case 'greenyellow':
+ return self::fromRgb(173, 255, 47);
+ case 'grey':
+ return self::fromRgb(128, 128, 128);
+ case 'honeydew':
+ return self::fromRgb(240, 255, 240);
+ case 'hotpink':
+ return self::fromRgb(255, 105, 180);
+ case 'indianred':
+ return self::fromRgb(205, 92, 92);
+ case 'indigo':
+ return self::fromRgb(75, 0, 130);
+ case 'ivory':
+ return self::fromRgb(255, 255, 240);
+ case 'khaki':
+ return self::fromRgb(240, 230, 140);
+ case 'lavender':
+ return self::fromRgb(230, 230, 250);
+ case 'lavenderblush':
+ return self::fromRgb(255, 240, 245);
+ case 'lawngreen':
+ return self::fromRgb(124, 252, 0);
+ case 'lemonchiffon':
+ return self::fromRgb(255, 250, 205);
+ case 'lightblue':
+ return self::fromRgb(173, 216, 230);
+ case 'lightcoral':
+ return self::fromRgb(240, 128, 128);
+ case 'lightcyan':
+ return self::fromRgb(224, 255, 255);
+ case 'lightgoldenrodyellow':
+ return self::fromRgb(250, 250, 210);
+ case 'lightgray':
+ return self::fromRgb(211, 211, 211);
+ case 'lightgreen':
+ return self::fromRgb(144, 238, 144);
+ case 'lightgrey':
+ return self::fromRgb(211, 211, 211);
+ case 'lightpink':
+ return self::fromRgb(255, 182, 193);
+ case 'lightsalmon':
+ return self::fromRgb(255, 160, 122);
+ case 'lightseagreen':
+ return self::fromRgb(32, 178, 170);
+ case 'lightskyblue':
+ return self::fromRgb(135, 206, 250);
+ case 'lightslategray':
+ return self::fromRgb(119, 136, 153);
+ case 'lightslategrey':
+ return self::fromRgb(119, 136, 153);
+ case 'lightsteelblue':
+ return self::fromRgb(176, 196, 222);
+ case 'lightyellow':
+ return self::fromRgb(255, 255, 224);
+ case 'lime':
+ return self::fromRgb(0, 255, 0);
+ case 'limegreen':
+ return self::fromRgb(50, 205, 50);
+ case 'linen':
+ return self::fromRgb(250, 240, 230);
+ case 'magenta':
+ return self::fromRgb(255, 0, 255);
+ case 'maroon':
+ return self::fromRgb(128, 0, 0);
+ case 'mediumaquamarine':
+ return self::fromRgb(102, 205, 170);
+ case 'mediumblue':
+ return self::fromRgb(0, 0, 205);
+ case 'mediumorchid':
+ return self::fromRgb(186, 85, 211);
+ case 'mediumpurple':
+ return self::fromRgb(147, 112, 219);
+ case 'mediumseagreen':
+ return self::fromRgb(60, 179, 113);
+ case 'mediumslateblue':
+ return self::fromRgb(123, 104, 238);
+ case 'mediumspringgreen':
+ return self::fromRgb(0, 250, 154);
+ case 'mediumturquoise':
+ return self::fromRgb(72, 209, 204);
+ case 'mediumvioletred':
+ return self::fromRgb(199, 21, 133);
+ case 'midnightblue':
+ return self::fromRgb(25, 25, 112);
+ case 'mintcream':
+ return self::fromRgb(245, 255, 250);
+ case 'mistyrose':
+ return self::fromRgb(255, 228, 225);
+ case 'moccasin':
+ return self::fromRgb(255, 228, 181);
+ case 'navajowhite':
+ return self::fromRgb(255, 222, 173);
+ case 'navy':
+ return self::fromRgb(0, 0, 128);
+ case 'oldlace':
+ return self::fromRgb(253, 245, 230);
+ case 'olive':
+ return self::fromRgb(128, 128, 0);
+ case 'olivedrab':
+ return self::fromRgb(107, 142, 35);
+ case 'orange':
+ return self::fromRgb(255, 165, 0);
+ case 'orangered':
+ return self::fromRgb(255, 69, 0);
+ case 'orchid':
+ return self::fromRgb(218, 112, 214);
+ case 'palegoldenrod':
+ return self::fromRgb(238, 232, 170);
+ case 'palegreen':
+ return self::fromRgb(152, 251, 152);
+ case 'paleturquoise':
+ return self::fromRgb(175, 238, 238);
+ case 'palevioletred':
+ return self::fromRgb(219, 112, 147);
+ case 'papayawhip':
+ return self::fromRgb(255, 239, 213);
+ case 'peachpuff':
+ return self::fromRgb(255, 218, 185);
+ case 'peru':
+ return self::fromRgb(205, 133, 63);
+ case 'pink':
+ return self::fromRgb(255, 192, 203);
+ case 'plum':
+ return self::fromRgb(221, 160, 221);
+ case 'powderblue':
+ return self::fromRgb(176, 224, 230);
+ case 'purple':
+ return self::fromRgb(128, 0, 128);
+ case 'rebeccapurple':
+ return self::fromRgb(102, 51, 153);
+ case 'red':
+ return self::fromRgb(255, 0, 0);
+ case 'rosybrown':
+ return self::fromRgb(188, 143, 143);
+ case 'royalblue':
+ return self::fromRgb(65, 105, 225);
+ case 'saddlebrown':
+ return self::fromRgb(139, 69, 19);
+ case 'salmon':
+ return self::fromRgb(250, 128, 114);
+ case 'sandybrown':
+ return self::fromRgb(244, 164, 96);
+ case 'seagreen':
+ return self::fromRgb(46, 139, 87);
+ case 'seashell':
+ return self::fromRgb(255, 245, 238);
+ case 'sienna':
+ return self::fromRgb(160, 82, 45);
+ case 'silver':
+ return self::fromRgb(192, 192, 192);
+ case 'skyblue':
+ return self::fromRgb(135, 206, 235);
+ case 'slateblue':
+ return self::fromRgb(106, 90, 205);
+ case 'slategray':
+ return self::fromRgb(112, 128, 144);
+ case 'slategrey':
+ return self::fromRgb(112, 128, 144);
+ case 'snow':
+ return self::fromRgb(255, 250, 250);
+ case 'springgreen':
+ return self::fromRgb(0, 255, 127);
+ case 'steelblue':
+ return self::fromRgb(70, 130, 180);
+ case 'tan':
+ return self::fromRgb(210, 180, 140);
+ case 'teal':
+ return self::fromRgb(0, 128, 128);
+ case 'thistle':
+ return self::fromRgb(216, 191, 216);
+ case 'tomato':
+ return self::fromRgb(255, 99, 71);
+ case 'transparent':
+ return self::fromRgb(0, 0, 0, 0);
+ case 'turquoise':
+ return self::fromRgb(64, 224, 208);
+ case 'violet':
+ return self::fromRgb(238, 130, 238);
+ case 'wheat':
+ return self::fromRgb(245, 222, 179);
+ case 'white':
+ return self::fromRgb(255, 255, 255);
+ case 'whitesmoke':
+ return self::fromRgb(245, 245, 245);
+ case 'yellow':
+ return self::fromRgb(255, 255, 0);
+ case 'yellowgreen':
+ return self::fromRgb(154, 205, 50);
+ default:
+ return null;
+ }
+ }
+}
diff --git a/vendor-scoped/jdenticon/jdenticon/src/Identicon.php b/vendor-scoped/jdenticon/jdenticon/src/Identicon.php
new file mode 100644
index 0000000..8116cf3
--- /dev/null
+++ b/vendor-scoped/jdenticon/jdenticon/src/Identicon.php
@@ -0,0 +1,421 @@
+iconGenerator = IconGenerator::getDefaultGenerator();
+ if ($options !== null) {
+ $this->setOptions($options);
+ }
+ if ($this->style === null) {
+ $this->style = new IdenticonStyle();
+ }
+ }
+ /**
+ * Creates an Identicon instance from a specified hash.
+ *
+ * @param string $hash A binary string containing the hash that will be used
+ * as base for this icon. The hash must contain at least 6 bytes.
+ * @param int $size The size of the icon in pixels (the icon is quadratic).
+ * @return \Jdenticon\Identicon
+ */
+ public static function fromHash($hash, $size)
+ {
+ return new Identicon(array('hash' => $hash, 'size' => $size));
+ }
+ /**
+ * Creates an Identicon instance from a specified value.
+ *
+ * @param mixed $value The value that will be used as base for this icon.
+ * The value will be converted to a UTF8 encoded string and then hashed
+ * using SHA1.
+ * @param int $size The size of the icon in pixels (the icon is quadratic).
+ * @return \Jdenticon\Identicon
+ */
+ public static function fromValue($value, $size)
+ {
+ return new Identicon(array('value' => $value, 'size' => $size));
+ }
+ /**
+ * Gets an associative array of all options of this identicon.
+ *
+ * @return array
+ */
+ public function getOptions()
+ {
+ $options = array();
+ if ($this->valueSet) {
+ $options['value'] = $this->getValue();
+ } elseif ($this->hash !== null) {
+ $options['hash'] = $this->getHash();
+ }
+ $options['size'] = $this->getSize();
+ $options['style'] = $this->getStyle()->getOptions();
+ if ($this->enableImageMagick !== null) {
+ $options['enableImageMagick'] = $this->getEnableImageMagick();
+ }
+ if ($this->iconGenerator !== IconGenerator::getDefaultGenerator()) {
+ $options['iconGenerator'] = $this->getIconGenerator();
+ }
+ return $options;
+ }
+ /**
+ * Sets options in this identicon by specifying an associative array of
+ * option values.
+ *
+ * @param array $options Options to set.
+ * @return self
+ */
+ public function setOptions(array $options)
+ {
+ foreach ($options as $key => $value) {
+ $this->__set($key, $value);
+ }
+ return $this;
+ }
+ public function __get($name)
+ {
+ switch (\strtolower($name)) {
+ case 'size':
+ return $this->getSize();
+ case 'hash':
+ return $this->getHash();
+ case 'value':
+ return $this->getValue();
+ case 'style':
+ return $this->getStyle();
+ case 'icongenerator':
+ return $this->getIconGenerator();
+ case 'enableimagemagick':
+ return $this->getEnableImageMagick();
+ default:
+ throw new \InvalidArgumentException("Unknown Identicon option '{$name}'.");
+ }
+ }
+ public function __set($name, $value)
+ {
+ switch (\strtolower($name)) {
+ case 'size':
+ $this->setSize($value);
+ break;
+ case 'hash':
+ $this->setHash($value);
+ break;
+ case 'value':
+ $this->setValue($value);
+ break;
+ case 'style':
+ $this->setStyle($value);
+ break;
+ case 'icongenerator':
+ $this->setIconGenerator($value);
+ break;
+ case 'enableimagemagick':
+ $this->setEnableImageMagick($value);
+ break;
+ default:
+ throw new \InvalidArgumentException("Unknown Identicon option '{$name}'.");
+ }
+ }
+ /**
+ * Gets the size of the icon in pixels.
+ */
+ public function getSize()
+ {
+ return $this->size;
+ }
+ /**
+ * Sets the size of this icon in pixels.
+ *
+ * @param int|float|double $size The width and height of the icon.
+ */
+ public function setSize($size)
+ {
+ if (!\is_numeric($size) || $size < 1) {
+ throw new \InvalidArgumentException("An invalid identicon size was specified. " . "A numeric value >= 1 was expected. Specified value: {$size}.");
+ }
+ $this->size = (int) $size;
+ }
+ /**
+ * Gets the size of the icon in pixels.
+ */
+ public function getEnableImageMagick()
+ {
+ // Enable ImageMagick on PHP < 7. On PHP 7 the performance increase
+ // is not as obvious as on PHP 5. Since the ImageMagick renderer has a
+ // lot of quirks, we don't want to use it unless really needed.
+ if ($this->enableImageMagick === null) {
+ return \PHP_MAJOR_VERSION < 7 && \extension_loaded('imagick');
+ }
+ return $this->enableImageMagick;
+ }
+ /**
+ * Sets whether ImageMagick should be used to generate PNG icons.
+ *
+ * @param bool $enable true to enable ImageMagick.
+ */
+ public function setEnableImageMagick($enable)
+ {
+ if (!\is_bool($enable)) {
+ throw new \InvalidArgumentException("enableImageMagick can only assume boolean values. Specified value: {$enable}.");
+ }
+ // Verify that the Imagick extension is installed
+ if ($enable && !\extension_loaded('imagick')) {
+ throw new \Exception('Failed to enable ImageMagick. ' . 'The Imagick PHP extension was not found on this system.');
+ }
+ $this->enableImageMagick = $enable;
+ }
+ /**
+ * Gets the {@see IconGenerator} used to generate icons.
+ *
+ * @return \Jdenticon\Rendering\IconGenerator
+ */
+ public function getIconGenerator()
+ {
+ return $this->iconGenerator;
+ }
+ /**
+ * Sets the {@see IconGenerator} used to generate icons.
+ *
+ * @param \Jdenticon\Rendering\IconGenerator $iconGenerator Icon generator
+ * that will render the shapes of the identicon.
+ * @return \Jdenticon\Identicon
+ */
+ public function setIconGenerator(IconGenerator $iconGenerator)
+ {
+ if ($iconGenerator === null) {
+ $iconGenerator = IconGenerator::getDefaultGenerator();
+ }
+ $this->iconGenerator = $iconGenerator;
+ return $this;
+ }
+ /**
+ * Gets or sets the style of the icon.
+ *
+ * @return \Jdenticon\IdenticonStyle
+ */
+ public function getStyle()
+ {
+ return $this->style;
+ }
+ /**
+ * Gets or sets the style of the icon.
+ *
+ * @param array|\Jdenticon\IdenticonStyle $style The new style of the icon.
+ * NULL will revert the identicon to use the default style.
+ * @return self
+ */
+ public function setStyle($style)
+ {
+ if ($style == null) {
+ $this->style = new IdenticonStyle();
+ } elseif ($style instanceof IdenticonStyle) {
+ $this->style = $style;
+ } elseif (\is_array($style)) {
+ $this->style = new IdenticonStyle($style);
+ } else {
+ throw new \InvalidArgumentException("Invalid indenticon style was specified. " . "Allowed values are IdenticonStyle instances and associative " . "arrays containing IdenticonStyle options.");
+ }
+ return $this;
+ }
+ /**
+ * Gets a binary string containing the hash that is used as base for this
+ * icon.
+ */
+ public function getHash()
+ {
+ return $this->hash;
+ }
+ /**
+ * Sets a binary string containing the hash that is used as base for this
+ * icon. The string should contain at least 6 bytes.
+ *
+ * @param string $hash Binary string containing the hash.
+ */
+ public function setHash($hash)
+ {
+ if (!\is_string($hash)) {
+ throw new \InvalidArgumentException('An invalid $hash was passed to Identicon. ' . 'A binary string was expected.');
+ }
+ if (\strlen($hash) < 6) {
+ throw new \InvalidArgumentException('An invalid $hash was passed to Identicon. ' . 'The hash was expected to contain at least 6 bytes.');
+ }
+ $this->hash = $hash;
+ $this->value = null;
+ $this->valueSet = \false;
+ return $this;
+ }
+ /**
+ * Gets a binary string containing the hash that is used as base for this
+ * icon.
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+ /**
+ * Sets a value that will be used as base for this icon. The value will
+ * be converted to a string and then hashed using SHA1.
+ *
+ * @param mixed $value Value that will be hashed.
+ */
+ public function setValue($value)
+ {
+ $this->hash = \sha1("{$value}");
+ $this->value = $value;
+ $this->valueSet = \true;
+ return $this;
+ }
+ /**
+ * Gets the bounds of the icon excluding its padding.
+ *
+ * @return \Jdenticon\Rendering\Rectangle
+ */
+ public function getIconBounds()
+ {
+ // Round padding to nearest integer
+ $padding = (int) ($this->style->getPadding() * $this->size + 0.5);
+ return new Rectangle($padding, $padding, $this->size - $padding * 2, $this->size - $padding * 2);
+ }
+ private function getRenderer($imageFormat)
+ {
+ switch (\strtolower($imageFormat)) {
+ case 'svg':
+ return new SvgRenderer($this->size, $this->size);
+ default:
+ return $this->getEnableImageMagick() ? new ImagickRenderer($this->size, $this->size) : new InternalPngRenderer($this->size, $this->size);
+ }
+ }
+ /**
+ * Draws this icon using a specified renderer.
+ *
+ * This method is only intended for usage with custom renderers. A custom
+ * renderer could as an example render an Identicon in a file format not
+ * natively supported by Jdenticon. To implement a new file format,
+ * implement {@see \Jdenticon\Rendering\RendererInterface}.
+ *
+ * @param \Jdenticon\Rendering\RendererInterface $renderer The renderer used
+ * to render this icon.
+ * @param \Jdenticon\Rendering\Rectangle $rect The bounds of the rendered
+ * icon. No padding will be applied to the rectangle. If the parameter
+ * is omitted, the rectangle is calculated from the current icon
+ * size and padding.
+ */
+ public function draw(\Avatar_Privacy\Vendor\Jdenticon\Rendering\RendererInterface $renderer, \Avatar_Privacy\Vendor\Jdenticon\Rendering\Rectangle $rect = null)
+ {
+ if ($rect === null) {
+ $rect = $this->getIconBounds();
+ }
+ $this->iconGenerator->generate($renderer, $rect, $this->style, $this->hash);
+ }
+ /**
+ * Renders the icon directly to the page output.
+ *
+ * The method will set the 'Content-Type' HTTP header. You are recommended
+ * to set an appropriate 'Cache-Control' header before calling this method
+ * to ensure the icon is cached client side.
+ *
+ * @param string $imageFormat The image format of the output.
+ * Supported values are 'png' and 'svg'.
+ */
+ public function displayImage($imageFormat = 'png')
+ {
+ $renderer = $this->getRenderer($imageFormat);
+ $this->draw($renderer, $this->getIconBounds());
+ $mimeType = $renderer->getMimeType();
+ $data = $renderer->getData();
+ \header("Content-Type: {$mimeType}");
+ echo $data;
+ }
+ /**
+ * Renders the icon to a binary string.
+ *
+ * @param string $imageFormat The image format of the output string.
+ * Supported values are 'png' and 'svg'.
+ * @return string
+ */
+ public function getImageData($imageFormat = 'png')
+ {
+ $renderer = $this->getRenderer($imageFormat);
+ $this->draw($renderer, $this->getIconBounds());
+ return $renderer->getData();
+ }
+ /**
+ * Renders the icon as a data URI. It is recommended to avoid using this
+ * method unless really necessary, since it will effectively disable client
+ * caching of generated icons, and will also cause the same icon to be
+ * rendered multiple times, when used multiple times on a single page.
+ *
+ * @param string $imageFormat The image format of the data URI.
+ * Supported values are 'png' and 'svg'.
+ * @return string
+ */
+ public function getImageDataUri($imageFormat = 'png')
+ {
+ $renderer = $this->getRenderer($imageFormat);
+ $this->draw($renderer, $this->getIconBounds());
+ $mimeType = $renderer->getMimeType();
+ $base64 = \base64_encode($renderer->getData());
+ return "data:{$mimeType};base64,{$base64}";
+ }
+}
diff --git a/vendor-scoped/jdenticon/jdenticon/src/IdenticonStyle.php b/vendor-scoped/jdenticon/jdenticon/src/IdenticonStyle.php
new file mode 100644
index 0000000..781cba5
--- /dev/null
+++ b/vendor-scoped/jdenticon/jdenticon/src/IdenticonStyle.php
@@ -0,0 +1,384 @@
+backgroundColor = self::getDefaultBackgroundColor();
+ $this->padding = self::getDefaultPadding();
+ $this->colorSaturation = self::getDefaultColorSaturation();
+ $this->grayscaleSaturation = self::getDefaultGrayscaleSaturation();
+ $this->colorLightness = self::getDefaultColorLightness();
+ $this->grayscaleLightness = self::getDefaultGrayscaleLightness();
+ if ($options !== null) {
+ $this->setOptions($options);
+ }
+ }
+ /**
+ * Gets an associative array of all options of this style.
+ *
+ * @return array
+ */
+ public function getOptions()
+ {
+ $options = array();
+ $options['backgroundColor'] = $this->getBackgroundColor()->__toString();
+ $options['padding'] = $this->getPadding();
+ $options['colorSaturation'] = $this->getColorSaturation();
+ $options['grayscaleSaturation'] = $this->getGrayscaleSaturation();
+ $options['colorLightness'] = $this->getColorLightness();
+ $options['grayscaleLightness'] = $this->getGrayscaleLightness();
+ if ($this->hues !== null) {
+ $options['hues'] = $this->getHues();
+ }
+ return $options;
+ }
+ /**
+ * Sets options in this style by specifying an associative array of option
+ * values.
+ *
+ * @param array $options Options to set.
+ * @return self
+ */
+ public function setOptions(array $options)
+ {
+ foreach ($options as $key => $value) {
+ $this->__set($key, $value);
+ }
+ return $this;
+ }
+ public function __get($name)
+ {
+ switch (\strtolower($name)) {
+ case 'backgroundcolor':
+ return $this->getBackgroundColor();
+ case 'padding':
+ return $this->getPadding();
+ case 'colorsaturation':
+ return $this->getColorSaturation();
+ case 'grayscalesaturation':
+ return $this->getGrayscaleSaturation();
+ case 'colorlightness':
+ return $this->getColorLightness();
+ case 'grayscalelightness':
+ return $this->getGrayscaleLightness();
+ case 'hues':
+ return $this->getHues();
+ default:
+ throw new \InvalidArgumentException("Unknown IdenticonStyle option '{$name}'.");
+ }
+ }
+ public function __set($name, $value)
+ {
+ switch (\strtolower($name)) {
+ case 'backgroundcolor':
+ $this->setBackgroundColor($value);
+ break;
+ case 'padding':
+ $this->setPadding($value);
+ break;
+ case 'colorsaturation':
+ $this->setColorSaturation($value);
+ break;
+ case 'grayscalesaturation':
+ $this->setGrayscaleSaturation($value);
+ break;
+ case 'colorlightness':
+ $this->setColorLightness($value);
+ break;
+ case 'grayscalelightness':
+ $this->setGrayscaleLightness($value);
+ break;
+ case 'hues':
+ $this->setHues($value);
+ break;
+ default:
+ throw new \InvalidArgumentException("Unknown IdenticonStyle option '{$name}'.");
+ }
+ }
+ /**
+ * Normalizes a hue to the first turn [0, 360).
+ *
+ * @param mixed $hue
+ * @return integer
+ */
+ private static function normalizeHue($hue)
+ {
+ if (!\is_numeric($hue)) {
+ throw new \InvalidArgumentException("'{$hue}' is not a valid hue.");
+ }
+ $hue = $hue % 360;
+ if ($hue < 0) {
+ $hue += 360;
+ }
+ return $hue;
+ }
+ /**
+ * Gets an array of allowed hues, or null if there are no restrictions.
+ *
+ * @return array(int)|null
+ */
+ public function getHues()
+ {
+ return $this->hues;
+ }
+ /**
+ * Sets the allowed hues of generated icons.
+ *
+ * @param array(integer)|integer|null $value A hue specified in degrees,
+ * or an array of hues specified in degrees. If set to null, the hue
+ * list is cleared.
+ * @return self
+ */
+ public function setHues($value)
+ {
+ $hues = array();
+ if ($value !== null) {
+ if (\is_array($value)) {
+ foreach ($value as $hue) {
+ $hues[] = self::normalizeHue($hue);
+ }
+ } else {
+ $hues[] = self::normalizeHue($value);
+ }
+ }
+ $this->hues = empty($hues) ? null : $hues;
+ return $this;
+ }
+ /**
+ * Gets the padding of an icon in percents in the range [0.0, 0.4].
+ *
+ * @return float
+ */
+ public function getPadding()
+ {
+ return $this->padding;
+ }
+ /**
+ * Sets the padding of an icon in percents.
+ *
+ * @param float $value New padding in the range [0.0, 0.4].
+ * @return self
+ */
+ public function setPadding($value)
+ {
+ if (!\is_numeric($value) || $value < 0 || $value > 0.4) {
+ throw new \InvalidArgumentException("Padding '{$value}' out of range. " . "Values in the range [0.0, 0.4] are allowed.");
+ }
+ $this->padding = (float) $value;
+ return $this;
+ }
+ /**
+ * Gets the color of the identicon background.
+ *
+ * @return \Jdenticon\Color
+ */
+ public function getBackgroundColor()
+ {
+ return $this->backgroundColor;
+ }
+ /**
+ * Sets the color of the identicon background.
+ *
+ * @param \Jdenticon\Color|string $value New background color.
+ * @return \Jdenticon\IdenticonStyle
+ */
+ public function setBackgroundColor($value)
+ {
+ if ($value instanceof Color) {
+ $this->backgroundColor = $value;
+ } else {
+ $this->backgroundColor = Color::parse($value);
+ }
+ return $this;
+ }
+ /**
+ * Gets the saturation of the originally grayscale identicon shapes.
+ *
+ * @return float Saturation in the range [0.0, 1.0].
+ */
+ public function getGrayscaleSaturation()
+ {
+ return $this->grayscaleSaturation;
+ }
+ /**
+ * Sets the saturation of the originally grayscale identicon shapes.
+ *
+ * @param $value float Saturation in the range [0.0, 1.0].
+ * @return self
+ */
+ public function setGrayscaleSaturation($value)
+ {
+ if (!\is_numeric($value) || $value < 0 || $value > 1) {
+ throw new \InvalidArgumentException("The grayscale saturation was invalid. " . "Only values in the range [0.0, 1.0] are allowed.");
+ }
+ $this->grayscaleSaturation = (float) $value;
+ return $this;
+ }
+ /**
+ * Gets the saturation of the colored identicon shapes.
+ *
+ * @return float Saturation in the range [0.0, 1.0].
+ */
+ public function getColorSaturation()
+ {
+ return $this->colorSaturation;
+ }
+ /**
+ * Sets the saturation of the colored identicon shapes.
+ *
+ * @param $value float Saturation in the range [0.0, 1.0].
+ * @return self
+ */
+ public function setColorSaturation($value)
+ {
+ if (!\is_numeric($value) || $value < 0 || $value > 1) {
+ throw new \InvalidArgumentException("The color saturation was invalid. " . "Only values in the range [0.0, 1.0] are allowed.");
+ }
+ $this->colorSaturation = (float) $value;
+ return $this;
+ }
+ /**
+ * Gets the value of the ColorLightness property.
+ *
+ * @return array(float, float)
+ */
+ public function getColorLightness()
+ {
+ return $this->colorLightness;
+ }
+ /**
+ * Sets the value of the ColorLightness property.
+ *
+ * @param $value array(float, float) Lightness range.
+ * @return self
+ */
+ public function setColorLightness($value)
+ {
+ if (!\is_array($value) || !\array_key_exists(0, $value) || !\array_key_exists(1, $value) || !\is_numeric($value[0]) || !\is_numeric($value[1]) || $value[0] < 0 || $value[0] > 1 || $value[1] < 0 || $value[1] > 1) {
+ throw new \InvalidArgumentException("The value passed to setColorLightness was invalid. " . "Please check the documentation.");
+ }
+ $this->colorLightness = array((float) $value[0], (float) $value[1]);
+ return $this;
+ }
+ /**
+ * Gets the value of the GrayscaleLightness property.
+ *
+ * @return array(float, float)
+ */
+ public function getGrayscaleLightness()
+ {
+ return $this->grayscaleLightness;
+ }
+ /**
+ * Sets the value of the GrayscaleLightness property.
+ *
+ * @param $value array(float, float) Lightness range.
+ * @return self
+ */
+ public function setGrayscaleLightness($value)
+ {
+ if (!\is_array($value) || !\array_key_exists(0, $value) || !\array_key_exists(1, $value) || !\is_numeric($value[0]) || !\is_numeric($value[1]) || $value[0] < 0 || $value[0] > 1 || $value[1] < 0 || $value[1] > 1) {
+ throw new \InvalidArgumentException("The value passed to setGrayscaleLightness was invalid. " . "Please check the documentation.");
+ }
+ $this->grayscaleLightness = array((float) $value[0], (float) $value[1]);
+ return $this;
+ }
+ /**
+ * Gets the default value of the BackgroundColor property. Resolves to transparent.
+ *
+ * @return \Jdenticon\Color
+ */
+ public static function getDefaultBackgroundColor()
+ {
+ return Color::fromRgb(255, 255, 255, 255);
+ }
+ /**
+ * Gets the default value of the Padding property. Resolves to 0.08.
+ *
+ * @return float
+ */
+ public static function getDefaultPadding()
+ {
+ return 0.08;
+ }
+ /**
+ * Gets the default value of the ColorSaturation property. Resolves to 0.5.
+ *
+ * @return float
+ */
+ public static function getDefaultColorSaturation()
+ {
+ return 0.5;
+ }
+ /**
+ * Gets the default value of the GrayscaleSaturation property. Resolves to 0.
+ *
+ * @return float
+ */
+ public static function getDefaultGrayscaleSaturation()
+ {
+ return 0;
+ }
+ /**
+ * Gets the default value of the ColorLightness property. Resolves to [0.4, 0.8].
+ *
+ * @return array
+ */
+ public static function getDefaultColorLightness()
+ {
+ return array(0.4, 0.8);
+ }
+ /**
+ * Gets the default value of the GrayscaleLightness property. Resolves to [0.3, 0.9].
+ *
+ * @return array
+ */
+ public static function getDefaultGrayscaleLightness()
+ {
+ return array(0.3, 0.9);
+ }
+}
diff --git a/vendor-scoped/jdenticon/jdenticon/src/Rendering/AbstractRenderer.php b/vendor-scoped/jdenticon/jdenticon/src/Rendering/AbstractRenderer.php
new file mode 100644
index 0000000..42fb82e
--- /dev/null
+++ b/vendor-scoped/jdenticon/jdenticon/src/Rendering/AbstractRenderer.php
@@ -0,0 +1,174 @@
+transform = Transform::getEmpty();
+ }
+ /**
+ * Sets the current transform that will be applied on all coordinates before
+ * being rendered to the target image.
+ *
+ * @param \Jdenticon\Rendering\Transform $transform The transform to set.
+ * If NULL is specified any existing transform is removed.
+ */
+ public function setTransform(\Avatar_Privacy\Vendor\Jdenticon\Rendering\Transform $transform)
+ {
+ $this->transform = $transform === null ? Transform::getEmpty() : $transform;
+ }
+ /**
+ * Gets the current transform that will be applied on all coordinates before
+ * being rendered to the target image.
+ *
+ * @return \Jdenticon\Rendering\Transform
+ */
+ public function getTransform()
+ {
+ return $this->transform;
+ }
+ /**
+ * Adds a polygon without translating its coordinates.
+ *
+ * @param array $points An array of the points that the polygon consists of.
+ */
+ protected abstract function addPolygonNoTransform($points);
+ /**
+ * Adds a circle without translating its coordinates.
+ *
+ * @param float $x The x-coordinate of the bounding rectangle
+ * upper-left corner.
+ * @param float $y The y-coordinate of the bounding rectangle
+ * upper-left corner.
+ * @param float $size The size of the bounding rectangle.
+ * @param bool $counterClockwise If true the circle will be drawn
+ * counter clockwise.
+ */
+ protected abstract function addCircleNoTransform($x, $y, $size, $counterClockwise);
+ /**
+ * Sets the background color of the image.
+ *
+ * @param \Jdenticon\Color $color The image background color.
+ */
+ public function setBackgroundColor(\Avatar_Privacy\Vendor\Jdenticon\Color $color)
+ {
+ $this->backgroundColor = $color;
+ }
+ /**
+ * Gets the background color of the image.
+ *
+ * @return \Jdenticon\Color
+ */
+ public function getBackgroundColor()
+ {
+ return $this->backgroundColor;
+ }
+ private function addPolygonCore(array $points, $invert)
+ {
+ $transformedPoints = array();
+ foreach ($points as $point) {
+ $transformedPoints[] = $this->transform->transformPoint($point->x, $point->y);
+ }
+ if ($invert) {
+ $transformedPoints = \array_reverse($transformedPoints);
+ }
+ //var_dump($transformedPoints);
+ $this->addPolygonNoTransform($transformedPoints);
+ }
+ /**
+ * Adds a rectangle to the image.
+ *
+ * @param float $x The x-coordinate of the rectangle upper-left corner.
+ * @param float $y The y-coordinate of the rectangle upper-left corner.
+ * @param float $width The width of the rectangle.
+ * @param float $height The height of the rectangle.
+ * @param bool $invert If true the area of the rectangle will be removed
+ * from the filled area.
+ */
+ public function addRectangle($x, $y, $width, $height, $invert = \false)
+ {
+ $this->addPolygonCore(array(new Point($x, $y), new Point($x + $width, $y), new Point($x + $width, $y + $height), new Point($x, $y + $height)), $invert);
+ }
+ /**
+ * Adds a circle to the image.
+ *
+ * @param float $x The x-coordinate of the bounding rectangle
+ * upper-left corner.
+ * @param float $y The y-coordinate of the bounding rectangle
+ * upper-left corner.
+ * @param float $size The size of the bounding rectangle.
+ * @param bool $invert If true the area of the circle will be removed
+ * from the filled area.
+ */
+ public function addCircle($x, $y, $size, $invert = \false)
+ {
+ $northWest = $this->transform->transformPoint($x, $y, $size, $size);
+ $this->addCircleNoTransform($northWest->x, $northWest->y, $size, $invert);
+ }
+ /**
+ * Adds a polygon to the image.
+ *
+ * @param array $points Array of points that the polygon consists of.
+ * @param bool $invert If true the area of the polygon will be removed
+ * from the filled area.
+ */
+ public function addPolygon($points, $invert = \false)
+ {
+ $this->addPolygonCore($points, $invert);
+ }
+ /**
+ * Adds a triangle to the image.
+ *
+ * @param float $x The x-coordinate of the bounding rectangle
+ * upper-left corner.
+ * @param float $y The y-coordinate of the bounding rectangle
+ * upper-left corner.
+ * @param float $width The width of the bounding rectangle.
+ * @param float $height The height of the bounding rectangle.
+ * @param float $direction The direction of the 90 degree corner of the
+ * triangle.
+ * @param bool $invert If true the area of the triangle will be removed
+ * from the filled area.
+ */
+ public function addTriangle($x, $y, $width, $height, $direction, $invert = \false)
+ {
+ $points = array(new Point($x + $width, $y), new Point($x + $width, $y + $height), new Point($x, $y + $height), new Point($x, $y));
+ \array_splice($points, $direction, 1);
+ $this->addPolygonCore($points, $invert);
+ }
+ /**
+ * Adds a rhombus to the image.
+ *
+ * @param float $x The x-coordinate of the bounding rectangle
+ * upper-left corner.
+ * @param float $y The y-coordinate of the bounding rectangle
+ * upper-left corner.
+ * @param float $width The width of the bounding rectangle.
+ * @param float $height The height of the bounding rectangle.
+ * @param bool $invert If true the area of the rhombus will be removed
+ * from the filled area.
+ */
+ public function addRhombus($x, $y, $width, $height, $invert = \false)
+ {
+ $this->addPolygonCore(array(new Point($x + $width / 2, $y), new Point($x + $width, $y + $height / 2), new Point($x + $width / 2, $y + $height), new Point($x, $y + $height / 2)), $invert);
+ }
+}
diff --git a/vendor-scoped/jdenticon/jdenticon/src/Rendering/ColorTheme.php b/vendor-scoped/jdenticon/jdenticon/src/Rendering/ColorTheme.php
new file mode 100644
index 0000000..3c7d878
--- /dev/null
+++ b/vendor-scoped/jdenticon/jdenticon/src/Rendering/ColorTheme.php
@@ -0,0 +1,83 @@
+getGrayscaleLightness();
+ $colorLightness = $style->getColorLightness();
+ $hues = $style->getHues();
+ if ($hues !== null) {
+ // $hue is in the range [0, 1]
+ // Multiply with 0.999 to change the range to [0, 1)
+ $hueIndex = (int) ($hue * 0.999 * \count($hues));
+ $hue = (float) $hues[$hueIndex] / 360;
+ }
+ $this->darkGray = Color::fromHslCompensated($hue, $style->getGrayscaleSaturation(), $grayscaleLightness[0]);
+ $this->midColor = Color::fromHslCompensated($hue, $style->getColorSaturation(), ($colorLightness[0] + $colorLightness[1]) / 2);
+ $this->lightGray = Color::fromHslCompensated($hue, $style->getGrayscaleSaturation(), $grayscaleLightness[1]);
+ $this->lightColor = Color::fromHslCompensated($hue, $style->getColorSaturation(), $colorLightness[1]);
+ $this->darkColor = Color::fromHslCompensated($hue, $style->getColorSaturation(), $colorLightness[0]);
+ }
+ /**
+ * Gets a color from this color theme by index.
+ *
+ * @param int $index Color index in the range [0, getCount()).
+ * @return Jdenticon\Color
+ */
+ public function getByIndex($index)
+ {
+ if ($index === 0) {
+ return $this->darkGray;
+ }
+ if ($index === 1) {
+ return $this->midColor;
+ }
+ if ($index === 2) {
+ return $this->lightGray;
+ }
+ if ($index === 3) {
+ return $this->lightColor;
+ }
+ if ($index === 4) {
+ return $this->darkColor;
+ }
+ return null;
+ }
+ /**
+ * Gets the number of available colors in this theme.
+ *
+ * @return int
+ */
+ public function getCount()
+ {
+ return 5;
+ }
+}
diff --git a/vendor-scoped/jdenticon/jdenticon/src/Rendering/IconGenerator.php b/vendor-scoped/jdenticon/jdenticon/src/Rendering/IconGenerator.php
new file mode 100644
index 0000000..caa1a8f
--- /dev/null
+++ b/vendor-scoped/jdenticon/jdenticon/src/Rendering/IconGenerator.php
@@ -0,0 +1,257 @@
+defaultShapes = array(
+ // Sides
+ new ShapeCategory(
+ /*$colorIndex=*/
+ 8,
+ /*$shapes=*/
+ ShapeDefinitions::getOuterShapes(),
+ /*$shapeIndex=*/
+ 2,
+ /*$rotationIndex=*/
+ 3,
+ /*$positions=*/
+ array(1, 0, 2, 0, 2, 3, 1, 3, 0, 1, 3, 1, 3, 2, 0, 2)
+ ),
+ // Corners
+ new ShapeCategory(
+ /*$colorIndex=*/
+ 9,
+ /*$shapes=*/
+ ShapeDefinitions::getOuterShapes(),
+ /*$shapeIndex=*/
+ 4,
+ /*$rotationIndex=*/
+ 5,
+ /*$positions=*/
+ array(0, 0, 3, 0, 3, 3, 0, 3)
+ ),
+ // Center
+ new ShapeCategory(
+ /*$colorIndex=*/
+ 10,
+ /*$shapes=*/
+ ShapeDefinitions::getCenterShapes(),
+ /*$shapeIndex=*/
+ 1,
+ /*$rotationIndex=*/
+ null,
+ /*$positions=*/
+ array(1, 1, 2, 1, 2, 2, 1, 2)
+ ),
+ );
+ }
+ public static function getDefaultGenerator()
+ {
+ if (self::$instance === null) {
+ self::$instance = new IconGenerator();
+ }
+ return self::$instance;
+ }
+ /**
+ * Gets the number of cells in each direction of the icons generated by
+ * this IconGenerator.
+ *
+ * @return int
+ */
+ public function getCellCount()
+ {
+ return 4;
+ }
+ /**
+ * Determines the hue to be used in an icon for the specified hash.
+ *
+ * @return float Hue in the range [0, 1].
+ */
+ protected static function getHue($hash)
+ {
+ $value = \hexdec(\substr($hash, -7));
+ return $value / 0xfffffff;
+ }
+ /**
+ * Determines whether $newValue is duplicated in $source if all values
+ * in $duplicateValues are determined to be equal.
+ *
+ * @return bool
+ */
+ private static function isDuplicate(array $source, $newValue, array $duplicateValues)
+ {
+ if (\in_array($newValue, $duplicateValues, \true)) {
+ foreach ($duplicateValues as $value) {
+ if (\in_array($value, $source, \true)) {
+ return \true;
+ }
+ }
+ }
+ return \false;
+ }
+ /**
+ * Gets the specified octet from a byte array.
+ *
+ * @param string $hash The hexstring from which the octet will be retrieved.
+ * @param int $index The zero-based index of the octet to be returned.
+ * @return int
+ */
+ protected static function getOctet($hash, $index)
+ {
+ return \hexdec($hash[$index]);
+ }
+ /**
+ * Gets an array of the shape categories to be rendered in icons generated
+ * by this IconGenerator.
+ *
+ * @return array
+ */
+ protected function getCategories()
+ {
+ return $this->defaultShapes;
+ }
+ /**
+ * Gets an enumeration of individual shapes to be rendered in an icon for a
+ * specific hash.
+ *
+ * @param \Jdenticon\Rendering\ColorTheme $colorTheme A color theme
+ * specifying the colors to be used in the icon.
+ * @param string $hash The hash for which the shapes will be returned.
+ * @return array(Jdenticon\Shapes\Shape)
+ */
+ protected function getShapes($colorTheme, $hash)
+ {
+ $usedColorThemeIndexes = array();
+ $categories = self::getCategories();
+ $shapes = array();
+ $colorCount = $colorTheme->getCount();
+ foreach ($categories as $category) {
+ $colorThemeIndex = self::getOctet($hash, $category->colorIndex) % $colorCount;
+ if (self::isDuplicate(
+ // Disallow dark gray and dark color combo
+ $usedColorThemeIndexes,
+ $colorThemeIndex,
+ array(0, 4)
+ ) || self::isDuplicate(
+ // Disallow light gray and light color combo
+ $usedColorThemeIndexes,
+ $colorThemeIndex,
+ array(2, 3)
+ )) {
+ $colorThemeIndex = 1;
+ }
+ $usedColorThemeIndexes[] = $colorThemeIndex;
+ $startRotationIndex = $category->rotationIndex === null ? 0 : self::getOctet($hash, $category->rotationIndex);
+ $shapeIndex = self::getOctet($hash, $category->shapeIndex) % \count($category->shapes);
+ $shape = $category->shapes[$shapeIndex];
+ $shapes[] = new Shape(
+ /*$definition=*/
+ $shape,
+ /*$color=*/
+ $colorTheme->getByIndex($colorThemeIndex),
+ /*$positions=*/
+ $category->positions,
+ /*$startRotationIndex=*/
+ $startRotationIndex
+ );
+ }
+ return $shapes;
+ }
+ /**
+ * Creates a quadratic copy of the specified
+ * {@link \Jdenticon\Rendering\Rectangle} with a multiple of the cell count
+ * as size.
+ *
+ * @param \Jdenticon\Rendering\Rectangle $rect The rectangle to be
+ * normalized.
+ */
+ protected function normalizeRectangle(\Avatar_Privacy\Vendor\Jdenticon\Rendering\Rectangle $rect)
+ {
+ $size = (int) \min($rect->width, $rect->height);
+ // Make size a multiple of the cell count
+ $size -= $size % $this->getCellCount();
+ return new Rectangle((int) ($rect->x + ($rect->width - $size) / 2), (int) ($rect->y + ($rect->height - $size) / 2), $size, $size);
+ }
+ /**
+ * Renders the background of an icon.
+ *
+ * @param \Jdenticon\Rendering\RendererInterface $renderer The renderer to
+ * be used for rendering the icon on the target surface.
+ * @param \Jdenticon\Rendering\Rectangle $rect The outer bounds of the icon.
+ * @param \Jdenticon\IdenticonStyle $style The style of the icon.
+ * @param \Jdenticon\Rendering\ColorTheme $colorTheme A color theme
+ * specifying the colors to be used in the icon.
+ * @param string $hash The hash to be used as basis for the generated icon.
+ */
+ protected function renderBackground(\Avatar_Privacy\Vendor\Jdenticon\Rendering\RendererInterface $renderer, \Avatar_Privacy\Vendor\Jdenticon\Rendering\Rectangle $rect, \Avatar_Privacy\Vendor\Jdenticon\IdenticonStyle $style, \Avatar_Privacy\Vendor\Jdenticon\Rendering\ColorTheme $colorTheme, $hash)
+ {
+ $renderer->setBackgroundColor($style->getBackgroundColor());
+ }
+ /**
+ * Renders the foreground of an icon.
+ *
+ * @param \Jdenticon\Rendering\RendererInterface $renderer The renderer to
+ * be used for rendering the icon on the target surface.
+ * @param \Jdenticon\Rendering\Rectangle $rect The outer bounds of the icon.
+ * @param \Jdenticon\IdenticonStyle $style The style of the icon.
+ * @param \Jdenticon\Rendering\ColorTheme $colorTheme A color theme
+ * specifying the colors to be used in the icon.
+ * @param string $hash The hash to be used as basis for the generated icon.
+ */
+ protected function renderForeground(\Avatar_Privacy\Vendor\Jdenticon\Rendering\RendererInterface $renderer, \Avatar_Privacy\Vendor\Jdenticon\Rendering\Rectangle $rect, \Avatar_Privacy\Vendor\Jdenticon\IdenticonStyle $style, \Avatar_Privacy\Vendor\Jdenticon\Rendering\ColorTheme $colorTheme, $hash)
+ {
+ // Ensure rect is quadratic and a multiple of the cell count
+ $normalizedRect = $this->normalizeRectangle($rect);
+ $cellSize = $normalizedRect->width / $this->getCellCount();
+ foreach ($this->getShapes($colorTheme, $hash) as $shape) {
+ $rotation = $shape->startRotationIndex;
+ $renderer->beginShape($shape->color);
+ $positionCount = \count($shape->positions);
+ for ($i = 0; $i + 1 < $positionCount; $i += 2) {
+ $renderer->setTransform(new Transform($normalizedRect->x + $shape->positions[$i + 0] * $cellSize, $normalizedRect->y + $shape->positions[$i + 1] * $cellSize, $cellSize, $rotation++ % 4));
+ $shape->definition->__invoke($renderer, $cellSize, $i / 2);
+ }
+ $renderer->endShape();
+ }
+ }
+ /**
+ * Generates an identicon for the specified hash.
+ *
+ * @param \Jdenticon\Rendering\RendererInterface $renderer The renderer to
+ * be used for rendering the icon on the target surface.
+ * @param \Jdenticon\Rendering\Rectangle $rect The outer bounds of the icon.
+ * @param \Jdenticon\IdenticonStyle $style The style of the icon.
+ * @param string $hash The hash to be used as basis for the generated icon.
+ */
+ public function generate(\Avatar_Privacy\Vendor\Jdenticon\Rendering\RendererInterface $renderer, \Avatar_Privacy\Vendor\Jdenticon\Rendering\Rectangle $rect, \Avatar_Privacy\Vendor\Jdenticon\IdenticonStyle $style, $hash)
+ {
+ $hue = self::getHue($hash);
+ $colorTheme = new ColorTheme($hue, $style);
+ $this->renderBackground($renderer, $rect, $style, $colorTheme, $hash);
+ $this->renderForeground($renderer, $rect, $style, $colorTheme, $hash);
+ }
+}
diff --git a/vendor-scoped/jdenticon/jdenticon/src/Rendering/Point.php b/vendor-scoped/jdenticon/jdenticon/src/Rendering/Point.php
new file mode 100644
index 0000000..33e58de
--- /dev/null
+++ b/vendor-scoped/jdenticon/jdenticon/src/Rendering/Point.php
@@ -0,0 +1,51 @@
+x = $x;
+ $this->y = $y;
+ }
+ /**
+ * The X coordinate of this point.
+ *
+ * @var float
+ */
+ public $x;
+ /**
+ * The Y coordinate of this point.
+ *
+ * @var float
+ */
+ public $y;
+ /**
+ * Gets a string representation of the point.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->x + ", " + $this->y;
+ }
+}
diff --git a/vendor-scoped/jdenticon/jdenticon/src/Rendering/Rectangle.php b/vendor-scoped/jdenticon/jdenticon/src/Rendering/Rectangle.php
new file mode 100644
index 0000000..68a9d6e
--- /dev/null
+++ b/vendor-scoped/jdenticon/jdenticon/src/Rendering/Rectangle.php
@@ -0,0 +1,56 @@
+x = $x;
+ $this->y = $y;
+ $this->width = $width;
+ $this->height = $height;
+ }
+}
diff --git a/vendor-scoped/jdenticon/jdenticon/src/Rendering/RendererInterface.php b/vendor-scoped/jdenticon/jdenticon/src/Rendering/RendererInterface.php
new file mode 100644
index 0000000..de48253
--- /dev/null
+++ b/vendor-scoped/jdenticon/jdenticon/src/Rendering/RendererInterface.php
@@ -0,0 +1,128 @@
+dataString = '';
+ }
+ /**
+ * Adds a circle to the SVG.
+ *
+ * @param float $x X coordinate of the left side of the containing rectangle.
+ * @param float $y Y coordinate of the top side of the containing rectangle.
+ * @param float $size The diameter of the circle.
+ * @param bool $counterClockwise If true the circle will be drawn counter
+ * clockwise. This affects the rendering since the evenodd filling rule
+ * is used by Jdenticon.
+ */
+ public function addCircle($x, $y, $size, $counterClockwise)
+ {
+ $sweepFlag = $counterClockwise ? '0' : '1';
+ $radiusAsString = \number_format($size / 2, 2, '.', '');
+ $this->dataString .= 'M' . \number_format($x, 2, '.', '') . ' ' . \number_format($y + $size / 2, 2, '.', '') . 'a' . $radiusAsString . ',' . $radiusAsString . ' 0 1,' . $sweepFlag . ' ' . \number_format($size, 2, '.', '') . ',0' . 'a' . $radiusAsString . ',' . $radiusAsString . ' 0 1,' . $sweepFlag . ' ' . \number_format(-$size, 2, '.', '') . ',0';
+ }
+ /**
+ * Adds a polygon to the SVG.
+ *
+ * @param array(\Jdenticon\Rendering\Point) $points The corners of the
+ * polygon.
+ */
+ public function addPolygon($points)
+ {
+ $pointCount = \count($points);
+ $this->dataString .= 'M' . \number_format($points[0]->x, 2, '.', '') . ' ' . \number_format($points[0]->y, 2, '.', '');
+ for ($i = 1; $i < $pointCount; $i++) {
+ $this->dataString .= 'L' . \number_format($points[$i]->x, 2, '.', '') . ' ' . \number_format($points[$i]->y, 2, '.', '');
+ }
+ $this->dataString .= 'Z';
+ }
+ /**
+ * Gets the path as a SVG path string.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->dataString;
+ }
+}
diff --git a/vendor-scoped/jdenticon/jdenticon/src/Rendering/SvgRenderer.php b/vendor-scoped/jdenticon/jdenticon/src/Rendering/SvgRenderer.php
new file mode 100644
index 0000000..764d907
--- /dev/null
+++ b/vendor-scoped/jdenticon/jdenticon/src/Rendering/SvgRenderer.php
@@ -0,0 +1,114 @@
+width = $width;
+ $this->height = $height;
+ }
+ /**
+ * Gets the MIME type of the renderer output.
+ *
+ * @return string
+ */
+ public function getMimeType()
+ {
+ return 'image/svg+xml';
+ }
+ /**
+ * Adds a circle without translating its coordinates.
+ *
+ * @param float $x The x-coordinate of the bounding rectangle
+ * upper-left corner.
+ * @param float $y The y-coordinate of the bounding rectangle
+ * upper-left corner.
+ * @param float $size The size of the bounding rectangle.
+ * @param bool $counterClockwise If true the circle will be drawn
+ * counter clockwise.
+ */
+ protected function addCircleNoTransform($x, $y, $size, $counterClockwise)
+ {
+ $this->path->addCircle($x, $y, $size, $counterClockwise);
+ }
+ /**
+ * Adds a polygon without translating its coordinates.
+ *
+ * @param array $points An array of the points that the polygon consists of.
+ */
+ protected function addPolygonNoTransform($points)
+ {
+ $this->path->addPolygon($points);
+ }
+ /**
+ * Begins a new shape. The shape should be ended with a call to endShape.
+ *
+ * @param \Jdenticon\Color $color The color of the shape.
+ */
+ public function beginShape(\Avatar_Privacy\Vendor\Jdenticon\Color $color)
+ {
+ $colorString = $color->toHexString(6);
+ if (isset($this->pathsByColor[$colorString])) {
+ $this->path = $this->pathsByColor[$colorString];
+ } else {
+ $this->path = new SvgPath();
+ $this->pathsByColor[$colorString] = $this->path;
+ }
+ }
+ /**
+ * Ends the currently drawn shape.
+ */
+ public function endShape()
+ {
+ }
+ /**
+ * Generates an SVG string of the renderer output.
+ *
+ * @param bool $fragment If true an SVG string without the root svg element
+ * will be rendered.
+ */
+ public function getData($fragment = \false)
+ {
+ $svg = '';
+ $widthAsString = \number_format($this->width, 0, '.', '');
+ $heightAsString = \number_format($this->height, 0, '.', '');
+ if (!$fragment) {
+ $svg .= '';
+ }
+ return $svg;
+ }
+}
diff --git a/vendor-scoped/jdenticon/jdenticon/src/Rendering/Transform.php b/vendor-scoped/jdenticon/jdenticon/src/Rendering/Transform.php
new file mode 100644
index 0000000..3d970ef
--- /dev/null
+++ b/vendor-scoped/jdenticon/jdenticon/src/Rendering/Transform.php
@@ -0,0 +1,79 @@
+x = $x;
+ $this->y = $y;
+ $this->size = $size;
+ $this->rotation = $rotation;
+ }
+ /**
+ * Gets a noop transform.
+ *
+ * @return \Jdenticon\Rendering\Transform
+ */
+ public static function getEmpty()
+ {
+ return new Transform(0, 0, 0, 0);
+ }
+ /**
+ * Transforms the specified point based on the translation and rotation
+ * specification for this Transform.
+ *
+ * @param float $x x-coordinate
+ * @param float $y y-coordinate
+ * @param float $width The width of the transformed rectangle. If greater
+ * than 0, this will ensure the returned point is of the upper left
+ * corner of the transformed rectangle.
+ * @param float $height The height of the transformed rectangle. If greater
+ * than 0, this will ensure the returned point is of the upper left
+ * corner of the transformed rectangle.
+ * @return \Jdenticon\Rendering\Point
+ */
+ public function transformPoint($x, $y, $width = 0, $height = 0)
+ {
+ $right = $this->x + $this->size;
+ $bottom = $this->y + $this->size;
+ switch ($this->rotation) {
+ case 1:
+ return new Point($right - $y - $height, $this->y + $x);
+ case 2:
+ return new Point($right - $x - $width, $bottom - $y - $height);
+ case 3:
+ return new Point($this->x + $y, $bottom - $x - $width);
+ default:
+ return new Point($this->x + $x, $this->y + $y);
+ }
+ }
+}
diff --git a/vendor-scoped/jdenticon/jdenticon/src/Rendering/TriangleDirection.php b/vendor-scoped/jdenticon/jdenticon/src/Rendering/TriangleDirection.php
new file mode 100644
index 0000000..4d3948d
--- /dev/null
+++ b/vendor-scoped/jdenticon/jdenticon/src/Rendering/TriangleDirection.php
@@ -0,0 +1,35 @@
+definition = $definition;
+ $this->color = $color;
+ $this->positions = $positions;
+ $this->startRotationIndex = $startRotationIndex;
+ }
+}
diff --git a/vendor-scoped/jdenticon/jdenticon/src/Shapes/ShapeCategory.php b/vendor-scoped/jdenticon/jdenticon/src/Shapes/ShapeCategory.php
new file mode 100644
index 0000000..bf3d4b5
--- /dev/null
+++ b/vendor-scoped/jdenticon/jdenticon/src/Shapes/ShapeCategory.php
@@ -0,0 +1,64 @@
+colorIndex = $colorIndex;
+ $this->shapes = $shapes;
+ $this->shapeIndex = $shapeIndex;
+ $this->rotationIndex = $rotationIndex;
+ $this->positions = $positions;
+ }
+}
diff --git a/vendor-scoped/jdenticon/jdenticon/src/Shapes/ShapeDefinitions.php b/vendor-scoped/jdenticon/jdenticon/src/Shapes/ShapeDefinitions.php
new file mode 100644
index 0000000..1e11294
--- /dev/null
+++ b/vendor-scoped/jdenticon/jdenticon/src/Shapes/ShapeDefinitions.php
@@ -0,0 +1,154 @@
+addTriangle(0, 0, $cell, $cell, 0);
+ }, function ($renderer, $cell, $index) {
+ $renderer->addTriangle(0, $cell / 2, $cell, $cell / 2, 0);
+ }, function ($renderer, $cell, $index) {
+ $renderer->addRhombus(0, 0, $cell, $cell);
+ }, function ($renderer, $cell, $index) {
+ $m = $cell / 6;
+ $renderer->addCircle($m, $m, $cell - 2 * $m);
+ });
+ }
+ private static function createCenterShapes()
+ {
+ return array(function ($renderer, $cell, $index) {
+ $k = $cell * 0.42;
+ $renderer->addPolygon(array(new Point(0, 0), new Point($cell, 0), new Point($cell, $cell - $k * 2), new Point($cell - $k, $cell), new Point(0, $cell)));
+ }, function ($renderer, $cell, $index) {
+ $w = (int) ($cell * 0.5);
+ $h = (int) ($cell * 0.8);
+ $renderer->addTriangle($cell - $w, 0, $w, $h, TriangleDirection::NORTH_EAST);
+ }, function ($renderer, $cell, $index) {
+ $s = (int) ($cell / 3);
+ $renderer->addRectangle($s, $s, $cell - $s, $cell - $s);
+ }, function ($renderer, $cell, $index) {
+ $tmp = $cell * 0.1;
+ if ($tmp > 1) {
+ // large icon => truncate decimals
+ $inner = (int) $tmp;
+ } elseif ($tmp > 0.5) {
+ // medium size icon => fixed width
+ $inner = 1;
+ } else {
+ // small icon => anti-aliased border
+ $inner = $tmp;
+ }
+ // Use fixed outer border widths in small icons to ensure
+ // the border is drawn
+ if ($cell < 6) {
+ $outer = 1;
+ } elseif ($cell < 8) {
+ $outer = 2;
+ } else {
+ $outer = (int) ($cell / 4);
+ }
+ $renderer->addRectangle($outer, $outer, $cell - $inner - $outer, $cell - $inner - $outer);
+ }, function ($renderer, $cell, $index) {
+ $m = (int) ($cell * 0.15);
+ $s = (int) ($cell * 0.5);
+ $renderer->addCircle($cell - $s - $m, $cell - $s - $m, $s);
+ }, function ($renderer, $cell, $index) {
+ $inner = $cell * 0.1;
+ $outer = $inner * 4;
+ // Align edge to nearest pixel in large icons
+ if ($outer > 3) {
+ $outer = (int) $outer;
+ }
+ $renderer->addRectangle(0, 0, $cell, $cell);
+ $renderer->addPolygon(array(new Point($outer, $outer), new Point($cell - $inner, $outer), new Point($outer + ($cell - $outer - $inner) / 2, $cell - $inner)), \true);
+ }, function ($renderer, $cell, $index) {
+ $renderer->addPolygon(array(new Point(0, 0), new Point($cell, 0), new Point($cell, $cell * 0.7), new Point($cell * 0.4, $cell * 0.4), new Point($cell * 0.7, $cell), new Point(0, $cell)));
+ }, function ($renderer, $cell, $index) {
+ $renderer->addTriangle($cell / 2, $cell / 2, $cell / 2, $cell / 2, TriangleDirection::SOUTH_EAST);
+ }, function ($renderer, $cell, $index) {
+ $renderer->addPolygon(array(new Point(0, 0), new Point($cell, 0), new Point($cell, $cell / 2), new Point($cell / 2, $cell), new Point(0, $cell)));
+ }, function ($renderer, $cell, $index) {
+ $tmp = $cell * 0.14;
+ if ($cell < 8) {
+ // small icon => anti-aliased border
+ $inner = $tmp;
+ } else {
+ // large icon => truncate decimals
+ $inner = (int) $tmp;
+ }
+ // Use fixed outer border widths in small icons to ensure
+ // the border is drawn
+ if ($cell < 4) {
+ $outer = 1;
+ } elseif ($cell < 6) {
+ $outer = 2;
+ } else {
+ $outer = (int) ($cell * 0.35);
+ }
+ $renderer->addRectangle(0, 0, $cell, $cell);
+ $renderer->addRectangle($outer, $outer, $cell - $outer - $inner, $cell - $outer - $inner, \true);
+ }, function ($renderer, $cell, $index) {
+ $inner = $cell * 0.12;
+ $outer = $inner * 3;
+ $renderer->addRectangle(0, 0, $cell, $cell);
+ $renderer->addCircle($outer, $outer, $cell - $inner - $outer, \true);
+ }, function ($renderer, $cell, $index) {
+ $renderer->addTriangle($cell / 2, $cell / 2, $cell / 2, $cell / 2, TriangleDirection::SOUTH_EAST);
+ }, function ($renderer, $cell, $index) {
+ $m = $cell * 0.25;
+ $renderer->addRectangle(0, 0, $cell, $cell);
+ $renderer->addRhombus($m, $m, $cell - $m, $cell - $m, \true);
+ }, function ($renderer, $cell, $index) {
+ $m = $cell * 0.4;
+ $s = $cell * 1.2;
+ if ($index != 0) {
+ $renderer->addCircle($m, $m, $s);
+ }
+ });
+ }
+}
diff --git a/vendor-scoped/jdenticon/jdenticon/src/Shapes/ShapePosition.php b/vendor-scoped/jdenticon/jdenticon/src/Shapes/ShapePosition.php
new file mode 100644
index 0000000..808d70b
--- /dev/null
+++ b/vendor-scoped/jdenticon/jdenticon/src/Shapes/ShapePosition.php
@@ -0,0 +1,42 @@
+x = $x;
+ $this->y = $y;
+ }
+}
diff --git a/vendor-scoped/level-2/dice/Dice.php b/vendor-scoped/level-2/dice/Dice.php
new file mode 100644
index 0000000..8fd8277
--- /dev/null
+++ b/vendor-scoped/level-2/dice/Dice.php
@@ -0,0 +1,319 @@
+ | https://r.je/dice
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version 4.0 */
+namespace Avatar_Privacy\Vendor\Dice;
+
+class Dice
+{
+ const CONSTANT = 'Dice::CONSTANT';
+ const GLOBAL = 'Dice::GLOBAL';
+ const INSTANCE = 'Dice::INSTANCE';
+ const CHAIN_CALL = 'Dice::CHAIN_CALL';
+ const SELF = 'Dice::SELF';
+ /**
+ * @var array $rules Rules which have been set using addRule()
+ */
+ private $rules = [];
+ /**
+ * @var array $cache A cache of closures based on class name so each class is only reflected once
+ */
+ private $cache = [];
+ /**
+ * @var array $instances Stores any instances marked as 'shared' so create() can return the same instance
+ */
+ private $instances = [];
+ /**
+ * Add a rule $rule to the class $name
+ * @param string $name The name of the class to add the rule for
+ * @param array $rule The container can be fully configured using rules provided by associative arrays. See {@link https://r.je/dice.html#example3} for a description of the rules.
+ */
+ public function addRule(string $name, array $rule) : self
+ {
+ $dice = clone $this;
+ $this->addRuleTo($dice, $name, $rule);
+ return $dice;
+ }
+ /**
+ * Add rules as array. Useful for JSON loading $dice->addRules(json_decode(file_get_contents('foo.json'));
+ * @param array Rules in a single array [name => $rule] format
+ */
+ public function addRules($rules) : self
+ {
+ if (\is_string($rules)) {
+ $rules = \json_decode(\file_get_contents($rules), \true);
+ }
+ $dice = clone $this;
+ foreach ($rules as $name => $rule) {
+ $this->addRuleTo($dice, $name, $rule);
+ }
+ return $dice;
+ }
+ private function addRuleTo(Dice $dice, string $name, array $rule)
+ {
+ if (isset($rule['instanceOf']) && (!\array_key_exists('inherit', $rule) || $rule['inherit'] === \true)) {
+ $rule = \array_replace_recursive($dice->getRule($rule['instanceOf']), $rule);
+ }
+ //Allow substitutions rules to be defined with a leading a slash
+ if (isset($rule['substitutions'])) {
+ foreach ($rule['substitutions'] as $key => $value) {
+ $rule['substitutions'][\ltrim($key, '\\')] = $value;
+ }
+ }
+ //Clear any existing instance or cache for this class
+ unset($dice->instances[$name], $dice->cache[$name]);
+ $dice->rules[\ltrim(\strtolower($name), '\\')] = \array_replace_recursive($dice->getRule($name), $rule);
+ }
+ /**
+ * Returns the rule that will be applied to the class $name when calling create()
+ * @param string name The name of the class to get the rules for
+ * @return array The rules for the specified class
+ */
+ public function getRule(string $name) : array
+ {
+ $lcName = \strtolower(\ltrim($name, '\\'));
+ if (isset($this->rules[$lcName])) {
+ return $this->rules[$lcName];
+ }
+ foreach ($this->rules as $key => $rule) {
+ // Find a rule which matches the class described in $name where:
+ if (empty($rule['instanceOf']) && $key !== '*' && \is_subclass_of($name, $key) && (!\array_key_exists('inherit', $rule) || $rule['inherit'] === \true)) {
+ // And that rule should be inherited to subclasses
+ return $rule;
+ }
+ }
+ // No rule has matched, return the default rule if it's set
+ return isset($this->rules['*']) ? $this->rules['*'] : [];
+ }
+ /**
+ * Returns a fully constructed object based on $name using $args and $share as constructor arguments if supplied
+ * @param string name The name of the class to instantiate
+ * @param array $args An array with any additional arguments to be passed into the constructor upon instantiation
+ * @param array $share a list of defined in shareInstances for objects higher up the object graph, should only be used internally
+ * @return object A fully constructed object based on the specified input arguments
+ */
+ public function create(string $name, array $args = [], array $share = [])
+ {
+ // Is there a shared instance set? Return it. Better here than a closure for this, calling a closure is slower.
+ if (!empty($this->instances[$name])) {
+ return $this->instances[$name];
+ }
+ // Create a closure for creating the object if there isn't one already
+ if (empty($this->cache[$name])) {
+ $this->cache[$name] = $this->getClosure(\ltrim($name, '\\'), $this->getRule($name));
+ }
+ // Call the cached closure which will return a fully constructed object of type $name
+ return $this->cache[$name]($args, $share);
+ }
+ /**
+ * Returns a closure for creating object $name based on $rule, caching the reflection object for later use
+ * @param string $name the Name of the class to get the closure for
+ * @param array $rule The container can be fully configured using rules provided by associative arrays. See {@link https://r.je/dice.html#example3} for a description of the rules.
+ * @return callable A closure
+ */
+ private function getClosure(string $name, array $rule)
+ {
+ // Reflect the class and constructor, this should only ever be done once per class and get cached
+ $class = new \ReflectionClass(isset($rule['instanceOf']) ? $rule['instanceOf'] : $name);
+ $constructor = $class->getConstructor();
+ // Create parameter generating function in order to cache reflection on the parameters. This way $reflect->getParameters() only ever gets called once
+ $params = $constructor ? $this->getParams($constructor, $rule) : null;
+ //PHP throws a fatal error rather than an exception when trying to instantiate an interface, detect it and throw an exception instead
+ if ($class->isInterface()) {
+ $closure = function () {
+ throw new \InvalidArgumentException('Cannot instantiate interface');
+ };
+ } else {
+ if ($params) {
+ $closure = function (array $args, array $share) use($class, $params) {
+ // This class has depenencies, call the $params closure to generate them based on $args and $share
+ return new $class->name(...$params($args, $share));
+ };
+ } else {
+ $closure = function () use($class) {
+ // No constructor arguments, just instantiate the class
+ return new $class->name();
+ };
+ }
+ }
+ if (!empty($rule['shared'])) {
+ $closure = function (array $args, array $share) use($class, $name, $constructor, $params, $closure) {
+ //Internal classes may not be able to be constructed without calling the constructor and will not suffer from #7, construct them normally.
+ if ($class->isInternal()) {
+ $this->instances[$class->name] = $this->instances['\\' . $class->name] = $closure($args, $share);
+ } else {
+ //Otherwise, create the class without calling the constructor (and write to \$name and $name, see issue #68)
+ $this->instances[$name] = $this->instances['\\' . $name] = $class->newInstanceWithoutConstructor();
+ // Now call this constructor after constructing all the dependencies. This avoids problems with cyclic references (issue #7)
+ if ($constructor) {
+ $constructor->invokeArgs($this->instances[$name], $params($args, $share));
+ }
+ }
+ return $this->instances[$name];
+ };
+ }
+ // If there are shared instances, create them and merge them with shared instances higher up the object graph
+ if (isset($rule['shareInstances'])) {
+ $closure = function (array $args, array $share) use($closure, $rule) {
+ foreach ($rule['shareInstances'] as $instance) {
+ $share[] = $this->create($instance, [], $share);
+ }
+ return $closure($args, $share);
+ };
+ }
+ // When $rule['call'] is set, wrap the closure in another closure which will call the required methods after constructing the object
+ // By putting this in a closure, the loop is never executed unless call is actually set
+ return isset($rule['call']) ? function (array $args, array $share) use($closure, $class, $rule, $name) {
+ // Construct the object using the original closure
+ $object = $closure($args, $share);
+ foreach ($rule['call'] as $call) {
+ // Generate the method arguments using getParams() and call the returned closure
+ $params = $this->getParams($class->getMethod($call[0]), ['shareInstances' => isset($rule['shareInstances']) ? $rule['shareInstances'] : []])($this->expand(isset($call[1]) ? $call[1] : []), $share);
+ $return = $object->{$call[0]}(...$params);
+ if (isset($call[2])) {
+ if ($call[2] === self::CHAIN_CALL) {
+ if (!empty($rule['shared'])) {
+ $this->instances[$name] = $return;
+ }
+ if (\is_object($return)) {
+ $class = new \ReflectionClass(\get_class($return));
+ }
+ $object = $return;
+ } else {
+ if (\is_callable($call[2])) {
+ \call_user_func($call[2], $return);
+ }
+ }
+ }
+ }
+ return $object;
+ } : $closure;
+ }
+ /**
+ * Looks for Dice::INSTANCE, Dice::GLOBAL or Dice::CONSTANT array keys in $param and when found returns an object based on the value see {@link https:// r.je/dice.html#example3-1}
+ * @param mixed $param Either a string or an array,
+ * @param array $share Array of instances from 'shareInstances', required for calls to `create`
+ * @param bool $createFromString
+ * @return mixed
+ */
+ private function expand($param, array $share = [], bool $createFromString = \false)
+ {
+ if (\is_array($param)) {
+ //if a rule specifies Dice::INSTANCE, look up the relevant instance
+ if (isset($param[self::INSTANCE])) {
+ if ($param[self::INSTANCE] === self::SELF) {
+ return $this;
+ }
+ //Check for 'params' which allows parameters to be sent to the instance when it's created
+ //Either as a callback method or to the constructor of the instance
+ $args = isset($param['params']) ? $this->expand($param['params']) : [];
+ //Support Dice::INSTANCE by creating/fetching the specified instance
+ if (\is_array($param[self::INSTANCE])) {
+ $param[self::INSTANCE][0] = $this->expand($param[self::INSTANCE][0], $share, \true);
+ }
+ if (\is_callable($param[self::INSTANCE])) {
+ return \call_user_func($param[self::INSTANCE], ...$args);
+ } else {
+ return $this->create($param[self::INSTANCE], \array_merge($args, $share));
+ }
+ } else {
+ if (isset($param[self::GLOBAL])) {
+ return $GLOBALS[$param[self::GLOBAL]];
+ } else {
+ if (isset($param[self::CONSTANT])) {
+ return \constant($param[self::CONSTANT]);
+ } else {
+ foreach ($param as $name => $value) {
+ $param[$name] = $this->expand($value, $share);
+ }
+ }
+ }
+ }
+ }
+ return \is_string($param) && $createFromString ? $this->create($param) : $param;
+ }
+ /**
+ * Looks through the array $search for any object which can be used to fulfil $param
+ The original array $search is modifed so must be passed by reference.
+ */
+ private function matchParam(\ReflectionParameter $param, $class, array &$search)
+ {
+ foreach ($search as $i => $arg) {
+ if ($class && ($arg instanceof $class || $arg === null && $param->allowsNull())) {
+ // The argument matched, return it and remove it from $search so it won't wrongly match another parameter
+ return \array_splice($search, $i, 1)[0];
+ }
+ }
+ return \false;
+ }
+ /**
+ * Returns a closure that generates arguments for $method based on $rule and any $args passed into the closure
+ * @param object $method An instance of ReflectionMethod (see: {@link http:// php.net/manual/en/class.reflectionmethod.php})
+ * @param array $rule The container can be fully configured using rules provided by associative arrays. See {@link https://r.je/dice.html#example3} for a description of the rules.
+ * @return callable A closure that uses the cached information to generate the arguments for the method
+ */
+ private function getParams(\ReflectionMethod $method, array $rule)
+ {
+ // Cache some information about the parameter in $paramInfo so (slow) reflection isn't needed every time
+ $paramInfo = [];
+ foreach ($method->getParameters() as $param) {
+ $type = $param->getType();
+ $class = $type instanceof \ReflectionNamedType && !$type->isBuiltIn() ? $type->getName() : null;
+ $paramInfo[] = [$class, $param, isset($rule['substitutions']) && \array_key_exists($class, $rule['substitutions'])];
+ }
+ // Return a closure that uses the cached information to generate the arguments for the method
+ return function (array $args, array $share = []) use($paramInfo, $rule) {
+ // If the rule has construtParams set, construct any classes reference and use them as $args
+ if (isset($rule['constructParams'])) {
+ $args = \array_merge($args, $this->expand($rule['constructParams'], $share));
+ }
+ // Array of matched parameters
+ $parameters = [];
+ // Fnd a value for each method argument
+ foreach ($paramInfo as list($class, $param, $sub)) {
+ // Loop through $args and see whether or not each value can match the current parameter based on type hint
+ if ($args && ($match = $this->matchParam($param, $class, $args)) !== \false) {
+ $parameters[] = $match;
+ } else {
+ if (($copy = $share) && ($match = $this->matchParam($param, $class, $copy)) !== \false) {
+ $parameters[] = $match;
+ } else {
+ if ($class) {
+ try {
+ if ($sub) {
+ $parameters[] = $this->expand($rule['substitutions'][$class], $share, \true);
+ } else {
+ $parameters[] = !$param->allowsNull() ? $this->create($class, [], $share) : null;
+ }
+ } catch (\InvalidArgumentException $e) {
+ }
+ } else {
+ if ($args && $param->getType()) {
+ for ($i = 0; $i < \count($args); $i++) {
+ if (\call_user_func('is_' . $param->getType()->getName(), $args[$i])) {
+ $parameters[] = \array_splice($args, $i, 1)[0];
+ break;
+ }
+ }
+ } else {
+ if ($args) {
+ $parameters[] = $this->expand(\array_shift($args));
+ } else {
+ if ($param->isVariadic()) {
+ $parameters = \array_merge($parameters, $args);
+ } else {
+ $parameters[] = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return $parameters;
+ };
+ }
+}
diff --git a/vendor-scoped/level-2/dice/README.md b/vendor-scoped/level-2/dice/README.md
new file mode 100644
index 0000000..ae47620
--- /dev/null
+++ b/vendor-scoped/level-2/dice/README.md
@@ -0,0 +1,365 @@
+[Dice PHP Dependency Injection Container](https://r.je/dice.html)
+======================================
+
+Dice is a minimalist Dependency Injection Container for PHP with a focus on being lightweight and fast as well as requiring as little configuration as possible.
+
+
+Project Goals
+-------------
+
+1) To be lightweight and not a huge library with dozens of files (Dice is a single 100 line class) yet support all features (and more) offered by much more complex containers
+
+2) To "just work". Basic functionality should work with zero configuration
+
+3) Where configuration is required, it should be as minimal and reusable as possible as well as easy to use.
+
+4) Speed! (See [the section on performance](#performance))
+
+
+Installation
+------------
+
+Just include the lightweight `Dice.php` in your project and it's usable without any further configuration:
+
+Simple example:
+
+```php
+b = $b;
+ }
+}
+
+class B {
+
+}
+
+require_once 'Dice.php';
+$dice = new \Dice\Dice;
+
+$a = $dice->create('A');
+
+var_dump($a->b); //B object
+
+?>
+```
+
+
+Full Documentation
+------------------
+
+For complete documentation please see the [Dice PHP Dependency Injection container home page](https://r.je/dice.html)
+
+
+PHP version compatibility
+-------------------------
+
+Dice is compatible with PHP 7.0 and up, there are archived versions of Dice which support PHP 5.6 however this is no longer maintanied.
+
+
+Performance
+-----------
+
+Dice uses reflection which is often wrongly labelled "slow". Reflection is considerably faster than loading and parsing a configuration file. There are a set of benchmarks [here](https://rawgit.com/TomBZombie/php-dependency-injection-benchmarks/master/test1-5_results.html) and [here](https://rawgit.com/TomBZombie/php-dependency-injection-benchmarks/master/test6_results.html) (To download the benchmark tool yourself see [this repository](https://github.com/TomBZombie/php-dependency-injection-benchmarks)) and Dice is faster than the others in most cases.
+
+In the real world test ([test 6](https://rawgit.com/TomBZombie/php-dependency-injection-benchmarks/master/test6_results.html)) Dice is neck-and-neck with Pimple (which requires writing an awful lot of configuration code) and although Symfony\DependencyInjection is faster at creating objects, it has a larger overhead and you need to create over 500 objects on each page load until it becomes faster than Dice. The same is true of Phalcon, the overhead of loading the Phalcon extension means that unless you're creating well over a thousand objects per HTTP request, the overhead is not worthwhile.
+
+
+Credits
+------------
+
+Originally developed by Tom Butler (@TomBZombie), with many thanks to daniel-meister (@daniel-meister), Garrett W. (@garrettw), maxwilms (@maxwilms) for bug fixes, suggestions and improvements.
+
+
+Updates
+------------
+
+### 15/11/2018 4.0 Release - Backwards incompatible
+
+Dice is now immutable and has better support for other immutable objects.
+
+**New Features**
+
+#### 1. Dice is Immutable
+
+This avoids [issues surrounding mutability](https://www.yegor256.com/2014/06/09/objects-should-be-immutable.html) where a Dice instance is passed around the application and reconfigured. The only difference is that `addRules` and `addRule` return a new Dice instance with the updated rules rather than changing the state of the existing instance.
+
+```php
+
+// Pre-4.0 code:
+$dice->addRule('PDO', ['shared' => true]);
+
+$db = $dice->create('PDO');
+
+// 4.0 code:
+$dice = $dice->addRule('PDO', ['shared' => true]);
+
+$db = $dice->create('PDO');
+```
+
+From a practical perspective in most cases just put `$dice = ` in front of any `$dice->addRule()` call and it will work as before.
+
+#### 2. Support for Object Method Chaining
+
+One feature some immutable objects have is they offer object chaining.
+
+Consider the following Object:
+
+```php
+
+$httpRequest = new HTTPRequest();
+$httpRequest = $httpRequest->url('http://example.org')->method('POST')->postdata('foo=bar');
+```
+
+It was not possible for Dice to consturuct the configured object in previous versions. As of 4.0 Dice supports chaining method call using the `call` rule and the `Dice::CHAIN_CALL` constant:
+
+```php
+$dice = $dice->addRule('HTTPRequest',
+ ['call' => [
+ ['url', ['http://example.org'], Dice::CHAIN_CALL],
+ ['method', ['POST'], Dice::CHAIN_CALL ],
+ ['postdata', ['foo=bar'], Dice::CHAIN_CALL]
+ ]
+ ]
+);
+```
+
+Dice will replace the HTTPRequest object with the result of the chained call. This is also useful for factories:
+
+
+```php
+$dice = $dice->addRule('MyDatabase',
+ [
+ 'instanceOf' => 'DatabaseFactory',
+ 'call' => [
+ ['get', ['Database'], Dice::CHAIN_CALL]
+ ]
+ ]
+);
+
+$database = $dice->create('MyDatabase');
+//Equivalent of:
+
+$factory = new DatabaseFactory();
+$database = $factory->get('Database');
+```
+
+
+### 06/03/2018 3.0 Release - Backwards incompatible
+
+**New Features**
+
+#### 1. The JSON loader has been removed in favour of a new `addRules` method.
+
+```php
+$dice->addRules([
+ '\PDO' => [
+ 'shared' => true
+ ],
+ 'Framework\Router' => [
+ 'constructParams' => ['Foo', 'Bar']
+ ]
+]);
+```
+
+The purpose of this addition is to make the JSON loader redundant. Loading of rules from a JSON file can easily be achieved with the code:
+
+```php
+$dice->addRules(json_decode(file_get_contents('rules.json')));
+```
+
+#### 2. Better JSON file support: constants and superglobals
+
+In order to improve support for rules being defined in external JSON files, constants and superglobals can now be passed into objects created by Dice.
+
+For example, passing the `$_SERVER` superglobal into a router instance and calling PDO's `setAttribute` with `PDO::ATTR_ERRMODE` and `PDO::ERRMODE_EXCEPTION` can be achieved like this in a JSON file:
+
+_rules.json_
+
+```json
+{
+ "Router": {
+ "constructParams": [
+ {"Dice::GLOBAL": "_SERVER"}
+ ]
+ },
+ "PDO": {
+ "shared": true,
+ "constructParams": [
+ "mysql:dbname=testdb;host=127.0.0.1",
+ "dbuser",
+ "dbpass"
+ ],
+ "call": [
+ [
+ "setAttribute",
+ [
+ {"Dice::CONSTANT": "PDO::ATTR_ERRMODE"},
+ {"Dice::CONSTANT": "PDO::ERRMODE_EXCEPTION"}
+ ]
+ ]
+ ]
+ }
+}
+```
+
+```php
+$dice->addRules(json_decode(file_get_contents('rules.json')));
+```
+
+**Backwards incompatible changes**
+
+1. Dice 3.0 requires PHP 7.0 or above, PHP 5.6 is no longer supported.
+
+2. Dice no longer supports `'instance'` keys to signify instances. For example:
+
+```php
+$dice->addRule('ClassName', [
+ 'constructParams' => ['instance' => '$NamedPDOInstance']
+]);
+```
+
+As noted in issue #125 this made it impossible to pass an array to a constructor if the array had a key `'instance'`. Instead, the new `\Dice\Dice::INSTANCE` constant should be used:
+
+```php
+$dice->addRule('ClassName', [
+ 'constructParams' => [\Dice\Dice::INSTANCE => '$NamedPDOInstance']
+]);
+```
+_to make the constant shorter to type out, you can `use \Dice\Dice;` and reference `Dice::INSTANCE`_
+
+10/06/2016
+
+** Backwards incompatible change **
+
+Based on [Issue 110](https://github.com/Level-2/Dice/pull/110) named instances using `instanceOf` will now inherit the rules applied to the class they are instances of:
+
+```php
+
+$rule = [];
+$rule['shared'] = true;
+
+$dice->addRule('MyClass', $rule);
+
+$rule = [];
+$rule['instanceOf'] = 'MyClass';
+$rule['constructParams'] = ['Foo', 'Bar'];
+
+$dice->addRule('$MyNamedInstance', $rule);
+
+
+```
+
+`$dice->create('$MyNamedInstance')` will now create a class following the rules applied to both `MyClass` and `$MyNamedInstance` so the instance will be shared.
+
+Previously only the rules applied to the named instance would be used.
+
+To restore the old behaviour, set `inherit` to `false` on the named instance:
+
+```php
+$rule = [];
+$rule['shared'] = true;
+
+$dice->addRule('MyClass', $rule);
+
+$rule = [];
+$rule['instanceOf'] = 'MyClass';
+$rule['constructParams'] = ['Foo', 'Bar'];
+
+
+//Prevent the named instance inheriting rules from the class named in `instanceOf`:
+$rule['inherit'] = false;
+
+$dice->addRule('$MyNamedInstance', $rule);
+
+```
+
+
+
+
+29/10/2014
+* Based on [Issue #15](https://github.com/TomBZombie/Dice/issues/15), Dice will now only call closures if they are wrapped in \Dice\Instance. **PLEASE NOTE: THIS IS BACKWARDS INCOMPATIBLE **.
+
+Previously Dice ran closures that were passed as substitutions, constructParams and when calling methods:
+
+```php
+
+$rule->substitutions['A'] = function() {
+ return new A;
+};
+
+$rule->call[] = ['someMethod', function() {
+// '2' will be provided as the first argument when someMethod is called
+return 2;
+}];
+
+$rule->constructParams[] = function() {
+ //'abc' will be providedas the first constructor parameter
+ return 'abc';
+};
+```
+
+This behaviour has changed as it makes it impossible to provide a closure as a construct parameter or when calling a method because the closure was always called and executed.
+
+To overcome this, Dice will now only call a closures if they're wrapped in \Dice\Instance:
+
+```php
+$rule->substitutions['A'] = ['instance' => function() {
+ return new A;
+}];
+
+$rule->call[] = ['someMethod', ['instance' => function() {
+// '2' will be provided as the first argument when someMethod is called
+return 2;
+}]]);
+
+$rule->constructParams[] = ['instance' => function() { {
+ //'abc' will be providedas the first constructor parameter
+ return 'abc';
+}]);
+```
+
+
+
+
+
+04/09/2014
+* Pushed PHP5.6 branch live. This is slightly more efficient using PHP5.6 features. For PHP5.4-PHP5.5 please see the relevant branch. This version will be maintained until PHP5.6 is more widespread.
+
+
+26/08/2014
+* Added PHP5.6 branch. Tidied up code by using PHP5.6 features. This will be moved to master when PHP5.6 is released
+
+28/06/2014
+* Greatly improved efficienty. Dice is now the fastest Dependency Injection Container for PHP!
+
+06/06/2014
+* Added support for cyclic references ( https://github.com/TomBZombie/Dice/issues/7 ). Please note this is poor design but this fix will stop the infinite loop this design creates.
+
+27/03/2014
+* Removed assign() method as this duplicated functionality available using $rule->shared
+* Removed $callback argument in $dice->create() as the only real use for this feature can be better achieved using $rule->shareInstances
+* Tidied up code, removing unused/undocumented features. Dice is now even more lightweight and faster.
+* Fixed a bug where when using $rule->call it would use the substitution rules from the constructor on each method called
+* Updated [Dice documentation](https://r.je/dice.html) to use shorthand array syntax
+
+01/03/2014
+* Added test cases for the Xml Loader and Loader Callback classes
+* Added a JSON loader + test case
+* Added all test cases to a test suite
+* Moved to PHP5.4 array syntax. A PHP5.3 compatible version is now available in the PHP5.3 branch.
+* Fixed an issue where using named instances would trigger the autoloader with an invalid class name every time a class was created
+
+
+28/02/2014
+* Added basic namespace support. Documentation update will follow shortly. Also moved the XML loader into its own file, you'll need to include it separately if you're using it.
+* Please note: CHANGES ARE NOT BACKWARDS COMPATIBLE. However they are easily fixed by doing the following find/replaces:
+
+```php
+ new Dice => new \Dice\Dice
+ new DiceInstance => new \Dice\Instance
+ new DiceRule => new \Dice\Rule
+```
diff --git a/vendor-scoped/mistic100/randomcolor/src/RandomColor.php b/vendor-scoped/mistic100/randomcolor/src/RandomColor.php
new file mode 100644
index 0000000..f0ef4cd
--- /dev/null
+++ b/vendor-scoped/mistic100/randomcolor/src/RandomColor.php
@@ -0,0 +1,259 @@
+ '', 'hue' => [], 'luminosity' => ''], $options);
+ $h = self::_pickHue($options);
+ $s = self::_pickSaturation($h, $options);
+ $v = self::_pickBrightness($h, $s, $options);
+ return self::format(\compact('h', 's', 'v'), @$options['format']);
+ }
+ public static function many($count, $options = array())
+ {
+ $colors = array();
+ for ($i = 0; $i < $count; $i++) {
+ $colors[] = self::one($options);
+ }
+ return $colors;
+ }
+ public static function format($hsv, $format = 'hex')
+ {
+ switch ($format) {
+ case 'hsv':
+ return $hsv;
+ case 'hsl':
+ return self::hsv2hsl($hsv);
+ case 'hslCss':
+ $hsl = self::hsv2hsl($hsv);
+ return 'hsl(' . $hsl['h'] . ',' . $hsl['s'] . '%,' . $hsl['l'] . '%)';
+ case 'rgb':
+ return self::hsv2rgb($hsv);
+ case 'rgbCss':
+ return 'rgb(' . \implode(',', self::hsv2rgb($hsv)) . ')';
+ case 'hex':
+ default:
+ return self::hsv2hex($hsv);
+ }
+ }
+ private static function _pickHue($options)
+ {
+ $range = self::_getHueRange($options);
+ if (empty($range)) {
+ return 0;
+ }
+ $hue = self::_rand($range, $options);
+ // Instead of storing red as two separate ranges,
+ // we group them, using negative numbers
+ if ($hue < 0) {
+ $hue = 360 + $hue;
+ }
+ return $hue;
+ }
+ private static function _pickSaturation($h, $options)
+ {
+ if (@$options['hue'] === 'monochrome') {
+ return 0;
+ }
+ if (@$options['luminosity'] === 'random') {
+ return self::_rand(array(0, 100), $options);
+ }
+ $colorInfo = self::_getColorInfo($h);
+ $range = $colorInfo['s'];
+ switch (@$options['luminosity']) {
+ case 'bright':
+ $range[0] = 55;
+ break;
+ case 'dark':
+ $range[0] = $range[1] - 10;
+ break;
+ case 'light':
+ $range[1] = 55;
+ break;
+ }
+ return self::_rand($range, $options);
+ }
+ private static function _pickBrightness($h, $s, $options)
+ {
+ if (@$options['luminosity'] === 'random') {
+ $range = array(0, 100);
+ } else {
+ $range = array(self::_getMinimumBrightness($h, $s), 100);
+ switch (@$options['luminosity']) {
+ case 'dark':
+ $range[1] = $range[0] + 20;
+ break;
+ case 'light':
+ $range[0] = \round(($range[1] + $range[0]) / 2);
+ break;
+ }
+ }
+ return self::_rand($range, $options);
+ }
+ private static function _getHueRange($options)
+ {
+ $ranges = array();
+ if (isset($options['hue'])) {
+ if (!\is_array($options['hue'])) {
+ $options['hue'] = array($options['hue']);
+ }
+ foreach ($options['hue'] as $hue) {
+ if ($hue === 'random') {
+ $ranges[] = array(0, 360);
+ } else {
+ if (isset(self::$dictionary[$hue])) {
+ $ranges[] = self::$dictionary[$hue]['h'];
+ } else {
+ if (\is_numeric($hue)) {
+ $hue = \intval($hue);
+ if ($hue <= 360 && $hue >= 0) {
+ $ranges[] = array($hue, $hue);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (($l = \count($ranges)) === 0) {
+ return array(0, 360);
+ } else {
+ if ($l === 1) {
+ return $ranges[0];
+ } else {
+ return $ranges[self::_rand(array(0, $l - 1), $options)];
+ }
+ }
+ }
+ private static function _getMinimumBrightness($h, $s)
+ {
+ $colorInfo = self::_getColorInfo($h);
+ $bounds = $colorInfo['bounds'];
+ for ($i = 0, $l = \count($bounds); $i < $l - 1; $i++) {
+ $s1 = $bounds[$i][0];
+ $v1 = $bounds[$i][1];
+ $s2 = $bounds[$i + 1][0];
+ $v2 = $bounds[$i + 1][1];
+ if ($s >= $s1 && $s <= $s2) {
+ $m = ($v2 - $v1) / ($s2 - $s1);
+ $b = $v1 - $m * $s1;
+ return \round($m * $s + $b);
+ }
+ }
+ return 0;
+ }
+ private static function _getColorInfo($h)
+ {
+ // Maps red colors to make picking hue easier
+ if ($h >= 334 && $h <= 360) {
+ $h -= 360;
+ }
+ foreach (self::$dictionary as $color) {
+ if ($color['h'] !== null && $h >= $color['h'][0] && $h <= $color['h'][1]) {
+ return $color;
+ }
+ }
+ }
+ private static function _rand($bounds, $options)
+ {
+ if (isset($options['prng'])) {
+ return $options['prng']($bounds[0], $bounds[1]);
+ } else {
+ return \mt_rand($bounds[0], $bounds[1]);
+ }
+ }
+ public static function hsv2hex($hsv)
+ {
+ $rgb = self::hsv2rgb($hsv);
+ $hex = '#';
+ foreach ($rgb as $c) {
+ $hex .= \str_pad(\dechex($c), 2, '0', \STR_PAD_LEFT);
+ }
+ return $hex;
+ }
+ public static function hsv2hsl($hsv)
+ {
+ \extract($hsv);
+ $s /= 100;
+ $v /= 100;
+ $k = (2 - $s) * $v;
+ return array('h' => $h, 's' => \round($s * $v / ($k < 1 ? $k : 2 - $k), 4) * 100, 'l' => $k / 2 * 100);
+ }
+ public static function hsv2rgb($hsv)
+ {
+ \extract($hsv);
+ $h /= 360;
+ $s /= 100;
+ $v /= 100;
+ $i = \floor($h * 6);
+ $f = $h * 6 - $i;
+ $m = $v * (1 - $s);
+ $n = $v * (1 - $s * $f);
+ $k = $v * (1 - $s * (1 - $f));
+ $r = 1;
+ $g = 1;
+ $b = 1;
+ switch ($i) {
+ case 0:
+ list($r, $g, $b) = array($v, $k, $m);
+ break;
+ case 1:
+ list($r, $g, $b) = array($n, $v, $m);
+ break;
+ case 2:
+ list($r, $g, $b) = array($m, $v, $k);
+ break;
+ case 3:
+ list($r, $g, $b) = array($m, $n, $v);
+ break;
+ case 4:
+ list($r, $g, $b) = array($k, $m, $v);
+ break;
+ case 5:
+ case 6:
+ list($r, $g, $b) = array($v, $m, $n);
+ break;
+ }
+ return array('r' => \floor($r * 255), 'g' => \floor($g * 255), 'b' => \floor($b * 255));
+ }
+}
+/*
+ * h=hueRange
+ * s=saturationRange : bounds[0][0] ; bounds[-][0]
+ */
+RandomColor::$dictionary = array('monochrome' => array('bounds' => array(array(0, 0), array(100, 0)), 'h' => NULL, 's' => array(0, 100)), 'red' => array('bounds' => array(array(20, 100), array(30, 92), array(40, 89), array(50, 85), array(60, 78), array(70, 70), array(80, 60), array(90, 55), array(100, 50)), 'h' => array(-26, 18), 's' => array(20, 100)), 'orange' => array('bounds' => array(array(20, 100), array(30, 93), array(40, 88), array(50, 86), array(60, 85), array(70, 70), array(100, 70)), 'h' => array(19, 46), 's' => array(20, 100)), 'yellow' => array('bounds' => array(array(25, 100), array(40, 94), array(50, 89), array(60, 86), array(70, 84), array(80, 82), array(90, 80), array(100, 75)), 'h' => array(47, 62), 's' => array(25, 100)), 'green' => array('bounds' => array(array(30, 100), array(40, 90), array(50, 85), array(60, 81), array(70, 74), array(80, 64), array(90, 50), array(100, 40)), 'h' => array(63, 178), 's' => array(30, 100)), 'blue' => array('bounds' => array(array(20, 100), array(30, 86), array(40, 80), array(50, 74), array(60, 60), array(70, 52), array(80, 44), array(90, 39), array(100, 35)), 'h' => array(179, 257), 's' => array(20, 100)), 'purple' => array('bounds' => array(array(20, 100), array(30, 87), array(40, 79), array(50, 70), array(60, 65), array(70, 59), array(80, 52), array(90, 45), array(100, 42)), 'h' => array(258, 282), 's' => array(20, 100)), 'pink' => array('bounds' => array(array(20, 100), array(30, 90), array(40, 86), array(60, 84), array(80, 80), array(90, 75), array(100, 73)), 'h' => array(283, 334), 's' => array(20, 100)));
diff --git a/vendor-scoped/mundschenk-at/check-wp-requirements/LICENSE b/vendor-scoped/mundschenk-at/check-wp-requirements/LICENSE
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/vendor-scoped/mundschenk-at/check-wp-requirements/LICENSE
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ , 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/vendor-scoped/mundschenk-at/check-wp-requirements/README.md b/vendor-scoped/mundschenk-at/check-wp-requirements/README.md
new file mode 100644
index 0000000..4823b0f
--- /dev/null
+++ b/vendor-scoped/mundschenk-at/check-wp-requirements/README.md
@@ -0,0 +1,59 @@
+# check-wp-requirements
+
+[![Build Status](https://travis-ci.com/mundschenk-at/check-wp-requirements.svg?branch=master)](https://travis-ci.com/mundschenk-at/check-wp-requirements)
+[![Latest Stable Version](https://poser.pugx.org/mundschenk-at/check-wp-requirements/v/stable)](https://packagist.org/packages/mundschenk-at/check-wp-requirements)
+[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/mundschenk-at/check-wp-requirements/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/mundschenk-at/check-wp-requirements/?branch=master)
+[![Code Coverage](https://scrutinizer-ci.com/g/mundschenk-at/check-wp-requirements/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/mundschenk-at/check-wp-requirements/?branch=master)
+[![License](https://poser.pugx.org/mundschenk-at/check-wp-requirements/license)](https://packagist.org/packages/mundschenk-at/check-wp-requirements)
+
+A helper class for WordPress plugins to check PHP version and other requirements.
+
+## Requirements
+
+* PHP 5.6.0 or above
+* WordPress 5.2 or higher.
+
+## Installation
+
+The best way to use this package is through Composer:
+
+```BASH
+$ composer require mundschenk-at/check-wp-requirements
+```
+
+## Basic Usage
+
+1. Create a `\Mundschenk\WP_Requirements` object and set the requirements in the constructor.
+2. Call the `\Mundschenk\WP_Requirements::check()` method and start your plugin normally if it
+ returns `true`.
+
+```PHP
+// Set up autoloader.
+require_once __DIR__ . '/vendor/autoload.php';
+
+/**
+ * Load the plugin after checking for the necessary PHP version.
+ *
+ * It's necessary to do this here because main class relies on namespaces.
+ */
+function run_your_plugin() {
+
+ $requirements = new \Mundschenk\WP_Requirements( 'Your Plugin Name', __FILE__, 'your-textdomain', [
+ 'php' => '5.6.0',
+ 'multibyte' => true,
+ 'utf-8' => false,
+ ] );
+
+ if ( $requirements->check() ) {
+ // Autoload the rest of your classes.
+
+ // Create and start the plugin.
+ ...
+ }
+}
+run_your_plugin();
+```
+
+## License
+
+check-wp-requirements is licensed under the GNU General Public License 2 or later - see the [LICENSE](LICENSE) file for details.
diff --git a/vendor-scoped/mundschenk-at/check-wp-requirements/class-wp-requirements.php b/vendor-scoped/mundschenk-at/check-wp-requirements/class-wp-requirements.php
new file mode 100644
index 0000000..9bfa1cc
--- /dev/null
+++ b/vendor-scoped/mundschenk-at/check-wp-requirements/class-wp-requirements.php
@@ -0,0 +1,219 @@
+plugin_name = $name;
+ $this->plugin_file = $plugin_path;
+ $this->textdomain = $textdomain;
+ $this->base_dir = \dirname(__FILE__);
+ $this->install_requirements = \wp_parse_args($requirements, ['php' => '5.2.0', 'multibyte' => \false, 'utf-8' => \false]);
+ }
+ /**
+ * Checks if all runtime requirements for the plugin are met.
+ *
+ * @return bool
+ */
+ public function check()
+ {
+ $requirements_met = \true;
+ foreach ($this->get_requirements() as $requirement) {
+ if (!empty($this->install_requirements[$requirement['enable_key']]) && !\call_user_func($requirement['check'])) {
+ $notice = $requirement['notice'];
+ $requirements_met = \false;
+ break;
+ }
+ }
+ if (!$requirements_met && !empty($notice) && \is_admin()) {
+ // Load text domain to ensure translated admin notices.
+ \load_plugin_textdomain($this->textdomain);
+ // Add admin notice.
+ \add_action('admin_notices', $notice);
+ }
+ return $requirements_met;
+ }
+ /**
+ * Retrieves an array of requirement specifications.
+ *
+ * @return array {
+ * An array of requirements checks.
+ *
+ * @type string $enable_key An index in the $install_requirements array to switch the check on and off.
+ * @type callable $check A function returning true if the check was successful, false otherwise.
+ * @type callable $notice A function displaying an appropriate error notice.
+ * }
+ */
+ protected function get_requirements()
+ {
+ return [['enable_key' => 'php', 'check' => [$this, 'check_php_support'], 'notice' => [$this, 'admin_notices_php_version_incompatible']], ['enable_key' => 'multibyte', 'check' => [$this, 'check_multibyte_support'], 'notice' => [$this, 'admin_notices_mbstring_incompatible']], ['enable_key' => 'utf-8', 'check' => [$this, 'check_utf8_support'], 'notice' => [$this, 'admin_notices_charset_incompatible']]];
+ }
+ /**
+ * Deactivates the plugin.
+ */
+ public function deactivate_plugin()
+ {
+ \deactivate_plugins(\plugin_basename($this->plugin_file));
+ }
+ /**
+ * Checks if the PHP version in use is at least equal to the required version.
+ *
+ * @return bool
+ */
+ protected function check_php_support()
+ {
+ return \version_compare(\PHP_VERSION, $this->install_requirements['php'], '>=');
+ }
+ /**
+ * Checks if multibyte functions are supported.
+ *
+ * @return bool
+ */
+ protected function check_multibyte_support()
+ {
+ return \function_exists('mb_strlen') && \function_exists('mb_strtolower') && \function_exists('mb_substr') && \function_exists('mb_detect_encoding');
+ }
+ /**
+ * Checks if the blog charset is set to UTF-8.
+ *
+ * @return bool
+ */
+ protected function check_utf8_support()
+ {
+ return 'utf-8' === \strtolower(\get_bloginfo('charset'));
+ }
+ /**
+ * Print 'PHP version incompatible' admin notice
+ */
+ public function admin_notices_php_version_incompatible()
+ {
+ $this->display_error_notice(
+ /* translators: 1: plugin name 2: target PHP version number 3: actual PHP version number */
+ \__('The activated plugin %1$s requires PHP %2$s or later. Your server is running PHP %3$s. Please deactivate this plugin, or upgrade your server\'s installation of PHP.', $this->textdomain),
+ "{$this->plugin_name}",
+ $this->install_requirements['php'],
+ \PHP_VERSION
+ );
+ }
+ /**
+ * Prints 'mbstring extension missing' admin notice
+ */
+ public function admin_notices_mbstring_incompatible()
+ {
+ $this->display_error_notice(
+ /* translators: 1: plugin name 2: mbstring documentation URL */
+ \__('The activated plugin %1$s requires the mbstring PHP extension to be enabled on your server. Please deactivate this plugin, or enable the extension.', $this->textdomain),
+ "{$this->plugin_name}",
+ /* translators: URL with mbstring PHP extension installation instructions */
+ \__('http://www.php.net/manual/en/mbstring.installation.php', $this->textdomain)
+ );
+ }
+ /**
+ * Prints 'Charset incompatible' admin notice
+ */
+ public function admin_notices_charset_incompatible()
+ {
+ $this->display_error_notice(
+ /* translators: 1: plugin name 2: current character encoding 3: options URL */
+ \__('The activated plugin %1$s requires your blog use the UTF-8 character encoding. You have set your blogs encoding to %2$s. Please deactivate this plugin, or change your character encoding to UTF-8.', $this->textdomain),
+ "{$this->plugin_name}",
+ \get_bloginfo('charset'),
+ '/wp-admin/options-reading.php'
+ );
+ }
+ /**
+ * Shows an error message in the admin area.
+ *
+ * @param string $format ... An `sprintf` format string, followd by an unspecified number of optional parameters.
+ */
+ protected function display_error_notice($format)
+ {
+ if (\func_num_args() < 1 || empty($format)) {
+ return;
+ // abort.
+ }
+ $args = \func_get_args();
+ $format = \array_shift($args);
+ $message = \vsprintf($format, $args);
+ require "{$this->base_dir}/partials/requirements-error-notice.php";
+ }
+}
diff --git a/vendor-scoped/mundschenk-at/check-wp-requirements/partials/requirements-error-notice.php b/vendor-scoped/mundschenk-at/check-wp-requirements/partials/requirements-error-notice.php
new file mode 100644
index 0000000..518f4fb
--- /dev/null
+++ b/vendor-scoped/mundschenk-at/check-wp-requirements/partials/requirements-error-notice.php
@@ -0,0 +1,31 @@
+
+
+
+
+
+ Copyright (C)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ , 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/vendor-scoped/mundschenk-at/wp-data-storage/README.md b/vendor-scoped/mundschenk-at/wp-data-storage/README.md
new file mode 100644
index 0000000..6d8de5e
--- /dev/null
+++ b/vendor-scoped/mundschenk-at/wp-data-storage/README.md
@@ -0,0 +1,22 @@
+# WordPress Data Storage
+
+[![Build Status](https://travis-ci.org/mundschenk-at/wp-data-storage.svg?branch=master)](https://travis-ci.org/mundschenk-at/wp-data-storage)
+[![Latest Stable Version](https://poser.pugx.org/mundschenk-at/wp-data-storage/v/stable)](https://packagist.org/packages/mundschenk-at/wp-data-storage)
+[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/mundschenk-at/wp-data-storage/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/mundschenk-at/wp-data-storage/?branch=master)
+[![Code Coverage](https://scrutinizer-ci.com/g/mundschenk-at/wp-data-storage/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/mundschenk-at/wp-data-storage/?branch=master)
+[![License](https://poser.pugx.org/mundschenk-at/wp-data-storage/license)](https://packagist.org/packages/mundschenk-at/wp-data-storage)
+
+An object oriented library for dealing with WordPress options and caching.
+
+## Requirements
+
+* PHP 5.6.0 or above
+* WordPress 4.4 or higher (for transient keys longer than 64 characters).
+
+## Installation
+
+The best way to use this package is through Composer:
+
+```BASH
+$ composer require mundschenk-at/wp-data-storage
+```
diff --git a/vendor-scoped/mundschenk-at/wp-data-storage/src/class-abstract-cache.php b/vendor-scoped/mundschenk-at/wp-data-storage/src/class-abstract-cache.php
new file mode 100644
index 0000000..48f55b9
--- /dev/null
+++ b/vendor-scoped/mundschenk-at/wp-data-storage/src/class-abstract-cache.php
@@ -0,0 +1,112 @@
+
+ */
+abstract class Abstract_Cache
+{
+ /**
+ * Incrementor for cache invalidation.
+ *
+ * @var int
+ */
+ protected $incrementor;
+ /**
+ * The prefix added to all keys.
+ *
+ * @var string
+ */
+ private $prefix;
+ /**
+ * Create new cache instance.
+ *
+ * @param string $prefix The prefix automatically added to cache keys.
+ */
+ public function __construct($prefix)
+ {
+ $this->prefix = $prefix;
+ if (empty($this->incrementor)) {
+ $this->invalidate();
+ }
+ }
+ /**
+ * Invalidate all cached elements by reseting the incrementor.
+ *
+ * @return void
+ */
+ public abstract function invalidate();
+ /**
+ * Retrieves a cached value.
+ *
+ * @param string $key The cache key root.
+ *
+ * @return mixed
+ */
+ public abstract function get($key);
+ /**
+ * Sets an entry in the cache and stores the key.
+ *
+ * @param string $key The cache key root.
+ * @param mixed $value The value to store.
+ * @param int $duration Optional. The duration in seconds. Default 0 (no expiration).
+ *
+ * @return bool True if the cache could be set successfully.
+ */
+ public abstract function set($key, $value, $duration = 0);
+ /**
+ * Deletes an entry from the cache.
+ *
+ * @param string $key The cache key root.
+ *
+ * @return bool True on successful removal, false on failure.
+ */
+ public abstract function delete($key);
+ /**
+ * Retrieves the complete key to use.
+ *
+ * @param string $key The cache key root.
+ *
+ * @return string
+ */
+ protected function get_key($key)
+ {
+ return "{$this->prefix}{$this->incrementor}_{$key}";
+ }
+ /**
+ * Retrieves the set prefix.
+ *
+ * @return string
+ */
+ protected function get_prefix()
+ {
+ return $this->prefix;
+ }
+}
diff --git a/vendor-scoped/mundschenk-at/wp-data-storage/src/class-cache.php b/vendor-scoped/mundschenk-at/wp-data-storage/src/class-cache.php
new file mode 100644
index 0000000..50e0446
--- /dev/null
+++ b/vendor-scoped/mundschenk-at/wp-data-storage/src/class-cache.php
@@ -0,0 +1,105 @@
+
+ */
+class Cache extends Abstract_Cache
+{
+ /**
+ * The incrementor cache key.
+ *
+ * @var string
+ */
+ private $incrementor_key;
+ /**
+ * The cache group.
+ *
+ * @var string
+ */
+ private $group;
+ /**
+ * Create new cache instance.
+ *
+ * @param string $prefix The prefix automatically added to cache keys.
+ * @param string|null $group Optional. The cache group. Defaults to $prefix.
+ */
+ public function __construct($prefix, $group = null)
+ {
+ $this->group = !isset($group) ? $prefix : $group;
+ $this->incrementor_key = "{$prefix}cache_incrementor";
+ $this->incrementor = (int) \wp_cache_get($this->incrementor_key, $this->group);
+ parent::__construct($prefix);
+ }
+ /**
+ * Invalidate all cached elements by reseting the incrementor.
+ */
+ public function invalidate()
+ {
+ $this->incrementor = \time();
+ \wp_cache_set($this->incrementor_key, $this->incrementor, $this->group, 0);
+ }
+ /**
+ * Retrieves a cached value.
+ *
+ * @param string $key The cache key.
+ * @param bool|null $found Optional. Whether the key was found in the cache. Disambiguates a return of false as a storable value. Passed by reference. Default null.
+ *
+ * @return mixed
+ */
+ public function get($key, &$found = null)
+ {
+ return \wp_cache_get($this->get_key($key), $this->group, \false, $found);
+ }
+ /**
+ * Sets an entry in the cache and stores the key.
+ *
+ * @param string $key The cache key.
+ * @param mixed $value The value to store.
+ * @param int $duration Optional. The duration in seconds. Default 0 (no expiration).
+ *
+ * @return bool True if the cache could be set successfully.
+ */
+ public function set($key, $value, $duration = 0)
+ {
+ return \wp_cache_set($this->get_key($key), $value, $this->group, $duration);
+ }
+ /**
+ * Deletes an entry from the cache.
+ *
+ * @param string $key The cache key root.
+ *
+ * @return bool True on successful removal, false on failure.
+ */
+ public function delete($key)
+ {
+ return \wp_cache_delete($this->get_key($key), $this->group);
+ }
+}
diff --git a/vendor-scoped/mundschenk-at/wp-data-storage/src/class-network-options.php b/vendor-scoped/mundschenk-at/wp-data-storage/src/class-network-options.php
new file mode 100644
index 0000000..7df5f5a
--- /dev/null
+++ b/vendor-scoped/mundschenk-at/wp-data-storage/src/class-network-options.php
@@ -0,0 +1,97 @@
+
+ */
+class Network_Options extends Options
+{
+ /**
+ * The network ID.
+ *
+ * @var int
+ */
+ private $network_id;
+ /**
+ * Create new Network Options instance.
+ *
+ * @param string $prefix The prefix automatically added to option names.
+ * @param int|null $network_id Optional. The network ID or null for the current network. Default null.
+ */
+ public function __construct($prefix, $network_id = null)
+ {
+ $this->network_id = !empty($network_id) ? $network_id : \get_current_network_id();
+ parent::__construct($prefix);
+ }
+ /**
+ * Retrieves an option value.
+ *
+ * @param string $option The option name (without the plugin-specific prefix).
+ * @param mixed $default Optional. Default value to return if the option does not exist. Default null.
+ * @param bool $raw Optional. Use the raw option name (i.e. don't call get_name). Default false.
+ *
+ * @return mixed Value set for the option.
+ */
+ public function get($option, $default = null, $raw = \false)
+ {
+ $value = \get_network_option($this->network_id, $raw ? $option : $this->get_name($option), $default);
+ if (\is_array($default) && '' === $value) {
+ $value = [];
+ }
+ return $value;
+ }
+ /**
+ * Sets or updates an option.
+ *
+ * @param string $option The option name (without the plugin-specific prefix).
+ * @param mixed $value The value to store.
+ * @param bool $autoload Optional. This value is ignored for network options,
+ * which are always autoloaded. Default true.
+ * @param bool $raw Optional. Use the raw option name (i.e. don't call get_name). Default false.
+ *
+ * @return bool False if value was not updated and true if value was updated.
+ */
+ public function set($option, $value, $autoload = \true, $raw = \false)
+ {
+ return \update_network_option($this->network_id, $raw ? $option : $this->get_name($option), $value);
+ }
+ /**
+ * Deletes an option.
+ *
+ * @param string $option The option name (without the plugin-specific prefix).
+ * @param bool $raw Optional. Use the raw option name (i.e. don't call get_name). Default false.
+ *
+ * @return bool True, if option is successfully deleted. False on failure.
+ */
+ public function delete($option, $raw = \false)
+ {
+ return \delete_network_option($this->network_id, $raw ? $option : $this->get_name($option));
+ }
+}
diff --git a/vendor-scoped/mundschenk-at/wp-data-storage/src/class-options.php b/vendor-scoped/mundschenk-at/wp-data-storage/src/class-options.php
new file mode 100644
index 0000000..1ab49dc
--- /dev/null
+++ b/vendor-scoped/mundschenk-at/wp-data-storage/src/class-options.php
@@ -0,0 +1,108 @@
+
+ */
+class Options
+{
+ /**
+ * The prefix added to all keys.
+ *
+ * @var string
+ */
+ private $prefix;
+ /**
+ * Create new Options instance.
+ *
+ * @param string $prefix The prefix automatically added to option names.
+ */
+ public function __construct($prefix)
+ {
+ $this->prefix = $prefix;
+ }
+ /**
+ * Retrieves an option value.
+ *
+ * @param string $option The option name (without the plugin-specific prefix).
+ * @param mixed $default Optional. Default value to return if the option does not exist. Default null.
+ * @param bool $raw Optional. Use the raw option name (i.e. don't call get_name). Default false.
+ *
+ * @return mixed Value set for the option.
+ */
+ public function get($option, $default = null, $raw = \false)
+ {
+ $value = \get_option($raw ? $option : $this->get_name($option), $default);
+ if (\is_array($default) && '' === $value) {
+ $value = [];
+ }
+ return $value;
+ }
+ /**
+ * Sets or updates an option.
+ *
+ * @param string $option The option name (without the plugin-specific prefix).
+ * @param mixed $value The value to store.
+ * @param bool $autoload Optional. Whether to load the option when WordPress
+ * starts up. For existing options, $autoload can only
+ * be updated using update_option() if $value is also
+ * changed. Default true.
+ * @param bool $raw Optional. Use the raw option name (i.e. don't call get_name). Default false.
+ *
+ * @return bool False if value was not updated and true if value was updated.
+ */
+ public function set($option, $value, $autoload = \true, $raw = \false)
+ {
+ return \update_option($raw ? $option : $this->get_name($option), $value, $autoload);
+ }
+ /**
+ * Deletes an option.
+ *
+ * @param string $option The option name (without the plugin-specific prefix).
+ * @param bool $raw Optional. Use the raw option name (i.e. don't call get_name). Default false.
+ *
+ * @return bool True, if option is successfully deleted. False on failure.
+ */
+ public function delete($option, $raw = \false)
+ {
+ return \delete_option($raw ? $option : $this->get_name($option));
+ }
+ /**
+ * Retrieves the complete option name to use.
+ *
+ * @param string $option The option name (without the plugin-specific prefix).
+ *
+ * @return string
+ */
+ public function get_name($option)
+ {
+ return "{$this->prefix}{$option}";
+ }
+}
diff --git a/vendor-scoped/mundschenk-at/wp-data-storage/src/class-site-transients.php b/vendor-scoped/mundschenk-at/wp-data-storage/src/class-site-transients.php
new file mode 100644
index 0000000..d98607f
--- /dev/null
+++ b/vendor-scoped/mundschenk-at/wp-data-storage/src/class-site-transients.php
@@ -0,0 +1,96 @@
+
+ */
+class Site_Transients extends Transients
+{
+ const TRANSIENT_SQL_PREFIX = '_site_transient_';
+ /**
+ * Retrieves a list of transients set by the plugin from the options table.
+ *
+ * @return string[]
+ */
+ public function get_keys_from_database()
+ {
+ // If we are not running on multisite, fall back to the parent implementation.
+ if (!\is_multisite()) {
+ return parent::get_keys_from_database();
+ }
+ /**
+ * WordPress database handler.
+ *
+ * @var \wpdb
+ */
+ global $wpdb;
+ $results = $wpdb->get_results($wpdb->prepare("SELECT meta_key FROM {$wpdb->sitemeta} WHERE meta_key like %s and site_id = %d", self::TRANSIENT_SQL_PREFIX . "{$this->get_prefix()}%", \get_current_network_id()), \ARRAY_A);
+ // WPCS: db call ok, cache ok.
+ return \str_replace(self::TRANSIENT_SQL_PREFIX, '', \wp_list_pluck($results, 'meta_key'));
+ }
+ /**
+ * Retrieves a cached value.
+ *
+ * @param string $key The cache key.
+ * @param bool $raw Optional. Use the raw key name (i.e. don't call get_key). Default false.
+ *
+ * @return mixed
+ */
+ public function get($key, $raw = \false)
+ {
+ return \get_site_transient($raw ? $key : $this->get_key($key));
+ }
+ /**
+ * Sets an entry in the cache and stores the key.
+ *
+ * @param string $key The cache key.
+ * @param mixed $value The value to store.
+ * @param int $duration Optional. The duration in seconds. Default 0 (no expiration).
+ * @param bool $raw Optional. Use the raw key name (i.e. don't call get_key). Default false.
+ *
+ * @return bool True if the cache could be set successfully.
+ */
+ public function set($key, $value, $duration = 0, $raw = \false)
+ {
+ return \set_site_transient($raw ? $key : $this->get_key($key), $value, $duration);
+ }
+ /**
+ * Deletes an entry from the cache.
+ *
+ * @param string $key The cache key root.
+ * @param bool $raw Optional. Use the raw key name (i.e. don't call get_key). Default false.
+ *
+ * @return bool True on successful removal, false on failure.
+ */
+ public function delete($key, $raw = \false)
+ {
+ return \delete_site_transient($raw ? $key : $this->get_key($key));
+ }
+}
diff --git a/vendor-scoped/mundschenk-at/wp-data-storage/src/class-transients.php b/vendor-scoped/mundschenk-at/wp-data-storage/src/class-transients.php
new file mode 100644
index 0000000..be9ecc2
--- /dev/null
+++ b/vendor-scoped/mundschenk-at/wp-data-storage/src/class-transients.php
@@ -0,0 +1,183 @@
+
+ */
+class Transients extends Abstract_Cache
+{
+ const TRANSIENT_SQL_PREFIX = '_transient_';
+ /**
+ * The incrementor transient key.
+ *
+ * @var string
+ */
+ protected $incrementor_key;
+ /**
+ * Create new cache instance.
+ *
+ * @param string $prefix The prefix automatically added to transient names.
+ */
+ public function __construct($prefix)
+ {
+ $this->incrementor_key = $prefix . 'transients_incrementor';
+ $this->incrementor = $this->get($this->incrementor_key, \true);
+ parent::__construct($prefix);
+ }
+ /**
+ * Invalidate all cached elements by reseting the incrementor.
+ */
+ public function invalidate()
+ {
+ if (!\wp_using_ext_object_cache()) {
+ // Clean up old transients.
+ foreach ($this->get_keys_from_database() as $old_transient) {
+ $this->delete($old_transient, \true);
+ }
+ }
+ // Update incrementor.
+ $this->incrementor = \time();
+ $this->set($this->incrementor_key, $this->incrementor, 0, \true);
+ }
+ /**
+ * Retrieves a list of transients set by the plugin from the options table.
+ *
+ * @return string[]
+ */
+ public function get_keys_from_database()
+ {
+ /**
+ * WordPress database handler.
+ *
+ * @var \wpdb
+ */
+ global $wpdb;
+ $results = $wpdb->get_results($wpdb->prepare("SELECT option_name FROM {$wpdb->options} WHERE option_name like %s", static::TRANSIENT_SQL_PREFIX . "{$this->get_prefix()}%"), \ARRAY_A);
+ // WPCS: db call ok, cache ok.
+ return \str_replace(static::TRANSIENT_SQL_PREFIX, '', \wp_list_pluck($results, 'option_name'));
+ }
+ /**
+ * Retrieves a cached value.
+ *
+ * @param string $key The cache key.
+ * @param bool $raw Optional. Use the raw key name (i.e. don't call get_key). Default false.
+ *
+ * @return mixed
+ */
+ public function get($key, $raw = \false)
+ {
+ return \get_transient($raw ? $key : $this->get_key($key));
+ }
+ /**
+ * Retrieves a cached large object.
+ *
+ * @param string $key The cache key.
+ *
+ * @return mixed
+ */
+ public function get_large_object($key)
+ {
+ $encoded = $this->get($key);
+ if (\false === $encoded) {
+ return \false;
+ }
+ $uncompressed = @\gzdecode(\base64_decode($encoded));
+ // @codingStandardsIgnoreLine
+ if (\false === $uncompressed) {
+ return \false;
+ }
+ return $this->maybe_fix_object(\unserialize($uncompressed));
+ // @codingStandardsIgnoreLine
+ }
+ /**
+ * Sets an entry in the cache and stores the key.
+ *
+ * @param string $key The cache key.
+ * @param mixed $value The value to store.
+ * @param int $duration Optional. The duration in seconds. Default 0 (no expiration).
+ * @param bool $raw Optional. Use the raw key name (i.e. don't call get_key). Default false.
+ *
+ * @return bool True if the cache could be set successfully.
+ */
+ public function set($key, $value, $duration = 0, $raw = \false)
+ {
+ return \set_transient($raw ? $key : $this->get_key($key), $value, $duration);
+ }
+ /**
+ * Sets a transient for a large PHP object. The object will be stored in
+ * serialized and gzip encoded form using Base64 encoding to ensure binary safety.
+ *
+ * @param string $key The cache key.
+ * @param mixed $value The value to store.
+ * @param int $duration Optional. The duration in seconds. Default 0 (no expiration).
+ *
+ * @return bool True if the cache could be set successfully.
+ */
+ public function set_large_object($key, $value, $duration = 0)
+ {
+ $compressed = \gzencode(\serialize($value));
+ // @codingStandardsIgnoreLine
+ if (\false === $compressed) {
+ return \false;
+ // @codeCoverageIgnore
+ }
+ return $this->set($key, \base64_encode($compressed), $duration);
+ }
+ /**
+ * Deletes an entry from the cache.
+ *
+ * @param string $key The cache key root.
+ * @param bool $raw Optional. Use the raw key name (i.e. don't call get_key). Default false.
+ *
+ * @return bool True on successful removal, false on failure.
+ */
+ public function delete($key, $raw = \false)
+ {
+ return \delete_transient($raw ? $key : $this->get_key($key));
+ }
+ /**
+ * Tries to fix object cache implementations sometimes returning __PHP_Incomplete_Class.
+ *
+ * Originally based on http://stackoverflow.com/a/1173769/6646342 and refactored
+ * for PHP 7.2 compatibility.
+ *
+ * @param object $object An object that should have been unserialized, but may be of __PHP_Incomplete_Class.
+ *
+ * @return object The object with its real class.
+ */
+ protected function maybe_fix_object($object)
+ {
+ if ('__PHP_Incomplete_Class' === \get_class($object)) {
+ $object = \unserialize(\serialize($object));
+ // phpcs:disable WordPress.PHP.DiscouragedPHPFunctions.serialize_unserialize,WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
+ }
+ return $object;
+ }
+}
diff --git a/vendor-scoped/mundschenk-at/wp-settings-ui/LICENSE b/vendor-scoped/mundschenk-at/wp-settings-ui/LICENSE
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/vendor-scoped/mundschenk-at/wp-settings-ui/LICENSE
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ , 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/vendor-scoped/mundschenk-at/wp-settings-ui/README.md b/vendor-scoped/mundschenk-at/wp-settings-ui/README.md
new file mode 100644
index 0000000..36c0e37
--- /dev/null
+++ b/vendor-scoped/mundschenk-at/wp-settings-ui/README.md
@@ -0,0 +1,17 @@
+# WordPress Settings UI
+
+A library providing an object-oriented interface to the WordPress Settings API.
+
+## Features
+
+* A WordPress plugin's settings page can be specified as an array of textual properties.
+* A plugin can provide additional custom controls by implementing the `Mundschenk\UI\Control` interface.
+* Standard controls included with the library:
+ - Checkbox (`Mundschenk\UI\Controls\Checkbox_Input`),
+ - Text field (`Mundschenk\UI\Controls\Text_Input`),
+ - Number field (`Mundschenk\UI\Controls\Number_Input`),
+ - Hidden field (`Mundschenk\UI\Controls\Hidden_Input`),
+ - Submit button (`Mundschenk\UI\Controls\Submit_Input`),
+ - Select box (`Mundschenk\UI\Controls\Select`),
+ - Plain text (`Mundschenk\UI\Controls\Display_Text`), and
+ - Text Area (`Mundschenk\UI\Controls\Textarea`).
diff --git a/vendor-scoped/mundschenk-at/wp-settings-ui/partials/control.php b/vendor-scoped/mundschenk-at/wp-settings-ui/partials/control.php
new file mode 100644
index 0000000..f75a719
--- /dev/null
+++ b/vendor-scoped/mundschenk-at/wp-settings-ui/partials/control.php
@@ -0,0 +1,65 @@
+get_outer_html_attributes(); // These are already escaped.
+$outer_attributes = empty( $outer_attributes ) ? '' : " {$outer_attributes}";
+
+$control_id = $this->get_id();
+
+?>
+grouped_controls ) ) : ?>
+