<?php
/*
 * Copyright (c) 2013 Michel Petit <petit.michel@gmail.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.
 */

namespace Malenki\Math\Stats;

use Malenki\Math\Random;

/**
 * Normal Distribution.
 *
 * Normal distribution is statistical mathematical function
 * defined by mean (µ) and standard deviation (𝛔).
 *
 * This class used curve created with given mean and sigma, can return value
 * for given x, but can also create fictive samples too.
 *
 * @property-read $mean Gets the mean
 * @property-read $mu Gets the mean too
 * @property-read $µ Last attribute to get mean
 * @property-read $sigma Gets standard deviation
 * @property-read $std This gets standard deviation too
 * @property-read $𝛔 Last way to get standard deviation
 * @author Michel Petit <petit.michel@gmail.com>
 * @license MIT
 */
class NormalDistribution
{
    /**
     * Stores sigma value, the standard deviation.
     *
     * @var float
     * @access protected
     */
    protected $float_sigma = 0;

    /**
     * Stores mu value, the mean.
     *
     * @var float
     * @access protected
     */
    protected $float_mu = 0;

    /**
     * Precision for number of digits into the mantis.
     *
     * @var float
     * @access protected
     */
    protected $int_precision = 0;

    /**
     * Defines magic getters to have easy acces to mean and standard deviation.
     *
     * @param  string $name
     * @access public
     * @return float
     */
    public function __get($name)
    {
        if (in_array($name, array('mean', 'mu', 'µ'))) {
            return $this->float_mu;
        }

        if (in_array($name, array('sigma', 'std', '𝛔'))) {
            return $this->float_sigma;
        }
    }

    /**
     * Create normal distribution object with given mean and sigma.
     *
     * To create fictive samples or just study curve, only mean and sigma are
     * necessary for the first step.
     *
     * @throw \InvalidArgumentException If sigma or mu are not number
     * @throw \InvalidArgumentException If mu is not a positive number
     * @param  float $mu    Mean
     * @param  float $sigma Standard deviation
     * @access public
     * @return void
     */
    public function __construct($mu = 0, $sigma = 1)
    {
        if (!is_numeric($sigma) || !is_numeric($mu)) {
            throw new \InvalidArgumentException('Sigma and Mu must be number.');
        }

        if ($mu < 0) {
            throw new \InvalidArgumentException('µ must be a positive real number.');
        }

        $this->float_sigma = $sigma;
        $this->float_mu = $mu;
    }

    /**
     * Compute the variance and return the result.
     *
     * @see NormalDistribution::precision()
     * @access public
     * @return float
     */
    public function variance()
    {
        $float_variance = pow($this->float_sigma, 2);

        if ($this->int_precision) {
            return round($float_variance, $this->int_precision);
        }

        return $float_variance;
    }

    /**
     * Set precision for all returned results.
     *
     * @param  integer $n Give number of digits for the mantis
     * @access public
     * @return void
     */
    public function precision($n)
    {
        if (!is_numeric($n) || $n < 0) {
            throw new \InvalidArgumentException('Precision must be positive number');
        }

        $this->int_precision = (integer) $n;
    }

    /**
     * Give the maximal value of the curve for the current sigma and mu.
     *
     * @see NormalDistribution::precision()
     * @access public
     * @return float
     */
    public function max()
    {
        $float_max = 1 / ($this->float_sigma * sqrt(2 * pi()));

        if ($this->int_precision) {
            return round($float_max, $this->int_precision);
        }

        return $float_max;
    }

    /**
     * Gets the full width at half maximum.
     *
     * @see NormalDistribution::precision()
     * @access public
     * @return float
     */
    public function fwhm()
    {
        $float_fwhm = 2 * sqrt(2 * log(2)) * $this->float_sigma;

        if ($this->int_precision) {
            return round($float_fwhm, $this->int_precision);
        }

        return $float_fwhm;
    }

    /**
     * Function that returns normal distribution value for given x.
     *
     * @see NormalDistribution::precision()
     * @throw \InvalidArgumentException If x is not numerical value.
     * @param  float $x
     * @access public
     * @return float
     */
    public function f($x)
    {
        if (!is_numeric($x)) {
            throw new \InvalidArgumentException('x variable must be numeric value.');
        }

        $float_fx = exp(-0.5 * pow(($x - $this->float_mu) / $this->float_sigma, 2)) / ($this->float_sigma * sqrt(2 * pi()));

        if ($this->int_precision) {
            return round($float_fx, $this->int_precision);
        }

        return $float_fx;
    }

    /**
     * Do same things like NormalDistribution::f() but for several values at once.
     *
     * @see NormalDistribution::precision()
     * @param  array $arr_x Several x values
     * @access public
     * @return array Each items is small object having x and fx attributes.
     */
    public function fn(array &$arr_x)
    {
        $arr = array();

        foreach ($arr_x as $x) {
            $item = new \stdClass();
            $item->x = $x;
            $item->fx = $this->f($x);
            $arr[] = $item;
        }

        return $arr;
    }

    /**
     * Simulates samples following normal distribution
     *
     * @see NormalDistribution::precision()
     * @throw \InvalidArgumentException If amount is not greater than zero
     * @param  integer $amount
     * @access public
     * @return array
     */
    public function samples($amount)
    {

        if (!is_numeric($amount) || $amount < 1) {
            throw new \InvalidArgumentException('Amount of samples must be greater or equal to one');
        }

        $arr = array();

        for ($i = 1; $i <= $amount; $i++) {
            $r = new Random();
            $float_u = $r->get();
            $float_v = $r->get();

            $double_x = $this->float_sigma * sqrt(-2 * log($float_u)) * cos(2 * pi() * $float_v) + $this->float_mu;

            if ($this->int_precision) {
                $arr[] = round($double_x, $this->int_precision);
            } else {
                $arr[] = $double_x;
            }
        }

        return $arr;
    }
}


<?php

/**
 * This file is part of SilverWare.
 *
 * PHP version >=5.6.0
 *
 * For full copyright and license information, please view the
 * LICENSE.md file that was distributed with this source code.
 *
 * @package SilverWare\FontIcons\Forms
 * @author Colin Tucker <colin@praxis.net.au>
 * @copyright 2017 Praxis Interactive
 * @license https://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
 * @link https://github.com/praxisnetau/silverware-font-icons
 */

namespace SilverWare\FontIcons\Forms;

use SilverStripe\Control\HTTPRequest;
use SilverStripe\View\ArrayData;
use SilverWare\Select2\Forms\Select2AjaxField;

/**
 * An extension of the Select2 Ajax field class for a font icon field.
 *
 * @package SilverWare\FontIcons\Forms
 * @author Colin Tucker <colin@praxis.net.au>
 * @copyright 2017 Praxis Interactive
 * @license https://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
 * @link https://github.com/praxisnetau/silverware-font-icons
 */
class FontIconField extends Select2AjaxField
{
    /**
     * Defines the allowed actions for this field.
     *
     * @var array
     * @config
     */
    private static $allowed_actions = [
        'search'
    ];

    /**
     * Defines the injector dependencies for this object.
     *
     * @var array
     * @config
     */
    private static $dependencies = [
        'backend' => '%$FontIconBackend'
    ];

    /**
     * Answers the field type for the template.
     *
     * @return string
     */
    public function Type()
    {
        return sprintf('fonticonfield %s', parent::Type());
    }

    /**
     * Answers the source items for the field.
     *
     * @return array|ArrayAccess
     */
    public function getSource()
    {
        // Answer Custom Source:

        if ($source = $this->source) {
            return $source;
        }

        // Answer Default Source:

        return $this->backend->getIcons();
    }

    /**
     * Answers an HTTP response containing JSON results matching the given search parameters.
     *
     * @param HTTPRequest $request
     *
     * @return HTTPResponse
     */
    public function search(HTTPRequest $request)
    {
        // Detect Ajax:

        if (!$request->isAjax()) {
            return;
        }

        // Initialise:

        $data = [];

        // Filter Icons:

        if ($term = $request->getVar('term')) {

            // Create Groups Array:

            $groups = [];

            // Iterate Icon Groups:

            foreach ($this->backend->getGroupedIcons() as $group => $icons) {

                // Create Children Array:

                $children = [];

                // Iterate Icons in Group:

                foreach ($icons as $id => $icon) {

                    if (stripos($id, $term) !== false) {
                        $children[] = $this->getResultData($this->getIconData($id));
                    }

                }

                // Create Result Group (if children defined):

                if (!empty($children)) {

                    $groups[] = [
                        'text' => $group,
                        'children' => $children
                    ];

                }

            }

            // Define Results:

            $data['results'] = $groups;

        }

        // Answer JSON Response:

        return $this->respond($data);
    }

    /**
     * Answers the result format defined for the receiver.
     *
     * @return string
     */
    public function getFormatResult()
    {
        return $this->formatResult ? $this->formatResult : $this->getFormatDefault();
    }

    /**
     * Answers the selection format defined for the receiver.
     *
     * @return string
     */
    public function getFormatSelection()
    {
        return $this->formatSelection ? $this->formatSelection : $this->getFormatDefault();
    }

    /**
     * Answers the default format for the receiver.
     *
     * @return string
     */
    protected function getFormatDefault()
    {
        return sprintf('<%1$s class="%2$s"></%1$s> $Title', $this->FormatTag, $this->FormatClass);
    }

    /**
     * Answers the tag for the default format.
     *
     * @return string
     */
    protected function getFormatTag()
    {
        return $this->backend->getFieldTagName();
    }

    /**
     * Answers the class for the default format.
     *
     * @return string
     */
    protected function getFormatClass()
    {
        return str_replace('{value}', '$ID', $this->backend->getFieldClasses());
    }

    /**
     * Answers the record identified by the given value.
     *
     * @param mixed $id
     *
     * @return ViewableData
     */
    protected function getValueRecord($id)
    {
        return $this->getIconData($id);
    }

    /**
     * Answers an array data object for the given icon ID.
     *
     * @param string $id
     *
     * @return ArrayData
     */
    protected function getIconData($id)
    {
        return ArrayData::create(['ID' => $id, 'Title' => $id]);
    }
}


<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Rougin\Slytherin\Http;

use Psr\Http\Message\StreamInterface;

/**
 * Stream
 *
 * @package Slytherin
 * @author  Kévin Dunglas <dunglas@gmail.com>
 * @author  Jérémy 'Jejem' Desvages <jejem@phyrexia.org>
 * @author  Rougin Gutib <rougingutib@gmail.com>
 */
class Stream implements StreamInterface
{
    /**
     * @var array|null
     */
    protected $meta = null;

    /**
     * @var array
     */
    protected $readable = array('r', 'r+', 'w+', 'a+', 'x+', 'c+', 'w+b');

    /**
     * @var integer|null
     */
    protected $size = null;

    /**
     * @var resource|null
     */
    protected $stream = null;

    /**
     * @var array
     */
    protected $writable = array('r+', 'w', 'w+', 'a', 'a+', 'x', 'x+', 'c', 'c+', 'w+b');

    /**
     * Initializes the stream instance.
     *
     * @param resource|null $stream
     */
    public function __construct($stream = null)
    {
        $this->stream = $stream;
    }

    /**
     * Reads all data from the stream into a string, from the beginning to end.
     *
     * @return string
     */
    public function __toString()
    {
        $this->rewind();

        return $this->getContents();
    }

    /**
     * Closes the stream and any underlying resources.
     *
     * @return void
     */
    public function close()
    {
        is_null($this->stream) ?: fclose($this->stream);

        $this->detach();
    }

    /**
     * Separates any underlying resources from the stream.
     *
     * @return resource|null
     */
    public function detach()
    {
        $stream = $this->stream;

        $this->meta = null;

        $this->size = null;

        $this->stream = null;

        return $stream;
    }

    /**
     * Returns true if the stream is at the end of the stream.
     *
     * @return boolean
     */
    public function eof()
    {
        return is_null($this->stream) ?: feof($this->stream);
    }

    /**
     * Returns the remaining contents in a string
     *
     * @return string
     *
     * @throws \RuntimeException
     */
    public function getContents()
    {
        if (is_null($this->stream) || ! $this->isReadable()) {
            $message = 'Could not get contents of stream';

            throw new \RuntimeException($message);
        }

        return stream_get_contents($this->stream);
    }

    /**
     * Returns stream metadata as an associative array or retrieve a specific key.
     *
     * @param  string $key
     * @return array|mixed|null
     */
    public function getMetadata($key = null)
    {
        isset($this->stream) && $this->meta = stream_get_meta_data($this->stream);

        $metadata = isset($this->meta[$key]) ? $this->meta[$key] : null;

        return is_null($key) ? $this->meta : $metadata;
    }

    /**
     * Returns the size of the stream if known.
     *
     * @return integer|null
     */
    public function getSize()
    {
        if (is_null($this->size) === true) {
            $stats = fstat($this->stream);

            $this->size = $stats['size'];
        }

        return $this->size;
    }

    /**
     * Returns whether or not the stream is readable.
     *
     * @return boolean
     */
    public function isReadable()
    {
        $mode = $this->getMetadata('mode');

        return in_array($mode, $this->readable);
    }

    /**
     * Returns whether or not the stream is seekable.
     *
     * @return boolean
     */
    public function isSeekable()
    {
        return $this->getMetadata('seekable');
    }

    /**
     * Returns whether or not the stream is writable.
     *
     * @return boolean
     */
    public function isWritable()
    {
        $mode = $this->getMetadata('mode');

        return in_array($mode, $this->writable);
    }

    /**
     * Read data from the stream.
     *
     * @param  integer $length
     * @return string
     *
     * @throws \RuntimeException
     */
    public function read($length)
    {
        $data = fread($this->stream, $length);

        if (! $this->isReadable() || $data === false) {
            $message = 'Could not read from stream';

            throw new \RuntimeException($message);
        }

        return $data;
    }

    /**
     * Seek to the beginning of the stream.
     *
     * @throws \RuntimeException
     */
    public function rewind()
    {
        $this->seek(0);
    }

    /**
     * Seek to a position in the stream.
     *
     * @param integer $offset
     * @param integer $whence
     *
     * @throws \RuntimeException
     */
    public function seek($offset, $whence = SEEK_SET)
    {
        $seek = -1;

        $this->stream && $seek = fseek($this->stream, $offset, $whence);

        if (! $this->isSeekable() || $seek === -1) {
            $message = 'Could not seek in stream';

            throw new \RuntimeException($message);
        }
    }

    /**
     * Returns the current position of the file read/write pointer.
     *
     * @return integer
     *
     * @throws \RuntimeException
     */
    public function tell()
    {
        $position = false;

        $this->stream && $position = ftell($this->stream);

        if (is_null($this->stream) || $position === false) {
            $message = 'Could not get position of pointer in stream';

            throw new \RuntimeException($message);
        }

        return $position;
    }

    /**
     * Write data to the stream.
     *
     * @param  string $string
     * @return integer
     *
     * @throws \RuntimeException
     */
    public function write($string)
    {
        if (! $this->isWritable()) {
            $message = 'Stream is not writable';

            throw new \RuntimeException($message);
        }

        $this->size = null;

        return fwrite($this->stream, $string);
    }
}


<?php
/*
 * Copyright (c) 2014 Michel Petit <petit.michel@gmail.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.
 */

namespace Malenki\Math\Stats;

class Stats implements \Countable
{
    protected $arr = array();
    protected $int_count = null;

    protected $float_harmonic_mean = null;
    protected $float_geometric_mean = null;
    protected $float_arithmetic_mean = null;
    protected $float_root_mean_square = null;
    protected $float_range = null;
    protected $float_variance = null;
    protected $float_stddev = null;
    protected $float_sample_variance = null;
    protected $float_kurtosis = null;
    protected $float_median = null;
    protected $float_skew = null;
    protected $arr_mode = null;
    protected $arr_f = null;
    protected $arr_frequency = null;
    protected $arr_cumulative_frequency = null;

    public function __get($name)
    {
        if($name == 'array'){
            return $this->arr;
        }

        if (in_array($name, array('is_unimodal', 'unimodal'))) {
            return $this->isUnimodal();
        }

        if (in_array($name, array('is_bimodal', 'bimodal'))) {
            return $this->isBimodal();
        }

        if (in_array($name, array('is_multimodal', 'multimodal'))) {
            return $this->isMultimodal();
        }

        if (in_array($name, array('harmonic_mean', 'subcontrary_mean', 'H'))) {
            return $this->harmonicMean();
        }

        if (in_array($name, array('geometric_mean', 'G'))) {
            return $this->geometricMean();
        }

        if (in_array($name, array('arithmetic_mean', 'mean', 'A', 'mu'))) {
            return $this->arithmeticMean();
        }

        if (in_array($name, array('root_mean_square', 'rms', 'quadratic_mean', 'Q'))) {
            return $this->rootMeanSquare();
        }

        if (in_array($name, array('heronian_mean', 'heronian'))) {
            return $this->heronianMean();
        }

        if (in_array($name, array('contraharmonic_mean', 'contraharmonic'))) {
            return $this->contraharmonicMean();
        }

        if (in_array($name, array('midrange', 'midextreme', 'mid_range', 'mid_extreme'))) {
            return $this->midrange();
        }

        if ($name == 'relative_frequency') {
            return $this->relativeFrequency();
        }

        if ($name == 'cumulative_frequency') {
            return $this->cumulativeFrequency();
        }

        if ($name == 'square_sum' || $name == 'sum2') {
            return $this->squareSum();
        }

        if (in_array($name, array('sum', 'center', 'median', 'min', 'max', 'mode', 'f', 'range'))) {
            return $this->$name();
        }

        if (in_array($name, array('variance', 'var', 'population_variance'))) {
            return $this->variance();
        }

        if (in_array($name, array('stdev', 'stddev', 'standard_deviation', 'sigma'))) {
            return $this->standardDeviation();
        }

        if (in_array($name, array('sample_variance', 's2'))) {
            return $this->sampleVariance();
        }

        if ($name == 'kurtosis') {
            return $this->kurtosis();
        }

        if ($name == 'is_platykurtic') {
            return $this->isPlatykurtic();
        }

        if ($name == 'is_leptokurtic') {
            return $this->isLeptokurtic();
        }

        if ($name == 'is_mesokurtic') {
            return $this->isMesokurtic();
        }

        if (preg_match('/(first|second|third|last)_quartile/', $name)) {
            $n = 1;

            if (preg_match('/^first/', $name)) {
                $n = 1;
            }
            if (preg_match('/^second/', $name)) {
                $n = 2;
            }
            if (preg_match('/^(third|last)/', $name)) {
                $n = 3;
            }

            return $this->quartile($n);
        }

        if(
            in_array(
                $name,
                array(
                    'interquartile_range',
                    'interquartile',
                    'iqr',
                    'IQR'
                )
            )
        )
        {
            return $this->interquartileRange();
        }

        if ($name == 'skew' || $name == 'skewness') {
            return $this->$name();
        }

        if(
            in_array(
                $name,
                array(
                    'is_left_skewed',
                    'left_skewed',
                    'is_negative_skew',
                    'negative_skew',
                    'is_left_tailed',
                    'left_tailed',
                    'skewed_to_the_left'
                )
            )
        )
        {
            return $this->isLeftSkewed();
        }

        if(
            in_array(
                $name,
                array(
                    'is_right_skewed',
                    'right_skewed',
                    'is_positive_skew',
                    'positive_skew',
                    'is_right_tailed',
                    'right_tailed',
                    'skewed_to_the_right'
                )
            )
        )
        {
            return $this->isRightSkewed();
        }

        if (in_array($name, array('frequency', 'freq'))) {
            return $this->frequency();
        }

        if (in_array($name, array('coefficient_of_variation', 'cv'))) {
            return $this->coefficientOfVariation();
        }

        if(
            in_array(
                $name,
                array(
                    'coefficient_of_dispersion',
                    'dispersion_index',
                    'coefficient_of_dispersion',
                    'variance_to_mean_ratio',
                    'vmr',
                    'VMR',
                    'D'
                )
            )
        )
        {
            return $this->indexOfDispersion();
        }

        if(
            in_array(
                $name,
                array(
                    'pearsons_rho',
                    'ppmcc',
                    'pcc',
                    'pearson_product_moment_correlation_coefficient'
                )
            )
        )
        {
            return $this->pearsonsR();
        }

    }

    public function __construct($arr = array())
    {
        $this->merge($arr);
    }

    public function get($idx)
    {
        if (!is_integer($idx)) {
            throw new \InvalidArgumentException('Index must be an integer');
        }

        if ($idx < 0) {
            throw new \InvalidArgumentException('Index must be null or positive integer!');
        }

        return $this->arr[$idx];
    }

    public function sum()
    {
        return array_sum($this->arr);
    }

    public function powerSum($p)
    {
        $arr = $this->arr;

        foreach($arr as $k => $v) {
            $arr[$k] = pow($v, $p);
        }

        return array_sum($arr);
    }

    public function squareSum()
    {
        return $this->powerSum(2);
    }

    public function min()
    {
        return min($this->arr);
    }

    public function max()
    {
        return max($this->arr);
    }

    public function count()
    {
        if (is_null($this->int_count)) {
            $this->int_count = count($this->arr);
        }

        return $this->int_count;
    }

    public function isEmpty()
    {
        return count($this) == 0;
    }

    public function allPositive()
    {
        for ($i = 0; $i < count($this); $i++) {
            if ($this->arr[$i] < 0) {
                return false;
            }
        }

        return true;
    }

    public function allInteger()
    {
        for ($i = 0; $i < count($this); $i++) {
            $n = $this->arr[$i];

            if (abs($n) - floor(abs($n)) != 0) {
                return false;
            }
        }

        return true;
    }

    protected function clear()
    {
        $this->int_count = null;
        $this->float_harmonic_mean = null;
        $this->float_geometric_mean = null;
        $this->float_arithmetic_mean = null;
        $this->float_root_mean_square = null;
        $this->float_range = null;
        $this->float_variance = null;
        $this->float_sample_variance = null;
        $this->float_stddev = null;
        $this->float_kurtosis = null;
        $this->float_median = null;
        $this->float_skew = null;
        $this->arr_mode = null;
        $this->arr_frequency = null;
        $this->arr_f = null;
        $this->arr_cumulative_frequency = null;
    }

    public function merge($arr)
    {
        if (!is_array($arr)) {
            throw new \InvalidArgumentException('Merging new values must be done with array!');
        }

        foreach ($arr as $k => $v) {
            if (!is_numeric($v)) {
                throw new \RuntimeException('Array to merge contains non numeric values!');
            }

            $arr[$k] = (double) $v;
        }

        $this->arr = array_merge($this->arr, $arr);
        $this->clear();

        return $this;
    }

    public function add($num)
    {
        if (!is_numeric($num)) {
            throw new \InvalidArgumentException(
                'Only numeric values are allowed into statistical collection.'
            );
        }
        $this->arr[] = (double) $num;
        $this->clear();

        return $this;
    }

    public function range()
    {
        if (is_null($this->float_range)) {
            $this->float_range = max($this->arr) - min($this->arr);
        }

        return $this->float_range;
    }

    /**
     * @todo Implement mode for continuous distribution, see http://en.wikipedia.org/wiki/Mode_(statistics)#Mode_of_a_sample
     */
    public function mode($inteval = null)
    {
        if (is_null($this->arr_mode)) {
            if ($this->allInteger()) {
                $arr = $this->frequency();
                $max = max($arr);
                $arr_out = array();

                foreach ($arr as $k => $v) {
                    if ($v == $max) {
                        $arr_out[] = (double) $k;
                    }
                }

                $this->arr_mode = $arr_out;
            } else {
                if (is_null($interval) || $interval <= 0) {
                    throw new \InvalidArgumentException('Interval for continuous distribution must be a valid positive number.');
                }
                throw new \RuntimeException('Mode for continuous distribution is not implemented yet.');
            }
        }

        return $this->arr_mode;
    }

    public function isUnimodal()
    {
        return count($this->mode()) == 1;
    }

    public function isBimodal()
    {
        return count($this->mode()) == 2;
    }

    public function isMultimodal()
    {
        return count($this->mode()) > 2;
    }

    public function arithmeticMean()
    {
        if (is_null($this->float_arithmetic_mean)) {
            $this->float_arithmetic_mean = array_sum($this->arr) / count($this);
        }

        return $this->float_arithmetic_mean;
    }

    public function mean()
    {
        return $this->arithmeticMean();
    }

    public function center()
    {
        $arr = array();

        foreach($this->arr as $v){
            $arr[] = $v - $this->arithmeticMean();
        }

        return $arr;
    }

    public function harmonicMean()
    {
        if (is_null($this->float_harmonic_mean)) {
            $arr = array();

            foreach ($this->arr as $v) {
                $arr[] = 1 / $v;
            }

            $this->float_harmonic_mean = count($this) / array_sum($arr);
        }

        return $this->float_harmonic_mean;
    }

    public function geometricMean()
    {
        if (is_null($this->float_geometric_mean)) {
            $this->float_geometric_mean = pow(
                array_product($this->arr),
                1 / count($this)
            );
        }

        return $this->float_geometric_mean;
    }

    public function rootMeanSquare()
    {
        if (is_null($this->float_root_mean_square)) {
            $s = new self(
                array_map(
                    function ($n) {
                        return $n * $n;
                    },
                    $this->arr
                )
            );

            $this->float_root_mean_square = sqrt($s->mean);
        }

        return $this->float_root_mean_square;
    }

    public function rms()
    {
        return $this->rootMeanSquare();
    }

    public function quadraticMean()
    {
        return $this->rootMeanSquare();
    }

    public function generalizedMean($p)
    {
        if ($p <= 0) {
            throw new \InvalidArgumentException('Generalized mean takes p as non-zero positive real number.');
        }

        if (!$this->allPositive()) {
            throw new \RuntimeException('Power mean use only collection of positive numbers!');
        }

        $arr = array();

        for ($i = 0; $i < count($this); $i++) {
            $arr[] = pow($this->arr[$i], $p);
        }

        return pow(array_sum($arr) / count($this), 1/$p);
    }

    public function powerMean($p)
    {
        return $this->generalizedMean($p);
    }

    public function heronianMean()
    {
        if (count($this) != 2) {
            throw new \RuntimeException('Heronian mean use only 2 numbers!');
        }

        if (!$this->allPositive()) {
            throw new \RuntimeException('Heronian mean is only possible on positive real numbers');
        }

        return ($this->arr[0] + sqrt(array_product($this->arr)) + $this->arr[1]) / 3;
    }

    public function heronian()
    {
        return $this->heronianMean();
    }

    public function lehmerMean($p)
    {
        if (!is_numeric($p)) {
            throw new \InvalidArgumentException('P must be a real number');
        }

        if (!$this->allPositive()) {
            throw new \RuntimeException('Lehmer mean is only possible on positive real numbers');
        }

        $top = 0;
        $bottom = 0;

        foreach ($this->arr as $v) {
            $top += pow($v, $p);
            $bottom += pow($v, $p - 1);
        }

        return $top / $bottom;
    }

    public function lehmer($p)
    {
        return $this->lehmerMean();
    }

    public function contraharmonicMean()
    {
        return $this->lehmerMean(2);
    }

    public function contraharmonic()
    {
        return $this->lehmerMean(2);
    }

    public function midrange()
    {
        $s = new self();
        $s->add(max($this->arr));
        $s->add(min($this->arr));

        return $s->mean;
    }

    public function midextreme()
    {
        return $this->midrange();
    }

    public function variance()
    {
        if ($this->isEmpty()) {
            throw new \RuntimeException('Cannot compute variance on void collection');
        }

        if (is_null($this->float_variance)) {
            $this->float_variance = $this->centralMoment(2);
        }

        return $this->float_variance;
    }

    public function populationVariance()
    {
        return $this->variance();
    }

    public function covariance($data, $is_sample = false)
    {
        if (!is_array($data) && !($data instanceof Stats)) {
            throw new \InvalidArgumentException('Covariance must be compute using array or Stats instance');
        }

        if (is_array($data)) {
            $data = new self($data);
        }

        $a = ($this->sum() * $data->sum())/ count($this);

        $sum = 0;

        for ($i = 0; $i < count($this); $i++) {
            $sum += $this->get($i) * $data->get($i);
        }

        $cnt = $is_sample ? count($this) - 1 : count($this);

        return ($sum - $a)/ $cnt;
    }

    public function populationCovariance($data)
    {
        return $this->covariance($data);
    }

    public function sampleCovariance($data)
    {
        return $this->covariance($data, true);
    }

    public function standardDeviation()
    {
        return sqrt($this->variance());
    }

    public function stddev()
    {
        return $this->standardDeviation();
    }

    public function stdev()
    {
        return $this->standardDeviation();
    }

    public function sigma()
    {
        return $this->standardDeviation();
    }

    public function sampleVariance()
    {
        if (count($this) <= 1) {
            throw new \RuntimeException('Cannot compute sample variance, sample must have at least 2 elements');
        }

        if (is_null($this->float_sample_variance)) {
            $arr = array();

            for ($i = 0; $i < count($this); $i++) {
                $arr[] = pow($this->arr[$i] - $this->mean(), 2);
            }

            $this->float_sample_variance = array_sum($arr) / (count($this) - 1);
        }

        return $this->float_sample_variance;
    }

    public function s2()
    {
        return $this->sampleVariance();
    }

    public function centralMoment($k)
    {
        $arr = array();

        for ($i = 0; $i < count($this); $i++) {
            $arr[] = pow($this->arr[$i] - $this->mean(), $k);
        }

        return array_sum($arr) / count($this);
    }

    public function moment($k)
    {
        return $this->centralMoment($k);
    }

    public function kurtosis()
    {
        if (is_null($this->float_kurtosis)) {
            $this->float_kurtosis = ($this->moment(4) / pow($this->moment(2), 2)) - 3;
        }

        return $this->float_kurtosis;
    }

    public function isPlatykurtic()
    {
        return $this->kurtosis() < 0;
    }

    public function isLeptokurtic()
    {
        return $this->kurtosis() > 0;
    }

    public function isMesokurtic()
    {
        return $this->kurtosis() == 0;
    }

    public function quartile($n)
    {
        $arr = $this->arr;
        sort($arr, SORT_NUMERIC);

        if ($n == 1 || $n == 3) {
            return $arr[floor($n * count($this) / 4) - 1];
        } else {
            //odd
            if (count($this) & 1) {
                return $arr[floor(count($this) / 2)];
            }
            //even
            else {
                $s = new self();
                $s->add($arr[(count($this)/2) - 1]);
                $s->add($arr[count($this)/2]);

                return $s->mean;

            }
        }
    }

    public function median()
    {
        if (is_null($this->float_median)) {
            $this->float_median = $this->quartile(2);
        }

        return $this->float_median;
    }

    public function interquartileRange()
    {
        return $this->quartile(3) - $this->quartile(1);
    }

    public function iqr()
    {
        return $this->interquartileRange();
    }

    public function percentile($n)
    {
        if($n > 100 || $n < 0) {
            throw new \OutOfRangeException('Percent must be number between 0 and 100.');
        }

        $arr = $this->arr;
        sort($arr, SORT_NUMERIC);

        if($n == 100)
        {
            return end($arr);
        }

        if ($n != 50) {
            return $arr[floor($n * count($this) / 100)];
        } else {
            //odd
            if (count($this) & 1) {
                return $arr[floor(count($this) / 2)];
            }
            //even
            else {
                $s = new self();
                $s->add($arr[(count($this)/2) - 1]);
                $s->add($arr[count($this)/2]);

                return $s->mean;

            }
        }
    }

    public function skewness()
    {
        if (is_null($this->float_skew)) {
            $this->float_skew = $this->centralMoment(3) / pow($this->centralMoment(2), 3/2);
        }

        return $this->float_skew;
    }

    public function skew()
    {
        return $this->skewness();
    }

    public function isLeftSkewed()
    {
        return $this->skewness() < 0;
    }

    public function isRightSkewed()
    {
        return $this->skewness() > 0;
    }

    public function frequency()
    {
        if(is_null($this->arr_frequency)){
            $arr = array();

            foreach ($this->arr as $n) {
                $idx = "$n";

                if (isset($arr[$idx])) {
                    $arr[$idx]++;
                } else {
                    $arr[$idx] = 1;
                }
            }

            $this->arr_frequency = $arr;
        }

        return $this->arr_frequency;
    }

    public function cumulativeFrequency()
    {
        if(is_null($this->arr_cumulative_frequency)){
            $this->arr_cumulative_frequency = $this->frequency();
            $prev = 0;

            foreach($this->arr_cumulative_frequency as $k => $v){
                $prev += $v;
                $this->arr_cumulative_frequency[$k] = $prev;
            }

        }

        return $this->arr_cumulative_frequency;
    }

    /**
     * Relative frequency, like frequency, but divide each but total amount.
     *
     * @access public
     * @return array
     */
    public function f()
    {
        if(is_null($this->arr_f)){
            $arr = $this->frequency();
            array_walk(
                $arr,
                function(&$v, $k, $n){
                    $v = $v / $n;
                },
                count($this)
            );

            $this->arr_f = $arr;
        }

        return $this->arr_f;
    }

    public function relativeFrequency()
    {
        return $this->f();
    }

    public function coefficientOfVariation()
    {
        return $this->standardDeviation() / $this->arithmeticMean();
    }

    public function cv()
    {
        return $this->coefficientOfVariation();
    }

    public function indexOfDispersion()
    {
        return $this->variance() / $this->arithmeticMean();
    }

    public function pearsonsR($data)
    {
        //TODO: complete and test it
        if (!is_array($data) && !($data instanceof Stats)) {
            throw new \InvalidArgumentException('PPMCC must be compute using array or Stats instance');
        }

        if (is_array($data)) {
            $data = new self($data);
        }

        return $this->covariance($data) / ($this->standardDeviation() * $data->stddev);
    }
}


<?php

namespace BryanCrowe\Growl\Builder;

/**
 * This class is a builder for terminal-notifier commands.
 */
class TerminalNotifierBuilder extends BuilderAbstract
{
    /**
     * The notifier's path.
     *
     * @var string
     */
    protected $path = 'terminal-notifier';

    /**
     * Builds the terminal-notifier command to be executed.
     *
     * @param array $options An array of options to use for building the command.
     * @return string The fully-built command to execute.
     */
    public function build($options)
    {
        $command = $this->path;

        if (isset($options['title'])) {
            $command .= " -title {$options['title']}";
        }
        if (isset($options['subtitle'])) {
            $command .= " -subtitle {$options['subtitle']}";
        }
        if (isset($options['message'])) {
            $command .= " -message {$options['message']}";
        }
        if (isset($options['image'])) {
            $command .= " -appIcon {$options['image']}";
        }
        if (isset($options['contentImage'])) {
            $command .= " -contentImage {$options['contentImage']}";
        }
        if (isset($options['url'])) {
            $command .= " -open {$options['url']}";
        }

        return $command;
    }
}


<?php

namespace Rougin\Slytherin\Template;

/**
 * Twig Renderer
 *
 * A simple implementation of a template renderer that is based on top of
 * Sensiolab's Twig - a flexible, fast, and secure template engine for PHP.
 *
 * http://twig.sensiolabs.org
 *
 * @package Slytherin
 * @author  Rougin Gutib <rougingutib@gmail.com>
 */
class TwigRenderer implements RendererInterface
{
    /**
     * @var \Twig_Environment
     */
    protected $twig;

    /**
     * @param \Twig_Environment $twig
     * @param array             $globals -- NOTE: To be removed in v1.0.0.
     */
    public function __construct(\Twig_Environment $twig, array $globals = array())
    {
        // NOTE: To be removed in v1.0.0. Use __call instead
        foreach ($globals as $key => $value) {
            $twig->addGlobal($key, $value);
        }

        $this->twig = $twig;
    }

    /**
     * Renders a template.
     *
     * @param  string $template
     * @param  array  $data
     * @param  string $extension
     * @return string
     */
    public function render($template, array $data = array(), $extension = 'twig')
    {
        $file = $template . '.' . $extension;

        return $this->twig->render($file, $data);
    }

    /**
     * Calls methods from the Twig instance.
     *
     * @param  string $method
     * @param  mixed  $parameters
     * @return mixed
     */
    public function __call($method, $parameters)
    {
        return call_user_func_array(array($this->twig, $method), $parameters);
    }
}


<?php

/**
 * This file is part of SilverWare.
 *
 * PHP version >=5.6.0
 *
 * For full copyright and license information, please view the
 * LICENSE.md file that was distributed with this source code.
 *
 * @package SilverWare\FontIcons\Extensions
 * @author Colin Tucker <colin@praxis.net.au>
 * @copyright 2017 Praxis Interactive
 * @license https://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
 * @link https://github.com/praxisnetau/silverware-font-icons
 */

namespace SilverWare\FontIcons\Extensions;

use SilverStripe\Core\Convert;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Tab;
use SilverStripe\ORM\ArrayLib;
use SilverStripe\ORM\DataExtension;
use SilverStripe\ORM\FieldType\DBField;
use SilverWare\Colorpicker\Forms\ColorField;
use SilverWare\FontIcons\Forms\FontIconField;

/**
 * A data extension class which allows extended objects to use font icons.
 *
 * @package SilverWare\FontIcons\Extensions
 * @author Colin Tucker <colin@praxis.net.au>
 * @copyright 2017 Praxis Interactive
 * @license https://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
 * @link https://github.com/praxisnetau/silverware-font-icons
 */
class FontIconExtension extends DataExtension
{
    /**
     * Maps field names to field types for the extended object.
     *
     * @var array
     * @config
     */
    private static $db = [
        'FontIcon' => 'FontIcon',
        'FontIconColor' => 'Color'
    ];

    /**
     * Maps field and method names to the class names of casting objects.
     *
     * @var array
     * @config
     */
    private static $casting = [
        'FontIconTag' => 'HTMLFragment'
    ];

    /**
     * Defines the summary fields of this object.
     *
     * @var array
     * @config
     */
    private static $summary_fields = [
        'FontIconTagCMS'
    ];

    /**
     * Defines the injector dependencies for this object.
     *
     * @var array
     * @config
     */
    private static $dependencies = [
        'backend' => '%$FontIconBackend'
    ];

    /**
     * Updates the CMS fields of the extended object.
     *
     * @param FieldList $fields List of CMS fields from the extended object.
     *
     * @return void
     */
    public function updateCMSFields(FieldList $fields)
    {
        // Insert Icon Tab:

        $fields->insertAfter(
            Tab::create(
                'Icon',
                $this->owner->fieldLabel('Icon')
            ),
            'Main'
        );

        // Create Icon Fields:

        $fields->addFieldsToTab(
            'Root.Icon',
            [
                FontIconField::create(
                    'FontIcon',
                    $this->owner->fieldLabel('FontIcon')
                ),
                ColorField::create(
                    'FontIconColor',
                    $this->owner->fieldLabel('FontIconColor')
                )
            ]
        );
    }

    /**
     * Updates the field labels of the extended object.
     *
     * @param array $labels Array of field labels from the extended object.
     *
     * @return void
     */
    public function updateFieldLabels(&$labels)
    {
        $labels['FontIconColor'] = _t(__CLASS__ . '.ICONCOLOR', 'Icon color');

        $labels['Icon'] = $labels['FontIcon'] = $labels['FontIconTagCMS'] = _t(__CLASS__ . '.ICON', 'Icon');
    }

    /**
     * Answers a string of font icon class names for the extended object.
     *
     * @return string
     */
    public function getFontIconClass()
    {
        return Convert::raw2att(implode(' ', array_filter($this->owner->getFontIconClassNames())));
    }

    /**
     * Answers an array of font icon class names for the extended object.
     *
     * @return array
     */
    public function getFontIconClassNames()
    {
        $classes = [];

        if ($this->owner->FontIcon) {

            if ($this->owner->FontIconListItem) {
                $classes[] = $this->backend->getClassName('list-item');
            }

            if ($this->owner->FontIconFixedWidth) {
                $classes[] = $this->backend->getClassName('fixed-width');
            }

            $classes[] = $this->backend->getClassName('icon', [$this->owner->FontIcon]);

        }

        return $classes;
    }

    /**
     * Answers true to enable list item mode.
     *
     * @return boolean
     */
    public function getFontIconListItem()
    {
        return false;
    }

    /**
     * Answers true to enable fixed width mode.
     *
     * @return boolean
     */
    public function getFontIconFixedWidth()
    {
        return false;
    }

    /**
     * Answers true if the extended object has a font icon defined.
     *
     * @return boolean
     */
    public function hasFontIcon()
    {
        return (boolean) $this->owner->FontIcon;
    }

    /**
     * Renders the font icon tag for the HTML template.
     *
     * @return DBHTMLText|string
     */
    public function getFontIconTag()
    {
        if ($this->owner->hasFontIcon()) {

            return $this->backend->getTag(
                $this->owner->FontIconClass,
                $this->owner->FontIconColor
            );

        }
    }

    /**
     * Renders the font icon tag for the CMS interface.
     *
     * @return string
     */
    public function getFontIconTagCMS()
    {
        return DBField::create_field('HTMLFragment', $this->getFontIconTag());
    }
}


<?php

namespace Rougin\Slytherin\Container;

use Psr\Container\ContainerInterface as PsrContainerInterface;

/**
 * Reflection Container
 *
 * A simple container utilizing PHP's Reflection classes.
 *
 * @package Slytherin
 * @author  Rougin Gutib <rougingutib@gmail.com>
 */
class ReflectionContainer implements PsrContainerInterface
{
    /**
     * @link https://petersuhm.com/recursively-resolving-dependencies-with-phps-reflection-api-part-1
     *
     * Finds an entry of the container by its identifier and returns it.
     *
     * @throws \Psr\Container\NotFoundExceptionInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     *
     * @param  string $id
     * @return mixed
     */
    public function get($id)
    {
        if ($this->has($id) === false) {
            $message = sprintf('Class (%s) does not exists', $id);

            throw new Exception\NotFoundException($message);
        }

        $reflection = new \ReflectionClass($id);

        if ($constructor = $reflection->getConstructor()) {
            $arguments = $this->arguments($constructor);

            return $reflection->newInstanceArgs($arguments);
        }

        return new $id;
    }

    /**
     * Returns true if the container can return an entry for the given identifier.
     *
     * @param  string $id
     * @return boolean
     */
    public function has($id)
    {
        return class_exists($id);
    }

    /**
     * Returns an argument based on the given parameter.
     *
     * @param  \ReflectionParameter $parameter
     * @param  string               $name
     * @return mixed|null
     */
    protected function argument(\ReflectionParameter $parameter, $name)
    {
        try {
            $argument = $parameter->getDefaultValue();
        } catch (\ReflectionException $exception) {
            $argument = $this->get($name);
        }

        return $argument;
    }

    /**
     * Resolves the specified parameters from a container.
     *
     * @param  \ReflectionFunction|\ReflectionMethod $reflector
     * @param  array                                 $parameters
     * @return array
     */
    protected function arguments($reflector, $parameters = array())
    {
        $arguments = array();

        foreach ($reflector->getParameters() as $key => $parameter) {
            $class = $parameter->getClass();

            $name = $class ? $class->getName() : $parameter->getName();

            $argument = $this->argument($parameter, $name);

            $exists = array_key_exists($name, $parameters);

            $arguments[$key] = $exists ? $parameters[$name] : $argument;
        }

        return $arguments;
    }
}


<?php
/**
 * prooph (http://getprooph.org/)
 *
 * @see       https://github.com/proophsoftware/prooph-interop-bundle for the canonical source repository
 * @copyright Copyright (c) 2016 prooph software GmbH (http://prooph-software.com/)
 * @license   https://github.com/proophsoftware/prooph-interop-bundle/blob/master/LICENSE.md New BSD License
 */
namespace Prooph\InteropBundle\DependencyInjection;

use Prooph\InteropBundle\Config\Definition\Builder\DynamicArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\NodeBuilder;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

/**
 * Configures only the prooph main node
 *
 * The prooph factories validates the given configuration
 */
class Configuration implements ConfigurationInterface
{
    /**
     * {@inheritdoc}
     */
    public function getConfigTreeBuilder()
    {
        $nodeBuilder = new NodeBuilder();
        $nodeBuilder->setNodeClass('dynamicArray', DynamicArrayNodeDefinition::class);
        $treeBuilder = new TreeBuilder();

        $rootNode = $treeBuilder->root('prooph', 'dynamicArray', $nodeBuilder);

        // our factories handles validation and we are flexible with keys
        // Please take a look at the docs or specific prooph component factory for the configuration options
        $rootNode->ignoreExtraKeys(false);

        return $treeBuilder;
    }
}


<?php

namespace Rougin\Slytherin\Routing;

use Phroute\Phroute\RouteCollector;

/**
 * Phroute Router
 *
 * A simple implementation of router that is built on top of Phroute.
 *
 * https://github.com/mrjgreen/phroute
 *
 * @package Slytherin
 * @author  Rougin Gutib <rougingutib@gmail.com>
 */
class PhrouteRouter extends Router
{
    /**
     * @var \Phroute\Phroute\RouteCollector
     */
    protected $collector;

    /**
     * @var array
     */
    protected $routes = array();

    /**
     * Initializes the router instance.
     *
     * @param array $routes
     */
    public function __construct(array $routes = array())
    {
        $this->collector = new RouteCollector;

        foreach ($routes as $route) {
            $middlewares = (isset($route[3])) ? $route[3] : array();

            $this->add($route[0], $route[1], $route[2], $middlewares);
        }
    }

    /**
     * Adds a new raw route.
     *
     * @param  string|string[] $httpMethod
     * @param  string          $route
     * @param  array|string    $handler
     * @param  array           $middlewares
     * @return self
     */
    public function add($httpMethod, $route, $handler, $middlewares = array())
    {
        $route = $this->parse(array($httpMethod, $route, $handler, $middlewares));

        $this->collector->addRoute($httpMethod, $route[1], $route[2]);

        $this->routes[] = $route;

        return $this;
    }

    /**
     * Returns a listing of available routes.
     *
     * @return \Phroute\Phroute\RouteDataArray
     */
    public function routes()
    {
        return $this->collector->getData();
    }

    /**
     * Sets the collector of routes.
     *
     * @param \Phroute\Phroute\RouteCollector $collector
     */
    public function setCollector(RouteCollector $collector)
    {
        $this->collector = $collector;

        return $this;
    }
}


<?php

namespace Rougin\Slytherin\Middleware;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Rougin\Slytherin\Http\Response;
use Rougin\Slytherin\Middleware\HandlerInterface;
use Zend\Stratigility\MiddlewarePipe;

/**
 * Stratigility Dispatcher
 *
 * A simple implementation of middleware dispatcher that is built on top of Zend's Stratigility.
 *
 * @package Slytherin
 * @author  Rougin Gutib <rougingutib@gmail.com>
 * @link    https://github.com/zendframework/zend-stratigility
 */
class StratigilityDispatcher extends Dispatcher
{
    /**
     * @var \Zend\Stratigility\MiddlewarePipe
     */
    protected $pipeline;

    /**
     * @var \Psr\Http\Message\ResponseInterface
     */
    protected $response;

    /**
     * @var array
     */
    protected $stack = array();

    /**
     * Initializes the dispatcher instance.
     *
     * @param \Zend\Stratigility\MiddlewarePipe        $pipeline
     * @param array                                    $stack
     * @param \Psr\Http\Message\ResponseInterface|null $response
     */
    public function __construct(MiddlewarePipe $pipeline, array $stack = array(), ResponseInterface $response = null)
    {
        $this->pipeline = $pipeline;

        $this->response = $response ?: new Response;

        $this->stack = $stack;
    }

    /**
     * Processes an incoming server request and return a response.
     *
     * @param  \Psr\Http\Message\ServerRequestInterface      $request
     * @param  \Rougin\Slytherin\Middleware\HandlerInterface $handler
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function process(ServerRequestInterface $request, HandlerInterface $handler)
    {
        $wrap = class_exists('Zend\Stratigility\Middleware\ErrorHandler');

        foreach ($this->stack as $middleware) {
            $middleware = is_string($middleware) ? new $middleware : $middleware;

            $this->pipeline->pipe($this->transform($middleware, $wrap));
        }

        return $this->pipeline->__invoke($request, $this->response, $handler);
    }
}


<?php

namespace Rougin\Slytherin\Debug;

use Rougin\Slytherin\Application;
use Rougin\Slytherin\Container\ContainerInterface;
use Rougin\Slytherin\Integration\Configuration;
use Rougin\Slytherin\Integration\IntegrationInterface;

/**
 * Error Handler Integration
 *
 * An integration for defined error handlers to be included in Slytherin.
 * NOTE: To be removed in v1.0.0. Move to "Integration" directory instead.
 *
 * @package Slytherin
 * @author  Rougin Gutib <rougingutib@gmail.com>
 */
class ErrorHandlerIntegration implements IntegrationInterface
{
    /**
     * Defines the specified integration.
     *
     * @param  \Rougin\Slytherin\Container\ContainerInterface $container
     * @param  \Rougin\Slytherin\Integration\Configuration    $config
     * @return \Rougin\Slytherin\Container\ContainerInterface
     */
    public function define(ContainerInterface $container, Configuration $config)
    {
        $environment = $config->get('app.environment', 'development');

        $handler = new ErrorHandler($environment);

        if (interface_exists('Whoops\RunInterface') === true) {
            $whoops = new \Whoops\Run;

            $handler = new WhoopsErrorHandler($whoops, $environment);
        }

        if ($environment === 'development') {
            error_reporting(E_ALL) && ini_set('display_errors', 1);

            // NOTE: To be removed in v1.0.0. Use $handler->display() instead.
            $container->set(Application::ERROR_HANDLER, $handler);
        }

        return $container;
    }
}


<?php

namespace Rougin\Slytherin\Routing;

use FastRoute\RouteCollector;

/**
 * FastRoute Router
 *
 * A simple implementation of router that is built on top of FastRoute.
 *
 * https://github.com/nikic/FastRoute
 *
 * @package Slytherin
 * @author  Rougin Gutib <rougingutib@gmail.com>
 */
class FastRouteRouter extends Router
{
    /**
     * @var \FastRoute\RouteCollector
     */
    protected $collector;

    /**
     * Initializes the router instance.
     *
     * @param array
     */
    public function __construct(array $routes = array())
    {
        parent::__construct($routes);

        $count = new \FastRoute\DataGenerator\GroupCountBased;

        $std = new \FastRoute\RouteParser\Std;

        $this->collector = new RouteCollector($std, $count);
    }

    /**
     * Sets the collector of routes.
     *
     * @param \FastRoute\RouteCollector $collector
     */
    public function setCollector(RouteCollector $collector)
    {
        $this->collector = $collector;

        return $this;
    }

    /**
     * Returns a listing of routes available.
     *
     * @return callable
     */
    public function routes()
    {
        $routes = array_merge($this->routes, $this->collector->getData());

        return function (RouteCollector $collector) use ($routes) {
            foreach (array_filter($routes) as $route) {
                list($method, $uri, $handler) = (array) $route;

                $collector->addRoute($method, $uri, $handler);
            }
        };
    }
}


<?php

namespace Quazardous\Assetic;

use Assetic\Factory\LazyAssetManager;
use Assetic\AssetWriter;
use Assetic\AssetManager;
use SilexAssetic\Assetic\Dumper as BaseDumper;
use Assetic\Util\VarUtils;
use Symfony\Component\Console\Output\OutputInterface;

class WatchingDumper extends BaseDumper
{

    protected $watching = false;
    /**
     * @var \Symfony\Component\Console\Output\OutputInterface
     */
    protected $commandOutput = null;

    /**
     * Start watch mode for command assetic:watch.
     * @param OutputInterface $output
     */
    public function watch(OutputInterface $output = null) {
        $this->watching = true;
        $this->commandOutput = $output;
    }

    protected $pathToWeb = null;
    public function __construct(AssetManager $am, LazyAssetManager $lam, AssetWriter $writer, $pathToWeb)
    {
        parent::__construct($am, $lam, $writer);
        $this->pathToWeb = $pathToWeb;
    }

    protected function dumpManagerAssets(AssetManager $am)
    {
        foreach ($am->getNames() as $name) {
            $asset = $am->get($name);

            if ($am instanceof LazyAssetManager) {
                $formula = $am->getFormula($name);
            }

            $dump = true;
            if ($this->watching) {
                // watching mode
                $dump = false;
                $resolved = VarUtils::resolve(
                    $asset->getTargetPath(),
                    $asset->getVars(),
                    $asset->getValues()
                    );
                $dest = $this->pathToWeb . '/' . $resolved;
                if (file_exists($dest)) {
                    $destmtime = filemtime($dest);
                } else {
                    $destmtime = 0;
                }
                // compare source and destination mtime
                if ($asset->getLastModified() > $destmtime) {
                    if ($this->commandOutput) {
                        $this->commandOutput->writeln("Dumping $dest");
                    }
                    $dump = true;
                }
            }
            if ($dump) {
                $this->writer->writeAsset($asset);

                if (!isset($formula[2])) {
                    continue;
                }

                $debug   = isset($formula[2]['debug'])   ? $formula[2]['debug']   : $am->isDebug();
                $combine = isset($formula[2]['combine']) ? $formula[2]['combine'] : null;

                if (null !== $combine ? !$combine : $debug) {
                    foreach ($asset as $leaf) {

                        $this->writer->writeAsset($leaf);
                    }
                }
            }
        }
    }
}


<?php

namespace Rougin\Slytherin\Routing;

use Rougin\Slytherin\Container\ContainerInterface;
use Rougin\Slytherin\Integration\Configuration;
use Rougin\Slytherin\Integration\IntegrationInterface;

/**
 * Routing Integration
 *
 * An integration for Slytherin's Routing packages.
 *
 * @package Slytherin
 * @author  Rougin Gutib <rougingutib@gmail.com>
 */
class RoutingIntegration implements IntegrationInterface
{
    /**
     * Defines the specified integration.
     *
     * @param  \Rougin\Slytherin\Container\ContainerInterface $container
     * @param  \Rougin\Slytherin\Integration\Configuration    $config
     * @return \Rougin\Slytherin\Container\ContainerInterface
     */
    public function define(ContainerInterface $container, Configuration $config)
    {
        $dispatcher = new Dispatcher;

        $router = $config->get('app.router', new Router);

        if (interface_exists('FastRoute\Dispatcher')) {
            $dispatcher = new FastRouteDispatcher;
        }

        if (class_exists('Phroute\Phroute\Dispatcher')) {
            $resolver = new PhrouteResolver($container);

            $dispatcher = new PhrouteDispatcher(null, $resolver);
        }

        $container->set('Rougin\Slytherin\Routing\DispatcherInterface', $dispatcher);

        $container->set('Rougin\Slytherin\Routing\RouterInterface', $router);

        return $container;
    }
}


<?php
/*
 * Copyright (c) 2014 Michel Petit <petit.michel@gmail.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.
 */

namespace Malenki\Math;
use \Malenki\Math\Number\Complex;

/**
 * Random generator of Complex Number.
 *
 * This class allows you to get one or many complex numbers with real and
 * imaginary or rho and theta inside given range.
 *
 * So, to get one complex number with its real part into `[2, 6.5]` range and
 * its imaginary part into `[-2, 5]` range, you must do that:
 *
 *     $rc = new RandomComplex();
 *     $rc->r(2, 6.5)->i(-2, 5)->get();
 *
 * You can do that with trigonometric form too, but now with 10 generated
 * items:
 *
 *     $rc = new RandomComplex();
 *     $rc->rho(1, 5)->theta(M_PI / 4, M_PI /2)->getMany(10);
 *
 * Beware: you cannot start with algebraic form and finish with trigonometric.
 * You must reset or instanciate other object.
 *
 * @property-read $rho Rho min/max object if defined
 * @property-read $theta Theta min/max object if defined
 * @property-read $r Real part min/max object if defined
 * @property-read $i Imaginary part min/max if defined
 * @author Michel Petit <petit.michel@gmail.com>
 * @license MIT
 */
class RandomComplex
{
    /**
     * Rho min/max object if defined, null otherwise
     *
     * @var mixed
     * @access protected
     */
    protected $rho = null;

    /**
     * theta angle min/max object if defined, null otherwise
     *
     * @var mixed
     * @access protected
     */
    protected $theta = null;

    /**
     * Real part min/max object if defined, null otherwise
     *
     * @var mixed
     * @access protected
     */
    protected $r = null;

    /**
     * Imaginary part min/max object if defined, null otherwise
     *
     * @var mixed
     * @access protected
     */
    protected $i = null;

    /**
     * Gets a random float numbers inside the given range.
     *
     * @param  float $float_min Minimal float value allowed
     * @param  mixed $float_max Maximal float value allowed
     * @static
     * @access protected
     * @return float
     */
    protected static function random($float_min, $float_max)
    {

        if ($float_max >= 0) {
            $r = new Random();

            while (true) {
                $float_prov = $float_max * $r->get();

                if ($float_prov >= $float_min) {
                    return $float_prov;
                }
            }
        } else {
            $r = new Random();

            while (true) {
                $float_prov = $float_min * $r->get();

                if ($float_prov <= $float_max) {
                    return $float_prov;
                }
            }
        }
    }

    /**
     * Check helper for some method to tests their arguments.
     *
     * If given argument are not numeric or first is greater than the second,
     * then Exception is risen.
     *
     * @throw \InvalidArgumentException If min and max values are not numbers.
     * @throw \InvalidArgumentException If min value is greater than max.
     * @param  float $float_min
     * @param  float $float_max
     * @static
     * @access protected
     * @return void
     */
    protected static function checkOrder($float_min, $float_max)
    {
        if (!is_numeric($float_min) && !is_numeric($float_max)) {
            throw new \InvalidArgumentException('Min and max values must be valid numbers.');
        }

        if ($float_min >= $float_max) {
            throw new \InvalidArgumentException('Max value must be greater than min value!');
        }
    }

    /**
     * Defines some magic getters for ranges rho, theta, real part and imaginary part.
     *
     * @param  string   $name
     * @access public
     * @return stdClass
     */
    public function __get($name)
    {
        if (in_array($name, array('rho', 'theta', 'r', 'i'))) {
            return $this->$name;
        }
    }

    /**
     * Sets min and max value for random rho
     *
     * @throw \InvalidArgumentException If rho is not positive number.
     * @throw \RuntimeException If this is called into algebraic context.
     * @param  float         $float_min
     * @param  float         $float_max
     * @access public
     * @return RandomComplex
     */
    public function rho($float_min, $float_max)
    {
        self::checkOrder($float_min, $float_max);

        if ($float_min < 0 || $float_max < 0) {
            throw new \InvalidArgumentException('Rho value must be a positive number!');
        }

        if ($this->r || $this->i) {
            throw new \RuntimeException('You cannot set rho value, because algebraic form is in use.');
        }

        $this->rho = new \stdClass();
        $this->rho->min = $float_min;
        $this->rho->max = $float_max;

        return $this;
    }

    /**
     * Sets min and max value for random theta angle
     *
     * @throw \RuntimeException If this is called into algebraic context.
     * @param  float         $float_min
     * @param  float         $float_max
     * @access public
     * @return RandomComplex
     */
    public function theta($float_min, $float_max)
    {
        self::checkOrder($float_min, $float_max);

        if ($this->r || $this->i) {
            throw new \RuntimeException('You cannot set theta value, because algebraic form is in use.');
        }

        $this->theta = new \stdClass();
        $this->theta->min = $float_min;
        $this->theta->max = $float_max;

        return $this;
    }

    /**
     * Sets min and max value for random real part
     *
     * @throw \RuntimeException If this is called into trigonometric context.
     * @param  float         $float_min
     * @param  float         $float_max
     * @access public
     * @return RandomComplex
     */
    public function r($float_min, $float_max)
    {
        self::checkOrder($float_min, $float_max);

        if ($this->rho || $this->theta) {
            throw new \RuntimeException('You cannot set real part because trigonometric form is in use.');
        }

        $this->r = new \stdClass();
        $this->r->min = $float_min;
        $this->r->max = $float_max;

        return $this;
    }

    /**
     * Sets min and max value for random imaginary part.
     *
     * @throw \RuntimeException If this is called into trigonometric context.
     * @param  float         $float_min
     * @param  float         $float_max
     * @access public
     * @return RandomComplex
     */
    public function i($float_min, $float_max)
    {
        self::checkOrder($float_min, $float_max);

        if ($this->rho || $this->theta) {
            throw new \RuntimeException('You cannot set imaginary part because trigonometric form is in use.');
        }

        $this->i = new \stdClass();
        $this->i->min = $float_min;
        $this->i->max = $float_max;

        return $this;
    }

    /**
     * Gets one complex number randomly
     *
     * @access public
     * @return Complex
     */
    public function get()
    {
        if ($this->r || $this->i) {
            if (!is_object($this->i)) {
                return new Complex(
                    self::random($this->r->min, $this->r->max),
                    0
                );
            }

            if (!is_object($this->r)) {
                return new Complex(
                    0,
                    self::random($this->i->min, $this->i->max)
                );
            }

            return new Complex(
                self::random($this->r->min, $this->r->max),
                self::random($this->i->min, $this->i->max)
            );
        }

        if ($this->rho || $this->theta) {
            if (!is_object($this->theta)) {
                return new Complex(
                    self::random($this->rho->min, $this->rho->max),
                    0,
                    Complex::TRIGONOMETRIC
                );
            }

            if (!is_object($this->rho)) {
                return new Complex(
                    0,
                    self::random($this->theta->min, $this->theta->max),
                    Complex::TRIGONOMETRIC
                );
            }

            return new Complex(
                self::random($this->rho->min, $this->rho->max),
                self::random($this->theta->min, $this->theta->max),
                Complex::TRIGONOMETRIC
            );
        }
    }

    /**
     * Get many Complex numbers.
     *
     * @throw \InvalidArgumentException If given amount is less than 2
     * @param  integer $n Amount of complex numbers to get. Must be greater than 2
     * @access public
     * @return array
     */
    public function getMany($n)
    {
        if (!is_integer($n) || $n < 2) {
            throw new \InvalidArgumentException('You must take 2 or more items in this case.');
        }

        $arr_out = array();

        for ($i = 0; $i < $n; $i++) {
            $arr_out[] = $this->get();
        }

        return $arr_out;
    }

    /**
     * Resets current generator to be able to used other range into other context.
     *
     * @access public
     * @return RandomComplex
     */
    public function reset()
    {
        $this->rho = null;
        $this->theta = null;
        $this->r = null;
        $this->i = null;

        return $this;
    }
}


<?php
namespace Quazardous\Assetic\Factory;

use Assetic\Factory\AssetFactory;

/**
 *
 * @author david
 *
 */
class NamespaceAwareAssetFactory extends AssetFactory
{
    protected $namespaces = [];

    /**
     * Add a namespace with its path.
     * @param string $ns
     * @param string $path
     */
    public function addNamespace($ns, $path) {
        $this->namespaces[$ns] = $path;
    }

    /**
     * Will detect inputs that begin with @MyNamespace/... and replace the namespace with the corresponding path.
     *
     * @see \Assetic\Factory\AssetFactory::parseInput()
     */
    protected function parseInput($input, array $options = array())
    {
        $matches = null;
        // search for @MyNamespace/path/to/asset
        if (preg_match("|^\@([a-z_][_a-z0-9]*)/|i", $input, $matches)) {
            $ns = $matches[1];
            if (!array_key_exists($ns, $this->namespaces)) {
                throw new \RuntimeException("$ns : unknown namespace !");
            }
            $input = $this->namespaces[$ns] . substr($input, strlen($ns) + 1);
        }
        return parent::parseInput($input, $options);
    }

}


<?php

namespace Rougin\Slytherin\Container;

use Psr\Container\ContainerInterface as PsrContainerInterface;
use Psr\Http\Message\ServerRequestInterface;

/**
 * Container
 *
 * A simple container that is implemented on \Psr\Container\ContainerInterface.
 *
 * @package Slytherin
 * @author  Rougin Gutib <rougingutib@gmail.com>
 */
class Container implements ContainerInterface
{
    /**
     * @var \Psr\Container\ContainerInterface
     */
    protected $extra;

    /**
     * NOTE: To be removed in v1.0.0. Use "protected" visibility instead.
     *
     * @var array
     */
    public $instances = array();

    /**
     * Initializes the container instance.
     *
     * @param array                                  $instances
     * @param \Psr\Container\ContainerInterface|null $container
     */
    public function __construct(array $instances = array(), PsrContainerInterface $container = null)
    {
        $this->instances = $instances;

        $this->extra = $container ?: new ReflectionContainer;
    }

    /**
     * Adds a new instance to the container.
     * NOTE: To be removed in v1.0.0. Use $this->set() instead.
     *
     * @param  string     $id
     * @param  mixed|null $concrete
     * @return self
     */
    public function add($id, $concrete = null)
    {
        return $this->set($id, $concrete);
    }

    /**
     * Creates an alias for a specified class.
     *
     * @param string $id
     * @param string $original
     */
    public function alias($id, $original)
    {
        $this->instances[$id] = $this->get($original);

        return $this;
    }

    /**
     * Resolves the specified parameters from a container.
     *
     * @param  \ReflectionFunctionAbstract $reflector
     * @param  array                       $parameters
     * @return array
     */
    public function arguments(\ReflectionFunctionAbstract $reflector, $parameters = array())
    {
        $arguments = array();

        foreach ($reflector->getParameters() as $key => $parameter) {
            $argument = $this->argument($parameter);

            $name = $parameter->getName();

            $arguments[$key] = $argument ?: $parameters[$name];
        }

        return $arguments;
    }

    /**
     * Finds an entry of the container by its identifier and returns it.
     *
     * @throws \Psr\Container\NotFoundExceptionInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     *
     * @param  string $id
     * @return mixed
     */
    public function get($id)
    {
        if ($this->has($id) === true) {
            $entry = isset($this->instances[$id]) ? $this->instances[$id] : $this->resolve($id);

            if (is_object($entry) === false) {
                $message = (string) 'Alias (%s) is not an object';

                $message = sprintf($message, $id);

                throw new Exception\ContainerException($message);
            }

            return $entry;
        }

        $message = 'Alias (%s) is not being managed by the container';

        throw new Exception\NotFoundException(sprintf($message, $id));
    }

    /**
     * Returns true if the container can return an entry for the given identifier.
     *
     * @param  string $id
     * @return boolean
     */
    public function has($id)
    {
        return isset($this->instances[$id]) || $this->extra->has($id);
    }

    /**
     * Resolves the specified identifier to an instance.
     *
     * @throws \Psr\Container\NotFoundExceptionInterface
     *
     * @param  string                                        $id
     * @param  \Psr\Http\Message\ServerRequestInterface|null $request
     * @return mixed
     */
    public function resolve($id, ServerRequestInterface $request = null)
    {
        $reflection = new \ReflectionClass($id);

        if ($constructor = $reflection->getConstructor()) {
            $arguments = array();

            foreach ($constructor->getParameters() as $parameter) {
                $argument = $this->argument($parameter);

                $arguments[] = $this->request($argument, $request);
            }

            return $reflection->newInstanceArgs($arguments);
        }

        return $this->extra->get($id);
    }

    /**
     * Sets a new instance to the container.
     *
     * @param  string $id
     * @param  mixed  $concrete
     * @return self
     */
    public function set($id, $concrete)
    {
        $this->instances[$id] = $concrete;

        return $this;
    }

    /**
     * Returns an argument based on the given parameter.
     *
     * @param  \ReflectionParameter $parameter
     * @return mixed|null
     */
    protected function argument(\ReflectionParameter $parameter)
    {
        try {
            $argument = $parameter->getDefaultValue();
        } catch (\ReflectionException $exception) {
            $class = $parameter->getClass();

            $exists = $parameter->getClass() !== null;

            $name = $exists ? $class->getName() : $parameter->getName();

            $argument = $this->value($name);
        }

        return $argument;
    }

    /**
     * Returns the manipulated ServerRequest (from middleware) to an argument.
     *
     * @param  mixed                                         $argument
     * @param  \Psr\Http\Message\ServerRequestInterface|null $request
     * @return mixed
     */
    protected function request($argument, ServerRequestInterface $request = null)
    {
        $instanceof = $argument instanceof ServerRequestInterface;

        $instanceof === true && $argument = $request ?: $argument;

        return $argument;
    }

    /**
     * Returns the value of the specified argument.
     *
     * @param  string $name
     * @return mixed|null
     */
    protected function value($name)
    {
        $object = isset($this->instances[$name]) ? $this->get($name) : null;

        $exists = ! $object && $this->extra->has($name) === true;

        return $exists === true ? $this->extra->get($name) : $object;
    }
}


<?php
/*
 * Copyright (c) 2014 Michel Petit <petit.michel@gmail.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.
 */

namespace Malenki\Math;

/**
 * Random generator for floats or integers.
 *
 * If no arguments given, generates float values into the `[0.0, 1.0]` range. If
 * the two arguments are integers, then generator will return value into the
 * range created by the this two integers.
 *
 * It can get one or many random numbers, with or without replacement.
 *
 * Into string context, returns one random number.
 *
 * @author Michel Petit <petit.michel@gmail.com>
 * @license MIT
 */
class Random
{
    /**
     * Store the range as an object, with, min, maw and attribute to test if it
     * is float or integers.
     *
     * @var mixed
     * @access protected
     */
    protected $range = null;

    /**
     * Create one random nuber generator.
     *
     * If no argument provided, then will generate only float values between 0 and 1.
     *
     * If to integers are provided, then they will define the range where to
     * take random number(s).
     *
     * @param  integer $int_min
     * @param  integer $int_max
     * @access public
     * @return void
     */
    public function __construct($int_min = null, $int_max = null)
    {
        $this->range = new \stdClass();

        if (is_integer($int_min) && is_integer($int_max) && $int_min < $int_max) {
            if ($int_max > mt_getrandmax()) {
                throw new \OutOfRangeException(sprintf('On this system, you cannot exceed %d integer value.', mt_getrandmax()));
            }
            $this->range->as_integer = true;
            $this->range->min = $int_min;
            $this->range->max = $int_max;
        } elseif (is_null($int_min) && is_null($int_max)) {
            $this->range->as_integer = false;
            $this->range->min = 0;
            $this->range->max = 1;
        } else {
            throw new \InvalidArgumentException('Random range must be integers');
        }
    }

    /**
     * Gets at each call a random number into the defined range.
     *
     * Random float between 0 and 1 or integers inside the range defined at
     * instanciation time is returned.
     *
     * @access public
     * @return mixed Integer or float.
     */
    public function get()
    {
        if ($this->range->as_integer) {
            return mt_rand($this->range->min, $this->range->max);
        } else {
            return mt_rand(0, mt_getrandmax()) / mt_getrandmax();
        }
    }

    /**
     * Gets many random value.
     *
     * Gets many random values, with the same behaviour as `get()` method.
     *
     * @param  integer $n Number of items to get. Must be greater than 1
     * @throw \InvalidArgumentException If argument is not integer or is less than 2
     * @access public
     * @return array
     */
    public function getMany($n)
    {
        if (!is_integer($n) || $n < 2) {
            throw new \InvalidArgumentException('You must take 2 or more items in this case.');
        }

        $arr_out = array();

        for ($i = 0; $i < $n; $i++) {
            $arr_out[] = $this->get();
        }

        return $arr_out;
    }

    /**
     * Gets many random items without replacement.
     *
     * @param  integer $n Number of items to get. Must be greater than 1
     * @throw \InvalidArgumentException If argument is not integer or is less than 2
     * @throw \OutOfRangeException If argument is bigger than ammount of
     *                    integers into the range (integer range context only)
     * @access public
     * @return array
     */
    public function getManyWithoutReplacement($n)
    {
        if (!is_integer($n) || $n < 2) {
            throw new \InvalidArgumentException('You must take 2 or more items in this case.');
        }

        if ($this->range->as_integer) {
            $arr_range = range($this->range->min, $this->range->max);
            $max_takable = count($arr_range);

            shuffle($arr_range);

            if ($n > $max_takable) {
                throw new \OutOfRangeException(
                    sprintf(
                        'Cannot take without replacement more than available items into range [%d;%d]',
                        $this->range->min,
                        $this->range->max
                    )
                );
            } elseif ($n == $max_takable) {
                return array_values($arr_range);
            } else {
                return array_slice($arr_range, 0, $n);
            }
        } else {
            $arr_out = array();

            while (count($arr_out) < $n) {
                $r = $this->get();

                if (!in_array($r, $arr_out)) {
                    $arr_out[] = $r;
                }
            }

            return $arr_out;
        }

    }

    /**
     * Into string context, returns one random number.
     *
     *
     * @access public
     * @return string
     */
    public function __toString()
    {
        return (string) $this->get();
    }
}


<?php
namespace Quazardous\Silex\Pack;

use Pimple\Container;
use Silex\Application;

/**
 *
 * Add some basic function to implement needed pack interface.
 *
 */
trait JetPackTrait
{
    /**
     * You can define the pack suffix. It's 'Pack' by default.
     * @const static::PACK_SUFFIX
     */
    //const PACK_SUFFIX = 'Pack';

    protected $packOptions = [
        'twig_templates_subpath' => 'views',
        'entity_subnamespace' => 'Entity',
        'entity_use_simple_annotation' => true,
        'target_entities_mapping' => [],
        'configs_subpath' => 'configs',
        'public_subpath' => 'public',
        'assets_subpath' => 'assets',
        'translations_subpath' => 'locale',
        'mount_prefix' => '/',
        'mount_host' => null,
    ];

    /**
     * Set the pack's options from the app container.
     * @see \Quazardous\Silex\Api\OptionnablePackInterface::setPackOptions()
     * @param Container $app
     */
    public function setPackOptions(Container $app) {
        foreach ($this->packOptions as $key => &$value) {
            $key = $this->_ns($key);
            if (isset($app[$key])) {
                $value = $app[$key];
            }
        }
    }

    /**
     * Return the name of the pack. It's the short class name without the 'Pack' suffix.
     * @see \Quazardous\Silex\Api\PackInterface::getName()
     * @return string
     */
    public function getName()
    {
        static $names = [];
        $me = get_class($this);
        if (empty($names[$me])) {
            $names[$me] = $this->getReflector()->getShortName();
            $suffix = defined('static::PACK_SUFFIX') ? static::PACK_SUFFIX : 'Pack';
            if (strrpos($names[$me], $suffix) == (strlen($names[$me]) - strlen($suffix))) {
                $names[$me] = substr($names[$me], 0, strlen($names[$me]) - strlen($suffix));
            }
        }
        return $names[$me];
    }

    /**
     * Return the path for the Twig templates. By default, it's a 'views' folder in the pack class namespace path.
     * @see \Quazardous\Silex\Api\TwiggablePackInterface::getTwigTemplatesPath()
     * @return string
     */
    public function getTwigTemplatesPath(Container $app)
    {
        static $paths = [];
        $me = get_class($this);
        if (empty($paths[$me])) {
            $subpath = $this->packOptions['twig_templates_subpath'];
            $paths[$me] = dirname($this->getReflector()->getFileName()) . '/' . $subpath;
        }
        return $paths[$me];
    }

    /**
     * Return a default mapping for the pack's entities.
     * @see \Quazardous\Silex\Api\EntitablePackInterface::getEntityMappings()
     * @return array
     */
    public function getEntityMappings(Container $app)
    {
        static $mappings = [];
        $me = get_class($this);
        if (empty($mappings[$me])) {
            $subns = $this->packOptions['entity_subnamespace'];
            $subns = trim($subns, '\\');
            $simple = $this->packOptions['entity_use_simple_annotation'];
            $ns = $this->getReflector()->getNamespaceName() . '\\' . $subns;
            $subpath = str_replace('\\', '/', $subns);
            $path = dirname($this->getReflector()->getFileName()) . '/' . $subpath;
            if (is_dir($path)) {
                $mappings[$me] = [
                    'type' => 'annotation',
                    'namespace' => $ns,
                    'path' => $path,
                    'use_simple_annotation_reader' => $simple,
                ];
            }
        }
        if (empty($mappings[$me])) {
            return [];
        }
        return [$mappings[$me]];
    }

    /**
     * Return a default interface to entity class mapping for the pack's entities.
     * @see \Quazardous\Silex\Api\EntitablePackInterface::getTargetEntitiesMapping()
     * @return array
     */
    public function getTargetEntitiesMapping(Container $app)
    {
        return (array)$this->packOptions['target_entities_mapping'];
    }

    /**
     * The path of the configs.
     * @see \Quazardous\Silex\Api\ConfigurablePackInterface::getConfigsPath()
     * @return string
     */
    public function getConfigsPath(Container $app)
    {
        static $paths = [];
        $me = get_class($this);
        if (empty($paths[$me])) {
            $subpath = $this->packOptions['configs_subpath'];
            $paths[$me] = dirname($this->getReflector()->getFileName()) . '/' . $subpath;
        }
        return $paths[$me];
    }

    /**
     * The path of the assets.
     * @see \Quazardous\Silex\Api\AssetablePackInterface::getAssetsPath()
     * @return string
     */
    public function getAssetsPath(Container $app)
    {
        static $paths = [];
        $me = get_class($this);
        if (empty($paths[$me])) {
            $subpath = $this->packOptions['assets_subpath'];
            $paths[$me] = dirname($this->getReflector()->getFileName()) . '/' . $subpath;
        }
        return $paths[$me];
    }

    /**
     * No assetic formulae by default.
     * @see \Quazardous\Silex\Api\AssetablePackInterface::getAsseticFormulae()
     * @return array
     */
    public function getAsseticFormulae(Container $app)
    {
        return [];
    }

    /**
     * The path of the translations.
     * @see \Quazardous\Silex\Api\TranslatablePackInterface::getTranslationsPath()
     * @return string
     */
    public function getTranslationsPath(Container $app)
    {
        static $paths = [];
        $me = get_class($this);
        if (empty($paths[$me])) {
            $subpath = $this->packOptions['translations_subpath'];
            $paths[$me] = dirname($this->getReflector()->getFileName()) . '/' . $subpath;
        }
        return $paths[$me];
    }

    /**
     * By default mount the pack on '/'.
     * @see \Quazardous\Silex\Api\MountablePackInterface::getMountPrefix()
     * @return string
     */
    public function getMountPrefix(Container $app) {
        return $this->packOptions['mount_prefix'];
    }

    /**
     * No specific host by default.
     * @see \Quazardous\Silex\Api\MountablePackInterface::getMountHost()
     * @return string
     */
    public function getMountHost(Container $app) {
        return $this->packOptions['mount_host'];;
    }

    /**
     * No controllers by default.
     * @see Silex\Api\ControllerProviderInterface::connect()
     * @return ControllerCollection A ControllerCollection instance
     */
    public function connect(Application $app)
    {
        return $app['controllers_factory'];
    }

    /**
     * No Twig extension by default.
     * @see \Quazardous\Silex\Api\TwiggablePackInterface::getTwigExtensions()
     * @return (\Twig_SimpleFilter|\Twig_SimpleFunction)[]
     */
    public function getTwigExtensions(Container $app)
    {
        return [];
    }

    /**
     * No commands by default.
     * @see \Quazardous\Silex\Api\ConsolablePackInterface::getConsoleCommands()
     * @return \Symfony\Component\Console\Command\Command[]
     */
    public function getConsoleCommands(Container $app)
    {
        return [];
    }

    /**
     * A list of symlinks to add.
     * @see \Quazardous\Silex\Api\LinkablePackInterface::getSymlinks()
     * @return array
     */
    public function getSymlinks(Container $app)
    {
        $symlinks = [];
        if ($this->getPublicPath($app)) {
            $symlinks[$this->getPublicPath($app)] = 'packs/' . $this->_ns();
        }
        return $symlinks;
    }

    /**
     * By default, public is the public folder.
     * @see \Quazardous\Silex\Api\LinkablePackInterface::getPublicPath()
     * @return string
     */
    public function getPublicPath(Container $app) {
        static $paths = [];
        $me = get_class($this);
        if (empty($paths[$me])) {
            $subpath = $this->packOptions['public_subpath'];
            $paths[$me] = dirname($this->getReflector()->getFileName()) . '/' . $subpath;
        }
        return $paths[$me];
    }

    /**
     * Returns the the pack namespace path.
     * @return string
     */
    public function getPackPath(Container $app) {
        static $paths = [];
        $me = get_class($this);
        if (empty($paths[$me])) {
            $paths[$me] = dirname($this->getReflector()->getFileName());
        }
        return $paths[$me];
    }

    /**
     *
     * @return \ReflectionClass
     */
    protected function getReflector() {
        static $reflectors = [];
        $me = get_class($this);
        if (empty($reflectors[$me])) {
            $reflectors[$me] = new \ReflectionClass($this);
        }
        return $reflectors[$me];
    }

    /**
     * Helper function  to prefix ids with the pack name as namespace.
     * ie. for a pack named 'MyFooPack', the  id 'bar' becomes 'MyFoo.bar' or 'my_foo.bar' (with decamelize).
     *
     * @param string $id an id to namespace
     * @param boolean $decamelize
     * @param string $separator
     * @return string the pack namespaced id
     */
    protected function _ns($id = null, $decamelize = true, $separator = '.') {
        static $decamelizeds = [];
        $me = get_class($this);
        if ($decamelize && empty($decamelizeds[$me])) {
            $decamelizeds[$me] = \decamelize($this->getName());
        }
        $ns = $decamelize ? $decamelizeds[$me] : $this->getName();
        return $ns . ($id ? $separator . $id : '');
    }

}


<?php

namespace Rougin\Slytherin\Routing;

/**
 * Abstract Dispatcher
 *
 * An abstract class for common methods in route dispatchers.
 *
 * @package Slytherin
 * @author  Rougin Gutib <rougingutib@gmail.com>
 */
abstract class AbstractDispatcher
{
    /**
     * @var array
     */
    protected $allowed = array('DELETE', 'GET', 'OPTIONS', 'PATCH', 'POST', 'PUT');

    /**
     * Initializes the route dispatcher instance.
     *
     * @param \Rougin\Slytherin\Routing\RouterInterface|null $router
     */
    public function __construct(RouterInterface $router = null)
    {
        if ($router instanceof RouterInterface)
        {
            $this->router($router);
        }
    }

    /**
     * Checks if the specified method is a valid HTTP method.
     *
     * @param  string $method
     * @return boolean
     *
     * @throws UnexpectedValueException
     */
    protected function allowed($method)
    {
        if (in_array($method, $this->allowed) === false) {
            $message = 'Used method is not allowed';

            throw new \UnexpectedValueException($message);
        }

        return true;
    }

    /**
     * Sets the router and parse its available routes if needed.
     *
     * @param  \Rougin\Slytherin\Routing\RouterInterface $router
     * @return self
     */
    abstract public function router(RouterInterface $router);
}