--- a/branches/h-hermsen/mqttsparkplugb/SparkplugB/Function Blocks/FB_Edge_Of_Network_Node/FB_Edge_Of_Network_Node/svnobj
+++ b/branches/h-hermsen/mqttsparkplugb/SparkplugB/Function Blocks/FB_Edge_Of_Network_Node/FB_Edge_Of_Network_Node/svnobj
@@ -1,5 +1,5 @@
-Gx_l¼×!0…jüo÷«=¯+Ļ5'bSystem.StringL{6f9dac99-8de1-4efc-8465-68ac443b7d08}SpecialFuncL{0db3d7bb-cde0-4416-9a7b-ce49a0124323}NoneImplementationL{3b83b776-fb25-43b8-99f2-3c507c9143fc}TextDocument	L{f3878285-8e4f-490b-bb1b-9acbb7eb04db}
-TextLinesL{a5de0b0b-1cb5-4913-ac21-9d70293ec00d}Id
longTagText// Components_MQTT();b_SparkplugB( AllmetricsList := _AllMetricsList );&_TryConnectTimer();PNumberOfDevices := _DeviceList.ListSize;”// MQTT Client errors? => the statemachine is pushed to EoNStateType.ERROR€_OnMQTT_Error(CLK := _MQTT.ClientError(eError => _MQTT_eError));.IF _OnMQTT_Error.Q THEN.    // Goto Error StateH    _EoNState := EoNStateType.ERROR;END_IFš// MQTT Connected? => the statemachine is pushed to EoNStateType.INITIALISING@_OnEoNConnect( CLK := Connect );.IF _OnEoNConnect.Q THENJ    // Start state machine (init EoN) F    _EoNState := EoNStateType.INIT;!END_IF;"ž// MQTT DisConnected? => the statemachine is pushed to EoNStateType.EXITING    #N_OnEoNDisConnect( CLK := NOT Connect );$4IF _OnEoNDisConnect.Q THEN%V    // Stop state machine in proper fashion&^    _EoNState := EoNStateType.DISCONNECTING;   '"CASE _EoNState OF(8    EoNStateType.ERROR :    )Ö                            // ERROR => the statemachine is pushed into this state by ANY MQTT Client Error*`                            // Reset the client;+\                            IF NOT _Reset THEN,p                                _Reset := _MQTT.Reset();-@                            ELSE.¼                                // No MQTT Client ERROR  AND Connected => we goto RECONNECTING/Ž                                _EoNState := EoNStateType.RECONNECTING;0`                                _Reset := FALSE;1D                            END_IF2@    EoNStateType.RECONNECTING : 3†                            _TryConnectTimer.Enable := TRUE;							4j	                        IF _TryConnectTimer.Out THEN5¶                                // enable MQTT Client to broker                            6x                                _Connect := _MQTT.Connect();7¼                                IF (TIME_TO_UDINT(_TryConnectTimer.OutTimeRemaining - T#1MS) MOD 15000) <= 2 * _taskCycleTime THEN // still needs some refinement                                                             8r                                    IF NOT _Already1 THEN9˜                                        WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN Connecting ... %s s remaining', UDINT_TO_STRING(TO_UDINT(_TryConnectTimer.OutTimeRemaining) / 1000));:									END_IF;:									_Already1 := TRUE;  <								ELSE=r                                    _Already1 := FALSE;  >								END_IF?´                                //  check connection state and goto next step if connected@Ö                                IF NOT _MQTT.IsConnecting() AND _MQTT.IsConnected() THEN                   Aª                                    // Resubscribe again which will trigger a ReBirthBx                                    _MQTT.UnsubscribeDCMD();Cx                                    _SubscribeDCMD := FALSE;Dx                                    _MQTT.UnsubscribeNCMD();Ex                                    _SubscribeNCMD := FALSE;Fš                                    _EoNState := EoNStateType.SUBSCRIBE_NCMD;GŒ                                    _TryConnectTimer.Enable := FALSE; HP                                END_IF; IT								_Disconnect := _MQTT.Disconnect();JÄ                                IF (TIME_TO_UDINT(_TryConnectTimer.LockTimeRemaining - T#1MS) MOD 15000) <= 2 * _taskCycleTime THEN // still needs some refinementKr                                    IF NOT _Already2 THENLŠ                                        WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN Next Attempt in: %s s', UDINT_TO_STRING(TO_UDINT(_TryConnectTimer.LockTimeRemaining) / 1000));M 									END_IF;Nl                                    _Already2 := TRUE;On                                    _Already2 := FALSE;PZ								END_IF                               Q							END_IF;RÚ    EoNStateType.OFFLINE :  // OFFLINE => the statemachine idles and gets pushed to INIT via 'Connect = TRUE'Sª                            _CurConnectionState := SparkplugSessionStateType.OFFLINE;T                 U.    EoNStateType.INIT :Vh                            IF NOT _Initialised THENW²                                // Initialises the MQTT Connection and update LW&T NDEATHXz                                _Initialised := Initialise();YŠ                                _EoNState := EoNStateType.CONNECTING;Z							END_IF[8                            \:    EoNStateType.CONNECTING :]„                                _Connect := _MQTT.Connect();					 ^r                                    IF NOT _Already3 THEN_:									_Already3 := TRUE;  `r                                    _Already3 := FALSE;  aD                            ELSE  b„                                _Disconnect := _MQTT.Disconnect();cr                                    IF NOT _Already4 THENdl                                    _Already4 := TRUE;en                                    _Already4 := FALSE;f								END_IF;gD                            						h>	EoNStateType.SUBSCRIBE_NCMD : i`                            // Subscribe to NCMDjl                            IF NOT _SubscribeNCMD THENkŠ                                 _SubscribeNCMD := SubscribeNCMD();  l							ELSEmd								_EoNState := EoNStateType.SUBSCRIBE_DCMD; n							o>	EoNStateType.SUBSCRIBE_DCMD : p`                            // Subscribe to DCMDql                            IF NOT _SubscribeDCMD THENr~                            	_SubscribeDCMD := SubscribeDCMD();s							ELSE tb								_EoNState := EoNStateType.PUBLISH_NBIRTH;u>	EoNStateType.PUBLISH_NBIRTH : vb                            // Publish Node Birthwv                            IF NOT _NodeBirthPublished THENxZ								// should contain 0 after first birthyê								_NodeBirthPublished := PublishNBIRTH( LWT_BdSeq := _NDEATH.Value, AllMetricsList := THIS^._AllMetricsList ); zV								_EoNState := EoNStateType.ONLINE;  {8    EoNStateType.ONLINE :   |¨                            _CurConnectionState := SparkplugSessionStateType.ONLINE;}l                            // NCMD Messages received?~~                            IF _MQTT.NCMDMessageReceived() THEN                                // Just pass the Ref, no copying of data€”								_RecvMesg REF= _MQTT.GetNCMDMessage( MessageTopic => _RecvTopic );¾								onNCMDMessage( pTopic := ADR(_RecvTopic), pMessage := _RecvMesg, Rebirth => _Rebirth );‚0								IF _Rebirth THENƒÌ									// Well, now we need to rebirth, which means we need to issue a new Death Certificate as well„b									_EoNState := EoNStateType.DISCONNECTING;…4								_Rebirth := FALSE;†:                             ‡l                            // DCMD Messages received?ˆ~                            IF _MQTT.DCMDMessageReceived() THEN‰€								//This will need to be fixed, once DCMDs are implementedŠ˜								//_RecvMesg REF= _MQTT.GetDCMDMessage( MessageTopic => _RecvTopic );‹ž								onDCMDMessage( pTopic := ADR(_RecvTopic), pMessage := ADR(_RecvMesg) );ŒN                                       Ò                            // Detect if any EoN values have changed and add them to the Encoder directlyŽ							//  If we have sent recently (_PublishBlocked), then do not checkd							//  If we are rebirthing, then do not check˜                            IF (NOT _PublishBlocked) AND (NOT _Rebirth) THEN‘X								// Set Prepare NDATA Payload Encoder’z								IF NOT(_NDATAEncoderPrepared) OR _ChangeDetected THEN“¨									_NDATAEncoderPrepared := PrepareNDATA( AllMetricsList := _AllMetricsList );”.								END_IF;        •								–¢								// Detect EoN data changes and feed them to the encoder for NDATA payload—²								_ChangeError := _SparkplugB.FindChanges(arSparkplugBoolean:= arSparkplugBoolean, ˜~																			 arSparkplugDateTime:= arSparkplugDateTime, ™r																			 arSparkplugFloat:= arSparkplugFloat, šv																			 arSparkplugDouble:= arSparkplugDouble, ›n																			 arSparkplugInt8:= arSparkplugInt8, œr																			 arSparkplugInt16:= arSparkplugInt16, r																			 arSparkplugInt32:= arSparkplugInt32, žr																			 arSparkplugInt64:= arSparkplugInt64, Ÿr																			 arSparkplugUInt8:= arSparkplugUInt8,  v																			 arSparkplugUInt16:= arSparkplugUInt16, ¡v																			 arSparkplugUInt32:= arSparkplugUInt32, ¢v																			 arSparkplugUInt64:= arSparkplugUInt64, £n																			 arSparkplugUUID:= arSparkplugUUID, ¤n																			 arSparkplugText:= arSparkplugText, ¥v																			 arSparkplugString:= arSparkplugString, ¦l																			 AllMetricsList:= _AllMetricsList, §n																			 ChangeDetected => _ChangeDetected, ¨j																			 ErrorDetected => _ErrorDetected, ©p																			 NumberOfChanges => _CurrentChanges);ª€								IF _ChangeError <> ERROR.NO_ERROR OR _ErrorDetected THEN«„									WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN FindChanges Error: %s', TO_STRING(_ChangeError) );        ¬									 ­r								IF _NDATAEncoderPrepared AND _ChangeDetected THEN®									WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN FindChanges Detected: %s', TO_STRING(_CurrentChanges) );        ¯¸									_PublishNDATAError := PublishNDATA( AllMetricsList := _AllMetricsList );           °–							_PublishBlockTimerEnable := _ChangeDetected AND NOT _PublishBlocked;±r							_PublishBlockTimer(IN := _PublishBlockTimerEnable,²`											   PT := UINT_TO_TIME(publishPeriod),³B												Q => _PublishBlocked,´^											   ET => _PublishBlockTimerElapsed);µB                                 ¶@    EoNStateType.DISCONNECTING :·¾                            // To Exit Cleanly we have to do the following in this exact order:¸                             //      1) DISABLE_PUBLISHER => Stop the publisher  ¹Ì                            //      2) UNSUBSCRIBE_DCMD => Unsubscribe from DCMD while still connectedºÌ                            //      3) UNSUBSCRIBE_NCMD => Unsubscribe from NCMD while still connected»¦                            //      4) DISCONNECT_MQTT =>Disconnect the MQTT Client¼\                            //      5) EXITING½n                            //          REBIRH => INIT ¾°                            //          OTHERWISE => OFFLINE                            ¿ú                            WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN Disconnection Requested %s',WAIT);À                            _EoNState := EoNStateType.DISABLE_PUBLISHER;ÁJ    EoNStateType.DISABLE_PUBLISHER :	²                            IF NOT _DisablePublisher THEN                                ÃÄ                               _DisablePublisher := _MQTT.DisablePublisher(); // Will become FALSEÄ                                 // publisher is now DISABLED                    Åö                                WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN Publisher stopped %s',WAIT);ÆÖ                                _EoNState := EoNStateType.UNSUBSCRIBE_DCMD;                                ÇF    EoNStateType.UNSUBSCRIBE_DCMD :Èp                            IF NOT _UnSubscribeDCMD THENɘ                                _UnSubscribeDCMD := _MQTT.UnSubscribeDCMD();Ê€                            ELSE                                Ë€                                WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN Unsubscribed from DCMD %s',WAIT);Ì–                                _EoNState := EoNStateType.UNSUBSCRIBE_NCMD;ÍF    EoNStateType.UNSUBSCRIBE_NCMD :Îp                            IF NOT _UnsubscribeNCMD THENϘ                                _UnsubscribeNCMD := _MQTT.UnSubscribeNCMD();Ѐ                                WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN Unsubscribed from NCMD %s',WAIT);Ñ”                                _EoNState := EoNStateType.DISCONNECT_MQTT;Ò    Ó|    EoNStateType.DISCONNECT_MQTT :                            Ôf                            IF NOT _Disconnect THENÕ„                                WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN MQTT Client Disconnected %s',WAIT);Ö„                                _EoNState := EoNStateType.EXITING;×6    EoNStateType.EXITING :	ØX                            // Un-initialiseÙ^                            IF NOT Connect THENÚz                                // Local Disconnect Initiatedې                                _EoNState := EoNStateType.OFFLINE;      Ü|                                // Rebirth or any other cause ݬ                                _EoNState := EoNStateType.INIT;                       ÞF                            // INITßd                            _Initialised := FALSE;àX                            // CONNECT_MQTT	á\                            _Connect := FALSE;âZ                            // PUBLISH_NBIRTHãr                            _NodeBirthPublished := FALSE;äZ                            // SUBSCRIBE_NCMDåh                            _SubscribeNCMD := FALSE;æZ                            // SUBSCRIBE_DCMDçh                            _SubscribeDCMD := FALSE;èJ                            // ONLINEéŒ                            _PublishBlocked := TRUE; // Should be TRUEêv                            _NDATAEncoderPrepared := FALSE;ë\                            _Rebirth := FALSE;ìj                            _ChangeDetected := FALSE;í\                            _ChangeError := 0;îh                            _ErrorDetected := FALSE;ïp                            _PublishNDATAError := FALSE;ðZ                            // DISCONNECTING	ñn                            _DisablePublisher := FALSE;ò^                            // UNSUBSCRIBE_DCMDól                            _UnSubscribeDCMD := FALSE;ô^                            // UNSUBSCRIBE_NCMDõl                            _UnsubscribeNCMD := FALSE;ö\                            // DISCONNECT_MQTT÷b                            _Disconnect := FALSE;øH                            // ERRORùX                            _Reset := FALSE;úELSEûL    _EoNState := EoNStateType.OFFLINE;üEND_CASEý&// Update EoN StateþfIF _CurConnectionState <> _PrevConnectionState THENÿö    WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN Connection State: %s', TO_STRING(_CurConnectionState) );€X_PrevConnectionState := _CurConnectionState;NConnectionState := _CurConnectionState;‚ // EoN DiagnosisƒDiag();„Interface…L{a9ed5b7e-75c5-4651-af16-d2c27e98cb94}†(*‡0    Edge of Network Nodeˆ˜    Binds together FB_MQTT_PubSub and FB_Sparkplug via a state machine in ST‰*)Š¢FUNCTION_BLOCK PUBLIC FB_Edge_Of_Network_Node IMPLEMENTS ISparkplugDeviceProtocol‹VAR_INPUTŒt    ServerUrl  : STRING;       // eg:'test.mosquitto.org';T    ServerPort : UINT := 1883; // eg: 1883Ž|    KeepAlive  : UINT := 60;   // eg: 60 (Value is in seconds)V    (* Persistent Session (FALSE = DEFAULT)°        * The client must get all messages FROM a certain topic, even IF it is offline. ‘ò        * You want the broker to queue the messages for the client and deliver them as soon as the client is back online.’X        * The client has limited resources. “ˆ        * You want the broker to store the subscription information of the client and restore the interrupted communication quickly.”È        * The client needs to reNumberOfMetricse all QoS 1 and 2 publish messages after a reconnect.•        –8        Clean session (TRUE)—à        * The client needs only to publish messages to topics, the client does not need to subscribe to topics. ˜Þ        * You don t want the broker to store session information or retry transmission of QoS 1 and 2 messages.™–        * The client does not need to get messages that it misses offline. š    *)›J    CleanSession  : BOOL    := FALSE;œ¨    Username      : WSTRING := "";           // specify a username if any (optional)À    Password      : WSTRING := "";           // specify the password for the username (optional)ž¼    UseTLS        : BOOL;                    // Enables usage of the TLS encryption (optional)Ÿö    hCert         : SysTypes.RTS_IEC_HANDLE; // Handle to the client certificate (optional) and only used if UseTLS is TRUE Œ    GroupId       : WSTRING;                 // eg: "SparkplugBDevice"¡t    NodeName      : WSTRING;                 // eg: "EoN1"¢ˆ    DeviceName    : WSTRING;                 // eg: "EmulatedDevice"£¦    publishPeriod : UINT;                    // eg: 5000 (Value is in milliseconds)¤END_VAR¥VAR_OUTPUT¦`    ConnectionState : SparkplugSessionStateType;§p    itfDevices      : ISparkplugDeviceProtocol := THIS^;¨8    NumberOfDevices : UDINT;©VAR_IN_OUTªt    arSparkplugBoolean  : ARRAY[*] OF FB_SparkplugBoolean;«v    arSparkplugDateTime : ARRAY[*] OF FB_SparkplugDateTime;¬p    arSparkplugFloat    : ARRAY[*] OF FB_SparkplugFloat;­r    arSparkplugDouble   : ARRAY[*] OF FB_SparkplugDouble;®n    arSparkplugInt8     : ARRAY[*] OF FB_SparkplugInt8;¯p    arSparkplugInt16    : ARRAY[*] OF FB_SparkplugInt16;°p    arSparkplugInt32    : ARRAY[*] OF FB_SparkplugInt32;±p    arSparkplugInt64    : ARRAY[*] OF FB_SparkplugInt64;²p    arSparkplugUInt8    : ARRAY[*] OF FB_SparkplugUInt8;³r    arSparkplugUInt16   : ARRAY[*] OF FB_SparkplugUInt16;´r    arSparkplugUInt32   : ARRAY[*] OF FB_SparkplugUInt32;µr    arSparkplugUInt64   : ARRAY[*] OF FB_SparkplugUInt64;¶n    arSparkplugUUID     : ARRAY[*] OF FB_SparkplugUUID;·n    arSparkplugText     : ARRAY[*] OF FB_SparkplugText;¸r    arSparkplugString   : ARRAY[*] OF FB_SparkplugString;¹VARº’    Connect : BOOL := TRUE; // TRUE: Connects EoN using the configured settings, FALSE: Disconnects EoN from server if it was connected  »l    (* Corrected GroupId, contains no illegal chars *)¼.    _GroupId : WSTRING;½p    (* Corrected _NodeName, contains no illegal chars *)¾0    _NodeName : WSTRING;¿t    (* Corrected _DeviceName, contains no illegal chars *)ÀP    _DeviceName               : WSTRING;ÁP    _MQTT                     : FB_MQTT;Â`    _MQTT_eError              : MQTT.MQTT_ERROR;î    _SparkplugB               : FB_SparkplugBSimple;        // Handles SparkPlugB Stuffĸ    _DeviceList               : List;                       // Handles all connected DevicesÅÊ    _TryConnectTimer          : FB_ExponentialBackOffTimer; // Handles the Exponential Backoff timingÆN    _OnMQTT_Error             : R_TRIG;ÇN    _OnMQTT_NoErr             : F_TRIG;ÈN    _OnEoNConnect             : R_TRIG;ÉN    _OnEoNDisConnect          : R_TRIG;ÊŠ    _EoNState                 : EoNStateType := EoNStateType.OFFLINE;Ët    _AllMetricsList           : LIST; // Complete List    Ìn    _ChangeList               : LIST; // The Send list;ÍJ    _Initialise               : BOOL;ÎJ    _Connect                  : BOOL;ÏJ    _Disconnect               : BOOL;ÐJ    _Initialised              : BOOL;ÑJ    _Reset                    : BOOL;ÒJ    _SubscribeNCMD            : BOOL;ÓJ    _UnSubscribeNCMD          : BOOL;ÔJ    _SubscribeDCMD            : BOOL;ÕJ    _UnSubscribeDCMD          : BOOL;ÖJ    _NodeBirthPublished       : BOOL;×J    _PublishNodeDataStart     : BOOL;ØJ    _DisablePublisher         : BOOL;Ù˜    _LastWillTopic            : WSTRING(Constants.supported_string_lengths);Ú¶    _NDEATH                   : FB_SparkplugUInt64;    // contains the current NDEATH BDSeqÛÆ    _NDEATHPayload            : ARRAY[0..255] OF BYTE; // what is the maximum size of this payload?ÜL    _NDEATHPayloadSize        : UDINT;݈    _LastWillQos              : MQTT.MQTT_QOS := MQTT.MQTT_QOS.QoS0;Þn    _LastWillRetain           : BOOL          := FALSE;ßÈ    _NBIRTH                   : FB_SparkplugUInt64;      // contains the current raw NBIRTH sequenceà®    _Blob                     : ARRAY[0..65535] OF BYTE; // buffer for encoded messagesá²    _BlobSize                 : UDINT;                   // current encoded message size âF    _PublishBlockTimer        : TP;ãJ    _PublishBlockTimerEnable  : BOOL;äJ    _PublishBlockTimerElapsed : TIME;å‚    _PublishBlocked           : BOOL; // Status of the BlockTimeræ\    _NDATAEncoderPrepared     : BOOL := FALSE;çJ    _PublishNDATAError        : BOOL;èJ    _ErrorDetected            : BOOL;éL    _ChangeError              : ERROR;êª    _ChangeDetected           : BOOL;  // At least 1 Signal change has been detected;ëÌ    _CurrentChanges           : UDINT; // Number of detected changes, each changes reflects 1 Signal  ìl    _MessageType              : SparkplugMessageTypes;íJ    _Rebirth                  : BOOL;îŠ    _RecvMesg                 : REFERENCE TO FB_PayloadSimpleDecoder;ï˜    _RecvTopic                : WSTRING(Constants.supported_string_lengths);ð¾    _CurConnectionState       : SparkplugSessionStateType := SparkplugSessionStateType.OFFLINE;ñ¼    _PrevConnectionState      : SparkplugSessionStateType := SparkplugSessionStateType.ONLINE;òN    _Diag                     : STRING;óŽ    _taskCycleTime            : DWORD; //ms, so equivelant also of TIMEôJ    _Already1                 : BOOL;õJ    _Already2                 : BOOL;öJ    _Already3                 : BOOL;÷J    _Already4                 : BOOL;øVAR CONSTANTù    // ASCIIú6    WAIT : STRING := '...';û*    // UTF-8 encodingüP    FW_SLASH           : WSTRING := "/";ý^    SPARKPLUGB         : WSTRING := "spBv1.0/";þR    TOPIC_FILTER_POUND : WSTRING := "/#";ÿR    TOPIC_FILTER_PLUS  : WSTRING := "/+";€^    NODE_DEATH_TOPIC   : WSTRING := "/NDEATH/";^    NODE_BIRTH_TOPIC   : WSTRING := "/NBIRTH/";‚\    NODE_DATA_TOPIC    : WSTRING := "/NDATA/";ƒ^    DEVICE_DEATH_TOPIC : WSTRING := "/DDEATH/";„^    DEVICE_BIRTH_TOPIC : WSTRING := "/DBIRTH/";…\    DEVICE_DATA_TOPIC  : WSTRING := "/DDATA/";†Z    NCMD               : WSTRING := "/NCMD/";‡Z    DCMD               : WSTRING := "/DCMD/";ˆP    POUND              : WSTRING := "#";‰P    PLUS               : WSTRING := "+";ŠP    UNDERSCORE         : WSTRING := "_";‹"UniqueIdGeneratorŒ9175POULevelŽL{8e575c5b-1d37-49c6-941b-5c0ec7874787}Standard ChildObjectGuids‘8System.Collections.ArrayList’,AddAttributeSubsequent“boolÐÐ-ÐÐ	E
+Gx_lÓ×!0…jüoõ«¿\¶+¡"âêSystem.StringL{6f9dac99-8de1-4efc-8465-68ac443b7d08}SpecialFuncL{0db3d7bb-cde0-4416-9a7b-ce49a0124323}NoneImplementationL{3b83b776-fb25-43b8-99f2-3c507c9143fc}TextDocument	L{f3878285-8e4f-490b-bb1b-9acbb7eb04db}
+TextLinesL{a5de0b0b-1cb5-4913-ac21-9d70293ec00d}Id
longTagText// Components_MQTT();b_SparkplugB( AllmetricsList := _AllMetricsList );&_TryConnectTimer();PNumberOfDevices := _DeviceList.ListSize;”// MQTT Client errors? => the statemachine is pushed to EoNStateType.ERROR€_OnMQTT_Error(CLK := _MQTT.ClientError(eError => _MQTT_eError));.IF _OnMQTT_Error.Q THEN.    // Goto Error StateH    _EoNState := EoNStateType.ERROR;END_IFš// MQTT Connected? => the statemachine is pushed to EoNStateType.INITIALISING@_OnEoNConnect( CLK := Connect );.IF _OnEoNConnect.Q THENJ    // Start state machine (init EoN) F    _EoNState := EoNStateType.INIT;!END_IF;"ž// MQTT DisConnected? => the statemachine is pushed to EoNStateType.EXITING    #N_OnEoNDisConnect( CLK := NOT Connect );$4IF _OnEoNDisConnect.Q THEN%V    // Stop state machine in proper fashion&^    _EoNState := EoNStateType.DISCONNECTING;   '"CASE _EoNState OF(8    EoNStateType.ERROR :    )Ö                            // ERROR => the statemachine is pushed into this state by ANY MQTT Client Error*`                            // Reset the client;+\                            IF NOT _Reset THEN,p                                _Reset := _MQTT.Reset();-@                            ELSE.¼                                // No MQTT Client ERROR  AND Connected => we goto RECONNECTING/Ž                                _EoNState := EoNStateType.RECONNECTING;0`                                _Reset := FALSE;1D                            END_IF2@    EoNStateType.RECONNECTING : 3†                            _TryConnectTimer.Enable := TRUE;							4j	                        IF _TryConnectTimer.Out THEN5¶                                // enable MQTT Client to broker                            6x                                _Connect := _MQTT.Connect();7¼                                IF (TIME_TO_UDINT(_TryConnectTimer.OutTimeRemaining - T#1MS) MOD 15000) <= 2 * _taskCycleTime THEN // still needs some refinement                                                             8r                                    IF NOT _Already1 THEN9˜                                        WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN Connecting ... %s s remaining', UDINT_TO_STRING(TO_UDINT(_TryConnectTimer.OutTimeRemaining) / 1000));:									END_IF;:									_Already1 := TRUE;  <								ELSE=r                                    _Already1 := FALSE;  >								END_IF?´                                //  check connection state and goto next step if connected@Ö                                IF NOT _MQTT.IsConnecting() AND _MQTT.IsConnected() THEN                   Aª                                    // Resubscribe again which will trigger a ReBirthBx                                    _MQTT.UnsubscribeDCMD();Cx                                    _SubscribeDCMD := FALSE;Dx                                    _MQTT.UnsubscribeNCMD();Ex                                    _SubscribeNCMD := FALSE;Fš                                    _EoNState := EoNStateType.SUBSCRIBE_NCMD;GŒ                                    _TryConnectTimer.Enable := FALSE; HP                                END_IF; IT								_Disconnect := _MQTT.Disconnect();JÄ                                IF (TIME_TO_UDINT(_TryConnectTimer.LockTimeRemaining - T#1MS) MOD 15000) <= 2 * _taskCycleTime THEN // still needs some refinementKr                                    IF NOT _Already2 THENLŠ                                        WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN Next Attempt in: %s s', UDINT_TO_STRING(TO_UDINT(_TryConnectTimer.LockTimeRemaining) / 1000));M 									END_IF;Nl                                    _Already2 := TRUE;On                                    _Already2 := FALSE;PZ								END_IF                               Q							END_IF;RÚ    EoNStateType.OFFLINE :  // OFFLINE => the statemachine idles and gets pushed to INIT via 'Connect = TRUE'Sª                            _CurConnectionState := SparkplugSessionStateType.OFFLINE;T                 U.    EoNStateType.INIT :Vh                            IF NOT _Initialised THENW²                                // Initialises the MQTT Connection and update LW&T NDEATHXz                                _Initialised := Initialise();YŠ                                _EoNState := EoNStateType.CONNECTING;Z							END_IF[8                            \:    EoNStateType.CONNECTING :]„                                _Connect := _MQTT.Connect();					 ^r                                    IF NOT _Already3 THEN_:									_Already3 := TRUE;  `r                                    _Already3 := FALSE;  aD                            ELSE  b„                                _Disconnect := _MQTT.Disconnect();cr                                    IF NOT _Already4 THENdl                                    _Already4 := TRUE;en                                    _Already4 := FALSE;f								END_IF;gD                            						h>	EoNStateType.SUBSCRIBE_NCMD : i`                            // Subscribe to NCMDjl                            IF NOT _SubscribeNCMD THENkŠ                                 _SubscribeNCMD := SubscribeNCMD();  l							ELSEmd								_EoNState := EoNStateType.SUBSCRIBE_DCMD; n							o>	EoNStateType.SUBSCRIBE_DCMD : p`                            // Subscribe to DCMDql                            IF NOT _SubscribeDCMD THENr~                            	_SubscribeDCMD := SubscribeDCMD();s							ELSE tb								_EoNState := EoNStateType.PUBLISH_NBIRTH;u>	EoNStateType.PUBLISH_NBIRTH : vb                            // Publish Node Birthwv                            IF NOT _NodeBirthPublished THENxZ								// should contain 0 after first birthyê								_NodeBirthPublished := PublishNBIRTH( LWT_BdSeq := _NDEATH.Value, AllMetricsList := THIS^._AllMetricsList ); zV								_EoNState := EoNStateType.ONLINE;  {8    EoNStateType.ONLINE :   |¨                            _CurConnectionState := SparkplugSessionStateType.ONLINE;}l                            // NCMD Messages received?~~                            IF _MQTT.NCMDMessageReceived() THEN                                // Just pass the Ref, no copying of data€”								_RecvMesg REF= _MQTT.GetNCMDMessage( MessageTopic => _RecvTopic );¾								onNCMDMessage( pTopic := ADR(_RecvTopic), pMessage := _RecvMesg, Rebirth => _Rebirth );‚0								IF _Rebirth THENƒÌ									// Well, now we need to rebirth, which means we need to issue a new Death Certificate as well„b									_EoNState := EoNStateType.DISCONNECTING;…4								_Rebirth := FALSE;†:                             ‡l                            // DCMD Messages received?ˆ~                            IF _MQTT.DCMDMessageReceived() THEN‰€								//This will need to be fixed, once DCMDs are implementedŠ˜								//_RecvMesg REF= _MQTT.GetDCMDMessage( MessageTopic => _RecvTopic );‹ž								onDCMDMessage( pTopic := ADR(_RecvTopic), pMessage := ADR(_RecvMesg) );ŒN                                       Ò                            // Detect if any EoN values have changed and add them to the Encoder directlyŽ							//  If we have sent recently (_PublishBlocked), then do not checkd							//  If we are rebirthing, then do not check˜                            IF (NOT _PublishBlocked) AND (NOT _Rebirth) THEN‘X								// Set Prepare NDATA Payload Encoder’z								IF NOT(_NDATAEncoderPrepared) OR _ChangeDetected THEN“¨									_NDATAEncoderPrepared := PrepareNDATA( AllMetricsList := _AllMetricsList );”.								END_IF;        •								–¢								// Detect EoN data changes and feed them to the encoder for NDATA payload—²								_ChangeError := _SparkplugB.FindChanges(arSparkplugBoolean:= arSparkplugBoolean, ˜~																			 arSparkplugDateTime:= arSparkplugDateTime, ™r																			 arSparkplugFloat:= arSparkplugFloat, šv																			 arSparkplugDouble:= arSparkplugDouble, ›n																			 arSparkplugInt8:= arSparkplugInt8, œr																			 arSparkplugInt16:= arSparkplugInt16, r																			 arSparkplugInt32:= arSparkplugInt32, žr																			 arSparkplugInt64:= arSparkplugInt64, Ÿr																			 arSparkplugUInt8:= arSparkplugUInt8,  v																			 arSparkplugUInt16:= arSparkplugUInt16, ¡v																			 arSparkplugUInt32:= arSparkplugUInt32, ¢v																			 arSparkplugUInt64:= arSparkplugUInt64, £n																			 arSparkplugUUID:= arSparkplugUUID, ¤n																			 arSparkplugText:= arSparkplugText, ¥v																			 arSparkplugString:= arSparkplugString, ¦l																			 AllMetricsList:= _AllMetricsList, §n																			 ChangeDetected => _ChangeDetected, ¨j																			 ErrorDetected => _ErrorDetected, ©p																			 NumberOfChanges => _CurrentChanges);ª€								IF _ChangeError <> ERROR.NO_ERROR OR _ErrorDetected THEN«„									WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN FindChanges Error: %s', TO_STRING(_ChangeError) );        ¬									 ­r								IF _NDATAEncoderPrepared AND _ChangeDetected THEN®									WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN FindChanges Detected: %s', TO_STRING(_CurrentChanges) );        ¯¸									_PublishNDATAError := PublishNDATA( AllMetricsList := _AllMetricsList );           °–							_PublishBlockTimerEnable := _ChangeDetected AND NOT _PublishBlocked;±r							_PublishBlockTimer(IN := _PublishBlockTimerEnable,²`											   PT := UINT_TO_TIME(publishPeriod),³B												Q => _PublishBlocked,´^											   ET => _PublishBlockTimerElapsed);µB                                 ¶@    EoNStateType.DISCONNECTING :·¾                            // To Exit Cleanly we have to do the following in this exact order:¸                             //      1) DISABLE_PUBLISHER => Stop the publisher  ¹Ì                            //      2) UNSUBSCRIBE_DCMD => Unsubscribe from DCMD while still connectedºÌ                            //      3) UNSUBSCRIBE_NCMD => Unsubscribe from NCMD while still connected»¦                            //      4) DISCONNECT_MQTT =>Disconnect the MQTT Client¼\                            //      5) EXITING½n                            //          REBIRH => INIT ¾°                            //          OTHERWISE => OFFLINE                            ¿ú                            WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN Disconnection Requested %s',WAIT);À                            _EoNState := EoNStateType.DISABLE_PUBLISHER;ÁJ    EoNStateType.DISABLE_PUBLISHER :	²                            IF NOT _DisablePublisher THEN                                ÃÄ                               _DisablePublisher := _MQTT.DisablePublisher(); // Will become FALSEÄ                                 // publisher is now DISABLED                    Åö                                WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN Publisher stopped %s',WAIT);ÆÖ                                _EoNState := EoNStateType.UNSUBSCRIBE_DCMD;                                ÇF    EoNStateType.UNSUBSCRIBE_DCMD :Èp                            IF NOT _UnSubscribeDCMD THENɘ                                _UnSubscribeDCMD := _MQTT.UnSubscribeDCMD();Ê€                            ELSE                                Ë€                                WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN Unsubscribed from DCMD %s',WAIT);Ì–                                _EoNState := EoNStateType.UNSUBSCRIBE_NCMD;ÍF    EoNStateType.UNSUBSCRIBE_NCMD :Îp                            IF NOT _UnsubscribeNCMD THENϘ                                _UnsubscribeNCMD := _MQTT.UnSubscribeNCMD();Ѐ                                WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN Unsubscribed from NCMD %s',WAIT);Ñ”                                _EoNState := EoNStateType.DISCONNECT_MQTT;Ò    Ó|    EoNStateType.DISCONNECT_MQTT :                            Ôf                            IF NOT _Disconnect THENÕ„                                WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN MQTT Client Disconnected %s',WAIT);Ö„                                _EoNState := EoNStateType.EXITING;×6    EoNStateType.EXITING :	ØX                            // Un-initialiseÙ^                            IF NOT Connect THENÚz                                // Local Disconnect Initiatedې                                _EoNState := EoNStateType.OFFLINE;      Ü|                                // Rebirth or any other cause ݬ                                _EoNState := EoNStateType.INIT;                       ÞF                            // INITßd                            _Initialised := FALSE;àX                            // CONNECT_MQTT	á\                            _Connect := FALSE;âZ                            // PUBLISH_NBIRTHãr                            _NodeBirthPublished := FALSE;äZ                            // SUBSCRIBE_NCMDåh                            _SubscribeNCMD := FALSE;æZ                            // SUBSCRIBE_DCMDçh                            _SubscribeDCMD := FALSE;èJ                            // ONLINEéŒ                            _PublishBlocked := TRUE; // Should be TRUEêv                            _NDATAEncoderPrepared := FALSE;ë\                            _Rebirth := FALSE;ìj                            _ChangeDetected := FALSE;í\                            _ChangeError := 0;îh                            _ErrorDetected := FALSE;ïp                            _PublishNDATAError := FALSE;ðZ                            // DISCONNECTING	ñn                            _DisablePublisher := FALSE;ò^                            // UNSUBSCRIBE_DCMDól                            _UnSubscribeDCMD := FALSE;ô^                            // UNSUBSCRIBE_NCMDõl                            _UnsubscribeNCMD := FALSE;ö\                            // DISCONNECT_MQTT÷b                            _Disconnect := FALSE;øH                            // ERRORùX                            _Reset := FALSE;úELSEûL    _EoNState := EoNStateType.OFFLINE;üEND_CASEý&// Update EoN StateþfIF _CurConnectionState <> _PrevConnectionState THENÿö    WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN Connection State: %s', TO_STRING(_CurConnectionState) );€X_PrevConnectionState := _CurConnectionState;NConnectionState := _CurConnectionState;‚ // EoN DiagnosisƒDiag();„Interface…L{a9ed5b7e-75c5-4651-af16-d2c27e98cb94}†(*‡0    Edge of Network Nodeˆ˜    Binds together FB_MQTT_PubSub and FB_Sparkplug via a state machine in ST‰*)Š¢FUNCTION_BLOCK PUBLIC FB_Edge_Of_Network_Node IMPLEMENTS ISparkplugDeviceProtocol‹VAR_INPUTŒt    ServerUrl  : STRING;       // eg:'test.mosquitto.org';T    ServerPort : UINT := 1883; // eg: 1883Ž|    KeepAlive  : UINT := 60;   // eg: 60 (Value is in seconds)V    (* Persistent Session (FALSE = DEFAULT)°        * The client must get all messages FROM a certain topic, even IF it is offline. ‘ò        * You want the broker to queue the messages for the client and deliver them as soon as the client is back online.’X        * The client has limited resources. “ˆ        * You want the broker to store the subscription information of the client and restore the interrupted communication quickly.”È        * The client needs to reNumberOfMetricse all QoS 1 and 2 publish messages after a reconnect.•        –8        Clean session (TRUE)—à        * The client needs only to publish messages to topics, the client does not need to subscribe to topics. ˜Þ        * You don t want the broker to store session information or retry transmission of QoS 1 and 2 messages.™–        * The client does not need to get messages that it misses offline. š    *)›J    CleanSession  : BOOL    := FALSE;œ¨    Username      : WSTRING := "";           // specify a username if any (optional)À    Password      : WSTRING := "";           // specify the password for the username (optional)ž¼    UseTLS        : BOOL;                    // Enables usage of the TLS encryption (optional)Ÿö    hCert         : SysTypes.RTS_IEC_HANDLE; // Handle to the client certificate (optional) and only used if UseTLS is TRUE Œ    GroupId       : WSTRING;                 // eg: "SparkplugBDevice"¡t    NodeName      : WSTRING;                 // eg: "EoN1"¢ˆ    DeviceName    : WSTRING;                 // eg: "EmulatedDevice"£¦    publishPeriod : UINT;                    // eg: 5000 (Value is in milliseconds)¤END_VAR¥VAR_OUTPUT¦`    ConnectionState : SparkplugSessionStateType;§p    itfDevices      : ISparkplugDeviceProtocol := THIS^;¨8    NumberOfDevices : UDINT;©VAR_IN_OUTªt    arSparkplugBoolean  : ARRAY[*] OF FB_SparkplugBoolean;«v    arSparkplugDateTime : ARRAY[*] OF FB_SparkplugDateTime;¬p    arSparkplugFloat    : ARRAY[*] OF FB_SparkplugFloat;­r    arSparkplugDouble   : ARRAY[*] OF FB_SparkplugDouble;®n    arSparkplugInt8     : ARRAY[*] OF FB_SparkplugInt8;¯p    arSparkplugInt16    : ARRAY[*] OF FB_SparkplugInt16;°p    arSparkplugInt32    : ARRAY[*] OF FB_SparkplugInt32;±p    arSparkplugInt64    : ARRAY[*] OF FB_SparkplugInt64;²p    arSparkplugUInt8    : ARRAY[*] OF FB_SparkplugUInt8;³r    arSparkplugUInt16   : ARRAY[*] OF FB_SparkplugUInt16;´r    arSparkplugUInt32   : ARRAY[*] OF FB_SparkplugUInt32;µr    arSparkplugUInt64   : ARRAY[*] OF FB_SparkplugUInt64;¶n    arSparkplugUUID     : ARRAY[*] OF FB_SparkplugUUID;·n    arSparkplugText     : ARRAY[*] OF FB_SparkplugText;¸r    arSparkplugString   : ARRAY[*] OF FB_SparkplugString;¹VARº’    Connect : BOOL := TRUE; // TRUE: Connects EoN using the configured settings, FALSE: Disconnects EoN from server if it was connected  »l    (* Corrected GroupId, contains no illegal chars *)¼.    _GroupId : WSTRING;½p    (* Corrected _NodeName, contains no illegal chars *)¾0    _NodeName : WSTRING;¿t    (* Corrected _DeviceName, contains no illegal chars *)ÀP    _DeviceName               : WSTRING;ÁP    _MQTT                     : FB_MQTT;Â`    _MQTT_eError              : MQTT.MQTT_ERROR;î    _SparkplugB               : FB_SparkplugBSimple;        // Handles SparkPlugB Stuffĸ    _DeviceList               : List;                       // Handles all connected DevicesÅÊ    _TryConnectTimer          : FB_ExponentialBackOffTimer; // Handles the Exponential Backoff timingÆN    _OnMQTT_Error             : R_TRIG;ÇN    _OnMQTT_NoErr             : F_TRIG;ÈN    _OnEoNConnect             : R_TRIG;ÉN    _OnEoNDisConnect          : R_TRIG;ÊŠ    _EoNState                 : EoNStateType := EoNStateType.OFFLINE;Ët    _AllMetricsList           : LIST; // Complete List    Ìn    _ChangeList               : LIST; // The Send list;ÍJ    _Initialise               : BOOL;ÎJ    _Connect                  : BOOL;ÏJ    _Disconnect               : BOOL;ÐJ    _Initialised              : BOOL;ÑJ    _Reset                    : BOOL;ÒJ    _SubscribeNCMD            : BOOL;ÓJ    _UnSubscribeNCMD          : BOOL;ÔJ    _SubscribeDCMD            : BOOL;ÕJ    _UnSubscribeDCMD          : BOOL;ÖJ    _NodeBirthPublished       : BOOL;×J    _PublishNodeDataStart     : BOOL;ØJ    _DisablePublisher         : BOOL;Ù˜    _LastWillTopic            : WSTRING(Constants.supported_string_lengths);Ú¶    _NDEATH                   : FB_SparkplugUInt64;    // contains the current NDEATH BDSeqÛÆ    _NDEATHPayload            : ARRAY[0..255] OF BYTE; // what is the maximum size of this payload?ÜL    _NDEATHPayloadSize        : UDINT;݈    _LastWillQos              : MQTT.MQTT_QOS := MQTT.MQTT_QOS.QoS0;Þn    _LastWillRetain           : BOOL          := FALSE;ßÈ    _NBIRTH                   : FB_SparkplugUInt64;      // contains the current raw NBIRTH sequenceà®    _Blob                     : ARRAY[0..65535] OF BYTE; // buffer for encoded messagesá°    _BlobSize                 : UDINT;                   // current encoded message sizeâF    _PublishBlockTimer        : TP;ãJ    _PublishBlockTimerEnable  : BOOL;äJ    _PublishBlockTimerElapsed : TIME;å‚    _PublishBlocked           : BOOL; // Status of the BlockTimeræ\    _NDATAEncoderPrepared     : BOOL := FALSE;çJ    _PublishNDATAError        : BOOL;èJ    _ErrorDetected            : BOOL;éL    _ChangeError              : ERROR;êª    _ChangeDetected           : BOOL;  // At least 1 Signal change has been detected;ëÌ    _CurrentChanges           : UDINT; // Number of detected changes, each changes reflects 1 Signal  ìl    _MessageType              : SparkplugMessageTypes;íJ    _Rebirth                  : BOOL;îŠ    _RecvMesg                 : REFERENCE TO FB_PayloadSimpleDecoder;ï˜    _RecvTopic                : WSTRING(Constants.supported_string_lengths);ð¾    _CurConnectionState       : SparkplugSessionStateType := SparkplugSessionStateType.OFFLINE;ñ¼    _PrevConnectionState      : SparkplugSessionStateType := SparkplugSessionStateType.ONLINE;òN    _Diag                     : STRING;óŽ    _taskCycleTime            : DWORD; //ms, so equivelant also of TIMEôJ    _Already1                 : BOOL;õJ    _Already2                 : BOOL;öJ    _Already3                 : BOOL;÷J    _Already4                 : BOOL;øVAR CONSTANTù    // ASCIIú6    WAIT : STRING := '...';û*    // UTF-8 encodingüP    FW_SLASH           : WSTRING := "/";ý^    SPARKPLUGB         : WSTRING := "spBv1.0/";þR    TOPIC_FILTER_POUND : WSTRING := "/#";ÿR    TOPIC_FILTER_PLUS  : WSTRING := "/+";€^    NODE_DEATH_TOPIC   : WSTRING := "/NDEATH/";^    NODE_BIRTH_TOPIC   : WSTRING := "/NBIRTH/";‚\    NODE_DATA_TOPIC    : WSTRING := "/NDATA/";ƒ^    DEVICE_DEATH_TOPIC : WSTRING := "/DDEATH/";„^    DEVICE_BIRTH_TOPIC : WSTRING := "/DBIRTH/";…\    DEVICE_DATA_TOPIC  : WSTRING := "/DDATA/";†Z    NCMD               : WSTRING := "/NCMD/";‡Z    DCMD               : WSTRING := "/DCMD/";ˆP    POUND              : WSTRING := "#";‰P    PLUS               : WSTRING := "+";ŠP    UNDERSCORE         : WSTRING := "_";‹"UniqueIdGeneratorŒ9176POULevelŽL{8e575c5b-1d37-49c6-941b-5c0ec7874787}Standard ChildObjectGuids‘8System.Collections.ArrayList’,AddAttributeSubsequent“boolÐÐ-ÐÐ	E
 ºÐÐ
­ãÚÐ-ÐÐ
­äÚÐ-ÐÐ
­åÚÐ-ÐÐ
­æÚÐ-ÐÐ
­M#ÚÐ-ÐÐ
­çÚÐ-ÐÐ
­èÚÐ-ÐÐ
­éÚÐ-ÐÐ
­êÚÐ-ÐÐ
­ëÚÐ-ÐÐ
­ìÚÐ-ÐÐ
­íÚÐ-ÐÐ
­îÚÐ-ÐÐ
­ïÚÐ-ÐÐ
­ðÚÐ-ÐÐ
­ñÚÐ-ÐÐ
­òÚÐ-ÐÐ
­óÚÐ- ÐÐ
­ôÚÐ-!ÐÐ
­õÚÐ-ÐÐ
­öÚÐ-"ÐÐ
­÷ÚÐ-#ÐÐ
­øÚÐ-$ÐÐ
­ùÚÐ-%ÐÐ
­úÚÐ-&ÐÐ
­ûÚÐ-!ÐÐ
­üÚÐ-ÐÐ
­ýÚÐ-'ÐÐ
­þÚÐ-(ÐÐ
­ÿÚÐ-)ÐÐ
­ ÚÐ-*ÐÐ
­ ÚÐ-+ÐÐ
­ ÚÐ-,ÐÐ
­ ÚÐ--ÐÐ
­ ÚÐ-.ÐÐ
­ ÚÐ-/ÐÐ
­ ÚÐ-0ÐÐ
­ ÚÐ-1ÐÐ
­ ÚÐ-ÐÐ
­	 ÚÐ-2ÐÐ
­
  ÚÐ-3ÐÐ
­ ÚÐ-4ÐÐ
­ ÚÐ-5ÐÐ
­
 ÚÐ-6ÐÐ
­ ÚÐ-7ÐÐ
­ ÚÐ-8ÐÐ
­£!ÚÐ-9ÐÐ
­¤!ÚÐ-:ÐÐ
­Ž!ÚÐ-;ÐÐ
­‘!ÚÐ-<ÐÐ
­’!ÚÐ-=ÐÐ
­ ÚÐ->ÐÐ
­ ÚÐ-?ÐÐ
­ ÚÐ-@ÐÐ
­ ÚÐ-AÐÐ
­ ÚÐ-BÐÐ
­ ÚÐ-CÐÐ
­ ÚÐ-DÐÐ
­ ÚÐ-EÐÐ
­ ÚÐ-FÐÐ
­ ÚÐ-GÐÐ
­ ÚÐ-HÐÐ
­ ÚÐ--ÐÐ
­ƒ!ÚÐ-IÐÐ
­ž!ÚÐ-JÐÐ
­Ÿ!ÚÐ-KÐÐ
­ !ÚÐ-LÐÐ
­¡!ÚÐ-MÐÐ
­¢!ÚÐ-NÐÐ
­•!ÚÐ-<ÐÐ
­”!ÚÐ-OÐÐ
­ ÚÐ-PÐÐ
­ ÚÐ-QÐÐ
­  ÚÐ-ÐÐ
­! ÚÐ-ÐÐ
­" ÚÐ-RÐÐ
­# ÚÐ-SÐÐ
­$ ÚÐ-TÐÐ
­% ÚÐ-UÐÐ
­& ÚÐ-VÐÐ
­' ÚÐ-WÐÐ
­( ÚÐ-XÐÐ
­) ÚÐ--ÐÐ
­* ÚÐ-YÐÐ
­+ ÚÐ-ZÐÐ
­, ÚÐ-[ÐÐ
­- ÚÐ-\ÐÐ
­. ÚÐ-3ÐÐ
­/ ÚÐ-4ÐÐ
­0 ÚÐ-5ÐÐ
­1 ÚÐ-]ÐÐ
­¥!ÚÐ-7ÐÐ
­¦!ÚÐ-^ÐÐ
­§!ÚÐ-9ÐÐ
­¨!ÚÐ-:ÐÐ
­©!ÚÐ-_ÐÐ
­ª!ÚÐ-<ÐÐ
­«!ÚÐ-`ÐÐ
­4 ÚÐ->ÐÐ
­5 ÚÐ-?ÐÐ
­6 ÚÐ-@ÐÐ
­7 ÚÐ-FÐÐ
­8 ÚÐ-GÐÐ
­9 ÚÐ-HÐÐ
­: ÚÐ-aÐÐ
­–!ÚÐ-bÐÐ
­—!ÚÐ-JÐÐ
­˜!ÚÐ-cÐÐ
­œ!ÚÐ-LÐÐ
­!ÚÐ-MÐÐ
­™!ÚÐ-dÐÐ
­š!ÚÐ-<ÐÐ
­›!ÚÐ-eÐÐ
­= ÚÐ-fÐÐ
­> ÚÐ-QÐÐ
­? ÚÐ-gÐÐ
­I ÚÐ-hÐÐ
­J ÚÐ-iÐÐ
­K ÚÐ-jÐÐ
­L ÚÐ-kÐÐ
­M ÚÐ-lÐÐ
­N ÚÐ-mÐÐ
­O ÚÐ-ZÐÐ
­P ÚÐ-nÐÐ
­Q ÚÐ-oÐÐ
­R ÚÐ-pÐÐ
­S ÚÐ-qÐÐ
­T ÚÐ-rÐÐ
­U ÚÐ-sÐÐ
­V ÚÐ-tÐÐ
­W ÚÐ-1ÐÐ
­X ÚÐ-nÐÐ
­…!ÚÐ-uÐÐ
­†!ÚÐ-vÐÐ
­‡!ÚÐ-wÐÐ
­ˆ!ÚÐ-xÐÐ
­‰!ÚÐ-yÐÐ
­Š!ÚÐ-lÐÐ
­‹!ÚÐ-zÐÐ
­„!ÚÐ-ZÐÐ
­Œ!ÚÐ-nÐÐ
­Y ÚÐ-{ÐÐ
­Z ÚÐ-|ÐÐ
­[ ÚÐ-}ÐÐ
­\ ÚÐ-~ÐÐ
­] ÚÐ-ÐÐ
­^ ÚÐ-€ÐÐ
­_ ÚÐ-ÐÐ
­` ÚÐ-‚ÐÐ
­a ÚÐ-ƒÐÐ
­b ÚÐ-„ÐÐ
­c ÚÐ->ÐÐ
­d ÚÐ-lÐÐ
­e ÚÐ-…ÐÐ
­f ÚÐ-1ÐÐ
­g ÚÐ-†ÐÐ
­h ÚÐ-‡ÐÐ
­i ÚÐ-ˆÐÐ
­j ÚÐ-‰ÐÐ
­k ÚÐ-ŠÐÐ
­l ÚÐ-‹ÐÐ
­m ÚÐ-1ÐÐ
­n ÚÐ-ŒÐÐ
­o ÚÐ-ÐÐ
­p ÚÐ-ŽÐÐ
­q ÚÐ-ÐÐ
­r ÚÐ-ÐÐ
­s ÚÐ-‘ÐÐ
­t ÚÐ-’ÐÐ
­u ÚÐ-“ÐÐ
­v ÚÐ-”ÐÐ
­w ÚÐ-•ÐÐ
­x ÚÐ-–ÐÐ
­y ÚÐ-—ÐÐ
­z ÚÐ-˜ÐÐ
­{ ÚÐ-™ÐÐ
­| ÚÐ-šÐÐ
­} ÚÐ-›ÐÐ
­~ ÚÐ-œÐÐ
­ ÚÐ-ÐÐ
­€ ÚÐ-žÐÐ
­ ÚÐ-ŸÐÐ
­‚ ÚÐ- ÐÐ
­ƒ ÚÐ-¡ÐÐ
­„ ÚÐ-¢ÐÐ
­… ÚÐ-£ÐÐ
­† ÚÐ-¤ÐÐ
­‡ ÚÐ-¥ÐÐ
­ˆ ÚÐ-¦ÐÐ
­‰ ÚÐ-§ÐÐ
­Š ÚÐ-¨ÐÐ
­‹ ÚÐ-©ÐÐ
­Œ ÚÐ-•ÐÐ
­ ÚÐ-ªÐÐ
­Ž ÚÐ-«ÐÐ
­ ÚÐ->ÐÐ
­ ÚÐ-¬ÐÐ
­‘ ÚÐ-­ÐÐ
­’ ÚÐ-®ÐÐ
­“ ÚÐ-¯ÐÐ
­” ÚÐ->ÐÐ
­• ÚÐ-ZÐÐ
­– ÚÐ-°ÐÐ
­— ÚÐ-±ÐÐ
­˜ ÚÐ-²ÐÐ
­™ ÚÐ-³ÐÐ
­š ÚÐ-´ÐÐ
­› ÚÐ-µÐÐ
­ ÚÐ-¶ÐÐ
­ž ÚÐ-·ÐÐ
­Ÿ ÚÐ-¸ÐÐ
­  ÚÐ-¹ÐÐ
­¡ ÚÐ-ºÐÐ
­¢ ÚÐ-»ÐÐ
­£ ÚÐ-¼ÐÐ
­¤ ÚÐ-½ÐÐ
­¥ ÚÐ-¾ÐÐ
­¦ ÚÐ-¿ÐÐ
­§ ÚÐ-ÀÐÐ
­¨ ÚÐ-ÐÐ
­© ÚÐ-ÁÐÐ
­ª ÚÐ-ÂÐÐ
­« ÚÐ-ÃÐÐ
­¬ ÚÐ--ÐÐ
­­ ÚÐ-ÄÐÐ
­® ÚÐ-ÅÐÐ
­¯ ÚÐ-ÆÐÐ
­° ÚÐ-1ÐÐ
­± ÚÐ-ÐÐ
­² ÚÐ-ÇÐÐ
­³ ÚÐ-ÈÐÐ
­´ ÚÐ-ÉÐÐ
­µ ÚÐ-ÊÐÐ
­¶ ÚÐ-ËÐÐ
­· ÚÐ-ÌÐÐ
­¸ ÚÐ-1ÐÐ
­¹ ÚÐ-ÐÐ
­º ÚÐ-ÍÐÐ
­» ÚÐ-ÎÐÐ
­¼ ÚÐ-ÏÐÐ
­½ ÚÐ-ÊÐÐ
­¾ ÚÐ-ÐÐÐ
­¿ ÚÐ-ÑÐÐ
­À ÚÐ-1ÐÐ
­Á ÚÐ-ÒÐÐ
­Â ÚÐ-ÓÐÐ
­Ã ÚÐ-ÔÐÐ
­Ä ÚÐ-bÐÐ
­Å ÚÐ-lÐÐ
­Æ ÚÐ-ÕÐÐ
­Ç ÚÐ-ÖÐÐ
­È ÚÐ-1ÐÐ
­É ÚÐ-ÐÐ
­Ê ÚÐ-×ÐÐ
­Ë ÚÐ-ØÐÐ
­Ì ÚÐ-ÙÐÐ
­Í ÚÐ-ÚÐÐ
­Î ÚÐ-ÛÐÐ
­Ï ÚÐ-lÐÐ
­Ð ÚÐ-ÜÐÐ
­Ñ ÚÐ-ÝÐÐ
­Ò ÚÐ-1ÐÐ
­Ó ÚÐ-ÐÐ
­Ô ÚÐ-ÞÐÐ
­Õ ÚÐ-ßÐÐ
­Ö ÚÐ-[ÐÐ
­× ÚÐ-àÐÐ
­Ø ÚÐ-áÐÐ
­Ù ÚÐ-[ÐÐ
­Ú ÚÐ-âÐÐ
­Û ÚÐ-ãÐÐ
­Ü ÚÐ-[ÐÐ
­Ý ÚÐ-äÐÐ
­Þ ÚÐ-åÐÐ
­ß ÚÐ-[ÐÐ
­à ÚÐ-æÐÐ
­á ÚÐ-çÐÐ
­â ÚÐ-[ÐÐ
­ã ÚÐ-èÐÐ
­ä ÚÐ-éÐÐ
­å ÚÐ-êÐÐ
­æ ÚÐ-ëÐÐ
­ç ÚÐ-ìÐÐ
­è ÚÐ-íÐÐ
­é ÚÐ-îÐÐ
­ê ÚÐ-ïÐÐ
­ë ÚÐ-[ÐÐ
­ì ÚÐ-ðÐÐ
­í ÚÐ-ñÐÐ
­î ÚÐ-[ÐÐ
­ï ÚÐ-òÐÐ
­ð ÚÐ-óÐÐ
­ñ ÚÐ-[ÐÐ
­ò ÚÐ-ôÐÐ
­ó ÚÐ-õÐÐ
­ô ÚÐ-[ÐÐ
­õ ÚÐ-öÐÐ
­ö ÚÐ-÷ÐÐ
­÷ ÚÐ-[ÐÐ
­ø ÚÐ-øÐÐ
­ù ÚÐ-ùÐÐ
­ú ÚÐ-úÐÐ
­û ÚÐ-ûÐÐ
­ü ÚÐ-üÐÐ
­K#ÚÐ-ÐÐ
­þ ÚÐ-ýÐÐ
­ÿ ÚÐ-þÐÐ
­!ÚÐ-ÿÐÐ
­!ÚÐ-ÐÐ
­!ÚÐ-€ÐÐ
­!ÚÐ-ÐÐ
­¯!ÚÐ-ÐÐ
­!ÚÐ-‚ÐÐ
­ÃÚÐ-ƒЄ…Ð	E
-‰ÐÐ
­P#ÚÐ-†ÐÐ
­Q#ÚÐ-‡ÐÐ
­R#ÚÐ-ˆÐÐ
­S#ÚÐ-‰ÐÐ
­T#ÚÐ-ŠÐÐ
­U#ÚÐ-‹ÐÐ
­V#ÚÐ-ŒÐÐ
­W#ÚÐ-ÐÐ
­X#ÚÐ-ŽÐÐ
­Y#ÚÐ-ÐÐ
­Z#ÚÐ-ÐÐ
­[#ÚÐ-‘ÐÐ
­\#ÚÐ-’ÐÐ
­]#ÚÐ-“ÐÐ
­^#ÚÐ-”ÐÐ
­_#ÚÐ-•ÐÐ
­`#ÚÐ-–ÐÐ
­a#ÚÐ-—ÐÐ
­b#ÚÐ-˜ÐÐ
­c#ÚÐ-™ÐÐ
­d#ÚÐ-šÐÐ
­e#ÚÐ-›ÐÐ
­f#ÚÐ-œÐÐ
­g#ÚÐ-ÐÐ
­h#ÚÐ-žÐÐ
­i#ÚÐ-ŸÐÐ
­j#ÚÐ- ÐÐ
­k#ÚÐ-¡ÐÐ
­l#ÚÐ-¢ÐÐ
­m#ÚÐ-£ÐÐ
­n#ÚÐ-¤ÐÐ
­o#ÚÐ-¥ÐÐ
­p#ÚÐ-¦ÐÐ
­q#ÚÐ-§ÐÐ
­r#ÚÐ-¨ÐÐ
­s#ÚÐ-¤ÐÐ
­t#ÚÐ-©ÐÐ
­u#ÚÐ-ªÐÐ
­v#ÚÐ-«ÐÐ
­w#ÚÐ-¬ÐÐ
­x#ÚÐ-­ÐÐ
­y#ÚÐ-®ÐÐ
­z#ÚÐ-¯ÐÐ
­{#ÚÐ-°ÐÐ
­|#ÚÐ-±ÐÐ
­}#ÚÐ-²ÐÐ
­~#ÚÐ-³ÐÐ
­#ÚÐ-´ÐÐ
­€#ÚÐ-µÐÐ
­#ÚÐ-¶ÐÐ
­‚#ÚÐ-·ÐÐ
­ƒ#ÚÐ-¸ÐÐ
­„#ÚÐ-¤ÐÐ
­…#ÚÐ-¹ÐÐ
­†#ÚÐ-ºÐÐ
­‡#ÚÐ-»ÐÐ
­ˆ#ÚÐ-¼ÐÐ
­‰#ÚÐ-½ÐÐ
­Š#ÚÐ-¾ÐÐ
­‹#ÚÐ-¿ÐÐ
­Œ#ÚÐ-ÀÐÐ
­#ÚÐ-ÁÐÐ
­Ž#ÚÐ-ÂÐÐ
­#ÚÐ-ÃÐÐ
­#ÚÐ-ÄÐÐ
­‘#ÚÐ-ÅÐÐ
­’#ÚÐ-ÆÐÐ
­“#ÚÐ-ÇÐÐ
­”#ÚÐ-ÈÐÐ
­•#ÚÐ-ÉÐÐ
­–#ÚÐ-ÊÐÐ
­—#ÚÐ-ËÐÐ
­˜#ÚÐ-ÌÐÐ
­™#ÚÐ-ÍÐÐ
­š#ÚÐ-ÎÐÐ
­›#ÚÐ-ÏÐÐ
­œ#ÚÐ-ÐÐÐ
­#ÚÐ-ÑÐÐ
­ž#ÚÐ-ÒÐÐ
­Ÿ#ÚÐ-ÓÐÐ
­ #ÚÐ-ÔÐÐ
­¡#ÚÐ-ÕÐÐ
­¢#ÚÐ-ÖÐÐ
­£#ÚÐ-×ÐÐ
­¤#ÚÐ-ØÐÐ
­¥#ÚÐ-ÙÐÐ
­¦#ÚÐ-ÚÐÐ
­§#ÚÐ-ÛÐÐ
­¨#ÚÐ-ÜÐÐ
­©#ÚÐ-ÝÐÐ
­ª#ÚÐ-ÞÐÐ
­«#ÚÐ-ßÐÐ
­¬#ÚÐ-àÐÐ
­­#ÚÐ-áÐÐ
­®#ÚÐ-âÐÐ
­¯#ÚÐ-ãÐÐ
­°#ÚÐ-äÐÐ
­±#ÚÐ-åÐÐ
­²#ÚÐ-æÐÐ
­³#ÚÐ-çÐÐ
­´#ÚÐ-èÐÐ
­µ#ÚÐ-éÐÐ
­¶#ÚÐ-êÐÐ
­·#ÚÐ-ëÐÐ
­¸#ÚÐ-ìÐÐ
­¹#ÚÐ-íÐÐ
­º#ÚÐ-îÐÐ
­»#ÚÐ-ïÐÐ
­¼#ÚÐ-ðÐÐ
­½#ÚÐ-ñÐÐ
­¾#ÚÐ-òÐÐ
­¿#ÚÐ-óÐÐ
­À#ÚÐ-ôÐÐ
­Á#ÚÐ-õÐÐ
­Â#ÚÐ-öÐÐ
­Ã#ÚÐ-÷ÐÐ
­Ä#ÚÐ-¤ÐÐ
­Å#ÚÐ-øÐÐ
­Æ#ÚÐ-ùÐÐ
­Ç#ÚÐ-úÐÐ
­È#ÚÐ-ûÐÐ
­É#ÚÐ-üÐÐ
­Ê#ÚÐ-ýÐÐ
­Ë#ÚÐ-þÐÐ
­Ì#ÚÐ-ÿÐÐ
­Í#ÚÐ-€ÐÐ
­Î#ÚÐ-ÐÐ
­Ï#ÚÐ-‚ÐÐ
­Ð#ÚÐ-ƒÐÐ
­Ñ#ÚÐ-„ÐÐ
­Ò#ÚÐ-…ÐÐ
­Ó#ÚÐ-†ÐÐ
­Ô#ÚÐ-‡ÐÐ
­Õ#ÚÐ-ˆÐÐ
­Ö#ÚÐ-‰ÐÐ
­×#ÚÐ-ŠÐÐ
­hÚÐ-¤Ћ-ŒЍŽ-‘В“­
\ No newline at end of file
+ŠÐÐ
­P#ÚÐ-†ÐÐ
­Q#ÚÐ-‡ÐÐ
­R#ÚÐ-ˆÐÐ
­S#ÚÐ-‰ÐÐ
­T#ÚÐ-ŠÐÐ
­U#ÚÐ-‹ÐÐ
­V#ÚÐ-ŒÐÐ
­W#ÚÐ-ÐÐ
­X#ÚÐ-ŽÐÐ
­Y#ÚÐ-ÐÐ
­Z#ÚÐ-ÐÐ
­[#ÚÐ-‘ÐÐ
­\#ÚÐ-’ÐÐ
­]#ÚÐ-“ÐÐ
­^#ÚÐ-”ÐÐ
­_#ÚÐ-•ÐÐ
­`#ÚÐ-–ÐÐ
­a#ÚÐ-—ÐÐ
­b#ÚÐ-˜ÐÐ
­c#ÚÐ-™ÐÐ
­d#ÚÐ-šÐÐ
­e#ÚÐ-›ÐÐ
­f#ÚÐ-œÐÐ
­g#ÚÐ-ÐÐ
­h#ÚÐ-žÐÐ
­i#ÚÐ-ŸÐÐ
­j#ÚÐ- ÐÐ
­k#ÚÐ-¡ÐÐ
­l#ÚÐ-¢ÐÐ
­m#ÚÐ-£ÐÐ
­n#ÚÐ-¤ÐÐ
­o#ÚÐ-¥ÐÐ
­p#ÚÐ-¦ÐÐ
­q#ÚÐ-§ÐÐ
­r#ÚÐ-¨ÐÐ
­s#ÚÐ-¤ÐÐ
­t#ÚÐ-©ÐÐ
­u#ÚÐ-ªÐÐ
­v#ÚÐ-«ÐÐ
­w#ÚÐ-¬ÐÐ
­x#ÚÐ-­ÐÐ
­y#ÚÐ-®ÐÐ
­z#ÚÐ-¯ÐÐ
­{#ÚÐ-°ÐÐ
­|#ÚÐ-±ÐÐ
­}#ÚÐ-²ÐÐ
­~#ÚÐ-³ÐÐ
­#ÚÐ-´ÐÐ
­€#ÚÐ-µÐÐ
­#ÚÐ-¶ÐÐ
­‚#ÚÐ-·ÐÐ
­ƒ#ÚÐ-¸ÐÐ
­„#ÚÐ-¤ÐÐ
­…#ÚÐ-¹ÐÐ
­†#ÚÐ-ºÐÐ
­‡#ÚÐ-»ÐÐ
­ˆ#ÚÐ-¼ÐÐ
­‰#ÚÐ-½ÐÐ
­Š#ÚÐ-¾ÐÐ
­‹#ÚÐ-¿ÐÐ
­Œ#ÚÐ-ÀÐÐ
­#ÚÐ-ÁÐÐ
­Ž#ÚÐ-ÂÐÐ
­#ÚÐ-ÃÐÐ
­#ÚÐ-ÄÐÐ
­‘#ÚÐ-ÅÐÐ
­’#ÚÐ-ÆÐÐ
­“#ÚÐ-ÇÐÐ
­”#ÚÐ-ÈÐÐ
­•#ÚÐ-ÉÐÐ
­–#ÚÐ-ÊÐÐ
­—#ÚÐ-ËÐÐ
­˜#ÚÐ-ÌÐÐ
­™#ÚÐ-ÍÐÐ
­š#ÚÐ-ÎÐÐ
­›#ÚÐ-ÏÐÐ
­œ#ÚÐ-ÐÐÐ
­#ÚÐ-ÑÐÐ
­ž#ÚÐ-ÒÐÐ
­Ÿ#ÚÐ-ÓÐÐ
­ #ÚÐ-ÔÐÐ
­¡#ÚÐ-ÕÐÐ
­¢#ÚÐ-ÖÐÐ
­£#ÚÐ-×ÐÐ
­¤#ÚÐ-ØÐÐ
­¥#ÚÐ-ÙÐÐ
­¦#ÚÐ-ÚÐÐ
­§#ÚÐ-ÛÐÐ
­¨#ÚÐ-ÜÐÐ
­©#ÚÐ-ÝÐÐ
­ª#ÚÐ-ÞÐÐ
­«#ÚÐ-ßÐÐ
­¬#ÚÐ-àÐÐ
­­#ÚÐ-áÐÐ
­Ø#ÚÐ-ÒÐÐ
­®#ÚÐ-âÐÐ
­¯#ÚÐ-ãÐÐ
­°#ÚÐ-äÐÐ
­±#ÚÐ-åÐÐ
­²#ÚÐ-æÐÐ
­³#ÚÐ-çÐÐ
­´#ÚÐ-èÐÐ
­µ#ÚÐ-éÐÐ
­¶#ÚÐ-êÐÐ
­·#ÚÐ-ëÐÐ
­¸#ÚÐ-ìÐÐ
­¹#ÚÐ-íÐÐ
­º#ÚÐ-îÐÐ
­»#ÚÐ-ïÐÐ
­¼#ÚÐ-ðÐÐ
­½#ÚÐ-ñÐÐ
­¾#ÚÐ-òÐÐ
­¿#ÚÐ-óÐÐ
­À#ÚÐ-ôÐÐ
­Á#ÚÐ-õÐÐ
­Â#ÚÐ-öÐÐ
­Ã#ÚÐ-÷ÐÐ
­Ä#ÚÐ-¤ÐÐ
­Å#ÚÐ-øÐÐ
­Æ#ÚÐ-ùÐÐ
­Ç#ÚÐ-úÐÐ
­È#ÚÐ-ûÐÐ
­É#ÚÐ-üÐÐ
­Ê#ÚÐ-ýÐÐ
­Ë#ÚÐ-þÐÐ
­Ì#ÚÐ-ÿÐÐ
­Í#ÚÐ-€ÐÐ
­Î#ÚÐ-ÐÐ
­Ï#ÚÐ-‚ÐÐ
­Ð#ÚÐ-ƒÐÐ
­Ñ#ÚÐ-„ÐÐ
­Ò#ÚÐ-…ÐÐ
­Ó#ÚÐ-†ÐÐ
­Ô#ÚÐ-‡ÐÐ
­Õ#ÚÐ-ˆÐÐ
­Ö#ÚÐ-‰ÐÐ
­×#ÚÐ-ŠÐÐ
­hÚÐ-¤Ћ-ŒЍŽ-‘В“­
\ No newline at end of file