Skip to content

Instantly share code, notes, and snippets.

@imzhi
Forked from robopuff/paint
Created October 9, 2024 09:09
Show Gist options
  • Select an option

  • Save imzhi/5f794987032edcd31c8affad660da28c to your computer and use it in GitHub Desktop.

Select an option

Save imzhi/5f794987032edcd31c8affad660da28c to your computer and use it in GitHub Desktop.

Revisions

  1. @robopuff robopuff revised this gist Jun 27, 2018. 1 changed file with 29 additions and 18 deletions.
    47 changes: 29 additions & 18 deletions paint
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    #!/usr/bin/env php
    <?php

    define('VERSION', '1.0.21');
    define('VERSION', '1.0.24');
    define('DEFAULT_PIXEL', "\xE2\x96\x84");
    define('RC', "\e[0m");
    define('RCNL', RC . PHP_EOL);
    @@ -28,7 +28,7 @@ $flags = [
    'value_required' => false,
    'description' => 'Show version',
    'callback' => function () {
    echo colorHelp(sprintf("Paint (`%s`) v%s, (c) 2017 <robopuff>\n", CURRENT_FILE, VERSION));
    echo colorHelp(sprintf("Paint (`%s`) v%s, (c) 2017-2018 <robopuff>\n", CURRENT_FILE, VERSION));
    return false;
    }
    ],
    @@ -59,11 +59,13 @@ $flags = [
    'value_required' => false,
    'description' => 'Test terminal color & font capabilities. It should show two lines of different color.',
    'callback' => function () {
    echo drawChar([255,80,105], [105, 80, 255]) . str_repeat(DEFAULT_PIXEL, 9) . RC .
    drawChar([105, 80, 255], [255,80,105]) . str_repeat(DEFAULT_PIXEL, 9) . RC .
    echo drawChar([255,80,105], [105, 80, 255]) . str_repeat(DEFAULT_PIXEL, 3) . RC .
    drawChar([105, 80, 255], [255,80,105]) . str_repeat(DEFAULT_PIXEL, 3) . RC .
    ' ' . drawChar([105, 80, 255], [255, 80, 105]) . RC . drawChar([255, 80, 105], [105, 80, 255]) . RC .
    ' ' . drawChar([105, 80, 255], [255, 80, 105]) . RC .
    ' ' . drawChar([255, 80, 105], [105, 80, 255]) . RCNL;
    ' -' . DEFAULT_PIXEL . drawChar([255, 80, 105], [105, 80, 255]) . RC . DEFAULT_PIXEL . '-' .
    ' ' . drawChar([255, 80, 105], [255, 80, 105]) . RC . DEFAULT_PIXEL . PHP_EOL;
    return false;
    }
    ],
    '-x' => [
    @@ -79,16 +81,15 @@ $flags = [
    $source = imagecreatetruecolor(255, 255);

    for ($y = 0; $y < 255; $y++) {
    for ($x = 0; $x < 255; $x++) {
    $r = $x;
    $g = $y;
    $b = ($x + $y) / 2;

    for ($x = 0; $x < 255 * 2; $x++) {
    $r = 255 - $x;
    $g = 255 - $y;
    $b = (($x + $y) / 2);
    imagesetpixel($source, $x, $y, imagecolorallocate($source, $r, $g, $b));
    }
    }

    drawImage($source, 255, 255, $width, $height, $context);
    return false;
    }
    ],
    '-f' => [
    @@ -141,9 +142,13 @@ function drawChar(array $upper, array $lower = [], $char = DEFAULT_PIXEL, $clean
    return $char;
    }

    if ($upper == $lower) {
    return drawUpperPixel($upper) .' ' . ($clean ? RC : '');
    }

    return drawUpperPixel($upper) .
    drawLowerPixel(empty($lower) ? $upper : $lower, $char) .
    ($clean ? RC : "");
    ($clean ? RC : '');
    };

    // Draw background color (upper pixel)
    @@ -237,8 +242,7 @@ function drawImage($source, $imW, $imH, $width, $height, $flags = [])
    // Show an error
    function showError($error)
    {
    $bg = [200, 20, 70];
    echo drawChar($bg, [255,255,255], str_repeat(' ', 50)) . "\n";
    echo drawChar([200, 20, 70], [255,255,255], str_repeat(' ', 50)) . "\n";
    echo ' Error occurred' . str_repeat(' ', 50 - 15) . "\n";
    echo str_repeat(' ', 50) . RCNL . PHP_EOL;
    echo ' ' . colorHelp($error) . "\n\n";
    @@ -271,7 +275,7 @@ function helpMessage($flags)
    +#++:++#+ +#++:++#++: +#+ +#+ +:+ +#+ +#+
    +#+ +#+ +#+ +#+ +#+ +#+#+# +#+
    #+# #+# #+# #+# #+# #+#+# #+#
    ### ### ################# #### ### v
    ### ### ################# #### ### v
    ASCII;
    echo VERSION . RCNL . PHP_EOL;

    @@ -291,6 +295,8 @@ ASCII;
    }

    echo colorHelp($help) . PHP_EOL;

    $flags['-v']['callback']();
    return false;
    }

    @@ -312,7 +318,7 @@ if ($file[0] != '-' && (file_exists($file) || strpos($file, 'http') === 0)) {

    $context = [];
    $callbacks = [];
    foreach ($argv as $aid => $arg) {
    foreach (array_unique($argv) as $aid => $arg) {
    $key = $arg;
    $value = null;

    @@ -326,14 +332,19 @@ foreach ($argv as $aid => $arg) {
    if (isset($flags[$key])) {
    $context[$key] = $value;

    if (null !== $value && $flags[$key]['value'] === false) {
    showError("Param `{$key}` does not have a value");
    die();
    }

    if (isset($flags[$key]['callback'])) {
    $callbacks[] = [
    $flags[$key]['callback'],
    $value
    ];
    }
    } else {
    showError("Param `{$key}`` not found.");
    showError("Param `{$key}` not found.");
    die();
    }
    }
    @@ -352,7 +363,7 @@ if (empty($callbacks)) {
    }

    foreach ($callbacks as $vars) {
    list($callback, $value) = $vars;
    [$callback, $value] = $vars;
    try {
    if ($callback($termWidth, $termHeight, $value, $context) === false) {
    break;
  2. @robopuff robopuff revised this gist Apr 21, 2017. 1 changed file with 18 additions and 7 deletions.
    25 changes: 18 additions & 7 deletions paint
    Original file line number Diff line number Diff line change
    @@ -1,14 +1,18 @@
    #!/usr/bin/env php
    <?php

    define('VERSION', '1.0.18');
    define('VERSION', '1.0.21');
    define('DEFAULT_PIXEL', "\xE2\x96\x84");
    define('RC', "\e[0m");
    define('RCNL', RC . PHP_EOL);
    define('CURRENT_FILE', array_shift($argv));

    error_reporting(0);

    if (PHP_MAJOR_VERSION < 7) {
    die('Minimum PHP v7.0' . PHP_EOL);
    }

    // --------------------------------------------------------
    // Flags in use

    @@ -46,7 +50,7 @@ $flags = [
    'value' => true,
    'value_required' => true,
    'description' => 'Set width',
    'callback' => function (&$width, $h, $value) {
    'callback' => function (&$width, $_, $value) {
    $width = $value;
    }
    ],
    @@ -55,9 +59,11 @@ $flags = [
    'value_required' => false,
    'description' => 'Test terminal color & font capabilities. It should show two lines of different color.',
    'callback' => function () {
    echo drawChar([255,80,105], [105, 80, 255]) . str_repeat(DEFAULT_PIXEL, 19) . RC .
    echo drawChar([255,80,105], [105, 80, 255]) . str_repeat(DEFAULT_PIXEL, 9) . RC .
    drawChar([105, 80, 255], [255,80,105]) . str_repeat(DEFAULT_PIXEL, 9) . RC .
    ' ' . drawChar([105, 80, 255], [255, 80, 105]) . RC . drawChar([255, 80, 105], [105, 80, 255]) . RC .
    ' ' . drawChar([105, 80, 255], [255, 80, 105]) . RCNL;
    ' ' . drawChar([105, 80, 255], [255, 80, 105]) . RC .
    ' ' . drawChar([255, 80, 105], [105, 80, 255]) . RCNL;
    }
    ],
    '-x' => [
    @@ -69,7 +75,7 @@ $flags = [
    'value' => false,
    'value_required' => false,
    'description' => 'Draw palette of colours, good for terminal test',
    'callback' => function ($width, $height, $v, $context) {
    'callback' => function ($width, $height, $_, $context) {
    $source = imagecreatetruecolor(255, 255);

    for ($y = 0; $y < 255; $y++) {
    @@ -96,7 +102,7 @@ $flags = [
    throw new \Exception('Improper usage of `-f`, should be `-f`=[IMAGE]');
    }

    if (strpos($value, 'http') === 0) {
    if (strpos($value, 'http') === 0 || strpos($value, 'ftp') === 0) {
    $curl = curl_init($value);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HEADER, false);
    @@ -173,6 +179,11 @@ function drawImage($source, $imW, $imH, $width, $height, $flags = [])
    $height = $width / $r;
    }

    if ($width > $imW) {
    $width = $imW;
    $height = $imH;
    }

    $thumb = imagecreatetruecolor($width, $height);
    imagecopyresampled($thumb, $source, 0, 0, 0, 0, $width, $height, $imW, $imH);

    @@ -346,7 +357,7 @@ foreach ($callbacks as $vars) {
    if ($callback($termWidth, $termHeight, $value, $context) === false) {
    break;
    }
    } catch (\Exception $e) {
    } catch (Throwable $e) {
    showError(sprintf('%s: %s', $e->getCode(), $e->getMessage()));
    die();
    }
  3. @robopuff robopuff revised this gist Feb 16, 2017. 1 changed file with 11 additions and 10 deletions.
    21 changes: 11 additions & 10 deletions paint
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,8 @@
    #!/usr/bin/env php
    <?php

    define('VERSION', '1.0.16');
    define('DEFAULT_PIXEL', '');
    define('VERSION', '1.0.18');
    define('DEFAULT_PIXEL', "\xE2\x96\x84");
    define('RC', "\e[0m");
    define('RCNL', RC . PHP_EOL);
    define('CURRENT_FILE', array_shift($argv));
    @@ -56,7 +56,8 @@ $flags = [
    'description' => 'Test terminal color & font capabilities. It should show two lines of different color.',
    'callback' => function () {
    echo drawChar([255,80,105], [105, 80, 255]) . str_repeat(DEFAULT_PIXEL, 19) . RC .
    '|' . drawChar([105, 80, 255], [255, 80, 105]) . RC . '|' . PHP_EOL;
    ' ' . drawChar([105, 80, 255], [255, 80, 105]) . RC . drawChar([255, 80, 105], [105, 80, 255]) . RC .
    ' ' . drawChar([105, 80, 255], [255, 80, 105]) . RCNL;
    }
    ],
    '-x' => [
    @@ -253,13 +254,13 @@ function helpMessage($flags)
    {
    echo drawLowerPixel([200, 20, 70], '');
    echo <<<ASCII
    ::::::::: ::: ::::::::::::::: ::::::::::::::
    :+: :+: :+: :+: :+: :+:+: :+: :+:
    +:+ +:++:+ +:+ +:+ :+:+:+ +:+ +:+
    +#++:++#++#++:++#++: +#+ +#+ +:+ +#+ +#+
    +#+ +#+ +#+ +#+ +#+ +#+#+# +#+
    #+# #+# #+# #+# #+# #+#+# #+#
    ### ### ################# #### ### v
    ::::::::: ::: ::::::::::::::: ::::::::::::::
    :+: :+: :+: :+: :+: :+:+: :+: :+:
    +:+ +: ++:+ +:+ +:+ :+:+:+ +:+ +:+
    +#++:++#+ +#++:++#++: +#+ +#+ +:+ +#+ +#+
    +#+ +#+ +#+ +#+ +#+ +#+#+# +#+
    #+# #+# #+# #+# #+# #+#+# #+#
    ### ### ################# #### ### v
    ASCII;
    echo VERSION . RCNL . PHP_EOL;

  4. @robopuff robopuff revised this gist Feb 13, 2017. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions paint
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    #!/usr/bin/env php
    <?php

    define('VERSION', '1.0.15');
    define('VERSION', '1.0.16');
    define('DEFAULT_PIXEL', '');
    define('RC', "\e[0m");
    define('RCNL', RC . PHP_EOL);
    @@ -263,7 +263,7 @@ function helpMessage($flags)
    ASCII;
    echo VERSION . RCNL . PHP_EOL;

    $help = "Usage `{CURRENT_FILE}` [PARAMS] <FILE>\n";
    $help = sprintf("Usage `%s` [PARAMS] <FILE>\n", CURRENT_FILE);
    foreach ($flags as $flag => $options) {
    $flagHelp = $flag;

  5. @robopuff robopuff revised this gist Feb 13, 2017. 1 changed file with 10 additions and 1 deletion.
    11 changes: 10 additions & 1 deletion paint
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    #!/usr/bin/env php
    <?php

    define('VERSION', '1.0.14');
    define('VERSION', '1.0.15');
    define('DEFAULT_PIXEL', '');
    define('RC', "\e[0m");
    define('RCNL', RC . PHP_EOL);
    @@ -19,6 +19,15 @@ $flags = [
    'description' => 'Show this help message',
    'callback' => null
    ],
    '-v' => [
    'value' => false,
    'value_required' => false,
    'description' => 'Show version',
    'callback' => function () {
    echo colorHelp(sprintf("Paint (`%s`) v%s, (c) 2017 <robopuff>\n", CURRENT_FILE, VERSION));
    return false;
    }
    ],
    '-b' => [
    'value' => true,
    'value_required' => false,
  6. @robopuff robopuff revised this gist Feb 13, 2017. 1 changed file with 96 additions and 46 deletions.
    142 changes: 96 additions & 46 deletions paint
    Original file line number Diff line number Diff line change
    @@ -1,15 +1,24 @@
    #!/usr/bin/env php
    <?php

    define('VERSION', '1.0.13');
    define('VERSION', '1.0.14');
    define('DEFAULT_PIXEL', '');
    define('RC', "\e[0m");
    define('RCNL', RC . PHP_EOL);
    define('CURRENT_FILE', array_shift($argv));

    error_reporting(0);

    // --------------------------------------------------------
    // Flags in use

    $flags = [
    '-h' => [
    'value' => false,
    'value_required' => false,
    'description' => 'Show this help message',
    'callback' => null
    ],
    '-b' => [
    'value' => true,
    'value_required' => false,
    @@ -28,18 +37,10 @@ $flags = [
    'value' => true,
    'value_required' => true,
    'description' => 'Set width',
    'callback' => function (&$width, $height, $value) {
    'callback' => function (&$width, $h, $value) {
    $width = $value;
    }
    ],
    '-h' => [
    'value' => true,
    'value_required' => true,
    'description' => 'Set height',
    'callback' => function ($width, &$height, $value) {
    $height = $value;
    }
    ],
    '-t' => [
    'value' => false,
    'value_required' => false,
    @@ -49,11 +50,16 @@ $flags = [
    '|' . drawChar([105, 80, 255], [255, 80, 105]) . RC . '|' . PHP_EOL;
    }
    ],
    '-x' => [
    'value' => true,
    'value_required' => true,
    'description' => 'Pixelate image before showing'
    ],
    '-p' => [
    'value' => false,
    'value_required' => false,
    'description' => 'Draw palette of colours, good for terminal test',
    'callback' => function ($width, $height) {
    'callback' => function ($width, $height, $v, $context) {
    $source = imagecreatetruecolor(255, 255);

    for ($y = 0; $y < 255; $y++) {
    @@ -66,16 +72,15 @@ $flags = [
    }
    }

    imagefilter($source, IMG_FILTER_PIXELATE, 2, true);
    drawImage($source, 255, 255, $width, $height);
    drawImage($source, 255, 255, $width, $height, $context);
    }
    ],
    '-f' => [
    'value' => true,
    'value_required' => true,
    'description' => 'Draw image provided in [VALUE], can combine with `-b` but `-f` must be provided last.' .
    'description' => 'Draw image provided in [VALUE], can combine with `-b, -w` but `-f` must be provided last.' .
    ' Can be skipped if <FILE> is provided.',
    'callback' => function ($width, $height, $value) {
    'callback' => function ($width, $height, $value, $context) {
    $content = null;
    if (!$value) {
    throw new \Exception('Improper usage of `-f`, should be `-f`=[IMAGE]');
    @@ -88,7 +93,7 @@ $flags = [
    $content = curl_exec($curl);
    curl_close($curl);
    } elseif (!file_exists($value) || !is_readable($value)) {
    throw new \Exception("Cannot find file `{$value}`");
    throw new \Exception("Cannot find file `{$value}`", 0x1f1);
    }

    if (!$content) {
    @@ -98,13 +103,13 @@ $flags = [
    $source = imagecreatefromstring($content);

    if (!$source) {
    throw new \Exception("Cannot read `{$value}` as image");
    throw new \Exception("Cannot read `{$value}` as image", 0x1f2);
    }

    $imW = imagesx($source);
    $imH = imagesy($source);
    imagefilter($source, IMG_FILTER_PIXELATE, 2, true);
    drawImage($source, $imW, $imH, $width, $height);
    drawImage($source, $imW, $imH, $width, $height, $context);
    imagedestroy($source);
    }
    ]
    @@ -144,7 +149,7 @@ function drawLowerPixel(array $color = [], $char = DEFAULT_PIXEL)
    }

    // Draw image pixel by pixel (with resize)
    function drawImage($source, $imW, $imH, $width, $height)
    function drawImage($source, $imW, $imH, $width, $height, $flags = [])
    {
    $r = $imW / $imH;

    @@ -161,6 +166,10 @@ function drawImage($source, $imW, $imH, $width, $height)
    $thumb = imagecreatetruecolor($width, $height);
    imagecopyresampled($thumb, $source, 0, 0, 0, 0, $width, $height, $imW, $imH);

    if (isset($flags['-x'])) {
    imagefilter($thumb, IMG_FILTER_PIXELATE, (int)$flags['-x'], true);
    }

    for ($y = 0; $y < imagesy($thumb) - 1; $y++) {
    if ($y % 2 != 0) {
    continue;
    @@ -204,6 +213,16 @@ function drawImage($source, $imW, $imH, $width, $height)
    imagedestroy($thumb);
    }

    // Show an error
    function showError($error)
    {
    $bg = [200, 20, 70];
    echo drawChar($bg, [255,255,255], str_repeat(' ', 50)) . "\n";
    echo ' Error occurred' . str_repeat(' ', 50 - 15) . "\n";
    echo str_repeat(' ', 50) . RCNL . PHP_EOL;
    echo ' ' . colorHelp($error) . "\n\n";
    }

    // Add color content
    function colorHelp($content)
    {
    @@ -220,20 +239,9 @@ function colorHelp($content)
    ], $content);
    }

    // --------------------------------------------------------
    // Terminal operations

    $termWidth = (int)exec('tput cols') - 1;
    $termHeight = 0;

    $currentFile = array_shift($argv);
    $file = end($argv);

    if ($file[0] != '-' && (file_exists($file) || strpos($file, 'http') === 0)) {
    $argv[] = "-f={$file}";
    }

    if (count($argv) < 1) {
    // Show help message
    function helpMessage($flags)
    {
    echo drawLowerPixel([200, 20, 70], '');
    echo <<<ASCII
    ::::::::: ::: ::::::::::::::: ::::::::::::::
    @@ -246,7 +254,7 @@ if (count($argv) < 1) {
    ASCII;
    echo VERSION . RCNL . PHP_EOL;

    $help = "Usage `{$currentFile}` [PARAMS] <FILE>\n";
    $help = "Usage `{CURRENT_FILE}` [PARAMS] <FILE>\n";
    foreach ($flags as $flag => $options) {
    $flagHelp = $flag;

    @@ -262,9 +270,27 @@ ASCII;
    }

    echo colorHelp($help) . PHP_EOL;
    die();
    return false;
    }

    $flags['-h']['callback'] = function () use ($flags) {
    return helpMessage($flags);
    };

    // --------------------------------------------------------
    // Terminal operations

    $termWidth = (int)exec('tput cols') - 1;
    $termHeight = 0;

    $file = end($argv);
    if ($file[0] != '-' && (file_exists($file) || strpos($file, 'http') === 0)) {
    array_pop($argv);
    $argv[] = "-f={$file}";
    }

    $context = [];
    $callbacks = [];
    foreach ($argv as $aid => $arg) {
    $key = $arg;
    $value = null;
    @@ -277,18 +303,42 @@ foreach ($argv as $aid => $arg) {
    }

    if (isset($flags[$key])) {
    $callback = $flags[$key]['callback'];
    try {
    if ($callback($termWidth, $termHeight, $value) === false) {
    break;
    }
    } catch (\Exception $e) {
    $bg = [200, 20, 70];
    echo drawChar($bg, [255,255,255], str_repeat(' ', 50)) . "\n";
    echo ' Error occurred' . str_repeat(' ', 50 - 15) . "\n";
    echo str_repeat(' ', 50) . RCNL . PHP_EOL;
    echo ' ' . colorHelp($e->getMessage()) . "\n\n";
    $context[$key] = $value;

    if (isset($flags[$key]['callback'])) {
    $callbacks[] = [
    $flags[$key]['callback'],
    $value
    ];
    }
    } else {
    showError("Param `{$key}`` not found.");
    die();
    }
    }

    if (empty($callbacks)) {
    if (!empty($context)) {
    showError(sprintf(
    'Provided flags `%s` cannot be used by themselves as they don\'t provide any action.',
    implode(', ', array_keys($context))
    ));
    die();
    }

    helpMessage($flags);
    die();
    }

    foreach ($callbacks as $vars) {
    list($callback, $value) = $vars;
    try {
    if ($callback($termWidth, $termHeight, $value, $context) === false) {
    break;
    }
    } catch (\Exception $e) {
    showError(sprintf('%s: %s', $e->getCode(), $e->getMessage()));
    die();
    }
    }

  7. @robopuff robopuff revised this gist Feb 9, 2017. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions paint
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    #!/usr/bin/env php
    <?php

    define('VERSION', '1.0.12');
    define('VERSION', '1.0.13');
    define('DEFAULT_PIXEL', '');
    define('RC', "\e[0m");
    define('RCNL', RC . PHP_EOL);
    @@ -45,7 +45,7 @@ $flags = [
    'value_required' => false,
    'description' => 'Test terminal color & font capabilities. It should show two lines of different color.',
    'callback' => function () {
    echo drawChar([255,80,105], [105, 80, 255]) . str_repeat(drawLowerPixel([]), 20) . RC .
    echo drawChar([255,80,105], [105, 80, 255]) . str_repeat(DEFAULT_PIXEL, 19) . RC .
    '|' . drawChar([105, 80, 255], [255, 80, 105]) . RC . '|' . PHP_EOL;
    }
    ],
  8. @robopuff robopuff revised this gist Feb 9, 2017. 1 changed file with 6 additions and 3 deletions.
    9 changes: 6 additions & 3 deletions paint
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    #!/usr/bin/env php
    <?php

    define('VERSION', '1.0.11');
    define('VERSION', '1.0.12');
    define('DEFAULT_PIXEL', '');
    define('RC', "\e[0m");
    define('RCNL', RC . PHP_EOL);
    @@ -45,7 +45,8 @@ $flags = [
    'value_required' => false,
    'description' => 'Test terminal color & font capabilities. It should show two lines of different color.',
    'callback' => function () {
    echo drawChar([255,80,105], [105, 80, 255]) . str_repeat(drawLowerPixel([]), 20) . RCNL;
    echo drawChar([255,80,105], [105, 80, 255]) . str_repeat(drawLowerPixel([]), 20) . RC .
    '|' . drawChar([105, 80, 255], [255, 80, 105]) . RC . '|' . PHP_EOL;
    }
    ],
    '-p' => [
    @@ -278,7 +279,9 @@ foreach ($argv as $aid => $arg) {
    if (isset($flags[$key])) {
    $callback = $flags[$key]['callback'];
    try {
    $callback($termWidth, $termHeight, $value);
    if ($callback($termWidth, $termHeight, $value) === false) {
    break;
    }
    } catch (\Exception $e) {
    $bg = [200, 20, 70];
    echo drawChar($bg, [255,255,255], str_repeat(' ', 50)) . "\n";
  9. @robopuff robopuff revised this gist Feb 9, 2017. 1 changed file with 12 additions and 11 deletions.
    23 changes: 12 additions & 11 deletions paint
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    #!/usr/bin/env php
    <?php

    define('VERSION', '1.0.0');
    define('VERSION', '1.0.11');
    define('DEFAULT_PIXEL', '');
    define('RC', "\e[0m");
    define('RCNL', RC . PHP_EOL);
    @@ -206,16 +206,17 @@ function drawImage($source, $imW, $imH, $width, $height)
    // Add color content
    function colorHelp($content)
    {
    $content = preg_replace_callback('/\[(.*?)\]/', function ($matches) {
    return drawChar([45, 35, 8], [255, 247, 97], $matches[0], true);
    }, $content);
    $content = preg_replace_callback('/\`(.*?)\`/', function ($matches) {
    return drawChar([35, 13, 14], [255, 100, 108], " {$matches[1]} ", true);
    }, $content);
    $content = preg_replace_callback('/\<(.*?)\>/', function ($matches) {
    return drawChar([10, 38, 13], [102, 245, 119], $matches[0], true);
    }, $content);
    return $content;
    return preg_replace_callback_array([
    '/\[(.*?)\]/' => function ($matches) {
    return drawChar([45, 35, 8], [255, 247, 97], $matches[0], true);
    },
    '/\`(.*?)\`/' => function ($matches) {
    return drawChar([35, 13, 14], [255, 100, 108], " {$matches[1]} ", true);
    },
    '/\<(.*?)\>/' => function ($matches) {
    return drawChar([10, 38, 13], [102, 245, 119], $matches[0], true);
    }
    ], $content);
    }

    // --------------------------------------------------------
  10. @robopuff robopuff revised this gist Feb 9, 2017. 1 changed file with 20 additions and 17 deletions.
    37 changes: 20 additions & 17 deletions paint
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,6 @@
    #!/usr/bin/env php
    <?php

    error_reporting(0);

    define('VERSION', '1.0.0');
    define('DEFAULT_PIXEL', '');
    define('RC', "\e[0m");
    @@ -79,7 +77,7 @@ $flags = [
    'callback' => function ($width, $height, $value) {
    $content = null;
    if (!$value) {
    throw new \Exception('Improper usage of -f, should be -f=[IMAGE]');
    throw new \Exception('Improper usage of `-f`, should be `-f`=[IMAGE]');
    }

    if (strpos($value, 'http') === 0) {
    @@ -162,15 +160,15 @@ function drawImage($source, $imW, $imH, $width, $height)
    $thumb = imagecreatetruecolor($width, $height);
    imagecopyresampled($thumb, $source, 0, 0, 0, 0, $width, $height, $imW, $imH);

    for ($y = 0; $y < $height - 1; $y++) {
    for ($y = 0; $y < imagesy($thumb) - 1; $y++) {
    if ($y % 2 != 0) {
    continue;
    }

    $lastUpper = [];
    $lastLower = [];

    for ($x = 0; $x < $width - 1; $x++) {
    for ($x = 0; $x < imagesx($thumb) - 1; $x++) {
    $c1 = imagecolorat($thumb, $x, $y);
    $c2 = imagecolorat($thumb, $x, $y + 1);

    @@ -205,6 +203,21 @@ function drawImage($source, $imW, $imH, $width, $height)
    imagedestroy($thumb);
    }

    // Add color content
    function colorHelp($content)
    {
    $content = preg_replace_callback('/\[(.*?)\]/', function ($matches) {
    return drawChar([45, 35, 8], [255, 247, 97], $matches[0], true);
    }, $content);
    $content = preg_replace_callback('/\`(.*?)\`/', function ($matches) {
    return drawChar([35, 13, 14], [255, 100, 108], " {$matches[1]} ", true);
    }, $content);
    $content = preg_replace_callback('/\<(.*?)\>/', function ($matches) {
    return drawChar([10, 38, 13], [102, 245, 119], $matches[0], true);
    }, $content);
    return $content;
    }

    // --------------------------------------------------------
    // Terminal operations

    @@ -246,17 +259,7 @@ ASCII;
    $help .= " {$flagHelp}\n {$options['description']}\n";
    }

    $help = preg_replace_callback('/\[(.*?)\]/', function ($matches) {
    return drawChar([45, 35, 8], [255, 247, 97], $matches[0], true);
    }, $help);
    $help = preg_replace_callback('/\`(.*?)\`/', function ($matches) {
    return drawChar([35, 13, 14], [255, 100, 108], " {$matches[1]} ", true);
    }, $help);
    $help = preg_replace_callback('/\<(.*?)\>/', function ($matches) {
    return drawChar([10, 38, 13], [102, 245, 119], $matches[0], true);
    }, $help);

    echo "{$help}\n";
    echo colorHelp($help) . PHP_EOL;
    die();
    }

    @@ -280,7 +283,7 @@ foreach ($argv as $aid => $arg) {
    echo drawChar($bg, [255,255,255], str_repeat(' ', 50)) . "\n";
    echo ' Error occurred' . str_repeat(' ', 50 - 15) . "\n";
    echo str_repeat(' ', 50) . RCNL . PHP_EOL;
    echo ' ' . $e->getMessage() . "\n\n";
    echo ' ' . colorHelp($e->getMessage()) . "\n\n";
    }
    }
    }
  11. @robopuff robopuff revised this gist Feb 9, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion paint
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    #!/usr/bin/env php
    <?php

    error_repoting(0);
    error_reporting(0);

    define('VERSION', '1.0.0');
    define('DEFAULT_PIXEL', '');
  12. @robopuff robopuff revised this gist Feb 9, 2017. 1 changed file with 76 additions and 32 deletions.
    108 changes: 76 additions & 32 deletions paint
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,13 @@
    #!/usr/bin/env php
    <?php

    error_repoting(0);

    define('VERSION', '1.0.0');
    define('DEFAULT_PIXEL', '');
    define('RC', "\e[0m");
    define('RCNL', RC . PHP_EOL);

    // --------------------------------------------------------
    // Flags in use

    @@ -40,7 +47,7 @@ $flags = [
    'value_required' => false,
    'description' => 'Test terminal color & font capabilities. It should show two lines of different color.',
    'callback' => function () {
    echo str_repeat(drawPixel([255, 80, 105], [105, 80, 255]), 20) . PHP_EOL;
    echo drawChar([255,80,105], [105, 80, 255]) . str_repeat(drawLowerPixel([]), 20) . RCNL;
    }
    ],
    '-p' => [
    @@ -107,16 +114,36 @@ $flags = [
    // --------------------------------------------------------
    // Helper functions

    // Draw single pixel with subpixel as lower block char
    function drawPixel(array $upper, array $lower = [], $char = '') // •
    // Draw single pixel with sub-pixel as lower block char
    function drawChar(array $upper, array $lower = [], $char = DEFAULT_PIXEL, $clean = false) // •
    {
    $upper = implode(';', $upper);
    $lower = empty($lower) ? $upper : implode(';', $lower);
    if (empty($upper) && empty($lower)) {
    return $char;
    }

    return "\e[48;2;{$upper}m" .
    "\e[38;2;{$lower}m{$char}\e[0m";
    return drawUpperPixel($upper) .
    drawLowerPixel(empty($lower) ? $upper : $lower, $char) .
    ($clean ? RC : "");
    };

    // Draw background color (upper pixel)
    function drawUpperPixel(array $color)
    {
    $color = implode(';', $color);
    return "\e[48;2;{$color}m";
    }

    // Draw foreground color (lower pixel)
    function drawLowerPixel(array $color = [], $char = DEFAULT_PIXEL)
    {
    if (empty($color)) {
    return $char;
    }

    $color = implode(';', $color);
    return "\e[38;2;{$color}m{$char}";
    }

    // Draw image pixel by pixel (with resize)
    function drawImage($source, $imW, $imH, $width, $height)
    {
    @@ -140,40 +167,44 @@ function drawImage($source, $imW, $imH, $width, $height)
    continue;
    }

    $lastUpper = [];
    $lastLower = [];

    for ($x = 0; $x < $width - 1; $x++) {
    $c1 = imagecolorat($thumb, $x, $y);
    $c2 = imagecolorat($thumb, $x, $y + 1);

    echo drawPixel([
    $upper = [
    ($c1 >> 16) & 0xFF,
    ($c1 >> 8) & 0xFF,
    ($c1) & 0xFF,
    ], [
    ];

    $lower = $drawLower = [
    ($c2 >> 16) & 0xFF,
    ($c2 >> 8) & 0xFF,
    ($c2) & 0xFF,
    ]);
    ];

    if ($lastUpper != $upper) {
    echo drawUpperPixel($upper);
    }

    if ($lastLower == $lower) {
    $drawLower = [];
    }

    echo drawLowerPixel($drawLower);

    $lastLower = $lower;
    $lastUpper = $upper;
    }
    echo PHP_EOL;
    echo RCNL;
    }

    imagedestroy($thumb);
    }

    function parseError($e)
    {
    $bg = [200, 20, 70];
    echo str_repeat(drawPixel($bg, [], ' '), 50) . PHP_EOL;
    echo drawPixel($bg, [255, 255, 255], ' Error occured');
    echo str_repeat(drawPixel($bg, [], ' '), 50 - 14) . PHP_EOL;
    echo str_repeat(drawPixel($bg, [], ' '), 50) . "\n\n";
    echo ' ' . $e->getMessage() . "\n\n";
    }

    if (!class_exists('Error', false)) {
    class Error extends \Exception { }
    }

    // --------------------------------------------------------
    // Terminal operations

    @@ -188,6 +219,18 @@ if ($file[0] != '-' && (file_exists($file) || strpos($file, 'http') === 0)) {
    }

    if (count($argv) < 1) {
    echo drawLowerPixel([200, 20, 70], '');
    echo <<<ASCII
    ::::::::: ::: ::::::::::::::: ::::::::::::::
    :+: :+: :+: :+: :+: :+:+: :+: :+:
    +:+ +:++:+ +:+ +:+ :+:+:+ +:+ +:+
    +#++:++#++#++:++#++: +#+ +#+ +:+ +#+ +#+
    +#+ +#+ +#+ +#+ +#+ +#+#+# +#+
    #+# #+# #+# #+# #+# #+#+# #+#
    ### ### ################# #### ### v
    ASCII;
    echo VERSION . RCNL . PHP_EOL;

    $help = "Usage `{$currentFile}` [PARAMS] <FILE>\n";
    foreach ($flags as $flag => $options) {
    $flagHelp = $flag;
    @@ -204,20 +247,19 @@ if (count($argv) < 1) {
    }

    $help = preg_replace_callback('/\[(.*?)\]/', function ($matches) {
    return drawPixel([45, 35, 8], [255, 247, 97], $matches[0]);
    return drawChar([45, 35, 8], [255, 247, 97], $matches[0], true);
    }, $help);
    $help = preg_replace_callback('/\`(.*?)\`/', function ($matches) {
    return drawPixel([35, 13, 14], [255, 100, 108], " {$matches[1]} ");
    return drawChar([35, 13, 14], [255, 100, 108], " {$matches[1]} ", true);
    }, $help);
    $help = preg_replace_callback('/\<(.*?)\>/', function ($matches) {
    return drawPixel([10, 38, 13], [102, 245, 119], $matches[0]);
    return drawChar([10, 38, 13], [102, 245, 119], $matches[0], true);
    }, $help);

    echo "{$help}\n";
    die();
    }

    //echo "\e[H\e[2J\e[H";
    foreach ($argv as $aid => $arg) {
    $key = $arg;
    $value = null;
    @@ -234,9 +276,11 @@ foreach ($argv as $aid => $arg) {
    try {
    $callback($termWidth, $termHeight, $value);
    } catch (\Exception $e) {
    parseError($e);
    } catch (\Error $e) {
    parseError($e);
    $bg = [200, 20, 70];
    echo drawChar($bg, [255,255,255], str_repeat(' ', 50)) . "\n";
    echo ' Error occurred' . str_repeat(' ', 50 - 15) . "\n";
    echo str_repeat(' ', 50) . RCNL . PHP_EOL;
    echo ' ' . $e->getMessage() . "\n\n";
    }
    }
    }
  13. @robopuff robopuff revised this gist Feb 9, 2017. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions paint
    Original file line number Diff line number Diff line change
    @@ -132,8 +132,6 @@ function drawImage($source, $imW, $imH, $width, $height)
    $height = $width / $r;
    }

    $height = $height / 1.25;

    $thumb = imagecreatetruecolor($width, $height);
    imagecopyresampled($thumb, $source, 0, 0, 0, 0, $width, $height, $imW, $imH);

  14. @robopuff robopuff revised this gist Feb 9, 2017. 1 changed file with 2 additions and 4 deletions.
    6 changes: 2 additions & 4 deletions paint
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,6 @@
    #!/usr/bin/env php
    <?php

    error_reporting(0);

    // --------------------------------------------------------
    // Flags in use

    @@ -139,12 +137,12 @@ function drawImage($source, $imW, $imH, $width, $height)
    $thumb = imagecreatetruecolor($width, $height);
    imagecopyresampled($thumb, $source, 0, 0, 0, 0, $width, $height, $imW, $imH);

    for ($y = 0; $y < $height; $y++) {
    for ($y = 0; $y < $height - 1; $y++) {
    if ($y % 2 != 0) {
    continue;
    }

    for ($x = 0; $x < $width; $x++) {
    for ($x = 0; $x < $width - 1; $x++) {
    $c1 = imagecolorat($thumb, $x, $y);
    $c2 = imagecolorat($thumb, $x, $y + 1);

  15. @robopuff robopuff revised this gist Feb 9, 2017. 1 changed file with 8 additions and 0 deletions.
    8 changes: 8 additions & 0 deletions paint
    Original file line number Diff line number Diff line change
    @@ -37,6 +37,14 @@ $flags = [
    $height = $value;
    }
    ],
    '-t' => [
    'value' => false,
    'value_required' => false,
    'description' => 'Test terminal color & font capabilities. It should show two lines of different color.',
    'callback' => function () {
    echo str_repeat(drawPixel([255, 80, 105], [105, 80, 255]), 20) . PHP_EOL;
    }
    ],
    '-p' => [
    'value' => false,
    'value_required' => false,
  16. @robopuff robopuff revised this gist Feb 9, 2017. 1 changed file with 18 additions and 8 deletions.
    26 changes: 18 additions & 8 deletions paint
    Original file line number Diff line number Diff line change
    @@ -102,7 +102,7 @@ $flags = [
    // Helper functions

    // Draw single pixel with subpixel as lower block char
    function drawPixel(array $upper, array $lower = [], $char = '')
    function drawPixel(array $upper, array $lower = [], $char = '') // •
    {
    $upper = implode(';', $upper);
    $lower = empty($lower) ? $upper : implode(';', $lower);
    @@ -166,9 +166,8 @@ function parseError($e)
    echo ' ' . $e->getMessage() . "\n\n";
    }

    if (!class_exists('Error')) {
    class Error extends \Exception {
    }
    if (!class_exists('Error', false)) {
    class Error extends \Exception { }
    }

    // --------------------------------------------------------
    @@ -185,7 +184,7 @@ if ($file[0] != '-' && (file_exists($file) || strpos($file, 'http') === 0)) {
    }

    if (count($argv) < 1) {
    echo "Usage {$currentFile} [PARAMS] <FILE>\n";
    $help = "Usage `{$currentFile}` [PARAMS] <FILE>\n";
    foreach ($flags as $flag => $options) {
    $flagHelp = $flag;

    @@ -197,13 +196,24 @@ if (count($argv) < 1) {
    }
    }

    echo " {$flagHelp}\n {$options['description']}\n";

    $help .= " {$flagHelp}\n {$options['description']}\n";
    }

    $help = preg_replace_callback('/\[(.*?)\]/', function ($matches) {
    return drawPixel([45, 35, 8], [255, 247, 97], $matches[0]);
    }, $help);
    $help = preg_replace_callback('/\`(.*?)\`/', function ($matches) {
    return drawPixel([35, 13, 14], [255, 100, 108], " {$matches[1]} ");
    }, $help);
    $help = preg_replace_callback('/\<(.*?)\>/', function ($matches) {
    return drawPixel([10, 38, 13], [102, 245, 119], $matches[0]);
    }, $help);

    echo "{$help}\n";
    die();
    }

    echo "\e[H\e[2J\e[H";
    //echo "\e[H\e[2J\e[H";
    foreach ($argv as $aid => $arg) {
    $key = $arg;
    $value = null;
  17. @robopuff robopuff revised this gist Feb 8, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion paint
    Original file line number Diff line number Diff line change
    @@ -203,7 +203,7 @@ if (count($argv) < 1) {
    die();
    }

    echo "\033[H\e[2J\e[H";
    echo "\e[H\e[2J\e[H";
    foreach ($argv as $aid => $arg) {
    $key = $arg;
    $value = null;
  18. @robopuff robopuff revised this gist Feb 8, 2017. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions paint
    Original file line number Diff line number Diff line change
    @@ -54,7 +54,7 @@ $flags = [
    }
    }

    imagefilter($source, IMG_FILTER_PIXELATE, 3);
    imagefilter($source, IMG_FILTER_PIXELATE, 2, true);
    drawImage($source, 255, 255, $width, $height);
    }
    ],
    @@ -91,7 +91,7 @@ $flags = [

    $imW = imagesx($source);
    $imH = imagesy($source);
    imagefilter($source, IMG_FILTER_PIXELATE, 3, true);
    imagefilter($source, IMG_FILTER_PIXELATE, 2, true);
    drawImage($source, $imW, $imH, $width, $height);
    imagedestroy($source);
    }
  19. @robopuff robopuff created this gist Feb 8, 2017.
    230 changes: 230 additions & 0 deletions paint
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,230 @@
    #!/usr/bin/env php
    <?php

    error_reporting(0);

    // --------------------------------------------------------
    // Flags in use

    $flags = [
    '-b' => [
    'value' => true,
    'value_required' => false,
    'description' => 'Resize to [VALUE] box, if no value provided then terminal height is used',
    'callback' => function (&$width, &$height, $value = null) {
    if ($value) {
    $height = $value;
    } else {
    $height = ((int)exec('tput lines'));
    }

    $width = $height;
    }
    ],
    '-w' => [
    'value' => true,
    'value_required' => true,
    'description' => 'Set width',
    'callback' => function (&$width, $height, $value) {
    $width = $value;
    }
    ],
    '-h' => [
    'value' => true,
    'value_required' => true,
    'description' => 'Set height',
    'callback' => function ($width, &$height, $value) {
    $height = $value;
    }
    ],
    '-p' => [
    'value' => false,
    'value_required' => false,
    'description' => 'Draw palette of colours, good for terminal test',
    'callback' => function ($width, $height) {
    $source = imagecreatetruecolor(255, 255);

    for ($y = 0; $y < 255; $y++) {
    for ($x = 0; $x < 255; $x++) {
    $r = $x;
    $g = $y;
    $b = ($x + $y) / 2;

    imagesetpixel($source, $x, $y, imagecolorallocate($source, $r, $g, $b));
    }
    }

    imagefilter($source, IMG_FILTER_PIXELATE, 3);
    drawImage($source, 255, 255, $width, $height);
    }
    ],
    '-f' => [
    'value' => true,
    'value_required' => true,
    'description' => 'Draw image provided in [VALUE], can combine with `-b` but `-f` must be provided last.' .
    ' Can be skipped if <FILE> is provided.',
    'callback' => function ($width, $height, $value) {
    $content = null;
    if (!$value) {
    throw new \Exception('Improper usage of -f, should be -f=[IMAGE]');
    }

    if (strpos($value, 'http') === 0) {
    $curl = curl_init($value);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HEADER, false);
    $content = curl_exec($curl);
    curl_close($curl);
    } elseif (!file_exists($value) || !is_readable($value)) {
    throw new \Exception("Cannot find file `{$value}`");
    }

    if (!$content) {
    $content = file_get_contents($value);
    }

    $source = imagecreatefromstring($content);

    if (!$source) {
    throw new \Exception("Cannot read `{$value}` as image");
    }

    $imW = imagesx($source);
    $imH = imagesy($source);
    imagefilter($source, IMG_FILTER_PIXELATE, 3, true);
    drawImage($source, $imW, $imH, $width, $height);
    imagedestroy($source);
    }
    ]
    ];

    // --------------------------------------------------------
    // Helper functions

    // Draw single pixel with subpixel as lower block char
    function drawPixel(array $upper, array $lower = [], $char = '')
    {
    $upper = implode(';', $upper);
    $lower = empty($lower) ? $upper : implode(';', $lower);

    return "\e[48;2;{$upper}m" .
    "\e[38;2;{$lower}m{$char}\e[0m";
    };

    // Draw image pixel by pixel (with resize)
    function drawImage($source, $imW, $imH, $width, $height)
    {
    $r = $imW / $imH;

    if ($height > 0) {
    if ($width > $height) {
    $height = $width / $r;
    } else {
    $width = $height * $r;
    }
    } else {
    $height = $width / $r;
    }

    $height = $height / 1.25;

    $thumb = imagecreatetruecolor($width, $height);
    imagecopyresampled($thumb, $source, 0, 0, 0, 0, $width, $height, $imW, $imH);

    for ($y = 0; $y < $height; $y++) {
    if ($y % 2 != 0) {
    continue;
    }

    for ($x = 0; $x < $width; $x++) {
    $c1 = imagecolorat($thumb, $x, $y);
    $c2 = imagecolorat($thumb, $x, $y + 1);

    echo drawPixel([
    ($c1 >> 16) & 0xFF,
    ($c1 >> 8) & 0xFF,
    ($c1) & 0xFF,
    ], [
    ($c2 >> 16) & 0xFF,
    ($c2 >> 8) & 0xFF,
    ($c2) & 0xFF,
    ]);
    }
    echo PHP_EOL;
    }

    imagedestroy($thumb);
    }

    function parseError($e)
    {
    $bg = [200, 20, 70];
    echo str_repeat(drawPixel($bg, [], ' '), 50) . PHP_EOL;
    echo drawPixel($bg, [255, 255, 255], ' Error occured');
    echo str_repeat(drawPixel($bg, [], ' '), 50 - 14) . PHP_EOL;
    echo str_repeat(drawPixel($bg, [], ' '), 50) . "\n\n";
    echo ' ' . $e->getMessage() . "\n\n";
    }

    if (!class_exists('Error')) {
    class Error extends \Exception {
    }
    }

    // --------------------------------------------------------
    // Terminal operations

    $termWidth = (int)exec('tput cols') - 1;
    $termHeight = 0;

    $currentFile = array_shift($argv);
    $file = end($argv);

    if ($file[0] != '-' && (file_exists($file) || strpos($file, 'http') === 0)) {
    $argv[] = "-f={$file}";
    }

    if (count($argv) < 1) {
    echo "Usage {$currentFile} [PARAMS] <FILE>\n";
    foreach ($flags as $flag => $options) {
    $flagHelp = $flag;

    if ($options['value']) {
    if ($options['value_required']) {
    $flagHelp .= "=[VALUE]";
    } else {
    $flagHelp .= ", {$flag}=[VALUE]";
    }
    }

    echo " {$flagHelp}\n {$options['description']}\n";

    }
    die();
    }

    echo "\033[H\e[2J\e[H";
    foreach ($argv as $aid => $arg) {
    $key = $arg;
    $value = null;

    $pos = strpos($arg, '=');

    if ($pos > 0) {
    $key = substr($arg, 0, $pos);
    $value = substr($arg, $pos + 1);
    }

    if (isset($flags[$key])) {
    $callback = $flags[$key]['callback'];
    try {
    $callback($termWidth, $termHeight, $value);
    } catch (\Exception $e) {
    parseError($e);
    } catch (\Error $e) {
    parseError($e);
    }
    }
    }

    __halt_compiler();