HEX
Server: Apache
System: Linux vmi318001.contaboserver.net 6.8.0-117-generic #117-Ubuntu SMP PREEMPT_DYNAMIC Tue May 5 19:26:24 UTC 2026 x86_64
User: boxelikax (1004)
PHP: 8.2.33
Disabled: NONE
Upload Files
File: /home/boxelikax/public_html/demoltec.com/clue.zip
PK�]"6�f*f*#phar-composer/src/Phar/Packager.phpnu�[���<?php

namespace Clue\PharComposer\Phar;

use Symfony\Component\Process\Process;
use Symfony\Component\Process\ExecutableFinder;
use UnexpectedValueException;
use InvalidArgumentException;
use RuntimeException;
use Symfony\Component\Console\Output\OutputInterface;
use Clue\PharComposer\Package\Package;

class Packager
{
    const PATH_BIN = '/usr/local/bin';

    private $output;
    private $binSudo = 'sudo';

    public function __construct()
    {
        $this->setOutput(true);
    }

    private function log($message)
    {
        $fn = $this->output;
        $fn($message . PHP_EOL);
    }

    public function setBinSudo($bin)
    {
        $this->binSudo = $bin;
    }

    /**
     * @param OutputInterface|bool|callable $fn
     */
    public function setOutput($fn)
    {
        if ($fn instanceof OutputInterface) {
            $fn = function ($line) use ($fn) {
                $fn->write($line);
            };
        } elseif ($fn === true) {
            $fn = function ($line) {
                echo $line;
            };
        } elseif ($fn === false) {
            $fn = function () { };
        }
        $this->output = $fn;
    }

    /**
     * ensure writing phar files is enabled or respawn with PHP setting which allows writing
     *
     * @param int $wait
     * @return void
     * @uses assertWritable()
     */
    public function coerceWritable($wait = 1)
    {
        try {
            $this->assertWritable();
        }
        catch (UnexpectedValueException $e) {
            if (!function_exists('pcntl_exec')) {
                $this->log('<error>' . $e->getMessage() . '</error>');
                return;
            }

            $this->log('<info>' . $e->getMessage() . ', trying to re-spawn with correct config</info>');
            if ($wait) {
                sleep($wait);
            }

            $args = array_merge(array('php', '-d phar.readonly=off'), $_SERVER['argv']);
            if (pcntl_exec('/usr/bin/env', $args) === false) {
                $this->log('<error>Unable to switch into new configuration</error>');
                return;
            }
        }
    }

    /**
     * ensure writing phar files is enabled or throw an exception
     *
     * @throws UnexpectedValueException
     */
    public function assertWritable()
    {
        if (ini_get('phar.readonly') === '1') {
            throw new UnexpectedValueException('Your configuration disabled writing phar files (phar.readonly = On), please update your configuration or run with "php -d phar.readonly=off ' . $_SERVER['argv'][0].'"');
        }
    }

    /**
     * @param string $path
     * @param string $version
     * @return PharComposer
     * @throws UnexpectedValueException
     * @throws InvalidArgumentException
     * @throws RuntimeException
     */
    public function getPharer($path, $version = null)
    {
        if ($version !== null) {
            // TODO: should be the other way around
            $path .= ':' . $version;
        }

        $step = 1;
        $steps = 1;

        if ($this->isPackageUrl($path)) {
            $url = $path;
            $version = null;
            $steps = 3;

            if (preg_match('/(.+)\:((?:dev\-|v\d)\S+)$/i', $url, $match)) {
                $url = $match[1];
                $version = $match[2];
                if (substr($version, 0, 4) === 'dev-') {
                    $version = substr($version, 4);
                }
            }


            $path = $this->getDirTemporary();

            $finder = new ExecutableFinder();

            $git = escapeshellarg($finder->find('git', 'git'));

            $that = $this;
            $this->displayMeasure(
                '[' . $step++ . '/' . $steps.'] Cloning <info>' . $url . '</info> into temporary directory <info>' . $path . '</info>',
                function() use ($that, $url, $path, $version, $git) {
                    $that->exec($git . ' clone ' . escapeshellarg($url) . ' ' . escapeshellarg($path));

                    if ($version !== null) {
                        $this->exec($git . ' checkout ' . escapeshellarg($version) . ' 2>&1', $path);
                    }
                },
                'Cloning base repository completed'
            );

            $pharcomposer = new PharComposer($path . '/composer.json');
            $package = $pharcomposer->getPackageRoot()->getName();

            if (is_file('composer.phar')) {
                $command = escapeshellarg($finder->find('php', 'php')) . ' composer.phar';
            } else {
                $command = escapeshellarg($finder->find('composer', 'composer'));
            }
            $command .= ' install --no-dev --no-progress --no-scripts';

            $this->displayMeasure(
                '[' . $step++ . '/' . $steps.'] Installing dependencies for <info>' . $package . '</info> into <info>' . $path . '</info> (using <info>' . $command . '</info>)',
                function () use ($that, $command, $path) {
                    try {
                        $that->exec($command, $path);
                    }
                    catch (UnexpectedValueException $e) {
                        throw new UnexpectedValueException('Installing dependencies via composer failed', 0, $e);
                    }
                },
                'Downloading dependencies completed'
            );
        } elseif ($this->isPackageName($path)) {
            if (is_dir($path)) {
                $this->log('<info>There\'s also a directory with the given name</info>');
            }
            $steps = 2;
            $package = $path;

            $path = $this->getDirTemporary();

            $finder = new ExecutableFinder();
            if (is_file('composer.phar')) {
                $command = escapeshellarg($finder->find('php', 'php')) . ' composer.phar';
            } else {
                $command = escapeshellarg($finder->find('composer', 'composer'));
            }
            $command .= ' create-project ' . escapeshellarg($package) . ' ' . escapeshellarg($path) . ' --no-dev --no-progress --no-scripts';

            $that = $this;
            $this->displayMeasure(
                '[' . $step++ . '/' . $steps.'] Installing <info>' . $package . '</info> to temporary directory <info>' . $path . '</info> (using <info>' . $command . '</info>)',
                function () use ($that, $command) {
                    try {
                        $that->exec($command);
                    }
                    catch (UnexpectedValueException $e) {
                        throw new UnexpectedValueException('Installing package via composer failed', 0, $e);
                    }
                },
                'Downloading package completed'
            );
        }

        if (is_dir($path)) {
            $path = rtrim($path, '/') . '/composer.json';
        }
        if (!is_file($path)) {
            throw new InvalidArgumentException('The given path "' . $path . '" is not a readable file');
        }

        $pharer = new PharComposer($path);
        $pharer->setOutput($this->output);
        $pharer->setStep($step);

        $pathVendor = $pharer->getPackageRoot()->getDirectory() . $pharer->getPackageRoot()->getPathVendor();
        if (!is_dir($pathVendor)) {
            throw new RuntimeException('Project is not installed via composer. Run "composer install" manually');
        }

        return $pharer;
    }

    public function measure($fn)
    {
        $time = microtime(true);

        $fn();

        return max(microtime(true) - $time, 0);
    }

    public function displayMeasure($title, $fn, $success)
    {
        $this->log($title);

        $time = $this->measure($fn);

        $this->log('');
        $this->log('    <info>OK</info> - ' . $success .' (after ' . round($time, 1) . 's)');
    }

    /**
     * @param string $cmd
     * @param ?string $chdir
     * @return void
     * @throws UnexpectedValueException
     */
    public function exec($cmd, $chdir = null)
    {
        $nl = true;

        //
        $output = $this->output;

        // Symfony 5+ requires 'fromShellCommandline', older versions support direct instantiation with command line
        // @codeCoverageIgnoreStart
        try {
            new \ReflectionMethod('Symfony\Component\Process\Process', 'fromShellCommandline');
            $process = Process::fromShellCommandline($cmd, $chdir);
        } catch (\ReflectionException $e) {
            $process = new Process($cmd, $chdir);
        }
        // @codeCoverageIgnoreEnd

        $process->setTimeout(null);
        $code = $process->run(function($type, $data) use ($output, &$nl) {
            if ($nl === true) {
                $data = PHP_EOL . $data;
                $nl = false;
            }
            if (substr($data, -1) === "\n") {
                $nl = true;
                $data = substr($data, 0, -strlen(PHP_EOL));
            }
            $data = str_replace("\n", "\n    ", $data);

            $output($data);
        });
        if ($nl) {
            $this->log('');
        }

        if ($code !== 0) {
            throw new UnexpectedValueException('Error status code: ' . $process->getExitCodeText() . ' (code ' . $code . ')');
        }
    }

    public function install(PharComposer $pharer, $path)
    {
        $pharer->build();

        $this->log('Move resulting phar to <info>' . $path . '</info>');
        $this->exec($this->binSudo . ' -- mv -f ' . escapeshellarg($pharer->getTarget()) . ' ' . escapeshellarg($path));

        $this->log('');
        $this->log('    <info>OK</info> - Moved to <info>' . $path . '</info>');
    }

    /**
     * @param Package $package
     * @param ?string $path
     * @return string
     */
    public function getSystemBin(Package $package, $path = null)
    {
        // no path given => place in system bin path
        if ($path === null) {
            $path = self::PATH_BIN;
        }

        // no slash => path is relative to system bin path
        if (strpos($path, '/') === false) {
            $path = self::PATH_BIN . '/' . $path;
        }

        // path is actually a directory => append package name
        if (is_dir($path)) {
            $path = rtrim($path, '/') . '/' . $package->getShortName();
        }

        return $path;
    }

    private function isPackageName($path)
    {
        return !!preg_match('/^[^\s\/]+\/[^\s\/]+(\:[^\s]+)?$/i', $path);
    }

    public function isPackageUrl($path)
    {
        return (strpos($path, '://') !== false && @parse_url($path) !== false) || preg_match('/^[^-\/\s][^:\/\s]*:[^\s\\\\]\S*/', $path);
    }

    private function getDirTemporary()
    {
        $path = sys_get_temp_dir() . '/phar-composer' . mt_rand(0,9);
        while (is_dir($path)) {
            $path .= mt_rand(0, 9);
        }

        return $path;
    }
}
PK�]'B٩�%phar-composer/src/Phar/TargetPhar.phpnu�[���<?php

namespace Clue\PharComposer\Phar;

use Clue\PharComposer\Package\Bundle;

/**
 * Represents the target phar to be created.
 */
class TargetPhar
{
    /** @var \Phar */
    private $phar;

    /** @var  PharComposer */
    private $pharComposer;

    public function __construct(\Phar $phar, PharComposer $pharComposer)
    {
        $phar->startBuffering();
        $this->phar = $phar;
        $this->pharComposer = $pharComposer;
    }

    /**
     * finalize writing of phar file
     */
    public function stopBuffering()
    {
        $this->phar->stopBuffering();
    }

    /**
     * adds given list of resources to phar
     *
     * @param  Bundle  $bundle
     */
    public function addBundle(Bundle $bundle)
    {
        foreach ($bundle as $resource) {
            if (is_string($resource)) {
                $this->addFile($resource);
            } else {
                $this->buildFromIterator($resource);
            }
        }
    }

     /**
     * Adds a file to the Phar
     *
     * @param string $file  The file name.
     */
    public function addFile($file)
    {
        $this->phar->addFile($file, $this->pharComposer->getPathLocalToBase($file));
    }

    public function buildFromIterator(\Traversable $iterator)
    {
        $this->phar->buildFromIterator($iterator, $this->pharComposer->getPackageRoot()->getDirectory());
    }

    /**
     * Used to set the PHP loader or bootstrap stub of a Phar archive
     *
     * @param  string $stub
     */
    public function setStub($stub)
    {
        $this->phar->setStub($stub);
    }

    public function addFromString($local, $contents)
    {
        $this->phar->addFromString($local, $contents);
    }
}
PK�]��>�#�#'phar-composer/src/Phar/PharComposer.phpnu�[���<?php

namespace Clue\PharComposer\Phar;

use Clue\PharComposer\Logger;
use Clue\PharComposer\Package\Package;
use Clue\PharComposer\Box\StubGenerator;

/**
 * The PharComposer is responsible for collecting options and then building the target phar
 */
class PharComposer
{
    private $package;
    private $main = null;
    private $target = null;
    private $logger;
    private $step = '?';

    /**
     * @param string $path path to composer.json file
     * @throws \InvalidArgumentException when given $path can not be parsed as JSON
     */
    public function __construct($path)
    {
        $this->package = new Package($this->loadJson($path), dirname(realpath($path)));
        $this->logger = new Logger();
    }

    /**
     * set output function to use to output log messages
     *
     * @param callable|boolean $output callable that receives a single $line argument or boolean echo
     */
    public function setOutput($output)
    {
        $this->logger->setOutput($output);
    }

    /**
     * Get path to target phar file (absolute path or relative to current directory)
     *
     * @return string
     */
    public function getTarget()
    {
        if ($this->target === null) {
            $this->target = $this->package->getShortName() . '.phar';
        }
        return $this->target;
    }

    /**
     * Set path to target phar file (absolute path or relative to current directory)
     *
     * If the given path is a directory, the default target (package short name)
     * will be appended automatically.
     *
     * @param string $target
     * @return $this
     */
    public function setTarget($target)
    {
        // path is actually a directory => append package name
        if (is_dir($target)) {
            $this->target = null;
            $target = rtrim($target, '/') . '/' . $this->getTarget();
        }
        $this->target = $target;
        return $this;
    }

    /**
     * Get path to main bin (relative to package directory)
     *
     * @return string
     * @throws \UnexpectedValueException
     */
    public function getMain()
    {
        if ($this->main === null) {
            foreach ($this->package->getBins() as $path) {
                if (!file_exists($this->package->getDirectory() . $path)) {
                    throw new \UnexpectedValueException('Bin file "' . $path . '" does not exist');
                }
                $this->main = $path;
                break;
            }
        }
        return $this->main;
    }

    /**
     * set path to main bin (relative to package directory)
     *
     * @param string $main
     * @return $this
     */
    public function setMain($main)
    {
        $this->main = $main;
        return $this;
    }

    /**
     *
     * @return Package
     */
    public function getPackageRoot()
    {
        return $this->package;
    }

    /**
     *
     * @return Package[]
     */
    public function getPackagesDependencies()
    {
        $packages = array();

        $pathVendor = $this->package->getDirectory() . $this->package->getPathVendor();

        // load all installed packages (use installed.json which also includes version instead of composer.lock)
        if (is_file($pathVendor . 'composer/installed.json')) {
            // file does not exist if there's nothing to be installed
            $installed = $this->loadJson($pathVendor . 'composer/installed.json');

            // Composer 2.0 format wrapped in additional root key
            if (isset($installed['packages'])) {
                $installed = $installed['packages'];
            }

            foreach ($installed as $package) {
                $dir = $package['name'] . '/';
                if (isset($package['target-dir'])) {
                    $dir .= trim($package['target-dir'], '/') . '/';
                }

                $dir = $pathVendor . $dir;
                $packages []= new Package($package, $dir);
            }
        }

        return $packages;
    }

    public function build()
    {
        $this->log('[' . $this->step . '/' . $this->step.'] Creating phar <info>' . $this->getTarget() . '</info>');
        $time = microtime(true);

        $pathVendor = $this->package->getDirectory() . $this->package->getPathVendor();
        if (!is_dir($pathVendor)) {
            throw new \RuntimeException('Directory "' . $pathVendor . '" not properly installed, did you run "composer install"?');
        }

        // get target and tempory file name to write to
        $target = $this->getTarget();
        do {
            $tmp = $target . '.' . mt_rand() . '.phar';
        } while (file_exists($tmp));

        $targetPhar = new TargetPhar(new \Phar($tmp), $this);
        $this->log('  - Adding main package "' . $this->package->getName() . '"');
        $targetPhar->addBundle($this->package->bundle());

        $this->log('  - Adding composer base files');
        // explicitly add composer autoloader
        $targetPhar->addFile($pathVendor . 'autoload.php');

        // only add composer base directory (no sub-directories!)
        $targetPhar->buildFromIterator(new \GlobIterator($pathVendor . 'composer/*.*', \FilesystemIterator::KEY_AS_FILENAME));

        foreach ($this->getPackagesDependencies() as $package) {
            $this->log('  - Adding dependency "' . $package->getName() . '" from "' . $this->getPathLocalToBase($package->getDirectory()) . '"');
            $targetPhar->addBundle($package->bundle());
        }

        $this->log('  - Setting main/stub');
        $chmod = 0755;
        $main = $this->getMain();
        if ($main === null) {
            $this->log('    WARNING: No main bin file defined! Resulting phar will NOT be executable');
        } else {
            $generator = StubGenerator::create()
                ->index($main)
                ->extract(true)
                ->banner("Bundled by phar-composer with the help of php-box.\n\n@link https://github.com/clue/phar-composer");

            $lines = file($this->package->getDirectory() . $main, FILE_IGNORE_NEW_LINES);
            if (substr($lines[0], 0, 2) === '#!') {
                $this->log('    Using referenced shebang "'. $lines[0] . '"');
                $generator->shebang($lines[0]);

                // remove shebang from main file and add (overwrite)
                unset($lines[0]);
                $targetPhar->addFromString($main, implode("\n", $lines));
            }

            $targetPhar->setStub($generator->generate());

            $chmod = octdec(substr(decoct(fileperms($this->package->getDirectory() . $main)),-4));
            $this->log('    Using referenced chmod ' . sprintf('%04o', $chmod));
        }

        // stop buffering contents in memory and write to file
        // failure to write will emit a warning (ignore) and throw an (uncaught) exception
        try {
            @$targetPhar->stopBuffering();
            $targetPhar = null;
        } catch (\PharException $e) {
            throw new \RuntimeException('Unable to write phar: ' . $e->getMessage());
        }

        if ($chmod !== null) {
            $this->log('    Applying chmod ' . sprintf('%04o', $chmod));
            if (chmod($tmp, $chmod) === false) {
                throw new \UnexpectedValueException('Unable to chmod target file "' . $target .'"');
            }
        }

        if (file_exists($target)) {
            $this->log('  - Overwriting existing file <info>' . $target . '</info> (' . $this->getSize($target) . ')');
        }

        if (@rename($tmp, $target) === false) {
            // retry renaming after sleeping to give slow network drives some time to flush data
            sleep(5);
            if (rename($tmp, $target) === false) {
                throw new \UnexpectedValueException('Unable to rename temporary phar archive to "'.$target.'"');
            }
        }

        $time = max(microtime(true) - $time, 0);

        $this->log('');
        $this->log('    <info>OK</info> - Creating <info>' . $this->getTarget() .'</info> (' . $this->getSize($this->getTarget()) . ') completed after ' . round($time, 1) . 's');
    }

    private function getSize($path)
    {
        return round(filesize($path) / 1024, 1) . ' KiB';
    }

    public function getPathLocalToBase($path)
    {
        $root = $this->package->getDirectory();
        if (strpos($path, $root) !== 0) {
            throw new \UnexpectedValueException('Path "' . $path . '" is not within base project path "' . $root . '"');
        }
        return substr($path, strlen($root));
    }

    public function log($message)
    {
        $this->logger->log($message);
    }

    public function setStep($step)
    {
        $this->step = $step;
    }

    /**
     * @param string $path
     * @return mixed
     * @throws \InvalidArgumentException
     */
    private function loadJson($path)
    {
        $ret = @json_decode(file_get_contents($path), true);
        if ($ret === null) {
            throw new \InvalidArgumentException('Unable to parse given path "' . $path . '"', json_last_error());
        }
        return $ret;
    }
}
PK�]c�`2��phar-composer/src/App.phpnu�[���<?php

namespace Clue\PharComposer;

use Symfony\Component\Console\Application as BaseApplication;

class App extends BaseApplication
{
    public function __construct()
    {
        parent::__construct('phar-composer', '@dev');

        $this->add(new Command\Build());
        $this->add(new Command\Search());
        $this->add(new Command\Install());

        $this->setDefaultCommand('search');
    }
}
PK�]2�$+_	_	%phar-composer/src/Command/Install.phpnu�[���<?php

namespace Clue\PharComposer\Command;

use Clue\PharComposer\Phar\Packager;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;

class Install extends Command
{
    /** @var Packager */
    private $packager;

    /** @var bool */
    private $isWindows;

    public function __construct(Packager $packager = null, $isWindows = null)
    {
        if ($packager === null) {
            $packager = new Packager();
        }
        if ($isWindows === null) {
            $isWindows = DIRECTORY_SEPARATOR === '\\';
        }
        $this->packager = $packager;
        $this->isWindows = $isWindows;

        parent::__construct();
    }

    protected function configure()
    {
        $this->setName('install')
             ->setDescription('Install phar into system wide binary directory' . ($this->isWindows ? ' (not available on Windows)' : ''))
             ->addArgument('project', InputArgument::OPTIONAL, 'Project name or path', '.')
             ->addArgument('target', InputArgument::OPTIONAL, 'Path to install to', '/usr/local/bin');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        if ($this->isWindows) {
            $output->writeln('<error>Command not available on this platform. Please use the "build" command and place Phar in your $PATH manually.</error>');
            return 1;
        }

        $this->packager->setOutput($output);
        $this->packager->coerceWritable();

        $pharer = $this->packager->getPharer($input->getArgument('project'));

        $path = $this->packager->getSystemBin($pharer->getPackageRoot(), $input->getArgument('target'));

        if (is_file($path)) {
            $helper = $this->getHelper('question');
            assert($helper instanceof QuestionHelper);

            $question = new ConfirmationQuestion('Overwrite existing file <info>' . $path . '</info>? [y] > ', true);
            if (!$helper->ask($input, $output, $question)) {
                $output->writeln('Aborting');
                return 0;
            }
        }

        $this->packager->install($pharer, $path);

        return 0;
    }
}
PK�]�*:4��$phar-composer/src/Command/Search.phpnu�[���<?php


namespace Clue\PharComposer\Command;

use Clue\PharComposer\Phar\Packager;
use Packagist\Api\Client;
use Packagist\Api\Result\Package;
use Packagist\Api\Result\Package\Version;
use Packagist\Api\Result\Result;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\Question;

class Search extends Command
{
    /** @var Packager */
    private $packager;

    /** @var Client */
    private $packagist;

    /** @var bool */
    private $isWindows;

    public function __construct(Packager $packager = null, Client $packagist = null, $isWindows = null)
    {
        if ($packager === null) {
            $packager = new Packager();
        }
        if ($packagist === null) {
            $packagist = new Client();
        }
        if ($isWindows === null) {
            $isWindows = DIRECTORY_SEPARATOR === '\\';
        }
        $this->packager = $packager;
        $this->packagist = $packagist;
        $this->isWindows = $isWindows;

        parent::__construct();
    }

    protected function configure()
    {
        $this->setName('search')
             ->setDescription('Interactive search for project name')
             ->addArgument('project', InputArgument::OPTIONAL, 'Project name or path', null);
    }

    /**
     * @param InputInterface       $input
     * @param OutputInterface      $output
     * @param string               $label
     * @param array<string,string> $choices
     * @param ?string              $abortable
     * @return ?string
     */
    protected function select(InputInterface $input, OutputInterface $output, $label, array $choices, $abortable = null)
    {
        $helper = $this->getHelper('question');
        assert($helper instanceof QuestionHelper);

        if (!$choices) {
            $output->writeln('<error>No matching packages found</error>');
            return null;
        }

        // use numeric keys for all options
        $select = array_merge(array(0 => $abortable), array_values($choices));
        if ($abortable === null) {
            unset($select[0]);
        }

        $question = new ChoiceQuestion($label, $select);
        $index = array_search($helper->ask($input, $output, $question), $select);

        if ($index === 0) {
            return null;
        }

        $indices = array_keys($choices);
        return $indices[$index - 1];
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->packager->setOutput($output);
        $this->packager->coerceWritable();

        $helper = $this->getHelper('question');
        assert($helper instanceof QuestionHelper);

        $project = $input->getArgument('project');

        do {
            if ($project === null) {
                // ask for input
                $question = new Question('Enter (partial) project name > ', '');
                $project = $helper->ask($input, $output, $question);
            } else {
                $output->writeln('Searching for <info>' . $project . '</info>...');
            }

            $choices = array();
            foreach ($this->packagist->search($project) as $result) {
                assert($result instanceof Result);

                $label = str_pad($result->getName(), 39) . ' ';
                $label = str_replace($project, '<info>' . $project . '</info>', $label);
                $label .= $result->getDescription();

                $label .= ' (⤓' . $result->getDownloads() . ')';

                $choices[$result->getName()] = $label;
            }

            $project = $this->select($input, $output, 'Select matching package', $choices, 'Start new search');
        } while ($project === null);

        $output->writeln('Selected <info>' . $project . '</info>, listing versions...');

        $package = $this->packagist->get($project);
        assert($package instanceof Package);

        $choices = array();
        foreach ($package->getVersions() as $version) {
            assert($version instanceof Version);

            $label = $version->getVersion();

            /* @var ?string $bin */
            $bin = $version->getBin();
            $label .= $bin !== null ? ' (☑ executable bin)' : ' (<error>no executable bin</error>)';

            $choices[$version->getVersion()] = $label;
        }

        $version = $this->select($input, $output, 'Select available version', $choices);

        $action = $this->select(
            $input,
            $output,
            'Action',
            array_filter(array(
                'build'   => 'Build project',
                'install' => $this->isWindows ? null : 'Install project system-wide'
            )),
            'Quit'
        );

        if ($action === null) {
            return 0;
        }

        $pharer = $this->packager->getPharer($project, $version);

        if ($action === 'install') {
            $path = $this->packager->getSystemBin($pharer->getPackageRoot());
            $this->packager->install($pharer, $path);
        } else {
            $pharer->build();
        }

        return 0;
    }
}
PK�]�F���#phar-composer/src/Command/Build.phpnu�[���<?php

namespace Clue\PharComposer\Command;

use Clue\PharComposer\Phar\Packager;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class Build extends Command
{
    /** @var Packager */
    private $packager;

    public function __construct(Packager $packager = null)
    {
        parent::__construct();

        if ($packager === null) {
            $packager = new Packager();
        }
        $this->packager = $packager;
    }

    protected function configure()
    {
        $this->setName('build')
             ->setDescription('Build phar for the given composer project')
             ->addArgument('project', InputArgument::OPTIONAL, 'Path to project directory or composer.json', '.')
             ->addArgument('target', InputArgument::OPTIONAL, 'Path to write phar output to (defaults to project name)');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->packager->setOutput($output);
        $this->packager->coerceWritable();

        $pharer = $this->packager->getPharer($input->getArgument('project'));

        $target = $input->getArgument('target');
        if ($target !== null) {
            $pharer->setTarget($target);
        }

        $pharer->build();

        return 0;
    }
}
PK�]���%phar-composer/src/Box/Extract.min.phpnu�[���<?php
namespace Herrera\Box;
use InvalidArgumentException;
use LengthException;
use RuntimeException;
use UnexpectedValueException;
define('BOX_EXTRACT_PATTERN_DEFAULT','__HALT'.'_COMPILER(); ?>');
define('BOX_EXTRACT_PATTERN_OPEN',"__HALT"."_COMPILER(); ?>\r\n");
class Extract
{
const PATTERN_DEFAULT=BOX_EXTRACT_PATTERN_DEFAULT;
const PATTERN_OPEN=BOX_EXTRACT_PATTERN_OPEN;
const GZ=4096;
const BZ2=8192;
const MASK=12288;
private$file;
private$handle;
private$stub;
function __construct($file,$stub){
if(!is_file($file)){
throw new InvalidArgumentException(sprintf('The path "%s" is not a file or does not exist.',$file
));
}
$this->file=$file;
$this->stub=$stub;
}
static function findStubLength($file,$pattern=self::PATTERN_OPEN
){
if(!($fp=fopen($file,'rb'))){
throw new RuntimeException(sprintf('The phar "%s" could not be opened for reading.',$file
));
}
$stub=null;
$offset=0;
$combo=str_split($pattern);
while(!feof($fp)){
if(fgetc($fp)===$combo[$offset]){
$offset++;
if(!isset($combo[$offset])){
$stub=ftell($fp);
break;
}
}else{
$offset=0;
}
}
fclose($fp);
if(null===$stub){
throw new InvalidArgumentException(sprintf('The pattern could not be found in "%s".',$file
));
}
return$stub;
}
function go($dir=null){
if(null===$dir){
$dir=rtrim(sys_get_temp_dir(),'\\/').DIRECTORY_SEPARATOR
.'pharextract'.DIRECTORY_SEPARATOR
.basename($this->file,'.phar');
}else{
$dir=realpath($dir);
}
$md5=$dir.DIRECTORY_SEPARATOR.md5_file($this->file);
if(file_exists($md5)){
return$dir;
}
if(!is_dir($dir)){
$this->createDir($dir);
}
$this->open();
if(-1===fseek($this->handle,$this->stub)){
throw new RuntimeException(sprintf('Could not seek to %d in the file "%s".',$this->stub,$this->file
));
}
$info=$this->readManifest();
if($info['flags']&self::GZ){
if(!function_exists('gzinflate')){
throw new RuntimeException('The zlib extension is (gzinflate()) is required for "%s.',$this->file
);
}
}
if($info['flags']&self::BZ2){
if(!function_exists('bzdecompress')){
throw new RuntimeException('The bzip2 extension (bzdecompress()) is required for "%s".',$this->file
);
}
}
self::purge($dir);
$this->createDir($dir);
$this->createFile($md5);
foreach($info['files']as$info){
$path=$dir.DIRECTORY_SEPARATOR.$info['path'];
$parent=dirname($path);
if(!is_dir($parent)){
$this->createDir($parent);
}
if(preg_match('{/$}',$info['path'])){
$this->createDir($path,511,false);
}else{
$this->createFile($path,$this->extractFile($info));
}
}
return$dir;
}
static function purge($path){
if(is_dir($path)){
foreach(scandir($path)as$item){
if(('.'===$item)||('..'===$item)){
continue;
}
self::purge($path.DIRECTORY_SEPARATOR.$item);
}
if(!rmdir($path)){
throw new RuntimeException(sprintf('The directory "%s" could not be deleted.',$path
));
}
}else{
if(!unlink($path)){
throw new RuntimeException(sprintf('The file "%s" could not be deleted.',$path
));
}
}
}
private function createDir($path,$chmod=511,$recursive=true){
if(!mkdir($path,$chmod,$recursive)){
throw new RuntimeException(sprintf('The directory path "%s" could not be created.',$path
));
}
}
private function createFile($path,$contents='',$mode=438){
if(false===file_put_contents($path,$contents)){
throw new RuntimeException(sprintf('The file "%s" could not be written.',$path
));
}
if(!chmod($path,$mode)){
throw new RuntimeException(sprintf('The file "%s" could not be chmodded to %o.',$path,$mode
));
}
}
private function extractFile($info){
if(0===$info['size']){
return'';
}
$data=$this->read($info['compressed_size']);
if($info['flags']&self::GZ){
if(false===($data=gzinflate($data))){
throw new RuntimeException(sprintf('The "%s" file could not be inflated (gzip) from "%s".',$info['path'],$this->file
));
}
}elseif($info['flags']&self::BZ2){
if(false===($data=bzdecompress($data))){
throw new RuntimeException(sprintf('The "%s" file could not be inflated (bzip2) from "%s".',$info['path'],$this->file
));
}
}
if(($actual=strlen($data))!==$info['size']){
throw new UnexpectedValueException(sprintf('The size of "%s" (%d) did not match what was expected (%d) in "%s".',$info['path'],$actual,$info['size'],$this->file
));
}
$crc32=sprintf('%u',crc32($data)&4294967295);
if($info['crc32']!=$crc32){
throw new UnexpectedValueException(sprintf('The crc32 checksum (%s) for "%s" did not match what was expected (%s) in "%s".',$crc32,$info['path'],$info['crc32'],$this->file
));
}
return$data;
}
private function open(){
if(null===($this->handle=fopen($this->file,'rb'))){
$this->handle=null;
throw new RuntimeException(sprintf('The file "%s" could not be opened for reading.',$this->file
));
}
}
private function read($bytes){
$read='';
$total=$bytes;
while(!feof($this->handle)&&$bytes){
if(false===($chunk=fread($this->handle,$bytes))){
throw new RuntimeException(sprintf('Could not read %d bytes from "%s".',$bytes,$this->file
));
}
$read.=$chunk;
$bytes-=strlen($chunk);
}
if(($actual=strlen($read))!==$total){
throw new RuntimeException(sprintf('Only read %d of %d in "%s".',$actual,$total,$this->file
));
}
return$read;
}
private function readManifest(){
$size=unpack('V',$this->read(4));
$size=$size[1];
$raw=$this->read($size);
$count=unpack('V',substr($raw,0,4));
$count=$count[1];
$aliasSize=unpack('V',substr($raw,10,4));
$aliasSize=$aliasSize[1];
$raw=substr($raw,14+$aliasSize);
$metaSize=unpack('V',substr($raw,0,4));
$metaSize=$metaSize[1];
$offset=0;
$start=4+$metaSize;
$manifest=array('files'=>array(),'flags'=>0,);
for($i=0;$i<$count;$i++){
$length=unpack('V',substr($raw,$start,4));
$length=$length[1];
$start+=4;
$path=substr($raw,$start,$length);
$start+=$length;
$file=unpack('Vsize/Vtimestamp/Vcompressed_size/Vcrc32/Vflags/Vmetadata_length',substr($raw,$start,24));
$file['path']=$path;
$file['crc32']=sprintf('%u',$file['crc32']&4294967295);
$file['offset']=$offset;
$offset+=$file['compressed_size'];
$start+=24+$file['metadata_length'];
$manifest['flags']|=$file['flags']&self::MASK;
$manifest['files'][]=$file;
}
return$manifest;
}
}
PK�]��<<!phar-composer/src/Box/Extract.phpnu�[���<?php

namespace Herrera\Box;

use InvalidArgumentException;
use LengthException;
use RuntimeException;
use UnexpectedValueException;

/**
 * The default stub pattern.
 *
 * @var string
 */
define('BOX_EXTRACT_PATTERN_DEFAULT', '__HALT' . '_COMPILER(); ?>');

/**
 * The open-ended stub pattern.
 *
 * @var string
 */
define('BOX_EXTRACT_PATTERN_OPEN', "__HALT" . "_COMPILER(); ?>\r\n");

/**
 * Extracts a phar without the extension.
 *
 * This class is a rewrite of the `Extract_Phar` class that is included
 * in the default stub for all phars. The class is designed to work from
 * inside and outside of a phar. Unlike the original class, the stub
 * length must be specified.
 *
 * @author Kevin Herrera <kevin@herrera.io>
 *
 * @link https://github.com/php/php-src/blob/master/ext/phar/shortarc.php
 */
class Extract
{
    /**
     * The default stub pattern.
     *
     * @var string
     */
    const PATTERN_DEFAULT = BOX_EXTRACT_PATTERN_DEFAULT;

    /**
     * The open-ended stub pattern.
     *
     * @var string
     */
    const PATTERN_OPEN = BOX_EXTRACT_PATTERN_OPEN;

    /**
     * The gzip compression flag.
     *
     * @var integer
     */
    const GZ = 0x1000;

    /**
     * The bzip2 compression flag.
     *
     * @var integer
     */
    const BZ2 = 0x2000;

    /**
     * @var integer
     */
    const MASK = 0x3000;

    /**
     * The phar file path to extract.
     *
     * @var string
     */
    private $file;

    /**
     * The open file handle.
     *
     * @var resource
     */
    private $handle;

    /**
     * The length of the stub in the phar.
     *
     * @var integer
     */
    private $stub;

    /**
     * Sets the file to extract and the stub length.
     *
     * @param string $file The file path.
     * @param integer $stub The stub length.
     *
     * @throws InvalidArgumentException If the file does not exist.
     */
    public function __construct($file, $stub)
    {
        if (!is_file($file)) {
            throw new InvalidArgumentException(
                sprintf(
                    'The path "%s" is not a file or does not exist.',
                    $file
                )
            );
        }

        $this->file = $file;
        $this->stub = $stub;
    }

    /**
     * Finds the phar's stub length using the end pattern.
     *
     * A "pattern" is a sequence of characters that indicate the end of a
     * stub, and the beginning of a manifest. This determines the complete
     * size of a stub, and is used as an offset to begin parsing the data
     * contained in the phar's manifest.
     *
     * The stub generated included with the Box library uses what I like
     * to call an open-ended pattern. This pattern uses the function
     * "__HALT_COMPILER();" at the end, with no following whitespace or
     * closing PHP tag. By default, this method will use that pattern,
     * defined as `Extract::PATTERN_OPEN`.
     *
     * The Phar class generates its own default stub. The pattern for the
     * default stub is slightly different than the one used by Box. This
     * pattern is defined as `Extract::PATTERN_DEFAULT`.
     *
     * If you have used your own custom stub, you will need to specify its
     * pattern as the `$pattern` argument, if you cannot use either of the
     * pattern constants defined.
     *
     * @param string $file    The phar file path.
     * @param string $pattern The stub end pattern.
     *
     * @return integer The stub length.
     *
     * @throws InvalidArgumentException If the pattern could not be found.
     * @throws RuntimeException         If the phar could not be read.
     */
    public static function findStubLength(
        $file,
        $pattern = self::PATTERN_OPEN
    ) {
        if (!($fp = fopen($file, 'rb'))) {
            throw new RuntimeException(
                sprintf(
                    'The phar "%s" could not be opened for reading.',
                    $file
                )
            );
        }

        $stub = null;
        $offset = 0;
        $combo = str_split($pattern);

        while (!feof($fp)) {
            if (fgetc($fp) === $combo[$offset]) {
                $offset++;

                if (!isset($combo[$offset])) {
                    $stub = ftell($fp);

                    break;
                }
            } else {
                $offset = 0;
            }
        }

        fclose($fp);

        if (null === $stub) {
            throw new InvalidArgumentException(
                sprintf(
                    'The pattern could not be found in "%s".',
                    $file
                )
            );
        }

        return $stub;
    }

    /**
     * Extracts the phar to the directory path.
     *
     * If no directory path is given, a temporary one will be generated and
     * returned. If a directory path is given, the returned directory path
     * will be the same.
     *
     * @param string $dir The directory to extract to.
     *
     * @return string The directory extracted to.
     *
     * @throws LengthException
     * @throws RuntimeException
     */
    public function go($dir = null)
    {
        // set up the output directory
        if (null === $dir) {
            $dir = rtrim(sys_get_temp_dir(), '\\/')
                . DIRECTORY_SEPARATOR
                . 'pharextract'
                . DIRECTORY_SEPARATOR
                . basename($this->file, '.phar');
        } else {
            $dir = realpath($dir);
        }

        // skip if already extracted
        $md5 = $dir . DIRECTORY_SEPARATOR . md5_file($this->file);

        if (file_exists($md5)) {
            return $dir;
        }

        if (!is_dir($dir)) {
            $this->createDir($dir);
        }

        // open the file and skip stub
        $this->open();

        if (-1 === fseek($this->handle, $this->stub)) {
            throw new RuntimeException(
                sprintf(
                    'Could not seek to %d in the file "%s".',
                    $this->stub,
                    $this->file
                )
            );
        }

        // read the manifest
        $info = $this->readManifest();

        if ($info['flags'] & self::GZ) {
            if (!function_exists('gzinflate')) {
                throw new RuntimeException(
                    'The zlib extension is (gzinflate()) is required for "%s.',
                    $this->file
                );
            }
        }

        if ($info['flags'] & self::BZ2) {
            if (!function_exists('bzdecompress')) {
                throw new RuntimeException(
                    'The bzip2 extension (bzdecompress()) is required for "%s".',
                    $this->file
                );
            }
        }

        self::purge($dir);
        $this->createDir($dir);
        $this->createFile($md5);

        foreach ($info['files'] as $info) {
            $path = $dir . DIRECTORY_SEPARATOR . $info['path'];
            $parent = dirname($path);

            if (!is_dir($parent)) {
                $this->createDir($parent);
            }

            if (preg_match('{/$}', $info['path'])) {
                $this->createDir($path, 0777, false);
            } else {
                $this->createFile(
                    $path,
                    $this->extractFile($info)
                );
            }
        }

        return $dir;
    }

    /**
     * Recursively deletes the directory or file path.
     *
     * @param string $path The path to delete.
     *
     * @throws RuntimeException If the path could not be deleted.
     */
    public static function purge($path)
    {
        if (is_dir($path)) {
            foreach (scandir($path) as $item) {
                if (('.' === $item) || ('..' === $item)) {
                    continue;
                }

                self::purge($path . DIRECTORY_SEPARATOR . $item);
            }

            if (!rmdir($path)) {
                throw new RuntimeException(
                    sprintf(
                        'The directory "%s" could not be deleted.',
                        $path
                    )
                );
            }
        } else {
            if (!unlink($path)) {
                throw new RuntimeException(
                    sprintf(
                        'The file "%s" could not be deleted.',
                        $path
                    )
                );
            }
        }
    }

    /**
     * Creates a new directory.
     *
     * @param string $path      The directory path.
     * @param integer $chmod     The file mode.
     * @param boolean $recursive Recursively create path?
     *
     * @throws RuntimeException If the path could not be created.
     */
    private function createDir($path, $chmod = 0777, $recursive = true)
    {
        if (!mkdir($path, $chmod, $recursive)) {
            throw new RuntimeException(
                sprintf(
                    'The directory path "%s" could not be created.',
                    $path
                )
            );
        }
    }

    /**
     * Creates a new file.
     *
     * @param string $path     The file path.
     * @param string $contents The file contents.
     * @param integer $mode     The file mode.
     *
     * @throws RuntimeException If the file could not be created.
     */
    private function createFile($path, $contents = '', $mode = 0666)
    {
        if (false === file_put_contents($path, $contents)) {
            throw new RuntimeException(
                sprintf(
                    'The file "%s" could not be written.',
                    $path
                )
            );
        }

        if (!chmod($path, $mode)) {
            throw new RuntimeException(
                sprintf(
                    'The file "%s" could not be chmodded to %o.',
                    $path,
                    $mode
                )
            );
        }
    }

    /**
     * Extracts a single file from the phar.
     *
     * @param array $info The file information.
     *
     * @return string The file data.
     *
     * @throws RuntimeException         If the file could not be extracted.
     * @throws UnexpectedValueException If the crc32 checksum does not
     *                                  match the expected value.
     */
    private function extractFile($info)
    {
        if (0 === $info['size']) {
            return '';
        }

        $data = $this->read($info['compressed_size']);

        if ($info['flags'] & self::GZ) {
            if (false === ($data = gzinflate($data))) {
                throw new RuntimeException(
                    sprintf(
                        'The "%s" file could not be inflated (gzip) from "%s".',
                        $info['path'],
                        $this->file
                    )
                );
            }
        } elseif ($info['flags'] & self::BZ2) {
            if (false === ($data = bzdecompress($data))) {
                throw new RuntimeException(
                    sprintf(
                        'The "%s" file could not be inflated (bzip2) from "%s".',
                        $info['path'],
                        $this->file
                    )
                );
            }
        }

        if (($actual = strlen($data)) !== $info['size']) {
            throw new UnexpectedValueException(
                sprintf(
                    'The size of "%s" (%d) did not match what was expected (%d) in "%s".',
                    $info['path'],
                    $actual,
                    $info['size'],
                    $this->file
                )
            );
        }

        $crc32 = sprintf('%u', crc32($data) & 0xffffffff);

        if ($info['crc32'] != $crc32) {
            throw new UnexpectedValueException(
                sprintf(
                    'The crc32 checksum (%s) for "%s" did not match what was expected (%s) in "%s".',
                    $crc32,
                    $info['path'],
                    $info['crc32'],
                    $this->file
                )
            );
        }

        return $data;
    }

    /**
     * Opens the file for reading.
     *
     * @throws RuntimeException If the file could not be opened.
     */
    private function open()
    {
        if (null === ($this->handle = fopen($this->file, 'rb'))) {
            $this->handle = null;

            throw new RuntimeException(
                sprintf(
                    'The file "%s" could not be opened for reading.',
                    $this->file
                )
            );
        }
    }

    /**
     * Reads the number of bytes from the file.
     *
     * @param integer $bytes The number of bytes.
     *
     * @return string The binary string read.
     *
     * @throws RuntimeException If the read fails.
     */
    private function read($bytes)
    {
        $read = '';
        $total = $bytes;

        while (!feof($this->handle) && $bytes) {
            if (false === ($chunk = fread($this->handle, $bytes))) {
                throw new RuntimeException(
                    sprintf(
                        'Could not read %d bytes from "%s".',
                        $bytes,
                        $this->file
                    )
                );
            }

            $read .= $chunk;
            $bytes -= strlen($chunk);
        }

        if (($actual = strlen($read)) !== $total) {
            throw new RuntimeException(
                sprintf(
                    'Only read %d of %d in "%s".',
                    $actual,
                    $total,
                    $this->file
                )
            );
        }

        return $read;
    }

    /**
     * Reads and unpacks the manifest data from the phar.
     *
     * @return array The manifest.
     */
    private function readManifest()
    {
        $size = unpack('V', $this->read(4));
        $size = $size[1];

        $raw = $this->read($size);

        // ++ start skip: API version, global flags, alias, and metadata
        $count = unpack('V', substr($raw, 0, 4));
        $count = $count[1];

        $aliasSize = unpack('V', substr($raw, 10, 4));
        $aliasSize = $aliasSize[1];
        $raw = substr($raw, 14 + $aliasSize);

        $metaSize = unpack('V', substr($raw, 0, 4));
        $metaSize = $metaSize[1];

        $offset = 0;
        $start = 4 + $metaSize;
        // -- end skip

        $manifest = array(
            'files' => array(),
            'flags' => 0,
        );

        for ($i = 0; $i < $count; $i++) {
            $length = unpack('V', substr($raw, $start, 4));
            $length = $length[1];
            $start += 4;

            $path = substr($raw, $start, $length);
            $start += $length;

            $file = unpack(
                'Vsize/Vtimestamp/Vcompressed_size/Vcrc32/Vflags/Vmetadata_length',
                substr($raw, $start, 24)
            );

            $file['path'] = $path;
            $file['crc32'] = sprintf('%u', $file['crc32'] & 0xffffffff);
            $file['offset'] = $offset;

            $offset += $file['compressed_size'];
            $start += 24 + $file['metadata_length'];

            $manifest['flags'] |= $file['flags'] & self::MASK;

            $manifest['files'][] = $file;
        }

        return $manifest;
    }
}
PK�]t��,,'phar-composer/src/Box/StubGenerator.phpnu�[���<?php

namespace Clue\PharComposer\Box;

/**
 * Generates a new PHP bootstrap loader stub for a Phar.
 *
 * This has been copied from herrera-io/box v1.6.1 as is with only the
 * following minor adjustments:
 * - adjusted namespace
 * - use global `InvalidArgumentException` instead of namespaced variant
 * - use minified Extract.min.php instead of running Compactor on Extract.php (original)
 *
 * @author Kevin Herrera <kevin@herrera.io>
 */
class StubGenerator
{
    /**
     * The list of server variables that are allowed to be modified.
     *
     * @var array
     */
    private static $allowedMung = array(
        'PHP_SELF',
        'REQUEST_URI',
        'SCRIPT_FILENAME',
        'SCRIPT_NAME'
    );

    /**
     * The alias to be used in "phar://" URLs.
     *
     * @var string
     */
    private $alias;

    /**
     * The top header comment banner text.
     *
     * @var string.
     */
    private $banner = 'Generated by Box.

@link https://github.com/herrera-io/php-box/';

    /**
     * Embed the Extract class in the stub?
     *
     * @var boolean
     */
    private $extract = false;

    /**
     * The processed extract code.
     *
     * @var array
     */
    private $extractCode = array();

    /**
     * Force the use of the Extract class?
     *
     * @var boolean
     */
    private $extractForce = false;

    /**
     * The location within the Phar of index script.
     *
     * @var string
     */
    private $index;

    /**
     * Use the Phar::interceptFileFuncs() method?
     *
     * @var boolean
     */
    private $intercept = false;

    /**
     * The map for file extensions and their mimetypes.
     *
     * @var array
     */
    private $mimetypes = array();

    /**
     * The list of server variables to modify.
     *
     * @var array
     */
    private $mung = array();

    /**
     * The location of the script to run when a file is not found.
     *
     * @var string
     */
    private $notFound;

    /**
     * The rewrite function.
     *
     * @var string
     */
    private $rewrite;

    /**
     * The shebang line.
     *
     * @var string
     */
    private $shebang = '#!/usr/bin/env php';

    /**
     * Use Phar::webPhar() instead of Phar::mapPhar()?
     *
     * @var boolean
     */
    private $web = false;

    /**
     * Sets the alias to be used in "phar://" URLs.
     *
     * @param string $alias The alias.
     *
     * @return StubGenerator The stub generator.
     */
    public function alias($alias)
    {
        $this->alias = $alias;

        return $this;
    }

    /**
     * Sets the top header comment banner text.
     *
     * @param string $banner The banner text.
     *
     * @return StubGenerator The stub generator.
     */
    public function banner($banner)
    {
        $this->banner = $banner;

        return $this;
    }

    /**
     * Creates a new instance of the stub generator.
     *
     * @return StubGenerator The stub generator.
     */
    public static function create()
    {
        return new static();
    }

    /**
     * Embed the Extract class in the stub?
     *
     * @param boolean $extract Embed the class?
     * @param boolean $force   Force the use of the class?
     *
     * @return StubGenerator The stub generator.
     */
    public function extract($extract, $force = false)
    {
        $this->extract = $extract;
        $this->extractForce = $force;

        if ($extract) {
            $this->extractCode = array(
                'constants' => array(),
                'class' => array(),
            );

            $code = file_get_contents(__DIR__ . '/Extract.min.php');
            $code = preg_replace('/\n+/', "\n", $code);
            $code = explode("\n", $code);
            $code = array_slice($code, 2);

            foreach ($code as $i => $line) {
                if ((0 === strpos($line, 'use'))
                    && (false === strpos($line, '\\'))
                ) {
                    unset($code[$i]);
                } elseif (0 === strpos($line, 'define')) {
                    $this->extractCode['constants'][] = $line;
                } else {
                    $this->extractCode['class'][] = $line;
                }
            }
        }

        return $this;
    }

    /**
     * Sets location within the Phar of index script.
     *
     * @param string $index The index file.
     *
     * @return StubGenerator The stub generator.
     */
    public function index($index)
    {
        $this->index = $index;

        return $this;
    }

    /**
     * Use the Phar::interceptFileFuncs() method in the stub?
     *
     * @param boolean $intercept Use interceptFileFuncs()?
     *
     * @return StubGenerator The stub generator.
     */
    public function intercept($intercept)
    {
        $this->intercept = $intercept;

        return $this;
    }

    /**
     * Generates the stub.
     *
     * @return string The stub.
     */
    public function generate()
    {
        $stub = array();

        if ('' !== $this->shebang) {
            $stub[] = $this->shebang;
        }

        $stub[] = '<?php';

        if (null !== $this->banner) {
            $stub[] = $this->getBanner();
        }

        if ($this->extract) {
            $stub[] = join("\n", $this->extractCode['constants']);

            if ($this->extractForce) {
                $stub = array_merge($stub, $this->getExtractSections());
            }
        }

        $stub = array_merge($stub, $this->getPharSections());

        if ($this->extract) {
            if ($this->extractForce) {
                if ($this->index && !$this->web) {
                    $stub[] = "require \"\$dir/{$this->index}\";";
                }
            } else {
                end($stub);

                $stub[key($stub)] .= ' else {';

                $stub = array_merge($stub, $this->getExtractSections());

                if ($this->index) {
                    $stub[] = "require \"\$dir/{$this->index}\";";
                }

                $stub[] = '}';
            }

            $stub[] = join("\n", $this->extractCode['class']);
        }

        $stub[] = "__HALT_COMPILER();";

        return join("\n", $stub);
    }

    /**
     * Sets the map for file extensions and their mimetypes.
     *
     * @param array $mimetypes The map.
     *
     * @return StubGenerator The stub generator.
     */
    public function mimetypes(array $mimetypes)
    {
        $this->mimetypes = $mimetypes;

        return $this;
    }

    /**
     * Sets the list of server variables to modify.
     *
     * @param array $list The list.
     *
     * @return StubGenerator The stub generator.
     *
     * @throws \InvalidArgumentException If the list contains an invalid value.
     */
    public function mung(array $list)
    {
        foreach ($list as $value) {
            if (false === in_array($value, self::$allowedMung)) {
                throw new \InvalidArgumentException(sprintf(
                    'The $_SERVER variable "%s" is not allowed.',
                    $value
                ));
            }
        }

        $this->mung = $list;

        return $this;
    }

    /**
     * Sets the location of the script to run when a file is not found.
     *
     * @param string $script The script.
     *
     * @return StubGenerator The stub generator.
     */
    public function notFound($script)
    {
        $this->notFound = $script;

        return $this;
    }

    /**
     * Sets the rewrite function.
     *
     * @param string $function The function.
     *
     * @return StubGenerator The stub generator.
     */
    public function rewrite($function)
    {
        $this->rewrite = $function;

        return $this;
    }

    /**
     * Sets the shebang line.
     *
     * @param string $shebang The shebang line.
     *
     * @return StubGenerator The stub generator.
     */
    public function shebang($shebang)
    {
        $this->shebang = $shebang;

        return $this;
    }

    /**
     * Use Phar::webPhar() instead of Phar::mapPhar()?
     *
     * @param boolean $web Use Phar::webPhar()?
     *
     * @return StubGenerator The stub generator.
     */
    public function web($web)
    {
        $this->web = $web;

        return $this;
    }

    /**
     * Escapes an argument so it can be written as a string in a call.
     *
     * @param string $arg   The argument.
     * @param string $quote The quote.
     *
     * @return string The escaped argument.
     */
    private function arg($arg, $quote = "'")
    {
        return $quote . addcslashes($arg, $quote) . $quote;
    }

    /**
     * Returns the alias map.
     *
     * @return string The alias map.
     */
    private function getAlias()
    {
        $stub = '';
        $prefix = '';

        if ($this->extractForce) {
            $prefix = '$dir/';
        }

        if ($this->web) {
            $stub .= 'Phar::webPhar(' . $this->arg($this->alias);

            if ($this->index) {
                $stub .= ', ' . $this->arg($prefix . $this->index, '"');

                if ($this->notFound) {
                    $stub .= ', ' . $this->arg($prefix . $this->notFound, '"');

                    if ($this->mimetypes) {
                        $stub .= ', ' . var_export(
                            $this->mimetypes,
                            true
                        );

                        if ($this->rewrite) {
                            $stub .= ', ' . $this->arg($this->rewrite);
                        }
                    }
                }
            }

            $stub .= ');';
        } else {
            $stub .= 'Phar::mapPhar(' . $this->arg($this->alias) . ');';
        }

        return $stub;
    }

    /**
     * Returns the banner after it has been processed.
     *
     * @return string The processed banner.
     */
    private function getBanner()
    {
        $banner = "/**\n * ";
        $banner .= str_replace(
            " \n",
            "\n",
            str_replace("\n", "\n * ", $this->banner)
        );

        $banner .= "\n */";

        return $banner;
    }

    /**
     * Returns the self extracting sections of the stub.
     *
     * @return array The stub sections.
     */
    private function getExtractSections()
    {
        return array(
            '$extract = new Extract(__FILE__, Extract::findStubLength(__FILE__));',
            '$dir = $extract->go();',
            'set_include_path($dir . PATH_SEPARATOR . get_include_path());',
        );
    }

    /**
     * Returns the sections of the stub that use the Phar class.
     *
     * @return array The stub sections.
     */
    private function getPharSections()
    {
        $stub = array(
            'if (class_exists(\'Phar\')) {',
            $this->getAlias(),
        );

        if ($this->intercept) {
            $stub[] = "Phar::interceptFileFuncs();";
        }

        if ($this->mung) {
            $stub[] = 'Phar::mungServer(' . var_export($this->mung, true) . ");";
        }

        if ($this->index && !$this->web && !$this->extractForce) {
            $stub[] = "require 'phar://' . __FILE__ . '/{$this->index}';";
        }

        $stub[] = '}';

        return $stub;
    }
}
PK�]���GGphar-composer/src/Logger.phpnu�[���<?php

namespace Clue\PharComposer;

/**
 * Interface for logging outout.
 *
 * TODO: should be used in the Command classes as well
 */
class Logger
{
    private $output = true;

    /**
     * set output function to use to output log messages
     *
     * @param callable|boolean $output callable that receives a single $line argument or boolean echo
     *
     * TODO: think about whether this should be a constructor instead
     */
    public function setOutput($output)
    {
        $this->output = $output;
    }

    public function log($message)
    {
        $this->output($message . PHP_EOL);
    }

    private function output($message)
    {
        if ($this->output === true) {
            echo $message;
        } elseif ($this->output !== false) {
            call_user_func($this->output, $message);
        }
    }
}
PK�]N���$phar-composer/src/Package/Bundle.phpnu�[���<?php

namespace Clue\PharComposer\Package;

use Symfony\Component\Finder\Finder;

/**
 * A bundle represents all resources from a package that should be bundled into
 * the target phar.
 */
class Bundle implements \IteratorAggregate
{
    /**
     * list of resources in this bundle
     *
     * @type  array
     */
    private $resources = array();

    /**
     * add given file to bundle
     *
     * @param   string  $file
     * @return  Bundle
     */
    public function addFile($file)
    {
        $this->resources[] = $file;
        return $this;
    }

    /**
     * add given directory to bundle
     *
     * @param   Finder  $dir
     * @return  Bundle
     */
    public function addDir(Finder $dir)
    {
        $this->resources[] = $dir;
        return $this;
    }

    /**
     * checks if a bundle contains given resource
     *
     * @param   string  $resource
     * @return  bool
     */
    public function contains($resource)
    {
        foreach ($this->resources as $containedResource) {
            if (is_string($containedResource) && $containedResource == $resource) {
                return true;
            }

            if ($containedResource instanceof Finder && $this->directoryContains($containedResource, $resource)) {
                return true;
            }
        }

        return false;
    }

    /**
     * checks if given directory contains given resource
     *
     * @param   Finder  $dir
     * @param   string  $resource
     * @return  bool
     */
    private function directoryContains(Finder $dir, $resource)
    {
        foreach ($dir as $containedResource) {
            /* @var $containedResource \SplFileInfo */
            if (substr($containedResource->getRealPath(), 0, strlen($resource)) == $resource) {
                return true;
            }
        }

        return false;
    }

    /**
     * returns list of resources
     *
     * @return  \Traversable
     */
    #[\ReturnTypeWillChange]
    public function getIterator()
    {
        return new \ArrayIterator($this->resources);
    }
}
PK�]��-�
�
%phar-composer/src/Package/Package.phpnu�[���<?php

namespace Clue\PharComposer\Package;

use Symfony\Component\Finder\Finder;

/**
 * The package represents either the main/root package or one of the vendor packages.
 */
class Package
{
    private $package;
    private $directory;

    /**
     * Instantiate package
     *
     * @param array  $package   package information (parsed composer.json)
     * @param string $directory base directory of this package
     */
    public function __construct(array $package, $directory)
    {
        $this->package = $package;
        $this->directory = rtrim($directory, '/') . '/';
    }

    /**
     * get package name as defined in composer.json
     *
     * @return ?string
     */
    public function getName()
    {
        return isset($this->package['name']) ? $this->package['name'] : null;
    }

    /**
     * @return string
     */
    public function getShortName()
    {
        // skip vendor name from package name or default to last directory component
        $name = $this->getName();
        if ($name === null) {
            $name = realpath($this->directory);
            if ($name === false) {
                $name = $this->directory;
            }
        }
        return basename($name);
    }

    /**
     * Get path to vendor directory (relative to package directory, always ends with slash)
     *
     * @return string
     */
    public function getPathVendor()
    {
        $vendor = 'vendor';
        if (isset($this->package['config']['vendor-dir'])) {
            $vendor = $this->package['config']['vendor-dir'];
        }
        return $vendor . '/';
    }

    /**
     * Get package directory (the directory containing its composer.json, always ends with slash)
     *
     * @return string
     */
    public function getDirectory()
    {
        return $this->directory;
    }

    /**
     * @return \Clue\PharComposer\Package\Bundle
     */
    public function bundle()
    {
        $bundle = new Bundle();

        // return empty bundle if this package does not define any files and directory does not exist
        if (empty($this->package['autoload']) && !is_dir($this->directory . $this->getPathVendor())) {
            return $bundle;
        }

        $iterator = Finder::create()
            ->files()
            ->ignoreVCS(true)
            ->exclude(rtrim($this->getPathVendor(), '/'))
            ->notPath('/^composer\.phar/')
            ->notPath('/^phar-composer\.phar/')
            ->in($this->getDirectory());

        return $bundle->addDir($iterator);
    }

    /**
     * Get list of files defined as "bin" (relative to package directory)
     *
     * @return string[]
     */
    public function getBins()
    {
        return isset($this->package['bin']) ? $this->package['bin'] : array();
    }
}
PK�]v���2)2)phar-composer/README.mdnu�[���# clue/phar-composer

[![CI status](https://github.com/clue/phar-composer/workflows/CI/badge.svg)](https://github.com/clue/phar-composer/actions) 
[![downloads on GitHub](https://img.shields.io/github/downloads/clue/phar-composer/total?color=blue&label=downloads%20on%20GitHub)](https://github.com/clue/phar-composer/releases)
[![installs on Packagist](https://img.shields.io/packagist/dt/clue/phar-composer?color=blue&label=installs%20on%20Packagist)](https://packagist.org/packages/clue/phar-composer)  

Simple phar creation for any project managed via Composer.

It takes your existing project's `composer.json` and builds an executable phar
for your project among with its bundled dependencies.

* Create a single executable phar archive, including its dependencies (i.e. vendor directory included)
* Automated build process
* Zero additional configuration

**Table of contents**

* [Support us](#support-us)
* [Usage](#usage)
  * [phar-composer](#phar-composer)
  * [phar-composer build](#phar-composer-build)
  * [phar-composer install](#phar-composer-install)
  * [phar-composer search](#phar-composer-search)
* [Install](#install)
  * [As a phar (recommended)](#as-a-phar-recommended)
  * [Installation using Composer](#installation-using-composer)
* [Development](#development)
* [Tests](#tests)
* [License](#license)

## Support us

We invest a lot of time developing, maintaining and updating our awesome
open-source projects. You can help us sustain this high-quality of our work by
[becoming a sponsor on GitHub](https://github.com/sponsors/clue). Sponsors get
numerous benefits in return, see our [sponsoring page](https://github.com/sponsors/clue)
for details.

Let's take these projects to the next level together! 🚀

## Usage

Once clue/phar-composer is [installed](#install), you can use it via command line like this.

### phar-composer

This tool supports several sub-commands. To get you started, you can now use the following simple command:

```bash
$ phar-composer
```

This will actually execute the `search` command that allows you to interactively search and build any package
listed on packagist (see below description of the [search command](#phar-composer-search) for more details).

### phar-composer build

The `build` command can be used to build an executable single-file phar (php archive) for any project
managed by composer:

```bash
$ phar-composer build ~/path/to/your/project
```

The second argument can be pretty much everything that can be resolved to a valid project managed by composer.
Besides creating phar archives for locally installed packages like above, you can also easily download and
bundle packages from packagist.org like this:

```bash
$ phar-composer build d11wtq/boris
```

The above will download and install the latest stable tagged release (if any).
You can also specify a tagged version like this:

```bash
$ phar-composer build clue/phar-composer:~1.0
```

Or you can specify to install the head of a given branch like this:

```bash
$ phar-composer build clue/phar-composer:dev-master
```

A similar syntax can be used to clone a package from any git URL. This is particularly
useful for private packages or temporary git clones not otherwise listed on packagist:

```bash
$ phar-composer build https://github.com/composer/composer.git
```

The above will clone the repository and check out the default branch.
Again, you can specify either a tag or branch name very similar to how composer works:

```bash
$ phar-composer build https://github.com/composer/composer.git:dev-master
```

### phar-composer install

The `install` command will both build the given package and then
install it into the system-wide bin directory `/usr/local/bin` (usually already
in your `$PATH`). This works for any package name or URL just like with the
`build` command, e.g.:

```bash
$ phar-composer install phpunit/phpunit
```

After some (lengthy) build output, you should now be able to run it by just issuing:

```bash
$ phpunit
```

> In essence, the `install` command will basically just issue a `build` and then
`sudo mv $target.phar /usr/local/bin/$target`. It will ask you for your sudo password
when necessary, so it's not needed (and in fact not *recommended*) to run the whole
comamnd via `sudo`.
>
> Windows limitation: Note that this subcommand is not available on Windows.
  Please use the `build` command and place Phar in your `$PATH` manually.

### phar-composer search

The `search` command provides an interactive command line search.
It will ask for the package name and issue an search via packagist.org's API and
present a list of matching packages. So if you don't know the exact package name,
you can use the following command:

```bash
$ phar-composer search boris
```

It uses an interactive command line menu to ask you for the matching package name,
its version and will then offer you to either `build` or `install` it.

## Install

You can grab a copy of clue/phar-composer in either of the following ways.

This project aims to run on any platform and thus does not require any PHP
extensions and supports running on legacy PHP 5.3 through current PHP 8+.
It's *highly recommended to use the latest supported PHP version* for this project.

### As a phar (recommended)

You can simply download a pre-compiled and ready-to-use version as a Phar
to any directory.
You can simply download the latest `phar-composer.phar` file from our
[releases page](https://github.com/clue/phar-composer/releases).
The [latest release](https://github.com/clue/phar-composer/releases/latest) can
always be downloaded like this:

```bash
$ curl -JOL https://clue.engineering/phar-composer-latest.phar
```

That's it already. Once downloaded, you can verify everything works by running this:

```bash
$ cd ~/Downloads
$ php phar-composer.phar --version
```

The above usage examples assume you've installed phar-composer system-wide to your $PATH (recommended),
so you have the following options:

1.  Only use phar-composer locally and adjust the usage examples: So instead of
    running `$ phar-composer --version`, you have to type `$ php phar-composer.phar --version`.

2.  Use phar-composer's `install` command to install itself to your $PATH by running:

    ```bash
    $ php phar-composer.phar install clue/phar-composer
    ```

3.  Or you can manually make the `phar-composer.phar` executable and move it to your $PATH by running:

   ```bash
   $ chmod 755 phar-composer.phar
   $ sudo mv phar-composer.phar /usr/local/bin/phar-composer
   ```

If you have installed phar-composer system-wide, you can now verify everything works by running:

```bash
$ phar-composer --version
```

There's no separate `update` procedure, simply download the latest release again
and overwrite the existing phar.

Again, if you have already installed phar-composer system-wide, updating is as easy as
running a self-installation like this:

```bash
$ phar-composer install clue/phar-composer
```

### Installation using Composer

Alternatively, you can also install phar-composer as part of your development dependencies.
You will likely want to use the `require-dev` section to exclude phar-composer in your production environment.

You can either modify your `composer.json` manually or run the following command to include the latest tagged release:

```bash
$ composer require --dev clue/phar-composer
```

Now you should be able to invoke the following command in your project root:

```bash
$ vendor/bin/phar-composer --version
```

> Note: You should only invoke and rely on the main phar-composer bin file.
Installing this project as a non-dev dependency in order to use its
source code as a library is *not supported*.

To update to the latest release, just run `composer update clue/graph-composer`.

## Development

clue/phar-composer is an [open-source project](#license) and encourages everybody to
participate in its development.
You're interested in checking out how clue/phar-composer works under the hood and/or want
to contribute to the development of clue/phar-composer?
Then this section is for you!

The recommended way to install clue/phar-composer is to clone (or download) this repository
and use [Composer](https://getcomposer.org/) to download its dependencies.
Therefore you'll need PHP, Composer, git and curl installed.
For example, on a recent Ubuntu/Debian-based system, simply run:

```bash
$ sudo apt install php-cli git curl

$ git clone https://github.com/clue/phar-composer.git
$ cd phar-composer

$ curl -s https://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/composer

$ composer install
```

You can now verify everything works by running clue/phar-composer like this:

```bash
$ php bin/phar-composer --version
```

If you want to distribute clue/phar-composer as a single standalone release file, you may
compile the project into a single `phar-composer.phar` file like this:

```bash
$ composer build
```

> Note that compiling will temporarily install a copy of this project to the
  local `build/` directory and install all non-development dependencies
  for distribution. This should only take a second or two if you've previously
  installed its dependencies already.
  The build script optionally accepts the version number (`VERSION` env) and
  an output file name or will otherwise try to look up the last release tag,
  such as `phar-composer-1.0.0.phar`.

You can now verify the resulting `phar-composer.phar` file works by running it
like this:

```bash
$ php phar-composer.phar --version
```

To update your development version to the latest version, just run this:

```bash
$ git pull
$ composer install
```

Made some changes to your local development version?

Make sure to let the world know! :shipit:
We welcome PRs and would love to hear from you!

Happy hacking!

## Tests

To run the test suite, you first need to clone this repo and then install all
dependencies [through Composer](https://getcomposer.org/):

```bash
$ composer install
```

To run the test suite, go to the project root and run:

```bash
$ vendor/bin/phpunit
```

## License

This project is released under the permissive [MIT license](LICENSE).

This project bundles the `StubGenerator` and `Extract` classes with minor changes
from the original herrera-io/box v1.6.1 licensed under MIT which no longer has
an installable candidate. Copyright (c) 2013 Kevin Herrera.

> Did you know that I offer custom development services and issuing invoices for
  sponsorships of releases and for contributions? Contact me (@clue) for details.
PK�]�TiE::phar-composer/LICENSEnu�[���The MIT License (MIT)

Copyright (c) 2013 Christian Lück

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.
PK�]�t��phar-composer/composer.jsonnu�[���{
    "name": "clue/phar-composer",
    "description": "Simple phar creation for any project managed via Composer",
    "keywords": ["executable phar", "build process", "bundle dependencies", "phar", "composer"],
    "homepage": "https://github.com/clue/phar-composer",
    "license": "MIT",
    "authors": [
        {
            "name": "Christian Lück",
            "email": "christian@clue.engineering"
        }
    ],
    "require": {
        "php": ">=5.3.6",
        "knplabs/packagist-api": "^1.0",
        "symfony/console": "^6.0 || ^5.0 || ^4.0 || ^3.0 || ^2.5",
        "symfony/finder": "^6.0 || ^5.0 || ^4.0 || ^3.0 || ^2.5",
        "symfony/process": "^6.0 || ^5.0 || ^4.0 || ^3.0 || ^2.5"
    },
    "require-dev": {
        "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.36"
    },
    "autoload": {
        "psr-4": {"Clue\\PharComposer\\": "src/"}
    },
    "bin": ["bin/phar-composer"],
    "scripts": {
        "build": "@php bin/build.php"
    }
}
PK�]Bv/�66!phar-composer/.github/FUNDING.ymlnu�[���github: clue
custom: https://clue.engineering/support
PK�]AxB-phar-composer/bin/phar-composernuȯ��#!/usr/bin/env php
<?php

if (file_exists(__DIR__ . '/../vendor/autoload.php')) {
    require __DIR__ . '/../vendor/autoload.php';
} elseif (file_exists(__DIR__ . '/../../../autoload.php')) {
    require __DIR__ . '/../../../autoload.php';
} else {
    fwrite(STDERR, 'ERROR: Composer dependencies not properly set up! Run "composer install" or see README.md for more details' . PHP_EOL);
    exit(1);
}

// hide PHP 8.1 deprecations
error_reporting(E_ALL & ~E_DEPRECATED);

$app = new Clue\PharComposer\App();
$app->run();
PK�]��V���phar-composer/CHANGELOG.mdnu�[���# Changelog

## 1.4.0 (2022-02-14)

*   Feature: Windows support, improve package path detection, and retry rename to fix slow network drives.
    (#129 and #130 by @clue)

*   Feature / Fix: Escape binary path when executing system binaries (git, php, composer).
    (#128 by @clue)

*   Drop legacy HHVM support due to lack of support.
    (#127 by @clue)

## 1.3.0 (2021-12-29)

*   Feature: Support Symfony 6 and PHP 8.1 release.
    (#122 and #123 by @clue)

*   Feature: Bundle `StubGenerator` and `Extract` from legacy herrera-io/box v1.6.1.
    (#119 by @clue)

*   Feature / Fix: Fix check for valid package URL.
    (#117 by @icedream)

*   Update project setup, use PSR-4 autoloading, drop `composer.lock` and instead lock PHP version when building phar.
    (#120 and #124 by @clue and #118 by @PaulRotmann)

*   Improve test suite and add `.gitattributes` to exclude dev files from exports.
    Update test suite to support PHPUnit 9 and test against PHP 8.1 release.
    (#121 and #125 by @clue)

## 1.2.0 (2020-12-11)

*   Feature: Support Composer 2.0!
    (#114 by @thojou and @clue)

*   Minor documentation improvements and simplify install instructions.
    (#98 and #99 by @clue)

*   Use GitHub actions for continuous integration (CI).
    (#112 by @SimonFrings and #113 by @szepeviktor)

## 1.1.0 (2019-11-22)

*   Feature: Update all dependencies and improve forward compatibility with symfony/console v5 through legacy v2.5.
    (#87 by @clue)

*   Feature: Significantly improve performance when adding phar contents.
    (#90 by @clue)

*   Feature: Support cloning projects from git SSH URLs.
    (#96 by @clue)

*   Feature: Ignore packages without autoload definition and missing vendor directory.
    (#94 by @clue)

*   Feature: Write phar to temporary file to support any extension and overwriting.
    (#93 by @clue)

*   Feature / Fix: Disable install subcommand on Windows.
    (#95 by @clue)

*   Improve test suite by adding PHPUnit to require-dev and support legacy PHP 5.3 through PHP 7.2 and HHVM,
    add tests for all commands and perform some minor code cleanup/maintenance,
    minor internal refactoring to clean up some unneeded code duplication and unneeded references and
    remove dedicated bundler classes, always bundle complete package.
    (#85, #86, #89 and #92 by @clue)

*   Add build script removing uneeded files and update development docs.
    (#91 by @clue)

## 1.0.0 (2015-11-15)

*   First stable release, now following SemVer.

*   Feature: Can now be installed as a `require-dev` Composer dependency and
    supports running as `./vendor/bin/phar-composer`.
    (#36 by @radford)

*   Fix: Actually exclude `vendor/` directory. This prevents processing all
    vendor files twice and reduces build time by 50%.
    (#38 by @radford)

*   Fix: Fix error reporting when processing invalid project paths.
    (#56 by @staabm and @clue)

*   Fix: Fix description of `phar-composer install` command.
    (#47 by @staabm)

*   Updated documentation, tests and project structure.
    (#54, #57, #58 and #59 by @clue)

## 0.5.0 (2014-07-10)

*   Feature: The `search` command is the new default if you do not pass any command
    ([#13](https://github.com/clue/phar-composer/pull/13)).
    You can now use the following command to get started:

    ```bash
    $ phar-composer
    ```

*   Fix: Pass through STDERR output of child processes instead of aborting
    ([#33](https://github.com/clue/phar-composer/pull/33))

*   Fix: Do not timeout when child process takes longer than 60s.
    This also helps users with slower internet connections.
    ([#31](https://github.com/clue/phar-composer/pull/31))

*   Fix: Update broken dependencies
    ([#18](https://github.com/clue/phar-composer/pull/18))

*   Fix: Fixed an undocumented config key
    ([#14](https://github.com/clue/phar-composer/pull/14), thanks @mikey179)

## 0.4.0 (2013-09-12)

*   Feature: New `install` command will now both build the given package and then
    install it into the system-wide bin directory `/usr/local/bin` (usually already
    in your `$PATH`). This works for any package name or URL just like with the
    `build` command, e.g.:

    ```bash
    $ phar-composer install phpunit/phpunit
    ```

    After some (lengthy) build output, you should now be able to run it by just issuing:

    ```bash
    $ phpunit
    ```

*   Feature: New `search` command provides an interactive command line search.
    It will ask for the package name and issue an search via packagist.org's API and
    present a list of matching packages. So if you don't know the exact package name,
    you can now use the following command:

    ```bash
    $ phar-composer search boris
    ```

*   Feature: Both `build` and `install` commands now also optionally accept an
    additional target directory to place the resulting phar into.

## 0.3.0 (2013-08-21)

*   Feature: Resulting phar files can now be executed on systems without
    ext-phar (#8). This vastly improves portability for legacy setups by including
    a small startup script which self-extracts the current archive into a temporary
    directory.

*   Feature: Resulting phar files can now be executed without the phar file name
    extension. E.g. this convenient feature now allows you to move your `~demo.phar`
    to `/usr/bin/demo` for easy system wide installations.

*   Fix: Resolving absolute paths to `vendor/autoload.php`

## 0.2.0 (2013-08-15)

*   Feature: Packages can now also be cloned from any git URLs (#9), like this:

    ```bash
    $ phar-composer build https://github.com/clue/phar-composer.git
    ```

    The above will clone the repository and check out the default branch.
    You can also specify either a tag or branch name very similar to how composer works:

    ```bash
    $ phar-composer build https://github.com/clue/phar-composer.git:dev-master
    ```

## 0.1.0 (2013-08-12)

*   Feature: Packages listed on packagist.org can now automatically be downloaded and installed
    prior to generating phar (#7), like this:

    ```bash
    $ phar-composer build clue/phar-composer
    ```

    The above will download and install the latest stable tagged release (if any).
    You can also specify a tagged version like this:

    ```bash
    $ phar-composer build clue/phar-composer:0.1.*
    ```

    Or you can specify to install the head of a given branch like this:

    ```bash
    $ phar-composer build clue/phar-composer:dev-master
    ```

## 0.0.2 (2013-05-25)

*   Feature: Bundle complete project directories

## 0.0.1 (2013-05-18)

*   First tagged release

PK�I]8&�t��ndjson-react/src/Encoder.phpnu�[���<?php

namespace RectorPrefix202411\Clue\React\NDJson;

use RectorPrefix202411\Evenement\EventEmitter;
use RectorPrefix202411\React\Stream\WritableStreamInterface;
/**
 * The Encoder / Serializer can be used to write any value, encode it as a JSON text and forward it to an output stream
 */
class Encoder extends EventEmitter implements WritableStreamInterface
{
    private $output;
    private $options;
    private $depth;
    private $closed = \false;
    /**
     * @param WritableStreamInterface $output
     * @param int $options
     * @param int $depth (requires PHP 5.5+)
     * @throws \InvalidArgumentException
     * @throws \BadMethodCallException
     */
    public function __construct(WritableStreamInterface $output, $options = 0, $depth = 512)
    {
        // @codeCoverageIgnoreStart
        if (\defined('JSON_PRETTY_PRINT') && $options & \JSON_PRETTY_PRINT) {
            throw new \InvalidArgumentException('Pretty printing not available for NDJSON');
        }
        if ($depth !== 512 && \PHP_VERSION < 5.5) {
            throw new \BadMethodCallException('Depth parameter is only supported on PHP 5.5+');
        }
        if (\defined('JSON_THROW_ON_ERROR')) {
            $options = $options & ~\JSON_THROW_ON_ERROR;
        }
        // @codeCoverageIgnoreEnd
        $this->output = $output;
        if (!$output->isWritable()) {
            $this->close();
            return;
        }
        $this->options = $options;
        $this->depth = $depth;
        $this->output->on('drain', array($this, 'handleDrain'));
        $this->output->on('error', array($this, 'handleError'));
        $this->output->on('close', array($this, 'close'));
    }
    public function write($data)
    {
        if ($this->closed) {
            return \false;
        }
        // we have to handle PHP warnings for legacy PHP < 5.5
        // certain values (such as INF etc.) emit a warning, but still encode successfully
        // @codeCoverageIgnoreStart
        if (\PHP_VERSION_ID < 50500) {
            $errstr = null;
            \set_error_handler(function ($_, $error) use(&$errstr) {
                $errstr = $error;
            });
            // encode data with options given in ctor (depth not supported)
            $data = \json_encode($data, $this->options);
            // always check error code and match missing error messages
            \restore_error_handler();
            $errno = \json_last_error();
            if (\defined('JSON_ERROR_UTF8') && $errno === \JSON_ERROR_UTF8) {
                // const JSON_ERROR_UTF8 added in PHP 5.3.3, but no error message assigned in legacy PHP < 5.5
                // this overrides PHP 5.3.14 only: https://3v4l.org/IGP8Z#v5314
                $errstr = 'Malformed UTF-8 characters, possibly incorrectly encoded';
            } elseif ($errno !== \JSON_ERROR_NONE && $errstr === null) {
                // error number present, but no error message applicable
                $errstr = 'Unknown error';
            }
            // abort stream if encoding fails
            if ($errno !== \JSON_ERROR_NONE || $errstr !== null) {
                $this->handleError(new \RuntimeException('Unable to encode JSON: ' . $errstr, $errno));
                return \false;
            }
        } else {
            // encode data