Author: 7uk80cn3143e

  • nefit-easy-cli

    Nefit Easy™ command line interface

    Command line interface for communications with Nefit/Bosch backend.

    Use in moderation!

    Each command that you execute using this tool will set up a new connection to the backend, which is relatively CPU-intensive (for both the client and the backend).

    If you want to run commands periodically (say, more than once every few minutes), you should consider running the HTTP server, which opens a connection to the backend at startup and reuses it for all commands sent to it. The HTTP server will (eventually) support all the commands that the CLI tool supports.

    Installation

    This library requires Node.js 4.0.0 or later.

    $ npm i nefit-easy-cli -g
    

    This will install the easy client in a well-known “bin/” directory (npm config get prefix will show you where)

    Options

    
    easy – Nefit Easy™ client
    
    Usage:
      easy [options] status
      easy [options] pressure
      easy [options] location
      easy [options] active-program
      easy [options] program-data
      easy [options] display-code
      easy [options] supply-temperature
      easy [options] gas-usage [<page> | "?"]
      easy [options] hot-water-supply [ on | off ]
      easy [options] get <uri>
      easy [options] put <uri> <data>
      easy [options] set temperature <value>
      easy [options] set active-program <value>
      easy [options] decrypt [--type=TYPE] <base64>
    
    Options:
      -h --help            Show this screen
      -v --version         Show version
      -V --verbose         Be more verbose
      --serial=SERIAL      Nefit Easy™ serial number
      --access-key=KEY     Nefit Easy™ access key
      --password=PASSWORD  Nefit Easy™ password
      --timeout=TIMEOUT    Request timeout in seconds [default: 30]
      --type=TYPE          Message type ('chat', 'alarm', 'email') [default: chat]
      --pretty             Pretty-print JSON output
    
    Instead of specifying serial number, access key or password through
    options, you can also define them through environment variables:
    
      NEFIT_SERIAL_NUMBER
      NEFIT_ACCESS_KEY
      NEFIT_PASSWORD
    
    The temperature value for "set temperature" can be prefixed with a specifier
    to conditionally set the temperature if the current temperature doesn't
    already meet the specification. For example, to set the temperature to 21°C,
    unless it's not already set higher:
    
      $ easy set temperature '>21'
    
    

    Visit original content creator repository

  • Gene-Expression-Networks-3-Brain-Region-R

    Gene-Expression-Networks-3-Brain-Region-R

    SOME TERMS LEFT INTENTIONALLY GENERAL SO AS NOT TO UNDERMINE UNPUBLISHED WORKS

    CONSTRUCTION OF GENE EXPRESSION NETWORKS ACROSS 3 BRAIN REGIONS USING R

    The goal was to construct gene expression networks in B6 mice across three brain regions after acute exposure to ethanol. The script walks through the process of inputting each data set, filtering out at a determined significance level, binding the 3 regions together into a master gene list and removing redundancies before extracting the probeset_ids for each row in the data set.

    From there, extraneous information (to this analysis) in the dataframe is removed, and a sampleTree is constructed and pickSoftThreshold employed to use R and WGCNA built in functionality to decide the best power for the analysis. Once completed for each brain region, the network construction function of WGCNA, blockwiseModules is begun, taking in the dataframe of each region, the block size determined by the memory and strength of the computing machine, the power selected previously, and other default setting as suggested by the tutorial methods of WGCNA.

    Dendrograms are then plotted to show the users the options for the deepsplit and merge cut height. A table is given to specify the number of genes in each color, colors then set here to the name of a module. The annotation data, provided by Affymetrix, is loaded into R, and the names of the members in each module are matched to probeset_ID from the original data frame and against the given annotation data.

    The unique Entrez IDs are then saved under a file named for the module it is a member of. Annotation data is saved into another file with the module name in the title.

    CONNECTIVITY MEASURES BETWEEN MODULES

    After network construction is run, it was of interest to know the similarity and dissimilarity between the modules in each region. The gene lists per brain region were loaded and extraneous information removed. The data was then observed for an average, to ensure there were no outliers, and no missing values. The average was plotted for better visualization.

    An adjacency matrix was constructed for each region, observing the same powers that were used in the construction of their networks. A histogram and Scale Free Topology were plotted. Dissimilarity matrixes were calculated by subtracting the adjacency matrix from one.

    The dendrograms from network construction were then run again so that the user had the variables net0, net1, net2 to proceed with. Module Eigengenes were then defined with a set significance and correlation.

    A dissimilarity measure was again defined, but now between the module Eigengenes, so as to keep track of the sign of the correlation. The Eigengenes were then plotted to a dendrogram, and a heatmap was constructed for specific modules to show its similarity to others.

    The measures of connectivity were written to excel files and a module membership list was constructed and also written to excel files.

    Module membership and intramodular connectivity measures could then be shown as a scatterplot.

    TRAIT INPUT AND CORRELATION

    Phenotype Behavior information was inputted into R for stress behaviors in mice. The input was turned into a date frame, with the columns removed that were unnecessary (strains of mice not in the experiment), and saved as an rdata file.

    The data was loaded in, with the number of genes in the first region being the same as the number of columns as our original data frame datExpr0, the number of Samples equaling the number of rows.

    The Module Eigengenes were calculated with color labels for the brain region, and then correlated with the trait information gathered from the rows of the inputted phenotype file. That calculation was given a p value against the number of samples in the region, and then the p value and correlation between trait and Module Eigengene was plotted into a test Matrix. The test matrix was shown as a heatmap to display higher intensity color as stringer correlation between the Module Eigengene and the phenotype trait.

    Such was repeated for the other two brain regions.

    Visit original content creator repository

  • google-github-oauth2-nodejs

    How to Implement GitHub and Google OAuth in Node.js and Express

    In these articles, you’ll learn how to implement Google and GitHub OAuth in Node.js applications.

    How to Implement Google OAuth2 in Node.js

    In this article, I’ll walk you through the process of setting up Google OAuth2 in a Node.js application, including creating the OAuth project on the Google API console, configuring the OAuth Client ID and secret, and implementing the necessary code in the Node.js project.

    How to Implement Google OAuth2 in Node.js

    Topics Covered

    • Run the Node.js Google OAuth2 Project
    • Run the Node.js API with a React.js App
    • Setup the Node.js Project
    • Get the Google OAuth2 Credentials
    • Setup the Database with Prisma
    • Create the Validation Schemas
    • Get the Google OAuth Access Token and User’s Info
      • Get the OAuth Access Token
      • Get the Google Account User
    • Implement the Google OAuth2 in Node.js
      • Register User Route Handler
      • Login User Route Handler
      • Logout User Route Handler
      • Authenticate with Google OAuth2 Route Handler
    • Create a User Route Handler
    • Create the Authentication Guards
      • Authentication Middleware
      • Require User Middleware
    • Create the API Routes
    • Setup CORS and Register the API Routers

    Read the entire article here: https://codevoweb.com/how-to-implement-google-oauth2-in-nodejs/

    How to Implement GitHub OAuth in Node.js

    In this tutorial, I’ll walk you through the process of integrating GitHub OAuth into a Node.js application, including setting up the OAuth App on GitHub, retrieving the OAuth client ID and secret, and implementing the necessary code to handle the OAuth flow.

    How to Implement GitHub OAuth in Node.js

    Topics Covered

    • Run the Node.js GitHub OAuth Project
    • Run the Node.js API with a React App
    • Setup the Node.js Project
    • Get the GitHub OAuth Credentials
    • Create the Database Model
    • Create the Validation Schemas
    • Obtain the GitHub OAuth Access Token and User’s Info
      • Retrieve the OAuth Access Token
      • Retrieve the GitHub Account Information
    • Implement GitHub OAuth in Node.js
      • Account Registration Route Function
      • Account Login Route Function
      • Logout Route Function
      • Authenticate with GitHub OAuth Route Function
    • GetMe Route Function
    • Create the Authentication Middleware
      • Authentication Guard
      • Require User Middleware
    • Create the API Routes
    • Register the API Routes and Setup CORS

    Read the entire article here: https://codevoweb.com/how-to-implement-github-oauth-in-nodejs/

    Visit original content creator repository
  • PHP7-Reference


    PHP 7.0

    PHP 7 was released on December 3rd, 2015. It comes
    with a number of new features, changes, and backwards compatibility breakages
    that are outlined below.

    Performance

    Features

    Changes

    FAQ

    Performance

    Unarguably the greatest part about PHP 7 is the incredible performance boosts
    it provides to applications. This is a result of refactoring the Zend Engine to
    use more compact data structures and less heap allocations/deallocations.

    The performance gains on real world applications will vary, though many
    applications seem to receive a ~100% performance boost – with lower memory
    consumption too!

    The refactored codebase provides further opportunities for future optimisations
    as well (such as JIT compilation). So it looks like future PHP versions will
    continue to see performance enhancements too.

    PHP 7 performance chart comparisons:

    Features

    Combined Comparison Operator

    The combined comparison operator (or spaceship operator) is a shorthand
    notation for performing three-way comparisons from two operands. It has an
    integer return value that can be either:

    • a positive integer (if the left-hand operand is greater than the right-hand operand)
    • 0 (if both operands are equal)
    • a negative integer (if the right-hand operand is greater than the left-hand operand)

    The operator has the same precedence as the equality operators (==, !=,
    ===, !==) and has the exact same behaviour as the other loose comparison
    operators (<, >=, etc). It is also non-associative like them too, so
    chaining of the operands (like 1 <=> 2 <=> 3) is not allowed.

    // compares strings lexically
    var_dump('PHP' <=> 'Node'); // int(1)
    
    // compares numbers by size
    var_dump(123 <=> 456); // int(-1)
    
    // compares corresponding array elements with one-another
    var_dump(['a', 'b'] <=> ['a', 'b']); // int(0)

    Objects are not comparable, and so using them as operands with this operator
    will result in undefined behaviour.

    RFC: Combined Comparison Operator

    Null Coalesce Operator

    The null coalesce operator (or isset ternary operator) is a shorthand notation
    for performing isset() checks in the ternary operator. This is a common thing
    to do in applications, and so a new syntax has been introduced for this exact
    purpose.

    // Pre PHP 7 code
    $route = isset($_GET['route']) ? $_GET['route'] : 'index';
    
    // PHP 7+ code
    $route = $_GET['route'] ?? 'index';

    RFC: Null Coalesce Operator

    Scalar Type Declarations

    Scalar type declarations come in two flavours: coercive (default) and
    strict. The following types for parameters can now be enforced (either
    coercively or strictly): strings (string), integers (int), floating-point
    numbers (float), and booleans (bool). They augment the other types
    introduced in the PHP 5.x versions: class names, interfaces, array and
    callable.

    // Coercive mode
    function sumOfInts(int ...$ints)
    {
        return array_sum($ints);
    }
    
    var_dump(sumOfInts(2, '3', 4.1)); // int(9)

    To enable strict mode, a single declare() directive must be placed at the top
    of the file. This means that the strictness of typing for scalars is configured
    on a per-file basis. This directive not only affects the type declarations of
    parameters, but also a function’s return type (see Return Type
    Declarations
    ), built-in PHP functions, and
    functions from loaded extensions.

    If the type-check fails, then a TypeError exception (see Exceptions in the
    Engine
    ) is thrown. The only leniency present in
    strict typing is the automatic conversion of integers to floats (but not
    vice-versa) when an integer is provided in a float context.

    declare(strict_types=1);
    
    function multiply(float $x, float $y)
    {
        return $x * $y;
    }
    
    function add(int $x, int $y)
    {
        return $x + $y;
    }
    
    var_dump(multiply(2, 3.5)); // float(7)
    var_dump(add('2', 3)); // Fatal error: Uncaught TypeError: Argument 1 passed to add() must be of the type integer, string given...

    Note that only the invocation context applies when the type-checking is
    performed. This means that the strict typing applies only to function/method
    calls, and not to the function/method definitions. In the above example, the
    two functions could have been declared in either a strict or coercive file, but
    so long as they’re being called in a strict file, then the strict typing rules
    will apply.

    BC Breaks

    • Classes with names int, string, float, and bool are now forbidden.

    RFC: Scalar Type Declarations

    Return Type Declarations

    Return type declarations enable for the return type of a function, method, or
    closure to be specified. The following return types are supported: string,
    int, float, bool, array, callable, self (methods only), parent
    (methods only), Closure, the name of a class, and the name of an interface.

    function arraysSum(array ...$arrays): array
    {
        return array_map(function(array $array): int {
            return array_sum($array);
        }, $arrays);
    }
    
    print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));
    /* Output
    Array
    (
        [0] => 6
        [1] => 15
        [2] => 24
    )
    */

    With respect to subtyping, invariance has been chosen for return types.
    This simply means that when a method is either overridden in a subtyped class
    or implemented as defined in a contract, its return type must match exactly the
    method it is (re)implementing.

    class A {}
    class B extends A {}
    
    class C
    {
        public function test() : A
        {
            return new A;
        }
    }
    
    class D extends C
    {
        // overriding method C::test() : A
        public function test() : B // Fatal error due to variance mismatch
        {
            return new B;
        }
    }

    The overriding method D::test() : B causes an E_COMPILE_ERROR because
    covariance is not allowed. In order for this to work, D::test() method must
    have a return type of A.

    class A {}
    
    interface SomeInterface
    {
        public function test() : A;
    }
    
    class B implements SomeInterface
    {
        public function test() : A // all good!
        {
            return null; // Fatal error: Uncaught TypeError: Return value of B::test() must be an instance of A, null returned...
        }
    }

    This time, the implemented method causes a TypeError exception (see
    Exceptions in the Engine) to be thrown when
    executed. This is because null is not a valid return type – only an instance of the
    class A can be returned.

    RFC: Return Type Declarations

    Anonymous Classes

    Anonymous classes are useful when simple, one-off objects need to be created.

    // Pre PHP 7 code
    class Logger
    {
        public function log($msg)
        {
            echo $msg;
        }
    }
    
    $util->setLogger(new Logger());
    
    // PHP 7+ code
    $util->setLogger(new class {
        public function log($msg)
        {
            echo $msg;
        }
    });

    They can pass arguments through to their constructors, extend other classes,
    implement interfaces, and use traits just like a normal class can:

    class SomeClass {}
    interface SomeInterface {}
    trait SomeTrait {}
    
    var_dump(new class(10) extends SomeClass implements SomeInterface {
        private $num;
    
        public function __construct($num)
        {
            $this->num = $num;
        }
    
        use SomeTrait;
    });
    
    /** Output:
    object(class@anonymous)#1 (1) {
      ["Command line code0x104c5b612":"class@anonymous":private]=>
      int(10)
    }
    */

    Nesting an anonymous class within another class does not give it access to any
    private or protected methods or properties of that outer class. In order to use
    the outer class’ protected properties or methods, the anonymous class can
    extend the outer class. To use the private or protected properties of the outer
    class in the anonymous class, they must be passed through its constructor:

    <?php
    
    class Outer
    {
        private $prop = 1;
        protected $prop2 = 2;
    
        protected function func1()
        {
            return 3;
        }
    
        public function func2()
        {
            return new class($this->prop) extends Outer {
                private $prop3;
    
                public function __construct($prop)
                {
                    $this->prop3 = $prop;
                }
    
                public function func3()
                {
                    return $this->prop2 + $this->prop3 + $this->func1();
                }
            };
        }
    }
    
    echo (new Outer)->func2()->func3(); // 6

    RFC: Anonymous Classes

    Unicode Codepoint Escape Syntax

    This enables a UTF-8 encoded unicode codepoint to be output in either a
    double-quoted string or a heredoc. Any valid codepoint is accepted, with
    leading 0‘s being optional.

    echo "\u{aa}"; // ª
    echo "\u{0000aa}"; // ª (same as before but with optional leading 0's)
    echo "\u{9999}"; // 香

    RFC: Unicode Codepoint Escape Syntax

    Closure call() Method

    The new call() method for closures is used as a shorthand way of invoking a
    closure whilst binding an object scope to it. This creates more perfomant and
    compact code by removing the need to create an intermediate closure before
    invoking it.

    class A {private $x = 1;}
    
    // Pre PHP 7 code
    $getXCB = function() {return $this->x;};
    $getX = $getXCB->bindTo(new A, 'A'); // intermediate closure
    echo $getX(); // 1
    
    // PHP 7+ code
    $getX = function() {return $this->x;};
    echo $getX->call(new A); // 1

    RFC: Closure::call

    Filtered unserialize()

    This feature seeks to provide better security when unserializing objects on
    untrusted data. It prevents possible code injections by enabling the developer
    to whitelist classes that can be unserialized.

    // converts all objects into __PHP_Incomplete_Class object
    $data = unserialize($foo, ["allowed_classes" => false]);
    
    // converts all objects into __PHP_Incomplete_Class object except those of MyClass and MyClass2
    $data = unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]]);
    
    // default behaviour (same as omitting the second argument) that accepts all classes
    $data = unserialize($foo, ["allowed_classes" => true]);

    RFC: Filtered unserialize()

    IntlChar Class

    The new IntlChar class seeks to expose additional ICU functionality. The
    class itself defines a number of static methods and constants that can be used
    to manipulate unicode characters.

    printf('%x', IntlChar::CODEPOINT_MAX); // 10ffff
    echo IntlChar::charName('@'); // COMMERCIAL AT
    var_dump(IntlChar::ispunct('!')); // bool(true)

    In order to use this class, the Intl extension must be installed.

    BC Breaks

    • Classes in the global namespace must not be called IntlChar.

    RFC: IntlChar class

    Expectations

    Expectations are backwards compatible enhancement to the older assert()
    function. They enable for zero-cost assertions in production code, and provide
    the ability to throw custom exceptions on error.

    The assert() function’s prototype is as follows:

    void assert (mixed $expression [, mixed $message]);
    

    As with the old API, if $expression is a string, then it will be evaluated.
    If the first argument is falsy, then the assertion fails. The second argument
    can either be a plain string (causing an AssertionError to be triggered),
    or a custom exception object containing an error message.

    ini_set('assert.exception', 1);
    
    class CustomError extends AssertionError {}
    
    assert(false, new CustomError('Some error message'));

    With this feature comes two PHP.ini settings (along with their default values):

    • zend.assertions = 1
    • assert.exception = 0

    zend.assertions has three values:

    • 1 = generate and execute code (development mode)
    • 0 = generate code and jump around at it at runtime
    • -1 = don’t generate any code (zero-cost, production mode)

    assert.exception means that an exception is thrown when an assertion fails.
    This is switched off by default to remain compatible with the old assert()
    function.

    RFC: Expectations

    Group use Declarations

    This gives the ability to group multiple use declarations according to the
    parent namespace. This seeks to remove code verbosity when importing multiple
    classes, functions, or constants that come under the same namespace.

    // Pre PHP 7 code
    use some\namespace\ClassA;
    use some\namespace\ClassB;
    use some\namespace\ClassC as C;
    
    use function some\namespace\fn_a;
    use function some\namespace\fn_b;
    use function some\namespace\fn_c;
    
    use const some\namespace\ConstA;
    use const some\namespace\ConstB;
    use const some\namespace\ConstC;
    
    // PHP 7+ code
    use some\namespace\{ClassA, ClassB, ClassC as C};
    use function some\namespace\{fn_a, fn_b, fn_c};
    use const some\namespace\{ConstA, ConstB, ConstC};

    RFC: Group use Declarations

    Generator Return Expressions

    This feature builds upon the generator functionality introduced into PHP 5.5.
    It enables for a return statement to be used within a generator to enable for
    a final expression to be returned (return by reference is not allowed). This
    value can be fetched using the new Generator::getReturn() method, which may
    only be used once the generator has finishing yielding values.

    // IIFE syntax now possible - see the Uniform Variable Syntax subsection in the Changes section
    $gen = (function() {
        yield 1;
        yield 2;
    
        return 3;
    })();
    
    foreach ($gen as $val) {
        echo $val, PHP_EOL;
    }
    
    echo $gen->getReturn(), PHP_EOL;
    
    // output:
    // 1
    // 2
    // 3

    Being able to explicitly return a final value from a generator is a handy
    ability to have. This is because it enables for a final value to be returned by
    a generator (from perhaps some form of coroutine computation) that can be
    specifically handled by the client code executing the generator. This is far
    simpler than forcing the client code to firstly check whether the final value
    has been yielded, and then if so, to handle that value specifically.

    RFC: Generator Return Expressions

    Generator Delegation

    Generator delegation builds upon the ability of being able to return
    expressions from generators. It does this by using an new syntax of yield from <expr>, where can be any Traversable object or array. This
    will be advanced until no longer valid, and then execution will continue in the
    calling generator. This feature enables yield statements to be broken down
    into smaller operations, thereby promoting cleaner code that has greater
    reusability.

    function gen()
    {
        yield 1;
        yield 2;
    
        return yield from gen2();
    }
    
    function gen2()
    {
        yield 3;
    
        return 4;
    }
    
    $gen = gen();
    
    foreach ($gen as $val)
    {
        echo $val, PHP_EOL;
    }
    
    echo $gen->getReturn();
    
    // output
    // 1
    // 2
    // 3
    // 4

    RFC: Generator Delegation

    Integer Division with intdiv()

    The intdiv() function has been introduced to handle division where an integer is to be returned.

    var_dump(intdiv(10, 3)); // int(3)

    BC Breaks

    • Functions in the global namespace must not be called intdiv.

    RFC: intdiv()

    session_start() Options

    This feature gives the ability to pass in an array of options to the
    session_start() function. This is used to set session-based php.ini options:

    session_start(['cache_limiter' => 'private']); // sets the session.cache_limiter option to private

    This feature also introduces a new php.ini setting (session.lazy_write) that
    is, by default, set to true and means that session data is only rewritten if it
    changes.

    RFC: Introduce session_start() Options

    preg_replace_callback_array() Function

    This new function enables code to be written more cleanly when using the
    preg_replace_callback() function. Prior to PHP 7, callbacks that needed to be
    executed per regular expression required the callback function (second
    parameter of preg_replace_callback()) to be polluted with lots of branching
    (a hacky method at best).

    Now, callbacks can be registered to each regular expression using an associative
    array, where the key is a regular expression and the value is a callback.

    Function Signature:

    string preg_replace_callback_array(array $regexesAndCallbacks, string $input);
    

    $tokenStream = []; // [tokenName, lexeme] pairs
    
    $input = <<<'end'
    $a = 3; // variable initialisation
    end;
    
    // Pre PHP 7 code
    preg_replace_callback(
        [
            '~\$[a-z_][a-z\d_]*~i',
            '~=~',
            '~[\d]+~',
            '~;~',
            '~//.*~'
        ],
        function ($match) use (&$tokenStream) {
            if (strpos($match[0], '$') === 0) {
                $tokenStream[] = ['T_VARIABLE', $match[0]];
            } elseif (strpos($match[0], '=') === 0) {
                $tokenStream[] = ['T_ASSIGN', $match[0]];
            } elseif (ctype_digit($match[0])) {
                $tokenStream[] = ['T_NUM', $match[0]];
            } elseif (strpos($match[0], ';') === 0) {
                $tokenStream[] = ['T_TERMINATE_STMT', $match[0]];
            } elseif (strpos($match[0], '//') === 0) {
                $tokenStream[] = ['T_COMMENT', $match[0]];
            }
        },
        $input
    );
    
    // PHP 7+ code
    preg_replace_callback_array(
        [
            '~\$[a-z_][a-z\d_]*~i' => function ($match) use (&$tokenStream) {
                $tokenStream[] = ['T_VARIABLE', $match[0]];
            },
            '~=~' => function ($match) use (&$tokenStream) {
                $tokenStream[] = ['T_ASSIGN', $match[0]];
            },
            '~[\d]+~' => function ($match) use (&$tokenStream) {
                $tokenStream[] = ['T_NUM', $match[0]];
            },
            '~;~' => function ($match) use (&$tokenStream) {
                $tokenStream[] = ['T_TERMINATE_STMT', $match[0]];
            },
            '~//.*~' => function ($match) use (&$tokenStream) {
                $tokenStream[] = ['T_COMMENT', $match[0]];
            }
        ],
        $input
    );

    BC Breaks

    • Functions in the global namespace must not be called preg_replace_callback_array.

    RFC: Add preg_replace_callback_array Function

    CSPRNG Functions

    This feature introduces two new functions for generating cryptographically
    secure integers and strings. They expose simple APIs and are
    platform-independent.

    Function signatures:

    string random_bytes(int length);
    int random_int(int min, int max);
    

    Both functions will emit an Error exception if a source of sufficient
    randomness cannot be found.

    BC Breaks

    • Functions in the global namespace must not be called random_int or random_bytes.

    RFC: Easy User-land CSPRNG

    Support for Array Constants in define()

    The ability to define array constants was introduced in PHP 5.6 using the
    const keyword. This ability has now been applied to the define() function
    too:

    define('ALLOWED_IMAGE_EXTENSIONS', ['jpg', 'jpeg', 'gif', 'png']);

    RFC: no RFC available

    Reflection Additions

    Two new reflection classes have been introduced in PHP 7. The first is
    ReflectionGenerator, which is used for introspection on generators:

    class ReflectionGenerator
    {
        public __construct(Generator $gen)
        public array getTrace($options = DEBUG_BACKTRACE_PROVIDE_OBJECT)
        public int getExecutingLine(void)
        public string getExecutingFile(void)
        public ReflectionFunctionAbstract getFunction(void)
        public Object getThis(void)
        public Generator getExecutingGenerator(void)
    }

    The second is ReflectionType to better support the scalar and return type
    declaration features:

    class ReflectionType
    {
        public bool allowsNull(void)
        public bool isBuiltin(void)
        public string __toString(void)
    }

    Also, two new methods have been introduced into ReflectionParameter:

    class ReflectionParameter
    {
        // ...
        public bool hasType(void)
        public ReflectionType getType(void)
    }

    As well as two new methods in ReflectionFunctionAbstract:

    class ReflectionFunctionAbstract
    {
        // ...
        public bool hasReturnType(void)
        public ReflectionType getReturnType(void)
    }

    BC Breaks

    • Classes in the global namespace must not be called ReflectionGenerator or
      ReflectionType.

    RFC: no RFC available

    Changes

    Loosening Reserved Word Restrictions

    Globally reserved words as property, constant, and method names within classes,
    interfaces, and traits are now allowed. This reduces the surface of BC breaks
    when new keywords are introduced and avoids naming restrictions on APIs.

    This is particularly useful when creating internal DSLs with fluent interfaces:

    // 'new', 'private', and 'for' were previously unusable
    Project::new('Project Name')->private()->for('purpose here')->with('username here');

    The only limitation is that the class keyword still cannot be used as a
    constant name, otherwise it would conflict with the class name resolution
    syntax (ClassName::class).

    RFC: Context Sensitive Lexer

    Uniform Variable Syntax

    This change brings far greater orthogonality to the variable operators in PHP.
    It enables for a number of new combinations of operators that were previously
    disallowed, and so introduces new ways to achieve old operations in terser
    code.

    // nesting ::
    $foo::$bar::$baz // access the property $baz of the $foo::$bar property
    
    // nesting ()
    foo()() // invoke the return of foo()
    
    // operators on expressions enclosed in ()
    (function () {})() // IIFE syntax from JS

    The ability to arbitrarily combine variable operators came from reversing the
    evaluation semantics of indirect variable, property, and method references. The
    new behaviour is more intuitive and always follows a left-to-right evaluation
    order:

                            // old meaning            // new meaning
    $$foo['bar']['baz']     ${$foo['bar']['baz']}     ($$foo)['bar']['baz']
    $foo->$bar['baz']       $foo->{$bar['baz']}       ($foo->$bar)['baz']
    $foo->$bar['baz']()     $foo->{$bar['baz']}()     ($foo->$bar)['baz']()
    Foo::$bar['baz']()      Foo::{$bar['baz']}()      (Foo::$bar)['baz']()

    BC Breaks

    • Code that relied upon the old evaluation order must be rewritten to
      explicitly use that evaluation order with curly braces (see middle column of
      the above). This will make the code both forwards compatible with PHP 7.x and
      backwards compatible with PHP 5.x

    RFC: Uniform Variable Syntax

    Exceptions in the Engine

    Exceptions in the engine converts many fatal and recoverable fatal errors into
    exceptions. This enables for graceful degradation of applications through
    custom error handling procedures. It also means that cleanup-driven features
    such as the finally clause and object destructors will now be executed.
    Furthermore, by using exceptions for application errors, stack traces will be
    produced for additional debugging information.

    function sum(float ...$numbers) : float
    {
        return array_sum($numbers);
    }
    
    try {
        $total = sum(3, 4, null);
    } catch (TypeError $typeErr) {
        // handle type error here
    }

    The new exception hierarchy is as follows:

    interface Throwable
        |- Exception implements Throwable
            |- ...
        |- Error implements Throwable
            |- TypeError extends Error
            |- ParseError extends Error
            |- AssertionError extends Error
            |- ArithmeticError extends Error
                |- DivisionByZeroError extends ArithmeticError
    

    See the Throwable Interface subsection in the Changes
    section for more information on this new exception hierarchy.

    BC Breaks

    • Custom error handlers used for handling (and typically ignoring) recoverable
      fatal errors will not longer work since exceptions will now be thrown
    • Parse errors occurring in eval()ed code will now become exceptions,
      requiring them to be wrapped in a try...catch block

    RFC: Exceptions in the Engine

    Throwable Interface

    This change affects PHP’s exception hierarchy due to the introduction of
    exceptions in the engine. Rather than placing
    fatal and recoverable fatal errors under the pre-existing Exception class
    hierarchy, it was
    decided

    to implement a new hierarchy of exceptions to prevent PHP 5.x code from
    catching these new exceptions with catch-all (catch (Exception $e)) clauses.

    The new exception hierarchy is as follows:

    interface Throwable
        |- Exception implements Throwable
            |- ...
        |- Error implements Throwable
            |- TypeError extends Error
            |- ParseError extends Error
            |- AssertionError extends Error
            |- ArithmeticError extends Error
                |- DivisionByZeroError extends ArithmeticError
    

    The Throwable interface is implemented by both Exception and Error base
    class hierarchies and defines the following contract:

    interface Throwable
    {
        final public string getMessage ( void )
        final public mixed getCode ( void )
        final public string getFile ( void )
        final public int getLine ( void )
        final public array getTrace ( void )
        final public string getTraceAsString ( void )
        public string __toString ( void )
    }
    

    Throwable cannot be implemented by user-defined classes – instead, a custom
    exception class should extend one of the pre-existing exceptions classes in
    PHP.

    RFC: Throwable Interface

    Integer Semantics

    The semantics for some integer-based behaviour has changed in an effort to make
    them more intuitive and platform-independent. Here is a list of those changes:

    • Casting NAN and INF to an integer will always result in 0
    • Bitwise shifting by a negative number of bits is now disallowed (causes a
      bool(false) return and emits an E_WARNING)
    • Left bitwise shifts by a number of bits beyond the bit width of an integer will always result in 0
    • Right bitwise shifts by a number of bits beyond the bit width of an integer
      will always result in 0 or -1 (sign dependent)

    BC Breaks

    • Any reliance on the old semantics for the above will no longer work

    RFC: Integer Semantics

    JSON Extension Replaced with JSOND

    The licensing of the old JSON extension was regarded as non-free, causing
    issues for many Linux-based distributions. The extension has since been
    replaced with JSOND and comes with some performance
    gains

    and backward compatibility breakages.

    BC Breaks

    • A number must not end in a decimal point (i.e. 34. must be changed to either 34.0 or just 34)
    • The e exponent must not immediately follow the decimal point (i.e.
      3.e3 must be changed to either 3.0e3 or just 3e3)

    RFC: Replace current json extension with jsond

    ZPP Failure on Overflow

    Coercion between floats to integers can occur when a float is passed to an
    internal function expecting an integer. If the float is too large to represent
    as an integer, then the value will be silently truncated (which may result in a
    loss of magnitude and sign). This can introduce hard-to-find bugs. This change
    therefore seeks to notify the developer when an implicit conversion from a
    float to an integer has occurred and failed by returning null and emitting an
    E_WARNING.

    BC Breaks

    • Code that once silently worked will now emit an E_WARNING and may fail if
      the result of the function invocation is directly passed to another function
      (since null will now be passed in).

    RFC: ZPP Failure on Overflow

    Fixes to foreach()‘s Behaviour

    PHP’s foreach() loop had a number of strange edge-cases to it. These were all
    implementation-driven and caused a lot of undefined and inconsistent behaviour
    when iterating between copies and references of an array, when using iterator
    manipulators like current() and reset(), when modifying the array currently
    being iterated, and so on.

    This change eliminates the undefined behaviour of these edge-cases and makes
    the semantics more predictable and intuitive.

    foreach() by value on arrays

    $array = [1,2,3];
    $array2 = &$array;
    
    foreach($array as $val) {
        unset($array[1]); // modify array being iterated over
        echo "{$val} - ", current($array), PHP_EOL;
    }
    
    // Pre PHP 7 result
    1 - 3
    3 -
    
    // PHP 7+ result
    1 - 1
    2 - 1
    3 - 1

    When by-value semantics are used, the array being iterated over is now not
    modified in-place. current() also now has defined behaviour, where it will
    always begin at the start of the array.

    foreach() by reference on arrays and objects and by value on objects

    $array = [1,2,3];
    
    foreach($array as &$val) {
        echo "{$val} - ", current($array), PHP_EOL;
    }
    
    // Pre PHP 7 result
    1 - 2
    2 - 3
    3 -
    
    // PHP 7+ result
    1 - 1
    2 - 1
    3 - 1

    The current() function is no longer affected by foreach()‘s iteration on
    the array. Also, nested foreach()‘s using by-reference semantics work
    independently from each other now:

    $array = [1,2,3];
    
    foreach($array as &$val) {
        echo $val, PHP_EOL;
    
        foreach ($array as &$val2) {
            unset($array[1]);
            echo $val, PHP_EOL;
        }
    }
    
    // Pre PHP 7 result
    1
    1
    1
    
    // PHP 7+ result
    1
    1
    1
    3
    3
    3

    BC Breaks

    • Any reliance on the old (quirky and undocumented) semantics will no longer work.

    RFC: Fix “foreach” behavior

    Changes to list()‘s Behaviour

    The list() function was documented as not supporting strings, however in few cases strings could have been used:

    // array dereferencing
    $str[0] = 'ab';
    list($a, $b) = $str[0];
    echo $a; // a
    echo $b; // b
    
    // object dereferencing
    $obj = new StdClass();
    $obj->prop = 'ab';
    list($a, $b) = $obj->prop;
    echo $a; // a
    echo $b; // b
    
    // function return
    function func()
    {
        return 'ab';
    }
    
    list($a, $b) = func();
    var_dump($a, $b);
    echo $a; // a
    echo $b; // b

    This has now been changed making string usage with list() forbidden in all cases.

    Also, empty list()‘s are now a fatal error, and the order of assigning variables has been changed to left-to-right:

    $a = [1, 2];
    list($a, $b) = $a;
    
    // OLD: $a = 1, $b = 2
    // NEW: $a = 1, $b = null + "Undefined index 1"
    
    $b = [1, 2];
    list($a, $b) = $b;
    
    // OLD: $a = null + "Undefined index 0", $b = 2
    // NEW: $a = 1, $b = 2

    BC Breaks

    • Making list() equal to any non-direct string value is no longer possible.
      null will now be the value for the variable $a and $b in the above
      examples
    • Invoking list() without any variables will cause a fatal error
    • Reliance upon the old right-to-left assignment order will no longer work

    RFC: Fix list() behavior inconsistency

    RFC: Abstract syntax tree

    Changes to Division by Zero Semantics

    Prior to PHP 7, when a divisor was 0 for either the divide (/) or modulus (%) operators,
    an E_WARNING would be emitted and false would be returned. This was nonsensical for
    an arithmetic operation to return a boolean in some cases, and so the behaviour has been
    rectified in PHP 7.

    The new behaviour causes the divide operator to return a float as either +INF, -INF, or
    NAN. The modulus operator E_WARNING has been removed and (alongside the new intdiv()
    function) will throw a DivisionByZeroError exception. In addition, the intdiv()
    function may also throw an ArithmeticError when valid integer arguments are supplied
    that cause an incorrect result (due to integer overflow).

    var_dump(3/0); // float(INF) + E_WARNING
    var_dump(0/0); // float(NAN) + E_WARNING
    
    var_dump(0%0); // DivisionByZeroError
    
    intdiv(PHP_INT_MIN, -1); // ArithmeticError

    BC Breaks

    • The divide operator will no longer return false (which could have been silently coerced
      to 0 in an arithmetic operation)
    • The modulus operator will now throw an exception with a 0 divisor instead of returning false

    RFC: No RFC available

    Fixes to Custom Session Handler Return Values

    When implementing custom session handlers, predicate functions from the
    SessionHandlerInterface that expect a true or false return value did not
    behave as expected. Due to an error in the previous implementation, only a -1
    return value was considered false – meaning that even if the boolean
    false was used to denote a failure, it was taken as a success:

    <?php
    
    class FileSessionHandler implements SessionHandlerInterface
    {
        private $savePath;
    
        function open($savePath, $sessionName)
        {
            return false; // always fail
        }
    
        function close(){return true;}
    
        function read($id){}
    
        function write($id, $data){}
    
        function destroy($id){}
    
        function gc($maxlifetime){}
    }
    
    session_set_save_handler(new FileSessionHandler());
    
    session_start(); // doesn't cause an error in pre PHP 7 code

    Now, the above will fail with a fatal error. Having a -1 return value will
    also continue to fail, whilst 0 and true will continue to mean success. Any
    other value returned will now cause a failure and emit an E_WARNING.

    BC Breaks

    • If boolean false is returned, it will actually fail now
    • If anything other than a boolean, 0, or -1 is returned, it will fail and cause a warning to be emitted

    RFC: Fix handling of custom session handler return values

    Deprecation of PHP 4-Style Constructors

    PHP 4 constructors were preserved in PHP 5 alongside the new __construct().
    Now, PHP 4-style constructors are being deprecated in favour of having only a
    single method (__construct()) to be invoked on object creation. This is
    because the conditions upon whether the PHP 4-style constructor was invoked
    caused additional cognitive overhead to developers that could also be confusing
    to the inexperienced.

    For example, if the class is defined within a namespace or if an
    __construct() method existed, then a PHP 4-style constructor was recognised
    as a plain method. If it was defined above an __construct() method, then an
    E_STRICT notice would be emitted, but still recognised as a plain method.

    Now in PHP 7, if the class is not in a namespace and there is no
    __construct() method present, the PHP 4-style constructor will be used as a
    constructor but an E_DEPRECATED will be emitted. In PHP 8, the PHP 4-style
    constructor will always be recognised as a plain method and the E_DEPRECATED
    notice will disappear.

    BC Breaks

    • Custom error handlers may be affected by the raising of E_DEPRECATED
      warnings. To fix this, simply update the class constructor name to
      __construct.

    RFC: Remove PHP 4 Constructors

    Removal of date.timezone Warning

    When any date- or time-based functions were invoked and a default timezone had
    not been set, a warning was emitted. The fix was to simply set the
    date.timezone INI setting to a valid timezone, but this forced users to have
    a php.ini file and to configure it beforehand. Since this was the only setting
    that had a warning attached to it, and it defaulted to UTC anyway, the warning
    has now been removed.

    RFC: Remove the date.timezone warning

    Removal of Alternative PHP Tags

    The alternative PHP tags <% (and <%=), %>, <script language="php">, and
    </script> have now been removed.

    BC Breaks

    • Code that relied upon these alternative tags needs to be updated to either
      the normal or short opening and closing tags. This can either be done
      manually or automated with this porting script.

    RFC: Remove alternative PHP tags

    Removal of Multiple Default Blocks in Switch Statements

    Previously, it was possible to specify multiple default block statements
    within a switch statement (where the last default block was only executed).
    This (useless) ability has now been removed and causes a fatal error.

    BC Breaks

    • Any code written (or more likely generated) that created switch statements
      with multiple default blocks will now become a fatal error.

    RFC: Make defining multiple default cases in a switch a syntax error

    Removal of Redefinition of Parameters with Duplicate Names

    Previously, it was possible to specify parameters with duplicate names within a function definition.
    This ability has now been removed and causes a fatal error.

    function foo($version, $version)
    {
        return $version;
    }
    
    echo foo(5, 7);
    
    // Pre PHP 7 result
    7
    
    // PHP 7+ result
    Fatal error: Redefinition of parameter $version in /redefinition-of-parameters.php

    BC Breaks

    • Function parameters with duplicate name will now become a fatal error.

    Removal of Dead Server APIs

    The following SAPIs have been removed from the core (most of which have been moved to PECL):

    • sapi/aolserver
    • sapi/apache
    • sapi/apache_hooks
    • sapi/apache2filter
    • sapi/caudium
    • sapi/continuity
    • sapi/isapi
    • sapi/milter
    • sapi/nsapi
    • sapi/phttpd
    • sapi/pi3web
    • sapi/roxen
    • sapi/thttpd
    • sapi/tux
    • sapi/webjames
    • ext/mssql
    • ext/mysql
    • ext/sybase_ct
    • ext/ereg

    RFC: Removal of dead or not yet PHP7 ported SAPIs and extensions

    Removal of Hex Support in Numerical Strings

    A Stringy hexadecimal number is no longer recognised as numerical.

    var_dump(is_numeric('0x123'));
    var_dump('0x123' == '291');
    echo '0x123' + '0x123';
    
    // Pre PHP 7 result
    bool(true)
    bool(true)
    582
    
    // PHP 7+ result
    bool(false)
    bool(false)
    0

    The reason for this change is to promote better consistency between the
    handling of stringy hex numbers across the language. For example, explicit
    casts do not recognise stringy hex numbers:

    var_dump((int) '0x123'); // int(0)

    Instead, stringy hex numbers should be validated and converted using the filter_var() function:

    var_dump(filter_var('0x123', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX)); // int(291)

    BC Breaks

    • This change affects the is_numeric() function and various operators, including ==, +, -, *, /, %, **, ++, and --

    RFC: Remove hex support in numeric strings

    Removal of Deprecated Functionality

    All Deprecated functionality has been removed, most notably:

    • The original mysql extension (ext/mysql)
    • The ereg extension (ext/ereg)
    • Assigning new by reference
    • Scoped calls of non-static methods from an incompatible $this context
      (such as Foo::bar() from outside a class, where bar() is not a static
      method)

    BC Breaks

    • Any code that ran with deprecation warnings in PHP 5 will no longer work (you were warned!)

    RFC: Remove deprecated functionality in PHP 7

    Reclassification and Removal of E_STRICT Notices

    E_STRICT notices have always been a bit of a grey area in their meaning. This
    changes removes this error category altogether and either: removes the E_STRICT
    notice, changes it to an E_DEPRECATED if the functionality will be removed in
    future, changes it to an E_NOTICE, or promotes it to an E_WARNING.

    BC Breaks

    • Because E_STRICT is in the lowest severity error category, any error
      promotions to an E_WARNING may break custom error handlers

    RFC: Reclassify E_STRICT notices

    Deprecation of Salt Option for password_hash()

    With the introduction of the new password hashing API in PHP 5.5, many began
    implementing it and generating their own salts. Unfortunately, many of these
    salts were generated from cryptographically insecure functions like mt_rand(),
    making the salt far weaker than what would have been generated by default.
    (Yes, a salt is always used when hashing passwords with this new API!) The option to
    generate salts have therefore been deprecated to prevent developers from
    creating insecure salts.

    RFC: no RFC available

    Error on Invalid Octal Literals

    Invalid octal literals will now cause a parse error rather than being
    truncated and silently ignored.

    echo 0678; // Parse error:  Invalid numeric literal in...

    BC Breaks

    • Any invalid octal literals in code will now cause parse errors

    RFC: no RFC available

    substr() Return Value Change

    substr() will now return an empty string instead of false when the start
    position of the truncation is equal to the string length:

    var_dump(substr('a', 1));
    
    // Pre PHP 7 result
    bool(false)
    
    // PHP 7+ result
    string(0) ""

    substr() may still return false in other cases, however.

    BC Breaks

    • Code that strictly checked for a bool(false) return value may now be
      semantically invalid

    RFC: no RFC available

    FAQ

    What happened to PHP 6?

    PHP 6 was the major PHP version that never came to light. It was supposed to
    feature full support for Unicode in the core, but this effort was too ambitious
    with too many complications arising. The predominant reasons why version 6 was
    skipped for this new major version are as follows:

    • To prevent confusion. Many resources were written about PHP 6 and much
      of the community knew what was featured in it. PHP 7 is a completely
      different beast with entirely different focuses (specifically on performance)
      and entirely different feature sets. Thus, a version has been skipped to
      prevent any confusion or misconceptions surrounding what PHP 7 is.
    • To let sleeping dogs lie. PHP 6 was seen as a failure and a large amount
      of PHP 6 code still remains in the PHP repository. It was therefore seen as
      best to move past version 6 and start afresh on the next major version, version

    RFC: Name of Next Release of PHP

    Visit original content creator repository

  • nodejs-npm-buildpack

    Node.js NPM Cloud Native Buildpack (MOVED)

    This repo has moved to https://github.com/heroku/buildpacks-node.

    This buildpack builds on top of the existing Node.js Engine Cloud Native Buildpack. It runs subsequent scripts after Node is install.

    • Run automatically
      • npm install or npm ci
    • Run when configured in package.json
      • npm run build or npm run heroku-postbuild

    Usage

    Install pack

    Using brew (assuming development is done on MacOS), install pack.

    brew tap buildpack/tap
    brew install pack

    If you’re using Windows or Linux, follow instructions here.

    Install shpec (optional)

    This buildpack uses shpec for unit tests, so to run them locally, you’ll need to install the package.

    curl -sLo- http://get.bpkg.sh | bash
    bpkg install rylnd/shpec

    Clone the buildpack

    Right now, we are prototyping with a local version of the buildpack. Clone it to your machine.

    git clone git@github.com:heroku/nodejs-npm-buildpack.git

    Clone the Heroku Node.js Engine Cloud Native Buildpack.

    cd .. # change from nodejs-npm-buildpack directory
    git clone git@github.com:heroku/nodejs-engine-buildpack.git

    Build the image

    with buildpacks

    Using pack, you’re ready to create an image from the buildpack and source code. You will need to add flags that point to the path of the source code (--path) and the paths of the buildpacks (--buildpack).

    cd nodejs-npm-buildpack
    pack build TEST_IMAGE_NAME --path ../TEST_REPO_PATH --buildpack ../nodejs-engine-buildpack --buildpack ../nodejs-npm-buildpack

    with a builder

    You can also create a builder.toml file that will have explicit directions when creating a buildpack. This is useful when there are multiple “detect” paths a build can take (ie. yarn vs. npm commands).

    In a directory outside of this buildpack, create a builder file:

    cd ..
    mkdir heroku_nodejs_builder
    touch heroku_nodejs_builder/builder.toml

    For local development, you’ll want the file to look like this:

    [[buildpacks]]
      id = "heroku/nodejs-engine"
      uri = "../nodejs-engine-buildpack"
    
    [[buildpacks]]
      id = "heroku/nodejs-npm"
      uri = "../nodejs-npm-buildpack"
    
    [[order]]
      group = [
        { id = "heroku/nodejs-engine", version = "0.4.3" },
        { id = "heroku/nodejs-npm", version = "0.1.4" }
      ]
    
    [stack]
      id = "heroku-18"
      build-image = "heroku/pack:18"
      run-image = "heroku/pack:18"

    Create the builder with pack:

    pack create-builder nodejs --config ../heroku-nodejs-builder/builder.toml

    Now you can use the builder image instead of chaining the buildpacks.

    pack build TEST_IMAGE_NAME --path ../TEST_REPO_PATH --builder nodejs

    Common Issues

    jq: Permission denied on a build

    This issue may happen if a binary that is installed is not executable. This may happen on a Linux machine or while using a private network, such as a VPN, when using a local buildpack tool. If using sfdx evergreen or pack, pass in --network host to the command.

    An example of this command running from the source code directory with a local builder image called nodejs would look like this:

    pack build TEST_IMAGE_NAME --builder nodejs --network host

    If building a function with sfdx, a command looks like this:

    sfdx evergreen:functions:build image-repo/myfunction:dev --network host

    Testing

    The complete test suite needs Docker to run. Make sure to install Docker first.

    make test

    If you want to run individual test suites, that’s available too.

    Unit Tests

    To run the tests on the local host, make sure shpec is installed.

    make unit-test

    Unit tests in Docker

    Running the shpec aren’t ideal since the test scripts read and write to the local buildpack directory, so Docker may be preferred.

    As suggested above, install Docker. Next, run the tests with the Make script:

    make docker-unit-test

    Debugging tests

    To debug, make changes from the code and rerun with the make command. To see what is happening, I suggest wrapping code blocks in question with set -x/set +x. It would look like this in the shpec file:

    set -x
    it "creates a toolbox.toml"
      install_or_reuse_toolbox "$layers_dir/toolbox"
    
      assert file_present "$layers_dir/toolbox.toml"
    end
    set +x

    Contributing

    1. Open a pull request.
    2. Make update to CHANGELOG.md under main with a description (PR title is fine) of the change, the PR number and link to PR.
    3. Let the tests run on CI. When tests pass and PR is approved, the branch is ready to be merged.
    4. Merge branch to main.

    Release

    Note: if you’re not a contributor to this project, a contributor will have to make the release for you.

    1. Create a new branch (ie. 1.14.2-release).
    2. Update the version in the buildpack.toml.
    3. Move the changes from main to a new header with the version and date (ie. 1.14.2 (2020-02-30)).
    4. Open a pull request.
    5. Let the tests run on CI. When tests pass and PR is approved, the branch is ready to be merged.
    6. Merge branch to main.
    7. Pull down main to local machine.
    8. Tag the current main with the version. (git tag v1.14.2)
    9. Push up to GitHub. (git push origin main --tags) CI will run the suite and create a new release on successful run.

    Glossary

    • buildpacks: provide framework and a runtime for source code. Read more here.
    • OCI image: OCI (Open Container Initiative) is a project to create open sourced standards for OS-level virtualization, most importantly in Linux containers.

    Visit original content creator repository

  • AcuCallTest

    Prerequisites

    • Visual Studio 2017 version 15.7
    • .NET Core
    • Microsoft SQL Server (Not required on local machine if database is hosted on a server)

    Steps To Run Project

    1. Clone project.
    2. First of all make sure if you want to rename database name then update Database connection settings in appSettings.json -> ConnectionStrings -> AcuCallContext.
    3. You can create database, tables and stored procs using migration or script.
    4. If you want to run Db script then skip from step 5 to 8. Then navigate to Sql\DbScript.sql and execute it.
    5. Migration can be performed by opening Package Manager console and On top right selecting AcuCall.Infrastructure.Data from Default Project.
    6. Then run command Update-Database, It will create database if it does not exist else perform migrations.
    7. Once Migration is performed successfully, We need to enable Broker for Db notifications. So open your SQL Server instance.
    8. Connect to your server instance, and execute ALTER DATABASE [DatabaseName] SET ENABLE_BROKER.
    9. Executing migration or script will create a user admin with password admin.
    10. Now you are all ready to start application.

    Deployment Of Project

    The very first step is to install .NET Core Runtime on your machine.

    Setup IIS Configuration

    Windows Server Operating Systems

    Enable the Web Server (IIS) server role and establish role services

    1. Use the Add Roles and Features wizard from the Manage menu or the link in Server Manager. On the Server Roles step, check the box for Web Server (IIS).
    2. After the Features step, the Role services step loads for Web Server (IIS). Select the IIS role services desired or accept the default role services provided.
    3. You can select different security levels from Web Server > Security if required.
    4. Proceed through the Confirmation step to install the web server role and services. A server/IIS restart isn’t required after installing the Web Server (IIS) role.
    Windows Desktop Operating Systems

    Enable the IIS Management Console and World Wide Web Services

    1. Navigate to Control Panel > Programs > Programs and Features > Turn Windows features on or off (left side of the screen).
    2. Open the Internet Information Services node. Open the Web Management Tools node.
    3. Check the box for IIS Management Console.
    4. Check the box for World Wide Web Services.
    5. Accept the default features for World Wide Web Services.
    6. You can select different security levels from World Wide Web Services > Security if required.

    If the IIS installation requires a restart, restart the system.

    Now Create IIS Site

    1. On the hosting system, create a folder to contain the app’s published folders and files.

    2. Within the new folder, create a logs folder to hold ASP.NET Core Module stdout logs when stdout logging is enabled. If logs folder already exist then we don’t need to create it. This folder will hold error logs happening in website.

    3. Open IIS Manager and then open the server’s node in the Connections panel. Right-click the Sites folder. Select Add Website from the contextual menu. capture

    4. Provide a Site name and set the Physical path to the app’s deployment folder. Provide the Binding configuration by default port is 80 and create the website by selecting OK. capture1

    5. Under the server’s node, select Application Pools.

    6. Right-click the site’s app pool and select Basic Settings from the contextual menu.

    7. In the Edit Application Pool window, set the .NET CLR version to No Managed Code. As ASP.NET Core runs in a separate process and manages the runtime. ASP.NET Core doesn’t rely on loading the desktop CLR. Setting the .NET CLR version to No Managed Code is optional. capture2

    Deploy App

    Deploy the app to the folder created on the hosting system by following below steps.

    1. Right-click the project AcuCall.Web and select Publish.
    2. When Folder is selected, specify a folder path to store the published assets. The default folder is bin\Release\PublishOutput but we need to set the path of Physical Path while creating new website in IIS Manager. Click the Publish button to finish. capture

    NOW your application is served on localhost:[BindingPort]

    For more further information regarding deployment you can visit Microsoft website.

    Configure IIS To Access Website Using IP Address

    1. Open IIS Manager Console, It can be found in Administrative Tools -> Internet Information Services (IIS) Manager.

    2. In the Connections pane of IIS, expand the Sites and select the website AcuCallAspNetCore this is what i have named previously in this doc or the one you have named.

    3. Click on Bindings link and you will see current bindings of that website. capture

    4. Click on Add button.

    5. On the Add Site Binding window, keep website Type as http. Select an IP address from the drop-down menu upon which you want to bind the website. Since other websites (along with their Host Header Values) are already bound on port 80, you won’t be able to bind this new website on port 80 without Host Header Value (Host name). So, specify a port number (other than default port 80) on which you want to bind this new website. Keep Host name as blank, click OK and then Close. Once the binding is added in IIS Manager, the next step is allowing a port in Windows Firewall. capture2

    6. Go to Administrative Tools -> Windows Defender Firewall with Advanced Security.

    7. At Windows Firewall window, click on Inbound Rules. capture

    8. Under Actions pane, click on New Rule and New Inbound Rule Wizard will be opened. On this window, select the Port radio button and click on Next. capture

    9. On the next screen, select TCP and Specific local ports radio button. Specify a port number (upon which you set binding in IIS) in Specific local ports field and click Next. capture

    10. On the next screen, select Allow the connection and click Next. capture

    11. Select the profiles for those we want to apply this rule and click Next. capture

    12. Very last step is to provide Name and Description for the newly created rule & click Finish. capture

    Now we are able to access your website using via IP address like http://VPS-IP-Address:81

    Visit original content creator repository
  • THREE.SixDOF

    THREE.6DoF


    Plugin for rendering 6DoF equirectangular 360 images and video with depthmaps 🌐


    Getting startedExamplesAPIThanks

    Getting started

    To quickly get started include the latest three-6dof.js after including three.js in your project. Next create your 6DoF viewer like

    // Create the loader
    var loadingManager = new THREE.LoadingManager();
    var textureLoader = new THREE.TextureLoader(loadingManager);
    
    // Load the textures
    var colorTexture, depthTexture;
    textureLoader.load('360_color_image.jpg', texture => { colorTexture = texture });
    textureLoader.load('360_depth_image.jpg', texture => { depthTexture = texture });
    
    // On finish loading create the viewer with the textures
    loadingManager.onLoad = () => {
        sixDofViewer = new SixDOF.Viewer(colorTexture, depthTexture);
        scene.add(sixDofViewer);
    }

    Using with ES6

    If you are using yarn with ES6 you can also

    yarn add https://github.com/juniorxsound/THREE.SixDOF

    You can import the plugin by simply

    import { 
        Viewer,
        TextureType,
        MeshDensity, 
        Style
    } from 'three-6dof'

    Examples

    API

    When creating a viewer you pass the following parameters

    const instance = new Viewer(
        colorTexture, // Or top bottom texture
        depthTexture, // Optionally
        {
            'type': TextureType.SEPERATE, // For seperate depth and texture (for single top bottom use TextureType.TOP_BOTTOM)
            'style': Style.WIRE, // Chooses the rendering style (defaults to Style.MESH)
            'density': MeshDensity.EXTRA_HIGH // Chooses geometry tesselation level
            'displacement': 4.0, // Defaults to 4.0
            'radius' : 6 // Defaults to 6
        }
    )

    For a full list of options see the constants.ts file.

    • instance.texture – get the THREE.Texture

    • instance.depth – get the THREE.Texture depth map (null if none)

    • instance.displacement – get or set the displacement amount

    • instance.pointSize – get or set the point size when rendering points

    • instance.opacity – get or set the material’s opacity

    • instance.config – returns the current config object

    • instance.toggleDepthDebug(state) – toggle color and depth rendering (useful for debugging)


    Thanks

    To krpano and Kandao for the depth panoramas.

    Visit original content creator repository
  • Retail_sales_analysis

    Retail Sales Analysis

    Introduction

    This project uses the Retail Sales dataset to analyze sales performance, identify trends, and understand product demand across different regions and time periods.
    The goal is to uncover key insights related to sales volume, revenue, and product performance.

    Dataset

    Setup and Installation

    1. Power BI: Install Power BI Desktop from Power BI Downloads.
    2. Dataset: Download the Retail Sales dataset from a reliable source (e.g., Kaggle).
    3. Import Dataset: Import the dataset into Power BI.
    4. Data Analysis: Use Power BI to create reports and dashboards, analyzing sales by product, region, and customer behavior.

    Screenshots

    Screenshot 2025-01-12 232916

    Insights

    • Cost Comparison Across Categories:
      The total cost for fruits is lower compared to categories like office supplies and household, which have significantly higher costs.

    • Profit Distribution Across Regions:
      Both Sub-Saharan Africa and Europe contribute to more than 50% of the total profit, while North America has the lowest profit contribution among all regions.

    • Total Profit and Total Revenue:
      In this case, Total Profit and Total Revenue are the same, indicating that there are no expenses or costs subtracted from the total revenue, which is uncommon in a typical business scenario.

    • Total Profit by Item Category:
      The highest total profit comes from Cosmetic and Household items, while Meat has the lowest total profit among all item categories.

    Recommendations

    • Cost Optimization:
      Focus on reducing costs in the office supplies and household categories to improve overall profit margins. Consider negotiating supplier prices or exploring cheaper alternatives without compromising quality.

    • Profit Maximization in Europe and Sub-Saharan Africa:
      Since Sub-Saharan Africa and Europe contribute heavily to the total profit, consider expanding efforts in these regions to further capitalize on their profitable performance. Increase marketing and sales campaigns to boost revenues.

    • Review and Adjust Expenses:
      Investigate why Total Profit and Total Revenue are the same, as it might indicate an error or an unusual business structure where no operating costs are considered. Ensure accurate tracking of expenses to maintain profitability.

    • Focus on High-Profit Items:
      Given that Cosmetic and Household items generate the highest profit, focus on expanding the product offerings in these categories. Consider bundling these items together or running promotions to increase their sales.

    Visit original content creator repository

  • react-native-mmkv

    V4 Docs old V3 Docs
    react-native-mmkv

    MMKV

    The fastest key/value storage for React Native.


    • MMKV is an efficient, small mobile key-value storage framework developed by WeChat. See Tencent/MMKV for more information
    • react-native-mmkv is a library that allows you to easily use MMKV inside your React Native app through fast and direct JS bindings to the native C++ library.

    Features

    • Get and set strings, booleans, numbers and ArrayBuffers
    • Fully synchronous calls, no async/await, no Promises, no Bridge.
    • Encryption support (secure storage)
    • Multiple instances support (separate user-data with global data)
    • Customizable storage location
    • High performance because everything is written in C++
    • ~30x faster than AsyncStorage
    • Uses JSI and C++ NitroModules instead of the “old” Bridge
    • iOS, Android and Web support
    • Easy to use React Hooks API

    Important

    Benchmark

    StorageBenchmark compares popular storage libraries against each other by reading a value from storage for 1000 times:

    MMKV vs other storage libraries: Reading a value from Storage 1000 times.
    Measured in milliseconds on an iPhone 11 Pro, lower is better.

    Installation

    React Native

    npm install react-native-mmkv react-native-nitro-modules
    cd ios && pod install

    Expo

    npx expo install react-native-mmkv react-native-nitro-modules
    npx expo prebuild

    Usage

    Create a new instance

    To create a new instance of the MMKV storage, use the MMKV constructor. It is recommended that you re-use this instance throughout your entire app instead of creating a new instance each time, so export the storage object.

    Default

    import { createMMKV } from 'react-native-mmkv'
    
    export const storage = createMMKV()

    This creates a new storage instance using the default MMKV storage ID (mmkv.default).

    App Groups or Extensions

    If you want to share MMKV data between your app and other apps or app extensions in the same group, open Info.plist and create an AppGroupIdentifier key with your app group’s value. MMKV will then automatically store data inside the app group which can be read and written to from other apps or app extensions in the same group by making use of MMKV’s multi processing mode. See Configuring App Groups.

    Customize

    import { createMMKV } from 'react-native-mmkv'
    
    export const storage = createMMKV({
      id: `user-${userId}-storage`,
      path: `${USER_DIRECTORY}/storage`,
      encryptionKey: 'hunter2',
      mode: 'multi-process',
      readOnly: false
    })

    This creates a new storage instance using a custom MMKV storage ID. By using a custom storage ID, your storage is separated from the default MMKV storage of your app.

    The following values can be configured:

    • id: The MMKV instance’s ID. If you want to use multiple instances, use different IDs. For example, you can separate the global app’s storage and a logged-in user’s storage. (required if path or encryptionKey fields are specified, otherwise defaults to: 'mmkv.default')
    • path: The MMKV instance’s root path. By default, MMKV stores file inside $(Documents)/mmkv/. You can customize MMKV’s root directory on MMKV initialization (documentation: iOS / Android)
    • encryptionKey: The MMKV instance’s encryption/decryption key. By default, MMKV stores all key-values in plain text on file, relying on iOS’s/Android’s sandbox to make sure the file is encrypted. Should you worry about information leaking, you can choose to encrypt MMKV. (documentation: iOS / Android)
    • mode: The MMKV’s process behaviour – when set to multi-process, the MMKV instance will assume data can be changed from the outside (e.g. App Clips, Extensions or App Groups).
    • readOnly: Whether this MMKV instance should be in read-only mode. This is typically more efficient and avoids unwanted writes to the data if not needed. Any call to set(..) will throw.

    Set

    storage.set('user.name', 'Marc')
    storage.set('user.age', 21)
    storage.set('is-mmkv-fast-asf', true)

    Get

    const username = storage.getString('user.name') // 'Marc'
    const age = storage.getNumber('user.age') // 21
    const isMmkvFastAsf = storage.getBoolean('is-mmkv-fast-asf') // true

    Hooks

    const [username, setUsername] = useMMKVString('user.name')
    const [age, setAge] = useMMKVNumber('user.age')
    const [isMmkvFastAsf, setIsMmkvFastAf] = useMMKVBoolean('is-mmkv-fast-asf')

    Keys

    // checking if a specific key exists
    const hasUsername = storage.contains('user.name')
    
    // getting all keys
    const keys = storage.getAllKeys() // ['user.name', 'user.age', 'is-mmkv-fast-asf']
    
    // delete a specific key + value
    const wasRemoved = storage.remove('user.name')
    
    // delete all keys
    storage.clearAll()

    Objects

    const user = {
      username: 'Marc',
      age: 21
    }
    
    // Serialize the object into a JSON string
    storage.set('user', JSON.stringify(user))
    
    // Deserialize the JSON string into an object
    const jsonUser = storage.getString('user') // { 'username': 'Marc', 'age': 21 }
    const userObject = JSON.parse(jsonUser)

    Encryption

    // encrypt all data with a private key
    storage.recrypt('hunter2')
    
    // remove encryption
    storage.recrypt(undefined)

    Buffers

    const buffer = new ArrayBuffer(3)
    const dataWriter = new Uint8Array(buffer)
    dataWriter[0] = 1
    dataWriter[1] = 100
    dataWriter[2] = 255
    storage.set('someToken', buffer)
    
    const buffer = storage.getBuffer('someToken')
    console.log(buffer) // [1, 100, 255]

    Size

    // get size of MMKV storage in bytes
    const size = storage.size
    if (size >= 4096) {
      // clean unused keys and clear memory cache
      storage.trim()
    }

    Importing all data from another MMKV instance

    To import all keys and values from another MMKV instance, use importAllFrom(...):

    const storage = createMMKV(...)
    const otherStorage = createMMKV(...)
    
    const importedCount = storage.importAllFrom(otherStorage)

    Check if an MMKV instance exists

    To check if an MMKV instance exists, use existsMMKV(...):

    import { existsMMKV } from 'react-native-mmkv'
    
    const exists = existsMMKV('my-instance')

    Delete an MMKV instance

    To delete an MMKV instance, use deleteMMKV(...):

    import { deleteMMKV } from 'react-native-mmkv'
    
    const wasDeleted = deleteMMKV('my-instance')

    Testing with Jest or Vitest

    A mocked MMKV instance is automatically used when testing with Jest or Vitest, so you will be able to use createMMKV() as per normal in your tests. Refer to example/__tests__/MMKV.harness.ts for an example using Jest.

    Documentation

    LocalStorage and In-Memory Storage (Web)

    If a user chooses to disable LocalStorage in their browser, the library will automatically provide a limited in-memory storage as an alternative. However, this in-memory storage won’t persist data, and users may experience data loss if they refresh the page or close their browser. To optimize user experience, consider implementing a suitable solution within your app to address this scenario.

    Limitations

    • react-native-mmkv V3 requires react-native 0.74 or higher.
    • react-native-mmkv V3 requires the new architecture/TurboModules to be enabled.
    • Since react-native-mmkv uses JSI for synchronous native method invocations, remote debugging (e.g. with Chrome) is no longer possible. Instead, you should use Flipper or React DevTools.

    Integrations

    Rozenite

    Use @rozenite/mmkv-plugin to debug your MMKV storage using Rozenite.

    Reactotron

    Use reactotron-react-native-mmkv to automatically log writes to your MMKV storage using Reactotron. See the docs for how to setup this plugin with Reactotron.

    Community Discord

    Join the Margelo Community Discord to chat about react-native-mmkv or other Margelo libraries.

    Adopting at scale

    react-native-mmkv is provided as is, I work on it in my free time.

    If you’re integrating react-native-mmkv in a production app, consider funding this project and contact me to receive premium enterprise support, help with issues, prioritize bugfixes, request features, help at integrating react-native-mmkv, and more.

    Contributing

    See the contributing guide to learn how to contribute to the repository and the development workflow.

    License

    MIT

    Visit original content creator repository
  • CellTK

    CellTK

    Live-cell analysis toolkit.

    Image processing is simply an image conversion/transformation process.
    CellTK has the following five major processes which all implement conversion between img and labels.

    1. preprocessing: img -> img
    2. segmentation: img -> labels
    3. subdetection: labels (and img) -> labels
    4. tracking: labels -> labels*
    5. postprocessing: labels -> labels*

    where

    • img: np.ndarray[np.float32] (e.g. a raw image from a microscope)
    • labels: np.ndarray[np.int16] (e.g. nuclear objects)
      * tracked objects have consistent values over frames

    For each processes, you can find a module named *_operation.py. (e.g. celltk/preprocess_operations.py).

    These files are the “repositories” of functions.
    They simply contain a list of functions which takes an input and convert images. If you need a new function, simply add it to here.

    When you input a raw image, it should take TIFF or PNG files with various datatypes as well.

    Command line Example:

    The simplest way to apply a function is to use command.py.
    This option is convenient to play with functions and parameters.

    python celltk/command.py -i data/testimages0/CFP/img* -f constant_thres -p THRES=2000 -o output/c1
    python celltk/command.py -i data/testimages0/CFP/img* -l output/c1/img* -f run_lap track_neck_cut -o output/nuc
    

    -i for images path, -l for labels path, -o for an output directory, -f for a function name from *operation.py modules, -p for arguments to the function.

    Note that, time-lapse files need to have file names in a sorted order.

    Caller Example:

    You can run a pipeline of operations using celltk/caller.py.

    python celltk/caller.py input_files/input_tests1.yml
    

    This configuration file contains operations defined like this:

    - function: constant_thres
      images: /example/img_00*.tif
      output: output_0
      params:
        THRES: 500
    

    You can find how to set up a configuration file here.

    Apply to extract single-cell properties

    After segmenting and tracking cells, we want to extract single-cell properties as a table.

    Unlike other five major processes, celltk/apply.py produces csv and npz file as an output.

    python celltk/apply.py -i data/testimages0/CFP/img* -l output/nuc/img* -o output/array.npz
    

    By default, it will use a folder name as a table key.
    To specify table keys, use -p and -s in a command line.

    python celltk/apply.py -i data/testimages0/YFP/img* -l output/nuc/img* -o output/array.npz -p nuc -s YFP
    

    Or use obj_names and ch_names in a caller.

    # Sample YML
    - function: apply
      images:
        - DAPI/img*
        - TRITC/img*
      labels:
        - op001
        - op002
      ch_names:
        - DAPI
        - JNKKTR
      obj_names:
        - nuc
        - cyto
    

    The output can be loaded with LabeledArray class.
    e.g.

    python -c "from celltk.labeledarray import LabeledArray;arr = LabeledArray().load('output/array.npz');print arr.labels;print arr['CFP', 'nuc', 'x']"
    

    For visualization and manipulation of these arrays, I recommend to take a loot at covertrace.

    Install dependencies

    If you do not need a dev version, simply

    pip install celltk
    

    This will register celltk command, where you can pass input file like celltk input_file/input_tests1.yml.


    It is compatible with poetry.

    git clone https://github.com/braysia/CellTK.git & cd CellTK
    pip install poetry
    poetry install
    

    Install the additional package may speed up computation.

    pip install git+https://github.com/jfrelinger/cython-munkres-wrapper
    

    You can also pip install each – see this for example.


    The other option is to use Docker container.

    docker pull braysia/celltk
    docker run -it -v /$FOLDER_TO_MOUNT:/home/ braysia/celltk
    

    Please modify $FOLDER_TO_MOUNT, like docker run -it -v /Users/kudo/example:/home/ braysia/celltk.

    You can add “-p 8888:8888” for running jupyter notebook from the docker image.

    Covert lab specific details

    Visit original content creator repository