snail-lang 0.7.1__tar.gz → 0.7.2__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.
- {snail_lang-0.7.1 → snail_lang-0.7.2}/Cargo.lock +5 -5
- {snail_lang-0.7.1 → snail_lang-0.7.2}/PKG-INFO +12 -1
- {snail_lang-0.7.1 → snail_lang-0.7.2}/README.md +11 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-ast/Cargo.toml +1 -1
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-error/Cargo.toml +1 -1
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-parser/Cargo.toml +1 -1
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-parser/src/snail.pest +2 -2
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-parser/tests/syntax_expressions.rs +9 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-python/Cargo.toml +1 -1
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-python/src/lower/constants.rs +3 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/pyproject.toml +1 -1
- {snail_lang-0.7.1 → snail_lang-0.7.2}/python/snail/cli.py +37 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/python/snail/runtime/__init__.py +11 -0
- snail_lang-0.7.2/python/snail/runtime/env.py +26 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/Cargo.toml +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/LICENSE +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-ast/README.md +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-ast/src/ast.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-ast/src/awk.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-ast/src/lib.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-error/README.md +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-error/src/lib.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-parser/README.md +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-parser/src/awk.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-parser/src/expr.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-parser/src/lib.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-parser/src/literal.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-parser/src/stmt.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-parser/src/string.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-parser/src/util.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-parser/tests/common.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-parser/tests/errors.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-parser/tests/parser.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-parser/tests/statements.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-parser/tests/syntax_strings.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-python/build.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-python/src/compiler.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-python/src/lib.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-python/src/linecache.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-python/src/lower/awk.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-python/src/lower/desugar.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-python/src/lower/expr.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-python/src/lower/helpers.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-python/src/lower/map.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-python/src/lower/mod.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-python/src/lower/operators.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-python/src/lower/program.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-python/src/lower/py_ast.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-python/src/lower/stmt.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-python/src/lower/validate.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/crates/snail-python/src/profiling.rs +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/python/snail/__init__.py +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/python/snail/runtime/augmented.py +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/python/snail/runtime/compact_try.py +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/python/snail/runtime/lazy_file.py +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/python/snail/runtime/lazy_text.py +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/python/snail/runtime/regex.py +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/python/snail/runtime/structured_accessor.py +0 -0
- {snail_lang-0.7.1 → snail_lang-0.7.2}/python/snail/runtime/subprocess.py +0 -0
|
@@ -312,25 +312,25 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
|
|
312
312
|
|
|
313
313
|
[[package]]
|
|
314
314
|
name = "snail-ast"
|
|
315
|
-
version = "0.7.
|
|
315
|
+
version = "0.7.2"
|
|
316
316
|
|
|
317
317
|
[[package]]
|
|
318
318
|
name = "snail-error"
|
|
319
|
-
version = "0.7.
|
|
319
|
+
version = "0.7.2"
|
|
320
320
|
dependencies = [
|
|
321
321
|
"snail-ast",
|
|
322
322
|
]
|
|
323
323
|
|
|
324
324
|
[[package]]
|
|
325
325
|
name = "snail-lower"
|
|
326
|
-
version = "0.7.
|
|
326
|
+
version = "0.7.2"
|
|
327
327
|
dependencies = [
|
|
328
328
|
"snail-python",
|
|
329
329
|
]
|
|
330
330
|
|
|
331
331
|
[[package]]
|
|
332
332
|
name = "snail-parser"
|
|
333
|
-
version = "0.7.
|
|
333
|
+
version = "0.7.2"
|
|
334
334
|
dependencies = [
|
|
335
335
|
"pest",
|
|
336
336
|
"pest_derive",
|
|
@@ -340,7 +340,7 @@ dependencies = [
|
|
|
340
340
|
|
|
341
341
|
[[package]]
|
|
342
342
|
name = "snail-python"
|
|
343
|
-
version = "0.7.
|
|
343
|
+
version = "0.7.2"
|
|
344
344
|
dependencies = [
|
|
345
345
|
"pyo3",
|
|
346
346
|
"snail-ast",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: snail-lang
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.2
|
|
4
4
|
Requires-Dist: astunparse>=1.6.3 ; python_full_version < '3.9'
|
|
5
5
|
Requires-Dist: jmespath>=1.0.1
|
|
6
6
|
Requires-Dist: maturin>=1.5 ; extra == 'dev'
|
|
@@ -76,6 +76,7 @@ END { print("done") }
|
|
|
76
76
|
| `$p` | Current file path |
|
|
77
77
|
| `$m` | Last regex match object |
|
|
78
78
|
|
|
79
|
+
|
|
79
80
|
Begin/end blocks can live in the source file (`BEGIN { ... }` / `END { ... }`) or be supplied
|
|
80
81
|
via CLI flags (`-b`/`--begin`, `-e`/`--end`) for setup and teardown. CLI BEGIN blocks run
|
|
81
82
|
before in-file BEGIN blocks; CLI END blocks run after in-file END blocks.
|
|
@@ -113,6 +114,13 @@ BEGIN/END blocks are regular Snail blocks, so awk/map-only `$` variables are not
|
|
|
113
114
|
snail --map --begin "print('start')" --end "print('done')" "print($src)" *.txt
|
|
114
115
|
```
|
|
115
116
|
|
|
117
|
+
### Built-in Variables (All Modes)
|
|
118
|
+
|
|
119
|
+
| Variable | Description |
|
|
120
|
+
|----------|-------------|
|
|
121
|
+
| `$e` | Exception object in `expr:fallback?` |
|
|
122
|
+
| `$env` | Environment map (wrapper around `os.environ`) |
|
|
123
|
+
|
|
116
124
|
### Compact Error Handling
|
|
117
125
|
|
|
118
126
|
The `?` operator makes error handling terse yet expressive:
|
|
@@ -263,6 +271,9 @@ snail 'if let [_, user, domain] = "user@example.com" in /^[\w.]+@([\w.]+)$/ { pr
|
|
|
263
271
|
|
|
264
272
|
# Awk mode: print line numbers for matches
|
|
265
273
|
rg -n "TODO" README.md | snail --awk '/TODO/ { print("{$n}: {$0}") }'
|
|
274
|
+
|
|
275
|
+
# Environment variables
|
|
276
|
+
snail 'print($env.PATH)'
|
|
266
277
|
```
|
|
267
278
|
|
|
268
279
|
## 📚 Documentation
|
|
@@ -63,6 +63,7 @@ END { print("done") }
|
|
|
63
63
|
| `$p` | Current file path |
|
|
64
64
|
| `$m` | Last regex match object |
|
|
65
65
|
|
|
66
|
+
|
|
66
67
|
Begin/end blocks can live in the source file (`BEGIN { ... }` / `END { ... }`) or be supplied
|
|
67
68
|
via CLI flags (`-b`/`--begin`, `-e`/`--end`) for setup and teardown. CLI BEGIN blocks run
|
|
68
69
|
before in-file BEGIN blocks; CLI END blocks run after in-file END blocks.
|
|
@@ -100,6 +101,13 @@ BEGIN/END blocks are regular Snail blocks, so awk/map-only `$` variables are not
|
|
|
100
101
|
snail --map --begin "print('start')" --end "print('done')" "print($src)" *.txt
|
|
101
102
|
```
|
|
102
103
|
|
|
104
|
+
### Built-in Variables (All Modes)
|
|
105
|
+
|
|
106
|
+
| Variable | Description |
|
|
107
|
+
|----------|-------------|
|
|
108
|
+
| `$e` | Exception object in `expr:fallback?` |
|
|
109
|
+
| `$env` | Environment map (wrapper around `os.environ`) |
|
|
110
|
+
|
|
103
111
|
### Compact Error Handling
|
|
104
112
|
|
|
105
113
|
The `?` operator makes error handling terse yet expressive:
|
|
@@ -250,6 +258,9 @@ snail 'if let [_, user, domain] = "user@example.com" in /^[\w.]+@([\w.]+)$/ { pr
|
|
|
250
258
|
|
|
251
259
|
# Awk mode: print line numbers for matches
|
|
252
260
|
rg -n "TODO" README.md | snail --awk '/TODO/ { print("{$n}: {$0}") }'
|
|
261
|
+
|
|
262
|
+
# Environment variables
|
|
263
|
+
snail 'print($env.PATH)'
|
|
253
264
|
```
|
|
254
265
|
|
|
255
266
|
## 📚 Documentation
|
|
@@ -250,9 +250,9 @@ boolean = { "True" | "False" }
|
|
|
250
250
|
none = { "None" }
|
|
251
251
|
|
|
252
252
|
// Special variables: exception, AWK fields, map vars, injected vars
|
|
253
|
-
exception_var = { "$e" }
|
|
253
|
+
exception_var = { "$e" ~ !ident_continue }
|
|
254
254
|
field_index_var = @{ "$" ~ ASCII_DIGIT+ }
|
|
255
|
-
injected_var = { "$text" | "$src" | "$fn" | "$fd" | "$n" | "$p" | "$m" | "$f" }
|
|
255
|
+
injected_var = { "$text" | "$src" | "$env" | "$fn" | "$fd" | "$n" | "$p" | "$m" | "$f" }
|
|
256
256
|
|
|
257
257
|
// Number, string, and regex literals
|
|
258
258
|
number = @{ ASCII_DIGIT+ ~ ("." ~ ASCII_DIGIT+)? }
|
|
@@ -293,6 +293,15 @@ fn parses_structured_accessor_with_pipeline() {
|
|
|
293
293
|
}
|
|
294
294
|
}
|
|
295
295
|
|
|
296
|
+
#[test]
|
|
297
|
+
fn parses_env_var() {
|
|
298
|
+
let program = parse_ok("value = $env");
|
|
299
|
+
assert_eq!(program.stmts.len(), 1);
|
|
300
|
+
|
|
301
|
+
let (_, value) = expect_assign(&program.stmts[0]);
|
|
302
|
+
expect_name(value, "$env");
|
|
303
|
+
}
|
|
304
|
+
|
|
296
305
|
#[test]
|
|
297
306
|
fn parses_empty_structured_accessor() {
|
|
298
307
|
let program = parse_ok("result = $[]");
|
|
@@ -37,9 +37,11 @@ pub(crate) const SNAIL_AWK_MATCH_PYVAR: &str = "__snail_match";
|
|
|
37
37
|
pub(crate) const SNAIL_MAP_SRC: &str = "$src";
|
|
38
38
|
pub(crate) const SNAIL_MAP_FD: &str = "$fd";
|
|
39
39
|
pub(crate) const SNAIL_MAP_TEXT: &str = "$text";
|
|
40
|
+
pub(crate) const SNAIL_ENV: &str = "$env";
|
|
40
41
|
pub(crate) const SNAIL_MAP_SRC_PYVAR: &str = "__snail_src";
|
|
41
42
|
pub(crate) const SNAIL_MAP_FD_PYVAR: &str = "__snail_fd";
|
|
42
43
|
pub(crate) const SNAIL_MAP_TEXT_PYVAR: &str = "__snail_text";
|
|
44
|
+
pub(crate) const SNAIL_ENV_PYVAR: &str = "__snail_env";
|
|
43
45
|
pub const SNAIL_LAZY_TEXT_CLASS: &str = "__SnailLazyText";
|
|
44
46
|
pub const SNAIL_LAZY_FILE_CLASS: &str = "__SnailLazyFile";
|
|
45
47
|
|
|
@@ -55,6 +57,7 @@ pub(crate) fn injected_py_name(name: &str) -> Option<&'static str> {
|
|
|
55
57
|
SNAIL_MAP_SRC => Some(SNAIL_MAP_SRC_PYVAR),
|
|
56
58
|
SNAIL_MAP_FD => Some(SNAIL_MAP_FD_PYVAR),
|
|
57
59
|
SNAIL_MAP_TEXT => Some(SNAIL_MAP_TEXT_PYVAR),
|
|
60
|
+
SNAIL_ENV => Some(SNAIL_ENV_PYVAR),
|
|
58
61
|
_ => None,
|
|
59
62
|
}
|
|
60
63
|
}
|
|
@@ -99,6 +99,7 @@ class _Args:
|
|
|
99
99
|
self.no_auto_import = False
|
|
100
100
|
self.debug = False
|
|
101
101
|
self.debug_snail_ast = False
|
|
102
|
+
self.debug_python_ast = False
|
|
102
103
|
self.version = False
|
|
103
104
|
self.help = False
|
|
104
105
|
self.begin_code: list[str] = []
|
|
@@ -132,6 +133,7 @@ def _print_help(file=None) -> None:
|
|
|
132
133
|
print(" -I, --no-auto-import disable auto-imports", file=file)
|
|
133
134
|
print(" --debug parse and compile, then print, do not run", file=file)
|
|
134
135
|
print(" --debug-snail-ast parse and print Snail AST, do not run", file=file)
|
|
136
|
+
print(" --debug-python-ast parse and print Python AST, do not run", file=file)
|
|
135
137
|
print(" -v, --version show version and exit", file=file)
|
|
136
138
|
print(" -h, --help show this help message and exit", file=file)
|
|
137
139
|
|
|
@@ -234,6 +236,10 @@ def _parse_args(argv: list[str]) -> _Args:
|
|
|
234
236
|
args.debug_snail_ast = True
|
|
235
237
|
idx += 1
|
|
236
238
|
continue
|
|
239
|
+
if token == "--debug-python-ast":
|
|
240
|
+
args.debug_python_ast = True
|
|
241
|
+
idx += 1
|
|
242
|
+
continue
|
|
237
243
|
if token == "-f":
|
|
238
244
|
if idx + 1 >= len(argv):
|
|
239
245
|
raise ValueError("option -f requires an argument")
|
|
@@ -282,6 +288,18 @@ def _get_version() -> str:
|
|
|
282
288
|
return version
|
|
283
289
|
|
|
284
290
|
|
|
291
|
+
def _format_python_runtime() -> str:
|
|
292
|
+
version = (
|
|
293
|
+
f"{sys.version_info.major}."
|
|
294
|
+
f"{sys.version_info.minor}."
|
|
295
|
+
f"{sys.version_info.micro}"
|
|
296
|
+
)
|
|
297
|
+
executable = sys.executable or "<unknown>"
|
|
298
|
+
if executable != "<unknown>":
|
|
299
|
+
executable = os.path.abspath(executable)
|
|
300
|
+
return f"Python {version} ({executable})"
|
|
301
|
+
|
|
302
|
+
|
|
285
303
|
def main(argv: Optional[list[str]] = None) -> int:
|
|
286
304
|
if argv is None:
|
|
287
305
|
_install_trimmed_excepthook()
|
|
@@ -299,6 +317,7 @@ def main(argv: Optional[list[str]] = None) -> int:
|
|
|
299
317
|
return 0
|
|
300
318
|
if namespace.version:
|
|
301
319
|
print(_format_version(_get_version(), __build_info__))
|
|
320
|
+
print(_format_python_runtime())
|
|
302
321
|
return 0
|
|
303
322
|
|
|
304
323
|
# Validate --awk and --map are mutually exclusive
|
|
@@ -348,6 +367,24 @@ def main(argv: Optional[list[str]] = None) -> int:
|
|
|
348
367
|
print(snail_ast)
|
|
349
368
|
return 0
|
|
350
369
|
|
|
370
|
+
if namespace.debug_python_ast:
|
|
371
|
+
import ast
|
|
372
|
+
|
|
373
|
+
python_ast = compile_ast(
|
|
374
|
+
source,
|
|
375
|
+
mode=mode,
|
|
376
|
+
auto_print=not namespace.no_print,
|
|
377
|
+
filename=filename,
|
|
378
|
+
begin_code=namespace.begin_code,
|
|
379
|
+
end_code=namespace.end_code,
|
|
380
|
+
)
|
|
381
|
+
try:
|
|
382
|
+
output = ast.dump(python_ast, indent=2)
|
|
383
|
+
except TypeError:
|
|
384
|
+
output = ast.dump(python_ast)
|
|
385
|
+
print(output)
|
|
386
|
+
return 0
|
|
387
|
+
|
|
351
388
|
if namespace.debug:
|
|
352
389
|
import ast
|
|
353
390
|
import builtins
|
|
@@ -48,6 +48,7 @@ _incr_attr = None
|
|
|
48
48
|
_incr_index = None
|
|
49
49
|
_aug_attr = None
|
|
50
50
|
_aug_index = None
|
|
51
|
+
_env_map = None
|
|
51
52
|
|
|
52
53
|
|
|
53
54
|
def _get_compact_try():
|
|
@@ -131,6 +132,15 @@ def _get_lazy_file_class():
|
|
|
131
132
|
return _lazy_file_class
|
|
132
133
|
|
|
133
134
|
|
|
135
|
+
def _get_env_map():
|
|
136
|
+
global _env_map
|
|
137
|
+
if _env_map is None:
|
|
138
|
+
from .env import EnvMap
|
|
139
|
+
|
|
140
|
+
_env_map = EnvMap()
|
|
141
|
+
return _env_map
|
|
142
|
+
|
|
143
|
+
|
|
134
144
|
def _get_incr_attr():
|
|
135
145
|
global _incr_attr
|
|
136
146
|
if _incr_attr is None:
|
|
@@ -245,6 +255,7 @@ def install_helpers(globals_dict: dict) -> None:
|
|
|
245
255
|
globals_dict["__snail_incr_index"] = _lazy_incr_index
|
|
246
256
|
globals_dict["__snail_aug_attr"] = _lazy_aug_attr
|
|
247
257
|
globals_dict["__snail_aug_index"] = _lazy_aug_index
|
|
258
|
+
globals_dict["__snail_env"] = _get_env_map()
|
|
248
259
|
globals_dict["js"] = _lazy_js
|
|
249
260
|
globals_dict["__SnailLazyText"] = _get_lazy_text_class()
|
|
250
261
|
globals_dict["__SnailLazyFile"] = _get_lazy_file_class()
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class EnvMap:
|
|
7
|
+
__slots__ = ("_env",)
|
|
8
|
+
|
|
9
|
+
def __init__(self, env=None) -> None:
|
|
10
|
+
self._env = os.environ if env is None else env
|
|
11
|
+
|
|
12
|
+
def __fallback__(self) -> str:
|
|
13
|
+
return ""
|
|
14
|
+
|
|
15
|
+
def _lookup(self, key):
|
|
16
|
+
try:
|
|
17
|
+
return self._env[key]
|
|
18
|
+
except KeyError as exc:
|
|
19
|
+
exc.__fallback__ = self.__fallback__
|
|
20
|
+
raise
|
|
21
|
+
|
|
22
|
+
def __getitem__(self, key):
|
|
23
|
+
return self._lookup(key)
|
|
24
|
+
|
|
25
|
+
def __getattr__(self, name):
|
|
26
|
+
return self._lookup(name)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|