Fix bin/publish: copy docs.dist from project root

Fix bin/publish: use correct .env path for rspade_system
Fix bin/publish script: prevent grep exit code 1 from terminating script

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-10-21 02:08:33 +00:00
commit f6fac6c4bc
79758 changed files with 10547827 additions and 0 deletions

293
vendor/nicmart/tree/CHANGELOG.md vendored Executable file
View File

@@ -0,0 +1,293 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
For a full diff see [`0.9.0...master`][0.9.0...master].
## [`0.9.0`][0.9.0]
For a full diff see [0.8.0...0.9.0`][0.8.0...0.9.0].
### Added
- Added support for PHP 8.4 ([#331]), by [@pascalbaljet]
## [`0.8.0`][0.8.0]
For a full diff see [0.7.2...0.8.0`][0.7.2...0.8.0].
### Added
- Added support for PHP 8.3 ([#236]), by [@localheinz]
## [`0.7.2`][0.7.2]
For a full diff see [0.7.1...0.7.2`][0.7.1...0.7.2].
### Fixed
- Started throwing a `LogicException` when attempting to get a `Node` from an empty `NodeBuilder` ([#209]), by [@localheinz]
## [`0.7.1`][0.7.1]
For a full diff see [0.7.0...0.7.1`][0.7.0...0.7.1].
### Changed
- Made use of variadic parameters in `NodeBuilderInterface::leafs()` and `NodeBuilder::leafs()` ([#168]), by [@localheinz]
## [`0.7.0`][0.7.0]
For a full diff see [0.6.0...0.7.0`][0.6.0...0.7.0].
### Changed
- Changed return type declaration of `NodeInterface::root()` from `self` to `static` ([#149]), by [@localheinz]
- Added a missing return type declaration to `NodeInterface::getSize()` ([#150]), by [@localheinz]
- Added parameter type declarations ([#151]), by [@localheinz]
- Added property type declarations ([#152]), by [@localheinz]
### Fixed
- Returned empty array from `Node::getNeigbors()` when node is root ([#153]), by [@localheinz]
- Returned array with node only from `Node::getNeigborsAndSelf()` when node is root ([#154]), by [@localheinz]
## [`0.6.0`][0.6.0]
For a full diff see [0.5.0...0.6.0`][0.5.0...0.6.0].
### Changed
- Added return type declarations ([#113]), by [@localheinz]
- Added `getSize()` to `NodeInterface` ([#147]), by [@localheinz]
- Added `root()` to `NodeInterface` ([#148]), by [@localheinz]
## [`0.5.0`][0.5.0]
For a full diff see [`0.4.0...0.5.0`][0.4.0...0.5.0].
### Added
- Added support for PHP 8.2 ([#135]), by [@localheinz]
### Changed
- Dropped support for PHP 7.2 ([#136]), by [@localheinz]
- Dropped support for PHP 7.3 ([#137]), by [@localheinz]
- Dropped support for PHP 7.4 ([#138]), by [@localheinz]
## [`0.4.0`][0.4.0]
For a full diff see [`0.3.1...0.4.0`][0.3.1...0.4.0].
### Added
- Added support for PHP 8.1 ([#105]), by [@localheinz]
### Changed
- Dropped support for PHP 7.1 ([#106]), by [@localheinz]
## [`0.3.1`][0.3.1]
For a full diff see [`0.3.0...0.3.1`][0.3.0...0.3.1].
### Added
- Added support for PHP 8.0 ([#79]), by [@pascalbaljet]
### Changed
- Dropped support for PHP 5.4 ([#55]), by [@localheinz]
- Dropped support for PHP 5.5 ([#57]), by [@localheinz]
- Dropped support for PHP 5.6 ([#58]), by [@localheinz]
- Dropped support for PHP 7.0 ([#59]), by [@localheinz]
## [`0.3.0`][0.3.0]
For a full diff see [`0.2.7...0.3.0`][0.2.7...0.3.0].
### Added
- Added support for PHP 7.1 ([#47]), by [@localheinz]
- Added support for PHP 7.2 ([#48]), by [@localheinz]
- Added support for PHP 7.3 ([#49]), by [@localheinz]
- Added support for PHP 7.4 ([#50]), by [@localheinz]
### Changed
- Dropped support for HHVM ([#35]), by [@localheinz]
- Moved constructor from `NodeTrait` to `Node` ([#30]), by [@asalazar-pley]
## [`0.2.7`][0.2.7]
For a full diff see [`0.2.6...0.2.7`][0.2.6...0.2.7].
### Added
- Added pre-order and post-order visitors ([#24]), by [@localheinz]
## [`0.2.6`][0.2.6]
For a full diff see [`0.2.5...0.2.6`][0.2.5...0.2.6].
### Added
- Added a `getSize()` method to `Node` ([#17]), by [@Djuki]
## [`0.2.5`][0.2.5]
For a full diff see [`0.2.4...0.2.5`][0.2.4...0.2.5].
### Added
- Added `getDepth()` and `getHeight()` methods to `Node` ([#9]), by [@nicmart]
## [`0.2.4`][0.2.4]
For a full diff see [`0.2.3...0.2.4`][0.2.3...0.2.4].
### Added
- New accessor methods ([#6]), by [@mdwheele]
## [`0.2.3`][0.2.3]
For a full diff see [`0.2.2...0.2.3`][0.2.2...0.2.3].
### Changed
- `Node::getAncestors()` now does not return the current node ([#4]), by [@nicmart],
## [`0.2.2`][0.2.2]
For a full diff see [`0.2.1...0.2.2`][0.2.1...0.2.2].
### Fixed
- Fixed a bug in the builder ([#3]), by [@nicmart]
## [`0.2.1`][0.2.1]
For a full diff see [`0.2.0...0.2.1`][0.2.0...0.2.1].
### Added
- Added `root()` and `isRoot()` to `Node`
## [`0.2.0`][0.2.0]
For a full diff see [`0.1.2...0.2.0`][0.1.2...0.2.0].
### Changed
- Dropped support for PHP 5.3
- Extracted `NodeTrait` from `Node`
## [`0.1.2`][0.1.2]
For a full diff see [`0.1.1...0.1.2`][0.1.1...0.1.2].
### Added
- Added `YieldVisitor`, to get the yield of the tree
## [`0.1.1`][0.1.1]
For a full diff see [`fcfd14e...v0.1.1`][fcfd14e...0.1.1].
### Added
- Parent and neighbors methods, by [@jdeniau]
[0.1.1]: https://github.com/nicmart/Tree/releases/tag/v0.1.0
[0.1.2]: https://github.com/nicmart/Tree/releases/tag/v0.1.2
[0.2.0]: https://github.com/nicmart/Tree/releases/tag/v0.2.0
[0.2.1]: https://github.com/nicmart/Tree/releases/tag/v0.2.1
[0.2.2]: https://github.com/nicmart/Tree/releases/tag/v0.2.2
[0.2.3]: https://github.com/nicmart/Tree/releases/tag/v0.2.3
[0.2.4]: https://github.com/nicmart/Tree/releases/tag/v0.2.4
[0.2.5]: https://github.com/nicmart/Tree/releases/tag/v0.2.5
[0.2.6]: https://github.com/nicmart/Tree/releases/tag/v0.2.6
[0.2.7]: https://github.com/nicmart/Tree/releases/tag/v0.2.7
[0.3.0]: https://github.com/nicmart/Tree/releases/tag/0.3.0
[0.3.1]: https://github.com/nicmart/Tree/releases/tag/0.3.1
[0.4.0]: https://github.com/nicmart/Tree/releases/tag/0.4.0
[0.5.0]: https://github.com/nicmart/Tree/releases/tag/0.5.0
[0.6.0]: https://github.com/nicmart/Tree/releases/tag/0.6.0
[0.7.0]: https://github.com/nicmart/Tree/releases/tag/0.7.0
[0.7.1]: https://github.com/nicmart/Tree/releases/tag/0.7.1
[0.7.2]: https://github.com/nicmart/Tree/releases/tag/0.7.2
[0.8.0]: https://github.com/nicmart/Tree/releases/tag/0.8.0
[0.9.0]: https://github.com/nicmart/Tree/releases/tag/0.9.0
[fcfd14e...0.1.1]: https://github.com/nicmart/Tree/compare/fcfd14e...v0.1.1
[0.1.1...0.1.2]: https://github.com/nicmart/Tree/compare/v0.1.1...v0.1.2
[0.1.2...0.2.0]: https://github.com/nicmart/Tree/compare/v0.1.2...v0.2.0
[0.2.0...0.2.1]: https://github.com/nicmart/Tree/compare/v0.2.0...v0.2.1
[0.2.1...0.2.2]: https://github.com/nicmart/Tree/compare/v0.2.1...v0.2.2
[0.2.2...0.2.3]: https://github.com/nicmart/Tree/compare/v0.2.2...v0.2.3
[0.2.3...0.2.4]: https://github.com/nicmart/Tree/compare/v0.2.3...v0.2.4
[0.2.4...0.2.5]: https://github.com/nicmart/Tree/compare/v0.2.4...v0.2.5
[0.2.5...0.2.6]: https://github.com/nicmart/Tree/compare/v0.2.5...v0.2.6
[0.2.6...0.2.7]: https://github.com/nicmart/Tree/compare/v0.2.6...v0.2.7
[0.2.7...0.3.0]: https://github.com/nicmart/Tree/compare/v0.2.7...0.3.0
[0.3.0...0.3.1]: https://github.com/nicmart/Tree/compare/0.3.0...0.3.1
[0.3.1...0.4.0]: https://github.com/nicmart/Tree/compare/0.3.1...0.4.0
[0.4.0...0.5.0]: https://github.com/nicmart/Tree/compare/0.4.0...0.5.0
[0.5.0...0.6.0]: https://github.com/nicmart/Tree/compare/0.5.0...0.6.0
[0.6.0...0.7.0]: https://github.com/nicmart/Tree/compare/0.6.0...0.7.0
[0.7.0...0.7.1]: https://github.com/nicmart/Tree/compare/0.7.0...0.7.1
[0.7.1...0.7.2]: https://github.com/nicmart/Tree/compare/0.7.1...0.7.2
[0.7.2...0.8.0]: https://github.com/nicmart/Tree/compare/0.7.2...0.8.0
[0.8.0...0.9.0]: https://github.com/nicmart/Tree/compare/0.8.0...0.9.0
[0.9.0...master]: https://github.com/nicmart/Tree/compare/0.9.0...master
[#3]: https://github.com/nicmart/Tree/issues/3
[#4]: https://github.com/nicmart/Tree/issues/4
[#6]: https://github.com/nicmart/Tree/pull/6
[#9]: https://github.com/nicmart/Tree/issues/9
[#17]: https://github.com/nicmart/Tree/pull/17
[#24]: https://github.com/nicmart/Tree/pull/24
[#30]: https://github.com/nicmart/Tree/pull/30
[#35]: https://github.com/nicmart/Tree/pull/35
[#47]: https://github.com/nicmart/Tree/pull/47
[#48]: https://github.com/nicmart/Tree/pull/48
[#49]: https://github.com/nicmart/Tree/pull/49
[#50]: https://github.com/nicmart/Tree/pull/50
[#55]: https://github.com/nicmart/Tree/pull/55
[#57]: https://github.com/nicmart/Tree/pull/57
[#58]: https://github.com/nicmart/Tree/pull/58
[#59]: https://github.com/nicmart/Tree/pull/59
[#79]: https://github.com/nicmart/Tree/pull/79
[#105]: https://github.com/nicmart/Tree/pull/105
[#106]: https://github.com/nicmart/Tree/pull/106
[#113]: https://github.com/nicmart/Tree/pull/113
[#125]: https://github.com/nicmart/Tree/pull/125
[#136]: https://github.com/nicmart/Tree/pull/136
[#137]: https://github.com/nicmart/Tree/pull/137
[#138]: https://github.com/nicmart/Tree/pull/138
[#147]: https://github.com/nicmart/Tree/pull/147
[#148]: https://github.com/nicmart/Tree/pull/148
[#149]: https://github.com/nicmart/Tree/pull/149
[#150]: https://github.com/nicmart/Tree/pull/150
[#151]: https://github.com/nicmart/Tree/pull/151
[#152]: https://github.com/nicmart/Tree/pull/152
[#153]: https://github.com/nicmart/Tree/pull/153
[#154]: https://github.com/nicmart/Tree/pull/154
[#168]: https://github.com/nicmart/Tree/pull/168
[#209]: https://github.com/nicmart/Tree/pull/209
[#236]: https://github.com/nicmart/Tree/pull/236
[#331]: https://github.com/nicmart/Tree/pull/331
[@asalazar-pley]: https://github.com/asalazar-pley
[@Djuki]: https://github.com/Djuki
[@jdeniau]: https://github.com/jdeniau
[@localheinz]: https://github.com/localheinz
[@mdwheele]: https://github.com/mdwheele
[@nicmart]: https://github.com/nicmart
[@pascalbaljet]: https://github.com/pascalbaljet

16
vendor/nicmart/tree/LICENSE.md vendored Executable file
View File

@@ -0,0 +1,16 @@
# The MIT License (MIT)
Copyright (c) 2013-2024 Nicolò Martini
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the _Software_), to deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED **AS IS**, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

286
vendor/nicmart/tree/README.md vendored Executable file
View File

@@ -0,0 +1,286 @@
# Tree
[![Integrate](https://github.com/nicmart/Tree/workflows/Integrate/badge.svg?branch=master)](https://github.com/nicmart/Tree/actions)
[![Release](https://github.com/nicmart/Tree/workflows/Release/badge.svg?branch=master)](https://github.com/nicmart/Tree/actions)
[![Code Coverage](https://codecov.io/gh/nicmart/tree/branch/master/graph/badge.svg)](https://codecov.io/gh/nicmart/tree)
[![Type Coverage](https://shepherd.dev/github/nicmart/tree/coverage.svg)](https://shepherd.dev/github/nicmart/tree)
[![Latest Stable Version](https://poser.pugx.org/nicmart/tree/v/stable)](https://packagist.org/packages/nicmart/tree)
[![Total Downloads](https://poser.pugx.org/nicmart/tree/downloads)](https://packagist.org/packages/nicmart/tree)
[![Monthly Downloads](http://poser.pugx.org/nicmart/tree/d/monthly)](https://packagist.org/packages/nicmart/tree)
In Tree you can find a basic but flexible tree data structure for php together with and an handful Builder class, that enables you to build tree in a fluent way.
## The tree data structure
The `Tree\Node\NodeInterface` interface abstracts the concept of a tree node. In `Tree` a Node has essentially two things:
a set of children (that implements the same `NodeInterface` interface) and a value.
On the other hand, the `Tree\Node\Node` gives a straight implementation for that interface.
### Creating a node
```php
use Tree\Node\Node;
$node = new Node('foo');
```
### Getting and setting the value of a node
Each node has a value property, that can be any php value.
```php
$node->setValue('my value');
echo $node->getValue(); //Prints 'my value'
```
### Adding one or more children
```php
$child1 = new Node('child1');
$child2 = new Node('child2');
$node
->addChild($child1)
->addChild($child2);
```
### Removing a child
```php
$node->removeChild($child1);
```
### Getting the array of all children
```php
$children = $node->getChildren();
```
### Overwriting the children set
```php
$node->setChildren([new Node('foo'), new Node('bar')]);
```
### Removing all children
```php
$node->removeAllChildren();
```
### Getting if the node is a leaf or not
A leaf is a node with no children.
```php
$node->isLeaf();
```
### Getting if the node is a child or not
A child is a node that has a parent.
```php
$node->isChild();
```
### Getting the parent of a node
Reference to the parent node is automatically managed by child-modifiers methods
```php
$root->addChild($node = new Node('child'));
$node->getParent(); // Returns $root
```
### Getting the ancestors of a node
```php
$root = (new Node('root'))
->addChild($child = new Node('child'))
->addChild($grandChild = new Node('grandchild'))
;
$grandchild->getAncestors(); // Returns [$root, $child]
```
#### Related Methods
- `getAncestorsAndSelf` retrieves ancestors of a node with the current node included.
### Getting the root of a node
```php
$root = $node->root();
```
### Getting the neighbors of a node
```php
$root = (new Node('root'))
->addChild($child1 = new Node('child1'))
->addChild($child2 = new Node('child2'))
->addChild($child3 = new Node('child3'))
;
$child2->getNeighbors(); // Returns [$child1, $child3]
```
#### Related Methods
- `getNeighborsAndSelf` retrieves neighbors of current node and the node itself.
### Getting the number of nodes in the tree
```php
$node->getSize();
```
### Getting the depth of a node
```php
$node->getDepth();
```
### Getting the height of a node
```php
$node->getHeight();
```
## The Builder
The builder provides a convenient way to build trees. It is provided by the ```Builder``` class,
but you can implement your own builder making an implementation of the ```BuilderInterface```class.
### Example
Let's see how to build the following tree, where the nodes label are represents nodes values:
```
A
/ \
B C
/|\
D E F
/|
G H
```
And here is the code:
```php
$builder = new Tree\Builder\NodeBuilder;
$builder
->value('A')
->leaf('B')
->tree('C')
->tree('D')
->leaf('G')
->leaf('H')
->end()
->leaf('E')
->leaf('F')
->end()
;
$nodeA = $builder->getNode();
```
The example should be self-explanatory, but here you are a brief description of the methods used above.
### Builder::value($value)
Set the value of the current node to ```$value```
### Builder::leaf($value)
Add to the current node a new child whose value is ```$value```.
### Builder::tree($value)
Add to the current node a new child whose value is ```$value```, and set the new node as the builder current node.
### Builder::end()
Returns to the context the builder was before the call to ```tree```method,
i.e. make the builder go one level up.
### Builder::getNode()
Returns the current node.
## Traversing a tree
### Yield
You can obtain the yield of a tree (i.e. the list of leaves in a pre-order traversal) using
the YieldVisitor.
For example, if `$node` is the tree built above, then
```php
use Tree\Visitor\YieldVisitor;
$visitor = new YieldVisitor;
$yield = $node->accept($visitor);
// $yield will contain nodes B, G, H, E, F
```
### Pre-order Traversal
You can walk a tree in pre-order:
```php
use Tree\Visitor\PreOrderVisitor;
$visitor = new PreOrderVisitor;
$yield = $node->accept($visitor);
// $yield will contain nodes A, B, C, D, G, H, E, F
```
### Post-order Traversal
You can walk a tree in post-order:
```php
use Tree\Visitor\PostOrderVisitor;
$visitor = new PostOrderVisitor;
$yield = $node->accept($visitor);
// $yield will contain nodes B, G, H, D, E, F, C, A
```
## Install
Run
```
$ composer require nicmart/tree
```
# Tests
```
phpunit
```
## Changelog
Please have a look at [`CHANGELOG.md`](CHANGELOG.md).
## Contributing
Please have a look at [`CONTRIBUTING.md`](.github/CONTRIBUTING.md).
## License
This package is licensed using the MIT License.
Please have a look at [`LICENSE.md`](LICENSE.md).

50
vendor/nicmart/tree/composer.json vendored Executable file
View File

@@ -0,0 +1,50 @@
{
"name": "nicmart/tree",
"description": "A basic but flexible php tree data structure and a fluent tree builder implementation.",
"license": "MIT",
"type": "library",
"keywords": [],
"authors": [
{
"name": "Nicolò Martini",
"email": "nicmartnic@gmail.com"
},
{
"name": "Andreas Möller",
"email": "am@localheinz.com"
}
],
"require": {
"php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
},
"require-dev": {
"ergebnis/composer-normalize": "^2.44.0",
"ergebnis/license": "^2.6.0",
"ergebnis/php-cs-fixer-config": "^6.28.1",
"fakerphp/faker": "^1.24.1",
"infection/infection": "~0.26.19",
"phpunit/phpunit": "^9.6.19",
"psalm/plugin-phpunit": "~0.19.0",
"vimeo/psalm": "^5.26.1"
},
"autoload": {
"psr-4": {
"Tree\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tree\\Test\\": "test/"
}
},
"config": {
"allow-plugins": {
"ergebnis/composer-normalize": true,
"infection/extension-installer": true
},
"platform": {
"php": "8.0.25"
},
"sort-packages": true
}
}

6150
vendor/nicmart/tree/composer.lock generated vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,116 @@
<?php
/**
* Copyright (c) 2013-2024 Nicolò Martini
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/nicmart/Tree
*/
namespace Tree\Builder;
use Tree\Node\Node;
use Tree\Node\NodeInterface;
/**
* Main implementation of the NodeBuilderInterface.
*/
class NodeBuilder implements NodeBuilderInterface
{
/**
* @var array<int, NodeInterface>
*/
private array $nodeStack = [];
public function __construct(?NodeInterface $node = null)
{
$this->setNode($node ?: $this->nodeInstanceByValue());
}
public function setNode(NodeInterface $node): static
{
$this
->emptyStack()
->pushNode($node);
return $this;
}
public function getNode(): NodeInterface
{
$count = \count($this->nodeStack);
if (0 === $count) {
throw new \LogicException('The node builder currently does not manage any nodes.');
}
return $this->nodeStack[$count - 1];
}
public function leaf(mixed $value = null): static
{
$this->getNode()->addChild(
$this->nodeInstanceByValue($value),
);
return $this;
}
public function leafs(mixed ...$values): static
{
foreach ($values as $value) {
$this->leaf($value);
}
return $this;
}
public function tree(mixed $value = null): static
{
$node = $this->nodeInstanceByValue($value);
$this->getNode()->addChild($node);
$this->pushNode($node);
return $this;
}
public function end(): ?static
{
$this->popNode();
return $this;
}
public function nodeInstanceByValue(mixed $value = null): NodeInterface
{
return new Node($value);
}
public function value(mixed $value): static
{
$this->getNode()->setValue($value);
return $this;
}
private function emptyStack(): static
{
$this->nodeStack = [];
return $this;
}
private function pushNode(NodeInterface $node): static
{
$this->nodeStack[] = $node;
return $this;
}
private function popNode(): void
{
\array_pop($this->nodeStack);
}
}

View File

@@ -0,0 +1,65 @@
<?php
/**
* Copyright (c) 2013-2024 Nicolò Martini
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/nicmart/Tree
*/
namespace Tree\Builder;
use Tree\Node\NodeInterface;
/**
* Interface that allows a fluent tree building.
*
* @author Nicolò Martini <nicmartnic@gmail.com>
*/
interface NodeBuilderInterface
{
/**
* Set the node the builder will manage.
*/
public function setNode(NodeInterface $node): static;
/**
* Get the node the builder manages.
*
* @throws \LogicException
*/
public function getNode(): NodeInterface;
/**
* Set the value of the underlaying node.
*/
public function value(mixed $value): static;
/**
* Add a leaf to the node.
*/
public function leaf(mixed $value = null): static;
/**
* Add several leafs to the node.
*/
public function leafs(mixed ...$values): static;
/**
* Add a child to the node enter in its scope.
*/
public function tree(mixed $value = null): static;
/**
* Goes up to the parent node context.
*/
public function end(): ?static;
/**
* Return a node instance set with the given value. Implementation can follow their own logic
* in choosing the NodeInterface implmentation taking into account the value.
*/
public function nodeInstanceByValue(mixed $value = null): NodeInterface;
}

33
vendor/nicmart/tree/src/Node/Node.php vendored Executable file
View File

@@ -0,0 +1,33 @@
<?php
/**
* Copyright (c) 2013-2024 Nicolò Martini
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/nicmart/Tree
*/
namespace Tree\Node;
class Node implements NodeInterface
{
use NodeTrait;
/**
* @param array<int, NodeInterface> $children
*/
public function __construct(
mixed $value = null,
array $children = [],
) {
$this->setValue($value);
if ([] === $children) {
return;
}
$this->setChildren($children);
}
}

139
vendor/nicmart/tree/src/Node/NodeInterface.php vendored Executable file
View File

@@ -0,0 +1,139 @@
<?php
/**
* Copyright (c) 2013-2024 Nicolò Martini
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/nicmart/Tree
*/
namespace Tree\Node;
use Tree\Visitor\Visitor;
/**
* Interface for tree nodes.
*
* @author Nicolò Martini <nicmartnic@gmail.com>
*/
interface NodeInterface
{
/**
* Set the value of the current node.
*/
public function setValue(mixed $value): static;
/**
* Get the current node value.
*/
public function getValue(): mixed;
/**
* Add a child.
*
* @return mixed
*/
public function addChild(self $child): static;
/**
* Remove a node from children.
*/
public function removeChild(self $child): static;
/**
* Remove all children.
*/
public function removeAllChildren(): static;
/**
* Return the array of children.
*
* @return array<int, NodeInterface>
*/
public function getChildren(): array;
/**
* Replace the children set with the given one.
*
* @param array<int, NodeInterface> $children
*
* @return mixed
*/
public function setChildren(array $children): static;
/**
* Set the parent node.
*/
public function setParent(?self $parent = null): void;
/**
* Return the parent node.
*/
public function getParent(): ?static;
/**
* Retrieves all ancestors of node excluding current node.
*/
public function getAncestors(): array;
/**
* Retrieves all ancestors of node as well as the node itself.
*
* @return array<int, Node>
*/
public function getAncestorsAndSelf(): array;
/**
* Retrieves all neighboring nodes, excluding the current node.
*/
public function getNeighbors(): array;
/**
* Returns all neighboring nodes, including the current node.
*
* @return array<int, NodeInterface>
*/
public function getNeighborsAndSelf(): array;
/**
* Return true if the node is the root, false otherwise.
*/
public function isRoot(): bool;
/**
* Return true if the node is a child, false otherwise.
*/
public function isChild(): bool;
/**
* Return true if the node has no children, false otherwise.
*/
public function isLeaf(): bool;
/**
* Find the root of the node.
*/
public function root(): static;
/**
* Return the distance from the current node to the root.
*/
public function getDepth(): int;
/**
* Return the height of the tree whose root is this node.
*/
public function getHeight(): int;
/**
* Return the number of nodes in a tree.
*/
public function getSize(): int;
/**
* Accept method for the visitor pattern (see http://en.wikipedia.org/wiki/Visitor_pattern).
*/
public function accept(Visitor $visitor): mixed;
}

214
vendor/nicmart/tree/src/Node/NodeTrait.php vendored Executable file
View File

@@ -0,0 +1,214 @@
<?php
/**
* Copyright (c) 2013-2024 Nicolò Martini
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/nicmart/Tree
*/
namespace Tree\Node;
use Tree\Visitor\Visitor;
trait NodeTrait
{
private mixed $value = null;
private ?NodeInterface $parent = null;
/**
* @var array<int, NodeInterface>
*/
private array $children = [];
public function setValue(mixed $value): static
{
$this->value = $value;
return $this;
}
public function getValue(): mixed
{
return $this->value;
}
public function addChild(NodeInterface $child): static
{
$child->setParent($this);
$this->children[] = $child;
return $this;
}
public function removeChild(NodeInterface $child): static
{
foreach ($this->children as $key => $myChild) {
if ($child === $myChild) {
unset($this->children[$key]);
}
}
$this->children = \array_values($this->children);
$child->setParent(null);
return $this;
}
public function removeAllChildren(): static
{
$this->setChildren([]);
return $this;
}
public function getChildren(): array
{
return $this->children;
}
public function setChildren(array $children): static
{
foreach ($this->getChildren() as $child) {
$child->setParent(null);
}
$this->children = [];
foreach ($children as $child) {
$this->addChild($child);
}
return $this;
}
public function setParent(?NodeInterface $parent = null): void
{
$this->parent = $parent;
}
public function getParent(): ?static
{
return $this->parent;
}
public function getAncestors(): array
{
$parents = [];
$node = $this;
while (($parent = $node->getParent()) instanceof NodeInterface) {
\array_unshift($parents, $parent);
$node = $parent;
}
return $parents;
}
public function getAncestorsAndSelf(): array
{
return \array_merge($this->getAncestors(), [$this]);
}
public function getNeighbors(): array
{
if (null === $this->parent) {
return [];
}
$neighbors = $this->parent->getChildren();
$that = $this;
return \array_values(\array_filter($neighbors, static function (NodeInterface $node) use ($that): bool {
return $node !== $that;
}));
}
public function getNeighborsAndSelf(): array
{
if (null === $this->parent) {
return [
$this,
];
}
return $this->parent->getChildren();
}
public function isRoot(): bool
{
return null === $this->parent;
}
public function isChild(): bool
{
return null !== $this->parent;
}
public function isLeaf(): bool
{
return [] === $this->children;
}
public function root(): static
{
$node = $this;
while (($parent = $node->getParent()) instanceof NodeInterface) {
$node = $parent;
}
return $node;
}
/**
* Return the distance from the current node to the root.
*
* Warning, can be expensive, since each descendant is visited
*/
public function getDepth(): int
{
if ($this->isRoot()) {
return 0;
}
return $this->getParent()->getDepth() + 1;
}
/**
* Return the height of the tree whose root is this node.
*/
public function getHeight(): int
{
if ($this->isLeaf()) {
return 0;
}
$heights = [];
foreach ($this->getChildren() as $child) {
$heights[] = $child->getHeight();
}
return \max($heights) + 1;
}
public function getSize(): int
{
$size = 1;
foreach ($this->getChildren() as $child) {
$size += $child->getSize();
}
return $size;
}
public function accept(Visitor $visitor): mixed
{
return $visitor->visit($this);
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
* Copyright (c) 2013-2024 Nicolò Martini
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/nicmart/Tree
*/
namespace Tree\Visitor;
use Tree\Node\NodeInterface;
class PostOrderVisitor implements Visitor
{
/**
* @return array<int, NodeInterface> $node
*/
public function visit(NodeInterface $node): mixed
{
$nodes = [];
foreach ($node->getChildren() as $child) {
$nodes = \array_merge(
$nodes,
$child->accept($this),
);
}
$nodes[] = $node;
return $nodes;
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
* Copyright (c) 2013-2024 Nicolò Martini
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/nicmart/Tree
*/
namespace Tree\Visitor;
use Tree\Node\NodeInterface;
class PreOrderVisitor implements Visitor
{
/**
* @return array<int, NodeInterface> $node
*/
public function visit(NodeInterface $node): array
{
$nodes = [
$node,
];
foreach ($node->getChildren() as $child) {
$nodes = \array_merge(
$nodes,
$child->accept($this),
);
}
return $nodes;
}
}

24
vendor/nicmart/tree/src/Visitor/Visitor.php vendored Executable file
View File

@@ -0,0 +1,24 @@
<?php
/**
* Copyright (c) 2013-2024 Nicolò Martini
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/nicmart/Tree
*/
namespace Tree\Visitor;
use Tree\Node\NodeInterface;
/**
* Visitor interface for Nodes.
*
* @author Nicolò Martini <nicmartnic@gmail.com>
*/
interface Visitor
{
public function visit(NodeInterface $node): mixed;
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* Copyright (c) 2013-2024 Nicolò Martini
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/nicmart/Tree
*/
namespace Tree\Visitor;
use Tree\Node\NodeInterface;
class YieldVisitor implements Visitor
{
/**
* @return array<int, NodeInterface>
*/
public function visit(NodeInterface $node): mixed
{
if ($node->isLeaf()) {
return [$node];
}
$yield = [];
foreach ($node->getChildren() as $child) {
$yield = \array_merge($yield, $child->accept($this));
}
return $yield;
}
}