<?php

namespace Haleks\Markdown\Compilers;

use Illuminate\View\Compilers\BladeCompiler;
use Illuminate\View\Compilers\CompilerInterface;

class BladeExtCompiler extends BladeCompiler implements CompilerInterface
{
    /**
     * Array of opening and closing tags for markdown echos.
     *
     * @var array
     */
    protected $markdownTags = ['{%', '%}'];

    /**
     * The markdown string format.
     *
     * @var string
     */
    protected $markdownFormat = 'app(\'markdown\')->convertToHtml(%s)';

    /**
     * Compile the view's markdown with given contents.
     *
     * @param  string  $contents
     * @return void
     */
    public function markdown($contents)
    {
        $contents = app('markdown')->convertToHtml($contents);

        if (! is_null($this->cachePath)) {
            $this->files->put($this->getCompiledPath($this->getPath()), $contents);
        }

        return $contents;
    }

    /**
     * Get the echo methods in the proper order for compilation.
     *
     * @return array
     */
    protected function getEchoMethods()
    {
        $methods = [
            'compileRawEchos' => strlen(stripcslashes($this->rawTags[0])),
            'compileEscapedEchos' => strlen(stripcslashes($this->escapedTags[0])),
            'compileMarkdownEchos' => strlen(stripcslashes($this->markdownTags[0])),
            'compileRegularEchos' => strlen(stripcslashes($this->contentTags[0])),
        ];

        uksort($methods, function ($method1, $method2) use ($methods) {
            // Ensure the longest tags are processed first
            if ($methods[$method1] > $methods[$method2]) {
                return -1;
            }
            if ($methods[$method1] < $methods[$method2]) {
                return 1;
            }

            // Otherwise give preference to raw tags (assuming they've overridden)
            if ($method1 === 'compileRawEchos') {
                return -1;
            }
            if ($method2 === 'compileRawEchos') {
                return 1;
            }

            if ($method1 === 'compileEscapedEchos') {
                return -1;
            }
            if ($method2 === 'compileEscapedEchos') {
                return 1;
            }

            if ($method1 === 'compileMarkdownEchos') {
                return -1;
            }
            if ($method2 === 'compileMarkdownEchos') {
                return 1;
            }
        });

        return $methods;
    }

    /**
     * Compile markdown into valid html.
     *
     * @param  string  $value
     * @return string
     */
    protected function compileMarkdownEchos($value)
    {
        $pattern = sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->markdownTags[0], $this->markdownTags[1]);

        $callback = function ($matches) {
            $wrapper = sprintf($this->markdownFormat, $this->compileEchoDefaults($matches[2]));

            return $matches[1] ? strlen(stripcslashes($this->markdownTags[0])) > 2 ? $matches[0] : substr($matches[0], 1) : '<?php echo '.$wrapper.'; ?>';
        };

        return preg_replace_callback($pattern, $callback, $value);
    }

    /**
     * Sets the escaped content tags used for the compiler.
     *
     * @param  string  $openTag
     * @param  string  $closeTag
     * @return void
     */
    public function setMarkdownTags($openTag, $closeTag)
    {
        $this->markdownTags = [preg_quote($openTag), preg_quote($closeTag)];
    }

    /**
     * Gets the tags used for the compiler.
     *
     * @param  bool  $escaped
     * @return array
     */
    protected function getMarkdownTags()
    {
        return $this->markdownTags;
    }
}


<?php

namespace CakephpCaptcha\Controller\Component;

use Cake\Controller\Component;
use CakephpCaptcha\Lib\PhpCaptcha;
use Cake\Event\Event;

/**
 * Captcha Component
 */
class CaptchaComponent extends Component
{
    /**
     * holds PhpCaptcha object
     * @var object
     */
    private $visualCaptcha = null;

    /**
     * startup method
     *
     * @param Event $event
     */
    public function startup(Event $event)
    {
        $this->request->session()->read();
        $this->visualCaptcha = new PhpCaptcha();
    }

    /**
     * image method
     *
     * @param int $count
     * @return string - the image's content
     */
    function image($count = 5)
    {
        $this->visualCaptcha->SetNumChars($count);
        return $this->visualCaptcha->Create();
    }

    /**
     * check method - checks if the provided code matches the previosly generated catpcha
     *
     * @param string $userCode
     * @param boolean $caseInsensitive
     * @return boolean
     */
    function check($userCode, $caseInsensitive = true)
    {
        return $this->visualCaptcha->Validate($userCode, $caseInsensitive);
    }

    /**
     * @TODO
     */
    function audio()
    {
        $oAudioCaptcha = new AudioPhpCaptcha('/usr/bin/flite', '/tmp/');
        $oAudioCaptcha->Create();
    }
}


<?php

namespace Haleks\Markdown;

use Haleks\Markdown\Compilers\BladeExtCompiler;
use Haleks\Markdown\Compilers\MarkdownCompiler;
use Haleks\Markdown\Compilers\MarkdownPhpCompiler;
use Haleks\Markdown\Compilers\MarkdownBladeCompiler;
use Haleks\Markdown\Engines\MarkdownEngine;
use League\CommonMark\DocParser;
use League\CommonMark\Environment;
use League\CommonMark\HtmlRenderer;
use League\CommonMark\Converter;
use Illuminate\Support\ServiceProvider;
use Illuminate\View\Engines\CompilerEngine;

class MarkdownServiceProvider extends ServiceProvider
{
    /**
     * Boot the service provider.
     *
     * @return void
     */
    public function boot()
    {
        $this->publishes([
            __DIR__.'/../config/markdown.php' => config_path('markdown.php'),
        ], 'config');
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->mergeConfigFrom(__DIR__.'/../config/markdown.php', 'markdown');

        $this->registerMarkdownEnvironment();
        $this->registerMarkdownParser();
        $this->registerMarkdownHtmlRenderer();
        $this->registerMarkdown();
        $this->registerEngines();
    }

    /**
     * Register the CommonMark Environment.
     *
     * @return void
     */
    protected function registerMarkdownEnvironment()
    {
        $app = $this->app;

        $app->singleton('commonmark.environment', function ($app) {
            $config = $app['config']['markdown'];
            $environment = Environment::createCommonMarkEnvironment();

            if ($config['configurations']) {
                $environment->mergeConfig($config['configurations']);
            }

            foreach ($config['extensions'] as $extension) {
                if (class_exists($extension)) {
                    $environment->addExtension(new $extension());
                }
            }

            return $environment;
        });

        $app->alias('commonmark.environment', Environment::class);
    }

    /**
     * Register the CommonMark DocParser.
     *
     * @return void
     */
    protected function registerMarkdownParser()
    {
        $app = $this->app;

        $app->singleton('commonmark.docparser', function ($app) {
            $environment = $app['commonmark.environment'];

            return new DocParser($environment);
        });

        $app->alias('commonmark.docparser', DocParser::class);
    }

    /**
     * Register the CommonMark HTML Renderer.
     *
     * @return void
     */
    protected function registerMarkdownHtmlRenderer()
    {
        $app = $this->app;

        $app->singleton('commonmark.htmlrenderer', function ($app) {
            $environment = $app['commonmark.environment'];

            return new HtmlRenderer($environment);
        });

        $app->alias('commonmark.htmlrenderer', HtmlRenderer::class);
    }

    /**
     * Register the CommonMarkConverter.
     *
     * @return void
     */
    protected function registerMarkdown()
    {
        $app = $this->app;

        $app->singleton('markdown', function ($app) {
            return new Converter($app['commonmark.docparser'], $app['commonmark.htmlrenderer']);
        });

        $app->alias('markdown', Converter::class);
    }

    /**
     * Register the service provider engines.
     *
     * @return void
     */
    protected function registerEngines()
    {
        $app = $this->app;
        $config = $app['config'];
        $resolver = $app['view.engine.resolver'];

        if ($config['markdown.tags']) {
            $this->registerBladeEngine($resolver);
        }

        if ($config['markdown.views']) {
            $this->registerMarkdownEngine($resolver);
            $this->registerMarkdownPhpEngine($resolver);
            $this->registerMarkdownBladeEngine($resolver);
        }
    }

    /**
     * Overwrite the Blade engine implementation.
     *
     * @return void
     */
    protected function registerBladeEngine($resolver)
    {
        $app = $this->app;

        $app->singleton('blade.compiler', function ($app) {
            $cache = $app['config']['view.compiled'];

            return new BladeExtCompiler($app['files'], $cache);
        });

        $resolver->register('blade', function () use ($app) {
            return new CompilerEngine($app['blade.compiler'], $app['files']);
        });
    }

    /**
     * Register the Markdown engine implementation.
     *
     * @return void
     */
    protected function registerMarkdownEngine($resolver)
    {
        $app = $this->app;

        $app->singleton('markdown.compiler', function ($app) {
            $cache = $app['config']['view.compiled'];

            return new MarkdownCompiler($app['files'], $cache);
        });

        $resolver->register('markdown', function () use ($app) {
            return new MarkdownEngine($app['markdown.compiler'], $app['files']);
        });

        $app['view']->addExtension('md', 'markdown');
    }

    /**
     * Register the Markdown Php engine implementation.
     *
     * @return void
     */
    protected function registerMarkdownPhpEngine($resolver)
    {
        $app = $this->app;

        $app->singleton('markdown.php.compiler', function ($app) {
            $cache = $app['config']['view.compiled'];

            return new MarkdownPhpCompiler($app['files'], $cache);
        });

        $resolver->register('markdown.php', function () use ($app) {
            return new MarkdownEngine($app['markdown.php.compiler'], $app['files']);
        });

        $app['view']->addExtension('md.php', 'markdown.php');
    }

    /**
     * Register the Markdown Blade engine implementation.
     *
     * @return void
     */
    protected function registerMarkdownBladeEngine($resolver)
    {
        $app = $this->app;

        $app->singleton('markdown.blade.compiler', function ($app) {
            $cache = $app['config']['view.compiled'];

            return new MarkdownBladeCompiler($app['files'], $cache);
        });

        $resolver->register('markdown.blade', function () use ($app) {
            return new MarkdownEngine($app['markdown.blade.compiler'], $app['files']);
        });

        $app['view']->addExtension('md.blade.php', 'markdown.blade');
    }
}


<?php
/**
* File containing the eZIEImageToolResize class.
*
* @copyright Copyright (C) 1999-2014 eZ Systems AS. All rights reserved.
* @license http://ez.no/licenses/gnu_gpl GNU GPL v2
* @version //autogentag//
* @package ezie
*/
class eZIEImageToolResize extends eZIEImageAction
{
    /**
    * Returns a resize filter
    *
    * @param  int $width Resize width
    * @param  int $height Resize height
    * @return array( ezcImageFilter )
    */
    static function filter( $width, $height )
    {
        return array(
            new ezcImageFilter(
                'scale',
                array(
                    'width'     => intval( $width ),
                    'height'    => intval( $height ),
                    'direction' => ezcImageGeometryFilters::SCALE_BOTH
                )
            )
        );
    }

    /**
    * Resizes an image
    *
    * @param  string $src Source image path
    * @param  string $dst Destination image path
    * @param  int $width Resize width
    * @param  int $height Resize height
    *
    * @return void
    */
    static function resize( $src, $dst, $width, $height )
    {
        $imageconverter = new eZIEezcImageConverter( self::filter( $width, $height ) );
        $imageconverter->perform( $src, $dst );
    }

    /**
    * Creates a thumb (250x250px) out of an image
    * @param  string $src Source image path
    * @param  string $dst Destination image path
    * @return void
    */
    static function doThumb( $src, $dst )
    {
        self::resize( $src, $dst, 250, 250 );
    }
}

?>


<?php
/**
 * File containing the eZIEEzcGDHandler class.
 *
 * @copyright Copyright (C) eZ Systems AS.
 * @license For full copyright and license information view LICENSE file distributed with this source code.
 * @version //autogentag//
 * @package ezie
 */
class eZIEEzcGDHandler extends ezcImageGdHandler implements eZIEEzcConversions
{
    /**
     * Apply the filter on the specified region and return the new resource
     *
     * @param  $filter
     * @param  $resource
     * @param  $region
     * @param  $colorspace
     * @param  $value parameters for region handling
     * @return imageresource
     */
    private function region( $filter, $resource, $region, $colorspace = null, $value = null )
    {
        $dest = imagecreatetruecolor( $region["w"], $region["h"] );
        if ( !imagecopy( $dest, $resource, 0, 0, $region["x"], $region["y"], $region["w"], $region["h"] ) )
        {
            throw new ezcImageFilterFailedException( "1/ {$function} applied on region {$region['x']}x{$region['y']}" );
        }

        if ( !$colorspace )
        {
            if ( $filter == "pixelateImg" )
            {
                $result = $this->$filter( $dest, imagesx( $resource ), imagesy( $resource ) );
            }
            else
                $result = $this->$filter( $dest, $value );
        }
        else
        {
            $this->setActiveResource( $dest );
            parent::colorspace( $colorspace );
            $result = $dest;
        }

        if ( !imagecopy( $resource, $result, $region["x"], $region["y"], 0, 0, $region["w"], $region["h"] ) )
        {
            throw new ezcImageFilterFailedException( "2/ {$function} applied on region {$region['x']}x{$region['y']}" );
        }

        return $resource;
    }

    /**
     *
     * @param  $hex
     * @return array
     */
    private function bgArrayFromHex( $hex )
    {
        return array(
            'r' => hexdec( substr( $hex, 0, 2 ) ),
            'g' => hexdec( substr( $hex, 2, 2 ) ),
            'b' => hexdec( substr( $hex, 4, 2 ) ),
            'a' => 127
        );
    }

    /* (non-PHPdoc)
     * @see lib/ezc/ImageConversion/src/handlers/ezcImageGdHandler#colorspace($space)
     */
    public function colorspace( $space, $region = null )
    {
        $resource = $this->getActiveResource();

        if ( $region )
        {
            $newResource = $this->region( null, $resource, $region, $space );
        }
        else
        {
            parent::colorspace( $space );
            return;
        }

        $this->setActiveResource( $newResource );
    }

    /* (non-PHPdoc)
     * @see extension/ezie/autoloads/eziezc/interfaces/eZIEEzcConversions#rotate($angle, $color)
     */
    public function rotate( $angle, $background = 'FFFFFF' )
    {
        $angle = intval( $angle );
        if ( !is_int( $angle ) || $angle < 0 || $angle > 360 )
        {
            throw new ezcBaseValueException( 'height', $angle, 'int > 0 && int < 360' );
        }

        $resource = $this->getActiveResource();

        $bg = $this->bgArrayFromHex( $background );
        $gdBackgroundColor = imagecolorallocatealpha( $resource, $bg['r'], $bg['g'], $bg['b'], $bg['a'] );

        $newResource = ImageRotate( $resource, $angle, $gdBackgroundColor );
        if ( $newResource === false )
        {
            throw new ezcImageFilterFailedException( 'rotate', 'Rotation of image failed.' );
        }

        imagedestroy( $resource );
        $this->setActiveResource( $newResource );
    }

    /* (non-PHPdoc)
     * @see extension/ezie/autoloads/eziezc/interfaces/eZIEEzcConversions#verticalFlip($region)
     */
    public function verticalFlip( $region = null )
    {
        $resource = $this->getActiveResource();

        $w = imagesx( $resource );
        $h = imagesy( $resource );

        $newResource = imagecreatetruecolor( $w, $h );

        imagealphablending( $newResource, false );
        imagesavealpha( $newResource, true );

        $res = imagecopyresampled( $newResource, $resource,
            0, 0,
            0, $h,
            $w, $h,
            $w, - $h );

        if ( $res === false )
        {
            throw new ezcImageFilterFailedException( 'rotate', 'Rotation of image failed.' );
        }

        imagedestroy( $resource );
        $this->setActiveResource( $newResource );
    }

    /**
     *
     * @param  $resource
     * @return unknown_type
     */
    private function horizontalFlipImg( $resource )
    {
        $w = imagesx( $resource );
        $h = imagesy( $resource );

        $newResource = imagecreatetruecolor( $w, $h );

        imagealphablending( $newResource, false );
        imagesavealpha( $newResource, true );

        $res = imagecopyresampled( $newResource, $resource,
            0, 0,
            $w, 0,
            $w, $h, - $w, $h );

        if ( $res === false )
        {
            throw new ezcImageFilterFailedException( 'rotate', 'Rotation of image failed.' );
        }

        imagedestroy( $resource );
        return $newResource;
    }

    /* (non-PHPdoc)
     * @see extension/ezie/autoloads/eziezc/interfaces/eZIEEzcConversions#horizontalFlip($region)
     */
    public function horizontalFlip( $region = null )
    {
        $resource = $this->getActiveResource();

        if ( $region )
        {
            $newResource = $this->region( "horizontalFlipImg", $resource, $region );
        }
        else
        {
            $newResource = $this->horizontalFlipImg( $resource );
        }

        $this->setActiveResource( $newResource );
    }

    /**
     *
     * @param  $resource
     * @param  $width
     * @param  $height
     * @return unknown_type
     */
    private function pixelateImg( $resource, $width, $height )
    {
        $w = imagesx( $resource );
        $h = imagesy( $resource );

        $size = ceil( max( $width, $height ) ) / 42;

        $tmp_w = $w / $size;
        $tmp_h = $h / $size;

        $tmpResource = imagecreatetruecolor( $tmp_w, $tmp_h );

        imagealphablending( $tmpResource, false );
        imagesavealpha( $tmpResource, true );

        $res = imagecopyresampled( $tmpResource, $resource,
            0, 0,
            0, 0,
            $tmp_w, $tmp_h,
            $w, $h );

        if ( $res === false )
        {
            throw new ezcImageFilterFailedException( 'pixelate', 'First part of pixelate failed.' );
        }
        imagedestroy( $resource );

        $newResource = imagecreatetruecolor( $w, $h );

        imagealphablending( $newResource, false );
        imagesavealpha( $newResource, true );

        $res = imagecopyresampled( $newResource, $tmpResource,
            0, 0,
            0, 0,
            $w, $h,
            $tmp_w, $tmp_h );

        if ( $res === false )
        {
            throw new ezcImageFilterFailedException( 'pixelate', 'Second part of pixelate failed.' );
        }

        imagedestroy( $tmpResource );
        return $newResource;
    }

    /**
     * contrast the given image, change $resource and return changed $resoure
     * @param $resource
     * @param $value contrast parameter
     * @return object $resource changed
     */
    private function contrastImg( $resource, $value )
    {
        imagefilter( $resource, IMG_FILTER_CONTRAST, - $value );
        return $resource;
    }

    /**
     * brightness the given image, change $resource and return changed $resource
     * @param $resource
     * @param unknown_type $value
     * @return object $resource changed
     */
    private function brightnessImg( $resource, $value )
    {
        imagefilter( $resource, IMG_FILTER_BRIGHTNESS, $value );
        return $resource;
    }

    /* (non-PHPdoc)
     * @see extension/ezie/autoloads/eziezc/interfaces/eZIEEzcConversions#pixelate($width, $height, $region)
     */
    public function pixelate( $width, $height, $region = null )
    {
        $resource = $this->getActiveResource();

        if ( $region )
        {
            $newResource = $this->region( "pixelateImg", $resource, $region );
        }
        else
        {
            $newResource = $this->pixelateImg( $resource, $width, $height );
        }

        $this->setActiveResource( $newResource );
    }

    /* (non-PHPdoc)
     * @see extension/ezie/autoloads/eziezc/interfaces/eZIEEzcConversions#brightness($value)
     */
    public function brightness( $value, $region = null )
    {
        $resource = $this->getActiveResource();

        if ( $value < - 255 || $value > 255 )
        {
            throw new ezcBaseValueException( 'value', $value, 'int >= -255 && int <= 255' );
        }

        if( $region )
        {
            $this->region( "brightnessImg", $resource, $region, null, $value );
        }
        else
        {
            $this->brightnessImg( $resource, $value );
        }
    }

    /* (non-PHPdoc)
     * @see extension/ezie/autoloads/eziezc/interfaces/eZIEEzcConversions#contrast($value)
     */
    public function contrast( $value, $region = null )
    {
        $resource = $this->getActiveResource();

        if ( $value < - 100 || $value > 100 )
        {
            throw new ezcBaseValueException( 'value', $value, 'int >= -100 && int <= 100' );
        }

        if ( $region )
        {
            $this->region( "contrastImg", $resource, $region, null, $value );
        }
        else
        {
            $this->contrastImg( $resource, $value );
        }
    }
}

?>


<?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\ORM\FieldType
 * @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\ORM\FieldType;

use SilverStripe\ORM\Connect\MySQLDatabase;
use SilverStripe\ORM\DB;
use SilverStripe\ORM\FieldType\DBField;
use SilverWare\FontIcons\Forms\FontIconField;

/**
 * A database field used to store a font icon reference.
 *
 * @package SilverWare\FontIcons\ORM\FieldType
 * @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 DBFontIcon extends DBField
{
    /**
     * Maps field and method names to the class names of casting objects.
     *
     * @var array
     * @config
     */
    private static $casting = [
        'Tag' => 'HTMLFragment'
    ];

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

    /**
     * Adds the field to the underlying database.
     *
     * @return void
     */
    public function requireField()
    {
        // Obtain Charset and Collation:

        $charset   = MySQLDatabase::config()->charset;
        $collation = MySQLDatabase::config()->collation;

        // Define Field Specification:

        $spec = [
            'type' => 'varchar',
            'parts' => [
                'datatype' => 'varchar',
                'precision' => 64,
                'collate' => $collation,
                'character set' => $charset,
                'arrayValue' => $this->arrayValue
            ]
        ];

        // Require Database Field:

        DB::require_field($this->tableName, $this->name, $spec);
    }

    /**
     * Answers a form field instance for automatic form scaffolding.
     *
     * @param string $title Title of the field instance.
     * @param array $params Array of extra parameters.
     *
     * @return FontIconField
     */
    public function scaffoldFormField($title = null, $params = null)
    {
        return FontIconField::create($this->name, $title);
    }

    /**
     * Answers the font icon tag for the HTML template.
     *
     * @return string
     */
    public function getTag()
    {
        return $this->backend->getTag($this->backend->getClassName('icon', $this->getValue()));
    }
}


<?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\Unit;

/**
 * Angle deals with degrees, radians, grades and turns.
 *
 * By default, radians are used, but you can instanciate angle using unit you want.
 *
 *     $a = new Angle(M_PI / 2); // create angle from radians
 *     $a = new Angle(90, Angle::TYPE_DEG); // degrees
 *
 * As you can see, the second argument is a class constant. There are 4 constants, listed below:
 *
 *  - `TYPE_RAD` for radians,
 *  - `TYPE_DEG` for degrees,
 *  - `TYPE_GON` for grades,
 *  - `TYPE_TURN` for turns.
 *
 * When Angle is created, you can compare it with another to know if they are complementary or supplementary.
 *
 * For current angle, you can convert it to other units.
 *
 * Current angle can also be tested to know if it is right, straight or perigon (complete lap).
 *
 * See methods to know more!
 *
 * @property-read $rad Get radians
 * @property-read $deg Get degrees
 * @property-read $gon Get gon
 * @property-read $turn Get number of turns
 * @property-read $dms Get Degrees/Minutes/Second object
 * @property-read $type Original type used to create Angle, the type returned by get()
 * @todo use http://en.wikipedia.org/wiki/Angle to have other ideas of units.
 * @author Michel Petit <petit.michel@gmail.com>
 * @license MIT
 */
class Angle
{
    const TYPE_RAD = 'rad';
    const TYPE_DEG = 'deg';
    const TYPE_GON = 'gon';
    const TYPE_TURN = 'trn';

    /**
     * Radians internal value.
     *
     * @var float
     * @access protected
     */
    protected $float_rad = 0;

    /**
     * Stored original value if other than radians.
     *
     * @var mixed
     * @access protected
     */
    protected $original = null;

    /**
     * Method to have magick getters.
     *
     * @param  string $name
     * @access public
     * @return mixed
     */
    public function __get($name)
    {
        if (in_array($name, array('rad', 'deg', 'gon', 'turn', 'dms'))) {
            return $this->$name();
        }

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

    /**
     * Create new Angle, from radians by default, or with second argument, can
     * be degrees, grades or turns too.
     *
     * @param  float  $float_angle Value of the angle, in radians if second argument is not given
     * @param  string $str_type    One of the class' constants. Optional.
     * @access public
     * @return void
     */
    public function __construct($float_angle, $str_type = self::TYPE_RAD)
    {
        $this->original = new \stdClass();
        $this->original->value = $float_angle;
        $this->original->type = $str_type;

        if ($str_type == self::TYPE_DEG) {
            $this->float_rad = deg2rad($float_angle);
        } elseif ($str_type == self::TYPE_GON) {
            $this->float_rad = $float_angle * pi() / 200;
        } elseif ($str_type == self::TYPE_TURN) {
            $this->float_rad = $float_angle * 2 * pi();
        } else {
            $this->float_rad = $float_angle;
        }
    }

    /**
     * Gets angle's value as gon (grade).
     *
     * @access public
     * @return float
     */
    public function gon()
    {
        if ($this->original->type == self::TYPE_GON) {
            return $this->original->value;
        }

        return $this->float_rad * 200 / pi();
    }

    /**
     * Gets angle's value as degrees.
     *
     * @access public
     * @return float
     */
    public function deg()
    {
        if ($this->original->type == self::TYPE_DEG) {
            return $this->original->value;
        }

        return rad2deg($this->float_rad);
    }

    /**
     * gets angles as radians
     *
     * @access public
     * @return float
     */
    public function rad()
    {
        if ($this->original->type == self::TYPE_RAD) {
            return $this->original->value;
        }

        return $this->float_rad;
    }

    /**
     * Gets angle's value, as it was given at instenciation time.
     *
     * @access public
     * @return float
     */
    public function get()
    {
        return $this->original->value;
    }

    /**
     * Gets number of turns
     *
     * @access public
     * @return float
     */
    public function turn()
    {
        if ($this->original->type == self::TYPE_TURN) {
            return $this->original->value;
        }

        return $this->float_rad / (2 * pi());
    }

    /**
     * Gets angle as a "Degrees/Minutes/seconds" object.
     *
     * DMS object returned as 4 attributes:
     *
     *  - `d` for degrees,
     *  - `m` for minutes,
     *  - `s` for seconds,
     *  - `str` for the DMS string (`34°56′23″`)
     *
     * @access public
     * @return stdClass
     */
    public function dms()
    {
        $float = abs($this->deg());

        $prov = function ($float) {
            $whole_part = (integer) $float;
            $fractional_part = $float - $whole_part;

            $out = new \stdClass();
            $out->whole = $whole_part;
            $out->fractional = $fractional_part * 60;

            return $out;
        };

        $prov_1 = $prov($float);
        $prov_2 = $prov($prov_1->fractional);
        $prov_3 = $prov($prov_2->fractional);

        $dms = new \stdClass();
        $dms->d = $prov_1->whole;
        $dms->m = $prov_2->whole;
        $dms->s = $prov_3->whole;
        $dms->str = sprintf('%d°%d′%d″', $dms->d, $dms->m, $dms->s);

        return $dms;
    }

    /**
     * Checks whether current angle is right (90°), even if there are several turns.
     *
     * @access public
     * @return boolean
     */
    public function isRight()
    {
        return in_array(abs($this->turn()) - (integer) abs($this->turn()), array(1/4, 3/4));
    }

    /**
     * Checks whether current angle is straight (180°), even if there are several turns.
     *
     * @access public
     * @return boolean
     */
    public function isStraight()
    {
        return abs($this->turn()) - (integer) abs($this->turn()) == 0.5;
    }

    /**
     * Checks whether angle does at least one complete turn (360° × n).
     *
     * @access public
     * @return boolean
     */
    public function isPerigon()
    {
        return fmod(abs($this->turn()), 1) == 0;
    }

    /**
     * Tests current angle with another to know if there are complementary together
     *
     * @param  Angle   $angle
     * @access public
     * @return boolean
     */
    public function isComplementary(Angle $angle)
    {
        $out = new self($this->float_rad + $angle->rad);

        return $out->isRight();
    }

    /**
     * Test if current angle is supplementary with another.
     *
     * @param  Angle   $angle
     * @access public
     * @return boolean
     */
    public function isSupplementary(Angle $angle)
    {
        $out = new self($this->float_rad + $angle->rad);

        return $out->isStraight();
    }
}


<?php

namespace Rougin\Slytherin\Integration;

/**
 * Configuration
 *
 * Serves as a storage for configuration data.
 *
 * @package Slytherin
 * @author  Rougin Gutib <rougingutib@gmail.com>
 */
class Configuration implements ConfigurationInterface
{
    /**
     * @var array
     */
    protected $data = array();

    /**
     * Initializes the configuration instance.
     *
     * @param array|string|null $data
     */
    public function __construct($data = null)
    {
        if (is_array($data))
        {
            $this->data = $data;
        }

        if (is_string($data))
        {
            $this->load($data);
        }
    }

    /**
     * Returns the value from the specified key.
     *
     * @param  string     $key
     * @param  mixed|null $default
     * @return mixed
     */
    public function get($key, $default = null)
    {
        $keys = array_filter(explode('.', $key));

        $length = count($keys);

        $data = $this->data;

        for ($i = 0; $i < $length; $i++) {
            $index = $keys[$i];

            $data = &$data[$index];
        }

        return $data !== null ? $data : $default;
    }

    /**
     * Loads the configuration from a specified directory.
     *
     * @param  string $directory
     * @return self
     */
    public function load($directory)
    {
        $configurations = glob($directory . '/*.php');

        foreach ($configurations as $configuration) {
            $items = require $configuration;

            $name = basename($configuration, '.php');

            $this->data = array_merge($this->data, array($name => $items));
        }

        return $this->data;
    }

    /**
     * Sets the value to the specified key.
     *
     * @param  string  $key
     * @param  mixed   $value
     * @param  boolean $fromFile
     * @param  mixed
     * @return self
     */
    public function set($key, $value, $fromFile = false)
    {
        $keys = array_filter(explode('.', $key));

        $value = ($fromFile) ? require $value : $value;

        $this->save($keys, $this->data, $value);

        return $this;
    }

    /**
     * Saves the specified key in the list of data.
     *
     * @param  array  &$keys
     * @param  array  &$data
     * @param  mixed  $value
     * @return mixed
     */
    protected function save(array &$keys, &$data, $value)
    {
        $key = array_shift($keys);

        if (empty($keys)) {
            $data[$key] = $value;

            return $data[$key];
        }

        isset($data[$key]) || $data[$key] = array();

        return $this->save($keys, $data[$key], $value);
    }
}


<?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;
/**
 * Matrix basic implementation.
 *
 * Different ways are available to instanciate a Matrix:
 *
 * - by setting all values using one dimensional array,
 * - by adding columns,
 * - by adding rows
 *
 * So, a little example to show you:
 *
 *     $m = new Matrix(2, 3); // 2 rows, 3 columns
 *
 *     $m->populate(array(1, 2, 3, 4, 5, 6)); // populate into one shot
 *
 *     // or adding columns
 *     $m->addCol(array(1, 4));
 *     $m->addCol(array(2, 5));
 *     $m->addCol(array(3, 6));
 *
 *     // or adding rows
 *     $m->addRow(array(1, 2, 3));
 *     $m->addRow(array(4, 5, 6));
 *
 *
 *  Some actions are available, like __transpose__, __multiply__ with scalar or Matrix,
 *  __add__ Matrix, test if a Matrix is square… See methods to have more information!
 *
 * @todo as a reminder: http://www.latp.univ-mrs.fr/~torresan/CalcMat/cours/node2.html
 *
 * @property-read $cols Amount of columns
 * @property-read $rows Amount of rows
 * @author Michel Petit <petit.michel@gmail.com>
 * @license MIT
 */
class Matrix
{
    /**
     * Items of the matrix, as an array of array.
     *
     * @var array
     * @access protected
     */
    protected $arr = array();

    /**
     * Size of the matrix: column and row number.
     *
     * @var mixed
     * @access protected
     */
    protected $size = null;

    /**
     * Defines magic getter to acces to column's numbers and row's numbers
     *
     * @param  mixed   $name
     * @access public
     * @return integer
     */
    public function __get($name)
    {
        if (in_array($name, array('cols', 'rows'))) {
            return $this->size->$name;
        }

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

        if ($name == 'is_square' || $name == 'square') {
            return $this->isSquare();
        }

        if ($name == 'is_diagonal' || $name == 'diagonal') {
            return $this->isDiagonal();
        }

        if (in_array($name, array('cofactor', 'adjugate', 'inverse', 'det', 'trace', 'determinant', 'transpose'))) {
            return $this->$name();
        }
    }

    /**
     * Constructs new matrix giving its size.
     *
     * @throw \InvalidArgumentException If numbers of cols or rows are not integers.
     * @throw \InvalidArgumentException If numbers of cols or rows are not positive numbers.
     * @param  integer $int_rows
     * @param  integer $int_cols
     * @access public
     * @return Matrix
     */
    public function __construct($int_rows, $int_cols)
    {
        if (!is_numeric($int_cols) || !is_numeric($int_rows)) {
            throw new \InvalidArgumentException('number of cols and rows must be integers.');
        }

        $int_cols = (integer) $int_cols;
        $int_rows = (integer) $int_rows;

        if ($int_cols <= 0 || $int_rows <= 0) {
            throw new \InvalidArgumentException('Number of cols and rows must be positive not null integers.');
        }

        $this->size = new \stdClass();
        $this->size->cols = $int_cols;
        $this->size->rows = $int_rows;
    }

    /**
     * Puts all values into the matrix.
     *
     * Argument is a simple array of one dimension. If the matrix has 3 columns
     * and 2 rows, the the argument must have 6 elements. Under the hood, the
     * given array is split to fit the matrix.
     *
     * By the way, you can use rows and colunms in place of this method.
     *
     * @param  array  $arrAll
     * @access public
     * @return Matrix
     */
    public function populate($arrAll)
    {
        $this->arr = array_chunk($arrAll, $this->size->cols);

        return $this;
    }

    /**
     * Gets one item at given row and column.
     *
     * @throw \InvalidArgumentException If indexes are not integers
     * @throw \InvalidArgumentException If one of the given indexes does not exist.
     * @param  integer $int_i Row index
     * @param  integer $int_j Column index
     * @access public
     * @return float
     */
    public function get($int_i, $int_j)
    {
        if (!is_integer($int_i) || !is_integer($int_j)) {
            throw new \InvalidArgumentException('Indices must be integers.');
        }

        if(
            $int_i >= $this->size->rows
            ||
            $int_j >= $this->size->cols
            ||
            $int_i < 0
            ||
            $int_j < 0
        )
        {
            throw new \InvalidArgumentException('Row’s index or column’s index does not exist!');
        }

        return $this->arr[$int_i][$int_j];
    }

    /**
     * Adds a row to populate step by step the matrix
     *
     * @throw \OutOfRangeException If this is called and the number of rows is full.
     * @throw \InvalidArgumentException If row has not the same number of column that previous one.
     * @param  array  $arr_row Data to add
     * @access public
     * @return Matrix
     */
    public function addRow(array $arr_row)
    {
        if (count($this->arr) == $this->size->rows) {
            throw new \OutOfRangeException(sprintf('You cannot add another row! Max number of rows is %d', $this->size->rows));
        }

        if (count($arr_row) != $this->size->cols) {
            throw new \InvalidArgumentException('New row must have same amout of columns than defined into the size matrix');
        }

        $this->arr[] = $arr_row;

        return $this;
    }

    /**
     * Adds a column to populate step by step the matrix
     *
     * @throw \OutOfRangeException If this is called and the number of columns is full.
     * @throw \InvalidArgumentException If colmun has not the same number of rows that previous one.
     * @param  array  $arr_col Data to add
     * @access public
     * @return Matrix
     */
    public function addCol($arr_col)
    {
        if (isset($this->arr[0]) && (count($this->arr[0]) == $this->size->cols)) {
            throw new \OutOfRangeException(sprintf('You cannot add another column! Max number of columns is %d', $this->size->cols));
        }

        if (count($arr_col) != $this->size->rows) {
            throw new \InvalidArgumentException('New column must have same amout of rows than previous columns.');
        }

        $arr_col = array_values($arr_col); //to be sure to have index 0, 1, 2…

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

        return $this;
    }

    /**
     * Gets the row having the given index.
     *
     * @throw \OutOfRangeException If given index does not exist.
     * @param  integer $int Row's index
     * @access public
     * @return mixed
     */
    public function getRow($int = 0)
    {
        if (!isset($this->arr[$int])) {
            throw new \OutOfRangeException('There is no line having this index.');
        }

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

    /**
     * Gets the column having the given index.
     *
     * @throw \OutOfRangeException If given index does not exist.
     * @param  integer $int column's index
     * @access public
     * @return mixed
     */
    public function getCol($int = 0)
    {
        if ($int >= $this->size->cols) {
            throw new \OutOfRangeException('There is not column having this index.');
        }

        $arr_out = array();

        foreach ($this->arr as $row) {
            $arr_out[] = $row[$int];
        }

        return $arr_out;
    }

    /**
     * Tells whether the current matrix is square or not.
     *
     * @access public
     * @return boolean
     */
    public function isSquare()
    {
        return $this->size->cols == $this->size->rows;
    }

    /**
     * Tests whether the current matrix is diagonal or not.
     *
     * @access public
     * @return boolean
     */
    public function isDiagonal()
    {
        $int_size = min((array) $this->size);

        if($int_size > 0){
            for($i = 0; $i < $int_size; $i++){
                $arr_row = $this->getRow($i);

                if($arr_row[$i] != 0){
                    unset($arr_row[$i]);

                    foreach($arr_row as $v){
                        if($v != 0){
                            return false;
                        }
                    }

                } else {
                    return false;
                }
            }

            return true;
        }

        return false;
    }

    public function exponential()
    {
        //TODO: implement it!
        if(!$this->isSquare()){
            throw new \RuntimeException('Computing exponential of non diagonal Matrix is not yet implemented');
        }

        $int_size = min((array) $this->size);

        $out = new self($this->size->rows, $this->size->cols);

        if($int_size > 0){
            for($i = 0; $i < $int_size; $i++){
                $arr_row = $this->getRow($i);

                if($arr_row[$i] != 0){
                    $arr_row[$i] = exp($arr_row[$i]);
                }

                $out->addRow($arr_row);
            }
        }

        return $out;

    }

    public function exp()
    {
        return $this->exponential();
    }

    /**
     * Tests whether the current matrix is the same as the given one.
     *
     * @param  Matrix  $matrix
     * @access public
     * @return boolean
     */
    public function sameSize($matrix)
    {
        return (
            $this->size->cols == $matrix->cols
            &&
            $this->size->rows == $matrix->rows
        );
    }

    /**
     * Tests whether the current matrix can be multiply with the given one.
     *
     * @param  mixed   $matrix Scalar, complex or matrix
     * @access public
     * @return boolean
     */
    public function multiplyAllow($matrix)
    {
        if (is_numeric($matrix)) {
            return true;
        }

        if ($matrix instanceof Complex) {
            return true;
        }

        if ($matrix instanceof Matrix) {
            return $this->size->cols == $matrix->rows;
        }

        return false;
    }

    /**
     * Returns the transpose of the current matrix.
     *
     * @access public
     * @return Matrix
     */
    public function transpose()
    {
        $out = new self($this->size->cols, $this->size->rows);

        foreach ($this->arr as $row) {
            $out->addCol($row);
        }

        return $out;
    }

    /**
     * Adds the given matrix with the current one to give another new matrix.
     *
     * @throw \InvalidArgumentException If argument is not a Matrix
     * @throw \RuntimeException If given matrix has not the same size.
     * @param  Matrix $matrix Matrix to add
     * @access public
     * @return Matrix
     */
    public function add($matrix)
    {
        if (!($matrix instanceof Matrix)) {
            throw new \InvalidArgumentException('Given argument must be an instance of \Malenki\Math\Matrix');
        }

        if (!$this->sameSize($matrix)) {
            throw new \RuntimeException('Cannot adding given matrix: it has wrong size.');
        }

        $out = new self($this->size->rows, $this->size->cols);

        foreach ($this->arr as $k => $v) {
            $arrOther = $matrix->getRow($k);
            $arrNew = array();

            foreach ($v as $kk => $vv) {
                if ($arrOther[$kk] instanceof Complex) {
                    $arrNew[] = $arrOther[$kk]->add($vv);
                } elseif ($vv instanceof Complex) {
                    $arrNew[] = $vv->add($arrOther[$kk]);
                } else {
                    $arrNew[] = $arrOther[$kk] + $vv;
                }
            }

            $out->addRow($arrNew);
        }

        return $out;
    }

    /**
     * Multiplies current matrix to another one or to a scalar.
     *
     * @throw \RuntimeException If argument is not valid number or if the given
     * matrix has not the right numbers of rows.
     * @param  mixed  $mix Number (Real or Complex) or Matrix
     * @access public
     * @return Matrix
     */
    public function multiply($mix)
    {
        if (!$this->multiplyAllow($mix)) {
            throw new \RuntimeException('Invalid number or matrix has not right number of rows.');
        }

        if ($mix instanceof Matrix) {
            $out = new self($this->size->rows, $mix->cols);

            for ($r = 0; $r < $this->size->rows; $r++) {
                $arrOutRow = array();

                for ($c = 0; $c < $mix->cols; $c++) {
                    $arrCol = $mix->getCol($c);
                    $arrRow = $this->getRow($r);

                    $arrItem = array();
                    $hasComplex = false;

                    foreach ($arrCol as $k => $v) {
                        if ($arrRow[$k] instanceof Complex) {
                            $arrItem[] = $arrRow[$k]->multiply($v);
                            $hasComplex = true;
                        } elseif ($v instanceof Complex) {
                            $arrItem[] = $v->multiply($arrRow[$k]);
                            $hasComplex = true;
                        } else {
                            $arrItem[] = $arrRow[$k] * $v;
                        }
                    }

                    if ($hasComplex) {
                        $sum = new Complex(0, 0);

                        foreach ($arrItem as $item) {
                            if (is_numeric($item)) {
                                $item = new Complex($item, 0);
                            }

                            $sum = $item->add($sum);
                        }

                        $arrOutRow[] = $sum;
                    } else {
                        $arrOutRow[] = array_sum($arrItem);
                    }
                }

                $out->addRow($arrOutRow);
            }

            return $out;
        }

        if (is_numeric($mix) || $mix instanceof Complex) {
            $out = new self($this->size->rows, $this->size->cols);

            for ($r = 0; $r < $this->size->rows; $r++) {
                $arrRow = $this->getRow($r);

                foreach ($arrRow as $k => $v) {
                    if (is_numeric($mix)) {
                        if ($v instanceof Complex) {
                            $arrRow[$k] = $v->multiply($mix);
                        } else {
                            $arrRow[$k] = $mix * $v;
                        }
                    } else {
                        $arrRow[$k] = $mix->multiply($v);
                    }
                }

                $out->addRow($arrRow);
            }

            return $out;
        }
    }

    /**
     * Gets the cofactor matrix
     *
     * @access public
     * @return Matrix
     */
    public function cofactor()
    {
        $c = new self($this->size->rows, $this->size->cols);

        for ($m = 0; $m < $this->size->rows; $m++) {
            $arr_row = array();

            for ($n = 0; $n < $this->size->cols; $n++) {
                if ($this->size->cols == 2) {
                    $arr_row[] = pow(-1, $m + $n) * $this->subMatrix($m, $n)->get(0,0);
                } else {
                    $arr_row[] = pow(-1, $m + $n) * $this->subMatrix($m, $n)->det();
                }
            }

            $c->addRow($arr_row);
        }

        return $c;
    }

    public function adjugate()
    {
        return $this->cofactor()->transpose();
    }

    /**
     * Gets inverse matrix.
     *
     * Inverse matrix is get if and only if the determinant is not null.
     *
     * @throw \RuntimeException If determinant is null.
     * @access public
     * @return Matrix
     */
    public function inverse()
    {
        $det = $this->det();

        if ($det == 0) {
            throw new \RuntimeException('Cannot get inverse matrix: determinant is nul!');
        }

        return $this->adjugate()->multiply(1 / $det);
    }

    /**
     * Gets sub matrix from current.
     *
     * This is usefull for determinant calculus, inverse, etc.
     *
     * @param  integer $int_m Index of rows to ignore
     * @param  integer $int_n Index of column to ignore
     * @access public
     * @return Matrix
     */
    public function subMatrix($int_m, $int_n)
    {
        $sm = new self($this->size->rows - 1, $this->size->cols - 1);

        foreach ($this->arr as $m => $row) {
            if ($m != $int_m) {
                $arr_row = array();

                foreach ($row as $n => $v) {
                    if ($n != $int_n) {
                        $arr_row[] = $v;
                    }
                }

                $sm->addRow($arr_row);
            }
        }

        return $sm;
    }

    /**
     * Computes the determinant.
     *
     * @todo What about complex number?
     * @throw \RuntimeException If matrix is not square.
     * @access public
     * @return float
     */
    public function det()
    {
        if (!$this->isSquare()) {
            throw new \RuntimeException('Cannot compute determinant of non square matrix!');
        }

        if ($this->size->rows == 2) {
            return $this->get(0,0) * $this->get(1,1) - $this->get(0,1) * $this->get(1,0);
        } else {
            $int_out = 0;

            $arr_row = $this->arr[0];

            foreach ($arr_row as $n => $v) {
                $int_out += pow(-1, $n + 2) * $v * $this->subMatrix(0, $n)->det();
            }

            return $int_out;
        }
    }

    public function trace()
    {
        if (!$this->isSquare()) {
            throw new \RuntimeException('Cannot compute trace of non square matrix!');
        }

        $int = 0;

        for ($i = 0; $i < $this->size->rows; $i++) {
            $int += $this->get($i, $i);
        }

        return $int;
    }

    public function determinant()
    {
        return $this->det();
    }

    /**
     * Gets all data of the current matrix as 2 dimensions array
     *
     * @access public
     * @return array
     */
    public function getAll()
    {
        return $this->arr;
    }

    /**
     * Returns human readable matrix string like a pseudo table.
     *
     * @access public
     * @return string
     */
    public function __toString()
    {
        $arr_out = array();
        $arr_col_width = array();

        foreach ($this->arr as $row) {
            $arr_row = array();

            foreach ($row as $k => $item) {
                $arr_row[] = (string) $item;

                $int_length = strlen($arr_row[count($arr_row) - 1]);

                if(
                    (isset($arr_col_width[$k]) && $arr_col_width[$k] < $int_length)
                    ||
                    !isset($arr_col_width[$k])
                )
                {
                    $arr_col_width[$k] = $int_length;
                }
            }

            $arr_out[] = $arr_row;
        }

        foreach ($arr_out as $idx => $row) {
            $arr_row = array();

            foreach ($row as $k => $item) {
                $arr_row[] = str_pad($item, $arr_col_width[$k], ' ' ,STR_PAD_LEFT);
            }

            $arr_out[$idx] = implode('  ', $arr_row);
        }

        return implode(PHP_EOL, $arr_out);
    }
}


<?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\RequestInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;

/**
 * Request
 *
 * @package Slytherin
 * @author  Rougin Gutib <rougingutib@gmail.com>
 */
class Request extends Message implements RequestInterface
{
    /**
     * @var string
     */
    protected $target = '/';

    /**
     * @var string
     */
    protected $method = 'GET';

    /**
     * @var \Psr\Http\Message\UriInterface
     */
    protected $uri;

    /**
     * Initializes the request instance.
     *
     * @param string                                 $method
     * @param string                                 $target
     * @param \Psr\Http\Message\UriInterface|null    $uri
     * @param \Psr\Http\Message\StreamInterface|null $body
     * @param array                                  $headers
     * @param string                                 $version
     */
    public function __construct($method = 'GET', $target = '/', UriInterface $uri = null, StreamInterface $body = null, array $headers = array(), $version = '1.1')
    {
        parent::__construct($body, $headers, $version);

        $this->method = $method;

        $this->target = $target;

        $this->uri = $uri === null ? new Uri : $uri;
    }

    /**
     * Retrieves the HTTP method of the request.
     *
     * @return string
     */
    public function getMethod()
    {
        return $this->method;
    }

    /**
     * Retrieves the message's request target.
     *
     * @return string
     */
    public function getRequestTarget()
    {
        return $this->target;
    }

    /**
     * Retrieves the URI instance.
     *
     * @return \Psr\Http\Message\UriInterface
     */
    public function getUri()
    {
        return $this->uri;
    }

    /**
     * Returns an instance with the provided HTTP method.
     *
     * @param  string $method
     * @return static
     *
     * @throws \InvalidArgumentException
     */
    public function withMethod($method)
    {
        // TODO: Add \InvalidArgumentException

        $static = clone $this;

        $static->method = $method;

        return $static;
    }

    /**
     * Returns an instance with the specific request-target.
     *
     * @param  mixed $target
     * @return static
     */
    public function withRequestTarget($target)
    {
        $static = clone $this;

        $static->target = $target;

        return $static;
    }

    /**
     * Returns an instance with the provided URI.
     *
     * @param  \Psr\Http\Message\UriInterface $uri
     * @param  boolean                        $preserve
     * @return static
     */
    public function withUri(UriInterface $uri, $preserve = false)
    {
        $static = clone $this;

        $static->uri = $uri;

        if (! $preserve && $host = $uri->getHost()) {
            $port = $host . ':' . $uri->getPort();

            $host = $uri->getPort() ? $port : $host;

            $static->headers['Host'] = (array) $host;
        }

        return $static;
    }
}


<?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;
use Psr\Http\Message\MessageInterface;

/**
 * Message
 *
 * @package Slytherin
 * @author  Kévin Dunglas <dunglas@gmail.com>
 * @author  Rougin Gutib <rougingutib@gmail.com>
 */
class Message implements MessageInterface
{
    /**
     * @var \Psr\Http\Message\StreamInterface
     */
    protected $body;

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

    /**
     * @var string
     */
    protected $version = '1.1';

    /**
     * Initializes the message instance.
     *
     * @param \Psr\Http\Message\StreamInterface|null $body
     * @param array                                  $headers
     * @param string                                 $version
     */
    public function __construct(StreamInterface $body = null, array $headers = array(), $version = '1.1')
    {
        if ($body === null) {
            $resource = fopen('php://temp', 'r+');

            $resource = $resource === false ? null : $resource;

            $body = new Stream($resource);
        }

        $this->body = $body;

        $this->headers = $headers;

        $this->version = $version;
    }

    /**
     * Returns the body of the message.
     *
     * @return \Psr\Http\Message\StreamInterface
     */
    public function getBody()
    {
        return $this->body;
    }

    /**
     * Retrieves a message header value by the given case-insensitive name.
     *
     * @param  string $name
     * @return string[]
     */
    public function getHeader($name)
    {
        return $this->hasHeader($name) ? $this->headers[$name] : array();
    }

    /**
     * Retrieves a comma-separated string of the values for a single header.
     *
     * @param  string $name
     * @return string
     */
    public function getHeaderLine($name)
    {
        return $this->hasHeader($name) ? implode(',', $this->headers[$name]) : '';
    }

    /**
     * Retrieves all message header values.
     *
     * @return string[][]
     */
    public function getHeaders()
    {
        return $this->headers;
    }

    /**
     * Retrieves the HTTP protocol version as a string.
     *
     * @return string
     */
    public function getProtocolVersion()
    {
        return $this->version;
    }

    /**
     * Retrieves a message header value by the given case-insensitive name.
     *
     * @param  string $name
     * @return string[]
     */
    public function hasHeader($name)
    {
        return isset($this->headers[$name]);
    }

    /**
     * Returns an instance with the specified header appended with the given value.
     *
     * @param  string          $name
     * @param  string|string[] $value
     * @return static
     *
     * @throws \InvalidArgumentException
     */
    public function withAddedHeader($name, $value)
    {
        // TODO: Add \InvalidArgumentException

        $static = clone $this;

        $static->headers[$name][] = $value;

        return $static;
    }

    /**
     * Returns an instance with the specified message body.
     *
     * @param  \Psr\Http\Message\StreamInterface $body
     * @return static
     *
     * @throws \InvalidArgumentException
     */
    public function withBody(StreamInterface $body)
    {
        $static = clone $this;

        $static->body = $body;

        return $static;
    }

    /**
     * Returns an instance with the provided value replacing the specified header.
     *
     * @param  string          $name
     * @param  string|string[] $value
     * @return static
     *
     * @throws \InvalidArgumentException
     */
    public function withHeader($name, $value)
    {
        // TODO: Add \InvalidArgumentException

        $static = clone $this;

        $static->headers[$name] = (array) $value;

        return $static;
    }

    /**
     * Returns an instance with the specified HTTP protocol version.
     *
     * @param  string $version
     * @return static
     */
    public function withProtocolVersion($version)
    {
        $static = clone $this;

        $static->version = $version;

        return $static;
    }

    /**
     * Returns an instance without the specified header.
     *
     * @param  string $name
     * @return static
     */
    public function withoutHeader($name)
    {
        $instance = clone $this;

        if ($this->hasHeader($name)) {
            $static = clone $this;

            unset($static->headers[$name]);

            $instance = $static;
        }

        return $instance;
    }
}


<?php
namespace MvLabs\Zf2Extension\ModuleRetriever;

use Zend\Mvc\Application;
/**
 * Description of ModuleRetriever
 *
 * @author David Contavalli <mauipipe@gmail.com>
 * @copyright M.V. Associate  - All Rights Reserved -
 *  You may execute and modify the contents of this file, but only within the scope of this project.
 *  Any other use shall be considered forbidden, unless otherwise specified.
 * @link http://www.mvassociates.it
 */
class ModuleDetailRetriever
{
    const STANDARD_AUTOLOLOADER = 'Zend\Loader\StandardAutoloader';
    const NAMESPACE_KEY = 'namespaces';

    private $zf2MvcApplication;
    private $loadedModules;

    public function __construct(Application $zf2MvcApplication)
    {
        $this->zf2MvcApplication = $zf2MvcApplication;
        $this->loadedModules = $this->zf2MvcApplication->getServiceManager()->get('ModuleManager')->getLoadedModules();
    }

    /**
     * get all loaded module name
     * @return array
     */
    public function getLoadedModules()
    {
        return array_keys($this->loadedModules);

    }

    /**
     * Retrieve the module path
     * @param string $moduleName
     */
    public function getModulePath($moduleName)
    {
        if (array_key_exists($moduleName, $this->loadedModules)) {

              $module = $this->loadedModules[$moduleName];
              $moduleConfig = $module->getAutoloaderConfig();

               return $moduleConfig[self::STANDARD_AUTOLOLOADER][self::NAMESPACE_KEY][$moduleName];

        }

        return null;

    }

}


<?php

namespace Rougin\Slytherin\Application;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Rougin\Slytherin\Container\Container;

/**
 * Final Callback
 *
 * Builds the final callback after handling from application.
 *
 * @package Slytherin
 * @author  Rougin Gutib <rougingutib@gmail.com>
 */
class FinalCallback
{
    const RESPONSE = 'Psr\Http\Message\ResponseInterface';

    /**
     * @var \Rougin\Slytherin\Container\Container
     */
    protected $container;

    /**
     * @var \Psr\Http\Message\ResponseInterface|mixed
     */
    protected $function;

    /**
     * Sets up the callback handler.
     *
     * @param \Rougin\Slytherin\Container\Container     $container
     * @param \Psr\Http\Message\ResponseInterface|mixed $function
     */
    public function __construct(Container $container, $function)
    {
        $this->container = $container;

        $this->function = $function;
    }

    /**
     * Returns a callback for handling the application.
     *
     * @param  \Psr\Http\Message\ServerRequestInterface $request
     * @return callback
     */
    public function __invoke(ServerRequestInterface $request)
    {
        if (is_array($this->function) === true) {
            $function = $this->function;

            if (is_array($function[0]) && is_string($function[0][0])) {
                $function[0][0] = $this->container->resolve($function[0][0], $request);

                $reflector = new \ReflectionMethod($function[0][0], $function[0][1]);
            } else {
                $reflector = new \ReflectionFunction($function[0]);
            }

            $function[1] = $this->container->arguments($reflector, $function[1]);

            $this->function = call_user_func_array($function[0], $function[1]);
        }

        return $this->finalize($this->function);
    }

    /**
     * Converts the result into a \Psr\Http\Message\ResponseInterface instance.
     *
     * @param  \Psr\Http\Message\ResponseInterface|mixed $function
     * @return \Psr\Http\Message\ResponseInterface
     */
    protected function finalize($function)
    {
        $response = $this->container->get(self::RESPONSE);

        if (is_string($function) === true) {
            $stream = $response->getBody();

            $stream->write((string) $function);
        }

        $instanceof = $function instanceof ResponseInterface;

        return $instanceof ? $function : $response;
    }
}


<?php

namespace Rougin\Slytherin\Application;

use Psr\Container\ContainerInterface;
use Psr\Http\Message\ServerRequestInterface;
use Rougin\Slytherin\Container\Container;
use Rougin\Slytherin\Middleware\Delegate;
use Rougin\Slytherin\Middleware\Dispatcher;

/**
 * Callback Handler
 *
 * Handles the final callback to be used in the application.
 *
 * @package Slytherin
 * @author  Rougin Gutib <rougingutib@gmail.com>
 */
class CallbackHandler
{
    const DISPATCHER = 'Rougin\Slytherin\Routing\DispatcherInterface';

    const ROUTER = 'Rougin\Slytherin\Routing\RouterInterface';

    const RESPONSE = 'Psr\Http\Message\ResponseInterface';

    /**
     * @var \Rougin\Slytherin\Application\FinalCallback
     */
    protected $callback;

    /**
     * @var \Rougin\Slytherin\Container\Container
     */
    protected $container;

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

    /**
     * Initializes the handler instance.
     *
     * @param \Psr\Container\ContainerInterface $container
     */
    public function __construct(ContainerInterface $container)
    {
        $this->container = new Container(array(), $container);
    }

    /**
     * Returns a response instance.
     *
     * @param  \Psr\Http\Message\ServerRequestInterface $request
     * @return callback
     */
    public function __invoke(ServerRequestInterface $request)
    {
        $dispatcher = $this->container->get(self::DISPATCHER);

        if ($this->container->has(self::ROUTER) === true) {
            $router = $this->container->get(self::ROUTER);

            $dispatcher = $dispatcher->router($router);
        }

        $path = $request->getUri()->getPath();

        $method = $request->getMethod();

        $result = $dispatcher->dispatch($method, $path);

        $this->middlewares = $result[1];

        $callback = new FinalCallback($this->container, $result[0]);

        return $this->middleware($callback, $request);
    }

    /**
     * Dispatches the middlewares of the specified request, if there are any.
     *
     * @param  \Rougin\Slytherin\Application\FinalCallback $callback
     * @param  \Psr\Http\Message\ServerRequestInterface    $request
     * @return \Psr\Http\Message\ResponseInterface|null
     */
    protected function middleware(FinalCallback $callback, ServerRequestInterface $request)
    {
        $response = $this->container->get(self::RESPONSE);

        if (interface_exists(Application::MIDDLEWARE) === true) {
            $middleware = new Dispatcher($this->middlewares, $response);

            $delegate = new Delegate($callback);

            $result = $middleware->process($request, $delegate);
        }

        return isset($result) ? $result : $callback($request);
    }
}


<?php

namespace Rougin\Slytherin\Middleware;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Rougin\Slytherin\Middleware\HandlerInterface;

/**
 * Callable Middleware Wrapper
 *
 * Converts callables into PSR-15 middlewares.
 *
 * @package Slytherin
 * @author  Rougin Gutib <rougingutib@gmail.com>
 * @author  Rasmus Schultz <rasmus@mindplay.dk>
 */
class CallableMiddlewareWrapper implements MiddlewareInterface
{
    /**
     * @var callable
     */
    protected $middleware;

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

    /**
     * Initializes the middleware instance.
     *
     * @param callable                                 $middleware
     * @param \Psr\Http\Message\ResponseInterface|null $response
     */
    public function __construct($middleware, ResponseInterface $response = null)
    {
        $this->middleware = $middleware;

        $this->response = $response;
    }

    /**
     * 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)
    {
        $middleware = $this->middleware;

        if ($this->response !== null)
        {
            $handler = function ($request) use ($handler)
            {
                return $handler->{HANDLER_METHOD}($request);
            };

            $response = $this->response;

            return $middleware($request, $response, $handler);
        }

        return $middleware($request, $handler);
    }
}


<?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\Number;
use \Malenki\Math\Unit\Angle;

/**
 * Complex number
 *
 * Complex numbers are defined by default using real part `a` and imaginary
 * part `bi` like that: `a+bi`.
 *
 * But this class allows you to use polar form too, using `rho` and `theta`
 * values (length and angle).
 *
 * @property-read float $real The real part
 * @property-read float $re 2nd way to get real part
 * @property-read float $r 3rd way to get real part
 * @property-read float $imaginary The imaginary part
 * @property-read float $im 2nd way to get imaginary part
 * @property-read float $i 3rd way to get imaginary part
 * @property-read float $rho 1st way to get rho, aka norm, aka modulus
 * @property-read float $modulus 2nd way to get rho
 * @property-read float $norm 3rd way to get rho
 * @property-read float $theta 1st way to get theta, aka arg, aka argument
 * @property-read float $arg 2nd way to get theta
 * @property-read float $argument 3rd way to get tehta
 * @property-read float $conjugate gets the conjugate number for the curent complex number
 * @property-read float $negative gets the negative of the current number
 * @property-read boolean $is_zero Tells if complex number is zero or not
 * @author Michel Petit <petit.michel@gmail.com>
 * @license MIT
 */
class Complex
{
    const ALGEBRAIC = '1';
    const TRIGONOMETRIC = '2';

    /**
     * Stores real part
     *
     * @var float
     * @access protected
     */
    protected $float_r = 0;

    /**
     * Stores imaginary part.
     *
     * @var float
     * @access protected
     */
    protected $float_i = 0;

    /**
     * If complex is created from trigonometric form, stores original values
     * inside this attribute.
     *
     * @var mixed
     * @access protected
     */
    protected $original = null;

    /**
     * Defines some magick getters for real and imaginary parts, rho and theta too.
     *
     * @param  string $name
     * @access public
     * @return float
     */
    public function __get($name)
    {
        if (in_array($name, array('real', 'r', 're'))) {
            return $this->float_r;
        }

        if (in_array($name, array('imaginary', 'i', 'im'))) {
            return $this->float_i;
        }

        if (in_array($name, array('rho', 'modulus', 'norm'))) {
            return $this->modulus();
        }

        if (in_array($name, array('theta', 'arg', 'argument'))) {
            return $this->argument();
        }

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

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

    }

    /**
     * Creates new Complex number object giving its real and imaginary parts or
     * rho and theta.
     *
     * For trigonometric form, the second argument can be a Malenki\Math\Angle
     * object, and then, the third argument is useless.
     *
     * @param  mixed   $float_a       Number for the real part if type is algebraic, rho otherwise.
     * @param  mixed   $mix_b         Number for the imaginary part if type is algebraic, theta otherwise. Can be an Angle object
     * @param  integer $int_type      Either Complex::ALGEBRAIC (default) or Complex::TRIGONOMETRIC
     * @param  integer $int_precision Round precision, deafult fixed at 5.
     * @access public
     * @return Complex
     */
    public function __construct($float_a, $mix_b, $int_type = self::ALGEBRAIC, $int_precision = 5)
    {
        if ($mix_b instanceof Angle) {
            $int_type = self::TRIGONOMETRIC;
        }

        if ($int_type == self::ALGEBRAIC) {
            if (!is_numeric($float_a) || !is_numeric($mix_b)) {
                throw new \InvalidArgumentException('Real and Imaginary parts must be valid real numbers.');
            }

            $this->float_r = $float_a;
            $this->float_i = $mix_b;
        } else {
            if (!is_numeric($float_a)) {
                throw new \InvalidArgumentException('Rho must be valid real numbers.');
            }

            if ($float_a < 0) {
                throw new \InvalidArgumentException('Rho must be positive or null.');
            }

            if (!(is_numeric($mix_b)||$mix_b instanceof Angle)) {
                throw new \InvalidArgumentException('Theta must be valid real numbers or an instance of Angle class.');
            }

            if ($mix_b instanceof Angle) {
                $mix_b = $mix_b->rad;
            }

            $this->float_r = round($float_a * cos($mix_b), $int_precision);
            $this->float_i = round($float_a * sin($mix_b), $int_precision);

            $this->original = new \stdClass();
            $this->original->rho = $float_a;
            $this->original->theta = $mix_b;
        }

    }

    public function isZero()
    {
        return $this->float_r == 0 && $this->float_i == 0;
    }

    /**
     * Computes and returns the norm.
     *
     * @access public
     * @return float
     */
    public function norm()
    {
        if ($this->original) {
            return $this->original->rho;
        }

        return sqrt(pow($this->float_r, 2) + pow($this->float_i, 2));
    }

    /**
     * Gets the complex's modulus.
     *
     * It is same mathod as `norm()`;
     * @access public
     * @return float
     */
    public function modulus()
    {
        return $this->norm();
    }

    /**
     * Computes and returns the argument.
     *
     * @access public
     * @return float
     */
    public function argument()
    {
        if ($this->original) {
            return $this->original->theta;
        }

        return atan2($this->float_i, $this->float_r);
    }

    /**
     * Return conjugate complex number for the current one.
     *
     * @access public
     * @return Complex
     */
    public function conjugate()
    {
        return new self($this->float_r, -1 * $this->float_i);
    }

    /**
     * Gives the negative Complex number of the current one.
     *
     * @access public
     * @return Complex
     */
    public function negative()
    {
        return new self(-1 * $this->float_r, -1 * $this->float_i);
    }

    /**
     * Add value to the current complex number, creating new complex number.
     *
     * @param  mixed   $z Complex or real number
     * @access public
     * @return Complex
     */
    public function add($z)
    {
        if (is_numeric($z)) {
            $z = new self($z, 0);
        }

        return new self($this->float_r + $z->re, $this->float_i + $z->im);
    }

    /**
     * Substracts complex number `z` from the current one.
     *
     * @param  mixed   $z Complex or real number
     * @access public
     * @return Complex
     */
    public function substract($z)
    {
        if (is_numeric($z)) {
            $z = new self($z, 0);
        }

        return $this->add($z->negative());
    }

    /**
     * Multiplies current complex number with another.
     *
     * @param  mixed   $z Complex or real number
     * @access public
     * @return Complex
     */
    public function multiply($z)
    {
        if (is_numeric($z)) {
            $z = new self($z, 0);
        }

        return new self(
            ($this->float_r * $z->re) - ($this->float_i * $z->im),
            ($this->float_r * $z->im) + ($z->re * $this->float_i)
        );
    }

    /**
     * Divides current complex number with another.
     *
     * @throw \InvalidArgumentException If argument is zero
     * @param  mixed   $z Complex or real number
     * @access public
     * @return Complex
     */
    public function divide($z)
    {
        if (is_numeric($z)) {
            $z = new self($z, 0);
        }

        if ($z->is_zero) {
            throw new \InvalidArgumentException('Cannot divide by zero!');
        }

        $divisor = pow($z->re, 2) + pow($z->im, 2);

        $r = ($this->float_r * $z->re) + ($this->float_i * $z->im);
        $i = ($this->float_i * $z->re) - ($this->float_r * $z->im);
        $r = $r / $divisor;
        $i = $i / $divisor;

        return new self( $r, $i);
    }

    /**
     * Tests whether given `z` complex number is equal to the current complex
     * number.
     *
     * @param  mixed   $z Complex or real number
     * @access public
     * @return boolean
     */
    public function equal($z)
    {
        if (is_numeric($z)) {
            $z = new self($z, 0);
        }

        return ($z->real == $this->float_r) && ($z->imaginary == $this->float_i);
    }

    /**
     * In string context, display complex number as algebraic form or trigonometric form.
     *
     * In string context, display complex number into the form `a+ib` if it has
     * been instanciated using algebraic form or into the form `ρ(cosθ+isinθ)`
     * for the trigonometric form.
     *
     * @access public
     * @return string
     */
    public function __toString()
    {
        // if trigo…
        if ($this->original) {
            if ($this->norm() == 0) {
                return 0;
            }
            if ($this->norm() == 1) {
                return sprintf('cos %1$f + i⋅sin %1$f', $this->argument());
            }

            return sprintf('%1$f(cos %2$f + i⋅sin %2$f)', $this->norm(), $this->argument());
        }

        $str_sign = '-';
        $str_re = '';
        $str_im = 'i';

        if ($this->float_i > 0) {
            $str_sign = '+';
        }

        if (abs($this->float_i) > 1) {
            $str_im = (string) abs($this->float_i) . 'i';
        }

        if ($this->float_i == 0) {
            return (string) $this->float_r;
        }

        if ($this->float_r == 0) {
            if (abs($this->float_i) == 1) {
                return $this->float_i == 1 ? 'i' : '-i';
            } else {
                return (string) $this->float_i . 'i';
            }
        } else {
            $str_re = (string) $this->float_r;
        }

        $arr = array();
        $arr[] = $str_re;
        $arr[] = $str_im;

        return implode($str_sign, $arr);
    }
}


<?php

namespace Rougin\Slytherin\Http;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Rougin\Slytherin\Container\ContainerInterface;
use Rougin\Slytherin\Http\Response;
use Rougin\Slytherin\Http\ServerRequest;
use Rougin\Slytherin\Integration\Configuration;
use Rougin\Slytherin\Integration\IntegrationInterface;
use Zend\Diactoros\Response as ZendResponse;
use Zend\Diactoros\ServerRequestFactory;

/**
 * HTTP Integration
 *
 * An integration for Slytherin's simple HTTP package.
 *
 * @package Slytherin
 * @author  Rougin Gutib <rougingutib@gmail.com>
 */
class HttpIntegration 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)
    {
        list($server, $cookies, $get, $files, $post) = $this->globals($config);

        $headers = (array) $this->headers($server);

        $request = new ServerRequest($server, $cookies, $get, $files, $post);

        foreach ($headers as $key => $value) {
            $request = $request->withHeader($key, $value);
        }

        return $this->resolve($container, $request, new Response);
    }

    /**
     * Returns the PHP's global variables.
     *
     * @param  \Rougin\Slytherin\Integration\Configuration $config
     * @return array
     */
    protected function globals(Configuration $config)
    {
        $cookies = $config->get('app.http.cookies', array());

        $files = $config->get('app.http.files', array());

        $get = $config->get('app.http.get', array());

        $post = $config->get('app.http.post', array());

        $server = $config->get('app.http.server', $this->server());

        return array($server, $cookies, $get, $files, $post);
    }

    /**
     * Converts $_SERVER parameters to message header values.
     *
     * @param  array $server
     * @return array
     */
    protected function headers(array $server)
    {
        $headers = array();

        foreach ((array) $server as $key => $value) {
            $http = strpos($key, 'HTTP_') === 0;

            $string = strtolower(substr($key, 5));

            $string = str_replace('_', ' ', $string);

            $string = ucwords(strtolower($string));

            $key = str_replace(' ', '-', $string);

            $http && $headers[$key] = $value;
        }

        return $headers;
    }

    /**
     * Checks on what object will be defined to container.
     *
     * @param  \Rougin\Slytherin\Container\ContainerInterface $container
     * @param  \Psr\Http\Message\ServerRequestInterface       $request
     * @param  \Psr\Http\Message\ResponseInterface            $response
     * @return \Rougin\Slytherin\Container\ContainerInterface
     */
    protected function resolve(ContainerInterface $container, ServerRequestInterface $request, ResponseInterface $response)
    {
        if (class_exists('Zend\Diactoros\ServerRequestFactory')) {
            $response = new ZendResponse;

            $request = ServerRequestFactory::fromGlobals();
        }

        $container->set('Psr\Http\Message\ServerRequestInterface', $request);

        return $container->set('Psr\Http\Message\ResponseInterface', $response);
    }

    /**
     * Returns a sample $_SERVER values.
     *
     * @return array
     */
    protected function server()
    {
        $server = array('SERVER_PORT' => 8000);

        $server['REQUEST_METHOD'] = 'GET';

        $server['REQUEST_URI'] = '/';

        $server['SERVER_NAME'] = 'localhost';

        $server['HTTP_CONTENT_TYPE'] = 'text/plain';

        return $server;
    }
}


<?php

namespace Rougin\Slytherin;

use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Rougin\Slytherin\Application\CallbackHandler;
use Rougin\Slytherin\Container\Container;
use Rougin\Slytherin\Integration\ConfigurationInterface;
use Rougin\Slytherin\Middleware\Delegate;

/**
 * Application
 *
 * Integrates all specified components into the application.
 *
 * @package Slytherin
 * @author  Rougin Gutib <rougingutib@gmail.com>
 */
class Application
{
    // NOTE: To be removed in v1.0.0
    const ERROR_HANDLER = 'Rougin\Slytherin\Debug\ErrorHandlerInterface';

    const MIDDLEWARE = 'Rougin\Slytherin\Middleware\MiddlewareInterface';

    const SERVER_REQUEST = 'Psr\Http\Message\ServerRequestInterface';

    /**
     * @var \Rougin\Slytherin\Integration\ConfigurationInterface
     */
    protected $config;

    /**
     * @var \Psr\Container\ContainerInterface
     */
    protected static $container;

    /**
     * Initializes the application instance.
     *
     * @param \Psr\Container\ContainerInterface|null                    $container
     * @param \Rougin\Slytherin\Integration\ConfigurationInterface|null $config
     */
    public function __construct(ContainerInterface $container = null, ConfigurationInterface $config = null)
    {
        $this->config = $config === null ? new Configuration : $config;

        static::$container = $container === null ? new Container : $container;
    }

    /**
     * Returns the static instance of the specified container.
     *
     * @return \Psr\Container\ContainerInterface
     */
    public static function container()
    {
        return static::$container;
    }

    /**
     * Handles the ServerRequestInterface to convert it to a ResponseInterface.
     *
     * @param  \Psr\Http\Message\ServerRequestInterface $request
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function handle(ServerRequestInterface $request)
    {
        $callback = new CallbackHandler(self::$container);

        if (static::$container->has(self::MIDDLEWARE)) {
            $middleware = static::$container->get(self::MIDDLEWARE);

            $delegate = new Delegate($callback);

            $result = $middleware->process($request, $delegate);
        }

        return isset($result) ? $result : $callback($request);
    }

    /**
     * Adds the specified integrations to the container.
     *
     * @param  \Rougin\Slytherin\Integration\IntegrationInterface|array|string $integrations
     * @param  \Rougin\Slytherin\Integration\ConfigurationInterface|null       $config
     * @return self
     */
    public function integrate($integrations, ConfigurationInterface $config = null)
    {
        list($config, $container) = array($config ?: $this->config, static::$container);

        foreach ((array) $integrations as $item) {
            $integration = is_string($item) ? new $item : $item;

            $container = $integration->define($container, $config);
        }

        static::$container = $container;

        return $this;
    }

    /**
     * Emits the headers from response and runs the application.
     *
     * @return void
     */
    public function run()
    {
        // NOTE: To be removed in v1.0.0. Use "ErrorHandlerIntegration" instead.
        if (static::$container->has(self::ERROR_HANDLER)) {
            $debugger = static::$container->get(self::ERROR_HANDLER);

            $debugger->display();
        }

        $request = static::$container->get(self::SERVER_REQUEST);

        echo (string) $this->emit($request)->getBody();
    }

    /**
     * Emits the headers based from the response.
     * NOTE: To be removed in v1.0.0. Should be included in run().
     *
     * @param  \Psr\Http\Message\ServerRequestInterface $request
     * @return \Psr\Http\Message\ResponseInterface
     */
    protected function emit(ServerRequestInterface $request)
    {
        $response = $this->handle($request);

        $code = (string) $response->getStatusCode();

        $code .= ' ' . $response->getReasonPhrase();

        $headers = (array) $response->getHeaders();

        $version = $response->getProtocolVersion();

        header('HTTP/' . $version . ' ' . $code);

        foreach ($headers as $name => $values) {
            $value = (string) implode(',', $values);

            header((string) $name . ': ' . $value);
        }

        return $response;
    }
}


<?php

namespace Rougin\Slytherin\Debug;

use Whoops\Handler\PrettyPageHandler;
use Whoops\Run;

/**
 * Whoops Error Handler
 *
 * A simple implementation of an error handler built on top of Filipe Dobreira's
 * Whoops. NOTE: To be removed in v1.0.0. Use "ErrorHandlerIntegration" instead.
 *
 * http://filp.github.io/whoops
 *
 * @package Slytherin
 * @author  Rougin Gutib <rougingutib@gmail.com>
 */
class WhoopsErrorHandler implements ErrorHandlerInterface
{
    /**
     * @var string
     */
    protected $environment = '';

    /**
     * @var \Whoops\Run
     */
    protected $whoops;

    /**
     * @param \Whoops\Run $whoops
     * @param string      $environment
     */
    public function __construct(Run $whoops, $environment = 'development')
    {
        $this->environment = $environment;

        $this->whoops = $whoops;
    }

    /**
     * Sets up the environment to be used.
     * NOTE: To be removed in v1.0.0.
     *
     * @param  string $environment
     * @return self
     */
    public function setEnvironment($environment)
    {
        $this->environment = $environment;

        return $this;
    }

    /**
     * Gets the specified environment.
     * NOTE: To be removed in v1.0.0.
     *
     * @return string
     */
    public function getEnvironment()
    {
        return $this->environment;
    }

    /**
     * Returns a listing of handlers.
     * NOTE: To be removed in v1.0.0. Use __call() instead.
     *
     * @return \Whoops\Handler\HandlerInterface[]
     */
    public function getHandlers()
    {
        return $this->whoops->getHandlers();
    }

    /**
     * Registers the instance as an error handler.
     *
     * @return mixed
     */
    public function display()
    {
        $handler = new PrettyPageHandler;

        error_reporting(E_ALL);

        $this->__call('pushHandler', array($handler));

        return $this->whoops->register();
    }

    /**
     * Sets a handler.
     * NOTE: To be removed in v1.0.0. Use __call() instead.
     *
     * @param \Whoops\Handler\HandlerInterface|callable $handler
     */
    public function setHandler($handler)
    {
        $this->whoops->pushHandler($handler);
    }

    /**
     * Calls methods from the \Whoops\Run instance.
     *
     * @param  string $method
     * @param  mixed  $parameters
     * @return mixed
     */
    public function __call($method, $parameters)
    {
        $instance = array($this->whoops, $method);

        return call_user_func_array($instance, $parameters);
    }
}


<?php

namespace Rougin\Slytherin\Middleware;

use Psr\Http\Message\ResponseInterface;
use Rougin\Slytherin\Container\ContainerInterface;
use Rougin\Slytherin\Integration\Configuration;
use Rougin\Slytherin\Integration\IntegrationInterface;
use Zend\Stratigility\MiddlewarePipe;

/**
 * Middleware Integration
 *
 * An integration for Slytherin's Middleware packages.
 *
 * @package Slytherin
 * @author  Rougin Gutib <rougingutib@gmail.com>
 */
class MiddlewareIntegration 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)
    {
        $response = $container->get('Psr\Http\Message\ResponseInterface');

        $stack = $config->get('app.middlewares', array());

        $dispatcher = $this->dispatcher($response, $stack);

        $interface = 'Rougin\Slytherin\Middleware\MiddlewareInterface';

        return $container->set($interface, $dispatcher);
    }

    /**
     * Returns the middleware dispatcher to be used.
     *
     * @param  \Psr\Http\Message\ResponseInterface $response
     * @param  array                               $stack
     * @return \Rougin\Slytherin\Middleware\DispatcherInterface
     */
    protected function dispatcher(ResponseInterface $response, $stack)
    {
        $dispatcher = new Dispatcher($stack, $response);

        if (class_exists('Zend\Stratigility\MiddlewarePipe')) {
            $pipe = new MiddlewarePipe;

            $dispatcher = new StratigilityDispatcher($pipe, $stack, $response);
        }

        return $dispatcher;
    }
}


<?php

namespace Rougin\Slytherin\Integration;

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

/**
 * Configuration Integration
 *
 * Integrates Configuration inside the specified container.
 *
 * @package Slytherin
 * @author  Rougin Gutib <rougingutib@gmail.com>
 */
class ConfigurationIntegration 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)
    {
        $container->set('Rougin\Slytherin\Configuration', $config);

        $container->set('Rougin\Slytherin\Integration\Configuration', $config);

        return $container;
    }
}