Browse Source

Ship mexitek/phpcolors

Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
John Molakvoæ 2 years ago
parent
commit
48381b8913
27 changed files with 1732 additions and 11 deletions
  1. 0 5
      lib/composer/autoload.php
  2. 4 2
      lib/composer/composer/InstalledVersions.php
  3. 1 0
      lib/composer/composer/autoload_classmap.php
  4. 3 1
      lib/composer/composer/autoload_real.php
  5. 1 0
      lib/composer/composer/autoload_static.php
  6. 58 1
      lib/composer/composer/installed.json
  7. 11 2
      lib/composer/composer/installed.php
  8. 26 0
      lib/composer/composer/platform_check.php
  9. 17 0
      lib/composer/mexitek/phpcolors/.editorconfig
  10. 5 0
      lib/composer/mexitek/phpcolors/.gitignore
  11. 10 0
      lib/composer/mexitek/phpcolors/.phpcs.xml
  12. 11 0
      lib/composer/mexitek/phpcolors/.travis.yml
  13. 21 0
      lib/composer/mexitek/phpcolors/LICENSE
  14. 173 0
      lib/composer/mexitek/phpcolors/README.md
  15. 37 0
      lib/composer/mexitek/phpcolors/composer.json
  16. 94 0
      lib/composer/mexitek/phpcolors/demo/demo.php
  17. BIN
      lib/composer/mexitek/phpcolors/demo/phpColor-demo.png
  18. 801 0
      lib/composer/mexitek/phpcolors/src/Mexitek/PHPColors/Color.php
  19. 11 0
      lib/composer/mexitek/phpcolors/tests/bootstrap.php
  20. 35 0
      lib/composer/mexitek/phpcolors/tests/colorAnalyze.phpt
  21. 28 0
      lib/composer/mexitek/phpcolors/tests/colorChange.phpt
  22. 28 0
      lib/composer/mexitek/phpcolors/tests/colorComplementary.phpt
  23. 72 0
      lib/composer/mexitek/phpcolors/tests/colorConvertHslToHex.phpt
  24. 170 0
      lib/composer/mexitek/phpcolors/tests/colorConvertNameToHex.phpt
  25. 72 0
      lib/composer/mexitek/phpcolors/tests/colorConvertRgbToHex.phpt
  26. 19 0
      lib/composer/mexitek/phpcolors/tests/colorInput.phpt
  27. 24 0
      lib/composer/mexitek/phpcolors/tests/colorMix.phpt

+ 0 - 5
lib/composer/autoload.php

@@ -2,11 +2,6 @@
 
 // autoload.php @generated by Composer
 
-if (PHP_VERSION_ID < 50600) {
-    echo 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
-    exit(1);
-}
-
 require_once __DIR__ . '/composer/autoload_real.php';
 
 return ComposerAutoloaderInit53792487c5a8370acc0b06b1a864ff4c::getLoader();

+ 4 - 2
lib/composer/composer/InstalledVersions.php

@@ -21,6 +21,8 @@ use Composer\Semver\VersionParser;
  * See also https://getcomposer.org/doc/07-runtime.md#installed-versions
  *
  * To require its presence, you can require `composer-runtime-api ^2.0`
+ *
+ * @final
  */
 class InstalledVersions
 {
@@ -264,7 +266,7 @@ class InstalledVersions
         if (null === self::$installed) {
             // only require the installed.php file if this file is loaded from its dumped location,
             // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
-            if (substr(__DIR__, -8, 1) !== 'C' && is_file(__DIR__ . '/installed.php')) {
+            if (substr(__DIR__, -8, 1) !== 'C') {
                 self::$installed = include __DIR__ . '/installed.php';
             } else {
                 self::$installed = array();
@@ -337,7 +339,7 @@ class InstalledVersions
         if (null === self::$installed) {
             // only require the installed.php file if this file is loaded from its dumped location,
             // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
-            if (substr(__DIR__, -8, 1) !== 'C' && is_file(__DIR__ . '/installed.php')) {
+            if (substr(__DIR__, -8, 1) !== 'C') {
                 self::$installed = require __DIR__ . '/installed.php';
             } else {
                 self::$installed = array();

+ 1 - 0
lib/composer/composer/autoload_classmap.php

@@ -7,6 +7,7 @@ $baseDir = dirname(dirname($vendorDir));
 
 return array(
     'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
+    'Mexitek\\PHPColors\\Color' => $vendorDir . '/mexitek/phpcolors/src/Mexitek/PHPColors/Color.php',
     'OCP\\Accounts\\IAccount' => $baseDir . '/lib/public/Accounts/IAccount.php',
     'OCP\\Accounts\\IAccountManager' => $baseDir . '/lib/public/Accounts/IAccountManager.php',
     'OCP\\Accounts\\IAccountProperty' => $baseDir . '/lib/public/Accounts/IAccountProperty.php',

+ 3 - 1
lib/composer/composer/autoload_real.php

@@ -22,12 +22,14 @@ class ComposerAutoloaderInit53792487c5a8370acc0b06b1a864ff4c
             return self::$loader;
         }
 
+        require __DIR__ . '/platform_check.php';
+
         spl_autoload_register(array('ComposerAutoloaderInit53792487c5a8370acc0b06b1a864ff4c', 'loadClassLoader'), true, true);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
         spl_autoload_unregister(array('ComposerAutoloaderInit53792487c5a8370acc0b06b1a864ff4c', 'loadClassLoader'));
 
         require __DIR__ . '/autoload_static.php';
-        call_user_func(\Composer\Autoload\ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c::getInitializer($loader));
+        \Composer\Autoload\ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c::getInitializer($loader)();
 
         $loader->register(true);
 

+ 1 - 0
lib/composer/composer/autoload_static.php

@@ -36,6 +36,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
 
     public static $classMap = array (
         'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
+        'Mexitek\\PHPColors\\Color' => __DIR__ . '/..' . '/mexitek/phpcolors/src/Mexitek/PHPColors/Color.php',
         'OCP\\Accounts\\IAccount' => __DIR__ . '/../../..' . '/lib/public/Accounts/IAccount.php',
         'OCP\\Accounts\\IAccountManager' => __DIR__ . '/../../..' . '/lib/public/Accounts/IAccountManager.php',
         'OCP\\Accounts\\IAccountProperty' => __DIR__ . '/../../..' . '/lib/public/Accounts/IAccountProperty.php',

+ 58 - 1
lib/composer/composer/installed.json

@@ -1,5 +1,62 @@
 {
-    "packages": [],
+    "packages": [
+        {
+            "name": "mexitek/phpcolors",
+            "version": "v1.0.4",
+            "version_normalized": "1.0.4.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/mexitek/phpColors.git",
+                "reference": "4043974240ca7dc3c2bec3c158588148b605b206"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/mexitek/phpColors/zipball/4043974240ca7dc3c2bec3c158588148b605b206",
+                "reference": "4043974240ca7dc3c2bec3c158588148b605b206",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2|^8.0"
+            },
+            "require-dev": {
+                "nette/tester": "^2.3",
+                "squizlabs/php_codesniffer": "^3.5"
+            },
+            "time": "2021-11-26T13:19:08+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Arlo Carreon",
+                    "homepage": "http://arlocarreon.com",
+                    "role": "creator"
+                }
+            ],
+            "description": "A series of methods that let you manipulate colors. Just incase you ever need different shades of one color on the fly.",
+            "homepage": "http://mexitek.github.com/phpColors/",
+            "keywords": [
+                "color",
+                "css",
+                "design",
+                "frontend",
+                "ui"
+            ],
+            "support": {
+                "issues": "https://github.com/mexitek/phpColors/issues",
+                "source": "https://github.com/mexitek/phpColors"
+            },
+            "install-path": "../mexitek/phpcolors"
+        }
+    ],
     "dev": false,
     "dev-package-names": []
 }

+ 11 - 2
lib/composer/composer/installed.php

@@ -5,7 +5,7 @@
         'type' => 'library',
         'install_path' => __DIR__ . '/../../../',
         'aliases' => array(),
-        'reference' => '42c7886f80c7a5e767b192d07474114dd0848b16',
+        'reference' => '3e28052303a61b134b454fdc31e72d371c03b793',
         'name' => '__root__',
         'dev' => false,
     ),
@@ -16,7 +16,16 @@
             'type' => 'library',
             'install_path' => __DIR__ . '/../../../',
             'aliases' => array(),
-            'reference' => '42c7886f80c7a5e767b192d07474114dd0848b16',
+            'reference' => '3e28052303a61b134b454fdc31e72d371c03b793',
+            'dev_requirement' => false,
+        ),
+        'mexitek/phpcolors' => array(
+            'pretty_version' => 'v1.0.4',
+            'version' => '1.0.4.0',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../mexitek/phpcolors',
+            'aliases' => array(),
+            'reference' => '4043974240ca7dc3c2bec3c158588148b605b206',
             'dev_requirement' => false,
         ),
     ),

+ 26 - 0
lib/composer/composer/platform_check.php

@@ -0,0 +1,26 @@
+<?php
+
+// platform_check.php @generated by Composer
+
+$issues = array();
+
+if (!(PHP_VERSION_ID >= 70200)) {
+    $issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.0". You are running ' . PHP_VERSION . '.';
+}
+
+if ($issues) {
+    if (!headers_sent()) {
+        header('HTTP/1.1 500 Internal Server Error');
+    }
+    if (!ini_get('display_errors')) {
+        if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
+            fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
+        } elseif (!headers_sent()) {
+            echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
+        }
+    }
+    trigger_error(
+        'Composer detected issues in your platform: ' . implode(' ', $issues),
+        E_USER_ERROR
+    );
+}

+ 17 - 0
lib/composer/mexitek/phpcolors/.editorconfig

@@ -0,0 +1,17 @@
+# EditorConfig is awesome: http://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+# Unix-style newlines with a newline ending every file
+[*]
+charset = utf-8
+end_of_line = lf
+indent_style = space
+indent_size = 4
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+# .travis.yml
+[.travis.yml]
+indent_size = 2

+ 5 - 0
lib/composer/mexitek/phpcolors/.gitignore

@@ -0,0 +1,5 @@
+*.bak
+*.*.bak
+vendor/*
+composer.lock
+.idea

+ 10 - 0
lib/composer/mexitek/phpcolors/.phpcs.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="PHPColors"
+         xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/squizlabs/PHP_CodeSniffer/master/phpcs.xsd">
+    <description>The coding standard for PHPColors.</description>
+
+    <file>./src</file>
+    <file>./tests</file>
+
+    <rule ref="PSR12"/>
+</ruleset>

+ 11 - 0
lib/composer/mexitek/phpcolors/.travis.yml

@@ -0,0 +1,11 @@
+language: php
+php:
+  - 7.2
+  - 7.3
+  - 7.4
+  - 8.0
+before_script:
+  - composer install --no-interaction --dev --prefer-source
+script:
+  - vendor/bin/phpcs --extensions=php,phpt --warning-severity=0
+  - vendor/bin/tester tests -s -p php

+ 21 - 0
lib/composer/mexitek/phpcolors/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Arlo Carreon, http://arlocarreon.com
+
+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.

+ 173 - 0
lib/composer/mexitek/phpcolors/README.md

@@ -0,0 +1,173 @@
+# PHPColors [![Build Status](https://travis-ci.org/mexitek/phpColors.svg?branch=master)](https://travis-ci.org/mexitek/phpColors)
+
+> A series of methods that let you manipulate colors. Just incase you ever need different shades of one color on the fly.
+
+## Requirements
+
+PHPColors requires PHP version 7.2.0 or greater.
+
+## Installation
+
+### Composer
+
+Simply add `mexitek/phpcolors` to `composer.json` using `dev-master`.
+
+```
+composer require mexitek/phpcolors:dev-master
+```
+
+## How it works
+Instantiate an object of the color class with a hex color string `$foo = new Color("336699")`.  That's it!  Now, call the methods you need for different color variants.
+
+## Available Methods
+- <strong>darken( [$amount] )</strong> : Allows you to obtain a darker shade of your color. Optionally you can decide to darken using a desired percentage.
+- <strong>lighten( [$amount] )</strong> : Allows you to obtain a lighter shade of your color. Optionally you can decide to lighten using a desired percentage.
+- <strong>mix($hex, [$amount] )</strong> : Allows you to mix another color to your color. Optionally you can decide to set the percent of second color or original color amount is ranged -100...0...100.
+- <strong>isLight( [$hex] )</strong> : Determins whether your color (or the provide param) is considered a "light" color. Returns `TRUE` if color is light.
+- <strong>isDark( [$hex] )</strong> : Determins whether your color (or the provide param) is considered a "dark" color. Returns `TRUE` if color is dark.
+- <strong>makeGradient( [$amount] )</strong> : Returns an array with 2 indices `light` and `dark`, the initial color will either be selected for `light` or `dark` depending on its brightness, then the other color will be generated.  The optional param allows for a static lighten or darkened amount.
+- <strong>complementary()</strong> : Returns the color "opposite" or complementary to your color.
+- <strong>getHex()</strong> : Returns the original hex color.
+- <strong>getHsl()</strong> : Returns HSL array for your color.
+- <strong>getRgb()</strong> : Returns RGB array for your color.
+
+> Auto lightens/darkens by 10% for sexily-subtle gradients
+
+```php
+/**
+ * Using The Class
+ */
+
+use Mexitek\PHPColors\Color;
+
+// Initialize my color
+$myBlue = new Color("#336699");
+
+echo $myBlue->darken();
+// 1a334d
+
+echo $myBlue->lighten();
+// 8cb3d9
+
+echo $myBlue->isLight();
+// false
+
+echo $myBlue->isDark();
+// true
+
+echo $myBlue->complementary();
+// 996633
+
+echo $myBlue->getHex();
+// 336699
+
+print_r( $myBlue->getHsl() );
+// array( "H"=> 210, "S"=> 0.5, "L"=>0.4 );
+
+print_r( $myBlue->getRgb() );
+// array( "R"=> 51, "G"=> 102, "B"=>153 );
+
+print_r($myBlue->makeGradient());
+// array( "light"=>"8cb3d9" ,"dark"=>"336699" )
+
+```
+
+
+## Static Methods
+- <strong>hslToHex( $hsl )</strong> : Convert a HSL array to a HEX string.
+- <strong>hexToHsl( $hex )</strong> : Convert a HEX string into an HSL array.
+- <strong>hexToRgb( $hex )</strong> : Convert a HEX string into an RGB array.
+- <strong>rgbToHex( $rgb )</strong> : Convert an RGB array into a HEX string.
+
+```php
+/**
+ * On The Fly Custom Calculations
+ */
+
+use Mexitek\PHPColors\Color;
+
+ // Convert my HEX
+ $myBlue = Color::hexToHsl("#336699");
+
+ // Get crazy with the HUE
+ $myBlue["H"] = 295;
+
+ // Gimme my new color!!
+ echo Color::hslToHex($myBlue);
+ // 913399
+
+```
+
+## CSS Helpers
+- <strong>getCssGradient( [$amount] [, $vintageBrowsers] )</strong> : Generates the CSS3 gradients for safari, chrome, opera, firefox and IE10. Optional percentage amount for lighter/darker shade. Optional boolean for older gradient CSS support.
+
+> Would like to add support to custom gradient stops
+
+```php
+
+use Mexitek\PHPColors\Color;
+
+// Initialize my color
+$myBlue = new Color("#336699");
+
+// Get CSS
+echo $myBlue->getCssGradient();
+/* - Actual output doesn't have comments and is single line
+
+  // fallback background
+  background: #336699;
+
+  // IE Browsers
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#8cb3d9', endColorstr='#336699');
+
+  // Safari 5.1+, Mobile Safari, Chrome 10+
+  background-image: -webkit-linear-gradient(top, #8cb3d9, #336699);
+
+  // Standards
+  background-image: linear-gradient(to bottom, #8cb3d9, #336699);
+
+*/
+
+```
+
+However, if you want to support the ancient browsers (which has negligible market share and almost died out), you can set the second parameter to `TRUE`. This will output:
+
+```php
+
+use Mexitek\PHPColors\Color;
+$myBlue = new Color("#336699");
+
+// Get CSS
+echo $myBlue->getCssGradient(10, TRUE);
+/* - Actual output doesn't have comments and is single line
+
+  background: #336699; // fallback background
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#8cb3d9', endColorstr='#336699'); // IE Browsers
+  background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#8cb3d9), to(#336699)); // Safari 4+, Chrome 1-9
+  background-image: -webkit-linear-gradient(top, #8cb3d9, #336699); // Safari 5.1+, Mobile Safari, Chrome 10+
+  background-image: -moz-linear-gradient(top, #8cb3d9, #336699); // Firefox 3.6+
+  background-image: -o-linear-gradient(top, #8cb3d9, #336699); // Opera 11.10+
+  background-image: linear-gradient(to bottom, #8cb3d9, #336699); // Standards
+
+*/
+
+```
+
+## Github Contributors
+- mexitek
+- danielpataki
+- alexmglover
+- intuxicated
+- pborreli
+- curtisgibby
+- matthewpatterson
+- there4
+- alex-humphreys
+- zaher
+- primozcigler
+- thedavidmeister
+- tylercd100
+- Braunson
+
+# License
+See LICENSE file or [arlo.mit-license.org](http://arlo.mit-license.org)

+ 37 - 0
lib/composer/mexitek/phpcolors/composer.json

@@ -0,0 +1,37 @@
+{
+    "name": "mexitek/phpcolors",
+    "description": "A series of methods that let you manipulate colors. Just incase you ever need different shades of one color on the fly.",
+    "type": "library",
+    "keywords": [
+        "color",
+        "ui",
+        "css",
+        "frontend",
+        "design"
+    ],
+    "homepage": "http://mexitek.github.com/phpColors/",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Arlo Carreon",
+            "homepage": "http://arlocarreon.com",
+            "role": "creator"
+        }
+    ],
+    "support": {
+        "issues": "https://github.com/mexitek/phpColors/issues",
+        "source": "https://github.com/mexitek/phpColors"
+    },
+    "require": {
+        "php": "^7.2|^8.0"
+    },
+    "require-dev": {
+        "nette/tester": "^2.3",
+        "squizlabs/php_codesniffer": "^3.5"
+    },
+    "autoload": {
+        "classmap": [
+            "src"
+        ]
+    }
+}

+ 94 - 0
lib/composer/mexitek/phpcolors/demo/demo.php

@@ -0,0 +1,94 @@
+<!doctype html>
+<html lang="en">
+<head>
+    <title>phpColors Demo</title>
+    <?php
+
+    require_once __DIR__ . '/../src/Mexitek/PHPColors/Color.php';
+
+    use Mexitek\PHPColors\Color;
+
+    // Use different colors to test
+    $myBlue = new Color("#336699");
+    $myBlack = new Color("#333");
+    $myPurple = new Color("#913399");
+    $myVintage = new Color("#bada55");
+
+    // ************** No Need to Change Below **********************
+    ?>
+    <style>
+        .block {
+            height: 100px;
+            width: 200px;
+            font-size: 20px;
+            text-align: center;
+            padding-top: 100px;
+            display: block;
+            margin: 0;
+            float: left;
+        }
+
+        .wide-block {
+            width: 360px;
+            padding-top: 70px;
+            padding-left: 20px;
+            padding-right: 20px;
+            margin-top: 10px;
+        }
+
+        .clear {
+            clear: both;
+        }
+
+        .testDiv {
+            <?= $myBlue->getCssGradient()?>
+            color: <?=($myBlue->isDark() ? "#EEE":"#333")?>;
+        }
+
+        .testDiv.plain {
+            background: #<?= $myBlue->getHex()?>;
+            color: <?=($myBlue->isDark() ? "#EEE":"#333")?>;
+        }
+
+        .testDiv2 {
+            <?= $myBlack->getCssGradient()?>
+            color: <?=($myBlack->isDark() ? "#EEE":"#333")?>;
+        }
+
+        .testDiv2.plain {
+            background: #<?= $myBlack->getHex();?>;
+            color: <?=($myBlack->isDark() ? "#EEE":"#333")?>;
+        }
+
+        .testDiv3 {
+            <?= $myPurple->getCssGradient()?>
+            color: <?=($myPurple->isDark() ? "#EEE":"#333")?>;
+        }
+
+        .testDiv3.plain {
+            background: #<?= $myPurple->getHex()?>;
+            color: <?=($myPurple->isDark() ? "#EEE":"#333")?>;
+        }
+
+        .testDiv4 {
+            <?= $myVintage->getCssGradient(30, true)?>
+            color: <?=($myVintage->isDark() ? "#EEE":"#333")?>;
+        }
+    </style>
+</head>
+<body>
+<div class="clear"></div>
+<div class="block testDiv">phpColor Gradient #<?= $myBlue->getHex() ?></div>
+<div class="block testDiv plain">Plain #<?= $myBlue->getHex() ?></div>
+<div class="clear"></div>
+<div class="block testDiv2">phpColor Gradient #<?= $myBlack->getHex() ?></div>
+<div class="block testDiv2 plain">Plain #<?= $myBlack->getHex() ?></div>
+<div class="clear"></div>
+<div class="block testDiv3">phpColor Gradient #<?= $myPurple->getHex() ?></div>
+<div class="block testDiv3 plain">Plain #<?= $myPurple->getHex() ?></div>
+<div class="clear"></div>
+<div class="block wide-block testDiv4">
+    phpColor Gradient with vintage browsers support #<?= $myVintage->getHex() ?>
+</div>
+</body>
+</html>

BIN
lib/composer/mexitek/phpcolors/demo/phpColor-demo.png


+ 801 - 0
lib/composer/mexitek/phpcolors/src/Mexitek/PHPColors/Color.php

@@ -0,0 +1,801 @@
+<?php
+
+/**
+ * Author: Arlo Carreon <http://arlocarreon.com>
+ * Info: http://mexitek.github.io/phpColors/
+ * License: http://arlo.mit-license.org/
+ */
+
+namespace Mexitek\PHPColors;
+
+use Exception;
+
+/**
+ * A color utility that helps manipulate HEX colors
+ */
+class Color
+{
+    /**
+     * @var string
+     */
+    private $_hex;
+
+    /**
+     * @var array
+     */
+    private $_hsl;
+
+    /**
+     * @var array
+     */
+    private $_rgb;
+
+    /**
+     * Auto darkens/lightens by 10% for sexily-subtle gradients.
+     * Set this to FALSE to adjust automatic shade to be between given color
+     * and black (for darken) or white (for lighten)
+     */
+    public const DEFAULT_ADJUST = 10;
+
+    /**
+     * Instantiates the class with a HEX value
+     * @param string $hex
+     * @throws Exception
+     */
+    public function __construct(string $hex)
+    {
+        $color = self::sanitizeHex($hex);
+        $this->_hex = $color;
+        $this->_hsl = self::hexToHsl($color);
+        $this->_rgb = self::hexToRgb($color);
+    }
+
+    /**
+     * Given a HEX string returns a HSL array equivalent.
+     * @param string $color
+     * @return array HSL associative array
+     * @throws Exception
+     */
+    public static function hexToHsl(string $color): array
+    {
+        // Sanity check
+        $color = self::sanitizeHex($color);
+
+        // Convert HEX to DEC
+        $R = hexdec($color[0] . $color[1]);
+        $G = hexdec($color[2] . $color[3]);
+        $B = hexdec($color[4] . $color[5]);
+
+        $HSL = array();
+
+        $var_R = ($R / 255);
+        $var_G = ($G / 255);
+        $var_B = ($B / 255);
+
+        $var_Min = min($var_R, $var_G, $var_B);
+        $var_Max = max($var_R, $var_G, $var_B);
+        $del_Max = $var_Max - $var_Min;
+
+        $L = ($var_Max + $var_Min) / 2;
+
+        if ($del_Max == 0) {
+            $H = 0;
+            $S = 0;
+        } else {
+            if ($L < 0.5) {
+                $S = $del_Max / ($var_Max + $var_Min);
+            } else {
+                $S = $del_Max / (2 - $var_Max - $var_Min);
+            }
+
+            $del_R = ((($var_Max - $var_R) / 6) + ($del_Max / 2)) / $del_Max;
+            $del_G = ((($var_Max - $var_G) / 6) + ($del_Max / 2)) / $del_Max;
+            $del_B = ((($var_Max - $var_B) / 6) + ($del_Max / 2)) / $del_Max;
+
+            if ($var_R == $var_Max) {
+                $H = $del_B - $del_G;
+            } elseif ($var_G == $var_Max) {
+                $H = (1 / 3) + $del_R - $del_B;
+            } elseif ($var_B == $var_Max) {
+                $H = (2 / 3) + $del_G - $del_R;
+            }
+
+            if ($H < 0) {
+                $H++;
+            }
+            if ($H > 1) {
+                $H--;
+            }
+        }
+
+        $HSL['H'] = ($H * 360);
+        $HSL['S'] = $S;
+        $HSL['L'] = $L;
+
+        return $HSL;
+    }
+
+    /**
+     * Given a HSL associative array returns the equivalent HEX string
+     * @param array $hsl
+     * @return string HEX string
+     * @throws Exception "Bad HSL Array"
+     */
+    public static function hslToHex(array $hsl = array()): string
+    {
+        // Make sure it's HSL
+        if (empty($hsl) || !isset($hsl["H"], $hsl["S"], $hsl["L"])) {
+            throw new Exception("Param was not an HSL array");
+        }
+
+        list($H, $S, $L) = array($hsl['H'] / 360, $hsl['S'], $hsl['L']);
+
+        if ($S == 0) {
+            $r = $L * 255;
+            $g = $L * 255;
+            $b = $L * 255;
+        } else {
+            if ($L < 0.5) {
+                $var_2 = $L * (1 + $S);
+            } else {
+                $var_2 = ($L + $S) - ($S * $L);
+            }
+
+            $var_1 = 2 * $L - $var_2;
+
+            $r = 255 * self::hueToRgb($var_1, $var_2, $H + (1 / 3));
+            $g = 255 * self::hueToRgb($var_1, $var_2, $H);
+            $b = 255 * self::hueToRgb($var_1, $var_2, $H - (1 / 3));
+        }
+
+        // Convert to hex
+        $r = dechex(round($r));
+        $g = dechex(round($g));
+        $b = dechex(round($b));
+
+        // Make sure we get 2 digits for decimals
+        $r = (strlen("" . $r) === 1) ? "0" . $r : $r;
+        $g = (strlen("" . $g) === 1) ? "0" . $g : $g;
+        $b = (strlen("" . $b) === 1) ? "0" . $b : $b;
+
+        return $r . $g . $b;
+    }
+
+
+    /**
+     * Given a HEX string returns a RGB array equivalent.
+     * @param string $color
+     * @return array RGB associative array
+     * @throws Exception
+     */
+    public static function hexToRgb(string $color): array
+    {
+        // Sanity check
+        $color = self::sanitizeHex($color);
+
+        // Convert HEX to DEC
+        $R = hexdec($color[0] . $color[1]);
+        $G = hexdec($color[2] . $color[3]);
+        $B = hexdec($color[4] . $color[5]);
+
+        $RGB['R'] = $R;
+        $RGB['G'] = $G;
+        $RGB['B'] = $B;
+
+        return $RGB;
+    }
+
+
+    /**
+     * Given an RGB associative array returns the equivalent HEX string
+     * @param array $rgb
+     * @return string Hex string
+     * @throws Exception "Bad RGB Array"
+     */
+    public static function rgbToHex(array $rgb = array()): string
+    {
+        // Make sure it's RGB
+        if (empty($rgb) || !isset($rgb["R"], $rgb["G"], $rgb["B"])) {
+            throw new Exception("Param was not an RGB array");
+        }
+
+        // https://github.com/mexitek/phpColors/issues/25#issuecomment-88354815
+        // Convert RGB to HEX
+        $hex[0] = str_pad(dechex((int)$rgb['R']), 2, '0', STR_PAD_LEFT);
+        $hex[1] = str_pad(dechex((int)$rgb['G']), 2, '0', STR_PAD_LEFT);
+        $hex[2] = str_pad(dechex((int)$rgb['B']), 2, '0', STR_PAD_LEFT);
+
+        // Make sure that 2 digits are allocated to each color.
+        $hex[0] = (strlen($hex[0]) === 1) ? '0' . $hex[0] : $hex[0];
+        $hex[1] = (strlen($hex[1]) === 1) ? '0' . $hex[1] : $hex[1];
+        $hex[2] = (strlen($hex[2]) === 1) ? '0' . $hex[2] : $hex[2];
+
+        return implode('', $hex);
+    }
+
+    /**
+     * Given an RGB associative array, returns CSS string output.
+     * @param array $rgb
+     * @return string rgb(r,g,b) string
+     * @throws Exception "Bad RGB Array"
+     */
+    public static function rgbToString(array $rgb = array()): string
+    {
+        // Make sure it's RGB
+        if (empty($rgb) || !isset($rgb["R"], $rgb["G"], $rgb["B"])) {
+            throw new Exception("Param was not an RGB array");
+        }
+
+        return 'rgb(' .
+            $rgb['R'] . ', ' .
+            $rgb['G'] . ', ' .
+            $rgb['B'] . ')';
+    }
+
+    /**
+     * Given a standard color name, return hex code
+     *
+     * @param string $color_name
+     * @return string
+     */
+    public static function nameToHex(string $color_name): string
+    {
+        $colors = array(
+            'aliceblue' => 'F0F8FF',
+            'antiquewhite' => 'FAEBD7',
+            'aqua' => '00FFFF',
+            'aquamarine' => '7FFFD4',
+            'azure' => 'F0FFFF',
+            'beige' => 'F5F5DC',
+            'bisque' => 'FFE4C4',
+            'black' => '000000',
+            'blanchedalmond' => 'FFEBCD',
+            'blue' => '0000FF',
+            'blueviolet' => '8A2BE2',
+            'brown' => 'A52A2A',
+            'burlywood' => 'DEB887',
+            'cadetblue' => '5F9EA0',
+            'chartreuse' => '7FFF00',
+            'chocolate' => 'D2691E',
+            'coral' => 'FF7F50',
+            'cornflowerblue' => '6495ED',
+            'cornsilk' => 'FFF8DC',
+            'crimson' => 'DC143C',
+            'cyan' => '00FFFF',
+            'darkblue' => '00008B',
+            'darkcyan' => '008B8B',
+            'darkgoldenrod' => 'B8860B',
+            'darkgray' => 'A9A9A9',
+            'darkgreen' => '006400',
+            'darkgrey' => 'A9A9A9',
+            'darkkhaki' => 'BDB76B',
+            'darkmagenta' => '8B008B',
+            'darkolivegreen' => '556B2F',
+            'darkorange' => 'FF8C00',
+            'darkorchid' => '9932CC',
+            'darkred' => '8B0000',
+            'darksalmon' => 'E9967A',
+            'darkseagreen' => '8FBC8F',
+            'darkslateblue' => '483D8B',
+            'darkslategray' => '2F4F4F',
+            'darkslategrey' => '2F4F4F',
+            'darkturquoise' => '00CED1',
+            'darkviolet' => '9400D3',
+            'deeppink' => 'FF1493',
+            'deepskyblue' => '00BFFF',
+            'dimgray' => '696969',
+            'dimgrey' => '696969',
+            'dodgerblue' => '1E90FF',
+            'firebrick' => 'B22222',
+            'floralwhite' => 'FFFAF0',
+            'forestgreen' => '228B22',
+            'fuchsia' => 'FF00FF',
+            'gainsboro' => 'DCDCDC',
+            'ghostwhite' => 'F8F8FF',
+            'gold' => 'FFD700',
+            'goldenrod' => 'DAA520',
+            'gray' => '808080',
+            'green' => '008000',
+            'greenyellow' => 'ADFF2F',
+            'grey' => '808080',
+            'honeydew' => 'F0FFF0',
+            'hotpink' => 'FF69B4',
+            'indianred' => 'CD5C5C',
+            'indigo' => '4B0082',
+            'ivory' => 'FFFFF0',
+            'khaki' => 'F0E68C',
+            'lavender' => 'E6E6FA',
+            'lavenderblush' => 'FFF0F5',
+            'lawngreen' => '7CFC00',
+            'lemonchiffon' => 'FFFACD',
+            'lightblue' => 'ADD8E6',
+            'lightcoral' => 'F08080',
+            'lightcyan' => 'E0FFFF',
+            'lightgoldenrodyellow' => 'FAFAD2',
+            'lightgray' => 'D3D3D3',
+            'lightgreen' => '90EE90',
+            'lightgrey' => 'D3D3D3',
+            'lightpink' => 'FFB6C1',
+            'lightsalmon' => 'FFA07A',
+            'lightseagreen' => '20B2AA',
+            'lightskyblue' => '87CEFA',
+            'lightslategray' => '778899',
+            'lightslategrey' => '778899',
+            'lightsteelblue' => 'B0C4DE',
+            'lightyellow' => 'FFFFE0',
+            'lime' => '00FF00',
+            'limegreen' => '32CD32',
+            'linen' => 'FAF0E6',
+            'magenta' => 'FF00FF',
+            'maroon' => '800000',
+            'mediumaquamarine' => '66CDAA',
+            'mediumblue' => '0000CD',
+            'mediumorchid' => 'BA55D3',
+            'mediumpurple' => '9370D0',
+            'mediumseagreen' => '3CB371',
+            'mediumslateblue' => '7B68EE',
+            'mediumspringgreen' => '00FA9A',
+            'mediumturquoise' => '48D1CC',
+            'mediumvioletred' => 'C71585',
+            'midnightblue' => '191970',
+            'mintcream' => 'F5FFFA',
+            'mistyrose' => 'FFE4E1',
+            'moccasin' => 'FFE4B5',
+            'navajowhite' => 'FFDEAD',
+            'navy' => '000080',
+            'oldlace' => 'FDF5E6',
+            'olive' => '808000',
+            'olivedrab' => '6B8E23',
+            'orange' => 'FFA500',
+            'orangered' => 'FF4500',
+            'orchid' => 'DA70D6',
+            'palegoldenrod' => 'EEE8AA',
+            'palegreen' => '98FB98',
+            'paleturquoise' => 'AFEEEE',
+            'palevioletred' => 'DB7093',
+            'papayawhip' => 'FFEFD5',
+            'peachpuff' => 'FFDAB9',
+            'peru' => 'CD853F',
+            'pink' => 'FFC0CB',
+            'plum' => 'DDA0DD',
+            'powderblue' => 'B0E0E6',
+            'purple' => '800080',
+            'red' => 'FF0000',
+            'rosybrown' => 'BC8F8F',
+            'royalblue' => '4169E1',
+            'saddlebrown' => '8B4513',
+            'salmon' => 'FA8072',
+            'sandybrown' => 'F4A460',
+            'seagreen' => '2E8B57',
+            'seashell' => 'FFF5EE',
+            'sienna' => 'A0522D',
+            'silver' => 'C0C0C0',
+            'skyblue' => '87CEEB',
+            'slateblue' => '6A5ACD',
+            'slategray' => '708090',
+            'slategrey' => '708090',
+            'snow' => 'FFFAFA',
+            'springgreen' => '00FF7F',
+            'steelblue' => '4682B4',
+            'tan' => 'D2B48C',
+            'teal' => '008080',
+            'thistle' => 'D8BFD8',
+            'tomato' => 'FF6347',
+            'turquoise' => '40E0D0',
+            'violet' => 'EE82EE',
+            'wheat' => 'F5DEB3',
+            'white' => 'FFFFFF',
+            'whitesmoke' => 'F5F5F5',
+            'yellow' => 'FFFF00',
+            'yellowgreen' => '9ACD32'
+        );
+
+        $color_name = strtolower($color_name);
+        if (isset($colors[$color_name])) {
+            return '#' . $colors[$color_name];
+        }
+
+        return $color_name;
+    }
+
+    /**
+     * Given a HEX value, returns a darker color. If no desired amount provided, then the color halfway between
+     * given HEX and black will be returned.
+     * @param int $amount
+     * @return string Darker HEX value
+     * @throws Exception
+     */
+    public function darken(int $amount = self::DEFAULT_ADJUST): string
+    {
+        // Darken
+        $darkerHSL = $this->darkenHsl($this->_hsl, $amount);
+        // Return as HEX
+        return self::hslToHex($darkerHSL);
+    }
+
+    /**
+     * Given a HEX value, returns a lighter color. If no desired amount provided, then the color halfway between
+     * given HEX and white will be returned.
+     * @param int $amount
+     * @return string Lighter HEX value
+     * @throws Exception
+     */
+    public function lighten(int $amount = self::DEFAULT_ADJUST): string
+    {
+        // Lighten
+        $lighterHSL = $this->lightenHsl($this->_hsl, $amount);
+        // Return as HEX
+        return self::hslToHex($lighterHSL);
+    }
+
+    /**
+     * Given a HEX value, returns a mixed color. If no desired amount provided, then the color mixed by this ratio
+     * @param string $hex2 Secondary HEX value to mix with
+     * @param int $amount = -100..0..+100
+     * @return string mixed HEX value
+     * @throws Exception
+     */
+    public function mix(string $hex2, int $amount = 0): string
+    {
+        $rgb2 = self::hexToRgb($hex2);
+        $mixed = $this->mixRgb($this->_rgb, $rgb2, $amount);
+        // Return as HEX
+        return self::rgbToHex($mixed);
+    }
+
+    /**
+     * Creates an array with two shades that can be used to make a gradient
+     * @param int $amount Optional percentage amount you want your contrast color
+     * @return array An array with a 'light' and 'dark' index
+     * @throws Exception
+     */
+    public function makeGradient(int $amount = self::DEFAULT_ADJUST): array
+    {
+        // Decide which color needs to be made
+        if ($this->isLight()) {
+            $lightColor = $this->_hex;
+            $darkColor = $this->darken($amount);
+        } else {
+            $lightColor = $this->lighten($amount);
+            $darkColor = $this->_hex;
+        }
+
+        // Return our gradient array
+        return array("light" => $lightColor, "dark" => $darkColor);
+    }
+
+
+    /**
+     * Returns whether or not given color is considered "light"
+     * @param string|bool $color
+     * @param int $lighterThan
+     * @return boolean
+     */
+    public function isLight($color = false, int $lighterThan = 130): bool
+    {
+        // Get our color
+        $color = ($color) ? $color : $this->_hex;
+
+        // Calculate straight from rbg
+        $r = hexdec($color[0] . $color[1]);
+        $g = hexdec($color[2] . $color[3]);
+        $b = hexdec($color[4] . $color[5]);
+
+        return (($r * 299 + $g * 587 + $b * 114) / 1000 > $lighterThan);
+    }
+
+    /**
+     * Returns whether or not a given color is considered "dark"
+     * @param string|bool $color
+     * @param int $darkerThan
+     * @return boolean
+     */
+    public function isDark($color = false, int $darkerThan = 130): bool
+    {
+        // Get our color
+        $color = ($color) ? $color : $this->_hex;
+
+        // Calculate straight from rbg
+        $r = hexdec($color[0] . $color[1]);
+        $g = hexdec($color[2] . $color[3]);
+        $b = hexdec($color[4] . $color[5]);
+
+        return (($r * 299 + $g * 587 + $b * 114) / 1000 <= $darkerThan);
+    }
+
+    /**
+     * Returns the complimentary color
+     * @return string Complementary hex color
+     * @throws Exception
+     */
+    public function complementary(): string
+    {
+        // Get our HSL
+        $hsl = $this->_hsl;
+
+        // Adjust Hue 180 degrees
+        $hsl['H'] += ($hsl['H'] > 180) ? -180 : 180;
+
+        // Return the new value in HEX
+        return self::hslToHex($hsl);
+    }
+
+    /**
+     * Returns the HSL array of your color
+     */
+    public function getHsl(): array
+    {
+        return $this->_hsl;
+    }
+
+    /**
+     * Returns your original color
+     */
+    public function getHex(): string
+    {
+        return $this->_hex;
+    }
+
+    /**
+     * Returns the RGB array of your color
+     */
+    public function getRgb(): array
+    {
+        return $this->_rgb;
+    }
+
+    /**
+     * Returns the cross browser CSS3 gradient
+     * @param int $amount Optional: percentage amount to light/darken the gradient
+     * @param boolean $vintageBrowsers Optional: include vendor prefixes for browsers that almost died out already
+     * @param string $prefix Optional: prefix for every lines
+     * @param string $suffix Optional: suffix for every lines
+     * @return string CSS3 gradient for chrome, safari, firefox, opera and IE10
+     * @throws Exception
+     * @link http://caniuse.com/css-gradients Resource for the browser support
+     */
+    public function getCssGradient($amount = self::DEFAULT_ADJUST, $vintageBrowsers = false, $suffix = "", $prefix = ""): string
+    {
+        // Get the recommended gradient
+        $g = $this->makeGradient($amount);
+
+        $css = "";
+        /* fallback/image non-cover color */
+        $css .= "{$prefix}background-color: #" . $this->_hex . ";{$suffix}";
+
+        /* IE Browsers */
+        $css .= "{$prefix}filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#" . $g['light'] . "', endColorstr='#" . $g['dark'] . "');{$suffix}";
+
+        /* Safari 4+, Chrome 1-9 */
+        if ($vintageBrowsers) {
+            $css .= "{$prefix}background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#" . $g['light'] . "), to(#" . $g['dark'] . "));{$suffix}";
+        }
+
+        /* Safari 5.1+, Mobile Safari, Chrome 10+ */
+        $css .= "{$prefix}background-image: -webkit-linear-gradient(top, #" . $g['light'] . ", #" . $g['dark'] . ");{$suffix}";
+
+        if ($vintageBrowsers) {
+            /* Firefox 3.6+ */
+            $css .= "{$prefix}background-image: -moz-linear-gradient(top, #" . $g['light'] . ", #" . $g['dark'] . ");{$suffix}";
+
+            /* Opera 11.10+ */
+            $css .= "{$prefix}background-image: -o-linear-gradient(top, #" . $g['light'] . ", #" . $g['dark'] . ");{$suffix}";
+        }
+
+        /* Unprefixed version (standards): FF 16+, IE10+, Chrome 26+, Safari 7+, Opera 12.1+ */
+        $css .= "{$prefix}background-image: linear-gradient(to bottom, #" . $g['light'] . ", #" . $g['dark'] . ");{$suffix}";
+
+        // Return our CSS
+        return $css;
+    }
+
+    /**
+     * Darkens a given HSL array
+     * @param array $hsl
+     * @param int $amount
+     * @return array $hsl
+     */
+    private function darkenHsl(array $hsl, int $amount = self::DEFAULT_ADJUST): array
+    {
+        // Check if we were provided a number
+        if ($amount) {
+            $hsl['L'] = ($hsl['L'] * 100) - $amount;
+            $hsl['L'] = ($hsl['L'] < 0) ? 0 : $hsl['L'] / 100;
+        } else {
+            // We need to find out how much to darken
+            $hsl['L'] /= 2;
+        }
+
+        return $hsl;
+    }
+
+    /**
+     * Lightens a given HSL array
+     * @param array $hsl
+     * @param int $amount
+     * @return array
+     */
+    private function lightenHsl(array $hsl, int $amount = self::DEFAULT_ADJUST): array
+    {
+        // Check if we were provided a number
+        if ($amount) {
+            $hsl['L'] = ($hsl['L'] * 100) + $amount;
+            $hsl['L'] = ($hsl['L'] > 100) ? 1 : $hsl['L'] / 100;
+        } else {
+            // We need to find out how much to lighten
+            $hsl['L'] += (1 - $hsl['L']) / 2;
+        }
+
+        return $hsl;
+    }
+
+    /**
+     * Mix two RGB colors and return the resulting RGB color
+     * ported from http://phpxref.pagelines.com/nav.html?includes/class.colors.php.source.html
+     * @param array $rgb1
+     * @param array $rgb2
+     * @param int $amount ranged -100..0..+100
+     * @return array
+     */
+    private function mixRgb(array $rgb1, array $rgb2, int $amount = 0): array
+    {
+        $r1 = ($amount + 100) / 100;
+        $r2 = 2 - $r1;
+
+        $rmix = (($rgb1['R'] * $r1) + ($rgb2['R'] * $r2)) / 2;
+        $gmix = (($rgb1['G'] * $r1) + ($rgb2['G'] * $r2)) / 2;
+        $bmix = (($rgb1['B'] * $r1) + ($rgb2['B'] * $r2)) / 2;
+
+        return array('R' => $rmix, 'G' => $gmix, 'B' => $bmix);
+    }
+
+    /**
+     * Given a Hue, returns corresponding RGB value
+     * @param float $v1
+     * @param float $v2
+     * @param float $vH
+     * @return float
+     */
+    private static function hueToRgb(float $v1, float $v2, float $vH): float
+    {
+        if ($vH < 0) {
+            ++$vH;
+        }
+
+        if ($vH > 1) {
+            --$vH;
+        }
+
+        if ((6 * $vH) < 1) {
+            return ($v1 + ($v2 - $v1) * 6 * $vH);
+        }
+
+        if ((2 * $vH) < 1) {
+            return $v2;
+        }
+
+        if ((3 * $vH) < 2) {
+            return ($v1 + ($v2 - $v1) * ((2 / 3) - $vH) * 6);
+        }
+
+        return $v1;
+    }
+
+    /**
+     * Checks the HEX string for correct formatting and converts short format to long
+     * @param string $hex
+     * @return string
+     * @throws Exception
+     */
+    private static function sanitizeHex(string $hex): string
+    {
+        // Strip # sign if it is present
+        $color = str_replace("#", "", $hex);
+
+        // Validate hex string
+        if (!preg_match('/^[a-fA-F0-9]+$/', $color)) {
+            throw new Exception("HEX color does not match format");
+        }
+
+        // Make sure it's 6 digits
+        if (strlen($color) === 3) {
+            $color = $color[0] . $color[0] . $color[1] . $color[1] . $color[2] . $color[2];
+        } elseif (strlen($color) !== 6) {
+            throw new Exception("HEX color needs to be 6 or 3 digits long");
+        }
+
+        return $color;
+    }
+
+    /**
+     * Converts object into its string representation
+     * @return string
+     */
+    public function __toString()
+    {
+        return "#" . $this->getHex();
+    }
+
+    /**
+     * @param string $name
+     * @return mixed|null
+     */
+    public function __get(string $name)
+    {
+        switch (strtolower($name)) {
+            case 'red':
+            case 'r':
+                return $this->_rgb["R"];
+            case 'green':
+            case 'g':
+                return $this->_rgb["G"];
+            case 'blue':
+            case 'b':
+                return $this->_rgb["B"];
+            case 'hue':
+            case 'h':
+                return $this->_hsl["H"];
+            case 'saturation':
+            case 's':
+                return $this->_hsl["S"];
+            case 'lightness':
+            case 'l':
+                return $this->_hsl["L"];
+        }
+
+        $trace = debug_backtrace();
+        trigger_error(
+            'Undefined property via __get(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'],
+            E_USER_NOTICE
+        );
+        return null;
+    }
+
+    /**
+     * @param string $name
+     * @param mixed $value
+     * @throws Exception
+     */
+    public function __set(string $name, $value)
+    {
+        switch (strtolower($name)) {
+            case 'red':
+            case 'r':
+                $this->_rgb["R"] = $value;
+                $this->_hex = self::rgbToHex($this->_rgb);
+                $this->_hsl = self::hexToHsl($this->_hex);
+                break;
+            case 'green':
+            case 'g':
+                $this->_rgb["G"] = $value;
+                $this->_hex = self::rgbToHex($this->_rgb);
+                $this->_hsl = self::hexToHsl($this->_hex);
+                break;
+            case 'blue':
+            case 'b':
+                $this->_rgb["B"] = $value;
+                $this->_hex = self::rgbToHex($this->_rgb);
+                $this->_hsl = self::hexToHsl($this->_hex);
+                break;
+            case 'hue':
+            case 'h':
+                $this->_hsl["H"] = $value;
+                $this->_hex = self::hslToHex($this->_hsl);
+                $this->_rgb = self::hexToRgb($this->_hex);
+                break;
+            case 'saturation':
+            case 's':
+                $this->_hsl["S"] = $value;
+                $this->_hex = self::hslToHex($this->_hsl);
+                $this->_rgb = self::hexToRgb($this->_hex);
+                break;
+            case 'lightness':
+            case 'light':
+            case 'l':
+                $this->_hsl["L"] = $value;
+                $this->_hex = self::hslToHex($this->_hsl);
+                $this->_rgb = self::hexToRgb($this->_hex);
+                break;
+        }
+    }
+}

+ 11 - 0
lib/composer/mexitek/phpcolors/tests/bootstrap.php

@@ -0,0 +1,11 @@
+<?php
+
+require __DIR__ . '/../vendor/autoload.php';
+require __DIR__ . '/../src/Mexitek/PHPColors/Color.php';
+
+if (!class_exists('Tester\Assert')) {
+    echo "Install Nette Tester using `composer update --dev`\n";
+    exit(1);
+}
+
+Tester\Environment::setup();

+ 35 - 0
lib/composer/mexitek/phpcolors/tests/colorAnalyze.phpt

@@ -0,0 +1,35 @@
+<?php
+
+require __DIR__ . '/bootstrap.php';
+
+use Mexitek\PHPColors\Color;
+use Tester\Assert;
+
+
+$isDark = array(
+    "000000" => true,
+    "336699" => true,
+    "913399" => true,
+    "E5C3E8" => false,
+    "D7E8DD" => false,
+    "218A47" => true,
+    "3D41CA" => true,
+    "E5CCDD" => false,
+    "FFFFFF" => false,
+);
+
+foreach ($isDark as $colorHex => $state) {
+    $color = new Color($colorHex);
+    Assert::same($state, $color->isDark(), 'Incorrect dark color analyzed (#' . $colorHex . ').');
+}
+
+$isLight = array(
+    "FFFFFF" => true,
+    "A3FFE5" => true,
+    "000000" => false,
+);
+
+foreach ($isLight as $colorHex => $state) {
+    $color = new Color($colorHex);
+    Assert::same($state, $color->isLight(), 'Incorrect light color analyzed (#' . $colorHex . ').');
+}

+ 28 - 0
lib/composer/mexitek/phpcolors/tests/colorChange.phpt

@@ -0,0 +1,28 @@
+<?php
+
+require __DIR__ . '/bootstrap.php';
+
+use Mexitek\PHPColors\Color;
+use Tester\Assert;
+
+
+$expected = array(
+    "336699" => "264d73",
+    "913399" => "6d2673"
+);
+
+foreach ($expected as $original => $darker) {
+    $color = new Color($original);
+    Assert::same($darker, $color->darken(), 'Incorrect darker color returned.');
+}
+
+
+$expected = array(
+    "336699" => "4080bf",
+    "913399" => "b540bf"
+);
+
+foreach ($expected as $original => $lighter) {
+    $color = new Color($original);
+    Assert::same($lighter, $color->lighten(), "Incorrect lighter color returned.");
+}

+ 28 - 0
lib/composer/mexitek/phpcolors/tests/colorComplementary.phpt

@@ -0,0 +1,28 @@
+<?php
+
+require __DIR__ . '/bootstrap.php';
+
+use Mexitek\PHPColors\Color;
+use Tester\Assert;
+
+
+$expected = array(
+    "ff0000" => "00ffff",
+    "0000ff" => "ffff00",
+    "00ff00" => "ff00ff",
+    "ffff00" => "0000ff",
+    "00ffff" => "ff0000",
+    "49cbaf" => "cb4965",
+    "003eb2" => "b27400",
+    "b27400" => "003eb2",
+    "ffff99" => "9999ff",
+    "ccff00" => "3300ff",
+    "3300ff" => "ccff00",
+    "fb4a2c" => "2cddfb",
+    "9cebff" => "ffb09c",
+);
+
+foreach ($expected as $original => $complementary) {
+    $color = new Color($original);
+    Assert::same($complementary, $color->complementary(), 'Incorrect complementary color returned.');
+}

+ 72 - 0
lib/composer/mexitek/phpcolors/tests/colorConvertHslToHex.phpt

@@ -0,0 +1,72 @@
+<?php
+
+require __DIR__ . '/bootstrap.php';
+
+use Mexitek\PHPColors\Color;
+use Tester\Assert;
+
+// Colors in HSL, for testing.
+$blue = [
+    'H' => 194,
+    'S' => 1.0,
+    'L' => 0.4,
+];
+$yellow = [
+    'H' => 57,
+    'S' => 0.91,
+    'L' => 0.51,
+];
+$black = [
+    'H' => 0,
+    'S' => 0.0,
+    'L' => 0.0,
+];
+$grey = [
+    'H' => 0,
+    'S' => 0.0,
+    'L' => 0.65,
+];
+$white = [
+    'H' => 0,
+    'S' => 0.0,
+    'L' => 1.0,
+];
+
+// Test cases.
+$colorsToConvert = array(
+    'blue' => [ // hsl(194, 100%, 40%)
+        'hex' => '009ccc',
+        'hsl' => $blue,
+    ],
+    'yellow' => [ // hsl(57, 91%, 51%)
+        'hex' => 'f4e810',
+        'hsl' => $yellow,
+    ],
+    'black' => [
+        'hex' => '000000',
+        'hsl' => $black,
+    ],
+    'grey' => [
+        'hex' => 'a6a6a6',
+        'hsl' => $grey,
+    ],
+    'white' => [
+        'hex' => 'ffffff',
+        'hsl' => $white,
+    ],
+);
+
+
+foreach ($colorsToConvert as $color) {
+    $hsl = $color['hsl'];
+    $hex = $color['hex'];
+
+    $answer = Color::hslToHex($hsl);
+    Assert::same(
+        $hex,
+        $answer,
+        'Incorrect hex result: "' . json_encode($hsl) .
+        '" should convert to "' . $hex .
+        '", but output was: "' . $answer . '".'
+    );
+}

+ 170 - 0
lib/composer/mexitek/phpcolors/tests/colorConvertNameToHex.phpt

@@ -0,0 +1,170 @@
+<?php
+
+require __DIR__ . '/bootstrap.php';
+
+use Mexitek\PHPColors\Color;
+use Tester\Assert;
+
+// Test cases.
+$colorsToConvert = array(
+    'aliceblue' => 'F0F8FF',
+    'antiquewhite' => 'FAEBD7',
+    'aqua' => '00FFFF',
+    'aquamarine' => '7FFFD4',
+    'azure' => 'F0FFFF',
+    'beige' => 'F5F5DC',
+    'bisque' => 'FFE4C4',
+    'black' => '000000',
+    'blanchedalmond' => 'FFEBCD',
+    'blue' => '0000FF',
+    'blueviolet' => '8A2BE2',
+    'brown' => 'A52A2A',
+    'burlywood' => 'DEB887',
+    'cadetblue' => '5F9EA0',
+    'chartreuse' => '7FFF00',
+    'chocolate' => 'D2691E',
+    'coral' => 'FF7F50',
+    'cornflowerblue' => '6495ED',
+    'cornsilk' => 'FFF8DC',
+    'crimson' => 'DC143C',
+    'cyan' => '00FFFF',
+    'darkblue' => '00008B',
+    'darkcyan' => '008B8B',
+    'darkgoldenrod' => 'B8860B',
+    'darkgray' => 'A9A9A9',
+    'darkgreen' => '006400',
+    'darkgrey' => 'A9A9A9',
+    'darkkhaki' => 'BDB76B',
+    'darkmagenta' => '8B008B',
+    'darkolivegreen' => '556B2F',
+    'darkorange' => 'FF8C00',
+    'darkorchid' => '9932CC',
+    'darkred' => '8B0000',
+    'darksalmon' => 'E9967A',
+    'darkseagreen' => '8FBC8F',
+    'darkslateblue' => '483D8B',
+    'darkslategray' => '2F4F4F',
+    'darkslategrey' => '2F4F4F',
+    'darkturquoise' => '00CED1',
+    'darkviolet' => '9400D3',
+    'deeppink' => 'FF1493',
+    'deepskyblue' => '00BFFF',
+    'dimgray' => '696969',
+    'dimgrey' => '696969',
+    'dodgerblue' => '1E90FF',
+    'firebrick' => 'B22222',
+    'floralwhite' => 'FFFAF0',
+    'forestgreen' => '228B22',
+    'fuchsia' => 'FF00FF',
+    'gainsboro' => 'DCDCDC',
+    'ghostwhite' => 'F8F8FF',
+    'gold' => 'FFD700',
+    'goldenrod' => 'DAA520',
+    'gray' => '808080',
+    'green' => '008000',
+    'greenyellow' => 'ADFF2F',
+    'grey' => '808080',
+    'honeydew' => 'F0FFF0',
+    'hotpink' => 'FF69B4',
+    'indianred' => 'CD5C5C',
+    'indigo' => '4B0082',
+    'ivory' => 'FFFFF0',
+    'khaki' => 'F0E68C',
+    'lavender' => 'E6E6FA',
+    'lavenderblush' => 'FFF0F5',
+    'lawngreen' => '7CFC00',
+    'lemonchiffon' => 'FFFACD',
+    'lightblue' => 'ADD8E6',
+    'lightcoral' => 'F08080',
+    'lightcyan' => 'E0FFFF',
+    'lightgoldenrodyellow' => 'FAFAD2',
+    'lightgray' => 'D3D3D3',
+    'lightgreen' => '90EE90',
+    'lightgrey' => 'D3D3D3',
+    'lightpink' => 'FFB6C1',
+    'lightsalmon' => 'FFA07A',
+    'lightseagreen' => '20B2AA',
+    'lightskyblue' => '87CEFA',
+    'lightslategray' => '778899',
+    'lightslategrey' => '778899',
+    'lightsteelblue' => 'B0C4DE',
+    'lightyellow' => 'FFFFE0',
+    'lime' => '00FF00',
+    'limegreen' => '32CD32',
+    'linen' => 'FAF0E6',
+    'magenta' => 'FF00FF',
+    'maroon' => '800000',
+    'mediumaquamarine' => '66CDAA',
+    'mediumblue' => '0000CD',
+    'mediumorchid' => 'BA55D3',
+    'mediumpurple' => '9370D0',
+    'mediumseagreen' => '3CB371',
+    'mediumslateblue' => '7B68EE',
+    'mediumspringgreen' => '00FA9A',
+    'mediumturquoise' => '48D1CC',
+    'mediumvioletred' => 'C71585',
+    'midnightblue' => '191970',
+    'mintcream' => 'F5FFFA',
+    'mistyrose' => 'FFE4E1',
+    'moccasin' => 'FFE4B5',
+    'navajowhite' => 'FFDEAD',
+    'navy' => '000080',
+    'oldlace' => 'FDF5E6',
+    'olive' => '808000',
+    'olivedrab' => '6B8E23',
+    'orange' => 'FFA500',
+    'orangered' => 'FF4500',
+    'orchid' => 'DA70D6',
+    'palegoldenrod' => 'EEE8AA',
+    'palegreen' => '98FB98',
+    'paleturquoise' => 'AFEEEE',
+    'palevioletred' => 'DB7093',
+    'papayawhip' => 'FFEFD5',
+    'peachpuff' => 'FFDAB9',
+    'peru' => 'CD853F',
+    'pink' => 'FFC0CB',
+    'plum' => 'DDA0DD',
+    'powderblue' => 'B0E0E6',
+    'purple' => '800080',
+    'red' => 'FF0000',
+    'rosybrown' => 'BC8F8F',
+    'royalblue' => '4169E1',
+    'saddlebrown' => '8B4513',
+    'salmon' => 'FA8072',
+    'sandybrown' => 'F4A460',
+    'seagreen' => '2E8B57',
+    'seashell' => 'FFF5EE',
+    'sienna' => 'A0522D',
+    'silver' => 'C0C0C0',
+    'skyblue' => '87CEEB',
+    'slateblue' => '6A5ACD',
+    'slategray' => '708090',
+    'slategrey' => '708090',
+    'snow' => 'FFFAFA',
+    'springgreen' => '00FF7F',
+    'steelblue' => '4682B4',
+    'tan' => 'D2B48C',
+    'teal' => '008080',
+    'thistle' => 'D8BFD8',
+    'tomato' => 'FF6347',
+    'turquoise' => '40E0D0',
+    'violet' => 'EE82EE',
+    'wheat' => 'F5DEB3',
+    'white' => 'FFFFFF',
+    'whitesmoke' => 'F5F5F5',
+    'yellow' => 'FFFF00',
+    'yellowgreen' => '9ACD32'
+);
+
+foreach ($colorsToConvert as $name => $hex) {
+    $hex = '#' . $hex;
+
+    $answer = Color::nameToHex($name);
+    Assert::same(
+        $hex,
+        $answer,
+        'Incorrect hex result: "' . Color::nameToHex($name) .
+        '" should convert to "' . $hex .
+        '", but output was: "' . $answer . '".'
+    );
+}

+ 72 - 0
lib/composer/mexitek/phpcolors/tests/colorConvertRgbToHex.phpt

@@ -0,0 +1,72 @@
+<?php
+
+require __DIR__ . '/bootstrap.php';
+
+use Mexitek\PHPColors\Color;
+use Tester\Assert;
+
+// Colors in RGB, for testing.
+$blue = [
+    'R' => 0,
+    'G' => 158,
+    'B' => 204,
+];
+$yellow = [
+    'R' => 244,
+    'G' => 231,
+    'B' => 15,
+];
+$black = [
+    'R' => 0,
+    'G' => 0,
+    'B' => 0,
+];
+$white = [
+    'R' => 255,
+    'G' => 255,
+    'B' => 255,
+];
+
+// Test cases.
+$colorsToConvert = array(
+    'blue' => [ // rgb(0, 158, 204)
+        'hex' => '009ecc',
+        'rgb' => $blue,
+    ],
+    'yellow' => [ // rgb(244, 231, 15)
+        'hex' => 'f4e70f',
+        'rgb' => $yellow,
+    ],
+    'black' => [
+        'hex' => '000000',
+        'rgb' => $black,
+    ],
+    'white' => [
+        'hex' => 'ffffff',
+        'rgb' => $white,
+    ],
+);
+
+
+foreach ($colorsToConvert as $color) {
+    $rgb = $color['rgb'];
+    $hex = $color['hex'];
+
+    $answer = Color::rgbToHex($rgb);
+    Assert::same(
+        $hex,
+        $answer,
+        'Incorrect hex result: "' . Color::rgbToString($rgb) .
+        '" should convert to "' . $hex .
+        '", but output was: "' . $answer . '".'
+    );
+
+    $revertAnswer = Color::hexToRgb($hex);
+    Assert::same(
+        $rgb,
+        $revertAnswer,
+        'Incorrect rgb result: "' . $hex .
+        '" should convert to "' . Color::rgbToString($rgb) .
+        '", but output was: "' . Color::rgbToString($revertAnswer) . '".'
+    );
+}

+ 19 - 0
lib/composer/mexitek/phpcolors/tests/colorInput.phpt

@@ -0,0 +1,19 @@
+<?php
+
+require __DIR__ . '/bootstrap.php';
+
+use Mexitek\PHPColors\Color;
+use Tester\Assert;
+
+// Test that a hex starting with '#' is supported as input
+$expected = array(
+    "#ffffff",
+    "#00ff00",
+    "#000000",
+    "#ff9a00",
+);
+
+foreach ($expected as $input) {
+    $color = new Color($input);
+    Assert::same((string) $color, $input, 'Incorrect color returned.');
+}

+ 24 - 0
lib/composer/mexitek/phpcolors/tests/colorMix.phpt

@@ -0,0 +1,24 @@
+<?php
+
+require __DIR__ . '/bootstrap.php';
+
+use Mexitek\PHPColors\Color;
+use Tester\Assert;
+
+
+$expected = array(
+    "ffffff" => array("ff0000", "ff7f7f"), // ffffff + ff0000 = ff7f7f
+    "00ff00" => array("ff0000", "7f7f00"),
+    "000000" => array("ff0000", "7f0000"),
+    "002fff" => array("000000", "00177f"),
+    "00ffed" => array("000000", "007f76"),
+    "ff9a00" => array("000000", "7f4d00"),
+    "ff9a00" => array("ffffff", "ffcc7f"),
+    "00ff2d" => array("ffffff", "7fff96"),
+    "8D43B4" => array("35CF64", "61898c"),
+);
+
+foreach ($expected as $original => $complementary) {
+    $color = new Color($original);
+    Assert::same($complementary[1], $color->mix($complementary[0]), 'Incorrect mix color returned.');
+}