Skip to content

Commit

Permalink
Merge branch 'main' into short_term_storage_complex
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/andromede/libs/standard_sc.py
  • Loading branch information
Yann-Temudjin committed Apr 19, 2024
2 parents a67a69b + 9f419cd commit 095c569
Show file tree
Hide file tree
Showing 58 changed files with 9,617 additions and 481 deletions.
50 changes: 50 additions & 0 deletions grammar/Expr.g4
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
Copyright (c) 2024, RTE (https://www.rte-france.com)
See AUTHORS.txt
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
SPDX-License-Identifier: MPL-2.0
This file is part of the Antares project.
*/

grammar Expr;

/* To match the whole input */
fullexpr: expr EOF;

shift: TIME (op=('+' | '-') expr)?;

expr: '-' expr # negation
| expr op=('/' | '*') expr # muldiv
| expr op=('+' | '-') expr # addsub
| expr COMPARISON expr # comparison
| IDENTIFIER # identifier
| IDENTIFIER '.' IDENTIFIER # portField
| NUMBER # number
| '(' expr ')' # expression
| IDENTIFIER '(' expr ')' # function
| IDENTIFIER '[' shift (',' shift)* ']' # timeShift
| IDENTIFIER '[' expr (',' expr )* ']' # timeIndex
| IDENTIFIER '[' shift1=shift '..' shift2=shift ']' # timeShiftRange
| IDENTIFIER '[' expr '..' expr ']' # timeRange
;

fragment DIGIT : [0-9] ;
fragment CHAR : [a-zA-Z_];
fragment CHAR_OR_DIGIT : (CHAR | DIGIT);

NUMBER : DIGIT+ ('.' DIGIT+)?;
TIME : 't';
IDENTIFIER : CHAR CHAR_OR_DIGIT*;
COMPARISON : ( '=' | '>=' | '<=' );
ADDSUB : ( '+' | '-' );
MULDIV : ( '*' | '/' );
LBRACKET: '[';
RBRACKET: ']';

WS: (' ' | '\t' | '\r'| '\n') -> skip;
17 changes: 17 additions & 0 deletions grammar/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Expression grammar definition

[Expr.g4](Expr.g4) defines the grammar for mathematical expressions
use for defining constraints, objective, etc.

[ANTLR](https://www.antlr.org) needs to be used to generate the associated
parser code, which must be written to [andromede.expression.parsing.antlr](/src/andromede/expression/parsing/antlr)
package. **No other files are expected to be present in that package**.

To achieve this you may use the provided `generate-parser.sh` script after having installed
antlr4-tools (`pip install -r requirements-dev.txt` in root directory).

You may also, for example, use the ANTLR4 PyCharm plugin.

We use the visitor and not the listener in order to translate ANTLR AST
into our own AST, so the options `-visitor` and `-no-listener` need to
to be used.
5 changes: 5 additions & 0 deletions grammar/generate-parser.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

script_file=$(readlink -f -- "$0")
script_dir=$(dirname -- "${script_file}")
antlr4 -Dlanguage=Python3 -Werror -no-listener -visitor -o ${script_dir}/../src/andromede/expression/parsing/antlr Expr.g4
2 changes: 1 addition & 1 deletion models-design/model_library/stock_final_level.drawio
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<mxCell id="48" value="r(h+1) = r(h) + u_in(h) - u_out(h)" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="39" vertex="1">
<mxGeometry y="270" width="270" height="30" as="geometry"/>
</mxCell>
<mxCell id="49" value="flow_s, flow_c, flow_out : Flow" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="39" vertex="1">
<mxCell id="49" value="flow_s, flow_in, flow_out : Flow" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="39" vertex="1">
<mxGeometry y="300" width="270" height="30" as="geometry"/>
</mxCell>
<mxCell id="50" value="flow_s.f = u_out - u_in" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="39" vertex="1">
Expand Down
394 changes: 394 additions & 0 deletions models-design/systems/EV_load_min.drawio

Large diffs are not rendered by default.

229 changes: 229 additions & 0 deletions models-design/systems/bc_total_import.drawio

Large diffs are not rendered by default.

103 changes: 53 additions & 50 deletions models-design/systems/electrolyzer_n_inputs.drawio

Large diffs are not rendered by default.

298 changes: 295 additions & 3 deletions models-design/systems/electrolyzer_subject_to_renewable.drawio

Large diffs are not rendered by default.

1,117 changes: 1,117 additions & 0 deletions models-design/systems/flow_based.drawio

Large diffs are not rendered by default.

301 changes: 301 additions & 0 deletions models-design/systems/hydro_valley.drawio

Large diffs are not rendered by default.

223 changes: 223 additions & 0 deletions models-design/systems/nuclear_modulation.drawio

Large diffs are not rendered by default.

1,556 changes: 1,202 additions & 354 deletions models-design/systems/reserve.drawio

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,10 @@ disallow_untyped_defs = true
disallow_untyped_calls = true

[mypy-ortools.*]
ignore_missing_imports = true
ignore_missing_imports = true

[mypy-andromede.expression.parsing.antlr.*]
ignore_errors = True

[mypy-antlr4.*]
ignore_missing_imports = true
2 changes: 2 additions & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ black~=23.7.0
isort~=5.12.0
pytest-cov
pre-commit~=3.5.0
types-PyYAML~=6.0.12.12
antlr4-tools~=0.2.1
4 changes: 3 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ numpy==1.24.4
ortools==9.6.2534
protobuf==4.23.3
scipy==1.10.1

antlr4-python3-runtime==4.13.1
PyYAML~=6.0.1
pydantic~=2.6.1
29 changes: 29 additions & 0 deletions src/andromede/expression/equality.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
BinaryOperatorNode,
ExpressionRange,
InstancesTimeIndex,
PortFieldAggregatorNode,
PortFieldNode,
ScenarioOperatorNode,
TimeAggregatorNode,
TimeOperatorNode,
Expand Down Expand Up @@ -84,6 +86,12 @@ def visit(self, left: ExpressionNode, right: ExpressionNode) -> bool:
right, ScenarioOperatorNode
):
return self.scenario_operator(left, right)
if isinstance(left, PortFieldNode) and isinstance(right, PortFieldNode):
return self.port_field(left, right)
if isinstance(left, PortFieldAggregatorNode) and isinstance(
right, PortFieldAggregatorNode
):
return self.port_field_aggregator(left, right)
raise NotImplementedError(f"Equality not implemented for {left.__class__}")

def literal(self, left: LiteralNode, right: LiteralNode) -> bool:
Expand Down Expand Up @@ -163,6 +171,16 @@ def scenario_operator(
) -> bool:
return left.name == right.name and self.visit(left.operand, right.operand)

def port_field(self, left: PortFieldNode, right: PortFieldNode) -> bool:
return left.port_name == right.port_name and left.field_name == right.field_name

def port_field_aggregator(
self, left: PortFieldAggregatorNode, right: PortFieldAggregatorNode
) -> bool:
return left.aggregator == right.aggregator and self.visit(
left.operand, right.operand
)


def expressions_equal(
left: ExpressionNode, right: ExpressionNode, abs_tol: float = 0, rel_tol: float = 0
Expand All @@ -171,3 +189,14 @@ def expressions_equal(
True if both expression nodes are equal. Literal values may be compared with absolute or relative tolerance.
"""
return EqualityVisitor(abs_tol, rel_tol).visit(left, right)


def expressions_equal_if_present(
lhs: Optional[ExpressionNode], rhs: Optional[ExpressionNode]
) -> bool:
if lhs is None and rhs is None:
return True
elif lhs is None or rhs is None:
return False
else:
return expressions_equal(lhs, rhs)
1 change: 1 addition & 0 deletions src/andromede/expression/expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ def expression_range(
)


@dataclass
class InstancesTimeIndex:
"""
Defines a set of time indices on which a time operator operates.
Expand Down
Empty file.
50 changes: 50 additions & 0 deletions src/andromede/expression/parsing/antlr/Expr.interp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
token literal names:
null
'+'
'-'
'/'
'*'
'.'
'('
')'
','
'..'
null
't'
null
null
null
null
'['
']'
null

token symbolic names:
null
null
null
null
null
null
null
null
null
null
NUMBER
TIME
IDENTIFIER
COMPARISON
ADDSUB
MULDIV
LBRACKET
RBRACKET
WS

rule names:
fullexpr
shift
expr


atn:
[4, 1, 18, 86, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 3, 1, 13, 8, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 5, 2, 37, 8, 2, 10, 2, 12, 2, 40, 9, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 5, 2, 49, 8, 2, 10, 2, 12, 2, 52, 9, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 70, 8, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 5, 2, 81, 8, 2, 10, 2, 12, 2, 84, 9, 2, 1, 2, 0, 1, 4, 3, 0, 2, 4, 0, 2, 1, 0, 1, 2, 1, 0, 3, 4, 97, 0, 6, 1, 0, 0, 0, 2, 9, 1, 0, 0, 0, 4, 69, 1, 0, 0, 0, 6, 7, 3, 4, 2, 0, 7, 8, 5, 0, 0, 1, 8, 1, 1, 0, 0, 0, 9, 12, 5, 11, 0, 0, 10, 11, 7, 0, 0, 0, 11, 13, 3, 4, 2, 0, 12, 10, 1, 0, 0, 0, 12, 13, 1, 0, 0, 0, 13, 3, 1, 0, 0, 0, 14, 15, 6, 2, -1, 0, 15, 16, 5, 2, 0, 0, 16, 70, 3, 4, 2, 13, 17, 70, 5, 12, 0, 0, 18, 19, 5, 12, 0, 0, 19, 20, 5, 5, 0, 0, 20, 70, 5, 12, 0, 0, 21, 70, 5, 10, 0, 0, 22, 23, 5, 6, 0, 0, 23, 24, 3, 4, 2, 0, 24, 25, 5, 7, 0, 0, 25, 70, 1, 0, 0, 0, 26, 27, 5, 12, 0, 0, 27, 28, 5, 6, 0, 0, 28, 29, 3, 4, 2, 0, 29, 30, 5, 7, 0, 0, 30, 70, 1, 0, 0, 0, 31, 32, 5, 12, 0, 0, 32, 33, 5, 16, 0, 0, 33, 38, 3, 2, 1, 0, 34, 35, 5, 8, 0, 0, 35, 37, 3, 2, 1, 0, 36, 34, 1, 0, 0, 0, 37, 40, 1, 0, 0, 0, 38, 36, 1, 0, 0, 0, 38, 39, 1, 0, 0, 0, 39, 41, 1, 0, 0, 0, 40, 38, 1, 0, 0, 0, 41, 42, 5, 17, 0, 0, 42, 70, 1, 0, 0, 0, 43, 44, 5, 12, 0, 0, 44, 45, 5, 16, 0, 0, 45, 50, 3, 4, 2, 0, 46, 47, 5, 8, 0, 0, 47, 49, 3, 4, 2, 0, 48, 46, 1, 0, 0, 0, 49, 52, 1, 0, 0, 0, 50, 48, 1, 0, 0, 0, 50, 51, 1, 0, 0, 0, 51, 53, 1, 0, 0, 0, 52, 50, 1, 0, 0, 0, 53, 54, 5, 17, 0, 0, 54, 70, 1, 0, 0, 0, 55, 56, 5, 12, 0, 0, 56, 57, 5, 16, 0, 0, 57, 58, 3, 2, 1, 0, 58, 59, 5, 9, 0, 0, 59, 60, 3, 2, 1, 0, 60, 61, 5, 17, 0, 0, 61, 70, 1, 0, 0, 0, 62, 63, 5, 12, 0, 0, 63, 64, 5, 16, 0, 0, 64, 65, 3, 4, 2, 0, 65, 66, 5, 9, 0, 0, 66, 67, 3, 4, 2, 0, 67, 68, 5, 17, 0, 0, 68, 70, 1, 0, 0, 0, 69, 14, 1, 0, 0, 0, 69, 17, 1, 0, 0, 0, 69, 18, 1, 0, 0, 0, 69, 21, 1, 0, 0, 0, 69, 22, 1, 0, 0, 0, 69, 26, 1, 0, 0, 0, 69, 31, 1, 0, 0, 0, 69, 43, 1, 0, 0, 0, 69, 55, 1, 0, 0, 0, 69, 62, 1, 0, 0, 0, 70, 82, 1, 0, 0, 0, 71, 72, 10, 12, 0, 0, 72, 73, 7, 1, 0, 0, 73, 81, 3, 4, 2, 13, 74, 75, 10, 11, 0, 0, 75, 76, 7, 0, 0, 0, 76, 81, 3, 4, 2, 12, 77, 78, 10, 10, 0, 0, 78, 79, 5, 13, 0, 0, 79, 81, 3, 4, 2, 11, 80, 71, 1, 0, 0, 0, 80, 74, 1, 0, 0, 0, 80, 77, 1, 0, 0, 0, 81, 84, 1, 0, 0, 0, 82, 80, 1, 0, 0, 0, 82, 83, 1, 0, 0, 0, 83, 5, 1, 0, 0, 0, 84, 82, 1, 0, 0, 0, 6, 12, 38, 50, 69, 80, 82]
30 changes: 30 additions & 0 deletions src/andromede/expression/parsing/antlr/Expr.tokens
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
T__0=1
T__1=2
T__2=3
T__3=4
T__4=5
T__5=6
T__6=7
T__7=8
T__8=9
NUMBER=10
TIME=11
IDENTIFIER=12
COMPARISON=13
ADDSUB=14
MULDIV=15
LBRACKET=16
RBRACKET=17
WS=18
'+'=1
'-'=2
'/'=3
'*'=4
'.'=5
'('=6
')'=7
','=8
'..'=9
't'=11
'['=16
']'=17
74 changes: 74 additions & 0 deletions src/andromede/expression/parsing/antlr/ExprLexer.interp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
token literal names:
null
'+'
'-'
'/'
'*'
'.'
'('
')'
','
'..'
null
't'
null
null
null
null
'['
']'
null

token symbolic names:
null
null
null
null
null
null
null
null
null
null
NUMBER
TIME
IDENTIFIER
COMPARISON
ADDSUB
MULDIV
LBRACKET
RBRACKET
WS

rule names:
T__0
T__1
T__2
T__3
T__4
T__5
T__6
T__7
T__8
DIGIT
CHAR
CHAR_OR_DIGIT
NUMBER
TIME
IDENTIFIER
COMPARISON
ADDSUB
MULDIV
LBRACKET
RBRACKET
WS

channel names:
DEFAULT_TOKEN_CHANNEL
HIDDEN

mode names:
DEFAULT_MODE

atn:
[4, 0, 18, 111, 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, 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, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 3, 11, 69, 8, 11, 1, 12, 4, 12, 72, 8, 12, 11, 12, 12, 12, 73, 1, 12, 1, 12, 4, 12, 78, 8, 12, 11, 12, 12, 12, 79, 3, 12, 82, 8, 12, 1, 13, 1, 13, 1, 14, 1, 14, 5, 14, 88, 8, 14, 10, 14, 12, 14, 91, 9, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 98, 8, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 0, 0, 21, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 0, 21, 0, 23, 0, 25, 10, 27, 11, 29, 12, 31, 13, 33, 14, 35, 15, 37, 16, 39, 17, 41, 18, 1, 0, 5, 1, 0, 48, 57, 3, 0, 65, 90, 95, 95, 97, 122, 2, 0, 43, 43, 45, 45, 2, 0, 42, 42, 47, 47, 3, 0, 9, 10, 13, 13, 32, 32, 114, 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, 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, 1, 43, 1, 0, 0, 0, 3, 45, 1, 0, 0, 0, 5, 47, 1, 0, 0, 0, 7, 49, 1, 0, 0, 0, 9, 51, 1, 0, 0, 0, 11, 53, 1, 0, 0, 0, 13, 55, 1, 0, 0, 0, 15, 57, 1, 0, 0, 0, 17, 59, 1, 0, 0, 0, 19, 62, 1, 0, 0, 0, 21, 64, 1, 0, 0, 0, 23, 68, 1, 0, 0, 0, 25, 71, 1, 0, 0, 0, 27, 83, 1, 0, 0, 0, 29, 85, 1, 0, 0, 0, 31, 97, 1, 0, 0, 0, 33, 99, 1, 0, 0, 0, 35, 101, 1, 0, 0, 0, 37, 103, 1, 0, 0, 0, 39, 105, 1, 0, 0, 0, 41, 107, 1, 0, 0, 0, 43, 44, 5, 43, 0, 0, 44, 2, 1, 0, 0, 0, 45, 46, 5, 45, 0, 0, 46, 4, 1, 0, 0, 0, 47, 48, 5, 47, 0, 0, 48, 6, 1, 0, 0, 0, 49, 50, 5, 42, 0, 0, 50, 8, 1, 0, 0, 0, 51, 52, 5, 46, 0, 0, 52, 10, 1, 0, 0, 0, 53, 54, 5, 40, 0, 0, 54, 12, 1, 0, 0, 0, 55, 56, 5, 41, 0, 0, 56, 14, 1, 0, 0, 0, 57, 58, 5, 44, 0, 0, 58, 16, 1, 0, 0, 0, 59, 60, 5, 46, 0, 0, 60, 61, 5, 46, 0, 0, 61, 18, 1, 0, 0, 0, 62, 63, 7, 0, 0, 0, 63, 20, 1, 0, 0, 0, 64, 65, 7, 1, 0, 0, 65, 22, 1, 0, 0, 0, 66, 69, 3, 21, 10, 0, 67, 69, 3, 19, 9, 0, 68, 66, 1, 0, 0, 0, 68, 67, 1, 0, 0, 0, 69, 24, 1, 0, 0, 0, 70, 72, 3, 19, 9, 0, 71, 70, 1, 0, 0, 0, 72, 73, 1, 0, 0, 0, 73, 71, 1, 0, 0, 0, 73, 74, 1, 0, 0, 0, 74, 81, 1, 0, 0, 0, 75, 77, 5, 46, 0, 0, 76, 78, 3, 19, 9, 0, 77, 76, 1, 0, 0, 0, 78, 79, 1, 0, 0, 0, 79, 77, 1, 0, 0, 0, 79, 80, 1, 0, 0, 0, 80, 82, 1, 0, 0, 0, 81, 75, 1, 0, 0, 0, 81, 82, 1, 0, 0, 0, 82, 26, 1, 0, 0, 0, 83, 84, 5, 116, 0, 0, 84, 28, 1, 0, 0, 0, 85, 89, 3, 21, 10, 0, 86, 88, 3, 23, 11, 0, 87, 86, 1, 0, 0, 0, 88, 91, 1, 0, 0, 0, 89, 87, 1, 0, 0, 0, 89, 90, 1, 0, 0, 0, 90, 30, 1, 0, 0, 0, 91, 89, 1, 0, 0, 0, 92, 98, 5, 61, 0, 0, 93, 94, 5, 62, 0, 0, 94, 98, 5, 61, 0, 0, 95, 96, 5, 60, 0, 0, 96, 98, 5, 61, 0, 0, 97, 92, 1, 0, 0, 0, 97, 93, 1, 0, 0, 0, 97, 95, 1, 0, 0, 0, 98, 32, 1, 0, 0, 0, 99, 100, 7, 2, 0, 0, 100, 34, 1, 0, 0, 0, 101, 102, 7, 3, 0, 0, 102, 36, 1, 0, 0, 0, 103, 104, 5, 91, 0, 0, 104, 38, 1, 0, 0, 0, 105, 106, 5, 93, 0, 0, 106, 40, 1, 0, 0, 0, 107, 108, 7, 4, 0, 0, 108, 109, 1, 0, 0, 0, 109, 110, 6, 20, 0, 0, 110, 42, 1, 0, 0, 0, 7, 0, 68, 73, 79, 81, 89, 97, 1, 6, 0, 0]
Loading

0 comments on commit 095c569

Please sign in to comment.