Skip to content

Commit d6d1216

Browse files
committed
Detect and skip string-type signals
This is an intermediate step to allow handling of files with string signals. Eventually, support should actually be added for string signals.
1 parent 49ff649 commit d6d1216

File tree

10 files changed

+216
-1
lines changed

10 files changed

+216
-1
lines changed

canmatrix/importsym.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ class Mode(object):
137137
is_signed = False
138138
elif tempArray[1] == 'signed':
139139
is_signed = True
140+
elif tempArray[1] == 'string':
141+
# TODO: actually support string variables instead of skipping
142+
print('Variable type \'string\' found and skipped')
143+
continue
140144
else:
141145
raise ValueError('Unknown type \'{}\' found'.format(tempArray[1]))
142146

test/reference/from_sym/test.arxml

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,26 @@
109109
</I-PDU-TRIGGERING-REFS>
110110
<FRAME-PORT-REFS/>
111111
</CAN-FRAME-TRIGGERING>
112+
<CAN-FRAME-TRIGGERING>
113+
<SHORT-NAME>justString</SHORT-NAME>
114+
<IDENTIFIER>486517952</IDENTIFIER>
115+
<CAN-ADDRESSING-MODE>EXTENDED</CAN-ADDRESSING-MODE>
116+
<FRAME-REF DEST="FRAME">/Frame/FRAME_justString</FRAME-REF>
117+
<I-PDU-TRIGGERING-REFS>
118+
<I-PDU-TRIGGERING-REF DEST="I-PDU-TRIGGERING">/Cluster/CAN/IPDUTRIGG_justString</I-PDU-TRIGGERING-REF>
119+
</I-PDU-TRIGGERING-REFS>
120+
<FRAME-PORT-REFS/>
121+
</CAN-FRAME-TRIGGERING>
122+
<CAN-FRAME-TRIGGERING>
123+
<SHORT-NAME>stringAndOther</SHORT-NAME>
124+
<IDENTIFIER>486517696</IDENTIFIER>
125+
<CAN-ADDRESSING-MODE>EXTENDED</CAN-ADDRESSING-MODE>
126+
<FRAME-REF DEST="FRAME">/Frame/FRAME_stringAndOther</FRAME-REF>
127+
<I-PDU-TRIGGERING-REFS>
128+
<I-PDU-TRIGGERING-REF DEST="I-PDU-TRIGGERING">/Cluster/CAN/IPDUTRIGG_stringAndOther</I-PDU-TRIGGERING-REF>
129+
</I-PDU-TRIGGERING-REFS>
130+
<FRAME-PORT-REFS/>
131+
</CAN-FRAME-TRIGGERING>
112132
<CAN-FRAME-TRIGGERING>
113133
<SHORT-NAME>StatusMeasuredPower</SHORT-NAME>
114134
<IDENTIFIER>218090231</IDENTIFIER>
@@ -311,6 +331,14 @@
311331
<SHORT-NAME>IPDUTRIGG_MasterMeasuredPowerAPU2</SHORT-NAME>
312332
<I-PDU-REF DEST="SIGNAL-I-PDU">/PDU/PDU_MasterMeasuredPowerAPU2</I-PDU-REF>
313333
</I-PDU-TRIGGERING>
334+
<I-PDU-TRIGGERING>
335+
<SHORT-NAME>IPDUTRIGG_justString</SHORT-NAME>
336+
<I-PDU-REF DEST="SIGNAL-I-PDU">/PDU/PDU_justString</I-PDU-REF>
337+
</I-PDU-TRIGGERING>
338+
<I-PDU-TRIGGERING>
339+
<SHORT-NAME>IPDUTRIGG_stringAndOther</SHORT-NAME>
340+
<I-PDU-REF DEST="SIGNAL-I-PDU">/PDU/PDU_stringAndOther</I-PDU-REF>
341+
</I-PDU-TRIGGERING>
314342
<I-PDU-TRIGGERING>
315343
<SHORT-NAME>IPDUTRIGG_StatusMeasuredPower</SHORT-NAME>
316344
<I-PDU-REF DEST="SIGNAL-I-PDU">/PDU/PDU_StatusMeasuredPower</I-PDU-REF>
@@ -625,6 +653,10 @@
625653
<SHORT-NAME>RealPower_measured</SHORT-NAME>
626654
<SIGNAL-REF DEST="I-SIGNAL">/ISignal/RealPower_measured</SIGNAL-REF>
627655
</I-SIGNAL-TRIGGERING>
656+
<I-SIGNAL-TRIGGERING>
657+
<SHORT-NAME>RealPower_measured</SHORT-NAME>
658+
<SIGNAL-REF DEST="I-SIGNAL">/ISignal/RealPower_measured</SIGNAL-REF>
659+
</I-SIGNAL-TRIGGERING>
628660
<I-SIGNAL-TRIGGERING>
629661
<SHORT-NAME>ReactivePower_measured</SHORT-NAME>
630662
<SIGNAL-REF DEST="I-SIGNAL">/ISignal/ReactivePower_measured</SIGNAL-REF>
@@ -1135,6 +1167,30 @@
11351167
</PDU-TO-FRAME-MAPPING>
11361168
</PDU-TO-FRAME-MAPPINGS>
11371169
</FRAME>
1170+
<FRAME>
1171+
<SHORT-NAME>FRAME_justString</SHORT-NAME>
1172+
<FRAME-LENGTH>8</FRAME-LENGTH>
1173+
<PDU-TO-FRAME-MAPPINGS>
1174+
<PDU-TO-FRAME-MAPPING>
1175+
<SHORT-NAME>justString</SHORT-NAME>
1176+
<PACKING-BYTE-ORDER>MOST-SIGNIFICANT-BYTE-LAST</PACKING-BYTE-ORDER>
1177+
<START-POSITION>0</START-POSITION>
1178+
<PDU-REF DEST="SIGNAL-I-PDU">/PDU/PDU_justString</PDU-REF>
1179+
</PDU-TO-FRAME-MAPPING>
1180+
</PDU-TO-FRAME-MAPPINGS>
1181+
</FRAME>
1182+
<FRAME>
1183+
<SHORT-NAME>FRAME_stringAndOther</SHORT-NAME>
1184+
<FRAME-LENGTH>8</FRAME-LENGTH>
1185+
<PDU-TO-FRAME-MAPPINGS>
1186+
<PDU-TO-FRAME-MAPPING>
1187+
<SHORT-NAME>stringAndOther</SHORT-NAME>
1188+
<PACKING-BYTE-ORDER>MOST-SIGNIFICANT-BYTE-LAST</PACKING-BYTE-ORDER>
1189+
<START-POSITION>0</START-POSITION>
1190+
<PDU-REF DEST="SIGNAL-I-PDU">/PDU/PDU_stringAndOther</PDU-REF>
1191+
</PDU-TO-FRAME-MAPPING>
1192+
</PDU-TO-FRAME-MAPPINGS>
1193+
</FRAME>
11381194
<FRAME>
11391195
<SHORT-NAME>FRAME_StatusMeasuredPower</SHORT-NAME>
11401196
<FRAME-LENGTH>8</FRAME-LENGTH>
@@ -1758,6 +1814,23 @@
17581814
</I-SIGNAL-TO-I-PDU-MAPPING>
17591815
</SIGNAL-TO-PDU-MAPPINGS>
17601816
</SIGNAL-I-PDU>
1817+
<SIGNAL-I-PDU>
1818+
<SHORT-NAME>PDU_justString</SHORT-NAME>
1819+
<LENGTH>64</LENGTH>
1820+
<SIGNAL-TO-PDU-MAPPINGS/>
1821+
</SIGNAL-I-PDU>
1822+
<SIGNAL-I-PDU>
1823+
<SHORT-NAME>PDU_stringAndOther</SHORT-NAME>
1824+
<LENGTH>64</LENGTH>
1825+
<SIGNAL-TO-PDU-MAPPINGS>
1826+
<I-SIGNAL-TO-I-PDU-MAPPING>
1827+
<SHORT-NAME>RealPower_measured</SHORT-NAME>
1828+
<START-POSITION>7</START-POSITION>
1829+
<PACKING-BYTE-ORDER>MOST-SIGNIFICANT-BYTE-FIRST</PACKING-BYTE-ORDER>
1830+
<SIGNAL-REF DEST="I-SIGNAL">/ISignal/RealPower_measured</SIGNAL-REF>
1831+
</I-SIGNAL-TO-I-PDU-MAPPING>
1832+
</SIGNAL-TO-PDU-MAPPINGS>
1833+
</SIGNAL-I-PDU>
17611834
<SIGNAL-I-PDU>
17621835
<SHORT-NAME>PDU_StatusMeasuredPower</SHORT-NAME>
17631836
<LENGTH>64</LENGTH>
@@ -2683,6 +2756,10 @@
26832756
<SHORT-NAME>RealPower_measured</SHORT-NAME>
26842757
<SYSTEM-SIGNAL-REF DEST="SYSTEM-SIGNAL">/Signal/RealPower_measured</SYSTEM-SIGNAL-REF>
26852758
</I-SIGNAL>
2759+
<I-SIGNAL>
2760+
<SHORT-NAME>RealPower_measured</SHORT-NAME>
2761+
<SYSTEM-SIGNAL-REF DEST="SYSTEM-SIGNAL">/Signal/RealPower_measured</SYSTEM-SIGNAL-REF>
2762+
</I-SIGNAL>
26862763
<I-SIGNAL>
26872764
<SHORT-NAME>ReactivePower_measured</SHORT-NAME>
26882765
<SYSTEM-SIGNAL-REF DEST="SYSTEM-SIGNAL">/Signal/ReactivePower_measured</SYSTEM-SIGNAL-REF>
@@ -3378,6 +3455,11 @@
33783455
<LENGTH>32</LENGTH>
33793456
<DATA-TYPE-REF DEST="INTEGER-TYPE">/DataType/RealPower_measured</DATA-TYPE-REF>
33803457
</SYSTEM-SIGNAL>
3458+
<SYSTEM-SIGNAL>
3459+
<SHORT-NAME>RealPower_measured</SHORT-NAME>
3460+
<LENGTH>32</LENGTH>
3461+
<DATA-TYPE-REF DEST="INTEGER-TYPE">/DataType/RealPower_measured</DATA-TYPE-REF>
3462+
</SYSTEM-SIGNAL>
33813463
<SYSTEM-SIGNAL>
33823464
<SHORT-NAME>ReactivePower_measured</SHORT-NAME>
33833465
<LENGTH>32</LENGTH>
@@ -4230,6 +4312,12 @@
42304312
<COMPU-METHOD-REF DEST="COMPU-METHOD">/DataType/Semantics/RealPower_measured</COMPU-METHOD-REF>
42314313
</SW-DATA-DEF-PROPS>
42324314
</INTEGER-TYPE>
4315+
<INTEGER-TYPE>
4316+
<SHORT-NAME>RealPower_measured</SHORT-NAME>
4317+
<SW-DATA-DEF-PROPS>
4318+
<COMPU-METHOD-REF DEST="COMPU-METHOD">/DataType/Semantics/RealPower_measured</COMPU-METHOD-REF>
4319+
</SW-DATA-DEF-PROPS>
4320+
</INTEGER-TYPE>
42334321
<INTEGER-TYPE>
42344322
<SHORT-NAME>ReactivePower_measured</SHORT-NAME>
42354323
<SW-DATA-DEF-PROPS>
@@ -7021,6 +7109,24 @@
70217109
</COMPU-SCALES>
70227110
</COMPU-INTERNAL-TO-PHYS>
70237111
</COMPU-METHOD>
7112+
<COMPU-METHOD>
7113+
<SHORT-NAME>RealPower_measured</SHORT-NAME>
7114+
<COMPU-INTERNAL-TO-PHYS>
7115+
<COMPU-SCALES>
7116+
<COMPU-SCALE>
7117+
<COMPU-RATIONAL-COEFFS>
7118+
<COMPU-NUMERATOR>
7119+
<V>0</V>
7120+
<V>1</V>
7121+
</COMPU-NUMERATOR>
7122+
<COMPU-DENOMINATOR>
7123+
<V>1</V>
7124+
</COMPU-DENOMINATOR>
7125+
</COMPU-RATIONAL-COEFFS>
7126+
</COMPU-SCALE>
7127+
</COMPU-SCALES>
7128+
</COMPU-INTERNAL-TO-PHYS>
7129+
</COMPU-METHOD>
70247130
<COMPU-METHOD>
70257131
<SHORT-NAME>ReactivePower_measured</SHORT-NAME>
70267132
<COMPU-INTERNAL-TO-PHYS>

test/reference/from_sym/test.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ CFFCAF7h,StatusMeasuredPower,100,,,5,0,ReactivePower_measured,Measured reactive
373373
1CFFA9F7h,StatusNVParam,,,,7,0,StatusK1Close,Mode 8:Maximum time required for the K1 contactor to close.,16,,,m,u,,0.0..2000.0,ms
374374
1CFFA9F7h,StatusNVParam,,,,7,0,StatusMX2Open,Mode 7:Maximum time required for the MX2 contactor to open.,16,,,m,u,,0.0..1.0,ms
375375
1CFFA9F7h,StatusNVParam,,,,7,0,V110to120pct,Mode 1:,16,,,m,u,,1.0..30000.0,ms
376+
1CFFABC0h,stringAndOther,,,,1,0,RealPower_measured,Measured real power.,32,,,m,s,,-2147483648.0..2147483647.0,W
376377
1CFFC1F7h,softwareRev,,,,1,0,ControlSwRev,Software revision of the control firmware.,16,,,m,u,,0.0..655.35,0.01
377378
1CFFC1F7h,softwareRev,,,,3,0,InterfaceRev,Software revision of the CAN communication interface.,16,,,m,u,,0.0..655.35,0.01
378379
1CFFC1F7h,softwareRev,,,,5,0,BuildTime,Build timestamp.,32,,,m,u,,0.0..4294967295.0

test/reference/from_sym/test.dbc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ BO_ 2365573879 MasterMeasuredPowerAPU2: 8 Vector__XXX
8989
SG_ RealPower_measured : 7|32@0- (1,0) [-2147483648.0|2147483647.0] "W" Vector__XXX
9090
SG_ ReactivePower_measured : 39|32@0- (1,0) [-2147483648.0|2147483647.0] "VA" Vector__XXX
9191

92+
BO_ 2634001600 justString: 8 Vector__XXX
93+
94+
BO_ 2634001344 stringAndOther: 8 Vector__XXX
95+
SG_ RealPower_measured : 7|32@0- (1,0) [-2147483648.0|2147483647.0] "W" Vector__XXX
96+
9297
BO_ 2365573879 StatusMeasuredPower: 8 Vector__XXX
9398
SG_ RealPower_measured : 7|32@0- (1,0) [-2147483648.0|2147483647.0] "W" Vector__XXX
9499
SG_ ReactivePower_measured : 39|32@0- (1,0) [-2147483648.0|2147483647.0] "VA" Vector__XXX
@@ -300,6 +305,7 @@ CM_ SG_ 2365562433 Voltage_command "Desired output voltage while in grid forming
300305
CM_ SG_ 2365562433 Frequency_command "Desired output frequency while in grid forming mode.";
301306
CM_ SG_ 2365573879 RealPower_measured "Measured real power of master unit.";
302307
CM_ SG_ 2365573879 ReactivePower_measured "Measured reactive power of master unit.";
308+
CM_ SG_ 2634001344 RealPower_measured "Measured real power.";
303309
CM_ SG_ 2365573879 RealPower_measured "Measured real power.";
304310
CM_ SG_ 2365573879 ReactivePower_measured "Measured reactive power.";
305311
CM_ SG_ 2566898935 RealPower_echo "Echoed real power command.";
@@ -461,6 +467,7 @@ BA_ "GenSigStartValue" SG_ 2365562433 Voltage_command 2400.0;
461467
BA_ "GenSigStartValue" SG_ 2365562433 Frequency_command 500.0;
462468
BA_ "GenSigStartValue" SG_ 2365573879 RealPower_measured 0.0;
463469
BA_ "GenSigStartValue" SG_ 2365573879 ReactivePower_measured 0.0;
470+
BA_ "GenSigStartValue" SG_ 2634001344 RealPower_measured 0.0;
464471
BA_ "GenSigStartValue" SG_ 2365573879 RealPower_measured 0.0;
465472
BA_ "GenSigStartValue" SG_ 2365573879 ReactivePower_measured 0.0;
466473
BA_ "GenSigStartValue" SG_ 2566898935 RealPower_echo 0.0;

test/reference/from_sym/test.dbf

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
[PROTOCOL] CAN
66

77
[BUSMASTER_VERSION] [1.7.2]
8-
[NUMBER_OF_MESSAGES] 26
8+
[NUMBER_OF_MESSAGES] 28
99
[START_MSG] CommandModeControl,16755521,8,11,1,X,Vector__XXX
1010
[START_SIGNALS] Enable_command,2,1,0,U,1.0,0.0,0,0.0,1.0,,,
1111
[VALUE_DESCRIPTION] "Disable",0
@@ -207,6 +207,13 @@
207207
[START_SIGNALS] ReactivePower_measured,32,8,0,S,2147483647.0,-2147483648.0,0,0.0,1.0,VA,,
208208
[END_MSG]
209209

210+
[START_MSG] justString,486517952,8,0,1,X,Vector__XXX
211+
[END_MSG]
212+
213+
[START_MSG] stringAndOther,486517696,8,1,1,X,Vector__XXX
214+
[START_SIGNALS] RealPower_measured,32,4,0,S,2147483647.0,-2147483648.0,0,0.0,1.0,W,,
215+
[END_MSG]
216+
210217
[START_MSG] StatusMeasuredPower,218090231,8,2,1,X,Vector__XXX
211218
[START_SIGNALS] RealPower_measured,32,4,0,S,2147483647.0,-2147483648.0,0,0.0,1.0,W,,
212219
[START_SIGNALS] ReactivePower_measured,32,8,0,S,2147483647.0,-2147483648.0,0,0.0,1.0,VA,,
@@ -559,6 +566,8 @@
559566
218078273 S "Sets the desired real (P) and reactive (Q) power levels for the module to follow while in the GRID FOLLOWING mode.";
560567
218078785 S "Sets the desired voltage and frequency for the module to produce while in the GRID FORMING mode. In addition, while in the READY and GRID FOLLOWING modes, this message is used to set the nominal voltage levels for detection of acceptable AC line voltage.";
561568
218090231 S "Returns the actual measured power.";
569+
486517952 S "";
570+
486517696 S "";
562571
218090231 S "Returns the actual measured power.";
563572
419415287 S "Echoes the commanded power (P&Q) as received in CommandPQ.";
564573
218088439 S "Bits representing the status of the power module.";
@@ -640,6 +649,7 @@
640649
218078785 S Frequency_command "Desired output frequency while in grid forming mode.";
641650
218090231 S RealPower_measured "Measured real power of master unit.";
642651
218090231 S ReactivePower_measured "Measured reactive power of master unit.";
652+
486517696 S RealPower_measured "Measured real power.";
643653
218090231 S RealPower_measured "Measured real power.";
644654
218090231 S ReactivePower_measured "Measured reactive power.";
645655
419415287 S RealPower_echo "Echoed real power command.";
@@ -826,6 +836,7 @@
826836
218078785,S,Frequency_command,"GenSigStartValue","500.0"
827837
218090231,S,RealPower_measured,"GenSigStartValue","0.0"
828838
218090231,S,ReactivePower_measured,"GenSigStartValue","0.0"
839+
486517696,S,RealPower_measured,"GenSigStartValue","0.0"
829840
218090231,S,RealPower_measured,"GenSigStartValue","0.0"
830841
218090231,S,ReactivePower_measured,"GenSigStartValue","0.0"
831842
419415287,S,RealPower_echo,"GenSigStartValue","0.0"

test/reference/from_sym/test.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,28 @@
619619
}
620620
]
621621
},
622+
{
623+
"id": 486517952,
624+
"is_extended_frame": true,
625+
"name": "justString",
626+
"signals": []
627+
},
628+
{
629+
"id": 486517696,
630+
"is_extended_frame": true,
631+
"name": "stringAndOther",
632+
"signals": [
633+
{
634+
"bit_length": 32,
635+
"factor": 1.0,
636+
"is_big_endian": true,
637+
"is_signed": true,
638+
"name": "RealPower_measured",
639+
"offset": 0.0,
640+
"start_bit": 24
641+
}
642+
]
643+
},
622644
{
623645
"id": 218090231,
624646
"is_extended_frame": true,

test/reference/from_sym/test.kcd

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,19 @@
501501
<LabelSet/>
502502
</Signal>
503503
</Message>
504+
<Message id="0x1CFFACC0" length="8" name="justString" format="extended">
505+
<Producer/>
506+
<Notes></Notes>
507+
</Message>
508+
<Message id="0x1CFFABC0" length="8" name="stringAndOther" format="extended">
509+
<Producer/>
510+
<Notes></Notes>
511+
<Signal name="RealPower_measured" offset="24" length="32" endianess="little">
512+
<Notes>Measured real power.</Notes>
513+
<Value type="signed" min="-2147483648.0" max="2147483647.0" unit="W"/>
514+
<LabelSet/>
515+
</Signal>
516+
</Message>
504517
<Message id="0xCFFCAF7" length="8" name="StatusMeasuredPower" format="extended" triggered="true" interval="100">
505518
<Producer/>
506519
<Notes>Returns the actual measured power.</Notes>

test/reference/from_sym/test.xls

0 Bytes
Binary file not shown.

test/reference/from_sym/test.yaml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,6 +1158,44 @@ _fl: !!python/object:canmatrix.canmatrix.FrameList
11581158
_startbit: 56
11591159
_unit: VA
11601160
_values: {}
1161+
- !!python/object:canmatrix.canmatrix.Frame
1162+
_Id: 486517952
1163+
_SignalGroups: []
1164+
_Size: 8
1165+
_Transmitter: []
1166+
_attributes: {}
1167+
_comment: ''
1168+
_extended: 1
1169+
_name: justString
1170+
_receiver: []
1171+
_signals: []
1172+
- !!python/object:canmatrix.canmatrix.Frame
1173+
_Id: 486517696
1174+
_SignalGroups: []
1175+
_Size: 8
1176+
_Transmitter: []
1177+
_attributes: {}
1178+
_comment: ''
1179+
_extended: 1
1180+
_name: stringAndOther
1181+
_receiver: []
1182+
_signals:
1183+
- !!python/object:canmatrix.canmatrix.Signal
1184+
_attributes: {GenSigStartValue: '0.0'}
1185+
_comment: Measured real power.
1186+
_factor: 1.0
1187+
_is_little_endian: 0
1188+
_is_signed: true
1189+
_max: 2147483647.0
1190+
_min: -2147483648.0
1191+
_multiplex: null
1192+
_name: RealPower_measured
1193+
_offset: 0.0
1194+
_receiver: []
1195+
_signalsize: 32
1196+
_startbit: 24
1197+
_unit: W
1198+
_values: {}
11611199
- !!python/object:canmatrix.canmatrix.Frame
11621200
_Id: 218090231
11631201
_SignalGroups: []

test/test.sym

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,19 @@ Var=ReactivePower_measured signed 32,32 -m /u:VA // Measured reactive power of m
180180

181181
{SENDRECEIVE}
182182

183+
[justString]
184+
ID=1CFFACC0h
185+
Type=Extended
186+
DLC=8
187+
Var=rev string 0,64 -m /d:"ICUx-03i"
188+
189+
[stringAndOther]
190+
ID=1CFFABC0h
191+
Type=Extended
192+
DLC=8
193+
Var=rev string 0,64 -m /d:"ICUx-03i"
194+
Var=RealPower_measured signed 0,32 -m /u:W // Measured real power.
195+
183196
[StatusMeasuredPower]
184197
ID=0CFFCAF7h // Returns the actual measured power.
185198
Type=Extended

0 commit comments

Comments
 (0)