urban-json 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- urban_json-0.1.0/LICENSE +21 -0
- urban_json-0.1.0/PKG-INFO +86 -0
- urban_json-0.1.0/README.md +53 -0
- urban_json-0.1.0/pyproject.toml +69 -0
- urban_json-0.1.0/setup.cfg +4 -0
- urban_json-0.1.0/src/urban_json/__init__.py +204 -0
- urban_json-0.1.0/src/urban_json/_antlr/JsltLexer.interp +211 -0
- urban_json-0.1.0/src/urban_json/_antlr/JsltLexer.py +306 -0
- urban_json-0.1.0/src/urban_json/_antlr/JsltLexer.tokens +115 -0
- urban_json-0.1.0/src/urban_json/_antlr/JsltParser.interp +178 -0
- urban_json-0.1.0/src/urban_json/_antlr/JsltParser.py +3497 -0
- urban_json-0.1.0/src/urban_json/_antlr/JsltParser.tokens +115 -0
- urban_json-0.1.0/src/urban_json/_antlr/JsltParserListener.py +381 -0
- urban_json-0.1.0/src/urban_json/_antlr/JsltParserVisitor.py +218 -0
- urban_json-0.1.0/src/urban_json/_antlr/__init__.py +0 -0
- urban_json-0.1.0/src/urban_json/ast/__init__.py +44 -0
- urban_json-0.1.0/src/urban_json/ast/base.py +76 -0
- urban_json-0.1.0/src/urban_json/ast/kind.py +38 -0
- urban_json-0.1.0/src/urban_json/ast/location.py +35 -0
- urban_json-0.1.0/src/urban_json/ast/nodes.py +319 -0
- urban_json-0.1.0/src/urban_json/ast/operation.py +39 -0
- urban_json-0.1.0/src/urban_json/ast/visitor.py +180 -0
- urban_json-0.1.0/src/urban_json/errors.py +45 -0
- urban_json-0.1.0/src/urban_json/functions/__init__.py +34 -0
- urban_json-0.1.0/src/urban_json/functions/_helpers.py +74 -0
- urban_json-0.1.0/src/urban_json/functions/builtins.py +110 -0
- urban_json-0.1.0/src/urban_json/functions/collection.py +49 -0
- urban_json-0.1.0/src/urban_json/functions/encoding.py +54 -0
- urban_json-0.1.0/src/urban_json/functions/maths.py +113 -0
- urban_json-0.1.0/src/urban_json/functions/misc.py +35 -0
- urban_json-0.1.0/src/urban_json/functions/registry.py +288 -0
- urban_json-0.1.0/src/urban_json/functions/text.py +79 -0
- urban_json-0.1.0/src/urban_json/jsonpath/__init__.py +43 -0
- urban_json-0.1.0/src/urban_json/jsonpath/filter.py +150 -0
- urban_json-0.1.0/src/urban_json/jsonpath/node.py +33 -0
- urban_json-0.1.0/src/urban_json/jsonpath/path.py +54 -0
- urban_json-0.1.0/src/urban_json/jsonpath/segment.py +56 -0
- urban_json-0.1.0/src/urban_json/jsonpath/selectors.py +183 -0
- urban_json-0.1.0/src/urban_json/parsing/__init__.py +5 -0
- urban_json-0.1.0/src/urban_json/parsing/antlr_parser.py +56 -0
- urban_json-0.1.0/src/urban_json/parsing/script_builder_visitor.py +595 -0
- urban_json-0.1.0/src/urban_json/py.typed +0 -0
- urban_json-0.1.0/src/urban_json/runtime/__init__.py +18 -0
- urban_json-0.1.0/src/urban_json/runtime/compiler.py +357 -0
- urban_json-0.1.0/src/urban_json/runtime/context.py +83 -0
- urban_json-0.1.0/src/urban_json/runtime/debug.py +188 -0
- urban_json-0.1.0/src/urban_json/runtime/evaluator.py +217 -0
- urban_json-0.1.0/src/urban_json/runtime/operators.py +198 -0
- urban_json-0.1.0/src/urban_json/runtime/variables.py +61 -0
- urban_json-0.1.0/src/urban_json/serialization.py +120 -0
- urban_json-0.1.0/src/urban_json.egg-info/PKG-INFO +86 -0
- urban_json-0.1.0/src/urban_json.egg-info/SOURCES.txt +72 -0
- urban_json-0.1.0/src/urban_json.egg-info/dependency_links.txt +1 -0
- urban_json-0.1.0/src/urban_json.egg-info/requires.txt +6 -0
- urban_json-0.1.0/src/urban_json.egg-info/top_level.txt +1 -0
- urban_json-0.1.0/tests/test_builtin_functions.py +59 -0
- urban_json-0.1.0/tests/test_casts.py +38 -0
- urban_json-0.1.0/tests/test_compiler.py +131 -0
- urban_json-0.1.0/tests/test_debug.py +71 -0
- urban_json-0.1.0/tests/test_distinct.py +45 -0
- urban_json-0.1.0/tests/test_extensibility.py +173 -0
- urban_json-0.1.0/tests/test_functions.py +58 -0
- urban_json-0.1.0/tests/test_functions_extended.py +94 -0
- urban_json-0.1.0/tests/test_guide_examples.py +76 -0
- urban_json-0.1.0/tests/test_jsonpath.py +76 -0
- urban_json-0.1.0/tests/test_jsonpath_advanced.py +47 -0
- urban_json-0.1.0/tests/test_jsonpath_filter.py +128 -0
- urban_json-0.1.0/tests/test_loops.py +67 -0
- urban_json-0.1.0/tests/test_operators.py +56 -0
- urban_json-0.1.0/tests/test_parsing.py +123 -0
- urban_json-0.1.0/tests/test_serialization.py +78 -0
- urban_json-0.1.0/tests/test_transform.py +76 -0
- urban_json-0.1.0/tests/test_variables.py +88 -0
- urban_json-0.1.0/tests/test_when.py +38 -0
urban_json-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 black beard
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: urban-json
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Portage Python du langage JSLT (JSON Stylesheet Language Transformations) — transformation JSON vers JSON pilotée par template.
|
|
5
|
+
Author-email: Gael Beard <gaelgael5@gmail.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/gaelgael5/Jslt
|
|
8
|
+
Project-URL: Repository, https://github.com/gaelgael5/Jslt
|
|
9
|
+
Project-URL: Documentation, https://github.com/gaelgael5/Jslt/blob/main/docs/guide.md
|
|
10
|
+
Project-URL: Issues, https://github.com/gaelgael5/Jslt/issues
|
|
11
|
+
Keywords: json,transform,template,jslt,jsonpath
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Topic :: Text Processing :: Markup
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.9
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: antlr4-python3-runtime==4.13.2
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
30
|
+
Requires-Dist: ruff==0.16.8; extra == "dev"
|
|
31
|
+
Requires-Dist: build>=1; extra == "dev"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
# urban-json
|
|
35
|
+
|
|
36
|
+
Portage Python du langage **JSLT — JSON Stylesheet Language Transformations** :
|
|
37
|
+
un langage de **transformation JSON → JSON piloté par template**, initialement
|
|
38
|
+
implémenté en .NET ([Black-Beard-Sdk/jslt](https://github.com/Black-Beard-Sdk/jslt)).
|
|
39
|
+
|
|
40
|
+
C'est le **paquet cœur** (moteur : parser, AST, interpréteur, JSONPath, fonctions
|
|
41
|
+
intégrées, extensibilité). Les capacités d'E-S (CSV, XML, SQL, HTTP, Elasticsearch)
|
|
42
|
+
sont des **plugins séparés** (`urban-json-csv`, `urban-json-xml`, `urban-json-db`, `urban-json-http`,
|
|
43
|
+
`urban-json-elastic`) découverts automatiquement.
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from urban_json import JsltTemplate
|
|
47
|
+
|
|
48
|
+
template = JsltTemplate.parse('{ "name": $.user.name, "year": $.user.age + 1 }')
|
|
49
|
+
template.transform({"user": {"name": "Alice", "age": 30}})
|
|
50
|
+
# -> {'name': 'Alice', 'year': 31}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Installation
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install urban-json
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Unique dépendance d'exécution : `antlr4-python3-runtime`. Le parser généré est
|
|
60
|
+
embarqué (aucun outil ANTLR ni Java requis pour *utiliser* la librairie).
|
|
61
|
+
|
|
62
|
+
## Documentation
|
|
63
|
+
|
|
64
|
+
- **Guide complet avec exemples testables** :
|
|
65
|
+
<https://github.com/gaelgael5/Jslt/blob/main/docs/guide.md>
|
|
66
|
+
([English](https://github.com/gaelgael5/Jslt/blob/main/docs/guide.en.md))
|
|
67
|
+
- **Vue d'ensemble du projet et des plugins** :
|
|
68
|
+
<https://github.com/gaelgael5/Jslt>
|
|
69
|
+
|
|
70
|
+
## API
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from urban_json import JsltTemplate
|
|
74
|
+
|
|
75
|
+
tpl = JsltTemplate.parse(source_str) # compile (JsltSyntaxError si invalide)
|
|
76
|
+
tpl.transform(document) # applique le template à un document
|
|
77
|
+
tpl.debug(document) # trace pas-à-pas (débogage)
|
|
78
|
+
tpl.to_source() # re-sérialise l'AST (ToString)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Extensibilité (ajouter/isoler/découvrir des fonctions, plugins via entry points
|
|
82
|
+
`urban_json.functions`) : voir le guide, section Extensibilité.
|
|
83
|
+
|
|
84
|
+
## Licence
|
|
85
|
+
|
|
86
|
+
Apache-2.0 (comme le projet .NET d'origine).
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# urban-json
|
|
2
|
+
|
|
3
|
+
Portage Python du langage **JSLT — JSON Stylesheet Language Transformations** :
|
|
4
|
+
un langage de **transformation JSON → JSON piloté par template**, initialement
|
|
5
|
+
implémenté en .NET ([Black-Beard-Sdk/jslt](https://github.com/Black-Beard-Sdk/jslt)).
|
|
6
|
+
|
|
7
|
+
C'est le **paquet cœur** (moteur : parser, AST, interpréteur, JSONPath, fonctions
|
|
8
|
+
intégrées, extensibilité). Les capacités d'E-S (CSV, XML, SQL, HTTP, Elasticsearch)
|
|
9
|
+
sont des **plugins séparés** (`urban-json-csv`, `urban-json-xml`, `urban-json-db`, `urban-json-http`,
|
|
10
|
+
`urban-json-elastic`) découverts automatiquement.
|
|
11
|
+
|
|
12
|
+
```python
|
|
13
|
+
from urban_json import JsltTemplate
|
|
14
|
+
|
|
15
|
+
template = JsltTemplate.parse('{ "name": $.user.name, "year": $.user.age + 1 }')
|
|
16
|
+
template.transform({"user": {"name": "Alice", "age": 30}})
|
|
17
|
+
# -> {'name': 'Alice', 'year': 31}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install urban-json
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Unique dépendance d'exécution : `antlr4-python3-runtime`. Le parser généré est
|
|
27
|
+
embarqué (aucun outil ANTLR ni Java requis pour *utiliser* la librairie).
|
|
28
|
+
|
|
29
|
+
## Documentation
|
|
30
|
+
|
|
31
|
+
- **Guide complet avec exemples testables** :
|
|
32
|
+
<https://github.com/gaelgael5/Jslt/blob/main/docs/guide.md>
|
|
33
|
+
([English](https://github.com/gaelgael5/Jslt/blob/main/docs/guide.en.md))
|
|
34
|
+
- **Vue d'ensemble du projet et des plugins** :
|
|
35
|
+
<https://github.com/gaelgael5/Jslt>
|
|
36
|
+
|
|
37
|
+
## API
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from urban_json import JsltTemplate
|
|
41
|
+
|
|
42
|
+
tpl = JsltTemplate.parse(source_str) # compile (JsltSyntaxError si invalide)
|
|
43
|
+
tpl.transform(document) # applique le template à un document
|
|
44
|
+
tpl.debug(document) # trace pas-à-pas (débogage)
|
|
45
|
+
tpl.to_source() # re-sérialise l'AST (ToString)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Extensibilité (ajouter/isoler/découvrir des fonctions, plugins via entry points
|
|
49
|
+
`urban_json.functions`) : voir le guide, section Extensibilité.
|
|
50
|
+
|
|
51
|
+
## Licence
|
|
52
|
+
|
|
53
|
+
Apache-2.0 (comme le projet .NET d'origine).
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "urban-json"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Portage Python du langage JSLT (JSON Stylesheet Language Transformations) — transformation JSON vers JSON pilotée par template."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = "Apache-2.0"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "Gael Beard", email = "gaelgael5@gmail.com" }]
|
|
14
|
+
keywords = ["json", "transform", "template", "jslt", "jsonpath"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 3 - Alpha",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"Operating System :: OS Independent",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.9",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Programming Language :: Python :: 3.13",
|
|
25
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
26
|
+
"Topic :: Text Processing :: Markup",
|
|
27
|
+
"Typing :: Typed",
|
|
28
|
+
]
|
|
29
|
+
dependencies = [
|
|
30
|
+
"antlr4-python3-runtime==4.13.2",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[project.urls]
|
|
34
|
+
Homepage = "https://github.com/gaelgael5/Jslt"
|
|
35
|
+
Repository = "https://github.com/gaelgael5/Jslt"
|
|
36
|
+
Documentation = "https://github.com/gaelgael5/Jslt/blob/main/docs/guide.md"
|
|
37
|
+
Issues = "https://github.com/gaelgael5/Jslt/issues"
|
|
38
|
+
|
|
39
|
+
[project.optional-dependencies]
|
|
40
|
+
dev = [
|
|
41
|
+
"pytest>=7",
|
|
42
|
+
# ruff épinglé : le lint fait partie de la CI et ses règles changent entre
|
|
43
|
+
# versions — on fige pour que CI == local (bump délibéré uniquement).
|
|
44
|
+
"ruff==0.16.8",
|
|
45
|
+
"build>=1",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
[tool.setuptools.dynamic]
|
|
49
|
+
# Version single-source : lue depuis urban_json.__version__ (littéral, pas d'import).
|
|
50
|
+
version = { attr = "urban_json.__version__" }
|
|
51
|
+
|
|
52
|
+
[tool.setuptools.packages.find]
|
|
53
|
+
where = ["src"]
|
|
54
|
+
|
|
55
|
+
[tool.setuptools.package-data]
|
|
56
|
+
# Marqueur de typage (PEP 561) + artefacts ANTLR versionnés.
|
|
57
|
+
urban_json = ["py.typed", "_antlr/*.tokens", "_antlr/*.interp"]
|
|
58
|
+
|
|
59
|
+
[tool.pytest.ini_options]
|
|
60
|
+
testpaths = ["tests"]
|
|
61
|
+
pythonpath = ["src"]
|
|
62
|
+
|
|
63
|
+
[tool.ruff]
|
|
64
|
+
line-length = 100
|
|
65
|
+
src = ["src", "tests"]
|
|
66
|
+
|
|
67
|
+
[tool.ruff.lint]
|
|
68
|
+
# Le code généré par ANTLR n'est pas soumis au lint.
|
|
69
|
+
exclude = ["src/urban_json/_antlr/*"]
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"""jslt — portage Python du langage JSLT (JSON Stylesheet Language Transformations).
|
|
2
|
+
|
|
3
|
+
API publique :
|
|
4
|
+
|
|
5
|
+
>>> from urban_json import JsltTemplate
|
|
6
|
+
>>> template = JsltTemplate.parse('{ "name": "x" }')
|
|
7
|
+
>>> template.transform({})
|
|
8
|
+
{'name': 'x'}
|
|
9
|
+
|
|
10
|
+
État d'avancement du portage (cœur) :
|
|
11
|
+
* Phase 0 — analyse syntaxique (parser ANTLR) [FAIT]
|
|
12
|
+
* Phase 1 — AST + transformation « défaut » [FAIT]
|
|
13
|
+
* Phase 2a — JSONPath simple [FAIT]
|
|
14
|
+
* Phase 2b — variables (déclaration, référence, projection) [FAIT]
|
|
15
|
+
* Phase 3a — boucles ($source / $where) [FAIT]
|
|
16
|
+
* Phase 3b — opérateurs (arithmétique, comparaison, logique) [FAIT]
|
|
17
|
+
* Phase 4a — fonctions (registre) + chaînage -> [FAIT]
|
|
18
|
+
* Phase 4b — casts (#type via convert) [FAIT]
|
|
19
|
+
* Phase 4c — when / switch [FAIT]
|
|
20
|
+
* Phase 5a — JSONPath : wildcard, descente .., slices [FAIT]
|
|
21
|
+
* Phase 5b — JSONPath : filtres ?(...) (comparaisons/logiques)[FAIT]
|
|
22
|
+
|
|
23
|
+
Restent hors périmètre « cœur » (extensibles) : opérateurs ensemblistes de
|
|
24
|
+
filtre (in/nin/subsetof/contains/size/empty) et fonctions de chemin, ainsi que
|
|
25
|
+
les fonctions d'E-S (csv, http, hash, randoms, group, sql).
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from __future__ import annotations
|
|
29
|
+
|
|
30
|
+
from typing import Any
|
|
31
|
+
|
|
32
|
+
from .ast import JsltBase
|
|
33
|
+
from .errors import JsltError, JsltSemanticError, JsltSyntaxError
|
|
34
|
+
from .functions import (
|
|
35
|
+
FunctionInfo,
|
|
36
|
+
FunctionRegistry,
|
|
37
|
+
ParameterInfo,
|
|
38
|
+
default_registry,
|
|
39
|
+
jslt_function,
|
|
40
|
+
load_plugins,
|
|
41
|
+
)
|
|
42
|
+
from .parsing import parse_to_tree
|
|
43
|
+
from .parsing.script_builder_visitor import ScriptBuilderVisitor
|
|
44
|
+
from .runtime import JsltEvaluationVisitor, RuntimeContext, Sources, compile_program
|
|
45
|
+
from .runtime.compiler import Program
|
|
46
|
+
from .runtime.debug import DebugResult, TraceStep, evaluate_with_trace
|
|
47
|
+
from .serialization import to_source
|
|
48
|
+
|
|
49
|
+
__all__ = [
|
|
50
|
+
"DebugResult",
|
|
51
|
+
"FunctionInfo",
|
|
52
|
+
"FunctionRegistry",
|
|
53
|
+
"JsltError",
|
|
54
|
+
"JsltSemanticError",
|
|
55
|
+
"JsltSyntaxError",
|
|
56
|
+
"JsltTemplate",
|
|
57
|
+
"ParameterInfo",
|
|
58
|
+
"Program",
|
|
59
|
+
"TraceStep",
|
|
60
|
+
"default_registry",
|
|
61
|
+
"jslt_function",
|
|
62
|
+
"load_plugins",
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
__version__ = "0.1.0"
|
|
66
|
+
|
|
67
|
+
# Chargement paresseux (une fois) des plugins tiers dans le registre par défaut.
|
|
68
|
+
_default_plugins_loaded = False
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _ensure_default_plugins() -> None:
|
|
72
|
+
global _default_plugins_loaded
|
|
73
|
+
if not _default_plugins_loaded:
|
|
74
|
+
load_plugins(default_registry)
|
|
75
|
+
_default_plugins_loaded = True
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class JsltTemplate:
|
|
79
|
+
"""Un template jslt compilé, prêt à transformer des documents JSON.
|
|
80
|
+
|
|
81
|
+
On n'instancie pas la classe directement : on passe par :meth:`parse`.
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
def __init__(self, ast: JsltBase, source: str) -> None:
|
|
85
|
+
self._ast = ast
|
|
86
|
+
self._source = source
|
|
87
|
+
#: Programme compilé (closures) si :meth:`build` a été appelé, sinon None.
|
|
88
|
+
self._compiled: Program | None = None
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def ast(self) -> JsltBase:
|
|
92
|
+
"""AST jslt construit à partir du template."""
|
|
93
|
+
return self._ast
|
|
94
|
+
|
|
95
|
+
@classmethod
|
|
96
|
+
def parse(cls, template: str) -> JsltTemplate:
|
|
97
|
+
"""Analyse un template jslt et construit son AST.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
template: le template jslt sous forme de chaîne.
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
Un :class:`JsltTemplate` prêt à l'emploi.
|
|
104
|
+
|
|
105
|
+
Raises:
|
|
106
|
+
JsltSyntaxError: si le template est syntaxiquement invalide.
|
|
107
|
+
JsltSemanticError: si le template est sémantiquement invalide.
|
|
108
|
+
"""
|
|
109
|
+
tree = parse_to_tree(template)
|
|
110
|
+
builder = ScriptBuilderVisitor()
|
|
111
|
+
ast = builder.visit(tree)
|
|
112
|
+
return cls(ast, template)
|
|
113
|
+
|
|
114
|
+
def build(self) -> JsltTemplate:
|
|
115
|
+
"""Compile l'AST en closures pour accélérer les transformations en masse.
|
|
116
|
+
|
|
117
|
+
Optionnel. Par défaut, :meth:`transform` utilise l'interpréteur d'AST, qui
|
|
118
|
+
suffit à la grande majorité des cas. Pour des transformations répétées sur
|
|
119
|
+
de gros volumes (imports en masse), ``build()`` pré-compile le template une
|
|
120
|
+
fois : les appels suivants à :meth:`transform` empruntent alors un chemin
|
|
121
|
+
d'exécution plus rapide (sans double-dispatch ni tests de type par nœud),
|
|
122
|
+
pour un résultat **identique**.
|
|
123
|
+
|
|
124
|
+
Idempotent. Renvoie ``self`` pour permettre
|
|
125
|
+
``JsltTemplate.parse(src).build()``.
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
Le template lui-même (compilé).
|
|
129
|
+
"""
|
|
130
|
+
if self._compiled is None:
|
|
131
|
+
self._compiled = compile_program(self._ast)
|
|
132
|
+
return self
|
|
133
|
+
|
|
134
|
+
def transform(
|
|
135
|
+
self, source: Any = None, functions: FunctionRegistry | None = None
|
|
136
|
+
) -> Any:
|
|
137
|
+
"""Applique le template au document source et renvoie le résultat.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
source: le document source (structures Python issues de ``json.loads``).
|
|
141
|
+
functions: registre de fonctions à utiliser. Par défaut, le registre
|
|
142
|
+
global (fonctions intégrées + plugins découverts). Passer un
|
|
143
|
+
registre dédié permet d'isoler/limiter les fonctions disponibles.
|
|
144
|
+
|
|
145
|
+
Returns:
|
|
146
|
+
Le document transformé (structures Python).
|
|
147
|
+
"""
|
|
148
|
+
if functions is None:
|
|
149
|
+
_ensure_default_plugins()
|
|
150
|
+
functions = default_registry
|
|
151
|
+
context = RuntimeContext(Sources(source), functions)
|
|
152
|
+
# Chemin compilé si build() a été appelé (identique, plus rapide en masse) ;
|
|
153
|
+
# sinon l'interpréteur d'AST. Le registre de fonctions reste résolu à
|
|
154
|
+
# l'exécution : un `functions=` par appel est honoré dans les deux cas.
|
|
155
|
+
if self._compiled is not None:
|
|
156
|
+
return self._compiled(context)
|
|
157
|
+
evaluator = JsltEvaluationVisitor(context)
|
|
158
|
+
return self._ast.accept(evaluator)
|
|
159
|
+
|
|
160
|
+
def debug(
|
|
161
|
+
self,
|
|
162
|
+
source: Any = None,
|
|
163
|
+
functions: FunctionRegistry | None = None,
|
|
164
|
+
break_functions: Any = (),
|
|
165
|
+
break_lines: Any = (),
|
|
166
|
+
max_steps: int = 10_000,
|
|
167
|
+
) -> DebugResult:
|
|
168
|
+
"""Évalue le template en collectant une trace pas-à-pas (débogage).
|
|
169
|
+
|
|
170
|
+
Interpréteur oblige, le débogage se fait au **niveau du template** (pas de
|
|
171
|
+
code généré comme en .NET) : chaque nœud évalué produit une étape
|
|
172
|
+
(:class:`~urban_json.runtime.debug.TraceStep`) avec sa localisation, la source
|
|
173
|
+
courante et la valeur produite.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
source: le document source.
|
|
177
|
+
functions: registre de fonctions (défaut : registre global).
|
|
178
|
+
break_functions: noms de fonctions (« méthodes du contexte ») sur
|
|
179
|
+
lesquelles marquer un point d'arrêt.
|
|
180
|
+
break_lines: lignes du template sur lesquelles marquer un point d'arrêt.
|
|
181
|
+
max_steps: nombre maximal d'étapes collectées (garde-fou).
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
Un :class:`~urban_json.runtime.debug.DebugResult` (résultat, étapes, erreur).
|
|
185
|
+
"""
|
|
186
|
+
if functions is None:
|
|
187
|
+
_ensure_default_plugins()
|
|
188
|
+
functions = default_registry
|
|
189
|
+
context = RuntimeContext(Sources(source), functions)
|
|
190
|
+
return evaluate_with_trace(
|
|
191
|
+
self._ast, context, break_functions, break_lines, max_steps
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
def to_source(self) -> str:
|
|
195
|
+
"""Re-sérialise l'AST du template en texte source ré-analysable.
|
|
196
|
+
|
|
197
|
+
Analogue du ``ToString`` du .NET : le résultat est un template valide,
|
|
198
|
+
équivalent en comportement à l'original (pas forcément identique au
|
|
199
|
+
caractère près — voir :mod:`urban_json.serialization`).
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
Le template jslt sérialisé depuis l'AST.
|
|
203
|
+
"""
|
|
204
|
+
return to_source(self._ast)
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
token literal names:
|
|
2
|
+
null
|
|
3
|
+
'.'
|
|
4
|
+
'*'
|
|
5
|
+
'@'
|
|
6
|
+
':'
|
|
7
|
+
'#'
|
|
8
|
+
'..'
|
|
9
|
+
'#uri'
|
|
10
|
+
'#time'
|
|
11
|
+
'#datetime'
|
|
12
|
+
'#string'
|
|
13
|
+
'#boolean'
|
|
14
|
+
'#uuid'
|
|
15
|
+
'#integer'
|
|
16
|
+
'#decimal'
|
|
17
|
+
'in'
|
|
18
|
+
'nin'
|
|
19
|
+
'subsetof'
|
|
20
|
+
'contains'
|
|
21
|
+
'size'
|
|
22
|
+
'empty'
|
|
23
|
+
'true'
|
|
24
|
+
'false'
|
|
25
|
+
'default'
|
|
26
|
+
'=='
|
|
27
|
+
'!='
|
|
28
|
+
'>'
|
|
29
|
+
'<'
|
|
30
|
+
'<='
|
|
31
|
+
'>='
|
|
32
|
+
'!'
|
|
33
|
+
'+'
|
|
34
|
+
'-'
|
|
35
|
+
'/'
|
|
36
|
+
'%'
|
|
37
|
+
'^'
|
|
38
|
+
'&'
|
|
39
|
+
'|'
|
|
40
|
+
'&&'
|
|
41
|
+
'||'
|
|
42
|
+
'??'
|
|
43
|
+
'->'
|
|
44
|
+
'null'
|
|
45
|
+
'{'
|
|
46
|
+
'}'
|
|
47
|
+
'['
|
|
48
|
+
']'
|
|
49
|
+
','
|
|
50
|
+
'('
|
|
51
|
+
')'
|
|
52
|
+
'$'
|
|
53
|
+
'?'
|
|
54
|
+
null
|
|
55
|
+
null
|
|
56
|
+
'\''
|
|
57
|
+
null
|
|
58
|
+
null
|
|
59
|
+
null
|
|
60
|
+
null
|
|
61
|
+
null
|
|
62
|
+
null
|
|
63
|
+
null
|
|
64
|
+
null
|
|
65
|
+
null
|
|
66
|
+
|
|
67
|
+
token symbolic names:
|
|
68
|
+
null
|
|
69
|
+
SUBSCRIPT
|
|
70
|
+
WILDCARD_SUBSCRIPT
|
|
71
|
+
CURRENT_VALUE
|
|
72
|
+
COLON
|
|
73
|
+
SHARP
|
|
74
|
+
RECURSIVE_DESCENT
|
|
75
|
+
URI_TYPE
|
|
76
|
+
TIME_TYPE
|
|
77
|
+
DATETIME_TYPE
|
|
78
|
+
STRING_TYPE
|
|
79
|
+
BOOLEAN_TYPE
|
|
80
|
+
GUID_TYPE
|
|
81
|
+
INTEGER_TYPE
|
|
82
|
+
DECIMAL_TYPE
|
|
83
|
+
IN
|
|
84
|
+
NIN
|
|
85
|
+
SUBSETOF
|
|
86
|
+
CONTAINS
|
|
87
|
+
SIZE
|
|
88
|
+
EMPTY
|
|
89
|
+
TRUE
|
|
90
|
+
FALSE
|
|
91
|
+
DEFAULT
|
|
92
|
+
EQ
|
|
93
|
+
NE
|
|
94
|
+
GT
|
|
95
|
+
LT
|
|
96
|
+
LE
|
|
97
|
+
GE
|
|
98
|
+
NT
|
|
99
|
+
PLUS
|
|
100
|
+
MINUS
|
|
101
|
+
DIVID
|
|
102
|
+
MODULO
|
|
103
|
+
POWER
|
|
104
|
+
AND
|
|
105
|
+
OR
|
|
106
|
+
AND_EXCLUSIVE
|
|
107
|
+
OR_EXCLUSIVE
|
|
108
|
+
COALESCE
|
|
109
|
+
CHAIN
|
|
110
|
+
NULL
|
|
111
|
+
BRACE_LEFT
|
|
112
|
+
BRACE_RIGHT
|
|
113
|
+
BRACKET_LEFT
|
|
114
|
+
BRACKET_RIGHT
|
|
115
|
+
COMMA
|
|
116
|
+
PAREN_LEFT
|
|
117
|
+
PAREN_RIGHT
|
|
118
|
+
DOLLAR
|
|
119
|
+
QUESTION
|
|
120
|
+
STRING
|
|
121
|
+
MULTI_LINE_COMMENT
|
|
122
|
+
SINGLE_QUOTE_CODE_STRING
|
|
123
|
+
NUMBER
|
|
124
|
+
SIGNED_NUMBER
|
|
125
|
+
INT
|
|
126
|
+
SIGNED_INT
|
|
127
|
+
WS
|
|
128
|
+
ID
|
|
129
|
+
IDQUOTED
|
|
130
|
+
VARIABLE_NAME
|
|
131
|
+
IDLOWCASE
|
|
132
|
+
|
|
133
|
+
rule names:
|
|
134
|
+
SUBSCRIPT
|
|
135
|
+
WILDCARD_SUBSCRIPT
|
|
136
|
+
CURRENT_VALUE
|
|
137
|
+
COLON
|
|
138
|
+
SHARP
|
|
139
|
+
RECURSIVE_DESCENT
|
|
140
|
+
URI_TYPE
|
|
141
|
+
TIME_TYPE
|
|
142
|
+
DATETIME_TYPE
|
|
143
|
+
STRING_TYPE
|
|
144
|
+
BOOLEAN_TYPE
|
|
145
|
+
GUID_TYPE
|
|
146
|
+
INTEGER_TYPE
|
|
147
|
+
DECIMAL_TYPE
|
|
148
|
+
IN
|
|
149
|
+
NIN
|
|
150
|
+
SUBSETOF
|
|
151
|
+
CONTAINS
|
|
152
|
+
SIZE
|
|
153
|
+
EMPTY
|
|
154
|
+
TRUE
|
|
155
|
+
FALSE
|
|
156
|
+
DEFAULT
|
|
157
|
+
EQ
|
|
158
|
+
NE
|
|
159
|
+
GT
|
|
160
|
+
LT
|
|
161
|
+
LE
|
|
162
|
+
GE
|
|
163
|
+
NT
|
|
164
|
+
PLUS
|
|
165
|
+
MINUS
|
|
166
|
+
DIVID
|
|
167
|
+
MODULO
|
|
168
|
+
POWER
|
|
169
|
+
AND
|
|
170
|
+
OR
|
|
171
|
+
AND_EXCLUSIVE
|
|
172
|
+
OR_EXCLUSIVE
|
|
173
|
+
COALESCE
|
|
174
|
+
CHAIN
|
|
175
|
+
NULL
|
|
176
|
+
BRACE_LEFT
|
|
177
|
+
BRACE_RIGHT
|
|
178
|
+
BRACKET_LEFT
|
|
179
|
+
BRACKET_RIGHT
|
|
180
|
+
COMMA
|
|
181
|
+
PAREN_LEFT
|
|
182
|
+
PAREN_RIGHT
|
|
183
|
+
DOLLAR
|
|
184
|
+
QUESTION
|
|
185
|
+
STRING
|
|
186
|
+
MULTI_LINE_COMMENT
|
|
187
|
+
SINGLE_QUOTE_CODE_STRING
|
|
188
|
+
ESC
|
|
189
|
+
UNICODE
|
|
190
|
+
HEX
|
|
191
|
+
SAFECODEPOINT
|
|
192
|
+
NUMBER
|
|
193
|
+
SIGNED_NUMBER
|
|
194
|
+
INT
|
|
195
|
+
SIGNED_INT
|
|
196
|
+
EXP
|
|
197
|
+
WS
|
|
198
|
+
ID
|
|
199
|
+
IDQUOTED
|
|
200
|
+
VARIABLE_NAME
|
|
201
|
+
IDLOWCASE
|
|
202
|
+
|
|
203
|
+
channel names:
|
|
204
|
+
DEFAULT_TOKEN_CHANNEL
|
|
205
|
+
HIDDEN
|
|
206
|
+
|
|
207
|
+
mode names:
|
|
208
|
+
DEFAULT_MODE
|
|
209
|
+
|
|
210
|
+
atn:
|
|
211
|
+
[4, 0, 63, 465, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 30, 1, 30, 1, 31, 1, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 34, 1, 34, 1, 35, 1, 35, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 43, 1, 43, 1, 44, 1, 44, 1, 45, 1, 45, 1, 46, 1, 46, 1, 47, 1, 47, 1, 48, 1, 48, 1, 49, 1, 49, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 5, 51, 338, 8, 51, 10, 51, 12, 51, 341, 9, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 52, 5, 52, 349, 8, 52, 10, 52, 12, 52, 352, 9, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 3, 54, 364, 8, 54, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 57, 1, 57, 1, 58, 1, 58, 1, 58, 4, 58, 379, 8, 58, 11, 58, 12, 58, 380, 3, 58, 383, 8, 58, 1, 58, 3, 58, 386, 8, 58, 1, 59, 3, 59, 389, 8, 59, 1, 59, 1, 59, 1, 59, 4, 59, 394, 8, 59, 11, 59, 12, 59, 395, 3, 59, 398, 8, 59, 1, 59, 3, 59, 401, 8, 59, 1, 60, 1, 60, 1, 60, 5, 60, 406, 8, 60, 10, 60, 12, 60, 409, 9, 60, 3, 60, 411, 8, 60, 1, 61, 3, 61, 414, 8, 61, 1, 61, 1, 61, 1, 61, 5, 61, 419, 8, 61, 10, 61, 12, 61, 422, 9, 61, 3, 61, 424, 8, 61, 1, 62, 1, 62, 3, 62, 428, 8, 62, 1, 62, 1, 62, 1, 63, 4, 63, 433, 8, 63, 11, 63, 12, 63, 434, 1, 63, 1, 63, 1, 64, 1, 64, 5, 64, 441, 8, 64, 10, 64, 12, 64, 444, 9, 64, 1, 65, 1, 65, 1, 65, 1, 65, 1, 66, 1, 66, 5, 66, 452, 8, 66, 10, 66, 12, 66, 455, 9, 66, 1, 66, 1, 66, 1, 67, 1, 67, 5, 67, 461, 8, 67, 10, 67, 12, 67, 464, 9, 67, 1, 350, 0, 68, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 37, 75, 38, 77, 39, 79, 40, 81, 41, 83, 42, 85, 43, 87, 44, 89, 45, 91, 46, 93, 47, 95, 48, 97, 49, 99, 50, 101, 51, 103, 52, 105, 53, 107, 54, 109, 0, 111, 0, 113, 0, 115, 0, 117, 55, 119, 56, 121, 57, 123, 58, 125, 0, 127, 59, 129, 60, 131, 61, 133, 62, 135, 63, 1, 0, 12, 8, 0, 34, 34, 47, 47, 92, 92, 98, 98, 102, 102, 110, 110, 114, 114, 116, 116, 3, 0, 48, 57, 65, 70, 97, 102, 3, 0, 0, 31, 34, 34, 92, 92, 2, 0, 43, 43, 45, 45, 1, 0, 49, 57, 1, 0, 48, 57, 2, 0, 69, 69, 101, 101, 3, 0, 9, 10, 13, 13, 32, 32, 3, 0, 65, 90, 95, 95, 97, 122, 4, 0, 48, 57, 65, 90, 95, 95, 97, 122, 2, 0, 95, 95, 97, 122, 3, 0, 48, 57, 95, 95, 97, 122, 480, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, 1, 0, 0, 0, 0, 105, 1, 0, 0, 0, 0, 107, 1, 0, 0, 0, 0, 117, 1, 0, 0, 0, 0, 119, 1, 0, 0, 0, 0, 121, 1, 0, 0, 0, 0, 123, 1, 0, 0, 0, 0, 127, 1, 0, 0, 0, 0, 129, 1, 0, 0, 0, 0, 131, 1, 0, 0, 0, 0, 133, 1, 0, 0, 0, 0, 135, 1, 0, 0, 0, 1, 137, 1, 0, 0, 0, 3, 139, 1, 0, 0, 0, 5, 141, 1, 0, 0, 0, 7, 143, 1, 0, 0, 0, 9, 145, 1, 0, 0, 0, 11, 147, 1, 0, 0, 0, 13, 150, 1, 0, 0, 0, 15, 155, 1, 0, 0, 0, 17, 161, 1, 0, 0, 0, 19, 171, 1, 0, 0, 0, 21, 179, 1, 0, 0, 0, 23, 188, 1, 0, 0, 0, 25, 194, 1, 0, 0, 0, 27, 203, 1, 0, 0, 0, 29, 212, 1, 0, 0, 0, 31, 215, 1, 0, 0, 0, 33, 219, 1, 0, 0, 0, 35, 228, 1, 0, 0, 0, 37, 237, 1, 0, 0, 0, 39, 242, 1, 0, 0, 0, 41, 248, 1, 0, 0, 0, 43, 253, 1, 0, 0, 0, 45, 259, 1, 0, 0, 0, 47, 267, 1, 0, 0, 0, 49, 270, 1, 0, 0, 0, 51, 273, 1, 0, 0, 0, 53, 275, 1, 0, 0, 0, 55, 277, 1, 0, 0, 0, 57, 280, 1, 0, 0, 0, 59, 283, 1, 0, 0, 0, 61, 285, 1, 0, 0, 0, 63, 287, 1, 0, 0, 0, 65, 289, 1, 0, 0, 0, 67, 291, 1, 0, 0, 0, 69, 293, 1, 0, 0, 0, 71, 295, 1, 0, 0, 0, 73, 297, 1, 0, 0, 0, 75, 299, 1, 0, 0, 0, 77, 302, 1, 0, 0, 0, 79, 305, 1, 0, 0, 0, 81, 308, 1, 0, 0, 0, 83, 311, 1, 0, 0, 0, 85, 316, 1, 0, 0, 0, 87, 318, 1, 0, 0, 0, 89, 320, 1, 0, 0, 0, 91, 322, 1, 0, 0, 0, 93, 324, 1, 0, 0, 0, 95, 326, 1, 0, 0, 0, 97, 328, 1, 0, 0, 0, 99, 330, 1, 0, 0, 0, 101, 332, 1, 0, 0, 0, 103, 334, 1, 0, 0, 0, 105, 344, 1, 0, 0, 0, 107, 358, 1, 0, 0, 0, 109, 360, 1, 0, 0, 0, 111, 365, 1, 0, 0, 0, 113, 371, 1, 0, 0, 0, 115, 373, 1, 0, 0, 0, 117, 375, 1, 0, 0, 0, 119, 388, 1, 0, 0, 0, 121, 410, 1, 0, 0, 0, 123, 413, 1, 0, 0, 0, 125, 425, 1, 0, 0, 0, 127, 432, 1, 0, 0, 0, 129, 438, 1, 0, 0, 0, 131, 445, 1, 0, 0, 0, 133, 449, 1, 0, 0, 0, 135, 458, 1, 0, 0, 0, 137, 138, 5, 46, 0, 0, 138, 2, 1, 0, 0, 0, 139, 140, 5, 42, 0, 0, 140, 4, 1, 0, 0, 0, 141, 142, 5, 64, 0, 0, 142, 6, 1, 0, 0, 0, 143, 144, 5, 58, 0, 0, 144, 8, 1, 0, 0, 0, 145, 146, 5, 35, 0, 0, 146, 10, 1, 0, 0, 0, 147, 148, 5, 46, 0, 0, 148, 149, 5, 46, 0, 0, 149, 12, 1, 0, 0, 0, 150, 151, 5, 35, 0, 0, 151, 152, 5, 117, 0, 0, 152, 153, 5, 114, 0, 0, 153, 154, 5, 105, 0, 0, 154, 14, 1, 0, 0, 0, 155, 156, 5, 35, 0, 0, 156, 157, 5, 116, 0, 0, 157, 158, 5, 105, 0, 0, 158, 159, 5, 109, 0, 0, 159, 160, 5, 101, 0, 0, 160, 16, 1, 0, 0, 0, 161, 162, 5, 35, 0, 0, 162, 163, 5, 100, 0, 0, 163, 164, 5, 97, 0, 0, 164, 165, 5, 116, 0, 0, 165, 166, 5, 101, 0, 0, 166, 167, 5, 116, 0, 0, 167, 168, 5, 105, 0, 0, 168, 169, 5, 109, 0, 0, 169, 170, 5, 101, 0, 0, 170, 18, 1, 0, 0, 0, 171, 172, 5, 35, 0, 0, 172, 173, 5, 115, 0, 0, 173, 174, 5, 116, 0, 0, 174, 175, 5, 114, 0, 0, 175, 176, 5, 105, 0, 0, 176, 177, 5, 110, 0, 0, 177, 178, 5, 103, 0, 0, 178, 20, 1, 0, 0, 0, 179, 180, 5, 35, 0, 0, 180, 181, 5, 98, 0, 0, 181, 182, 5, 111, 0, 0, 182, 183, 5, 111, 0, 0, 183, 184, 5, 108, 0, 0, 184, 185, 5, 101, 0, 0, 185, 186, 5, 97, 0, 0, 186, 187, 5, 110, 0, 0, 187, 22, 1, 0, 0, 0, 188, 189, 5, 35, 0, 0, 189, 190, 5, 117, 0, 0, 190, 191, 5, 117, 0, 0, 191, 192, 5, 105, 0, 0, 192, 193, 5, 100, 0, 0, 193, 24, 1, 0, 0, 0, 194, 195, 5, 35, 0, 0, 195, 196, 5, 105, 0, 0, 196, 197, 5, 110, 0, 0, 197, 198, 5, 116, 0, 0, 198, 199, 5, 101, 0, 0, 199, 200, 5, 103, 0, 0, 200, 201, 5, 101, 0, 0, 201, 202, 5, 114, 0, 0, 202, 26, 1, 0, 0, 0, 203, 204, 5, 35, 0, 0, 204, 205, 5, 100, 0, 0, 205, 206, 5, 101, 0, 0, 206, 207, 5, 99, 0, 0, 207, 208, 5, 105, 0, 0, 208, 209, 5, 109, 0, 0, 209, 210, 5, 97, 0, 0, 210, 211, 5, 108, 0, 0, 211, 28, 1, 0, 0, 0, 212, 213, 5, 105, 0, 0, 213, 214, 5, 110, 0, 0, 214, 30, 1, 0, 0, 0, 215, 216, 5, 110, 0, 0, 216, 217, 5, 105, 0, 0, 217, 218, 5, 110, 0, 0, 218, 32, 1, 0, 0, 0, 219, 220, 5, 115, 0, 0, 220, 221, 5, 117, 0, 0, 221, 222, 5, 98, 0, 0, 222, 223, 5, 115, 0, 0, 223, 224, 5, 101, 0, 0, 224, 225, 5, 116, 0, 0, 225, 226, 5, 111, 0, 0, 226, 227, 5, 102, 0, 0, 227, 34, 1, 0, 0, 0, 228, 229, 5, 99, 0, 0, 229, 230, 5, 111, 0, 0, 230, 231, 5, 110, 0, 0, 231, 232, 5, 116, 0, 0, 232, 233, 5, 97, 0, 0, 233, 234, 5, 105, 0, 0, 234, 235, 5, 110, 0, 0, 235, 236, 5, 115, 0, 0, 236, 36, 1, 0, 0, 0, 237, 238, 5, 115, 0, 0, 238, 239, 5, 105, 0, 0, 239, 240, 5, 122, 0, 0, 240, 241, 5, 101, 0, 0, 241, 38, 1, 0, 0, 0, 242, 243, 5, 101, 0, 0, 243, 244, 5, 109, 0, 0, 244, 245, 5, 112, 0, 0, 245, 246, 5, 116, 0, 0, 246, 247, 5, 121, 0, 0, 247, 40, 1, 0, 0, 0, 248, 249, 5, 116, 0, 0, 249, 250, 5, 114, 0, 0, 250, 251, 5, 117, 0, 0, 251, 252, 5, 101, 0, 0, 252, 42, 1, 0, 0, 0, 253, 254, 5, 102, 0, 0, 254, 255, 5, 97, 0, 0, 255, 256, 5, 108, 0, 0, 256, 257, 5, 115, 0, 0, 257, 258, 5, 101, 0, 0, 258, 44, 1, 0, 0, 0, 259, 260, 5, 100, 0, 0, 260, 261, 5, 101, 0, 0, 261, 262, 5, 102, 0, 0, 262, 263, 5, 97, 0, 0, 263, 264, 5, 117, 0, 0, 264, 265, 5, 108, 0, 0, 265, 266, 5, 116, 0, 0, 266, 46, 1, 0, 0, 0, 267, 268, 5, 61, 0, 0, 268, 269, 5, 61, 0, 0, 269, 48, 1, 0, 0, 0, 270, 271, 5, 33, 0, 0, 271, 272, 5, 61, 0, 0, 272, 50, 1, 0, 0, 0, 273, 274, 5, 62, 0, 0, 274, 52, 1, 0, 0, 0, 275, 276, 5, 60, 0, 0, 276, 54, 1, 0, 0, 0, 277, 278, 5, 60, 0, 0, 278, 279, 5, 61, 0, 0, 279, 56, 1, 0, 0, 0, 280, 281, 5, 62, 0, 0, 281, 282, 5, 61, 0, 0, 282, 58, 1, 0, 0, 0, 283, 284, 5, 33, 0, 0, 284, 60, 1, 0, 0, 0, 285, 286, 5, 43, 0, 0, 286, 62, 1, 0, 0, 0, 287, 288, 5, 45, 0, 0, 288, 64, 1, 0, 0, 0, 289, 290, 5, 47, 0, 0, 290, 66, 1, 0, 0, 0, 291, 292, 5, 37, 0, 0, 292, 68, 1, 0, 0, 0, 293, 294, 5, 94, 0, 0, 294, 70, 1, 0, 0, 0, 295, 296, 5, 38, 0, 0, 296, 72, 1, 0, 0, 0, 297, 298, 5, 124, 0, 0, 298, 74, 1, 0, 0, 0, 299, 300, 5, 38, 0, 0, 300, 301, 5, 38, 0, 0, 301, 76, 1, 0, 0, 0, 302, 303, 5, 124, 0, 0, 303, 304, 5, 124, 0, 0, 304, 78, 1, 0, 0, 0, 305, 306, 5, 63, 0, 0, 306, 307, 5, 63, 0, 0, 307, 80, 1, 0, 0, 0, 308, 309, 5, 45, 0, 0, 309, 310, 5, 62, 0, 0, 310, 82, 1, 0, 0, 0, 311, 312, 5, 110, 0, 0, 312, 313, 5, 117, 0, 0, 313, 314, 5, 108, 0, 0, 314, 315, 5, 108, 0, 0, 315, 84, 1, 0, 0, 0, 316, 317, 5, 123, 0, 0, 317, 86, 1, 0, 0, 0, 318, 319, 5, 125, 0, 0, 319, 88, 1, 0, 0, 0, 320, 321, 5, 91, 0, 0, 321, 90, 1, 0, 0, 0, 322, 323, 5, 93, 0, 0, 323, 92, 1, 0, 0, 0, 324, 325, 5, 44, 0, 0, 325, 94, 1, 0, 0, 0, 326, 327, 5, 40, 0, 0, 327, 96, 1, 0, 0, 0, 328, 329, 5, 41, 0, 0, 329, 98, 1, 0, 0, 0, 330, 331, 5, 36, 0, 0, 331, 100, 1, 0, 0, 0, 332, 333, 5, 63, 0, 0, 333, 102, 1, 0, 0, 0, 334, 339, 5, 34, 0, 0, 335, 338, 3, 109, 54, 0, 336, 338, 3, 115, 57, 0, 337, 335, 1, 0, 0, 0, 337, 336, 1, 0, 0, 0, 338, 341, 1, 0, 0, 0, 339, 337, 1, 0, 0, 0, 339, 340, 1, 0, 0, 0, 340, 342, 1, 0, 0, 0, 341, 339, 1, 0, 0, 0, 342, 343, 5, 34, 0, 0, 343, 104, 1, 0, 0, 0, 344, 345, 5, 47, 0, 0, 345, 346, 5, 42, 0, 0, 346, 350, 1, 0, 0, 0, 347, 349, 9, 0, 0, 0, 348, 347, 1, 0, 0, 0, 349, 352, 1, 0, 0, 0, 350, 351, 1, 0, 0, 0, 350, 348, 1, 0, 0, 0, 351, 353, 1, 0, 0, 0, 352, 350, 1, 0, 0, 0, 353, 354, 5, 42, 0, 0, 354, 355, 5, 47, 0, 0, 355, 356, 1, 0, 0, 0, 356, 357, 6, 52, 0, 0, 357, 106, 1, 0, 0, 0, 358, 359, 5, 39, 0, 0, 359, 108, 1, 0, 0, 0, 360, 363, 5, 92, 0, 0, 361, 364, 7, 0, 0, 0, 362, 364, 3, 111, 55, 0, 363, 361, 1, 0, 0, 0, 363, 362, 1, 0, 0, 0, 364, 110, 1, 0, 0, 0, 365, 366, 5, 117, 0, 0, 366, 367, 3, 113, 56, 0, 367, 368, 3, 113, 56, 0, 368, 369, 3, 113, 56, 0, 369, 370, 3, 113, 56, 0, 370, 112, 1, 0, 0, 0, 371, 372, 7, 1, 0, 0, 372, 114, 1, 0, 0, 0, 373, 374, 8, 2, 0, 0, 374, 116, 1, 0, 0, 0, 375, 382, 3, 121, 60, 0, 376, 378, 5, 46, 0, 0, 377, 379, 3, 121, 60, 0, 378, 377, 1, 0, 0, 0, 379, 380, 1, 0, 0, 0, 380, 378, 1, 0, 0, 0, 380, 381, 1, 0, 0, 0, 381, 383, 1, 0, 0, 0, 382, 376, 1, 0, 0, 0, 382, 383, 1, 0, 0, 0, 383, 385, 1, 0, 0, 0, 384, 386, 3, 125, 62, 0, 385, 384, 1, 0, 0, 0, 385, 386, 1, 0, 0, 0, 386, 118, 1, 0, 0, 0, 387, 389, 7, 3, 0, 0, 388, 387, 1, 0, 0, 0, 388, 389, 1, 0, 0, 0, 389, 390, 1, 0, 0, 0, 390, 397, 3, 121, 60, 0, 391, 393, 5, 46, 0, 0, 392, 394, 3, 121, 60, 0, 393, 392, 1, 0, 0, 0, 394, 395, 1, 0, 0, 0, 395, 393, 1, 0, 0, 0, 395, 396, 1, 0, 0, 0, 396, 398, 1, 0, 0, 0, 397, 391, 1, 0, 0, 0, 397, 398, 1, 0, 0, 0, 398, 400, 1, 0, 0, 0, 399, 401, 3, 125, 62, 0, 400, 399, 1, 0, 0, 0, 400, 401, 1, 0, 0, 0, 401, 120, 1, 0, 0, 0, 402, 411, 5, 48, 0, 0, 403, 407, 7, 4, 0, 0, 404, 406, 7, 5, 0, 0, 405, 404, 1, 0, 0, 0, 406, 409, 1, 0, 0, 0, 407, 405, 1, 0, 0, 0, 407, 408, 1, 0, 0, 0, 408, 411, 1, 0, 0, 0, 409, 407, 1, 0, 0, 0, 410, 402, 1, 0, 0, 0, 410, 403, 1, 0, 0, 0, 411, 122, 1, 0, 0, 0, 412, 414, 7, 3, 0, 0, 413, 412, 1, 0, 0, 0, 413, 414, 1, 0, 0, 0, 414, 423, 1, 0, 0, 0, 415, 424, 5, 48, 0, 0, 416, 420, 7, 4, 0, 0, 417, 419, 7, 5, 0, 0, 418, 417, 1, 0, 0, 0, 419, 422, 1, 0, 0, 0, 420, 418, 1, 0, 0, 0, 420, 421, 1, 0, 0, 0, 421, 424, 1, 0, 0, 0, 422, 420, 1, 0, 0, 0, 423, 415, 1, 0, 0, 0, 423, 416, 1, 0, 0, 0, 424, 124, 1, 0, 0, 0, 425, 427, 7, 6, 0, 0, 426, 428, 7, 3, 0, 0, 427, 426, 1, 0, 0, 0, 427, 428, 1, 0, 0, 0, 428, 429, 1, 0, 0, 0, 429, 430, 3, 121, 60, 0, 430, 126, 1, 0, 0, 0, 431, 433, 7, 7, 0, 0, 432, 431, 1, 0, 0, 0, 433, 434, 1, 0, 0, 0, 434, 432, 1, 0, 0, 0, 434, 435, 1, 0, 0, 0, 435, 436, 1, 0, 0, 0, 436, 437, 6, 63, 0, 0, 437, 128, 1, 0, 0, 0, 438, 442, 7, 8, 0, 0, 439, 441, 7, 9, 0, 0, 440, 439, 1, 0, 0, 0, 441, 444, 1, 0, 0, 0, 442, 440, 1, 0, 0, 0, 442, 443, 1, 0, 0, 0, 443, 130, 1, 0, 0, 0, 444, 442, 1, 0, 0, 0, 445, 446, 5, 39, 0, 0, 446, 447, 3, 129, 64, 0, 447, 448, 5, 39, 0, 0, 448, 132, 1, 0, 0, 0, 449, 453, 7, 8, 0, 0, 450, 452, 7, 9, 0, 0, 451, 450, 1, 0, 0, 0, 452, 455, 1, 0, 0, 0, 453, 451, 1, 0, 0, 0, 453, 454, 1, 0, 0, 0, 454, 456, 1, 0, 0, 0, 455, 453, 1, 0, 0, 0, 456, 457, 3, 7, 3, 0, 457, 134, 1, 0, 0, 0, 458, 462, 7, 10, 0, 0, 459, 461, 7, 11, 0, 0, 460, 459, 1, 0, 0, 0, 461, 464, 1, 0, 0, 0, 462, 460, 1, 0, 0, 0, 462, 463, 1, 0, 0, 0, 463, 136, 1, 0, 0, 0, 464, 462, 1, 0, 0, 0, 22, 0, 337, 339, 350, 363, 380, 382, 385, 388, 395, 397, 400, 407, 410, 413, 420, 423, 427, 434, 442, 453, 462, 1, 6, 0, 0]
|