Skip to content
Merged
Show file tree
Hide file tree
Changes from 122 commits
Commits
Show all changes
134 commits
Select commit Hold shift + click to select a range
26b5204
BUGFIX: 3585 Fusion Runtime `@apply` with integer indexed array
mhsdesign Oct 26, 2022
83d3548
TASK: Update dependabot configuration
markusguenther Jan 9, 2023
59426d1
WIP FEATURE: `Neos.Fusion:Component` easy `@computed` props
mhsdesign Nov 1, 2022
c87f8c2
FEATURE: `Neos.Fusion:Component` `@private` props
mhsdesign Nov 2, 2022
dd16d27
FEATURE: `Neos.Fusion:Component` self referencing `@private` props
mhsdesign Nov 28, 2022
4c2df2e
FEATURE: `Neos.Fusion:Component` self referencing `@private` cannot b…
mhsdesign Nov 30, 2022
2ae7ae6
FEATURE: `Neos.Fusion:Component` self referencing `@private` add furt…
mhsdesign Nov 30, 2022
d44a0e8
TASK: Undo refactoring LazyProps
mhsdesign Nov 30, 2022
3d7d1a5
TASK: Implement suggestions from code-review
mhsdesign Feb 19, 2023
9a22af1
TASK: Update references [skip ci]
Feb 23, 2023
6a71d5b
TASK: Update references [skip ci]
Feb 23, 2023
1301444
TASK: Add changelog for 7.3.11 [skip ci]
Feb 23, 2023
1239c26
TASK: Update references [skip ci]
Feb 23, 2023
2e5b58d
TASK: Add changelog for 8.2.3 [skip ci]
Feb 23, 2023
485bf16
TASK: Add changelog for 8.1.3 [skip ci]
Feb 23, 2023
ea8362e
TASK: Add changelog for 8.0.8 [skip ci]
Feb 23, 2023
b24eece
FEATURE: Fusion `@private` can only be declared inside root prototype…
mhsdesign Feb 23, 2023
37c41cb
Docs: Neos.Fusion:Component @private
mhsdesign Feb 23, 2023
5642d8a
BUGFIX 3835 - FusionParser stricter $contextPathAndFileName handling …
mhsdesign Jul 16, 2022
e1752f8
BUGFIX 3835 - FusionParser pass 'FusionCode' Dto to ObjectTreeParser
mhsdesign Jul 16, 2022
e2423c6
BUGFIX 3835 - FusionService allow legacy relative 'appendFusionIncludes'
mhsdesign Jul 16, 2022
9f17973
BUGFIX 3835 Adjust FusionCode to FusionSourceCode and introduce new `…
mhsdesign Oct 6, 2022
16035f4
BUGFIX 3835 Adjust Fusion Tests to use new api `Parser::parseFrom`
mhsdesign Oct 6, 2022
42259df
BUGFIX 3835 use normal Fusion\Exception instead of FusionSourceCodeI…
mhsdesign Oct 22, 2022
fb0fd1f
BUGFIX 3835 remove accidental breaking change
mhsdesign Oct 22, 2022
cf0fd29
BUGFIX 3835 adjust php-doc
mhsdesign Oct 22, 2022
0f06163
BUGFIX 3835 use `static` instead of `self` with `#[Flow\Proxy(false)]`
mhsdesign Nov 2, 2022
92de9a6
BUGFIX 3835 cleanup legacy mapping in Neos\Fusion\Core\Parser::parse
mhsdesign Nov 2, 2022
27ed5e2
Task: Minor cleanup of the FusionService/Parser/Runtime API
mhsdesign Feb 24, 2023
15f69c1
TASK: Translated using Weblate (Dutch)
weblate Feb 24, 2023
d3897b5
TASK: Update references [skip ci]
Feb 24, 2023
43594bd
LOVE: The style ci
mhsdesign Feb 24, 2023
ac0f244
Task: Better testable FusionConfigurationCache via constructor injection
mhsdesign Feb 25, 2023
4c37a30
Task: Cleanup FusionSourceCodeFactory
mhsdesign Feb 25, 2023
a461dbc
Task: Adjust naming of FusionSourceCode::fromDangerousPotentiallyDiff…
mhsdesign Feb 25, 2023
0f20f68
Task: Make $sourceCode lazy of FusionSourceCode
mhsdesign Feb 25, 2023
e8b2cfe
Task: Remove direct replacement for deprecated FusionService::createR…
mhsdesign Feb 25, 2023
5b78d7b
Task: Rename FusionSourceCodeCollection::tryFromPackageRootFusion
mhsdesign Feb 25, 2023
1665e3a
Task: Clean up ugly FusionSourceCodeFactoryPrototypeGeneratorTest
mhsdesign Feb 25, 2023
99afa8f
Task: Internal naming things
mhsdesign Feb 25, 2023
18e0515
Task: @private prop proxy throws, if path is not render-able
mhsdesign Feb 25, 2023
a72f00b
Task: Reserve @private.renderer for the future ;)
mhsdesign Feb 25, 2023
d5667e3
Merge pull request #3997 from neos/task/dependabot
mhsdesign Mar 3, 2023
3d8915a
TASK: Update references [skip ci]
Mar 3, 2023
d5abffe
Merge pull request #3936 from mhsdesign/bugfix/3585-fusion-runtime-ap…
kdambekalns Mar 6, 2023
6018aed
TASK: Update references [skip ci]
Mar 6, 2023
bc382ce
FEATURE: Add group `default` to Neos.Neos:Node
mficzel Mar 6, 2023
a2a6c89
TASK: Deprecate PluginViews
mficzel Mar 6, 2023
9a55ded
TASK: Docs
mhsdesign Mar 7, 2023
b72ac01
TASK: Make add label workfow run on forks
markusguenther Mar 8, 2023
75e1fea
TASK: Unify attributes rendering
mficzel Mar 8, 2023
c26572a
Merge pull request #4068 from mficzel/feature/defaultGroupForInspector
ahaeslich Mar 8, 2023
d25efca
TASK: Update references [skip ci]
Mar 8, 2023
68d2da0
FEATURE: Allow plain labels for nodetypes
Sebobo Mar 9, 2023
54bae63
TASK: Fix typo
Sebobo Mar 9, 2023
e2dd80c
Merge pull request #3943 from neos/feature/fusionComponentEasyCompute…
mhsdesign Mar 9, 2023
821d292
TASK: Update references [skip ci]
Mar 9, 2023
b608cdf
Docs: FusionConfiguration
mhsdesign Mar 9, 2023
7fa4fc6
Merge pull request #3839 from mhsdesign/bugfix/3835/fusionCodeCollect…
mhsdesign Mar 9, 2023
ba49ae1
TASK: Translated using Weblate (Spanish)
weblate Mar 14, 2023
88b9fcd
TASK: Update translation files
weblate Mar 14, 2023
e17d683
TASK: Update references [skip ci]
Mar 14, 2023
d8928f1
TASK: Use NodeTypes folder in Neos.Neos
Sebobo Mar 16, 2023
afba5ef
TASK: Use NodeTypes folder in Neos.NodeTypes
Sebobo Mar 16, 2023
1ec39e0
TASK: Use NodeTypes folder in Neos.NodeTypes.AssetList
Sebobo Mar 16, 2023
6f30986
TASK: Use NodeTypes folder in Neos.NodeTypes.BaseMixins
Sebobo Mar 16, 2023
3d85170
TASK: Use NodeTypes folder in Neos.NodeTypes.ColumnLayouts
Sebobo Mar 16, 2023
edbca00
TASK: Use NodeTypes folder in Neos.NodeTypes.ContentReferences
Sebobo Mar 16, 2023
78cf68a
TASK: Use NodeTypes folder in Neos.NodeTypes.Form
Sebobo Mar 16, 2023
0c69a78
TASK: Use NodeTypes folder in Neos.NodeTypes.Form
Sebobo Mar 16, 2023
b195efb
TASK: Use NodeTypes folder in Neos.NodeTypes.Navigation
Sebobo Mar 16, 2023
2b59bee
TASK: Use NodeTypes folder in Neos.ContentRepository
Sebobo Mar 16, 2023
4f4b6de
TASK: Update translation files
weblate Mar 17, 2023
efad225
TASK: Update translation files
weblate Mar 17, 2023
08bfc02
TASK: Update references [skip ci]
Mar 17, 2023
e1e3147
TASK: Update translation files
weblate Mar 19, 2023
78a6fb0
TASK: Update translation files
weblate Mar 19, 2023
4fb1589
Merge pull request #4083 from neos/feature/allow-non-eel-labels
Sebobo Mar 19, 2023
072186e
Apply fixes from StyleCI
StyleCIBot Mar 19, 2023
3c6c360
TASK: Update references [skip ci]
Mar 19, 2023
f03ad8f
TASK: Update translation files
weblate Mar 21, 2023
d3924a4
TASK: Update translation files
weblate Mar 21, 2023
942f910
TASK: Update references [skip ci]
Mar 21, 2023
fdf85de
TASK: Update translation files
weblate Mar 22, 2023
e953814
TASK: Update translation files
weblate Mar 22, 2023
10139a2
TASK: Translated using Weblate (Spanish)
weblate Mar 23, 2023
b1cd8d8
Apply fixes from StyleCI
StyleCIBot Mar 23, 2023
0662d6d
TASK: Update references [skip ci]
Mar 23, 2023
9eebd4b
Merge pull request #4141 from neos/analysis-xgMVpB
kdambekalns Mar 24, 2023
8d77ed8
Merge pull request #4132 from neos/analysis-Kox94Q
kdambekalns Mar 24, 2023
743dceb
TASK: Update translation files
weblate Mar 27, 2023
71ec239
TASK: Update translation files
weblate Mar 27, 2023
3be6559
FEATURE: add dimensions hash to node event model
andrehoffmann30 Jan 27, 2021
3264d83
FEATURE: merge migrations and adjust postUp function
andrehoffmann30 Feb 2, 2021
1975ee6
TASK: fix up after rebase
andrehoffmann30 Feb 19, 2023
25d328d
TASK: Update translation files
weblate Mar 31, 2023
286d983
TASK: Update translation files
weblate Mar 31, 2023
b1ffa56
TASK: Update references [skip ci]
Mar 31, 2023
24bed8c
Merge pull request #3279 from andrehoffmann30/feature/add-dimensions-…
markusguenther Mar 31, 2023
26a9c80
TASK: Update references [skip ci]
Mar 31, 2023
33810fb
Merge pull request #4081 from mficzel/task/unifyAttributesRendering
markusguenther Apr 1, 2023
41eb945
TASK: Update references [skip ci]
Apr 1, 2023
76cca3e
Merge remote-tracking branch 'origin/7.3' into 8.0
markusguenther Apr 1, 2023
6c8566c
Merge remote-tracking branch 'origin/8.0' into 8.1
markusguenther Apr 1, 2023
a82ece0
Merge remote-tracking branch 'origin/8.1' into 8.2
markusguenther Apr 1, 2023
33e1a93
TASK: Update references [skip ci]
Apr 1, 2023
42c5744
Merge remote-tracking branch 'origin/8.2' into 8.3
markusguenther Apr 1, 2023
ac1f42e
Merge pull request #4116 from neos/task/neos-nodetypes-folder
mhsdesign Apr 1, 2023
e4eb9b2
Merge pull request #4069 from mficzel/task/deprecatePluginViews
mhsdesign Apr 1, 2023
7e6facf
BUGFIX: Make functional tests run
markusguenther Apr 4, 2023
a8d626d
Merge pull request #4169 from markusguenther/bugfix/fix-functional-test
mhsdesign Apr 4, 2023
0d16698
TASK: Update references [skip ci]
Apr 4, 2023
41a1b12
FEATURE: node migration generate command
crydotsnake Feb 15, 2023
6c4d5ba
TASK: implement logic to copy node migration
crydotsnake Feb 28, 2023
7598714
TASK: add documentation about new command
crydotsnake Feb 28, 2023
268d358
TASK: adjust class and method naming
crydotsnake Apr 4, 2023
fad3032
TASK: Add testcases for map and loop with iterables
mficzel Apr 4, 2023
6b47329
TASK: Support iterables that are not countable in `Neos.Fusion:Map`, …
mficzel Apr 4, 2023
dd983a8
Merge pull request #4038 from crydotsnake/feature/node-migration-gene…
mhsdesign Apr 4, 2023
8a37115
Merge pull request #4168 from mficzel/task/allowLoopAndMapToWorkWithI…
markusguenther Apr 5, 2023
e3e468a
TASK: Update references [skip ci]
Apr 5, 2023
2166aed
Merge branch '8.3' into 9.0
bwaidelich Apr 5, 2023
9777fb9
TASK: Upmerge #3839 correctly and remove deprecated code of the Fusio…
mhsdesign Jul 16, 2022
56ca2e1
TASK: Re-add deprecated code of the FusionService
mhsdesign Jul 16, 2022
cf29270
Remove obsolete injects
bwaidelich Apr 11, 2023
d199874
Replace global `NodeTypeManager` from `FusionSourceCodeFactory`
bwaidelich Apr 11, 2023
0077826
Merge branch '9.0' into task/upmerge
bwaidelich Apr 11, 2023
a06e1fa
Fix type of site node name in FusionService
bwaidelich Apr 11, 2023
d7f39ef
Remove broken injection from SchemaController
bwaidelich Apr 11, 2023
8b17b22
Mostly cosmetic fixes to satisfy linter
bwaidelich Apr 12, 2023
f829356
Style fix
bwaidelich Apr 12, 2023
ff5b3ea
Merge branch '9.0' into task/upmerge
bwaidelich Apr 12, 2023
eac8785
Fix VO casting
bwaidelich Apr 12, 2023
8058fff
more tweaks
bwaidelich Apr 12, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
version: 2
updates:
- package-ecosystem: composer
directory: "/"
schedule:
interval: weekly
time: "09:00"
open-pull-requests-limit: 10

# Maintain dependencies for npm
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "daily"
target-branch: "7.3"
open-pull-requests-limit: 0
labels:
- "security"

# Maintain dependencies for Composer
- package-ecosystem: "composer"
directory: "/"
schedule:
interval: weekly
time: "09:00"
target-branch: "7.3"
open-pull-requests-limit: 10
labels:
- "dependencies"
4 changes: 3 additions & 1 deletion .github/workflows/add-pr-labels.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Add Labels to Pull Request

on:
pull_request:
pull_request_target:
types: [opened, reopened, synchronize, edited]

jobs:
Expand All @@ -10,6 +10,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Maybe remove base branch label
if: github.event.action == 'edited' && github.event.changes.base.ref.from != ''
uses: actions-ecosystem/action-remove-labels@v1
Expand Down
6 changes: 3 additions & 3 deletions Neos.ContentRepository.Core/Classes/NodeType/NodeType.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?php
declare(strict_types=1);

namespace Neos\ContentRepository\Core\NodeType;

/*
* This file is part of the Neos.ContentRepository package.
Expand All @@ -10,9 +13,6 @@
* source code.
*/

declare(strict_types=1);

namespace Neos\ContentRepository\Core\NodeType;

use Neos\ContentRepository\Core\SharedModel\Exception\NodeTypeNotFoundException;
use Neos\ContentRepository\Core\SharedModel\Node\NodeName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,9 @@
type: string
someDate:
type: DateTime

'Neos.ContentRepository.Testing:NodeTypeWithPlainLabel':
label: 'Test nodetype'

'Neos.ContentRepository.Testing:NodeTypeWithEelExpressionLabel':
label: '${"Test" + " " + "nodetype"}'
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php
namespace Neos\ContentRepository\Migration\Service;

/*
* This file is part of the Neos.ContentRepository package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

use Neos\Flow\Annotations as Flow;
use Neos\Flow\Package\Exception\UnknownPackageException;
use Neos\Flow\Package\PackageManager;
use Neos\Utility\Exception\FilesException;
use Neos\Utility\Files;

/**
* Service for the Migration generator
*
*/
class MigrationGeneratorService
{
/**
* @Flow\Inject
*/
protected PackageManager $packageManager;

/**
* Creates a node migration for the given $packageKey
*
* @param string $packageKey the package key
* @return string
* @throws UnknownPackageException
* @throws FilesException
*/
public function generateBoilerplateMigrationFileInPackage(string $packageKey): string
{
$templatePath = 'resource://Neos.ContentRepository/Private/Generator/Migrations/ContentRepository/NodeMigrationTemplate.yaml.tmpl';
$nodeMigrationPath = Files::concatenatePaths([$this->packageManager->getPackage($packageKey)->getPackagePath(), 'Migrations/ContentRepository']) . '/';

$timeStamp = (new \DateTimeImmutable())->format('YmdHis');
$nodeMigrationFileName = 'Version' . $timeStamp . '.yaml';

$targetPathAndFilename = $nodeMigrationPath . $nodeMigrationFileName;
$fileContent = file_get_contents($templatePath);

if (!is_dir(dirname($targetPathAndFilename))) {
Files::createDirectoryRecursively(dirname($targetPathAndFilename));
}

file_put_contents($targetPathAndFilename, $fileContent);

return $packageKey . '/Migrations/ContentRepository/' . $nodeMigrationFileName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#############################################################################################################################################################################
# For more information about node migrations in Neos, checkout the documentation: https://neos.readthedocs.io/en/stable/References/NodeMigrations.html?highlight=migrations #
#############################################################################################################################################################################
up:
comments: 'Migration description'
migration:
-
filters:
-

down:
comments: 'No down migration available'
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
*/
class NodeTypeEnrichmentService
{

/**
* @Flow\Inject
* @var ResourceManager
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

class NodeTypesLoader implements LoaderInterface
{

/**
* @var YamlSource
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,14 @@ public function initializeObject()
}

/**
* Render a node label
* Render a node label based on an eel expression or return the expression if it is not valid eel.
* @throws \Neos\Eel\Exception
*/
public function getLabel(Node $node): string
{
if (Utility::parseEelExpression($this->getExpression()) === null) {
return $this->getExpression();
}
return (string)Utility::evaluateEelExpression($this->getExpression(), $this->eelEvaluator, ['node' => $node], $this->defaultContextConfiguration);
}
}
40 changes: 40 additions & 0 deletions Neos.Fusion/Classes/Core/FusionConfiguration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);

namespace Neos\Fusion\Core;

/*
* This file is part of the Neos.Fusion package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

/**
* This holds the parsed Fusion Configuration and can be used to pass it to the Runtime via
* {@see RuntimeFactory::createFromConfiguration()}
* The contents of this DTO are internal and can change at any time!
*/
final class FusionConfiguration
{
/** @internal */
protected function __construct(
private array $fusionConfiguration
) {
}

/** @internal */
public static function fromArray(array $fusionConfiguration)
{
return new static($fusionConfiguration);
}

/** @internal */
public function toArray()
{
return $this->fusionConfiguration;
}
}
58 changes: 58 additions & 0 deletions Neos.Fusion/Classes/Core/FusionSourceCode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);

namespace Neos\Fusion\Core;

/*
* This file is part of the Neos.Fusion package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

use Neos\Fusion;

final class FusionSourceCode
{
protected function __construct(
private ?string $filePath,
private string|\Closure $sourceCodeOrFactory,
) {
}

public static function fromString(string $string): self
{
return new static(null, $string);
}

public static function fromFilePath(string $filePath): self
{
if (is_readable($filePath) === false) {
throw new Fusion\Exception("Trying to read Fusion source code from file, but '$filePath' is not readable.", 1657963790);
}
return new static($filePath, fn () => file_get_contents($filePath));
}

/**
* Watch out for unexpected behaviour {@link https://github.com/neos/neos-development-collection/issues/3835}
*/
public static function fromDangerousPotentiallyDifferingSourceCodeAndFilePath(string $sourceCode, string $filePath): self
{
return new static($filePath, $sourceCode);
}

public function getSourceCode(): string
{
return $this->sourceCodeOrFactory instanceof \Closure
? $this->sourceCodeOrFactory = ($this->sourceCodeOrFactory)()
: $this->sourceCodeOrFactory;
}

public function getFilePath(): ?string
{
return $this->filePath;
}
}
92 changes: 92 additions & 0 deletions Neos.Fusion/Classes/Core/FusionSourceCodeCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php
declare(strict_types=1);

namespace Neos\Fusion\Core;

/*
* This file is part of the Neos.Fusion package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

/** @api */
final class FusionSourceCodeCollection implements \IteratorAggregate, \Countable
{
/** @var array<int, FusionSourceCode> */
private array $fusionCodeCollection;

/** @param $fusionSourceCode array<int, FusionSourceCode> */
public function __construct(FusionSourceCode ...$fusionSourceCode)
{
$this->fusionCodeCollection = self::deduplicateItemsAndKeepLast($fusionSourceCode);
}

public static function fromFilePath(string $filePath): self
{
return new static(FusionSourceCode::fromFilePath($filePath));
}

public static function fromString(string $string): self
{
return new static(FusionSourceCode::fromString($string));
}

public static function tryFromFilePath(string $filePath): self
{
if (!is_readable($filePath)) {
return static::empty();
}
return static::fromFilePath($filePath);
}

public static function tryFromPackageRootFusion(string $packageKey): self
{
$fusionPathAndFilename = sprintf('resource://%s/Private/Fusion/Root.fusion', $packageKey);
return static::tryFromFilePath($fusionPathAndFilename);
}

public static function empty()
{
return new static();
}

public function union(FusionSourceCodeCollection $other): self
{
return new static(...$this->fusionCodeCollection, ...$other->fusionCodeCollection);
}

/** @return \ArrayIterator<int,FusionSourceCode>|FusionSourceCode[] */
public function getIterator(): \ArrayIterator
{
return new \ArrayIterator($this->fusionCodeCollection);
}

public function count(): int
{
return count($this->fusionCodeCollection);
}

/**
* @param array<int, FusionSourceCode> $fusionSourceCode
* @return array<int, FusionSourceCode>
*/
private static function deduplicateItemsAndKeepLast(array $fusionSourceCode): array
{
$deduplicated = [];
$includedFilePathsAndTheirPreviousIndex = [];
foreach ($fusionSourceCode as $index => $sourceCode) {
if (isset($includedFilePathsAndTheirPreviousIndex[$sourceCode->getFilePath()])) {
unset($deduplicated[$includedFilePathsAndTheirPreviousIndex[$sourceCode->getFilePath()]]);
}
$deduplicated[$index] = $sourceCode;
if ($sourceCode->getFilePath()) {
$includedFilePathsAndTheirPreviousIndex[$sourceCode->getFilePath()] = $index;
}
}
return array_values($deduplicated);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
class MergedArrayTree
{
public function __construct(
protected array $tree = []
protected array $tree
) {
}

Expand Down
Loading