From 4a75049193440f266f6da43f2a81ddaa84c0ce90 Mon Sep 17 00:00:00 2001 From: vados-dev Date: Sun, 10 May 2026 02:40:22 +0300 Subject: [PATCH] Backup for MikroMaster created successfully at May 10 02:40:22. --- .../20260510/20260510022002-Config.rsc | 4645 ++++++++++++++++ .../20260510/20260510024002-Binary.backup | Bin 0 -> 297972 bytes .../20260510/20260510024002-Config.rsc | 4648 +++++++++++++++++ .../20260510/20260510024002-Diff-Config.rsc | 22 + 4 files changed, 9315 insertions(+) create mode 100644 MikroMaster/20260510/20260510022002-Config.rsc create mode 100644 MikroMaster/20260510/20260510024002-Binary.backup create mode 100644 MikroMaster/20260510/20260510024002-Config.rsc create mode 100644 MikroMaster/history/20260510/20260510024002-Diff-Config.rsc diff --git a/MikroMaster/20260510/20260510022002-Config.rsc b/MikroMaster/20260510/20260510022002-Config.rsc new file mode 100644 index 0000000..ebedb4f --- /dev/null +++ b/MikroMaster/20260510/20260510022002-Config.rsc @@ -0,0 +1,4645 @@ +# 2026-05-10 02:20:03 by RouterOS 7.22.1 +# software id = A8L5-07YF +# +# model = RB952Ui-5ac2nD +# serial number = D3D50CEDCD38 +/caps-man configuration +add channel.band=2ghz-b/g/n .control-channel-width=20mhz .extension-channel=\ + XX country=belarus datapath.client-to-client-forwarding=yes \ + .local-forwarding=yes name=cfg-2ghz ssid=vados +add channel.band=5ghz-a/n/ac .control-channel-width=20mhz .extension-channel=\ + XXXX country=belarus datapath.client-to-client-forwarding=yes \ + .local-forwarding=yes name=cfg-5ghz-ac ssid=vados5g +add channel.band=5ghz-a/n .control-channel-width=20mhz .extension-channel=XX \ + country=belarus datapath.client-to-client-forwarding=yes \ + .local-forwarding=yes name=cfg-5ghz-an ssid=vados5g +/interface ethernet +set [ find default-name=ether1 ] comment="WAN - Unet" mac-address=\ + 48:8F:5A:8E:1A:C2 name="ether1 - Unet" +set [ find default-name=ether3 ] comment=LEN +set [ find default-name=ether4 ] comment=NUC +set [ find default-name=ether5 ] poe-out=off +/interface l2tp-server +add comment=Server disabled=yes name=l2tp-in1 user=vados +/interface l2tp-client +add comment="Starless 2 MikroSPb" connect-to=176.53.203.171 name=l2tp-EoIP \ + user=vados +add allow=mschap2 allow-fast-path=yes comment=Starless connect-to=\ + vpn.starless.ru max-mru=1280 name=l2tp-vpn use-ipsec=yes use-peer-dns=yes \ + user=vados +/interface wireguard +add listen-port=13231 mtu=1280 name=WG +/disk +add slot=tmpfs tmpfs-max-size=22369621 type=tmpfs +/interface list +add name=WAN +add name=LAN +/interface lte apn +set [ find default=yes ] ip-type=ipv4 use-network-apn=no +/interface wifi channel +add band=5ghz-ax disabled=no frequency=5180,5200,5220,5240 name=5G-AX +add band=5ghz-ac disabled=no frequency=5180,5200,5220,5240 name=5G-AC +add band=2ghz-n disabled=no frequency=2422,2442,2462 name=2G-N +add band=2ghz-ax disabled=no frequency=2422,2442,2462 name=2G-AX +add band=2ghz-g disabled=no frequency=2422,2442,2462 name=2G-G +add band=5ghz-n disabled=no frequency=5180,5200,5220,5240 name=5G-AN +/interface wifi security +add authentication-types=wpa2-psk,wpa3-psk disabled=no group-encryption=ccmp \ + group-key-update=1h management-protection=allowed name=sec2g +add authentication-types=wpa3-psk disable-pmkid=yes disabled=no \ + group-encryption=ccmp group-key-update=5m management-encryption=cmac \ + management-protection=required name=sec5G +/interface wifi configuration +add channel=5G-AX disabled=no mode=ap name=5G-AX security=sec5G security.ft=\ + yes .ft-over-ds=yes ssid=vados +add channel=5G-AN disabled=no mode=ap name=5G-AN security=sec5G ssid=vados +/interface wireless security-profiles +set [ find default=yes ] supplicant-identity=MikroTik +/ip dhcp-server option +add code=12 name=HostName +add code=119 force=yes name=domain-search-list value="0x03'WORKGROUP'0x00" +/ip dhcp-server option sets +add name=HP1505n options=HostName +add name=StartLife1 options=HostName +add name=amsterDev options=HostName +add name=MiTV options=HostName +add name=miller options=HostName +add name=amster options=HostName +add name=garage options=HostName +add name=domain-search-set options=domain-search-list +add name=VADOS-LEN options=HostName +add name=VADOS-NUC options=HostName +add name=MikroNUC options=HostName +add name=master options=HostName +add name=MikroYellow options=HostName +add name="=\"Client ID\"" options=HostName +/ip dns forwarders +add dns-servers=1.1.1.1,1.0.0.1 name=blsp.at verify-doh-cert=no +add comment=Kra dns-servers=1.0.0.1,1.1.1.1 name=slon2.to verify-doh-cert=no +add dns-servers=1.1.1.1,1.0.0.1 name=slon3.at verify-doh-cert=no +add dns-servers=1.0.0.1,1.1.1.1 name=slon3.cc verify-doh-cert=no +add dns-servers=1.1.1.1,1.0.0.1 name=bs2web.at verify-doh-cert=no +add dns-servers=1.1.1.1,1.0.0.1 name=bs2best.at verify-doh-cert=no +add dns-servers=1.0.0.1,1.1.1.1 name=psrms.is verify-doh-cert=no +/ip ipsec proposal +set [ find default=yes ] disabled=yes +/ip pool +add name=dhcp ranges=10.30.30.83-10.30.30.254 +/ip smb users +set [ find default=yes ] disabled=yes +add disabled=yes name=vados +/ppp profile +set *FFFFFFFE use-upnp=no +/routing bgp template +set default disabled=no output.network=bgp-networks +/routing table +add disabled=no fib name=To-VPN +/system logging action +add email-start-tls=yes email-to=vados@vados.ru name=email target=email +/system script +add dont-require-permissions=no name=fetchCustom owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + /tool/fetch mode=https url=(\$GlobalScriptsUrl . #\".bak/mikro_bak_rsa@10.\ + 30.30.86.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.86.pub\";\ + \n#:local Script AM-setup\ + \n#/system/script/add name=\$Script owner=\$Script source=([ /tool/fetch c\ + heck-certificate=yes-without-crl url=(\$GlobalScriptsUrl . \$Script . \".r\ + sc\") output=user as-value ]->\"data\");\ + \n#/usb1/mikro_bak_rsa.pub\ + \n\ + \n#\ + \n#/tool/fetch mode=https url=(\$GlobalScriptsUrl . \".bak/mikro_bak_rsa@1\ + 0.30.30.10.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.10.pub\";\ + \n#\ + \n#root.mnuc.backuper\ + \n\ + \n#/tool/fetch mode=https url=(\$GlobalScriptsUrl . \".bak/mikro_bak_rsa@1\ + 0.30.30.81.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.81.pub\";\ + \n#:local Script AM-GlobalConfig;\ + \n#/system/script/add name=\$Script owner=\$Script source=([ /tool/fetch c\ + heck-certificate=yes-without-crl url=(\$GlobalScriptsUrl . \$Script . \".r\ + sc\") output=user as-value ]->\"data\");\ + \n#/usb1/mikro_bak_rsa.pub\ + \n#:local FetchFile AM-DOHCert.rsc\ + \n\ + \n:global GlobalScriptsUrl \"https://ros.vados.ru/tmp/\";\ + \n:global MkDir;\ + \n\ + \n:local FetchFile Binary.backup\ + \n:local localDir \"\";\ + \n\ + \n#\$MkDir \$localDir;\ + \n\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \$FetchFile) dst-path=(\ + \$localDir . \$FetchFile);" +add comment="Example add WU servers to AddrList" dont-require-permissions=no \ + name=WU-add-to-list owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + \_Script to add target web sites DNS IP addresses into address list\r\ + \n# Tested with Mikrotik 6.4x\r\ + \n# Syed Jahanzaib / aacable@hotmail.com\r\ + \n# List name\r\ + \n:local LISTNAME \"windowsupdateslist\"\r\ + \n# Web site names which will be added in address list\r\ + \n:local TARGET1 \"update.microsoft.com\"\r\ + \n:local TARGET2 \"download.windowsupdate.com\"\r\ + \n:local TARGET3 \"download.microsoft.com\"\r\ + \n:local TARGET4 \"windowsupdate.com\"\r\ + \n:local TARGET5 \"ntservicepack.microsoft.com\"\r\ + \n:local TARGET6 \"wustat.windows.com\"\r\ + \n:local TARGET7 \"stats.microsoft.com\"\r\ + \n:local TARGET8 \"mp.microsoft.com\"\r\ + \n:local TARGET9 \"ws.microsoft.com\"\r\ + \n:local TARGET10 \"sls.update.microsoft.com.akadns.net\"\r\ + \n:local TARGET11 \"vortex.data.microsoft.com\"\r\ + \n:local TARGET12 \"vortex-win.data.microsoft.com\"\r\ + \n:local TARGET13 \"fe2.update.microsoft.com.akadns.net\"\r\ + \n:local TARGET14 \"statsfe2.update.microsoft.com.akadns.net\"\r\ + \n \r\ + \n# 1st time runner, check if address list is not created previously and a\ + dd entries in it for 1st time usage\r\ + \n:if ( [/ip firewall address-list find where list=\$LISTNAME] = \"\") do=\ + {\r\ + \n:log warning \"No address list for \$TARGET1 found ! creating and adding\ + \_resolved entry for 1st time usage ... zaib\"\r\ + \n \r\ + \n:local FirstAddr [resolve \$TARGET1];\r\ + \n\r\ + \n/ip firewall address-list add address=\$FirstAddr list=\$LISTNAME commen\ + t=\$TARGET1;\r\ + \n} else={\r\ + \n:log warning \"Previous List for \$LISTNAME found ! moving forward and c\ + hecking if DNS entries can be added in it ...\"\r\ + \n}\r\ + \n \r\ + \n# Check DNS entries and collect matching names\r\ + \n:foreach i in=[/ip dns cache find name~\"(\$TARGET1|\$TARGET2|\$TARGET3|\ + \$TARGET4|\$TARGET5|\$TARGET6|\$TARGET7|\$TARGET8|\$TARGET9|\$TARGET10|\$T\ + ARGET11|\$TARGET12|\$TARGET13|\$TARGET14)\" && \$type ~ \"^(A|CNAME)\\\$\"\ + \_] do={\r\ + \n \r\ + \n# Get IP Address from the names and hold it in temporary buffer\r\ + \n:local Buffer [/ip dns cache get \$i data];\r\ + \ndelay delay-time=10ms\r\ + \n \r\ + \n# Check if entry is already not exists, then OK, otherwise ignore duplic\ + ation\r\ + \n:if ( [/ip firewall address-list find where address=\$Buffer] = \"\") do\ + ={\r\ + \n \r\ + \n# Fetch DNS names for the entries\r\ + \n:local sitednsname [/ip dns cache get \$i name] ;\r\ + \n \r\ + \n# Print name in LOG window\r\ + \n:log info (\"added entry: \$sitednsname \$Buffer\");\r\ + \n \r\ + \n# Add IP addresses and there names to the address list\r\ + \n/ip firewall address-list add address=\$Buffer list=\$LISTNAME comment=\ + \$sitednsname;\r\ + \n}\r\ + \n}" +add comment="Add Hosts DNS names to NoWG addres list" \ + dont-require-permissions=no name=Add2vdsina owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + \_Script to add target web sites DNS IP addresses into address list\r\ + \n# Tested with Mikrotik 6.4x\r\ + \n# \r\ + \n# List name\r\ + \n:local LISTNAME \"NoWG\"\r\ + \n#\r\ + \n# Web site names which will be added in address list\r\ + \n:local TARGET1 \"comp-lenta.ru\"\r\ + \n:local TARGET2 \"ok.ru\"\r\ + \n:local TARGET3 \"vk.com\"\r\ + \n#:local TARGET4 \"smtp.mail.me.com\"\r\ + \n#:local TARGET4 \"windowsupdate.com\"\r\ + \n#:local TARGET5 \"ntservicepack.microsoft.com\"\r\ + \n#:local TARGET6 \"wustat.windows.com\"\r\ + \n#:local TARGET7 \"stats.microsoft.com\"\r\ + \n#:local TARGET8 \"mp.microsoft.com\"\r\ + \n#:local TARGET9 \"ws.microsoft.com\"\r\ + \n#:local TARGET10 \"sls.update.microsoft.com.akadns.net\"\r\ + \n#:local TARGET11 \"vortex.data.microsoft.com\"\r\ + \n#:local TARGET12 \"vortex-win.data.microsoft.com\"\r\ + \n#:local TARGET13 \"fe2.update.microsoft.com.akadns.net\"\r\ + \n#:local TARGET14 \"statsfe2.update.microsoft.com.akadns.net\"\r\ + \n \r\ + \n# 1st time runner, check if address list is not created previously and a\ + dd entries in it for 1st time usage\r\ + \n:if ( [/ip firewall address-list find where list=\$LISTNAME] = \"\") do=\ + {\r\ + \n:log warning \"No address list for \$TARGET1 found ! creating and adding\ + \_resolved entry for 1st time usage ... zaib\"\r\ + \n\r\ + \n:local FirstAddr [resolve \$TARGET1];\r\ + \n\r\ + \n/ip firewall address-list add address=\$FirstAddr list=\$LISTNAME commen\ + t=\$TARGET1;\r\ + \n\r\ + \n} else={\r\ + \n:log warning \"Previous List for \$LISTNAME found ! moving forward and c\ + hecking if DNS entries can be added in it ...\"\r\ + \n}\r\ + \n\r\ + \n# Check DNS entries and collect matching names\r\ + \n:foreach i in=[/ip dns cache find name~\"(\$TARGET1|\$TARGET2|\$TARGET3|\ + \$TARGET4)\" && \$type ~ \"^(A|CNAME)\\\$\" ] do={\r\ + \n\r\ + \n:log info (\"start entry: \$c \$sitednsname \$Buffer\");\r\ + \n\r\ + \n# Get IP Address from the names and hold it in temporary buffer\r\ + \n:local Buffer [/ip dns cache get \$i data];\r\ + \ndelay delay-time=10ms\r\ + \n:log info (\"1: \$Buffer\"); \r\ + \n\r\ + \n# Check if entry is already not exists, then OK, otherwise ignore duplic\ + ation\r\ + \n:if ( [/ip firewall address-list find where address=\$Buffer] = \"\") do\ + ={\r\ + \n\r\ + \n:log info (\"2: \$Buffer\"); \r\ + \n \r\ + \n# Fetch DNS names for the entries\r\ + \n:local sitednsname [/ip dns cache get \$i name] ;\r\ + \n \r\ + \n# Print name in LOG window\r\ + \n:log info (\"added entry: \$i \$sitednsname \$Buffer\");\r\ + \n \r\ + \n# Add IP addresses and there names to the address list\r\ + \n/ip firewall address-list add address=\$Buffer list=\$LISTNAME comment=\ + \$sitednsname;\r\ + \n}\r\ + \n}" +add comment="Flush DNS Cache" dont-require-permissions=no name=\ + DNS_Flush_Cache owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=\ + "/ip dns cache flush" +add comment="Certificates CloudFlare, Quad9 " dont-require-permissions=no \ + name=Update-Certificates owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + \_CloudFlare\r\ + \n#/tool/fetch mode=https url=https://cacerts.digicert.com/DigiCertGlobalR\ + ootCA.crt.pem;\r\ + \n#/certificate/import file-name=DigiCertGlobalRootCA.crt.pem passphrase=\ + \"\";\r\ + \n#/tool/ fetch mode=https url=https://cacerts.digicert.com/DigiCertGlobal\ + G2TLSRSASHA2562020CA1-1.crt.pem;\r\ + \n#/certificate/import file-name=DigiCertGlobalG2TLSRSASHA2562020CA1-1.crt\ + .pem passphrase=\"\";\r\ + \n# Quad9\r\ + \n#/tool/fetch mode=https url=\"https://cacerts.digicert.com/DigiCertGloba\ + lG3TLSECCSHA3842020CA1-1.crt.pem\"\r\ + \n#/certificate/import file-name=DigiCertGlobalG3TLSECCSHA3842020CA1-1.crt\ + .pem passphrase=\"\";\r\ + \n\r\ + \n:global GlobalScriptsUrl;\r\ + \n#google\r\ + \n:local CertName \"DigiCert-Global-Root-CA.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Global-Root-CA\" [ find where common-na\ + me=\"DigiCert Global Root CA\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Assured-ID-Root-CA.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Assured-ID-Root-CA\" [ find where commo\ + n-name=\"DigiCert Assured ID Root CA\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Assured-ID-Root-G2.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Assured-ID-Root-G2\" [ find where commo\ + n-name=\"DigiCert Assured ID Root G3\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Assured-ID-Root-G3.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Assured-ID-Root-G3\" [ find where commo\ + n-name=\"DigiCert Assured ID Root G3\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Global-G2-TLS-RSA-SHA256-2020-CA1.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Global-G2-TLS-RSA-SHA256-2020-CA1\" [ f\ + ind where common-name=\"DigiCert Global G2 TLS RSA SHA256 2020 CA1\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Global-G3-TLS-ECC-SHA384-2020-CA1.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Global-G3-TLS-ECC-SHA384-2020-CA1\" [ f\ + ind where common-name=\"DigiCert Global G3 TLS ECC SHA384 2020 CA1\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Global-Root-G2.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Global-Root-G2\" [ find where common-na\ + me=\"DigiCert Global Root G2\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Global-Root-G3.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Global-Root-G3\" [ find where common-na\ + me=\"DigiCert Global Root G3\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-TLS-ECC-P384-Root-G5.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-TLS-ECC-P384-Root-G5\" [ find where com\ + mon-name=\"DigiCert TLS ECC P384 Root G5\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-TLS-RSA4096-Root-G5.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-TLS-RSA4096-Root-G5\" [ find where comm\ + on-name=\"DigiCert TLS RSA4096 Root G5\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Trusted-Root-G4.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Trusted-Root-G4\" [ find where common-n\ + ame=\"DigiCert Trusted Root G4\" ];\r\ + \n\r\ + \n:set CertName \"GTS-Root-R4.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"GTS-Root-R4\" [ find where common-name=\"GTS Roo\ + t R4\" ];\r\ + \n\r\ + \n:set CertName \"Go-Daddy-Root-Certificate-Authority-G2.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"Go-Daddy-Root-Certificate-Authority-G2\" [ find \ + where common-name=\"Go Daddy Root Certificate Authority - G2\" ];\r\ + \n\r\ + \n:set CertName \"ISRG-Root-X1.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"ISRG-Root-X1\" [ find where common-name=\"ISRG R\ + oot X1\" ];\r\ + \n\r\ + \n:set CertName \"Root-YE.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"Root-YE\" [ find where common-name=\"Root YE\" ]\ + ;\r\ + \n\r\ + \n:set CertName \"Starfield-Root-Certificate-Authority-G2.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"Starfield-Root-Certificate-Authority-G2\" [ find\ + \_where common-name=\"Starfield Root Certificate Authority - G2\" ];\r\ + \n\r\ + \n:set CertName \"USERTrust-RSA-Certification-Authority.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"USERTrust-RSA-Certification-Authority\" [ find w\ + here common-name=\"USERTrust RSA Certification Authority\" ];\r\ + \n\r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n#:set CertName \"GTS-Root-RX.pem\";\r\ + \n#/tool/fetch mode=https url=(\$AmScriptsUrl . \"certs/\" . \$CertName);\ + \r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n#internet\r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n#:set CertName \"ISRG-Root-X2.pem\";\r\ + \n#/tool/fetch mode=https url=(\$AmScriptsUrl . \"certs/\" . \$CertName);\ + \r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n\r\ + \n\r\ + \n#/ip/dns/set allow-remote-requests=yes doh-max-concurrent-queries=100 do\ + h-max-server-connections=20 use-doh-server=https://security.cloudflare-dns\ + .com/dns-query verify-doh-cert=yes;\r\ + \n#/ip/dns/static remove [find where address=1.1.1.1];\r\ + \n#/ip/dns/static add address=1.1.1.1 name=security.cloudflare-dns.com com\ + ment=\"cloudflare-dns IPv4 1\";\r\ + \n#/ip/dns/ static remove [find where address=1.0.0.1];\r\ + \n#/ip/dns/static add address=1.0.0.1 name=security.cloudflare-dns.com com\ + ment=\"cloudflare-dns IPv4 2\"\r\ + \n#/ip dns static add address=2606:4700:4700::1111 name=security.cloudflar\ + e-dns.com type=AAAA\r\ + \n#/ip dns static add address=2606:4700:4700::1001 name=security.cloudflar\ + e-dns.com type=AAAA\r\ + \n#/ip/dns set servers=\"1.0.0.1, 8.8.4.4\";\r\ + \n#/ip/dns set servers=\"\";" +add dont-require-permissions=no name=script1 owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="/\ + tool/netwatch/add comment=\"doh-fallback, doh-url=https://security.cloudfl\ + are-dns.com/dns-query, doh-cert=DigiCert Global Root CA, notify, name=Clou\ + dFlare-doh IPv4 1\" host=1.1.1.1;\r\ + \n/tool/netwatch/add comment=\"doh, doh-url=https://security.cloudflare-dn\ + s.com/dns-query, doh-cert=DigiCert Global Root CA, notify, name=CloudFlare\ + -doh IPv4 2\" host=1.0.0.1;\r\ + \n/tool/netwatch/add comment=\"doh-fallback, dns-fallback, doh-url=https:/\ + /dns.google/dns-query, doh-cert=DigiCert Global Root G2, notify, name=Goog\ + le-doh IPv4 1\" host=8.8.8.8;\r\ + \n/tool/netwatch/add comment=\"doh-fallback, dns-fallback, doh-url=https:/\ + /dns.google/dns-query, doh-cert=DigiCert Global Root G2, notify, name=Goog\ + le-doh IPv4 2\" host=8.8.4.4;\r\ + \n/tool/netwatch/add comment=\"doh-fallback, dns-fallback, doh-url=https:/\ + /dns.quad9.net/dns-query, doh-cert=DigiCert Global Root G3, notify, name=C\ + uad9-doh IPv4 1\" host=9.9.9.9;\r\ + \n/tool/netwatch/add comment=\"doh-fallback, dns-fallback, doh-url=https:/\ + /dns.quad9.net/dns-query, doh-cert=DigiCert Global Root G3, notify, name=C\ + uad9-doh IPv4 2\" host=149.112.112.112;\r\ + \n\r\ + \n/tool/netwatch/add comment=\"dns, notify, name=ns1.unet.ws\" host=91.192\ + .189.2;" +add dont-require-permissions=no name=script2 owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + \r\ + \n\r\ + \n:global InspectVar;\r\ + \n#:global RouterBoard;\r\ + \n#:do {:set RouterBoard [[ :parse \"/system/routerboard/get\" ]]} on-erro\ + r={}\r\ + \n#:global Resources;\r\ + \n#:do {:set Resources [[ :parse \"/system/resource/get\" ]]} on-error={}\ + \r\ + \n\r\ + \n#:global Updates;\r\ + \n#:do {:set Updates [[ :parse \"/system/package/update/get\" ]]} on-error\ + ={}\r\ + \n\r\ + \n#:global PkgUpdStatus \"undefined\";\r\ + \n#:local Update [/system/package/update/get];\r\ + \n#:retry command={:set PkgUpdStatus (\$Update->\"status\")} delay=200ms m\ + ax=5 on-error={};\r\ + \n\r\ + \n#:log warning [\$InspectVar \$RouterBoard];\r\ + \n#:put [\$InspectVar \$RouterBoard];\r\ + \n\r\ + \n#:retry command={/system/package/update check-for-updates without-paging\ + \_as-value} delay=300ms max=5 on-error={};\r\ + \n\r\ + \n#:global arrDeviceInfo ({});\r\ + \n#:local arrDeviceInfo ({\"section\":{\"key\":\"\"; \"value\":\"\";};});\ + \r\ + \n#:set (\$arrDeviceInfo->\"RouterBoard\") [[ :parse \"/system/routerboard\ + /get\" ]];\r\ + \n#:retry command={:set (\$arrDeviceInfo->\"Updates\") [[ :parse \"/system\ + /package/update/get\" ]]} delay=500ms max=5 on-error={:log error (\"Error\ + \")};\r\ + \n# [:toarray {\"section\"={\"key\"=\"\"; \"value\"=\"\";} }];\r\ + \n# [:toarray \"\"];\r\ + \n:local arrDeviceInfo ({});\r\ + \n\r\ + \n:set (\$arrDeviceInfo->\"devUpdates\") {\"channel\"; \"stable\";};\r\ + \n#:do {:set (arrDeviceInfo->\"Updates\") [[ :parse \"/system/package/upda\ + te/get\" ]]} on-error={:log error (\$error)}\r\ + \n\$InspectVar \$arrDeviceInfo;\r\ + \n" +add comment="Script for setup routeros script system" \ + dont-require-permissions=no name=AM-setup owner=AM-setup policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + !rsc by Vados\r\ + \n# RouterOS script: AM-setup\r\ + \n# Script comment: Script for setup routeros script system\r\ + \n# Copyright (c) 2005-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n# requires device-mode, fetch\r\ + \n#\r\ + \n# :local ScriptName [ :jobname ];\r\ + \n# Additional commands:\r\ + \n#\r\ + \n# For scripts:\r\ + \n#:global NewScript \"script_name\"; \r\ + \n#:global GlobalScriptsUrl \"https://ros.vados.ru/\";\r\ + \n#/system/script/add name=\$NewScript owner=\$NewScript source=([/tool/fe\ + tch check-certificate=yes-without-crl (\$GlobalScriptsUrl . \$ScriptAdd . \ + \".rsc\") output=user as-value ]->\"data\");\r\ + \n#:global NewScript (a);\r\ + \n#:global ScriptInstallUpdate; \$ScriptInstallUpdate;\r\ + \n#\r\ + \n# For run from terminal:\r\ + \n#/system/script/add name=AM-setup owner=AM-Setup source=([/tool/fetch ch\ + eck-certificate=yes-without-crl \"https://ros.vados.ru/AM-setup.rsc\" outp\ + ut=user as-value ]->\"data\");\r\ + \n#\r\ + \n\r\ + \n:global ScriptUpdatesCRLF \"LF\";\r\ + \n#:if (\$ScriptUpdatesCRLF != false) do={\r\ + \n# :foreach Script in=[ /system/script/find where source~\"^#!rsc by Vad\ + os\" ] do={\r\ + \n# if (\$ScriptUpdatesCRLF = true) do={\r\ + \n# /system/script/set source=[ :tocrlf [ get \$Script source ] ] \$S\ + cript;\r\ + \n# } else={\r\ + \n# /system/script/set source=[ :tolf [ get \$Script source ] ] \$Scr\ + ipt;\r\ + \n# }\r\ + \n# }\r\ + \n#}\r\ + \n\r\ + \n# /import verbose=no \$ScriptName\r\ + \n:global Identity [/system/identity/get name];\r\ + \n:global SetupScript [ :jobname ];\r\ + \n:global RemoveMe true;\r\ + \n:global RunOnce (a);\r\ + \n:global InitSetup true;\r\ + \n:global tmpfs false;\r\ + \n\r\ + \n{\r\ + \n :local RmMe [:tobool \$1];\r\ + \n\r\ + \n :global GlobalScriptsUrl;\r\ + \n :global SetupScript;\r\ + \n :global RemoveMe;\r\ + \n :global InitSetup;\r\ + \n :global tmpfs;\r\ + \n\r\ + \n :local UrlSuffix \$Identity;\r\ + \n :local UrlDir \"certs/\";\r\ + \n :local CertUrl (\$GlobalScriptsUrl . \$UrlDir . \$UrlSuffix .\"/\"); \ + \r\ + \n :local CertCommonName \"Root YE\";\r\ + \n :local CertFileName \"Root-YE.pem\";\r\ + \n :local CertFingerprint \"e14ffcad5b0025731006caa43a121a22d8e9700f4fb9c\ + f852f02a708aa5d5666\";\r\ + \n\r\ + \n :if (\$SetupScript = false) do={\r\ + \n :global SetupScript \"AM-setup\";\r\ + \n }\r\ + \n :if (\$RemoveMe != false) do={\r\ + \n :set RemoveMe true;\r\ + \n }\r\ + \n\r\ + \n :log warning (\"\\n\\\$GlobalScriptsUrl = \" . \$GlobalScriptsUrl);\r\ + \n \r\ + \n\r\ + \n :if (!(((\$CertSettings->\"builtin-trust-anchors\") = \"trusted\" ||\ + \_\\\r\ + \n (\$CertSettings->\"builtin-trust-store\") ~ \"fetch\" || \\\r\ + \n (\$CertSettings->\"builtin-trust-store\") = \"all\") && \\\r\ + \n [ :len [ /certificate/builtin/find where common-name=\$CertComm\ + onName ] ] > 0)) do={\r\ + \n :put \"Importing certificate...\";\r\ + \n /tool/fetch (\$CertUrl . \$CertFileName) dst-path=\$CertFileName\ + \_as-value;\r\ + \n :delay 1s;\r\ + \n /certificate/import file-name=\$CertFileName passphrase=\"\";\r\ + \n /certificate/set name=\"Root-YE\" [ find where common-name=\"Roo\ + t YE\" ];\r\ + \n :delay 1s;\r\ + \n };\r\ + \n :local CertSettings [ /certificate/settings/get ];\r\ + \n :if ([ :len [ /certificate/find where fingerprint=\$CertFingerprint ] \ + ] != 1) do={\r\ + \n :error \"Something is wrong with your certificates!\";\r\ + \n };\r\ + \n\r\ + \n:local MkTmpfs do={\r\ + \n :local TmpFs [ /disk/find where slot=tmpfs type=tmpfs ];\r\ + \n :if ([ :len \$TmpFs ] = 1) do={\r\ + \n :if ([ /disk/get \$TmpFs disabled ] = true) do={\r\ + \n :log info (\"The tmpfs is disabled, enabling.\");\r\ + \n /disk/enable \$TmpFs;\r\ + \n }\r\ + \n :return true;\r\ + \n }\r\ + \n :log info (\"Try to removing directory 'tmpfs'.\");\r\ + \n :do {\r\ + \n :retry {\r\ + \n /file/remove tmpfs;\r\ + \n :return true;\r\ + \n } delay=100ms max=10;\r\ + \n } on-error={ }\r\ + \n# \$RmDir \"tmpfs\";\r\ + \n :onerror Err {\r\ + \n /disk/add slot=tmpfs type=tmpfs tmpfs-max-size=([ /system/resource/g\ + et total-memory ] / 3);\r\ + \n :do {\r\ + \n :retry {\r\ + \n /file/get tmpfs;\r\ + \n :return true;\r\ + \n } delay=222ms max=10;\r\ + \n } on-error={ }\r\ + \n } do={\r\ + \n :log warning (\"Creating disk of type tmpfs failed: \" . \$Err);\r\ + \n :return false;\r\ + \n }\r\ + \n# :return true;\r\ + \n}\r\ + \n:if (\$tmpfs = true) do={\r\ + \n :put \"Tmpfs variable is true. Checking for tmpfs/scripts directory...\ + \";\r\ + \n :if ([/file find name=\"tmpfs/scripts\"] != \"\") do={\r\ + \n :log info (\$0 . \"Directory tmpfs/scripts exsist.\");\r\ + \n :return \$true;\r\ + \n } else={\r\ + \n :log warning (\$0 . \"Directory tmpfs/scripts does't exsist.\");\r\ + \n :if ([ \$MkTmpfs ] = false) do={\r\ + \n :log error (\$0 . \"Directory tmpfs is not created!\");\r\ + \n :return false;\r\ + \n } else={\r\ + \n :onerror Err {\r\ + \n /file/add type=\"directory\" name=/tmpfs/scripts;\r\ + \n :do {\r\ + \n :retry {\r\ + \n /file/get /tmpfs/scripts;\r\ + \n :return true;\r\ + \n } delay=100ms max=10;\r\ + \n } on-error={ }\r\ + \n } do={\r\ + \n :log warning (\$0 . \"Making directory 'scripts' failed: \" . \$\ + Err);\r\ + \n :return false;\r\ + \n }\r\ + \n# :return true;\r\ + \n# [ /file/get \$FileName ]\r\ + \n }\r\ + \n# :log error (\$0 . \"Directory tmpfs/scripts does not exsist. Remove\ + \_global variable tmpfs!\");\r\ + \n# :global tmpfs (a);\r\ + \n# return false;\r\ + \n }\r\ + \n}\r\ + \n :put \"Renaming AM-GlobalConfig, if exists...\";\r\ + \n :local ConfOldName (\"AM-GlobalConfig-\" . [ /system/clock/get date ] \ + . [ /system/clock/get time ] . \".rsc\");\r\ + \n /system/script/set name=\$ConfOldName [ find where name=\"AM-GlobalCon\ + fig\" ];\r\ + \n :foreach Script in={ \"AM-GlobalConfig\"; \"AM-GlobalFunc\"; \"mod/AM-\ + Certs-By-Ident\" } do={\r\ + \n :put \"Installing \$Script...\";\r\ + \n /system/script/remove [ find where name=\$Script ];\r\ + \n /system/script/add name=\$Script owner=\$Script source=([ /tool/fetc\ + h check-certificate=yes-without-crl url=(\$GlobalScriptsUrl . \$Script . \ + \".rsc\") output=user as-value ]->\"data\");\r\ + \n \r\ + \n /system/script run \$Script;\r\ + \n :delay 2s;\r\ + \n };\r\ + \n\r\ + \n :if ([ :len [ /certificate/find where fingerprint=\$CertFingerprint ] \ + ] > 0) do={\r\ + \n :put \"Renaming certificate by its common-name...\";\r\ + \n :global CertificateNameByCN;\r\ + \n \$CertificateNameByCN \$CertFingerprint;\r\ + \n };\r\ + \n\r\ + \n :if (\$RemoveMe = true) do={\r\ + \n :put \"Add Scheduler for remove this script...\";\r\ + \n :local OnEvent (\":delay 30s;\\n\" . \"/system/script/remove [ find \ + where name=\\\"\$SetupScript\\\" ];\\n\" . \\\r\ + \n \":delay 2s;\\n\" . \"/system/scheduler/remove [ find where name=\\\ + \"_RemoveSetup\\\" ];\\n\" . \\\r\ + \n \":delay 2s;\\n\" . \":global RemoveMe (a);\\n\");\r\ + \n :local Comment \"_RemoveSetup tmp scheduler for remove setup script.\ + \";\r\ + \n /system/scheduler/add name=\"_RemoveSetup\" comment=\$Comment start-\ + time=startup interval=30s on-event=\$OnEvent;\r\ + \n :log warning (\$0 . \"\\nI've done everything, and now I'm tired..\ + . I'm leaving.\\nThere will be an error below, this is normal.\");\r\ + \n }\r\ + \n :delay 1;\r\ + \n :put \"Loading configuration and functions...\";\r\ + \n :do { \r\ + \n :global ScriptInstallUpdate; \$ScriptInstallUpdate;\r\ + \n :put \"Normal removing temporary global environment variables.\";\ + \r\ + \n :global SetupScript (a);\r\ + \n :global InitSetup (a);\r\ + \n :global RemoveMe (a);\r\ + \n } on-error={\r\ + \n :local ErrorMsg \"Loading configuration and functions error!\";\r\ + \n :log error (\$0 . \$ErrorMsg . :error);\r\ + \n :error \$ErrorMsg;\r\ + \n }\r\ + \n}\r\ + \n" +add comment="Global Config Script" dont-require-permissions=no name=\ + AM-GlobalConfig owner=AM-GlobalConfig policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + !rsc by Vados\r\ + \n# RouterOS script: AM-GlobalConfig\r\ + \n# Script comment: Global Config Script\r\ + \n# Copyright (c) 2007-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# Warning: Dont touch this line!\r\ + \n:global Identity [/system/identity/get name];\r\ + \n:global GlobalConfReady false;\r\ + \n#\r\ + \n#\r\ + \n# Global Url For Amster scripts to fetch\r\ + \n# most be defined in AM-Init-Script or AM-setup scripts\r\ + \n:global GlobalScriptsUrl \"https://ros.vados.ru/\";\r\ + \n:global ScriptsUrlSuffix (a);\r\ + \n:global CheckSumsVerify true;\r\ + \n\r\ + \n:global ScriptUpdatesCRLF true;\r\ + \n:global CommentsInScripts true;\r\ + \n\r\ + \n# Debug output:\r\ + \n:global PrintDebug true; #false;\r\ + \n\r\ + \n# Debug output for specific script:\r\ + \n#:set (\$PrintDebugOverride->\"AM-GlobalFunc\") true;\r\ + \n\r\ + \n# Debug logs\r\ + \n# Other actions (disk, email, remote or support) can be used as well.\r\ + \n# I do not recommend using echo - use debug output instead (https://rsc.\ + eworm.de/main/DEBUG.html#debug-output).\r\ + \n#/system/logging/add topics=script,debug action=memory;\r\ + \n\r\ + \n:global MikrotikUpgradeUrl \"https://upgrade.mikrotik.com/routeros\";\r\ + \n:global Domain \"WORKGROUP\";\r\ + \n\r\ + \n:global EmailGeneralTo \"vados@vados.ru\";\r\ + \n#:global EmailGeneralCc \"\";\r\ + \n\r\ + \n# \$ScriptInstallUpdate mod/notification-telegram\r\ + \n:global TelegramTokenId \"8390868324:AAG3_d1hfVR2M6pGAgDK6ZvhOe4J97nyopw\ + \";\r\ + \n:global TelegramChatId \"-1003631309063\"; #\"454403445\";\r\ + \n# Use this to send notifications to a specific topic in group.\r\ + \n#:global TelegramThreadId \"30\";\r\ + \n# Using telegram-chat you have to define trusted chat ids (not group ids\ + !)\r\ + \n# or user names. Groups allow to chat with devices simultaneously.\r\ + \n:global TelegramChatIdsTrusted {\r\ + \n \"454403445\"\r\ + \n \"-1003631309063\"\r\ + \n \"-5124482807\"\r\ + \n \"1087968824\";\r\ + \n};\r\ + \n# \"-5294757340\";\r\ + \n\r\ + \n:global TelegramChatGroups \"(all)\";\r\ + \n#:global TelegramChatGroups \"(all|home|office)\";\r\ + \n\r\ + \n:global NotificationFunctions {\r\ + \n \"email\"\r\ + \n \"telegram\";\r\ + \n};\r\ + \n# Toggle this to disable symbols in notifications.\r\ + \n:global NotificationsWithSymbols true;\r\ + \n:global TerminalColorOutput true;\r\ + \n\r\ + \n:global DetectIpAddrDefault \"https://ipv4.mikrotik.ovh/\";\r\ + \n:global DetectIpAddrFallback \"https://api.ipify.org/\";\r\ + \n\r\ + \n## Update channel. Possible values: stable, long-term, testing, developm\ + ent\r\ + \n:global updateChannel \"stable\";\r\ + \n\r\ + \n:global CertRenewUrl (\$GlobalScriptsUrl . \"certs/\" . \$Identity . \"/\ + \");\r\ + \n:global CertRenewTime 2w;\r\ + \n:global CertRenewPass (a); #{\r\ + \n# \"\";\r\ + \n# \"v3ry-s3cr3t\";\r\ + \n# \"4n0th3r-s3cr3t\";\r\ + \n#};\r\ + \n:global CertWarnTime 1w;\r\ + \n:global CertIssuedExportPass (a); # {\r\ + \n# \"\";\r\ + \n# \"cert1-cn\"=\"v3ry-s3cr3t\";\r\ + \n# \"cert2-cn\"=\"4n0th3r-s3cr3t\";\r\ + \n#};\r\ + \n\r\ + \n# Script BackupAndUpdate mode, possible values: backup,\r\ + \n# updateOnce - Update once as \"osnotify\" and back \"osnotify\" mode (i\ + n terminal run :set OSUpdateMode updateOnce; \$OSUpdateMode;). \r\ + \n# osupdate - Update if available and creates backups before/after update\ + \_(ignores `forceBackup`)\r\ + \n# Set `forceBackup` to true to always create backups, even\ + \_without updates\r\ + \n# osnotify - Set `forceBackup` to always create backups on every run\r\ + \n:global DevInfoIncludeIP true;\r\ + \n:global BackupAndUpdateMode \"osnotify\"\r\ + \n\r\ + \n:global forceBackup true;\r\ + \n:global BackupPassword \"Peskar55\";\r\ + \n\r\ + \n# SFTP Backup Variables\r\ + \n:global BackupRandomDelay 0;\r\ + \n:global BackupUploadUrl \"sftp://amster.vados.ru/upload/\";\r\ + \n:global BackupUploadUser \$Identity;\r\ + \n:global BackupUploadPass \"root.mnuc.backuper\";\r\ + \n\r\ + \n:global BackupSendBinary true;\r\ + \n:global BackupSendExport true;\r\ + \n:global BackupSendGlobalConfig true;\r\ + \n:global BackupSendScripts true;\r\ + \n\r\ + \n# Remove local file after uploading if no errors\r\ + \n:global BackupRmLocal true;\r\ + \n\r\ + \n# Local Backups Root Directory \r\ + \n:global BackupLocalRoot \"tmpfs\";\r\ + \n\r\ + \n# Encrypt Backup\r\ + \n:global BackupEncrypt true;\r\ + \n\r\ + \n# Sensitive information in Backups\r\ + \n:global BackupSens true;\r\ + \n\r\ + \n# User Export\r\ + \n:global BackupUser true;\r\ + \n\r\ + \n# License Export (not for CHR, will silently skip)\r\ + \n:global BackupLicense false;\r\ + \n\r\ + \n# SSH Keys\r\ + \n:global BackupSshKeys true;\r\ + \n\r\ + \n# Certificate Export\r\ + \n:global BackupCerts true;\r\ + \n\r\ + \n# Certificate Password\r\ + \n:global BackupCertsPasswd \"\";\r\ + \n\r\ + \n# User-Manager Export\r\ + \n:global BackupUserMan false;\r\ + \n\r\ + \n# The Dude Export\r\ + \n:global BackupDude false;\r\ + \n\r\ + \n# User Files to export, comma-separated string or array of strings\r\ + \n# User Files are not removed on backup\r\ + \n# Any directory paths will be removed (/ -> _) on remote file\r\ + \n# Nonpresent files are silently skipped\r\ + \n:global BackupUserList \"autosupout.rif,autosupout.old.rif\";\r\ + \n\r\ + \n# load functions and any custom scripts\r\ + \n# [ /system/script/find where name=\"global-config-ov\ + erlay\" ], \\\r\ + \n# [ /system/script/find where name~\"^global-config-o\ + verlay\\\\.d/.\" ]\r\ + \n#\r\ + \n#:foreach Script in=([ /system/script/find where name=\"Amster-TGglobalV\ + ars\" ], [ /system/script/find where name=\"Amster-TGglobalFunc\" ]) do={\ + \r\ + \n# :onerror Err {\r\ + \n# /system/script/run \$Script;\r\ + \n# } do={\r\ + \n# :log error (\"Loading configuration from configs and functions\"\ + \_. [ /system/script/get \$Script name ] . \" failed: \" . \$Err);\r\ + \n# }\r\ + \n#}\r\ + \n#:log info \"\\ndevMode = \$devMode\";\r\ + \n#:log info \"\\ndevRunning = \$devRunning\";\r\ + \n:foreach Script in=[ /system/script/find where source~\"^#!rsc by Vados \ + GlobalRUN\\r\?\\n\" ] do={\r\ + \n :onerror Err {\r\ + \n /system/script/run \$Script;\r\ + \n } do={\r\ + \n :log error (\"Run script \" . [ /system/script/get \$Script name \ + ] . \" width marker \\\" GlobalRUN\\\" failed: \" . \$Err);\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n# signal we are ready\r\ + \n:set GlobalConfReady true;\r\ + \n:while (\$GlobalConfReady != true) do={:delay 500ms};\r\ + \n" +add comment="Global functions" dont-require-permissions=no name=AM-GlobalFunc \ + owner=AM-GlobalFunc policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + !rsc by Vados\r\ + \n# RouterOS script: AM-GglobalFunc\r\ + \n# Script comment: Global functions\r\ + \n# Copyright (c) 2005-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n# requires device-mode, fetch, scheduler\r\ + \n:local ExitOK false;\r\ + \n:local ScriptName [ :jobname ];\r\ + \n#:global checkRunJob \$SriptName;\r\ + \n#:global fixCRLF;\r\ + \n#:if (\$fixCRLF != false) do={\r\ + \n#:foreach fixScript in=([ /system/script/find where name~\"*\" ]) do={/s\ + ystem/script/set source=[ :tocrlf [ get \$fixScript source ] ] \$fixScript\ + }\r\ + \n#:if (\$fixCRLF != \"LF\") do={ /system/script/set source=[ :tocrlf [ g\ + et \$fixScript source ] ] \$fixScript};};\r\ + \n#}\r\ + \n:global GlobalFuncReady false;\r\ + \n\r\ + \n# Git commit id & info, expected configuration version\r\ + \n:global CommitId \"main/633/2f6d4158\";\r\ + \n:global CommitTAG \"unknown\";\r\ + \n:global CommitInfo \"Autocommit in repo: ros.vados.ru, generated by owne\ + r: root, in 14:35:03 05.05.2026.\";\r\ + \n\r\ + \n# The variables are received right here.\r\ + \n:global GlobalConfVersion 140;\r\ + \n\r\ + \n:global SumsDirAndFileName \"tmp/checksums.json\";\r\ + \n\r\ + \n:global Identity [/system/identity/get name];\r\ + \n:global IdentityShort [:pick \$Identity 0 18];\r\ + \n\r\ + \n:global devBoardName [/system/resource/get board-name];\r\ + \n:global devMode [/system/device-mode/get mode];\r\ + \n:global devCurArch [/system/resource/get architecture-name];\r\ + \n:global devCurVersion [/system/resource/get version];\r\ + \n\r\ + \n# Variables defined in AM-GlobalConfig.rsc\r\ + \n:global TerminalColorOutput;\r\ + \n:global CommentsInScripts;\r\ + \n:global DetectIpAddrDefault;\r\ + \n:global DetectIpAddrFallback;\r\ + \n:global updateChannel;\r\ + \n:global Domain;\r\ + \n:global EmailGeneralTo;\r\ + \n:global BackupAndUpdateMode;\r\ + \n\r\ + \n# Single functions, without nested functions.\r\ + \n:global MiniDateTimeStamp;\r\ + \n:global MicroDateTimeStamp;\r\ + \n\r\ + \n# Include globals \$PrintDebug and \$PrintDebugOverride\r\ + \n:global LogPrint;\r\ + \n\r\ + \n# DeviceInfo and Updates\r\ + \n:global IsCheckUpdates;\r\ + \n:global WaitCheckUpdates;\r\ + \n:global GetPubIp;\r\ + \n\r\ + \n:global GetArrDeviceInfo;\r\ + \n:global WaitArrDeviceInfo;\r\ + \n\r\ + \n:global devModel;\r\ + \n:global devRunningMode;\r\ + \n\r\ + \n:global devRbRevision;\r\ + \n:global devRbSerialNumber;\r\ + \n:global devRbVerAvail;\r\ + \n\r\ + \n:global runningChannelVersion;\r\ + \n:global runningChannel;\r\ + \n:global runningVersion;\r\ + \n\r\ + \n:global devBuildTime;\r\ + \n:global ROsVerAvail;\r\ + \n:global PkgUpdStatus;\r\ + \n:global currentUpdateChannel;\r\ + \n\r\ + \n:global ScriptInstallUpdate;\r\ + \n\r\ + \n:global DeviceInfo;\r\ + \n\r\ + \n:global OldMode;\r\ + \n\r\ + \n:global ParseKeyValueStore;\r\ + \n:global RandomDelay;\r\ + \n:global GetRandomNumber;\r\ + \n:global EscapeForRegEx;\r\ + \n:global CharacterMultiply;\r\ + \n:global CharacterReplace;\r\ + \n:global CleanFilePath;\r\ + \n:global CleanName;\r\ + \n\r\ + \n:global CommitBrief;\r\ + \n\r\ + \n:global EitherOr;\r\ + \n:global FormatLine;\r\ + \n:global GetRandom20CharAlNum;\r\ + \n:global GetRandom20CharHex;\r\ + \n:global GetRandomNumber;\r\ + \n:global Grep;\r\ + \n:global IfThenElse;\r\ + \n:global MAX;\r\ + \n:global MIN;\r\ + \n:global HumanReadableNum;\r\ + \n\r\ + \n:global IsFullyConnected;\r\ + \n:global IsDNSResolving;\r\ + \n:global IsTimeSync;\r\ + \n:global IsTimeSyncCached;\r\ + \n:global IsTimeSyncResetNtp;\r\ + \n\r\ + \n:global WaitDNSResolving;\r\ + \n:global WaitFullyConnected;\r\ + \n:global WaitTimeSync;\r\ + \n:global MkDir;\r\ + \n:global RmDir;\r\ + \n:global RmFile;\r\ + \n:global FileGet;\r\ + \n:global Unix2Dos;\r\ + \n:global UrlEncode;\r\ + \n:global WaitForFile;\r\ + \n:global ScriptLock;\r\ + \n:global SendTelegram;\r\ + \n:global NotificationFunctions;\r\ + \n:global SendNotification;\r\ + \n:global SendNotification2;\r\ + \n:global SymbolForNotification;\r\ + \n:global SymbolByUnicodeName;\r\ + \n:global ValidateSyntax;\r\ + \n:global CheckSumsVerify;\r\ + \n:global GlobalConfChanges;\r\ + \n:global GlobalConfMigration;\r\ + \n:global VersionToNum;\r\ + \n:global RequiredRouterOS;\r\ + \n:global ExitError;\r\ + \n:global ExitOnError;\r\ + \n\r\ + \n:global FetchHugeFiles;\r\ + \n:global FetchUserAgentStr;\r\ + \n:global FileExists;\r\ + \n:global CertificateAvailable;\r\ + \n:global CertificateDownload;\r\ + \n:global CertificateNameByCN;\r\ + \n:global CharacterMultiply;\r\ + \n\r\ + \n:global InspectVar;\r\ + \n:global InspectVarRet;\r\ + \n:global ParseCustom;\r\ + \n\r\ + \n:set IsCheckUpdates do={\r\ + \n :local isInfo [:tobool \$1];\r\ + \n :global updateChannel;\r\ + \n :global PkgUpdStatus;\r\ + \n :global currentUpdateChannel;\r\ + \n :global ROsVerAvail;\r\ + \n :global arrDeviceInfo;\r\ + \n :log info (\$0 . \" \\\$isInfo = \" . \$isInfo); \r\ + \n :local CurrentChannel [ /system/package/update/get channel ];\r\ + \n :if ([ :len \$updateChannel ] > 0 && \$CurrentChannel != \$updateChann\ + el) do={\r\ + \n :retry command={/system/package/update set channel=\$updateChannel} \ + \_delay=300ms max=5 on-error={};\r\ + \n :log info (\$0 . \" Set updates channel to: \$updateChannel\");\r\ + \n }\r\ + \n :local Update [ /system/package/update/get ];\r\ + \n :local Channel [ :tostr (\$Update->\"channel\") ];\r\ + \n :set currentUpdateChannel \$Channel;\r\ + \n :log info (\$0 . \" Update Channel: \" . \$Channel . \".\");\r\ + \n :local StatusPkg \"undefined\";\r\ + \n :log info (\$0 . \" Checking for updates...\");\r\ + \n :retry command={:set \$StatusPkg ([/system/package/update/check-for-up\ + dates without-paging as-value]->\"status\")} \\\r\ + \n delay=300ms max=5 on-error={};\r\ + \n :log info (\$0 . \" \\\$StatusPkg = \" . \$StatusPkg);\r\ + \n :if (\$StatusPkg = \"New version is available\") do={ :set PkgUpdStatu\ + s true; } else={ :set PkgUpdStatus false; }\r\ + \n :set ROsVerAvail [ :tostr [ /system/package/update/get latest-version \ + ] ];\r\ + \n :log info (\$0 . \" \\\$PkgUpdStatus = \" . \$PkgUpdStatus);\r\ + \n :if (\$isInfo != false || \$PkgUpdStatus = true) do={\r\ + \n :log info (\$0 . \" \\\$PkgUpdStatus = \" . \$PkgUpdStatus);\r\ + \n :if ([ :typeof \$arrDeviceInfo ] != \"array\") do={\r\ + \n :set arrDeviceInfo [:toarray \$arrDeviceInfo];\r\ + \n }\r\ + \n :retry command={:set (\$arrDeviceInfo->\"devUpdates\") [ /system/pac\ + kage/update/get ]} delay=500ms max=5 on-error={:log error (\"Error\")};\r\ + \n :return true;\r\ + \n } else={\r\ + \n :return \$PkgUpdStatus;\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set WaitCheckUpdates do={\r\ + \n :global IsCheckUpdates;\r\ + \n :global PkgUpdStatus;\r\ + \n :global currentUpdateChannel;\r\ + \n :global ROsVerAvail;\r\ + \n :global arrDeviceInfo;\r\ + \n :local Status \"\";\r\ + \n :local Update;\r\ + \n :local WaitCount 0;\r\ + \n :if ([ \$IsCheckUpdates true ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n :set Status [ :tostr [ /system/package/update/get status ] ];\r\ + \n :while ((\$Status = \"\" || \$Status = \"finding out latest version...\ + \") && \$WaitCount < 60) do={\r\ + \n :delay 1s;\r\ + \n :set WaitCount (\$WaitCount + 1);\r\ + \n :set Status [ :tostr [ /system/package/update/get status ] ];\r\ + \n }\r\ + \n :set Update [ /system/package/update/get ];\r\ + \n :set currentUpdateChannel [ :tostr (\$Update->\"channel\") ];\r\ + \n :set ROsVerAvail [ :tostr (\$Update->\"latest-version\") ];\r\ + \n :if ((\$Update->\"status\") = \"New version is available\") do={\r\ + \n :set PkgUpdStatus true;\r\ + \n } else={\r\ + \n :set PkgUpdStatus false;\r\ + \n }\r\ + \n :if ([ :typeof \$arrDeviceInfo ] != \"array\") do={\r\ + \n :set arrDeviceInfo [:toarray \$arrDeviceInfo];\r\ + \n }\r\ + \n :set (\$arrDeviceInfo->\"devUpdates\") \$Update;\r\ + \n :if (\$Status = \"\" || \$Status = \"finding out latest version...\") \ + do={\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set WaitArrDeviceInfo do={\r\ + \n :global GetArrDeviceInfo;\r\ + \n :while ([ \$GetArrDeviceInfo ] = false) do={\r\ + \n :delay 1s;\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set GetArrDeviceInfo do={\r\ + \n :global LogPrint;\r\ + \n :global arrDeviceInfo;\r\ + \n :global devBoardName;\r\ + \n :global devModel;\r\ + \n :global devRunning;\r\ + \n :global devCurArch;\r\ + \n :global devRbRevision;\r\ + \n :global devRbSerialNumber;\r\ + \n :global devBuildTime;\r\ + \n :global runningChannelVersion;\r\ + \n :global runningChannel;\r\ + \n :global runningVersion;\r\ + \n :global currentUpdateChannel;\r\ + \n :global ROsVerAvail;\r\ + \n\r\ + \n :local DeviceInfo;\r\ + \n :local Resource [/system/resource/get];\r\ + \n :local Update [ /system/package/update/get ];\r\ + \n :local VersionString [ :tostr (\$Resource->\"version\") ];\r\ + \n :local ChannelStart [ :find \$VersionString \" (\" ];\r\ + \n :local RouterBoard;\r\ + \n :local IsRouterBoard false;\r\ + \n :local RunningMode \"\";\r\ + \n\r\ + \n :set devCurArch [ :tostr (\$Resource->\"architecture-name\") ];\r\ + \n :set devBuildTime [ :tostr (\$Resource->\"build-time\") ];\r\ + \n :set runningChannelVersion \$VersionString;\r\ + \n :set runningVersion \$VersionString;\r\ + \n :set runningChannel \"\";\r\ + \n\r\ + \n :if ([ :typeof \$ChannelStart ] = \"num\" && \$ChannelStart >= 0) do=\ + {\r\ + \n :set runningVersion [ :pick \$VersionString 0 \$ChannelStart ];\r\ + \n :local ChannelRest [ :pick \$VersionString (\$ChannelStart + 2) [ :\ + len \$VersionString ] ];\r\ + \n :local ChannelEnd [ :find \$ChannelRest \")\" ];\r\ + \n :if ([ :typeof \$ChannelEnd ] = \"num\" && \$ChannelEnd >= 0) do={\ + \r\ + \n :set runningChannel [ :pick \$ChannelRest 0 \$ChannelEnd ];\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :if ([:pick \$devBoardName 0 3] != \"CHR\" or [:pick \$devBoardName 0\ + \_3] != \"x86\") do={\r\ + \n :do {\r\ + \n :set RouterBoard [[ :parse \"/system/routerboard/get\" ]];\r\ + \n# :set RouterBoard [ /system/routerboard/get ];\r\ + \n :if ((\$RouterBoard->\"routerboard\") = true) do={\r\ + \n :set IsRouterBoard true;\r\ + \n }\r\ + \n } on-error={}\r\ + \n }\r\ + \n\r\ + \n :do {\r\ + \n :set RunningMode [ /system/device-mode/get mode ];\r\ + \n } on-error={\r\ + \n :do {\r\ + \n :set RunningMode [ /system/device-mode/get running ];\r\ + \n } on-error={\r\ + \n :set RunningMode \"\";\r\ + \n }\r\ + \n }\r\ + \n :set devRunning \$RunningMode;\r\ + \n\r\ + \n :if (\$IsRouterBoard = true) do={\r\ + \n :set devModel [ :tostr (\$RouterBoard->\"model\") ];\r\ + \n :set devRbRevision [ :tostr (\$RouterBoard->\"revision\") ];\r\ + \n :set devRbSerialNumber [ :tostr (\$RouterBoard->\"serial-number\") \ + ];\r\ + \n } else={\r\ + \n :set devModel \$devBoardName;\r\ + \n :set devRbRevision \"\";\r\ + \n :set devRbSerialNumber \"\";\r\ + \n }\r\ + \n\r\ + \n :set currentUpdateChannel [ :tostr (\$Update->\"channel\") ];\r\ + \n :set ROsVerAvail [ :tostr (\$Update->\"latest-version\") ];\r\ + \n\r\ + \n :set (\$DeviceInfo->\"board-name\") \$devBoardName;\r\ + \n :set (\$DeviceInfo->\"architecture-name\") \$devCurArch;\r\ + \n :set (\$DeviceInfo->\"model\") \$devModel;\r\ + \n :set (\$DeviceInfo->\"revision\") \$devRbRevision;\r\ + \n :set (\$DeviceInfo->\"serial-number\") \$devRbSerialNumber;\r\ + \n :set (\$DeviceInfo->\"running-mode\") \$devRunning;\r\ + \n :set (\$DeviceInfo->\"build-time\") \$devBuildTime;\r\ + \n :set (\$DeviceInfo->\"running-channel-version\") \$runningChannelVers\ + ion;\r\ + \n :set (\$DeviceInfo->\"running-version\") \$runningVersion;\r\ + \n :set (\$DeviceInfo->\"running-channel\") \$runningChannel;\r\ + \n :set (\$DeviceInfo->\"routerboard\") \$IsRouterBoard;\r\ + \n :set (\$DeviceInfo->\"current-firmware\") [ :tostr (\$RouterBoard->\"\ + current-firmware\") ];\r\ + \n :set (\$DeviceInfo->\"upgrade-firmware\") [ :tostr (\$RouterBoard->\"\ + upgrade-firmware\") ];\r\ + \n :set (\$DeviceInfo->\"package-channel\") \$currentUpdateChannel;\r\ + \n :set (\$DeviceInfo->\"installed-version\") [ :tostr (\$Update->\"inst\ + alled-version\") ];\r\ + \n :set (\$DeviceInfo->\"latest-version\") \$ROsVerAvail;\r\ + \n :set (\$DeviceInfo->\"update-status\") [ :tostr (\$Update->\"status\"\ + ) ];\r\ + \n\r\ + \n :set arrDeviceInfo \$DeviceInfo;\r\ + \n :return \$DeviceInfo;\r\ + \n}\r\ + \n\r\ + \n:set DeviceInfo do={\r\ + \n :global GetArrDeviceInfo;\r\ + \n :global GlobalConfVersion;\r\ + \n :global Identity;\r\ + \n :global IfThenElse;\r\ + \n :global FormatLine;\r\ + \n :global CommitBrief;\r\ + \n\r\ + \n :local License [/system/license/get];\r\ + \n :local Snmp [ /snmp/get ];\r\ + \n :local Info [ \$GetArrDeviceInfo ];\r\ + \n\r\ + \n :if ([ :typeof \$Info ] != \"array\") do={\r\ + \n :return false;\r\ + \n }\r\ + \n\r\ + \n :return ( \\\r\ + \n [ \$FormatLine \"Hostname\" \$Identity ] . \"\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$Snmp->\"location\") ] > 0) \\\r\ + \n ([ \$FormatLine \"Location\" (\$Snmp->\"location\") ] . \"\\n\") ]\ + \_. \\\r\ + \n [ \$IfThenElse ([ :len (\$Snmp->\"contact\") ] > 0) \\\r\ + \n ([ \$FormatLine \"Contact\" (\$Snmp->\"contact\") ] . \"\\n\") ] .\ + \_\\\r\ + \n \"Hardware:\\n\" . \\\r\ + \n [ \$FormatLine \" Board\" (\$Info->\"board-name\") ] . \"\\n\" . \ + \\\r\ + \n [ \$FormatLine \" Arch\" (\$Info->\"architecture-name\") ] . \"\\\ + n\" . \\\r\ + \n [ \$FormatLine \" Model\" (\$Info->\"model\") ] . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"revision\") ] > 0) \\\r\ + \n (\" \" . (\$Info->\"revision\")) ] . \"\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"serial-number\") ] > 0) \\\r\ + \n ([ \$FormatLine \" Serial\" (\$Info->\"serial-number\") ] . \"\ + \\n\") ] . \\\r\ + \n [ \$IfThenElse ([ :len (\$License->\"nlevel\") ] > 0) \\\r\ + \n ([ \$FormatLine \" License\" (\"level \" . (\$License->\"nlevel\ + \")) ] . \"\\n\") ] . \\\r\ + \n \"RouterOS:\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$License->\"level\") ] > 0) \\\r\ + \n ([ \$FormatLine \" License\" (\"level \" . (\$License->\"level\ + \")) ] . \"\\n\") ] . \\\r\ + \n [ \$FormatLine \" Channel\" (\$Info->\"package-channel\") ] . \"\ + \\n\" . \\\r\ + \n [ \$FormatLine \" Installed\" (\$Info->\"installed-version\") ] .\ + \_\"\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"running-channel\") ] > 0) \\\r\ + \n ([ \$FormatLine \" Running\" ((\$Info->\"running-version\") . \ + \" (\" . (\$Info->\"running-channel\") . \")\") ] . \"\\n\") \\\r\ + \n ([ \$FormatLine \" Running\" (\$Info->\"running-version\") ] . \ + \"\\n\") ] . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"latest-version\") ] > 0 && \\\r\ + \n (\$Info->\"installed-version\") != (\$Info->\"latest-version\"))\ + \_\\\r\ + \n ([ \$FormatLine \" Available\" (\$Info->\"latest-version\") ] .\ + \_\"\\n\") ] . \\\r\ + \n [ \$IfThenElse ((\$Info->\"routerboard\") = true && \\\r\ + \n (\$Info->\"current-firmware\") != (\$Info->\"upgrade-firmware\")\ + ) \\\r\ + \n ([ \$FormatLine \" Firmware\" ((\$Info->\"current-firmware\") .\ + \_\" -> \" . (\$Info->\"upgrade-firmware\")) ] . \"\\n\") ] . \\\r\ + \n \"RouterOS-Scripts:\\n\" . \\\r\ + \n [ \$FormatLine \" Commit\" [ \$CommitBrief ] ] . \"\\n\" . \\\r\ + \n [ \$FormatLine \" Version\" \$GlobalConfVersion ]);\r\ + \n}\r\ + \n\r\ + \n:if ([ :typeof \$NotificationFunctions ] != \"array\") do={:set Notifica\ + tionFunctions ({})}\r\ + \n\r\ + \n:set GetRandom20CharAlNum do={\r\ + \n :global EitherOr;\r\ + \n :return [ :rndstr length=[ \$EitherOr [ :tonum \$1 ] 20 ] from=\"ABCDE\ + FGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\" ];\r\ + \n}\r\ + \n\r\ + \n:set GetRandom20CharHex do={:global EitherOr; :return [ :rndstr length=[\ + \_\$EitherOr [ :tonum \$1 ] 20 ] from=\"0123456789abcdef\" ]; }\r\ + \n:set GetRandomNumber do={:global EitherOr; :return [ :rndnum from=0 to=[\ + \_\$EitherOr [ :tonum \$1 ] 4294967295 ] ]; }\r\ + \n\r\ + \n:global checkRunJob;\r\ + \n:set checkRunJob do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :global ScriptLock; \r\ + \n :if ([ \$ScriptLock \$Script ] = false) do={:return false}\r\ + \n :foreach Job in=[ /system/script/job/find where script=\$Script ] do={\ + :set Job [ /system/script/job/get \$Job ];\r\ + \n :while ([ :typeof (\$Job->\"parent\") ] = \"id\") do={:set Job [ /sy\ + stem/script/job/get [ find where .id=(\$Job->\"parent\") ] ]}\r\ + \n :if ((\$Job->\"type\") = \"login\") do={:return true};}; :return fa\ + lse; \r\ + \n}\r\ + \n\r\ + \n:set InspectVar do={\r\ + \n :global InspectVarRet;\r\ + \n :put [ :tocrlf [ \$InspectVarRet \$1 ] ];\r\ + \n}\r\ + \n\r\ + \n:set CommitBrief do={\r\ + \n :global CommitId;\r\ + \n :global CommitInfo;\r\ + \n :if (\$CommitId = \"unknown\") do={\r\ + \n :return \"unknown\";\r\ + \n }\r\ + \n :return (\$CommitInfo . \"/\" . [ :pick \$CommitId 0 8 ]);\r\ + \n}\r\ + \n\r\ + \n:set InspectVarRet do={\r\ + \n :local Input \$1;\r\ + \n :local Level (0 + [ :tonum \$2 ]);\r\ + \n :global CharacterReplace;\r\ + \n :global IfThenElse;\r\ + \n :global InspectVarRet;\r\ + \n :local IndentReturn do={\r\ + \n :local Prefix [ :tostr \$1 ];\r\ + \n :local Value [ :tostr \$2 ];\r\ + \n :local Level [ :tonum \$3 ];\r\ + \n :global CharacterMultiply;\r\ + \n :return ([ \$CharacterMultiply \" \" (\$Level * 2) ] . \"-\" . \$Pre\ + fix . \"-> \" . \$Value);\r\ + \n }\r\ + \n :local TypeOf [ :typeof \$Input ];\r\ + \n :local Len [ :len \$Input ];\r\ + \n :local Return [ \$IndentReturn \"type\" \$TypeOf \$Level ];\r\ + \n :if (\$TypeOf = \"array\") do={\r\ + \n :foreach Key,Value in=\$Input do={\r\ + \n :set \$Return (\$Return . \"\\n\" . \\\r\ + \n [ \$IndentReturn \"key\" \$Key (\$Level + 1) ] . \"\\n\" . \\\r\ + \n [ \$InspectVarRet \$Value (\$Level + 2) ]);\r\ + \n }\r\ + \n } else={\r\ + \n :if (\$TypeOf = \"str\") do={\r\ + \n :set \$Return (\$Return . \"\\n\" . \\\r\ + \n [ \$IndentReturn \"len\" \$Len \$Level ]);\r\ + \n :if ([ :typeof [ :find \$Input (\"\\r\") ] ] = \"num\") do={\r\ + \n :set Input [ \$CharacterReplace \$Input (\"\\r\") \"\" ];\r\ + \n }\r\ + \n :if ([ :typeof [ :find \$Input (\"\\n\") ] ] = \"num\") do={\r\ + \n :set Input [ \$CharacterReplace \$Input (\"\\n\") \" \" ];\r\ + \n }\r\ + \n }\r\ + \n :if (\$TypeOf != \"nothing\") do={\r\ + \n :set \$Return (\$Return . \"\\n\" . \\\r\ + \n [ \$IndentReturn \"value\" [ \$IfThenElse ([ :len \$Input ] > 80)\ + \_\\\r\ + \n ([ :pick \$Input 0 77 ] . \"...\") \$Input ] \$Level ]);\r\ + \n }\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set GetPubIp do={\r\ + \n :global DetectIpAddrDefault;\r\ + \n :global DetectIpAddrFallback;\r\ + \n\r\ + \n :local PubIpAddr false;\r\ + \n :local Url \$DetectIpAddrDefault;\r\ + \n :local JobName [ :jobname ];\r\ + \n\r\ + \n :do {\r\ + \n :log debug (\$0 . \" Trying to detect public IP using default serv\ + ice: \" . \$Url . \"...\");\r\ + \n :retry command={:set PubIpAddr ([ /tool/fetch http-method=\"get\"\ + \_check-certificate=yes-without-crl \$Url output=user as-value ]->\"data\"\ + )} \\\r\ + \n delay=50ms max=5 on-error={:log error (\$JobName . \" Failed to \ + detect public IP using default service: \" . \$Url . \".\")}\r\ + \n } on-error={\r\ + \n :log error (\$0 . \" Failed to detect public IP using default serv\ + ice: \" . \$Url . \".\");\r\ + \n :set Url \$DetectIpAddrFallBack;\r\ + \n :log debug (\$0 . \" Trying to detect public IP using fallback ser\ + vice: \" . \$Url . \"...\");\r\ + \n :retry command={:set PubIpAddr ([ /tool/fetch http-method=\"get\"\ + \_check-certificate=yes-without-crl \$Url output=user as-value ]->\"data\"\ + )} \\\r\ + \n delay=200ms max=5 on-error={:log error (\$JobName . \" Failed to\ + \_detect public IP using fallback service: \" . \$Url . \".\")}\r\ + \n };\r\ + \n :local IpLen ([ :len \$PubIpAddr ] -1);\r\ + \n :if (\$PubIpAddr = false) do={:set PubIpAddr \"not-detected\"} else=\ + {:set PubIpAddr [:pick \$PubIpAddr 0 \$IpLen]}\r\ + \n :return \$PubIpAddr;\r\ + \n}\r\ + \n\r\ + \n:set FormatLine do={\r\ + \n :local Key [ :tostr \$1 ];\r\ + \n :local Value [ :tostr \$2 ];\r\ + \n :local Indent [ :tonum \$3 ];\r\ + \n :local Spaces;\r\ + \n :local Return \"\";\r\ + \n :global CharacterMultiply;\r\ + \n :global EitherOr;\r\ + \n :set Indent [ \$EitherOr \$Indent 16 ];\r\ + \n :local Spaces [ \$CharacterMultiply \" \" \$Indent ];\r\ + \n :if ([ :len \$Key ] > 0) do={ :set Return (\$Key . \":\")}\r\ + \n :if ([ :len \$Key ] > (\$Indent - 2)) do={:set Return (\$Return . \"\\\ + n\" . [ :pick \$Spaces 0 \$Indent ] . \$Value);\r\ + \n } else={:set Return (\$Return . [ :pick \$Spaces 0 (\$Indent - [ :len \ + \$Return ]) ] . \$Value)}\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set ParseCustom do={\r\ + \n :local Str [ :tostr \$1 ];\r\ + \n :local Start [:find [ \$Str ] [:tostr \$2]];\r\ + \n :local End [ :tostr \$3 ];\r\ + \n :local Num [ :tonum \$4 ];\r\ + \n :local Return;\r\ + \n :if ([:len \$Num] = 0) do={:set Num \"0\"}\r\ + \n :local rest [:pick \$Str (\$Start+\$Num) [:len \$Str]]; \r\ + \n :if ([:len \$End ] = 0) do={:set Return [:pick \$Str \$Num \$Start]} e\ + lse={\r\ + \n :set End [:find \$rest \$End];\r\ + \n :set Return [:pick \$rest 0 \$End];\r\ + \n }\r\ + \n:return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set LogPrint do={\r\ + \n :local Severity [ :tostr \$1 ];\r\ + \n :local Name [ :tostr \$2 ];\r\ + \n :local Message [ :tostr \$3 ];\r\ + \n :global PrintDebug;\r\ + \n :global PrintDebugOverride;\r\ + \n :global EitherOr;\r\ + \n :local Debug [ \$EitherOr (\$PrintDebugOverride->\$Name) \$PrintDebug \ + ];\r\ + \n :local PrintSeverity do={\r\ + \n :global TerminalColorOutput;\r\ + \n :if (\$TerminalColorOutput != true) do={:return \$1}\r\ + \n :local Color { debug=96; info=97; warning=93; error=91 };\r\ + \n :return (\"\\1B[\" . \$Color->\$1 . \"m\" . \$1 . \"\\1B[0m\");\r\ + \n}\r\ + \n :local Log ([ \$EitherOr \$Name \"\" ] . \": \" . \$Message);\ + \r\ + \n :if (\$Severity ~ (\"^(custom|debug|error|info)\\\$\")) do={\r\ + \n :if (\$Severity = \"debug\") do={:log debug \$Log}\r\ + \n :if (\$Severity = \"error\") do={:log error \$Log}\r\ + \n :if (\$Severity = \"info\" ) do={:log info \$Log}\r\ + \n } else={:log warning \$Log; :set Severity \"warning\"}\r\ + \n :if (\$Severity != \"debug\" || \$Debug = true) do={:put ([ \$PrintSev\ + erity \$Severity ] . \": \" . \$Message)}\r\ + \n}\r\ + \n\r\ + \n:set CertificateAvailable do={\r\ + \n :local CommonName [ :tostr \$1 ];\r\ + \n :local UseFor [ :tostr \$2 ];\r\ + \n\r\ + \n :global CertificateDownload;\r\ + \n :global ParseKeyValueStore;\r\ + \n\r\ + \n :if ([ :len \$UseFor ] = 0) do={\r\ + \n :log warning (\$0 . \"The intended use is undefined!\");\r\ + \n :set UseFor \"undefined\";\r\ + \n }\r\ + \n :if ([ /system/resource/get free-hdd-space ] < 8388608 && \\\r\ + \n [ /certificate/settings/get crl-download ] = true && \\\r\ + \n [ /certificate/settings/get crl-store ] = \"system\") do={\r\ + \n :log warning (\$0 . \"This system has low free flash space but \" . \ + \\\r\ + \n \"is configured to download certificate CRLs to system!\");\r\ + \n }\r\ + \n :if ([ :len \$CommonName ] = 0) do={\r\ + \n :log warning (\$0 . \"No CommonName given!\");\r\ + \n :return false;\r\ + \n }\r\ + \n :local CertSettings [ /certificate/settings/get ];\r\ + \n :if (((\$CertSettings->\"builtin-trust-anchors\") = \"trusted\" || \\\ + \r\ + \n (\$CertSettings->\"builtin-trust-store\") ~ \$UseFor || \\\r\ + \n (\$CertSettings->\"builtin-trust-store\") = \"all\") && \\\r\ + \n [ :len [ /certificate/builtin/find where common-name=\$CommonName\ + \_] ] > 0) do={\r\ + \n :return true;\r\ + \n }\r\ + \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] = 0\ + ) do={\r\ + \n :log info (\$0 . \"Certificate with CommonName '\" . \$CommonName . \ + \"' not available.\");\r\ + \n :if ([ \$CertificateDownload \$CommonName ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] > 1\ + ) do={\r\ + \n :log info (\$0 . \"There are \" . \$CertCount . \" Certificates with\ + \_CommonName '\" . \$CommonName . \"'. Should be ok.\");\r\ + \n :return true;\r\ + \n }\r\ + \n :local CertVal [ /certificate/get [ find where common-name=\$CommonNam\ + e ] ];\r\ + \n :while ((\$CertVal->\"akid\") != \"\" && (\$CertVal->\"akid\") != (\$C\ + ertVal->\"skid\")) do={\r\ + \n :if ([ :len [ /certificate/find where skid=(\$CertVal->\"akid\") ] ]\ + \_= 0) do={\r\ + \n :local IssuerCN ([ \$ParseKeyValueStore (\$CertVal->\"issuer\") ]-\ + >\"CN\");\r\ + \n :log info (\$0 . \"Certificate chain for '\" . \$CommonName . \"' \ + is incomplete, missing '\" . \$IssuerCN . \"'.\");\r\ + \n :if ([ \$CertificateDownload \$IssuerCN ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n :set CertVal [ /certificate/get [ find where skid=(\$CertVal->\"akid\ + \") ] ];\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set CertificateDownload do={\r\ + \n :local CommonName [ :tostr \$1 ];\r\ + \n :global ScriptUpdatesBaseUrl;\r\ + \n :global ScriptUpdatesUrlSuffix;\r\ + \n :global CertificateNameByCN;\r\ + \n :global CleanName;\r\ + \n :global FetchUserAgentStr;\r\ + \n :global RmFile;\r\ + \n :global WaitForFile;\r\ + \n\r\ + \n :log info (\$0 . \"Downloading and importing certificate with \" . \\\ + \r\ + \n \"CommonName '\" . \$CommonName . \"'.\");\r\ + \n :local FileName ([ \$CleanName \$CommonName ] . \".pem\");\r\ + \n :do {\r\ + \n /tool/fetch check-certificate=yes-without-crl mode=https http-header\ + -field=({ [ \$FetchUserAgentStr \$0 ] }) \\\r\ + \n (\$ScriptUpdatesBaseUrl . \"certs/\" . \$FileName . \$ScriptUpdate\ + sUrlSuffix) \\\r\ + \n dst-path=\$FileName as-value;\r\ + \n \$WaitForFile \$FileName;\r\ + \n } on-error={\r\ + \n :log warning (\$0 . \" Failed downloading certificate with CommonNam\ + e '\" . \$CommonName . \\\r\ + \n \"' from repository! Trying fallback to mkcert.org...\");\r\ + \n :do {\r\ + \n :local CertSettings [ /certificate/settings/get ];\r\ + \n :if ([ :len [ /certificate/find where common-name=\"ISRG Root X1\"\ + \_] ] = 0 && \\\r\ + \n !(((\$CertSettings->\"builtin-trust-anchors\") = \"trusted\" \ + || \\\r\ + \n (\$CertSettings->\"builtin-trust-store\") ~ \"fetch\" || \ + \\\r\ + \n (\$CertSettings->\"builtin-trust-store\") = \"all\") && \\\ + \r\ + \n [ :len [ /certificate/builtin/find where common-name=\"ISRG\ + \_Root X1\" ] ] > 0)) do={\r\ + \n :log error (\$0 . \" Required certificate is not available.\");\ + \r\ + \n :return false;\r\ + \n }\r\ + \n /tool/fetch check-certificate=yes-without-crl mode=https http-head\ + er-field=({ [ \$FetchUserAgentStr \$0 ] }) \\\r\ + \n url=\"https://mkcert.org/generate/\" http-data=[ :serialize to=jso\ + n ({ \$CommonName }) ] \\\r\ + \n dst-path=\$FileName as-value;\r\ + \n \$WaitForFile \$FileName;\r\ + \n :if ([ /file/get \$FileName size ] = 0) do={\r\ + \n \$RmFile \$FileName;\r\ + \n :error false;\r\ + \n }\r\ + \n } on-error={\r\ + \n :log error (\$0 . \" Failed downloading certificate with CommonNam\ + e '\" . \$CommonName . \"'!\");\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n /certificate/import file-name=\$FileName passphrase=\"\" as-value;\r\ + \n :delay 1s;\r\ + \n \$RmFile \$FileName;\r\ + \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] = 0\ + ) do={\r\ + \n /certificate/remove [ find where name~(\"^\" . \$FileName . \"_[0-9]\ + +\\\$\") ];\r\ + \n :log warning (\$0 . \" Certificate with CommonName '\" . \$CommonNam\ + e . \"' still unavailable!\");\r\ + \n :return false;\r\ + \n }\r\ + \n :foreach Cert in=[ /certificate/find where name~(\"^\" . \$FileName . \ + \"_[0-9]+\\\$\") ] do={\r\ + \n \$CertificateNameByCN [ /certificate/get \$Cert common-name ];\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set CertificateNameByCN do={\r\ + \n :local Match [ :tostr \$1 ];\r\ + \n :global CleanName;\r\ + \n :local Cert ([ /certificate/find where (common-name=\$Match or fingerp\ + rint=\$Match or name=\$Match) ]->0);\r\ + \n :if ([ :len \$Cert ] = 0) do={\r\ + \n :log warning (\$0 .\" No matching certificate found.\");\r\ + \n :return false;\r\ + \n }\r\ + \n :local CommonName [ /certificate/get \$Cert common-name ];\r\ + \n /certificate/set \$Cert name=[ \$CleanName \$CommonName ];\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set CharacterMultiply do={\r\ + \n :local Str [ :tostr \$1 ];\r\ + \n :local Num [ :tonum \$2 ];\r\ + \n :if (\$Num = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :for I from=1 to=\$Num do={:set Return (\$Return . \$Str)}\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set FileExists do={\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :local Type [ :tostr \$2 ];\r\ + \n :global FileGet;\r\ + \n :local FileVal [ \$FileGet \$FileName ];\r\ + \n :if (\$FileVal = false) do={ :return false; }\r\ + \n :if ([ :len (\$FileVal->\"size\") ] = 0) do={ :return false; }\r\ + \n :if ([ :len \$Type ] = 0 || \$FileVal->\"type\" = \$Type) do={ :return\ + \_true; }\r\ + \n :return false;\r\ + \n}\r\ + \n\r\ + \n:set Grep do={\r\ + \n :local Input ([ :tostr \$1 ] . \"\\n\");\r\ + \n :local Pattern [ :tostr \$2 ];\r\ + \n :if ([ :typeof [ :find \$Input \$Pattern ] ] = \"nil\") do={:return []\ + }\r\ + \n :do {\r\ + \n :local Line [ :pick \$Input 0 [ :find \$Input \"\\n\" ] ];\r\ + \n :if ([ :typeof [ :find \$Line \$Pattern ] ] = \"num\") do={:return \ + \$Line}\r\ + \n :set Input [ :pick \$Input ([ :find \$Input \"\\n\" ] + 1) [ :len \$\ + Input ] ];\r\ + \n } while=([ :len \$Input ] > 0);\r\ + \n :return [];\r\ + \n}\r\ + \n\r\ + \n:set HumanReadableNum do={\r\ + \n :local Input [ :tonum \$1 ];\r\ + \n :local Base [ :tonum \$2 ];\r\ + \n :global EitherOr;\r\ + \n :global IfThenElse;\r\ + \n :local Prefix \"kMGTPE\";\r\ + \n :local Pow 1;\r\ + \n :set Base [ \$EitherOr \$Base 1024 ];\r\ + \n :local Bin [ \$IfThenElse (\$Base = 1024) \"i\" \"\" ];\r\ + \n :if (\$Input < \$Base) do={:return \$Input}\r\ + \n :for I from=0 to=[ :len \$Prefix ] do={\r\ + \n :set Pow (\$Pow * \$Base);\r\ + \n :if (\$Input / \$Base < \$Pow) do={\r\ + \n :set Prefix [ :pick \$Prefix \$I ];\r\ + \n :local Tmp1 (\$Input * 100 / \$Pow);\r\ + \n :local Tmp2 (\$Tmp1 / 100);\r\ + \n :if (\$Tmp2 >= 100) do={:return (\$Tmp2 . \$Prefix . \$Bin)}\r\ + \n :return (\$Tmp2 . \".\" . \\\r\ + \n [ :pick \$Tmp1 [ :len \$Tmp2 ] ([ :len \$Tmp1 ] - [ :len \$Tmp\ + 2 ] + 1) ] . \\\r\ + \n \$Prefix . \$Bin);\r\ + \n }\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set CleanFilePath do={\r\ + \n :local Path [ :tostr \$1 ];\r\ + \n :global CharacterReplace;\r\ + \n :while (\$Path ~ \"//\") do={ :set \$Path [ \$CharacterReplace \$Path \ + \"//\" \"/\" ]; }\r\ + \n :if ([ :pick \$Path 0 ] = \"/\") do={ :set Path [ :pick \$Path 1 [ :le\ + n \$Path ] ]; }\r\ + \n :if ([ :pick \$Path ([ :len \$Path ] - 1) ] = \"/\") do={ :set Path [ \ + :pick \$Path 0 ([ :len \$Path ] - 1) ]; }\r\ + \n :return \$Path;\r\ + \n}\r\ + \n\r\ + \n:set CleanName do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :local Return \"\";\r\ + \n :for I from=0 to=([ :len \$Input ] - 1) do={\r\ + \n :local Char [ :pick \$Input \$I ];\r\ + \n :if ([ :typeof [ find \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr\ + stuvwxyz0123456789\" \$Char ] ] = \"nil\") do={\r\ + \n :do {:if ([ :len \$Return ] = 0) do={:error true};\r\ + \n :if ([ :pick \$Return ([ :len \$Return ] - 1) ] = \"-\") do={:er\ + ror true}; :set Char \"-\"} on-error={:set Char \"\"}; \r\ + \n };\r\ + \n :set Return (\$Return . \$Char)};\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set RandomDelay do={\r\ + \n :local Time [ :tonum \$1 ];\r\ + \n :local Unit [ :tostr \$2 ];\r\ + \n :global EitherOr;\r\ + \n :global GetRandomNumber;\r\ + \n :global MAX;\r\ + \n :if (\$Time = 0) do={:return false}\r\ + \n :delay ([ \$MAX 10 [ \$GetRandomNumber ([ :tonsec [ :totime (\$Time . \ + [ \$EitherOr \$Unit \"s\" ]) ] ] / 1000000) ] ] . \"ms\");\r\ + \n}\r\ + \n\r\ + \n:set EscapeForRegEx do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :if ([ :len \$Input ] = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :local Chars (\"^.[]\\\$()|*+\?{}\\\\\");\r\ + \n :for I from=0 to=([ :len \$Input ] - 1) do={\r\ + \n :local Char [ :pick \$Input \$I ];\r\ + \n :if ([ :find \$Chars \$Char ]) do={:set Char (\"\\\\\" . \$Char)}\r\ + \n :set Return (\$Return . \$Char);\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set ExitError do={\r\ + \n :local ExitOK [ :tostr \$1 ];\r\ + \n :local Name [ :tostr \$2 ];\r\ + \n :local Error [ :tostr \$3 ];\r\ + \n :global IfThenElse;\r\ + \n :if (\$ExitOK = \"false\") do={\r\ + \n :log error (\$Name [ \$IfThenElse ([ :pick \$Name 0 1 ] = \"\\\$\") \ + \\\r\ + \n \"Function\" \"Script\" ] . \" '\" . \$Name . \"' exited with er\ + ror\" . \\\r\ + \n [ \$IfThenElse (!(\$Error ~ \"^(|true|false)\\\$\")) (\": \" . \ + \$Error) \".\" ]);\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set ExitOnError do={\r\ + \n :local Name [ :tostr \$1 ];\r\ + \n :local Error [ :tostr \$2 ];\r\ + \n :global IfThenElse;\r\ + \n :log error (\$Name . \" \" . [ \$IfThenElse ([ :pick \$Name 0 1 ] = \"\ + \\\$\") \\\r\ + \n \"Function\" \"Script\" ] . \" '\" . \$Name . \"' exited with erro\ + r\" . \\\r\ + \n [ \$IfThenElse (!(\$Error ~ \"^(|true|false)\\\$\")) (\": \" . \$E\ + rror) \".\" ]);\r\ + \n}\r\ + \n\r\ + \n:set MiniDateTimeStamp do={\r\ + \n :local mikro [ :tobool \$1 ];\r\ + \n /system/clock;\r\ + \n :local vdate [get date];\r\ + \n :local vtime [get time];\r\ + \n :local vdoff [:toarray \"0,4,5,7,8,10\"];\r\ + \n :local MM [:pick \$vdate (\$vdoff->2) (\$vdoff->3)];\r\ + \n :local M [:tonum \$MM];\r\ + \n :if (\$vdate ~ \".../../....\") do={\r\ + \n :set vdoff [:toarray \"7,11,1,3,4,6\"];\r\ + \n :set M ([:find \"xxanebarprayunulugepctovecANEBARPRAYUNULUGE\ + PCTOVEC\" [:pick \$vdate (\$vdoff->2) (\$vdoff->3)] -1] / 2);\r\ + \n :if (\$M>12) do={:set M (\$M - 12)}\r\ + \n :set MM [:pick (100 + \$M) 1 3];\r\ + \n }\r\ + \n :local yyyy [:pick \$vdate (\$vdoff->0) (\$vdoff->1)];\r\ + \n :local dd [:pick \$vdate (\$vdoff->4) (\$vdoff->5)];\r\ + \n :local HH [:pick \$vtime 0 2];\r\ + \n :local mm [:pick \$vtime 3 5];\r\ + \n :local ss [:pick \$vtime 6 8];\r\ + \n :local Return;\r\ + \n :if (\$mikro = true) do={\r\ + \n :set Return ([:pick \$yyyy 2 4] . [:pick \$dd 0 1] . [:pick \$HH 0\ + \_1] . [:pick \$mm 3 4] . [:pick \$ss 6 7]);\r\ + \n } else={\r\ + \n :set Return ([\$yyyy] . [\$MM] . [\$dd] . [\$HH] . [\$mm] . [\$ss]);\ + \r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set WaitForFile do={\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :local WaitTime [ :totime \$2 ];\r\ + \n :global CleanFilePath;\r\ + \n :global EitherOr;\r\ + \n :global MAX;\r\ + \n :set FileName [ \$CleanFilePath \$FileName ];\r\ + \n :local Delay ([ \$MAX [ \$EitherOr \$WaitTime 2s ] 100ms ] / 9);\r\ + \n :do {\r\ + \n :retry {\r\ + \n /file/get \$FileName;\r\ + \n :return true;\r\ + \n } delay=\$Delay max=10;\r\ + \n } on-error={ }\r\ + \n :while ([ :len [ /file/find where name=\$FileName ] ] > 0) do={\r\ + \n :do {\r\ + \n /file/get \$FileName;\r\ + \n :return true;\r\ + \n } on-error={ }\r\ + \n :delay \$Delay;\r\ + \n :set Delay (\$Delay * 3 / 2);\r\ + \n }\r\ + \n :return false;\r\ + \n}\r\ + \n\r\ + \n:set FileGet do={\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :global WaitForFile;\r\ + \n :if ([ \$WaitForFile \$FileName 0s ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n :local FileVal false;\r\ + \n :do {\r\ + \n :set FileVal [ /file/get \$FileName ];\r\ + \n } on-error={ }\r\ + \n :return \$FileVal;\r\ + \n}\r\ + \n\r\ + \n:set RmDir do={\r\ + \n :local DirName [ :tostr \$1 ];\r\ + \n :global FileGet;\r\ + \n :log debug (\$0 . \" Removing directory: \". \$DirName);\r\ + \n :local DirVal [ \$FileGet \$DirName ];\r\ + \n :if (\$DirVal = false) do={\r\ + \n :log debug (\$0 . \" ... which does not exist.\");\r\ + \n :return true;\r\ + \n };\r\ + \n :if (\$DirVal->\"type\" != \"directory\") do={\r\ + \n :log error (\$0 . \" Directory '\" . \$DirName . \"' is not a direct\ + ory.\");\r\ + \n :return false;\r\ + \n };\r\ + \n :onerror Err {\r\ + \n /file/remove \$DirName;\r\ + \n } do={\r\ + \n :log error (\$0 . \" Removing directory '\" . \$DirName . \"' failed\ + : \" . \$Err);\r\ + \n :return false;\r\ + \n };\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set RmFile do={\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :global FileGet;\r\ + \n :log debug (\$0 . \" Removing file: \". \$FileName);\r\ + \n :local FileVal [ \$FileGet \$FileName ];\r\ + \n :if (\$FileVal = false) do={\r\ + \n :log debug (\$0 . \" ... which does not exist.\");\r\ + \n :return true;\r\ + \n }\r\ + \n :if (\$FileVal->\"type\" = \"directory\" || \$FileVal->\"type\" = \"di\ + sk\") do={\r\ + \n :log error (\$0 . \" File '\" . \$FileName . \"' is not a file.\");\ + \r\ + \n :return false;\r\ + \n }\r\ + \n :onerror Err {\r\ + \n /file/remove \$FileName;\r\ + \n } do={\r\ + \n :log error (\$0 . \" Removing file '\" . \$FileName . \"' failed: \"\ + \_. \$Err); :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set MkDir do={\r\ + \n :local Path [ :tostr \$1 ];\r\ + \n :global CleanFilePath;\r\ + \n :global FileGet;\r\ + \n :global RmDir;\r\ + \n :global WaitForFile;\r\ + \n\r\ + \n :local MkTmpfs do={\r\ + \n :global WaitForFile;\r\ + \n :local TmpFs [ /disk/find where slot=tmpfs type=tmpfs ];\r\ + \n :if ([ :len \$TmpFs ] = 1) do={\r\ + \n :if ([ /disk/get \$TmpFs disabled ] = true) do={\r\ + \n :log info (\$0 . \" The tmpfs is disabled, enabling.\");\r\ + \n /disk/enable \$TmpFs;\r\ + \n }\r\ + \n :return true;\r\ + \n }\r\ + \n :log info (\$0 . \" Creating disk of type tmpfs.\");\r\ + \n \$RmDir \"tmpfs\";\r\ + \n :onerror Err {\r\ + \n /disk/add slot=tmpfs type=tmpfs tmpfs-max-size=([ /system/resource\ + /get total-memory ] / 3);\r\ + \n \$WaitForFile \"tmpfs\";\r\ + \n } do={\r\ + \n :log warning (\$0 . \" Creating disk of type tmpfs failed: \" . \$\ + Err);\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n }\r\ + \n :set Path [ \$CleanFilePath \$Path ];\r\ + \n :if (\$Path = \"\") do={\r\ + \n :return true;\r\ + \n }\r\ + \n :log debug (\$0 . \" Making directory: \" . \$Path);\r\ + \n :local PathVal [ \$FileGet \$Path ];\r\ + \n :if (\$PathVal->\"type\" = \"directory\") do={\r\ + \n :log debug (\$0 . \" ... which already exists.\");\r\ + \n :return true;\r\ + \n }\r\ + \n :if ([ :pick \$Path 0 5 ] = \"tmpfs\") do={\r\ + \n :if ([ \$MkTmpfs ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n :onerror Err {\r\ + \n /file/add type=\"directory\" name=\$Path;\r\ + \n \$WaitForFile \$Path;\r\ + \n } do={\r\ + \n :log warning (\$0 . \" Making directory '\" . \$Path . \"' failed: \ + \" . \$Err);\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set MAX do={:if (\$1 > \$2) do={:return \$1}\r\ + \n :return \$2;\r\ + \n}\r\ + \n:set MIN do={:if (\$1 < \$2) do={:return \$1}\r\ + \n :return \$2;\r\ + \n}\r\ + \n\r\ + \n:set CharacterMultiply do={\r\ + \n :local Str [ :tostr \$1 ];\r\ + \n :local Num [ :tonum \$2 ];\r\ + \n :if (\$Num = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :for I from=1 to=\$Num do={:set Return (\$Return . \$Str)}\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set CharacterReplace do={\r\ + \n :local String [ :tostr \$1 ];\r\ + \n :local ReplaceFrom [ :tostr \$2 ];\r\ + \n :local ReplaceWith [ :tostr \$3 ];\r\ + \n :local Return \"\";\r\ + \n :if (\$ReplaceFrom = \"\") do={:return \$String}\r\ + \n :while ([ :typeof [ :find \$String \$ReplaceFrom ] ] != \"nil\") do={\ + \r\ + \n :local Pos [ :find \$String \$ReplaceFrom ];\r\ + \n :set Return (\$Return . [ :pick \$String 0 \$Pos ] . \$ReplaceWith);\ + \r\ + \n :set String [ :pick \$String (\$Pos + [ :len \$ReplaceFrom ]) [ :len\ + \_\$String ] ];\r\ + \n }\r\ + \n :return (\$Return . \$String);\r\ + \n}\r\ + \n\r\ + \n:set IfThenElse do={\r\ + \n :if ([ :tostr \$1 ] = \"true\" || [ :tobool \$1 ] = true) do={:return \ + \$2};\r\ + \n :return \$3;\r\ + \n}\r\ + \n\r\ + \n:set EitherOr do={\r\ + \n :global IfThenElse;\r\ + \n :if ([ :typeof \$1 ] = \"num\") do={:return [ \$IfThenElse (\$1 != 0) \ + \$1 \$2 ]}\r\ + \n :if ([ :typeof \$1 ] = \"time\") do={:return [ \$IfThenElse (\$1 > 0s)\ + \_\$1 \$2 ]}\r\ + \n# this works for boolean values, literal ones with parentheses\r\ + \n :return [ \$IfThenElse ([ :len [ :tostr \$1 ] ] > 0) \$1 \$2 ];\r\ + \n}\r\ + \n\r\ + \n:set ParseKeyValueStore do={\r\ + \n :local Source \$1;\r\ + \n :if ([ :pick \$Source 0 1 ] = \"{\") do={\r\ + \n :do {\r\ + \n :return [ :deserialize from=json \$Source ];\r\ + \n } on-error={ }\r\ + \n } \r\ + \n :if ([ :typeof \$Source ] != \"array\") do={:set Source [ :tostr \$1 ]\ + }\r\ + \n :local Result ({});\r\ + \n :foreach KeyValue in=[ :toarray \$Source ] do={\r\ + \n :if ([ :find \$KeyValue \"=\" ]) do={\r\ + \n :local Key [ :pick \$KeyValue 0 [ :find \$KeyValue \"=\" ] ];\r\ + \n :local Value [ :pick \$KeyValue ([ :find \$KeyValue \"=\" ] + 1) [\ + \_:len \$KeyValue ] ];\r\ + \n :if (\$Value=\"true\") do={:set Value true}\r\ + \n :if (\$Value=\"false\") do={:set Value false}\r\ + \n :set (\$Result->\$Key) \$Value;\r\ + \n } else={:set (\$Result->\$KeyValue) true}\r\ + \n }\r\ + \n :return \$Result;\r\ + \n}\r\ + \n:set RequiredRouterOS do={\r\ + \n :local Caller [ :tostr \$1 ];\r\ + \n :local Required [ :tostr \$2 ];\r\ + \n :local Warn [ :tostr \$3 ];\r\ + \n :global IfThenElse;\r\ + \n :global VersionToNum;\r\ + \n :if (!(\$Required ~ \"^\\\\d+\\\\.\\\\d+((alpha|beta|rc|\\\\.)\\\\d+|)\ + \\\$\")) do={\r\ + \n :log error (\$0 . \" No valid RouterOS version: \" . \$Required);\r\ + \n :return false;\r\ + \n }\r\ + \n :if ([ \$VersionToNum \$Required ] > [ \$VersionToNum [ /system/packag\ + e/update/get installed-version ] ]) do={\r\ + \n :if (\$Warn = \"true\") do={\r\ + \n :log warning (\$0 . \" This \" . [ \$IfThenElse ([ :pick \$Caller \ + 0 ] = (\"\\\$\")) \"function\" \"script\" ] . \\\r\ + \n \" '\" . \$Caller . \"' (at least specific functionality) requir\ + es RouterOS \" . \$Required . \". Please update!\");\r\ + \n }\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set ValidateSyntax do={\r\ + \n :local Code [ :tostr \$1 ];\r\ + \n :global LogPrint;\r\ + \n :onerror Err {\r\ + \n [ :parse (\":local Validate do={\\n\" . \$Code . \"\\n}\") ];\r\ + \n } do={\r\ + \n \$LogPrint debug \$0 (\"Valdation failed: \" . \$Err);\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set VersionToNum do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :local Multi 0x1000000;\r\ + \n :local Return 0;\r\ + \n :global CharacterReplace;\r\ + \n :set Input [ \$CharacterReplace \$Input \".\" \",\" ];\r\ + \n :foreach I in={ \"zero\"; \"alpha\"; \"beta\"; \"rc\" } do={\r\ + \n :set Input [ \$CharacterReplace \$Input \$I (\",\" . \$I . \",\") ];\ + \r\ + \n }\r\ + \n :foreach Value in=([ :toarray \$Input ], 0) do={\r\ + \n :local Num [ :tonum \$Value ];\r\ + \n :if (\$Multi = 0x100) do={\r\ + \n :if ([ :typeof \$Num ] = \"num\") do={\r\ + \n :set Return (\$Return + 0xff00);\r\ + \n :set Multi (\$Multi / 0x100);\r\ + \n } else={\r\ + \n :if (\$Value = \"zero\") do={ }\r\ + \n :if (\$Value = \"alpha\") do={ :set Return (\$Return + 0x3f00); \ + }\r\ + \n :if (\$Value = \"beta\") do={ :set Return (\$Return + 0x5f00); }\ + \r\ + \n :if (\$Value = \"rc\") do={ :set Return (\$Return + 0x7f00); }\r\ + \n }\r\ + \n }\r\ + \n :if ([ :typeof \$Num ] = \"num\") do={ :set Return (\$Return + (\$Va\ + lue * \$Multi)); }\r\ + \n :set Multi (\$Multi / 0x100);\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set ScriptLock do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local WaitMax [ :totime \$2 ];\r\ + \n :global GetRandom20CharAlNum;\r\ + \n :global IfThenElse;\r\ + \n :global ScriptLockOrder;\r\ + \n :if ([ :typeof \$ScriptLockOrder ] = \"nothing\") do={\r\ + \n :set ScriptLockOrder ({});\r\ + \n }\r\ + \n :if ([ :typeof (\$ScriptLockOrder->\$Script) ] = \"nothing\") do={\r\ + \n :set (\$ScriptLockOrder->\$Script) ({});\r\ + \n }\r\ + \n :local JobCount do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :return [ :len [ /system/script/job/find where script=\$Script ] ];\ + \r\ + \n }\r\ + \n :local TicketCount do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :local Count 0;\r\ + \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :if ([ :typeof \$Ticket ] != \"nothing\") do={:set Count (\$Count \ + + 1)}\r\ + \n }\r\ + \n :return \$Count;\r\ + \n }\r\ + \n :local IsFirstTicket do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local Check [ :tostr \$2 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :if (\$Ticket = \$Check) do={:return true}\r\ + \n :if ([ :typeof \$Ticket ] != \"nothing\" && \$Ticket != \$Check) d\ + o={:return false}\r\ + \n }\r\ + \n :return false;\r\ + \n }\r\ + \n :local AddTicket do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local Add [ :tostr \$2 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :while (true) do={\r\ + \n :local Pos [ :len (\$ScriptLockOrder->\$Script) ];\r\ + \n :set (\$ScriptLockOrder->\$Script->\$Pos) \$Add;\r\ + \n :delay 10ms;\r\ + \n :if ((\$ScriptLockOrder->\$Script->\$Pos) = \$Add) do={:return tru\ + e}\r\ + \n }\r\ + \n }\r\ + \n :local RemoveTicket do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local Remove [ :tostr \$2 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :foreach Id,Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :while ((\$ScriptLockOrder->\$Script->\$Id) = \$Remove) do={\r\ + \n :set (\$ScriptLockOrder->\$Script->\$Id);\r\ + \n :delay 10ms;\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n :local CleanupTickets do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :if ([ :typeof \$Ticket ] != \"nothing\") do={:return false}\r\ + \n }\r\ + \n :set (\$ScriptLockOrder->\$Script) ({});\r\ + \n }\r\ + \n :if ([ :typeof \$WaitMax ] = \"nil\" ) do={:set WaitMax 0s}\r\ + \n :if ([ :len [ /system/script/find where name=\$Script ] ] = 0) do={\r\ + \n :log error (\$0 . \" A script named '\" . \$Script . \"' does not ex\ + ist!\");\r\ + \n :error false;\r\ + \n }\r\ + \n :if ([ \$JobCount \$Script ] = 0) do={\r\ + \n \$LogPrint error \$0 (\"No script '\" . \$Script . \"' is running!\"\ + );\r\ + \n :error false;\r\ + \n }\r\ + \n :if ([ \$TicketCount \$Script ] >= [ \$JobCount \$Script ]) do={\r\ + \n :log error (\$0 . \" More tickets than running scripts '\" . \$Scrip\ + t . \"', resetting!\");\r\ + \n :set (\$ScriptLockOrder->\$Script) ({});\r\ + \n /system/script/job/remove [ find where script=\$Script ];\r\ + \n }\r\ + \n :local MyTicket [ \$GetRandom20CharAlNum 6 ];\r\ + \n \$AddTicket \$Script \$MyTicket;\r\ + \n :local WaitInterval (\$WaitMax / 20);\r\ + \n :local WaitTime \$WaitMax;\r\ + \n :while (\$WaitTime > 0 && \\\r\ + \n ([ \$IsFirstTicket \$Script \$MyTicket ] = false || \\\r\ + \n [ \$TicketCount \$Script ] < [ \$JobCount \$Script ])) do={\r\ + \n :set WaitTime (\$WaitTime - \$WaitInterval);\r\ + \n :delay \$WaitInterval;\r\ + \n }\r\ + \n :if ([ \$IsFirstTicket \$Script \$MyTicket ] = true && \\\r\ + \n [ \$TicketCount \$Script ] = [ \$JobCount \$Script ]) do={\r\ + \n \$RemoveTicket \$Script \$MyTicket;\r\ + \n \$CleanupTickets \$Script;\r\ + \n :return true;\r\ + \n }\r\ + \n \$RemoveTicket \$Script \$MyTicket;\r\ + \n \$LogPrint debug \$0 (\"Script '\" . \$Script . \"' started more than \ + once\" . \\\r\ + \n [ \$IfThenElse (\$WaitTime < \$WaitMax) \" and timed out waiting for\ + \_lock\" \"\" ] . \"...\");\r\ + \n :return false;\r\ + \n}\r\ + \n\r\ + \n:set SendNotification do={ :onerror Err {\r\ + \n :global SendNotification2;\r\ + \n \$SendNotification2 ({ origin=\$0; subject=\$1; message=\$2; link=\$3;\ + \_silent=\$4 });\r\ + \n} do={:global ExitOnError; \$ExitOnError \$0 \$Err}\r\ + \n}\r\ + \n\r\ + \n:set SendNotification2 do={\r\ + \n :local Notification \$1;\r\ + \n :global NotificationFunctions;\r\ + \n :foreach FunctionName,Discard in=\$NotificationFunctions do={\r\ + \n (\$NotificationFunctions->\$FunctionName) (\"\\\$NotificationFunctio\ + ns->\\\"\" . \$FunctionName . \"\\\"\") \$Notification;\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set SymbolByUnicodeName do={\r\ + \n :local Name [ :tostr \$1 ];\r\ + \n :global EitherOr;\r\ + \n :global SymbolsExtra;\r\ + \n :local Symbols ({\r\ + \n \"abacus\"=\"\\F0\\9F\\A7\\AE\";\r\ + \n \"alarm-clock\"=\"\\E2\\8F\\B0\";\r\ + \n \"arrow-down\"=\"\\E2\\AC\\87\";\r\ + \n \"arrow-up\"=\"\\E2\\AC\\86\";\r\ + \n \"calendar\"=\"\\F0\\9F\\93\\85\";\r\ + \n \"card-file-box\"=\"\\F0\\9F\\97\\83\";\r\ + \n \"chart-decreasing\"=\"\\F0\\9F\\93\\89\";\r\ + \n \"chart-increasing\"=\"\\F0\\9F\\93\\88\";\r\ + \n \"cloud\"=\"\\E2\\98\\81\";\r\ + \n \"cross-mark\"=\"\\E2\\9D\\8C\";\r\ + \n \"earth\"=\"\\F0\\9F\\8C\\8D\";\r\ + \n \"fire\"=\"\\F0\\9F\\94\\A5\";\r\ + \n \"floppy-disk\"=\"\\F0\\9F\\92\\BE\";\r\ + \n \"gear\"=\"\\E2\\9A\\99\";\r\ + \n \"heart\"=\"\\E2\\99\\A5\";\r\ + \n \"high-voltage-sign\"=\"\\E2\\9A\\A1\";\r\ + \n \"incoming-envelope\"=\"\\F0\\9F\\93\\A8\";\r\ + \n \"information\"=\"\\E2\\84\\B9\";\r\ + \n \"large-orange-circle\"=\"\\F0\\9F\\9F\\A0\";\r\ + \n \"large-red-circle\"=\"\\F0\\9F\\94\\B4\";\r\ + \n \"link\"=\"\\F0\\9F\\94\\97\";\r\ + \n \"lock-with-ink-pen\"=\"\\F0\\9F\\94\\8F\";\r\ + \n \"memo\"=\"\\F0\\9F\\93\\9D\";\r\ + \n \"mobile-phone\"=\"\\F0\\9F\\93\\B1\";\r\ + \n \"pushpin\"=\"\\F0\\9F\\93\\8C\";\r\ + \n \"scissors\"=\"\\E2\\9C\\82\";\r\ + \n \"scroll\"=\"\\F0\\9F\\93\\9C\";\r\ + \n \"smiley-partying-face\"=\"\\F0\\9F\\A5\\B3\";\r\ + \n \"smiley-smiling-face\"=\"\\E2\\98\\BA\";\r\ + \n \"smiley-winking-face-with-tongue\"=\"\\F0\\9F\\98\\9C\";\r\ + \n \"sparkles\"=\"\\E2\\9C\\A8\";\r\ + \n \"speech-balloon\"=\"\\F0\\9F\\92\\AC\";\r\ + \n \"star\"=\"\\E2\\AD\\90\";\r\ + \n \"warning-sign\"=\"\\E2\\9A\\A0\";\r\ + \n \"white-heavy-check-mark\"=\"\\E2\\9C\\85\"\r\ + \n }, \$SymbolsExtra);\r\ + \n :local Magic [ :pick [ /system/clock/get date ] 4 10 ];\r\ + \n :local Special {\r\ + \n \"information-04-01\"=\"\\F0\\9F\\9A\\BB\";\r\ + \n \"large-orange-circle-04-01\"=\"\\F0\\9F\\8D\\8A\";\r\ + \n \"large-orange-circle-10-31\"=\"\\F0\\9F\\8E\\83\";\r\ + \n \"large-red-circle-04-01\"=\"\\F0\\9F\\8D\\92\" };\r\ + \n :if ([ :len (\$Symbols->\$Name) ] = 0) do={\r\ + \n :log warning (\$0 . \"No symbol available for name '\" . \$Name . \"\ + '!\");\r\ + \n :return \"\";\r\ + \n }\r\ + \n :return ([ \$EitherOr (\$Special->(\$Name . \$Magic)) (\$Symbols->\$Na\ + me) ] . \"\\EF\\B8\\8F\");\r\ + \n}\r\ + \n\r\ + \n:set SymbolForNotification do={\r\ + \n :global NotificationsWithSymbols;\r\ + \n :global SymbolByUnicodeName;\r\ + \n :global IfThenElse;\r\ + \n :if (\$NotificationsWithSymbols != true) do={:return [ \$IfThenElse ([\ + \_:len \$2 ] > 0) ([ :tostr \$2 ] . \" \") \"\" ]}\r\ + \n :local Return \"\";\r\ + \n :foreach Symbol in=[ :toarray \$1 ] do={:set Return (\$Return . [ \$Sy\ + mbolByUnicodeName \$Symbol ])}\r\ + \n :return (\$Return . \" \");\r\ + \n}\r\ + \n\r\ + \n:set Unix2Dos do={:return [ :tocrlf [ :tostr \$1 ] ]}\r\ + \n:set UrlEncode do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :if ([ :len \$Input ] = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :local Chars (\"\\n\\r !\\\"#\\\$%&'()*+,:;<=>\?@[\\\\]^`{|}~\");\r\ + \n :local Subs { \"%0A\"; \"%0D\"; \"%20\"; \"%21\"; \"%22\"; \"%23\"; \"\ + %24\"; \"%25\"; \"%26\"; \"%27\";\r\ + \n \"%28\"; \"%29\"; \"%2A\"; \"%2B\"; \"%2C\"; \"%3A\"; \"%3B\"; \ + \"%3C\"; \"%3D\"; \"%3E\"; \"%3F\";\r\ + \n \"%40\"; \"%5B\"; \"%5C\"; \"%5D\"; \"%5E\"; \"%60\"; \"%7B\"; \ + \"%7C\"; \"%7D\"; \"%7E\" };\r\ + \n :for I from=0 to=([ :len \$Input ] - 1) do={\r\ + \n :local Char [ :pick \$Input \$I ];\r\ + \n :local Replace [ :find \$Chars \$Char ];\r\ + \n :if ([ :typeof \$Replace ] = \"num\") do={:set Char (\$Subs->\$Repla\ + ce)}\r\ + \n :set Return (\$Return . \$Char);\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set IsDNSResolving do={\r\ + \n :do {:resolve \"api.telegram.org\"} on-error={:return false}\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set IsFullyConnected do={\r\ + \n :global IsDNSResolving;\r\ + \n :global IsTimeSync;\r\ + \n :if ([ \$IsDNSResolving ] = false) do={:return false};\r\ + \n :if ([ \$IsTimeSync ] = false) do={:return false};\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set IsTimeSync do={\r\ + \n :global IsTimeSyncCached;\r\ + \n :global IsTimeSyncResetNtp;\r\ + \n :if (\$IsTimeSyncCached = true) do={:return true}\r\ + \n :if ([ /system/ntp/client/get enabled ] = true) do={\r\ + \n :if ([ /system/ntp/client/get status ] = \"synchronized\") do={\r\ + \n :set IsTimeSyncCached true;\r\ + \n :return true;\r\ + \n }\r\ + \n :local Uptime [ /system/resource/get uptime ];\r\ + \n :if ([ :typeof \$IsTimeSyncResetNtp ] = \"nothing\") do={\r\ + \n :set IsTimeSyncResetNtp \$Uptime;\r\ + \n }\r\ + \n :if (\$Uptime - \$IsTimeSyncResetNtp < 3m) do={:return false}\r\ + \n :log warning \"\$0 The ntp client is configured, but did not sync.\"\ + ;\r\ + \n :set IsTimeSyncResetNtp \$Uptime;\r\ + \n /system/ntp/client/set enabled=no;\r\ + \n :delay 20ms;\r\ + \n /system/ntp/client/set enabled=yes;\r\ + \n :return false;\r\ + \n }\r\ + \n :if ([ /system/license/get ]->\"level\" = \"free\" || \\\r\ + \n [ /system/resource/get ]->\"board-name\" = \"x86\") do={\r\ + \n :log debug \"\$0 No ntp client configured, relying on RTC for CHR fr\ + ee license and x86.\";\r\ + \n :return true;\r\ + \n }\r\ + \n :if ([ /ip/cloud/get update-time ] = true) do={\r\ + \n :if ([ :typeof [ /ip/cloud/get public-address ] ] = \"ip\") do={\r\ + \n :set IsTimeSyncCached true;\r\ + \n :return true;\r\ + \n }\r\ + \n :return false;\r\ + \n }\r\ + \n :log debug \"\$0 No time source configured! Returning gracefully...\";\ + \r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set FetchHugeFiles do={\r\ + \n :local ScriptName [ :tostr \$1 ];\r\ + \n :local Url [ :tostr \$2 ];\r\ + \n :local CheckCert [ :tostr \$3 ];\r\ + \n\r\ + \n :global CleanName;\r\ + \n :global FetchUserAgentStr;\r\ + \n :global GetRandom20CharAlNum;\r\ + \n :global IfThenElse;\r\ + \n :global LogPrint;\r\ + \n :global MkDir;\r\ + \n :global RmDir;\r\ + \n :global RmFile;\r\ + \n :global WaitForFile;\r\ + \n\r\ + \n :set CheckCert [ \$IfThenElse (\$CheckCert = \"false\") \"no\" \"yes-w\ + ithout-crl\" ];\r\ + \n\r\ + \n :local DirName (\"tmpfs/\" . [ \$CleanName \$ScriptName ]);\r\ + \n :if ([ \$MkDir \$DirName ] = false) do={\r\ + \n \$LogPrint error \$0 (\"Failed creating directory!\");\r\ + \n :return false;\r\ + \n }\r\ + \n\r\ + \n :local FileName (\$DirName . \"/\" . [ \$CleanName \$0 ] . \"-\" . [ \ + \$GetRandom20CharAlNum ]);\r\ + \n :onerror Err {\r\ + \n /tool/fetch check-certificate=\$CheckCert \$Url dst-path=\$FileName \ + \\\r\ + \n http-header-field=({ [ \$FetchUserAgentStr \$ScriptName ] }) as-va\ + lue;\r\ + \n } do={\r\ + \n :if ([ \$WaitForFile \$FileName 500ms ] = true) do={\r\ + \n \$RmFile \$FileName;\r\ + \n }\r\ + \n \$LogPrint debug \$0 (\"Failed downloading from \" . \$Url . \" - \"\ + \_. \$Err);\r\ + \n \$RmDir \$DirName;\r\ + \n :return false;\r\ + \n }\r\ + \n\r\ + \n :if ([ \$WaitForFile \$FileName 5s ] = false) do={\r\ + \n \$LogPrint debug \$0 (\"The file downloaded from \" . \$Url . \" did\ + \_not show up.\");\r\ + \n :return false;\r\ + \n }\r\ + \n\r\ + \n :local FileSize [ /file/get \$FileName size ];\r\ + \n :local Return \"\";\r\ + \n :local VarSize 0;\r\ + \n :while (\$VarSize != \$FileSize) do={\r\ + \n :set Return (\$Return . ([ /file/read offset=\$VarSize chunk-size=32\ + 768 file=\$FileName as-value ]->\"data\"));\r\ + \n :set FileSize [ /file/get \$FileName size ];\r\ + \n :set VarSize [ :len \$Return ];\r\ + \n :if (\$VarSize > \$FileSize) do={\r\ + \n :delay 100ms;\r\ + \n }\r\ + \n }\r\ + \n \$RmDir \$DirName;\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set FetchUserAgentStr do={\r\ + \n :local Caller [ :tostr \$1 ];\r\ + \n :global GlobalScriptsUrl;\r\ + \n :global CommitBrief;\r\ + \n :global IfThenElse;\r\ + \n :local Resource [ /system/resource/get ];\r\ + \n :return (\"User-Agent: Mikrotik/\" . \$Resource->\"version\" . \" \" .\ + \_\$Resource->\"architecture-name\" . \\\r\ + \n \" \" . \$Caller . \"/Fetch (\" . \$GlobalScriptsUrl . \"; \" . [ \$\ + CommitBrief ] . \")\");\r\ + \n}\r\ + \n\r\ + \n:set ScriptInstallUpdate do={ :onerror Err {\r\ + \n :local Scripts [ :toarray \$1 ];\r\ + \n :local NewComment [ :tostr \$2 ];\r\ + \n :global InitSetup;\r\ + \n\r\ + \n :global CommitId;\r\ + \n :global ScriptUpdatesCRLF;\r\ + \n :global GlobalConfVersion;\r\ + \n :global Identity;\r\ + \n :global CertificateAvailable;\r\ + \n :global CheckSumsVerify;\r\ + \n :global GlobalScriptsUrl;\r\ + \n :global SumsDirAndFileName;\r\ + \n :global GlobalScriptsUrlSuffix;\r\ + \n :global EitherOr;\r\ + \n :global FetchUserAgentStr;\r\ + \n :global Grep;\r\ + \n :global IfThenElse;\r\ + \n :global LogPrint;\r\ + \n :global ParseKeyValueStore;\r\ + \n :global RequiredRouterOS;\r\ + \n :global SendNotification2;\r\ + \n :global SymbolForNotification;\r\ + \n :global ValidateSyntax;\r\ + \n :global CommentsInScripts;\r\ + \n\r\ + \n :if ([ \$CertificateAvailable \"Root YE\" \"fetch\" ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Downloading certificate failed, trying wit\ + hout.\");\r\ + \n }\r\ + \n\r\ + \n :foreach Script in=\$Scripts do={\r\ + \n :if ([ :len [ /system/script/find where name=\$Script ] ] = 0) do={\ + \r\ + \n \$LogPrint info \$0 (\"Adding new script: \" . \$Script);\r\ + \n /system/script/add name=\$Script owner=\$Script source=\"#!rsc by \ + Vados\\n\" comment=\$NewComment;\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :local CommitIdBefore \$CommitId;\r\ + \n :local GlobalConfVersionBefore \$GlobalConfVersion;\r\ + \n :local ReloadGlobal false;\r\ + \n :local DeviceMode [ /system/device-mode/get ];\r\ + \n\r\ + \n :if (\$CheckSumsVerify = true) do={\r\ + \n :local CheckSums ({});\r\ + \n :do {\r\ + \n :local Url (\$GlobalScriptsUrl . \$SumsDirAndFileName . \$GlobalScr\ + iptsUrlSuffix);\r\ + \n \$LogPrint debug \$0 (\"Fetching checksums from url: \" . \$Url);\ + \r\ + \n :set CheckSums [ :deserialize from=json ([ /tool/fetch check-certi\ + ficate=yes-without-crl \\\r\ + \n http-header-field=({ [ \$FetchUserAgentStr \$0 ] }) \$Url output\ + =user as-value ]->\"data\") ];\r\ + \n } on-error={ \$LogPrint warning \$0 (\"Err = \" . \$Err); }\r\ + \n }\r\ + \n\r\ + \n :foreach Script in=[ /system/script/find where source~\"^#!rsc by Vado\ + s\" ] do={\r\ + \n :local ScriptVal [ /system/script/get \$Script ];\r\ + \n :local ScriptInfo [ \$ParseKeyValueStore (\$ScriptVal->\"comment\") \ + ];\r\ + \n :local SourceNew;\r\ + \n\r\ + \n :foreach Scheduler in=[ /system/scheduler/find where on-event~(\"\\\ + \\b\" . \$ScriptVal->\"name\" . \"\\\\b\") ] do={\r\ + \n :local SchedulerVal [ /system/scheduler/get \$Scheduler ];\r\ + \n :if (\$ScriptVal->\"policy\" != \$SchedulerVal->\"policy\") do={\r\ + \n \$LogPrint warning \$0 (\"Policies differ for script '\" . \$Scr\ + iptVal->\"name\" . \"' and its scheduler '\" . \$SchedulerVal->\"name\" . \ + \"'!\");\r\ + \n }\r\ + \n }\r\ + \n :do {\r\ + \n :if (\$ScriptInfo->\"ignore\" = true) do={\r\ + \n \$LogPrint debug \$0 (\"Ignoring script '\" . \$ScriptVal->\"nam\ + e\" . \"', as requested.\");\r\ + \n :error true;\r\ + \n }\r\ + \n :if (\$CheckSumsVerify = true) do={\r\ + \n :local CheckSum (\$CheckSums->(\$ScriptVal->\"name\"));\r\ + \n :if ([ :len (\$ScriptInfo->\"base-url\") ] = 0 && [ :len (\$Scri\ + ptInfo->\"url-suffix\") ] = 0 && \\\r\ + \n [ :convert transform=md5 to=hex [ :tolf (\$ScriptVal->\"sou\ + rce\") ] ] = \$CheckSum) do={\r\ + \n \$LogPrint debug \$0 (\"Checksum for script '\" . \$ScriptVal-\ + >\"name\" . \"' matches, ignoring.\");\r\ + \n :error true;\r\ + \n }\r\ + \n }\r\ + \n :if ([ :len (\$ScriptInfo->\"certificate\") ] > 0) do={\r\ + \n :if ([ \$CertificateAvailable (\$ScriptInfo->\"certificate\") \"\ + fetch\" ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Downloading certificate failed, tryi\ + ng without.\");\r\ + \n }\r\ + \n }\r\ + \n :onerror Err {\r\ + \n :local BaseUrl [ \$EitherOr (\$ScriptInfo->\"base-url\") \$Globa\ + lScriptsUrl ];\r\ + \n :local UrlSuffix [ \$EitherOr (\$ScriptInfo->\"url-suffix\") \$G\ + lobalScriptsUrlSuffix ];\r\ + \n :local Url (\$BaseUrl . \$ScriptVal->\"name\" . \".rsc\" . \$Url\ + Suffix);\r\ + \n \$LogPrint warning \$0 (\"Fetching script '\" . (\$ScriptVal->\"\ + name\") . \"' from url: \" . \$Url);\r\ + \n :local Result [ /tool/fetch check-certificate=yes-without-crl \\\ + \r\ + \n http-header-field=({ [ \$FetchUserAgentStr \$0 ] }) \$Url outp\ + ut=user as-value ];\r\ + \n :if (\$Result->\"status\" = \"finished\") do={\r\ + \n :set SourceNew [ :tolf (\$Result->\"data\") ];\r\ + \n } \r\ + \n } do={\r\ + \n \$LogPrint warning \$0 (\"Failed fetching script '\" . \$ScriptV\ + al->\"name\" . \"': \" . \$Err);\r\ + \n :if (\$Err != \"Fetch failed with status 404\") do={\r\ + \n :error false;\r\ + \n }\r\ + \n :if (\$ScriptVal->\"source\" = \"#!rsc by Vados\") do={\r\ + \n \$LogPrint warning \$0 (\"Removing dummy. Typo on installation\ + \?\");\r\ + \n /system/script/remove \$Script;\r\ + \n :error false;\r\ + \n }\r\ + \n :if (\$CheckSumsVerify = true) do={\r\ + \n :if ([ :len (\$ScriptInfo->\"base-url\") ] = 0 && [ :len (\$Sc\ + riptInfo->\"url-suffix\") ] = 0 && \\\r\ + \n [ :len \$CheckSum ] = 0) do={\r\ + \n \$LogPrint warning \$0 (\"Added the script manually\? Skip u\ + pdates with 'ignore=true' in comment.\");\r\ + \n }\r\ + \n }\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :if ([ :len \$SourceNew ] = 0) do={\r\ + \n \$LogPrint debug \$0 (\"No update for script '\" . (\$ScriptVal-\ + >\"name\") . \"'.\");\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :local SourceCRLF [ :tocrlf \$SourceNew ];\r\ + \n :if (\$InitSetup != true && ((\$ScriptVal->\"name\") != \"AM-Globa\ + lConfig\" || (\$ScriptVal->\"name\") != \"AM-GlobalFunc\")) do={\r\ + \n :if (\$SourceNew = (\$ScriptVal->\"source\") || \$SourceCRLF = (\ + \$ScriptVal->\"source\")) do={\r\ + \n \$LogPrint debug \$0 (\"Script '\" . (\$ScriptVal->\"name\") \ + . \"' source did not change. End of lines set to CRLF.\");\r\ + \n if (\$ScriptUpdatesCRLF = false) do={\r\ + \n :put [ :tolf \$SourceNew ];\r\ + \n \$LogPrint debug \$0 (\"Script '\" . (\$ScriptVal->\"name\"\ + ) . \"' source update end of lines to LF.\");\r\ + \n }\r\ + \n :error false;\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :if ([ :pick \$SourceNew 0 14 ] != \"#!rsc by Vados\") do={\r\ + \n \$LogPrint warning \$0 (\"Looks like new script '\" . \$ScriptVa\ + l->\"name\" . \"' is not valid (missing shebang = '\$shebang') Ignoring!\"\ + );\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :if (\$CommentsInScripts = true) do={\r\ + \n :local CommentLine [ \$Grep \$SourceNew (\"\\23 Script comment:\ + \_\") ];\r\ + \n :if ([ :len \$CommentLine ] = 0) do={\r\ + \n \$LogPrint debug \$0 (\"The search in new script '\" . (\$Scr\ + iptVal->\"name\") . \"' for comment in script body, is not found result Ig\ + noring!\");\r\ + \n :error false;\r\ + \n } else={\r\ + \n :if ([ :len (\$ScriptVal->\"comment\")] = 0 || [ :len (\$Scri\ + ptVal->\"comment\")] != [ :pick \$CommentLine ([ :find \$CommentLine \":\"\ + ] + 2) [ :len \$CommentLine] ]) do={\r\ + \n \$LogPrint debug \$0 (\"Exsiting comment for script '\" . (\ + \$ScriptVal->\"name\") . \"' is '\" . (\$ScriptVal->\"comment\") . \"'.\")\ + ;\r\ + \n :set (\$ScriptVal->\"comment\") [ :pick \$CommentLine ([ :f\ + ind \$CommentLine \":\"] + 2) [ :len \$CommentLine] ];\r\ + \n \$LogPrint debug \$0 (\"New comment (\" . (\$ScriptVal->\"c\ + omment\") . \") for script '\" . (\$ScriptVal->\"name\") . \"' has been ad\ + ded!\");\r\ + \n } else={\r\ + \n \$LogPrint debug \$0 (\"Comment for script '\" . (\$ScriptV\ + al->\"name\") . \"' did not change.\");\r\ + \n :error false;\r\ + \n }\r\ + \n } \r\ + \n }\r\ + \n\r\ + \n :local RequiredROS ([ \$ParseKeyValueStore [ \$Grep \$SourceNew (\ + \"\\23 requires RouterOS, \") ] ]->version);\r\ + \n :if ([ \$RequiredRouterOS \$0 [ \$EitherOr \$RequiredROS \"0.0\" ]\ + \_false ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"The script '\" . (\$ScriptVal->\"name\ + \") . \"' requires RouterOS \" . \\\r\ + \n \$RequiredROS . \", which is not met by your installation. I\ + gnoring!\");\r\ + \n :error false;\r\ + \n }\r\ + \n :local RequiredDM [ \$ParseKeyValueStore [ \$Grep \$SourceNew (\"\ + \\23 requires device-mode, \") ] ];\r\ + \n :local MissingDM ({});\r\ + \n :foreach Feature,Value in=\$RequiredDM do={\r\ + \n :if ([ :typeof (\$DeviceMode->\$Feature) ] = \"bool\" && (\$Devi\ + ceMode->\$Feature) = false) do={\r\ + \n :set MissingDM (\$MissingDM, \$Feature);\r\ + \n }\r\ + \n }\r\ + \n :if ([ :len \$MissingDM ] > 0) do={\r\ + \n \$LogPrint warning \$0 (\"The script '\" . (\$ScriptVal->\"name\ + \") . \"' requires disabled \" . \\\r\ + \n \"device-mode features (\" . [ :tostr \$MissingDM ] . \"). I\ + gnoring!\");\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :if ([ \$ValidateSyntax \$SourceNew ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Syntax validation for script '\" . (\$\ + ScriptVal->\"name\") . \"' failed! Ignoring!\");\r\ + \n :error false;\r\ + \n }\r\ + \n \r\ + \n :log info (\"Updating script: \" . (\$ScriptVal->\"name\") . \" Sc\ + ript comment: \" . (\$ScriptVal->\"comment\"));\r\ + \n\r\ + \n /system/script/set owner=(\$ScriptVal->\"name\") comment=(\$Script\ + Val->\"comment\") \\\r\ + \n source=[ \$IfThenElse (\$ScriptUpdatesCRLF = true) \$SourceCRL\ + F \$SourceNew ] \$Script;\r\ + \n :if (\$ScriptVal->\"name\" = \"AM-GlobalConfig\" || \\\r\ + \n \$ScriptVal->\"name\" = \"AM-GlobalFunc\" || \\\r\ + \n \$ScriptVal->\"name\" ~ (\"^(AM-GlobalFunc\\\\.d|mod)/.\")) d\ + o={\r\ + \n :set ReloadGlobal true;\r\ + \n }\r\ + \n } on-error={ }\r\ + \n }\r\ + \n :if (\$ReloadGlobal = true) do={\r\ + \n \$LogPrint info \$0 (\"Reloading global configuration and functions.\ + \");\r\ + \n :onerror Err {\r\ + \n :global InitSetup (a);\r\ + \n /system/script {run AM-GlobalConfig; run AM-GlobalFunc;};\r\ + \n } do={\$LogPrint error \$0 (\"Reloading global configuration and fun\ + ctions failed! \" . \$Err)}\r\ + \n }\r\ + \n :if (\$GlobalConfVersionBefore > \$GlobalConfVersion) do={\r\ + \n \$LogPrint warning \$0 (\"The configuration version decreased from \ + \" . \\\r\ + \n \$GlobalConfVersionBefore . \" to \" . \$GlobalConfVersion . \\\r\ + \n \". Installed an older version\?\");\r\ + \n }\r\ + \n :if (\$GlobalConfVersionBefore < \$GlobalConfVersion) do={\r\ + \n :global GlobalConfChanges;\r\ + \n :global GlobalConfMigration;\r\ + \n :local ChangeLogCode;\r\ + \n :if ([ :len \$ChangeLogCode ] > 0) do={\r\ + \n :if ([ \$ValidateSyntax \$ChangeLogCode ] = true) do={\r\ + \n :onerror Err {\r\ + \n [ :parse \$ChangeLogCode ];\r\ + \n } do={\$LogPrint warning \$0 (\"The changelog failed to run: \" \ + . \$Err)}\r\ + \n } else={\$LogPrint warning \$0 (\"The changelog failed syntax vali\ + dation!\")}\r\ + \n }\r\ + \n :if ([ :len \$GlobalConfMigration ] > 0) do={\r\ + \n :for I from=(\$GlobalConfVersionBefore + 1) to=\$GlobalConfVersion\ + \_do={\r\ + \n :local Migration (\$GlobalConfMigration->[ :tostr \$I ]);\r\ + \n :do {\r\ + \n :if ([ :typeof \$Migration ] != \"str\") do={\r\ + \n \$LogPrint debug \$0 (\"Migration code for change \" . \$I .\ + \_\" is not available.\");\r\ + \n :error false;\r\ + \n }\r\ + \n :if ([ \$ValidateSyntax \$Migration ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Migration code for change \" . \$I\ + \_. \" failed syntax validation!\");\r\ + \n :error false}\r\ + \n \$LogPrint info \$0 (\"Applying migration for change \" . \$I \ + . \": \" . \$Migration);\r\ + \n :onerror Err {\r\ + \n [ :parse \$Migration ];\r\ + \n } do={\$LogPrint warning \$0 (\"Migration code for change \" .\ + \_\$I . \" failed to run: \" . \$Err)}\r\ + \n } on-error={ }\r\ + \n }\r\ + \n }\r\ + \n :local NotificationMessage (\"The configuration version on \" . \$Id\ + entity . \" increased \" . \\\r\ + \n \"to \" . \$GlobalConfVersion . \", current configuration may nee\ + d modification. \" . \\\r\ + \n \"Please review and update global-config-overlay, then re-run glo\ + bal-config.\");\r\ + \n \$LogPrint info \$0 (\$NotificationMessage);\r\ + \n :if ([ :len \$GlobalConfChanges ] > 0) do={\r\ + \n :set NotificationMessage (\$NotificationMessage . \"\\n\\nChanges:\ + \");\r\ + \n :for I from=(\$GlobalConfVersionBefore + 1) to=\$GlobalConfVersion\ + \_do={\r\ + \n :local Change (\$GlobalConfChanges->[ :tostr \$I ]);\r\ + \n :set NotificationMessage (\$NotificationMessage . \"\\n \" . \\\ + \r\ + \n [ \$SymbolForNotification \"pushpin\" \"*\" ] . \$Change);\r\ + \n \$LogPrint info \$0 (\"Change \" . \$I . \": \" . \$Change);\r\ + \n }\r\ + \n } else={\r\ + \n :set NotificationMessage (\$NotificationMessage . \"\\n\\nNews and\ + \_changes are not available.\");\r\ + \n\r\ + \n }\r\ + \n\r\ + \n :if ([ :len \$GlobalConfChanges ] > 0) do={ :set GlobalConfChanges; \ + } else={ :global GlobalConfChanges (a); }\r\ + \n :if ([ :len \$GlobalConfMigration ] > 0) do={ :set GlobalConfMigrati\ + on; } else={ :global GlobalConfMigration (a); }\r\ + \n }\r\ + \n} do={\r\ + \n :global ExitOnError; \$ExitOnError \$0 \$Err;\r\ + \n} }\r\ + \n\r\ + \n# load modules\r\ + \n:foreach Script in=[ /system/script/find where name ~ \"^(global-functio\ + ns\\\\.d|mod)/.\" ] do={\r\ + \n :local ScriptVal [ /system/script/get \$Script ];\r\ + \n :if ([ \$ValidateSyntax (\$ScriptVal->\"source\") ] = true) do={\r\ + \n :onerror Err {\r\ + \n /system/script/run \$Script;\r\ + \n } do={\r\ + \n \$LogPrint error \$0 (\"Module '\" . \$ScriptVal->\"name\" . \"' f\ + ailed to run: \" . \$Err);\r\ + \n }\r\ + \n } else={\r\ + \n \$LogPrint error \$0 (\"Module '\" . \$ScriptVal->\"name\" . \"' fai\ + led syntax validation, skipping.\");\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n# Add and fix global scheduler\r\ + \n:put \"Add or/and fix Global scheduler...\";\r\ + \n:local OnEvent \"/system/script { run AM-GlobalConfig; run AM-GlobalFunc\ + ; }\";\r\ + \n:local Comment \"Every Day Set Global Environment Variables\";\r\ + \n:if ([ :len [ /system/scheduler/find where name=\"AM-SetGlobalEnv\" ] ] \ + = 0) do={\r\ + \n /system/scheduler/add name=\"AM-SetGlobalEnv\" comment=\$Comment on-ev\ + ent=\$OnEvent start-time=startup;\r\ + \n}\r\ + \n:if ([ /system/scheduler/get \"AM-SetGlobalEnv\" comment ] != \$Comment)\ + \_do={\r\ + \n /system/scheduler/set \"AM-SetGlobalEnv\" comment=\$Comment;\r\ + \n}\r\ + \n:if ([ /system/scheduler/get \"AM-SetGlobalEnv\" on-event ] != \$OnEvent\ + ) do={\r\ + \n /system/scheduler/set \"AM-SetGlobalEnv\" on-event=\$OnEvent;\r\ + \n}\r\ + \n# Add Update Script scheduler\r\ + \n:put \"Add or/and fix Update Script scheduler\";\r\ + \n:set OnEvent \":global ScriptInstallUpdate; \\\$ScriptInstallUpdate;\";\ + \r\ + \n:set Comment \"Every Day Check For Update Scripts\";\r\ + \n:if ([ :len [ /system/scheduler/find where name=\"AM-ScriptInstallUpdate\ + \" ] ] = 0) do={\r\ + \n/system/scheduler/add name=\"AM-ScriptInstallUpdate\" comment=\$Comment \ + start-time=startup interval=1d on-event=\$OnEvent;\r\ + \n}\r\ + \n\r\ + \n:onerror Err {\r\ + \n :global GlobalConfReady;\r\ + \n :retry { :if (\$GlobalConfReady != true) do={ :error (\"Global configs\ + \_not ready.\"); }; } delay=100ms max=5;\r\ + \n\r\ + \n:log warning (\"This script \$ScriptName Loaded \" . \\\r\ + \n [ \$IfThenElse (\$CommitId != \"unknown\") ([ \$CommitBrief ] . \" \ + \") ] . \\\r\ + \n \"on \" . \$devBoardName . \"\\nRouterOS: \" . \$devCurVersion . \"\ + \\nArchitecture: \" . \$devCurArch . \"\\nIdentity: \" . \$Identity);\r\ + \n # signal we are ready\r\ + \n:set GlobalFuncReady true;\r\ + \n:set ExitOK true;\r\ + \n\r\ + \n:log info (\$0 . \"Global configs ready!\");\r\ + \n} do={\r\ + \n :global ExitOnError; \$ExitOnError \$0 \$Err;\r\ + \n}\r\ + \n" +add comment="download, import and update firewall address-lists" \ + dont-require-permissions=no name=AM-FwAddrLists owner=AM-FwAddrLists \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + source="#!rsc by Vados\r\ + \n# RouterOS script: AM-FwAddrLists\r\ + \n# Script comment: download, import and update firewall address-lists\r\ + \n# Copyright (c) 2007-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n# https://ros.vados.ru/doc/fw-addr-lists.md\r\ + \n:local ExitOK false;\r\ + \n:onerror Err {\r\ + \n :global GlobalConfReady; :global GlobalFuncReady;\r\ + \n :retry { :if (\$GlobalConfReady != true || \$GlobalFuncReady != true) \ + \\\r\ + \n do={ :error (\"Global config and/or functions not ready.\"); }; } \ + delay=500ms max=50;\r\ + \n :local ScriptName [ :jobname ];\r\ + \n\r\ + \n :global GlobalScriptsUrl;\r\ + \n :local ListsDirName (\"fw-addr-lists.d/\" . [ /system identity get nam\ + e ] . \"/\");\r\ + \n :local ListsUrl (\$GlobalScriptsUrl . \$ListsDirName);\r\ + \n :local ListsIndex \"index.lst\";\r\ + \n :local AddrListsTimeOut 1d;\r\ + \n :local CheckCerts false;\r\ + \n\r\ + \n :global CertificateAvailable;\r\ + \n :global EitherOr;\r\ + \n :global FetchHugeFiles;\r\ + \n :global HumanReadableNum;\r\ + \n :global IfThenElse;\r\ + \n :global LogPrint;\r\ + \n :global NetMask4;\r\ + \n :global NetMask6;\r\ + \n :global ScriptLock;\r\ + \n \r\ + \n :local FindDelim do={\r\ + \n :local ValidChars \"0123456789.:/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi\ + jklmnopqrstuvwxyz-\";\r\ + \n :for I from=0 to=[ :len \$1 ] do={\r\ + \n :if ([ :typeof [ :find \$ValidChars [ :pick (\$1 . \" \") \$I ] ] \ + ] != \"num\") do={\r\ + \n :return \$I;\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :local GetBranch do={\r\ + \n :global EitherOr;\r\ + \n :return [ :pick [ :convert transform=md5 to=hex [ :pick \$1 0 [ \$Ei\ + therOr [ :find \$1 \"/\" ] [ :len \$1 ] ] ] ] 0 2 ];\r\ + \n }\r\ + \n \r\ + \n :if ([ \$ScriptLock \$ScriptName ] = false) do={\r\ + \n :set ExitOK true;\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :local ListComment (\"managed by \" . \$ScriptName);\r\ + \n :local Url (\$ListsUrl . \$ListsIndex);\r\ + \n :local tmpIndex false;\r\ + \n\r\ + \n :for I from=1 to=5 do={\r\ + \n :if (\$tmpIndex = false) do={\r\ + \n :set tmpIndex [ :tolf [ \$FetchHugeFiles \$ScriptName \$Url \$Chec\ + kCerts ] ];\r\ + \n :if (\$tmpIndex = false && \$I < 5) do={\r\ + \n :log warning (\$ScriptName . \" Failed downloading address-list \ + index, \" . \$I . \". try from: \" . \$Url);\r\ + \n :delay ((\$I * \$I) . \"s\");\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n :if (\$tmpIndex = false) do={\r\ + \n :log warning (\$ScriptName . \" Failed downloading address-list inde\ + x from: \" . \$Url);\r\ + \n :set tmpIndex \"\";\r\ + \n }\r\ + \n\r\ + \n :foreach List in=[ :deserialize \$tmpIndex delimiter=\"\\n\" from=dsv \ + options=dsv.plain ] do={\r\ + \n# :set List (\$List->0);\r\ + \n :local ListName;\r\ + \n :local Delim [ \$FindDelim \$List ];\r\ + \n :if (\$Delim = 0) do={ :set List \"\"; };\r\ + \n :log warning (\$ScriptName . \" Parsing address-list index entry: \"\ + \_. \$List);\r\ + \n :if ([ :len \$List ] = 0) do={\r\ + \n :log error (\$ScriptName . \" Failed parsing address-list index en\ + try: \" . \$List);\r\ + \n } else={\r\ + \n :set ListName [ :pick \$List 0 \$Delim ];\r\ + \n }\r\ + \n :log warning (\$ScriptName . \" Parsing address-list index entry: \"\ + \_. \$ListName . \" - Ok.\");\r\ + \n :local ListUrl (\$ListsUrl . \$ListName);\r\ + \n :local CntAdd 0;\r\ + \n :local CntRenew 0;\r\ + \n :local CntRemove 0;\r\ + \n :local IPv4Addresses ({});\r\ + \n :local IPv6Addresses ({});\r\ + \n :local Failure false;\r\ + \n :local Data false;\r\ + \n :local TimeOut \$AddrListTimeOut;\r\ + \n\r\ + \n :for I from=1 to=5 do={\r\ + \n :if (\$Data = false) do={\r\ + \n :set Data [ :tolf [ \$FetchHugeFiles \$ScriptName \$ListUrl \$Ch\ + eckCerts ] ];\r\ + \n :if (\$Data = false && \$I < 5) do={\r\ + \n :log warning (\$ScriptName . \" Failed downloading for list '\ + \" . \$ListName . \"', \" . \$I . \". try from: \" . \$ListUrl);\r\ + \n :delay ((\$I * \$I) . \"s\");\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :if (\$Data = false) do={\r\ + \n :set Data \"\";\r\ + \n :set Failure true;\r\ + \n :log warning (\$ScriptName . \" Failed downloading for list '\" . \ + \$ListName . \"' from: \" . \$ListUrl);\r\ + \n } else={\r\ + \n :log warning (\$ScriptName . \" Downloaded \" . [ \$HumanReadableN\ + um [ :len \$Data ] 1024 ] . \"B for list '\" . \$ListName . \"' from: \" .\ + \_\$ListUrl);\r\ + \n }\r\ + \n\r\ + \n :foreach Line in=[ :deserialize \$Data delimiter=\"\\n\" from=dsv op\ + tions=dsv.plain ] do={\r\ + \n :set Line (\$Line->0);\r\ + \n :local Address;\r\ + \n :if ([ :pick \$Line 0 1 ] = \"{\" && [ :pick \$Line ([ :len \$Line\ + \_] - 1) ] = \"}\") do={\r\ + \n :do {\r\ + \n :set Address [ :tostr ([ :deserialize from=json \$Line ]->\"ci\ + dr\") ];\r\ + \n } on-error={ }\r\ + \n } else={\r\ + \n :set Address ([ :pick \$Line 0 [ \$FindDelim \$Line ] ] . (\$L\ + ist->\"cidr\"));\r\ + \n }\r\ + \n :do {\r\ + \n :local Branch;\r\ + \n :if (\$Address ~ \"^[0-9]{1,3}\\\\.[0-9]{1,3}\\\\.[0-9]{1,3}\\\\\ + .[0-9]{1,3}(/[0-9]{1,2})\?\\\$\") do={\r\ + \n :local Net \$Address;\r\ + \n :local CIDR 32;\r\ + \n :local Slash [ :find \$Address \"/\" ];\r\ + \n :if ([ :typeof \$Slash ] = \"num\") do={\r\ + \n :set Net [ :toip [ :pick \$Address 0 \$Slash ] ]\r\ + \n :set CIDR [ :pick \$Address (\$Slash + 1) [ :len \$Address ]\ + \_];\r\ + \n :set Address [ :tostr (([ :toip \$Net ] & [ \$NetMask4 \$CID\ + R ]) . [ \$IfThenElse (\$CIDR < 32) (\"/\" . \$CIDR) ]) ];\r\ + \n }\r\ + \n :set Branch [ \$GetBranch \$Address ];\r\ + \n :set (\$IPv4Addresses->\$Branch->\$Address) \$TimeOut;\r\ + \n }\r\ + \n :if (\$Address ~ \"^[0-9a-zA-Z]*:[0-9a-zA-Z:\\\\.]+(/[0-9]{1,3})\ + \?\\\$\") do={\r\ + \n :local Net \$Address;\r\ + \n :local CIDR 128;\r\ + \n :local Slash [ :find \$Address \"/\" ];\r\ + \n :if ([ :typeof \$Slash ] = \"num\") do={\r\ + \n :set Net [ :toip6 [ :pick \$Address 0 \$Slash ] ]\r\ + \n :set CIDR [ :pick \$Address (\$Slash + 1) [ :len \$Address ]\ + \_];\r\ + \n }\r\ + \n :set Address (([ :toip6 \$Net ] & [ \$NetMask6 \$CIDR ]) . \"/\ + \" . \$CIDR);\r\ + \n :set Branch [ \$GetBranch \$Address ];\r\ + \n :set (\$IPv6Addresses->\$Branch->\$Address) \$TimeOut;\r\ + \n }\r\ + \n :if (\$Address ~ \"^[\\\\.a-zA-Z0-9-]+\\\\.[a-zA-Z]{2,}\\\$\") d\ + o={\r\ + \n :set Branch [ \$GetBranch \$Address ];\r\ + \n :set (\$IPv4Addresses->\$Branch->\$Address) \$TimeOut;\r\ + \n :set (\$IPv6Addresses->\$Branch->\$Address) \$TimeOut;\r\ + \n }\r\ + \n } on-error={ }\r\ + \n }\r\ + \n \r\ + \n\r\ + \n :foreach Entry in=[ /ip/firewall/address-list/find where \\\r\ + \n list=\$ListName comment=\$ListComment ] do={\r\ + \n :local Address [ /ip/firewall/address-list/get \$Entry address ];\ + \r\ + \n :local Branch [ \$GetBranch \$Address ];\r\ + \n :local TimeOut (\$IPv4Addresses->\$Branch->\$Address);\r\ + \n :if ([ :typeof \$TimeOut ] = \"time\") do={\r\ + \n :log warning (\$ScriptName . \" Renewing IPv4 address \" . \$Add\ + ress . \\\r\ + \n \" in list '\" . \$ListName . \"' with \" . \$TimeOut . \".\ + \");\r\ + \n /ip/firewall/address-list/set \$Entry timeout=\$TimeOut;\r\ + \n :set (\$IPv4Addresses->\$Branch->\$Address);\r\ + \n :set CntRenew (\$CntRenew + 1);\r\ + \n } else={\r\ + \n :if (\$Failure = false) do={\r\ + \n :log warning (\$ScriptName . \" Removing IPv4 address \" . \$A\ + ddress . \\\r\ + \n \" from list '\" . \$ListName . \".\");\r\ + \n /ip/firewall/address-list/remove \$Entry;\r\ + \n :set CntRemove (\$CntRemove + 1);\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :foreach Entry in=[ /ipv6/firewall/address-list/find where \\\r\ + \n list=\$ListName comment=\$ListComment ] do={\r\ + \n :local Address [ /ipv6/firewall/address-list/get \$Entry address ]\ + ;\r\ + \n :local Branch [ \$GetBranch \$Address ];\r\ + \n :local TimeOut (\$IPv6Addresses->\$Branch->\$Address);\r\ + \n :if ([ :typeof \$TimeOut ] = \"time\") do={\r\ + \n :log warning (\$ScriptName . \" Renewing IPv6 address \" . \$Add\ + ress . \\\r\ + \n \" in list '\" . \$ListName . \"' with \" . \$TimeOut . \".\ + \");\r\ + \n /ipv6/firewall/address-list/set \$Entry timeout=\$TimeOut;\r\ + \n :set (\$IPv6Addresses->\$Branch->\$Address);\r\ + \n :set CntRenew (\$CntRenew + 1);\r\ + \n } else={\r\ + \n :if (\$Failure = false) do={\r\ + \n :log warning (\$ScriptName . \" Removing IPv6 address \" . \$A\ + ddress . \\\r\ + \n \" from list '\" . \$ListName . \".\");\r\ + \n /ipv6/firewall/address-list/remove \$Entry;\r\ + \n :set CntRemove (\$CntRemove + 1);\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :foreach BranchName,Branch in=\$IPv4Addresses do={\r\ + \n :log warning (\$ScriptName . \" Handling branch: \" . \$BranchName\ + );\r\ + \n :foreach Address,Timeout in=\$Branch do={\r\ + \n :log warning (\$ScriptName . \" Adding IPv4 address \" . \$Addre\ + ss . \\\r\ + \n \" to list '\" . \$ListName . \"' with \" . \$Timeout . \".\ + \");\r\ + \n :onerror Err {\r\ + \n /ip/firewall/address-list/add list=\$ListName comment=\$ListCo\ + mment \\\r\ + \n address=\$Address timeout=\$Timeout;\r\ + \n :set CntAdd (\$CntAdd + 1);\r\ + \n } do={\r\ + \n :log warning (\$ScriptName . \" Failed to add IPv4 address \" \ + . \$Address . \\\r\ + \n \" to list '\" . \$ListName . \"': \" . \$Err);\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :foreach BranchName,Branch in=\$IPv6Addresses do={\r\ + \n :log warning (\$ScriptName . \" Handling branch: \" . \$BranchName\ + );\r\ + \n :foreach Address,Timeout in=\$Branch do={\r\ + \n :log warning (\$ScriptName . \" Adding IPv6 address \" . \$Addre\ + ss . \\\r\ + \n \" to list '\" . \$ListName . \"' with \" . \$Timeout . \".\ + \");\r\ + \n :onerror Err {\r\ + \n /ipv6/firewall/address-list/add list=\$ListName comment=\$List\ + Comment \\\r\ + \n address=\$Address timeout=\$Timeout;\r\ + \n :set CntAdd (\$CntAdd + 1);\r\ + \n } do={\r\ + \n :log warning (\$ScriptName . \" Failed to add IPv6 address \" \ + . \$Address . \\\r\ + \n \" to list '\" . \$ListName . \"': \" . \$Err);\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :log info (\$ScriptName . \" list: \" . \$ListName . \\\r\ + \n \" (\" . [ \$HumanReadableNum (\$CntAdd + \$CntRenew) 1000 ] . \ + \")\" . \\\r\ + \n \" -- added: \" . [ \$HumanReadableNum \$CntAdd 1000 ] . \\\r\ + \n \" - renewed: \" . [ \$HumanReadableNum \$CntRenew 1000 ] . \\\r\ + \n \" - removed: \" . [ \$HumanReadableNum \$CntRemove 1000 ]);\r\ + \n }\r\ + \n} do={\r\ + \n :global ExitError; \$ExitError \$ExitOK [ :jobname ] \$Err;\r\ + \n}\r\ + \n" +add comment=\ + "Lookup IP addresses for RKN list and add them to firewall address-list" \ + dont-require-permissions=no name=AM-RKN-dnsLookup owner=AM-RKN-dnsLookup \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + source="#!rsc by Vados\r\ + \n# RouterOS script: AM-RKN-dnsLookup\r\ + \n# Script comment: Lookup IP addresses for RKN list and add them to firew\ + all address-list\r\ + \n# Copyright (c) 2007-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n# requires device-mode, fetch\r\ + \n#\r\ + \n# Script description: This script is intended to be run periodically, e.\ + g. once a day, to update the IP addresses in the firewall address-list bas\ + ed on the RKN list.\r\ + \n# It resolves the domain names in the RKN list and a\ + dds the corresponding IP addresses to the specified firewall address-list.\ + \r\ + \n# The script also handles CNAME records by following\ + \_them until it finds A records.\r\ + \n# Usage:\r\ + \n# /system/script { run AM-RKN-dnsLookup; }\r\ + \n:local ScriptName [ :jobname ];\r\ + \n\r\ + \n:global dnsLookupReady false;\r\ + \n:if ([:typeof \$dnsLookupReady] != \"boolean\") do={ :set dnsLookupReady\ + \_true; }\r\ + \nwhile (!\$dnsLookupReady) do={ :nothing; }\r\ + \n:set dnsLookupReady false;\r\ + \n\r\ + \n:local arrRKN {\r\ + \n \"telegra.ph\"\r\ + \n \"grani.ru\"\r\ + \n \"xhamster.com\"\r\ + \n \"kasparov.ru\"\r\ + \n \"lostfilm.tv\"\r\ + \n \"rutracker.org\"\r\ + \n \"lurkmore.to\"\r\ + \n \"dou.ua\"\r\ + \n \"youporn.com\"\r\ + \n \"pornolab.net\"\r\ + \n \"crimerussia.com\"\r\ + \n \"telegram.org\"\r\ + \n \"api.telegram.org\"\r\ + \n \"telegram.me\"\r\ + \n \"t.me\";}\r\ + \n\r\ + \n:local ListRKN \"FuckRKN\";\r\ + \n:local ListComment (\"ListRKN managed by \" . \$ScriptName);\r\ + \n:foreach aListItem in=[/ip/firewall/address-list find list=\$ListRKN] do\ + ={\r\ + \n /ip firewall address-list remove \$aListItem;\r\ + \n}\r\ + \n:foreach aItem in=\$arrRKN do={\r\ + \n :do {\r\ + \n :resolve \$aItem;\r\ + \n } on-error={\r\ + \n :log error \"dns resolve failure [ ip - resolve ip ]\";\r\ + \n }\r\ + \n :foreach dnsRecord in=[/ip dns cache all find where (name=\$aItem)] \ + do={\r\ + \n :if ([/ip dns cache all get \$dnsRecord type]=\"A\") do={\r\ + \n :local newAddress [/ip dns cache all get \$dnsRecord data];\ + \r\ + \n :do {\r\ + \n /ip firewall address-list add list=\$ListRKN address=\$n\ + ewAddress comment=\$aItem;\r\ + \n } on-error={\r\ + \n :log error \"error when adding ip to list: \$newAddress\ + \";\r\ + \n }\r\ + \n }\r\ + \n :if ([/ip dns cache all get \$dnsRecord type]=\"CNAME\") do={\r\ + \n :local cname;\r\ + \n :local nextCname;\r\ + \n :set cname [/ip dns cache all find where (name=\$aItem && ty\ + pe=\"CNAME\")];\r\ + \n :set nextCname [/ip dns cache all find where (name=[/ip dns \ + cache all get \$cname data] && type=\"CNAME\")];\r\ + \n :while (\$nextCname != \"\") do={\r\ + \n :set cname \$nextCname;\r\ + \n :set nextCname [/ip dns cache all find where (name=[/ip \ + dns cache all get \$cname data] && type=\"CNAME\")];\r\ + \n }\r\ + \n :foreach aRecord in=[/ip dns cache all find where (name=[/ip\ + \_dns cache all get \$cname data] && type=\"A\")] do={\r\ + \n :do {\r\ + \n /ip firewall address-list add list=\$ListRKN address\ + =[/ip dns cache all get \$aRecord data] comment=\$aItem;\r\ + \n } on-error={\r\ + \n :log error \"error when adding ip to list: \$newAddr\ + ess\";\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:if ([ :len [ /system/scheduler/find where name=\$ScriptName ] ] = 0) do\ + ={\r\ + \n :log error (\$ScriptName . \"System Scheduler for script: \" . \$Scri\ + ptName . \" is NOT SET! Fix It Now!\");\r\ + \n /system/scheduler/add name=\$ScriptName on-event=\"/system/script { \ + run \$ScriptName; }\" comment=\"Update RKN DNS Looup\" interval=00:20:00 p\ + olicy=\"ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon\"\ + \_start-time=startup;\r\ + \n }\r\ + \n:set dnsLookupReady true;\r\ + \ndelay 5s; \r\ + \n:global dnsLookupReady (a);\r\ + \n" +add dont-require-permissions=no name=dnsForwarders owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + !rsc by Vados\r\ + \n# RouterOS script: AM-dnsForwarders\r\ + \n# Script comment: DNS Forwarders and DOH Servers | by @xmrdenb43\r\ + \n# Copyright (c) 2005-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n# requires device-mode, fetch, scheduler\r\ + \n# \r\ + \n# tested on hap ac lite tc/hap ax3, RoS 7.18.2+\r\ + \n\r\ + \n\r\ + \n/ip/dns/set allow-remote-requests=yes doh-max-concurrent-queries=100 doh\ + -max-server-connections=20 use-doh-server=https://security.cloudflare-dns.\ + com/dns-query verify-doh-cert=no;\r\ + \n\r\ + \n/ip dns static\r\ + \n:do {\r\ + \nadd address=8.8.8.8 comment=\"DNS Google\" name=dns.google type=A\r\ + \nadd address=8.8.4.4 comment=\"DNS Google\" name=dns.google type=A\r\ + \nadd address=9.9.9.9 comment=\"DNS Quad9\" name=dns.quad9.net type=A\r\ + \nadd address=149.112.112.112 comment=\"DNS Quad9\" name=dns.quad9.net typ\ + e=A\r\ + \nadd address=195.133.25.16 comment=\"DNS Comss\" name=dns.comss.one type=\ + A\r\ + \n\r\ + \n/ip dns forwarders\r\ + \nadd doh-servers=https://cloudflare-dns.com/dns-query name=\"CloudFlare D\ + oH\"\r\ + \nadd doh-servers=https://secure.cloudflare-dns.com/dns-query name=\"Cloud\ + Flare Secure DoH\"\r\ + \nadd disabled=yes doh-servers=https://dns.quad9.net/dns-query name=\"Quad\ + 9 Default\" verify-doh-cert=no\r\ + \nadd doh-servers=https://dns.google/dns-query name=\"Google DoH\"\r\ + \nadd dns-servers=dns.comss.one doh-servers=https://dns.comss.one/mikrotik\ + \_name=\"Comss DoH\" verify-doh-cert=no\r\ + \nadd doh-servers=https://cloudflare-dns.com/dns-query,https://dns.google/\ + dns-query name=\"CF & Google DoH\"\r\ + \nadd dns-servers=1.0.0.1,8.8.4.4,1.1.1.1,8.8.8.8,77.88.8.1,77.88.8.8 name\ + =\"CF & G & Ya IPv4\" verify-doh-cert=no\r\ + \n} on-error={ }\r\ + \n\r\ + \n" +add dont-require-permissions=no name=AM-ADguardHome-container owner=vados \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + source="#!rsc by Vados\r\ + \n# RouterOS script: AM-ADguardHome-container\r\ + \n# Script comment: ADguardHome-container to container | by @xdenb43\r\ + \n# Copyright (c) 2005-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n# requires device-mode, fetch, scheduler\r\ + \n# \r\ + \n# tested on hap ac lite tc/hap ax3, RoS 7.18.2+\r\ + \n# tested on hap ax3/RoS 7.17.2+\r\ + \n\r\ + \n# enable containers, follow https://help.mikrotik.com/docs/spaces/ROS/pa\ + ges/84901929/Container\r\ + \n#/system/device-mode/update container=yes\r\ + \n\r\ + \n# MAIN PART STARTS HERE\r\ + \n/interface veth\r\ + \nadd address=192.168.254.5/24 gateway=192.168.254.1 name=ADGUARD-HOME\r\ + \n\r\ + \n/interface bridge\r\ + \nadd name=Bridge-Docker port-cost-mode=short\r\ + \n/interface bridge port\r\ + \nadd bridge=Bridge-Docker interface=ADGUARD-HOME\r\ + \n/ip address\r\ + \nadd address=192.168.254.1/24 interface=Bridge-Docker network=192.168.254\ + .0\r\ + \n\r\ + \n/ip firewall nat\r\ + \nadd action=masquerade chain=srcnat comment=AdGuardHome src-address=192.1\ + 68.254.5\r\ + \n\r\ + \n# USB flash drive, FS ext4\r\ + \n/container config\r\ + \nset ram-high=200.0MiB registry-url=https://registry-1.docker.io tmpdir=/\ + usb1/docker/pull\r\ + \n\r\ + \n/container mounts\r\ + \nadd dst=/opt/adguardhome/conf name=adguard_home_conf src=/usb1/docker_co\ + nfigs/adguard_home\r\ + \n\r\ + \n/container\r\ + \nadd cmd=\"-c /opt/adguardhome/conf/AdGuardHome.yaml -h 0.0.0.0 -w /opt/a\ + dguardhome/work\" entrypoint=/opt/adguardhome/AdGuardHome interface=ADGUAR\ + D-HOME logging=yes mounts=\\\r\ + \n adguard_home_conf root-dir=/usb1/docker/adguard_home workdir=/opt/ad\ + guardhome/work remote-image=adguard/adguardhome:latest\r\ + \n\r\ + \n/container/start [find where interface=ADGUARD-HOME]\r\ + \n\r\ + \n# ADH available on http://192.168.254.5:300 , configure before use\r\ + \n# Choose one of the options below\r\ + \n# uncomment lines before copying to terminal\r\ + \n\r\ + \n# OPTION 1\r\ + \n# Just set AGH ip as DNS server.\r\ + \n# /!\\ DNS FWD will work.\r\ + \n# /!\\ No device-related stats will be gathered (all dns requests are co\ + ming from mikrotik)\r\ + \n#/ip dns\r\ + \n#set allow-remote-requests=yes servers=192.168.254.5\r\ + \n#/ip firewall nat\r\ + \n#add action=redirect chain=dstnat comment=\"Incoming DNS redirect\" dst-\ + address-type=!local dst-port=53 in-interface-list=LAN protocol=udp\r\ + \n#add action=redirect chain=dstnat comment=\"Incoming DNS redirect\" dst-\ + address-type=!local dst-port=53 in-interface-list=LAN protocol=tcp\r\ + \n\r\ + \n\r\ + \n# OPTION 2\r\ + \n# Forward all DNS requests to ADH\r\ + \n# /!\\ DNS FWD will NOT work\r\ + \n# /!\\ WILL SHOW stats for every LAN device\r\ + \n#/ip firewall nat\r\ + \n#add action=dst-nat chain=dstnat comment=\"local AdGuard udp - NO NAT L\ + oopback / local addresses only!\" dst-port=53 in-interface-list=LAN protoc\ + ol=udp src-address=\\\r\ + \n# 192.168.88.0/24 to-addresses=192.168.254.5 to-ports=53\r\ + \n#add action=dst-nat chain=dstnat comment=\"local AdGuard tcp\" dst-port=\ + 53 in-interface-list=LAN protocol=tcp src-address=192.168.88.0/24 to-addre\ + sses=192.168.254.5 to-ports=53\r\ + \n# cat adguardhome_container.rsc\r\ + \n# adguard home to container | by @xdenb43\r\ + \n# tested on hap ax3/RoS 7.17.2+\r\ + \n\r\ + \n# enable containers, follow https://help.mikrotik.com/docs/spaces/ROS/pa\ + ges/84901929/Container\r\ + \n/system/device-mode/update container=yes\r\ + \n\r\ + \n# MAIN PART STARTS HERE\r\ + \n/interface veth\r\ + \nadd address=192.168.254.5/24 gateway=192.168.254.1 name=ADGUARD-HOME\r\ + \n\r\ + \n/interface bridge\r\ + \nadd name=Bridge-Docker port-cost-mode=short\r\ + \n/interface bridge port\r\ + \nadd bridge=Bridge-Docker interface=ADGUARD-HOME\r\ + \n/ip address\r\ + \nadd address=192.168.254.1/24 interface=Bridge-Docker network=192.168.254\ + .0\r\ + \n\r\ + \n/ip firewall nat\r\ + \nadd action=masquerade chain=srcnat comment=AdGuardHome src-address=192.1\ + 68.254.5\r\ + \n\r\ + \n# USB flash drive, FS ext4\r\ + \n/container config\r\ + \nset ram-high=200.0MiB registry-url=https://registry-1.docker.io tmpdir=/\ + usb1/docker/pull\r\ + \n\r\ + \n/container mounts\r\ + \nadd dst=/opt/adguardhome/conf name=adguard_home_conf src=/usb1/docker_co\ + nfigs/adguard_home\r\ + \n\r\ + \n/container\r\ + \nadd cmd=\"-c /opt/adguardhome/conf/AdGuardHome.yaml -h 0.0.0.0 -w /opt/a\ + dguardhome/work\" entrypoint=/opt/adguardhome/AdGuardHome interface=ADGUAR\ + D-HOME logging=yes mounts=\\\r\ + \n adguard_home_conf root-dir=/usb1/docker/adguard_home workdir=/opt/ad\ + guardhome/work remote-image=adguard/adguardhome:latest\r\ + \n\r\ + \n/container/start [find where interface=ADGUARD-HOME]\r\ + \n\r\ + \n# ADH available on http://192.168.254.5:300 , configure before use\r\ + \n# Choose one of the options below\r\ + \n# uncomment lines before copying to terminal\r\ + \n\r\ + \n# OPTION 1\r\ + \n# Just set AGH ip as DNS server.\r\ + \n# /!\\ DNS FWD will work.\r\ + \n# /!\\ No device-related stats will be gathered (all dns requests are co\ + ming from mikrotik)\r\ + \n#/ip dns\r\ + \n#set allow-remote-requests=yes servers=192.168.254.5\r\ + \n#/ip firewall nat\r\ + \n#add action=redirect chain=dstnat comment=\"Incoming DNS redirect\" dst-\ + address-type=!local dst-port=53 in-interface-list=LAN protocol=udp\r\ + \n#add action=redirect chain=dstnat comment=\"Incoming DNS redirect\" dst-\ + address-type=!local dst-port=53 in-interface-list=LAN protocol=tcp\r\ + \n\r\ + \n\r\ + \n# OPTION 2\r\ + \n# Forward all DNS requests to ADH\r\ + \n# /!\\ DNS FWD will NOT work\r\ + \n# /!\\ WILL SHOW stats for every LAN device\r\ + \n#/ip firewall nat\r\ + \n#add action=dst-nat chain=dstnat comment=\"local AdGuard udp - NO NAT L\ + oopback / local addresses only!\" dst-port=53 in-interface-list=LAN protoc\ + ol=udp src-address=\\\r\ + \n# 192.168.88.0/24 to-addresses=192.168.254.5 to-ports=53\r\ + \n#add action=dst-nat chain=dstnat comment=\"local AdGuard tcp\" dst-port=\ + 53 in-interface-list=LAN protocol=tcp src-address=192.168.88.0/24 to-addre\ + sses=192.168.254.5 to-ports=53" +/user group +add name=backup policy="telnet,ssh,ftp,read,write,policy,test,sniff,sensitive,\ + !local,!reboot,!winbox,!password,!web,!api,!romon,!rest-api" +/interface bridge +add admin-mac=48:8F:5A:8E:1A:BC auto-mac=no mlag-peer-port="ether1 - Unet" \ + name=Bridge-LAN port-cost-mode=short +/interface wireless +set [ find default-name=wlan1 ] ampdu-priorities=0,1,2,3,4,5,6,7 band=\ + 2ghz-b/g/n basic-rates-a/g=\ + 6Mbps,9Mbps,12Mbps,18Mbps,24Mbps,36Mbps,48Mbps,54Mbps basic-rates-b=\ + 1Mbps,2Mbps,5.5Mbps,11Mbps channel-width=20/40mhz-XX country=belarus \ + disabled=no frequency=auto hw-protection-mode=rts-cts mode=ap-bridge \ + rate-set=configured skip-dfs-channels=10min-cac ssid=vados \ + wds-default-bridge=Bridge-LAN wds-mode=dynamic-mesh wireless-protocol=\ + 802.11 wmm-support=enabled wps-mode=disabled +set [ find default-name=wlan2 ] ampdu-priorities=0,1,2,3,4,5,6,7 band=\ + 5ghz-a/n/ac basic-rates-a/g=\ + 6Mbps,9Mbps,12Mbps,18Mbps,24Mbps,36Mbps,48Mbps,54Mbps channel-width=\ + 20/40/80mhz-XXXX country=belarus disabled=no frequency=auto \ + hw-protection-mode=rts-cts mode=ap-bridge rate-set=configured \ + skip-dfs-channels=10min-cac ssid=vados5g wds-default-bridge=Bridge-LAN \ + wds-mode=dynamic-mesh wireless-protocol=802.11 wmm-support=enabled \ + wps-mode=disabled +/interface wireless nstreme +set wlan1 enable-nstreme=yes +set wlan2 enable-nstreme=yes +/caps-man provisioning +add action=create-dynamic-enabled hw-supported-modes=gn master-configuration=\ + cfg-2ghz name-format=prefix-identity name-prefix=2ghz +add action=create-dynamic-enabled hw-supported-modes=ac master-configuration=\ + cfg-5ghz-ac name-format=prefix-identity name-prefix=5ghz-ac +add action=create-dynamic-enabled hw-supported-modes=an master-configuration=\ + cfg-5ghz-an name-format=prefix-identity name-prefix=5ghz-an +/certificate settings +set builtin-trust-store="ipsec,wpa-eap,capsman,fetch,sstp,ovpn,radius,userman,\ + openflow,tr069,dot1x,www,api,reverse-proxy" crl-download=yes crl-store=\ + system crl-use=yes +/interface bridge port +add bridge=Bridge-LAN disabled=yes interface="ether1 - Unet" +add bridge=Bridge-LAN interface=ether2 +add bridge=Bridge-LAN interface=ether3 +add bridge=Bridge-LAN interface=ether4 +add bridge=Bridge-LAN interface=ether5 +add bridge=Bridge-LAN interface=wlan2 +add bridge=Bridge-LAN interface=wlan1 +/ip firewall connection tracking +set udp-timeout=10s +/ip neighbor discovery-settings +set discover-interface-list=LAN +/ip settings +set max-neighbor-entries=8192 secure-redirects=no +/ipv6 settings +set allow-fast-path=no disable-ipv6=yes disable-link-local-address=yes \ + forward=no max-neighbor-entries=8192 +/interface detect-internet +set detect-interface-list=WAN internet-interface-list=WAN lan-interface-list=\ + LAN wan-interface-list=WAN +/interface l2tp-server server +set authentication=mschap2 use-ipsec=yes +/interface list member +add interface="ether1 - Unet" list=WAN +add interface=Bridge-LAN list=LAN +/interface ovpn-server server +add auth=sha1,md5 mac-address=FE:82:A5:78:8E:84 name=ovpn-server1 +/interface wifi configuration +add channel=2G-AX datapath=xs-DataPath disabled=no mode=ap name=2G-AX \ + security=sec2g security.ft=yes .ft-over-ds=yes ssid=vados +add channel=2G-N datapath=xs-DataPath disabled=no mode=ap name=2G-N security=\ + sec2g security.ft=yes .ft-over-ds=yes ssid=vados +add channel=5G-AC datapath=xs-DataPath disabled=no mode=ap name=5G-AC \ + security=sec5G security.authentication-types="" .ft=yes .ft-over-ds=yes \ + ssid=vados +add channel=2G-G datapath=xs-DataPath disabled=no mode=ap name=2G-G security=\ + sec2g security.authentication-types="" .ft=yes .ft-over-ds=yes ssid=vados +/interface wifi datapath +add bridge=Bridge-LAN disabled=no interface-list=all name=xs-DataPath +/interface wireguard peers +add allowed-address=0.0.0.0/0,::/0 client-allowed-address=0.0.0.0/0,::/0 \ + endpoint-address=89.110.101.17 endpoint-port=29185 interface=WG name=\ + MikroVados persistent-keepalive=20m public-key=\ + "64Y25EUZQQt8EIeAJYD8qWt+te8qvGEepnswdBgmzlY=" +/interface wireless cap +set bridge=Bridge-LAN caps-man-addresses=10.30.30.10 \ + caps-man-certificate-common-names=CAPsMAN-51B25E507D07 certificate=\ + CAP-488F5A8E1ABC discovery-interfaces=ether2 interfaces=wlan1,wlan2 \ + lock-to-caps-man=yes +/ip address +add address=10.30.30.81/24 interface=Bridge-LAN network=10.30.30.0 +add address=10.8.0.2/24 interface=WG network=10.8.0.0 +/ip dhcp-client +add add-default-route=special-classless default-route-distance=2 \ + default-route-tables=main dhcp-options=clientid,clientid_duid interface=\ + "ether1 - Unet" name=client1 use-peer-dns=no use-peer-ntp=no +/ip dhcp-server +add add-arp=yes address-pool=dhcp always-broadcast=yes bootp-support=none \ + dhcp-option-set=domain-search-set interface=Bridge-LAN lease-time=10m \ + name=masterDHCP server-address=10.30.30.81 +/ip dhcp-server config +set accounting=no +/ip dhcp-server lease +add address=10.30.30.101 client-id=1:48:8f:5a:8e:ee:a8 mac-address=\ + 48:8F:5A:8E:EE:A8 server=masterDHCP +add address=10.30.30.107 client-id=1:f0:de:f1:91:d:1e mac-address=\ + F0:DE:F1:91:0D:1E server=masterDHCP +add address=10.30.30.83 client-id=1:0:80:77:ec:43:86 mac-address=\ + 00:80:77:EC:43:86 server=masterDHCP +add address=10.30.30.70 dhcp-option=domain-search-list,HostName \ + dhcp-option-set=HP1505n mac-address=00:1E:0B:1A:88:8D server=masterDHCP +add address=10.30.30.50 client-id=1:4:7c:16:36:f5:37 mac-address=\ + 04:7C:16:36:F5:37 server=masterDHCP +add address=10.30.30.71 client-id=1:10:2d:41:2c:20:c2 mac-address=\ + 10:2D:41:2C:20:C2 server=masterDHCP +add address=10.30.30.61 client-id=1:10:8:c1:81:59:5f mac-address=\ + 10:08:C1:81:59:5F server=masterDHCP +add address=10.30.30.72 client-id=1:10:38:1f:d2:5f:13 mac-address=\ + 10:38:1F:D2:5F:13 server=masterDHCP +add address=10.30.30.99 client-id=1:10:b1:df:e9:d0:d5 mac-address=\ + 10:B1:DF:E9:D0:D5 server=masterDHCP +add address=10.30.30.111 client-id=1:fe:2:52:be:3f:16 mac-address=\ + FE:02:52:BE:3F:16 server=masterDHCP +add address=10.30.30.92 client-id=1:d4:6d:6d:fd:e5:49 mac-address=\ + D4:6D:6D:FD:E5:49 server=masterDHCP +add address=10.30.30.93 client-id=1:7e:8b:1e:cb:b8:cb mac-address=\ + CC:42:10:12:46:94 server=masterDHCP +add address=10.30.30.94 client-id=1:50:cc:f8:85:96:a mac-address=\ + 50:CC:F8:85:96:0A server=masterDHCP +add address=10.30.30.82 client-id=1:e4:18:6b:58:34:ab mac-address=\ + E4:18:6B:58:34:AB server=masterDHCP +add address=10.30.30.75 client-id=1:0:27:15:41:97:a9 mac-address=\ + 00:27:15:41:97:A9 server=masterDHCP +add address=10.30.30.77 dhcp-option=HostName dhcp-option-set=StartLife1 \ + mac-address=C4:82:E1:03:49:10 server=masterDHCP +add address=10.30.30.73 client-id=1:10:38:1f:82:81:f2 mac-address=\ + 10:38:1F:82:81:F2 server=masterDHCP +add address=10.30.30.95 client-id=1:88:ae:dd:60:39:54 dhcp-option=HostName \ + dhcp-option-set=VADOS-NUC mac-address=88:AE:DD:60:39:54 server=masterDHCP +add address=10.30.30.98 client-id=1:c8:5b:76:d8:cc:bf dhcp-option=HostName \ + dhcp-option-set=VADOS-LEN mac-address=C8:5B:76:D8:CC:BF server=masterDHCP +add address=10.30.30.96 client-id=iPhone mac-address=4A:91:ED:0E:1F:39 \ + server=masterDHCP +add address=10.30.30.74 client-id=MiTV dhcp-option=HostName dhcp-option-set=\ + MiTV mac-address=20:72:A9:D3:34:36 server=masterDHCP +add address=10.30.30.30 dhcp-option=HostName dhcp-option-set=miller \ + mac-address=F0:75:5D:1E:5F:71 server=masterDHCP +add address=10.30.30.100 client-id=iVados dhcp-option=HostName \ + dhcp-option-set="=\"Client ID\"" mac-address=DE:4D:72:F3:1A:9F server=\ + masterDHCP +/ip dhcp-server network +add address=10.30.30.0/24 caps-manager=10.30.30.10 dhcp-option=\ + domain-search-list dhcp-option-set=domain-search-set dns-server=\ + 10.30.30.81 domain=WORKGROUP gateway=10.30.30.81 netmask=24 ntp-server=\ + 10.30.30.81,10.30.30.10 wins-server=10.30.30.95,10.30.30.98 +/ip dns +set allow-remote-requests=yes cache-max-ttl=1d doh-max-concurrent-queries=100 \ + doh-max-server-connections=20 servers=8.8.4.4,8.8.8.8 +/ip dns static +add address=8.8.4.4 comment="Google-dns IPv4 2" name=dns.google type=A +add address=8.8.8.8 comment="Google-dns IPv4 1" name=dns.google type=A +add address=10.30.30.33 comment=AMSTER name=amster.vados.ru type=A +add address=10.30.30.33 name=ros.vados.ru type=A +add address=10.30.30.95 name=vados-nuc type=A +add address=10.30.30.33 name=amster-nuc type=A +add address=10.30.30.33 name=amster type=A +add address=10.30.30.33 name=amster-reg type=A +add address=10.30.30.33 name=mng.vados.ru type=A +add address=10.30.30.33 name=mgr.vados.ru type=A +add address=10.30.30.33 name=prt.vados.ru type=A +add address=10.30.30.33 name=reg.vados.ru type=A +add address=10.30.30.33 match-subdomain=yes name=mikrots.vados.ru type=A +add address=10.30.30.33 name=oxidized.vados.ru type=A +add address=10.30.30.30 comment=MILLER name=miller.vados.ru type=A +add address=10.30.30.30 name=MILLER-LEN type=A +add address=10.30.30.30 name=miller type=A +add address=1.0.0.1 comment="CloudFlare-doh IPv4 2" disabled=yes name=\ + security.cloudflare-dns.com type=A +add address=1.1.1.1 comment="CloudFlare-doh IPv4 1" disabled=yes name=\ + security.cloudflare-dns.com type=A +add address=149.112.112.112 comment="Cuad9-dns IPv4 2" disabled=yes name=\ + dns.quad9.net type=A +add address=9.9.9.9 comment="Cuad9-dns IPv4 1" disabled=yes name=\ + dns.quad9.net type=A +add address=91.192.189.2 comment=Unet-DNS disabled=yes name=ns1.unet.ws type=\ + A +add address=10.30.30.81 comment=LocalNet name=MikroVados type=A +add address=10.30.30.10 name=MikroNUC type=A +add address=10.30.30.86 name=MikroYellow type=A +add address=10.30.30.85 name=MikroMic type=A +add address=10.30.30.95 name=VADOS-NUC type=A +add address=10.30.30.98 name=VADOS-LEN type=A +add address=10.30.30.20 name=garage type=A +add address=91.192.189.2 comment=Unet-DNS disabled=yes name=ns1.unet.ws type=\ + A +/ip firewall address-list +add address=91.215.120.206 list=TRUSTED +add address=185.71.70.78 disabled=yes list=TRUSTED +add address=176.53.203.171 disabled=yes list=TRUSTED +add address=176.53.203.170 disabled=yes list=TRUSTED +add address=176.53.202.194 disabled=yes list=TRUSTED +add address=10.30.30.100-255 list=KIDS +add address=8.8.4.0/24 list=YouTube +add address=8.8.8.0/24 list=YouTube +add address=8.34.208.0/20 list=YouTube +add address=8.35.192.0/20 list=YouTube +add address=23.236.48.0/20 list=YouTube +add address=23.251.128.0/19 list=YouTube +add address=34.0.0.0/15 list=YouTube +add address=34.2.0.0/16 list=YouTube +add address=34.3.0.0/23 list=YouTube +add address=34.3.3.0/24 list=YouTube +add address=34.3.4.0/24 list=YouTube +add address=34.3.8.0/21 list=YouTube +add address=34.3.16.0/20 list=YouTube +add address=34.3.32.0/19 list=YouTube +add address=34.3.64.0/18 list=YouTube +add address=34.4.0.0/14 list=YouTube +add address=34.8.0.0/13 list=YouTube +add address=34.16.0.0/12 list=YouTube +add address=34.32.0.0/11 list=YouTube +add address=34.64.0.0/10 list=YouTube +add address=34.128.0.0/10 list=YouTube +add address=35.184.0.0/13 list=YouTube +add address=35.192.0.0/14 list=YouTube +add address=35.196.0.0/15 list=YouTube +add address=35.198.0.0/16 list=YouTube +add address=35.199.0.0/17 list=YouTube +add address=35.199.128.0/18 list=YouTube +add address=35.200.0.0/13 list=YouTube +add address=35.208.0.0/12 list=YouTube +add address=35.224.0.0/12 list=YouTube +add address=35.240.0.0/13 list=YouTube +add address=57.140.192.0/18 list=YouTube +add address=64.15.112.0/20 list=YouTube +add address=64.233.160.0/19 list=YouTube +add address=66.22.228.0/23 list=YouTube +add address=66.102.0.0/20 list=YouTube +add address=66.249.64.0/19 list=YouTube +add address=70.32.128.0/19 list=YouTube +add address=72.14.192.0/18 list=YouTube +add address=74.125.0.0/16 list=YouTube +add address=104.154.0.0/15 list=YouTube +add address=104.196.0.0/14 list=YouTube +add address=104.237.160.0/19 list=YouTube +add address=107.167.160.0/19 list=YouTube +add address=107.178.192.0/18 list=YouTube +add address=108.59.80.0/20 list=YouTube +add address=108.170.192.0/18 list=YouTube +add address=108.177.0.0/17 list=YouTube +add address=130.211.0.0/16 list=YouTube +add address=136.22.160.0/20 list=YouTube +add address=136.22.176.0/21 list=YouTube +add address=136.22.184.0/23 list=YouTube +add address=136.22.186.0/24 list=YouTube +add address=142.250.0.0/15 list=YouTube +add address=146.148.0.0/17 list=YouTube +add address=152.65.208.0/22 list=YouTube +add address=152.65.214.0/23 list=YouTube +add address=152.65.218.0/23 list=YouTube +add address=152.65.222.0/23 list=YouTube +add address=152.65.224.0/19 list=YouTube +add address=162.120.128.0/17 list=YouTube +add address=162.216.148.0/22 list=YouTube +add address=162.222.176.0/21 list=YouTube +add address=172.110.32.0/21 list=YouTube +add address=172.217.0.0/16 list=YouTube +add address=172.253.0.0/16 list=YouTube +add address=173.194.0.0/16 list=YouTube +add address=173.255.112.0/20 list=YouTube +add address=192.158.28.0/22 list=YouTube +add address=192.178.0.0/15 list=YouTube +add address=193.186.4.0/24 list=YouTube +add address=199.36.154.0/23 list=YouTube +add address=199.36.156.0/24 list=YouTube +add address=199.192.112.0/22 list=YouTube +add address=199.223.232.0/21 list=YouTube +add address=207.223.160.0/20 list=YouTube +add address=208.65.152.0/22 list=YouTube +add address=208.68.108.0/22 list=YouTube +add address=208.81.188.0/22 list=YouTube +add address=208.117.224.0/19 list=YouTube +add address=209.85.128.0/17 list=YouTube +add address=216.58.192.0/19 list=YouTube +add address=216.73.80.0/20 list=YouTube +add address=216.239.32.0/19 list=YouTube +add address=2ip.ru list=Test +add address=157.240.247.174 list=Instagram +add address=46.53.178.107 list=Instagram +add address=179.60.195.174 list=Instagram +add address=157.240.205.174 list=Instagram +add address=31.13.24.0/21 list=Instagram +add address=31.13.64.0/18 list=Instagram +add address=45.64.40.0/22 list=Instagram +add address=66.220.144.0/20 list=Instagram +add address=69.63.176.0/20 list=Instagram +add address=69.171.224.0/19 list=Instagram +add address=74.119.76.0/22 list=Instagram +add address=103.4.96.0/22 list=Instagram +add address=129.134.0.0/16 list=Instagram +add address=157.240.0.0/16 list=Instagram +add address=173.252.64.0/18 list=Instagram +add address=179.60.192.0/22 list=Instagram +add address=185.60.216.0/22 list=Instagram +add address=204.15.20.0/22 list=Instagram +add address=157.240.200.63 list=Instagram +add address=185.60.219.63 list=Instagram +add address=129.134.31.12 list=Instagram +add address=66.81.203.132 list=Instagram +add address=185.89.218.12 list=Instagram +add address=31.13.66.63 list=Instagram +add address=84.15.65.162 list=Instagram +add address=68.66.224.28 list=Instagram +add address=157.240.253.63 list=Instagram +add address=83.174.11.224 list=Instagram +add address=157.240.9.52 list=Instagram +add address=157.240.252.174 list=Instagram +add address=157.240.195.63 list=Instagram +add address=31.13.71.52 list=Instagram +add address=57.144.110.192 list=Instagram +add address=157.240.252.17 list=Instagram +add address=84.15.66.97 list=Instagram +add address=217.168.6.33 list=Instagram +add address=31.13.83.52 list=Instagram +add address=157.240.241.63 list=Instagram +add address=129.134.30.12 list=Instagram +add address=185.89.219.12 list=Instagram +add address=157.240.252.10 list=Instagram +add address=157.240.201.63 list=Instagram +add address=66.81.203.197 list=Instagram +add address=179.60.195.52 list=Instagram +add address=66.81.203.7 list=Instagram +add address=216.40.34.41 list=Instagram +add address=157.240.202.63 list=Instagram +add address=157.240.229.63 list=Instagram +add address=157.240.252.63 list=Instagram +add address=31.13.72.53 list=Instagram +add address=124.108.16.224 list=Instagram +add address=157.240.205.63 list=Instagram +add address=92.46.37.96 list=Instagram +add address=157.240.247.63 list=Instagram +add address=157.240.234.63 list=Instagram +add address=157.240.235.63 list=Instagram +add address=87.245.208.97 list=Instagram +add address=216.58.192.0/19 list=Instagram +add address=209.85.128.0/17 list=Instagram +add address=198.105.240.0/20 list=Instagram +add address=173.194.0.0/16 list=Instagram +add address=172.217.0.0/16 list=Instagram +add address=142.250.0.0/15 list=Instagram +add address=108.177.0.0/17 list=Instagram +add address=87.245.197.140 list=Instagram +add address=74.125.0.0/16 list=Instagram +add address=64.233.160.0/19 list=Instagram +add address=157.240.0.1 list=Instagram +add address=157.240.238.63 list=Instagram +add address=157.240.238.174 list=Instagram +add address=157.240.0.63 list=Instagram +add address=157.240.224.63 list=Instagram +add address=157.240.224.174 list=Instagram +add address=157.240.251.36 list=Instagram +add address=157.240.253.12 list=Instagram +add address=157.240.253.35 list=Instagram +add address=157.240.238.13 list=Instagram +add address=157.240.238.56 list=Instagram +add address=157.240.238.175 list=Instagram +add address=57.144.112.141 list=Instagram +add address=157.240.251.60 list=Instagram +add address=157.240.251.128 list=Instagram +add address=157.240.238.5 list=Instagram +add address=157.240.253.13 list=Instagram +add address=157.240.253.5 list=Instagram +add address=157.240.238.2 list=Instagram +add address=157.240.238.37 list=Instagram +add address=157.240.251.5 list=Instagram +add address=157.240.251.34 list=Instagram +add address=57.144.112.1 list=Instagram +add address=157.240.238.54 list=Instagram +add address=129.134.26.123 list=Instagram +add address=157.240.252.3 list=Instagram +add address=31.13.84.4 list=Instagram +add address=157.240.224.12 list=Instagram +add address=157.240.238.4 list=Instagram +add address=157.240.0.13 list=Instagram +add address=3.33.139.32 list=Instagram +add address=157.240.0.35 list=Instagram +add address=157.240.238.14 list=Instagram +add address=157.240.238.60 list=Instagram +add address=57.144.112.145 list=Instagram +add address=157.240.251.35 list=Instagram +add address=151.101.84.159 list=Twitter +add address=pbs.twimg.com list=Twitter +add address=89.110.101.17 comment=VDSIna list=TRUSTED +add address=10.8.0.0/24 comment="WG VDSIna" list=TRUSTED +add address=ikus.pesc.ru comment=ikus.pesc.ru list=NoVdsina +add address=love.ru comment=love.ru list=NoVdsina +add address=gosuslugi.ru comment=gosuslugi.ru list=NoVdsina +add address=pochta.ru comment=pochta.ru list=NoVdsina +add address=vdsina.com list=NoVdsina +add address=vdsina.ru list=NoVdsina +add address=youla.ru list=NoVdsina +add address=kupiprodai.ru list=NoVdsina +add address=myip.ru list=Test +add address=geoip.co list=NoVdsina +add address=x.com list=Twitter +add address=facebook.com list=facebook +add address=fbcd.net list=facebook +add address=comp-lenta.ru list=NoVdsina +add address=128.85.102.70 comment=update.microsoft.com list=\ + windowsupdateslist +add address=wu-b-net.trafficmanager.net. comment=\ + ctldl.windowsupdate.com.delivery.microsoft.com list=windowsupdateslist +add address=ctldl.windowsupdate.com.delivery.microsoft.com. comment=\ + ctldl.windowsupdate.com list=windowsupdateslist +add address=redir.update.msft.com.trafficmanager.net. comment=\ + update.microsoft.com list=windowsupdateslist +add address=geo.prod.do.dsp.trafficmanager.net. comment=\ + geo.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=13.74.139.29 comment=array605.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=kv801.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + kv801.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=e12437.d.akamaiedge.net. comment=\ + kv801.prod.do.dsp.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=displaycatalog-rp.md.mp.microsoft.com.akadns.net. comment=\ + displaycatalog.mp.microsoft.com list=windowsupdateslist +add address=rp-consumer-prod-displaycatalog-geomap.trafficmanager.net. \ + comment=displaycatalog-rp.md.mp.microsoft.com.akadns.net list=\ + windowsupdateslist +add address=sls.update.microsoft.com. comment=slscr.update.microsoft.com \ + list=windowsupdateslist +add address=glb.sls.prod.dcat.dsp.trafficmanager.net. comment=\ + sls.update.microsoft.com list=windowsupdateslist +add address=fe3.delivery.mp.microsoft.com. comment=\ + fe3cr.delivery.mp.microsoft.com list=windowsupdateslist +add address=glb.cws.prod.dcat.dsp.trafficmanager.net. comment=\ + fe3.delivery.mp.microsoft.com list=windowsupdateslist +add address=fe2cr.update.msft.com.trafficmanager.net. comment=\ + fe2cr.update.microsoft.com list=windowsupdateslist +add address=download.windowsupdate.com.delivery.microsoft.com. comment=\ + download.windowsupdate.com list=windowsupdateslist +add address=wu-f-net.trafficmanager.net. comment=\ + download.windowsupdate.com.delivery.microsoft.com list=windowsupdateslist +add address=tsfe.trafficmanager.net. comment=\ + tsfe.trafficshaping.dsp.mp.microsoft.com list=windowsupdateslist +add address=edge.ds-c7110-microsoft.global.dns.qwilted-cds.cqloud.com. \ + comment=9.au.download.windowsupdate.com list=windowsupdateslist +add address=52.158.227.125 comment=array812.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=au.download.windowsupdate.com.delivery.microsoft.com. comment=\ + au.download.windowsupdate.com list=windowsupdateslist +add address=a767.dspw65.akamai.net. comment=\ + download.windowsupdate.com.edgesuite.net list=windowsupdateslist +add address=52.151.58.88 comment=array810.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=consumer-licensing-aks2aks.md.mp.microsoft.com.akadns.net. \ + comment=licensing.mp.microsoft.com list=windowsupdateslist +add address=licensing-prod-frontdoor-geomap.trafficmanager.net. comment=\ + consumer-licensing-aks2aks.md.mp.microsoft.com.akadns.net list=\ + windowsupdateslist +add address=star.f.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.f.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=cdp-f-nlu-net.trafficmanager.net. comment=\ + star.f.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=star.b.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.b.tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=cdp-f-tlu-net.trafficmanager.net. comment=\ + star.b.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=storeedgefd.xbetservices.akadns.net. comment=\ + storeedgefd.dsx.mp.microsoft.com list=windowsupdateslist +add address=\ + storeedgefd.dsx.mp.microsoft.com.edgekey.net.globalredir.akadns.net. \ + comment=storeedgefd.dsx.mp.microsoft.com.edgekey.net list=\ + windowsupdateslist +add address=e16646.dscg.akamaiedge.net. comment=\ + storeedgefd.dsx.mp.microsoft.com.edgekey.net.globalredir.akadns.net list=\ + windowsupdateslist +add address=40.69.76.189 comment=array621.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=bg.microsoft.map.fastly.net. comment=\ + 3.au.download.windowsupdate.com list=windowsupdateslist +add list=windowsupdateslist +add address=40.69.75.33 comment=array613.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=star.sf.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedgeextensions.sf.tlu.dl.delivery.mp.microsoft.com list=\ + windowsupdateslist +add address=cdp-f-ssl-tlu-net.trafficmanager.net. comment=\ + star.sf.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=a2033.dscd.akamai.net. comment=\ + star.sb.tlu.dl.delivery.mp.microsoft.com.edgesuite.net list=\ + windowsupdateslist +add address=13.74.138.242 comment=array602.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=dl.delivery.mp.microsoft.com.delivery.microsoft.com. comment=\ + dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=dcat-f-nlu-net.trafficmanager.net. comment=\ + dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=1d.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=1D.tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=dcat-b-tlu-net.trafficmanager.net. comment=\ + 1d.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=a122.dscg3.akamai.net. comment=\ + tlu.dl.delivery.mp.microsoft.com.edgesuite.net list=windowsupdateslist +add address=geover.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + geover.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=e10370.d.akamaiedge.net. comment=\ + geover.prod.do.dsp.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=52.232.182.21 comment=array511.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.70.77.95 comment=array519.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=a1683.dscd.akamai.net. comment=\ + dl.delivery.mp.microsoft.com-c.edgesuite.net list=windowsupdateslist +add address=consumer-collections-aks2eap.md.mp.microsoft.com.akadns.net. \ + comment=collections.mp.microsoft.com list=windowsupdateslist +add address=a1847.dscd.akamai.net. comment=\ + wildcard.f.tlu.dl.delivery.mp.microsoft.com.edgesuite.net list=\ + windowsupdateslist +add address=13.74.142.6 comment=array607.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=au.download.windowsupdate.com.edgesuite.net. comment=\ + 2.au.download.windowsupdate.com list=windowsupdateslist +add address=a767.dscg3.akamai.net. comment=\ + au.download.windowsupdate.com.edgesuite.net list=windowsupdateslist +add address=52.156.123.84 comment=array818.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.78.254 comment=array610.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=4.au.download.windowsupdate.com.delivery.microsoft.com. comment=\ + 4.au.download.windowsupdate.com list=windowsupdateslist +add address=cl-glcb907925.gcdn.co. comment=\ + 4.au.download.windowsupdate.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=52.167.167.111 comment=array510.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=40.69.70.43 comment=array623.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=tsfe.trafficshaping.dsp.mp.microsoft.com.delivery.microsoft.com. \ + comment=tsfe.trafficshaping.dsp.mp.microsoft.com list=windowsupdateslist +add address=ts-frontend.trafficmanager.net. comment=\ + tsfe.trafficshaping.dsp.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=40.69.75.248 comment=array616.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.74.84 comment=array615.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=sds.trafficmanager.net. comment=software-download.microsoft.com \ + list=windowsupdateslist +add address=40.69.74.80 comment=array611.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.175.242.182 comment=array804.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=dlc-shim.trafficmanager.net. comment=download.microsoft.com list=\ + windowsupdateslist +add address=e12671.dscd.akamaiedge.net. comment=\ + download.microsoft.com.edgekey.net list=windowsupdateslist +add address=20.187.55.34 comment=array808.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.167.231 comment=array513.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=52.167.222.13 comment=array518.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=kv601.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + kv601.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=e12358.d.akamaiedge.net. comment=\ + kv601.prod.do.dsp.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. comment=\ + tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=dcat-f-tlu-net.trafficmanager.net. comment=\ + tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=a1856.dspw65.akamai.net. comment=\ + tlu.dl.delivery.mp.microsoft.com-c.edgesuite.net list=windowsupdateslist +add address=52.167.164.252 comment=array506.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=13.74.137.54 comment=array601.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=kv501.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + kv501.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=collections-prod-frontdoor-geomap.trafficmanager.net. comment=\ + consumer-collections-aks2eap.md.mp.microsoft.com.akadns.net list=\ + windowsupdateslist +add address=52.167.160.173 comment=array509.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=40.70.77.148 comment=array516.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.200.126 comment=array507.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=52.167.167.59 comment=array508.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.76.172 comment=array620.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=82.202.162.184 comment=comp-lenta.ru list=NoWG +add address=smtp.mail.me.com.akadns.net. comment=smtp.mail.me.com list=NoWG +add address=17.57.155.37 comment=smtp.mail.me.com.akadns.net list=NoWG +add address=smtp.mail.me.com comment=smtp.mail.me.com list=NoVdsina +add address=40.70.76.5 comment=array514.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.186.119 comment=array618.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.177.176.186 comment=array520.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=40.70.76.27 comment=array515.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.160.43 comment=array503.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.110 comment=array817.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.142.8 comment=array614.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.138.254 comment=array603.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.167.96 comment=array501.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.76.215 comment=array622.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.143.200 comment=array606.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.111 comment=array818.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.112 comment=array819.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.137.53 comment=array608.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.98 comment=array805.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.96 comment=array803.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.104 comment=array811.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.101 comment=array808.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.99 comment=array806.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.17 comment=array802.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.97 comment=array804.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.103 comment=array810.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.16 comment=array801.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.70.77.177 comment=array517.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.164.84 comment=array512.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.105 comment=array812.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.107 comment=array814.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.232.161.82 comment=array502.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.108 comment=array815.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.161.91 comment=array505.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.102 comment=array809.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.109 comment=array816.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.106 comment=array813.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.117 comment=array622.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.107 comment=array612.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.108 comment=array613.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.105 comment=array610.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.113 comment=array618.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.116 comment=array621.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.98 comment=array603.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.114 comment=array619.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.111 comment=array616.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.97 comment=array602.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.106 comment=array611.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.110 comment=array615.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.119 comment=array624.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.135 comment=array514.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.97 comment=array503.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.99 comment=array604.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.61 comment=array504.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.131 comment=array510.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.132 comment=array511.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.96 comment=array601.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.104 comment=array609.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.138 comment=array517.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.60 comment=array501.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.139 comment=array518.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.118 comment=array623.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.113 comment=array820.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.103 comment=array608.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.100 comment=array807.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.129 comment=array508.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.134 comment=array513.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.62 comment=array505.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.137 comment=array516.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.101 comment=array606.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.96 comment=array502.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.130 comment=array509.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.112 comment=array617.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.100 comment=array605.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.115 comment=array620.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.136 comment=array515.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=purchase.md.mp.microsoft.com.akadns.net. comment=\ + purchase.mp.microsoft.com list=windowsupdateslist +add address=e110219.a.akamaiedge.net. comment=\ + purchase.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=72.153.5.140 comment=array519.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.141 list=windowsupdateslist +add address=72.153.5.63 comment=array506.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.128 comment=array507.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.102 comment=array607.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=storesdk.xbetservices.akadns.net. comment=\ + storesdk.dsx.mp.microsoft.com list=windowsupdateslist +add address=e16646.g.akamaiedge.net. comment=\ + storesdk.dsx.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=software-download.microsoft.com.delivery.microsoft.com. comment=\ + software-download.microsoft.com list=windowsupdateslist +add address=download.prss.microsoft.com.akamaized.net. comment=\ + software-download.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.109 comment=array614.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.133 comment=array512.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=213.180.192.0/19 comment=YandexDisk list=NoVdsina +add address=87.250.250.50 comment=YandexDisk list=NoVdsina +add address=consumer-prod-bcfd-v7-afd.trafficmanager.net. comment=\ + displaycatalog.mp.microsoft.com list=windowsupdateslist +add address=purchase-europeeap.md.mp.microsoft.com.akadns.net. comment=\ + purchase.md.mp.microsoft.com.akadns.net list=windowsupdateslist +add address=ne-az-conspurchase-mp.trafficmanager.net. comment=\ + purchase-europeeap.md.mp.microsoft.com.akadns.net list=windowsupdateslist +add address=storeedgefd.dsx.mp.microsoft.com.edgekey.net. comment=\ + cdn.storeedgefd.dsx.mp.microsoft.com list=windowsupdateslist +add address=star.f.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.f.tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=a1996.dscd.akamai.net. comment=\ + wildcard.f.dl.delivery.mp.microsoft.com.edgesuite.net list=\ + windowsupdateslist +add address=cp801.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + cp801.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=glb.tas02.sls-prod.dcat.dsp.mp.microsoft.com. comment=\ + tas02.sls.update.microsoft.com list=windowsupdateslist +add address=cp601.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + cp601.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=star.sb.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedgeextensions.sb.tlu.dl.delivery.mp.microsoft.com list=\ + windowsupdateslist +add address=star.sf.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.sf.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=cdp-f-ssl-nlu-net.trafficmanager.net. comment=\ + star.sf.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=tm-pifd-prod-gbl-weight.trafficmanager.net. comment=\ + paymentinstruments.mp.microsoft.com list=windowsupdateslist +add address=10.30.30.33 comment=NUC disabled=yes list=NoWG +add address=10.30.30.10 comment=MikroNUC disabled=yes list=NoWG +add address=89.110.101.17 comment=!!!VDSINA!!!! list=NoWG +add address=wg.vados.ru comment=VDSina-vpn list=Trusted-VPN +add address=80.85.244.9 list=TRUSTED +add address=disc801.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + disc801.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=185.71.70.78 disabled=yes list=TRUSTED +add address=176.53.203.171 disabled=yes list=TRUSTED +add address=176.53.203.170 disabled=yes list=TRUSTED +add address=176.53.202.194 disabled=yes list=TRUSTED +add address=89.110.101.17 comment="!!!VDSina Server!!!" disabled=yes list=\ + NoVdsina +add address=dns.quad9.net comment=Quad9-dns disabled=yes list=Trusted-DNS +add address=dns.google comment=Google-dns list=Trusted-DNS +add address=security.cloudflare-dns.com comment=CloudFlare-dns list=\ + Trusted-DNS +add address=time.google.com comment=Google-time list=Trusted-NTP +add address=0.ru.pool.ntp.org comment=ru.pool.ntp.org disabled=yes list=\ + Trusted-NTP +add address=1.ru.pool.ntp.org disabled=yes list=Trusted-NTP +add address=2.ru.pool.ntp.org comment=2.ru.pool.ntp.org disabled=yes list=\ + Trusted-NTP +add address=3.ru.pool.ntp.org comment=3.ru.pool.ntp.org disabled=yes list=\ + Trusted-NTP +add address=cp.vdsina.com comment=VDSina-vpn list=Trusted-VPN +add address=vdsina.ru comment=VDSina-vpn list=Trusted-VPN +add address=ns.vados.ru comment=VDSina-vpn list=Trusted-VPN +add address=vdsina.com comment=VDSina-vpn list=Trusted-VPN +add address=cp.vdsina.ru comment=VDSina-vpn list=Trusted-VPN +add address=ns1.vdsina.ru comment=VDSina-vpn list=Trusted-VPN +add address=ghcr.io comment=GitHub list=Trusted-VPN +add address=github.com comment=GitHub list=Trusted-VPN +add address=149.154.164.13 comment=telegra.ph list=FuckRKN +add address=194.85.61.76 comment=grani.ru list=FuckRKN +add address=109.70.26.37 comment=grani.ru list=FuckRKN +add address=104.16.3.81 comment=xhamster.com list=FuckRKN +add address=104.16.4.81 comment=xhamster.com list=FuckRKN +add address=188.114.97.1 comment=lostfilm.tv list=FuckRKN +add address=188.114.96.1 comment=lostfilm.tv list=FuckRKN +add address=172.67.182.196 comment=rutracker.org list=FuckRKN +add address=104.21.32.39 comment=rutracker.org list=FuckRKN +add address=104.247.81.99 comment=lurkmore.to list=FuckRKN +add address=8.6.112.6 comment=dou.ua list=FuckRKN +add address=8.47.69.6 comment=dou.ua list=FuckRKN +add address=66.254.114.79 comment=youporn.com list=FuckRKN +add address=185.110.92.40 comment=pornolab.net list=FuckRKN +add address=185.110.92.41 comment=pornolab.net list=FuckRKN +add address=172.67.172.95 comment=crimerussia.com list=FuckRKN +add address=104.21.71.238 comment=crimerussia.com list=FuckRKN +add address=149.154.167.99 comment=telegram.org list=FuckRKN +add address=149.154.166.110 comment=api.telegram.org list=FuckRKN +/ip firewall filter +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=12h chain=input comment="block honeypot DNS" \ + connection-state=new dst-port=53 in-interface-list=WAN protocol=udp \ + src-address=!10.30.30.0/24 src-address-list=!Trusted-DNS +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input connection-state=new dst-port=53 \ + in-interface-list=WAN protocol=tcp src-address=!10.30.30.0/24 \ + src-address-list=!Trusted-DNS +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input comment=\ + "block honeypot ssh rdp winbox" connection-state=new dst-port=\ + 22,8291,2222 in-interface-list=WAN protocol=tcp src-address-list=!TRUSTED +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input comment="block honeypot asterisk" \ + connection-state=new dst-port=5060 in-interface-list=WAN protocol=udp \ + src-address-list=!TRUSTED +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=5d chain=input comment="block honeypot NTP" \ + connection-state=new dst-port=123 in-interface-list=WAN protocol=udp \ + src-address=!10.30.30.0/24 src-address-list=!Trusted-NTP +add action=fasttrack-connection chain=forward comment=\ + "FastTrack for non-VPN connections" connection-mark=!VPN_No_FastTrack \ + connection-state=established,related,new disabled=yes +add action=accept chain=output comment="Accept Rule for Trusted-NTP Servers" \ + dst-address-list=Trusted-NTP dst-port=123 out-interface-list=WAN \ + protocol=udp +add action=accept chain=input comment=\ + "accept NTP clients on local area network" disabled=yes dst-port=123 \ + in-interface-list=LAN protocol=udp src-address=10.30.30.0/24 +add action=accept chain=output comment="accept WireGuard" disabled=yes \ + dst-address-list=VPN-Server dst-port=13231 out-interface="ether1 - Unet" \ + protocol=udp +add action=accept chain=output disabled=yes dst-address-list=VPN-Server \ + dst-port=29185 out-interface="ether1 - Unet" protocol=udp +add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \ + connection-state=established,related,new disabled=yes routing-mark=\ + !To-VPN +add action=accept chain=input disabled=yes dst-port=443 in-interface=\ + "ether1 - Unet" protocol=tcp +add action=accept chain=output disabled=yes protocol=tcp src-port=443 +add action=accept chain=input comment=\ + "defconf: accept established,related,untracked" connection-state=\ + established,related,untracked +add action=drop chain=input comment="defconf: drop invalid" connection-state=\ + invalid +add action=accept chain=input comment="defconf: accept ICMP" disabled=yes \ + protocol=icmp +add action=accept chain=input comment=\ + "defconf: accept to local loopback (for CAPsMAN)" disabled=yes \ + dst-address=127.0.0.1 +add action=accept chain=output disabled=yes src-address=127.0.0.1 +add action=accept chain=forward comment="defconf: accept in ipsec policy" \ + ipsec-policy=in,ipsec +add action=accept chain=forward comment="defconf: accept out ipsec policy" \ + ipsec-policy=out,ipsec +add action=accept chain=forward comment=\ + "defconf: accept established,related, untracked" connection-state=\ + established,related,untracked +add action=drop chain=forward comment="defconf: drop invalid" \ + connection-state=invalid +add action=drop chain=forward comment=\ + "defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat \ + connection-state=new in-interface="ether1 - Unet" +add action=accept chain=input connection-state=established disabled=yes +add action=accept chain=input connection-state=related disabled=yes +add action=drop chain=input disabled=yes in-interface-list=!LAN +add action=drop chain=forward comment=\ + "Filter Rule to block FB address LIST : )" disabled=yes dst-address-list=\ + facebook +add action=drop chain=forward comment=\ + "Filter Rule to block YOUTUBE address LIST : )" disabled=yes \ + dst-address-list=YouTube +/ip firewall mangle +add action=mark-routing chain=prerouting comment="Test sites" disabled=yes \ + dst-address=!10.30.30.0/24 dst-address-list=Test new-routing-mark=To-VPN \ + src-address=10.30.30.0/24 +add action=mark-routing chain=prerouting comment=FuckRKN disabled=yes \ + dst-address-list=FuckRKN new-routing-mark=To-VPN passthrough=no \ + src-address=10.30.30.0/24 src-address-list=!NoWG +add action=mark-routing chain=prerouting comment=Instagram dst-address-list=\ + Instagram new-routing-mark=To-VPN src-address=10.30.30.0/24 \ + src-address-list=!NoWG +add action=mark-routing chain=prerouting comment=Twitter dst-address-list=\ + Twitter new-routing-mark=To-VPN src-address=10.30.30.0/24 \ + src-address-list=!NoWG +add action=mark-routing chain=prerouting comment=YouTube dst-address-list=\ + YouTube new-routing-mark=To-VPN src-address=10.30.30.0/24 \ + src-address-list=!NoWG +add action=mark-routing chain=prerouting comment=facebook dst-address-list=\ + facebook new-routing-mark=To-VPN src-address=10.30.30.0/24 \ + src-address-list=!NoWG +add action=mark-routing chain=prerouting comment="VDSIna for All sites" \ + dst-address=!10.30.30.0/24 log-prefix=VPN-all new-routing-mark=To-VPN \ + passthrough=no src-address=10.30.30.0/24 +add action=change-mss chain=forward comment="MSS on WG" new-mss=1380 \ + out-interface=WG passthrough=no protocol=tcp routing-mark=To-VPN \ + tcp-flags=syn tcp-mss=1381-65535 +add action=mark-connection chain=prerouting comment=\ + "Mark VPN connections to exclude from FastTrack" disabled=yes \ + in-interface=WG log-prefix=Mark-VPN-FT new-connection-mark=\ + VPN_No_FastTrack passthrough=no +add action=mark-routing chain=prerouting comment="VPN Network" dst-address=\ + 10.8.0.0/24 log-prefix=VPN-Net new-routing-mark=To-VPN passthrough=no \ + src-address=10.30.30.0/24 +/ip firewall nat +add action=redirect chain=dstnat comment=\ + "FORCE DNS TO LOCAL MIKROTIK DNS SERVER" dst-port=53 protocol=tcp \ + src-address=10.30.30.0/24 to-ports=53 +add action=redirect chain=dstnat dst-port=53 protocol=udp src-address=\ + 10.30.30.0/24 to-ports=53 +add action=masquerade chain=srcnat comment=WG dst-address-list=!NoVdsina \ + log-prefix=WG-nat out-interface=WG +add action=masquerade chain=srcnat comment="masquerade Default" ipsec-policy=\ + out,none out-interface="ether1 - Unet" routing-mark=!To-VPN +add action=dst-nat chain=dstnat comment=amster.vados.ruhttps dst-port=443 \ + in-interface="ether1 - Unet" log-prefix=2Amster protocol=tcp \ + routing-mark=!To-VPN to-addresses=10.30.30.33 to-ports=443 +add action=dst-nat chain=dstnat comment=npm dst-port=81 in-interface=\ + "ether1 - Unet" protocol=tcp routing-mark=!To-VPN to-addresses=\ + 10.30.30.33 to-ports=81 +add action=dst-nat chain=dstnat comment="amster.vados.ru For Certbot HTTP" \ + dst-port=80 in-interface="ether1 - Unet" protocol=tcp routing-mark=\ + !To-VPN to-addresses=10.30.30.33 to-ports=80 +add action=dst-nat chain=dstnat disabled=yes dst-port=22 in-interface=\ + "ether1 - Unet" protocol=tcp routing-mark=!To-VPN to-addresses=\ + 10.30.30.33 to-ports=22 +add action=dst-nat chain=dstnat comment="Yandex.DNS Family" disabled=yes \ + dst-port=53 in-interface=Bridge-LAN protocol=udp src-address-list=KIDS \ + time=6h-15m,sun,mon,tue,wed,thu,fri,sat to-addresses=77.88.8.3 +add action=dst-nat chain=dstnat disabled=yes dst-port=53 in-interface=\ + Bridge-LAN protocol=tcp src-address-list=KIDS time=\ + 6h-15m,sun,mon,tue,wed,thu,fri,sat to-addresses=77.88.8.3 +/ip firewall raw +add action=drop chain=prerouting comment="Drop Honeypot Hackers" \ + in-interface="ether1 - Unet" src-address-list="Honeypot Hacker" +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + extras.getpagespeed.com content=extras.getpagespeed.com disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=linux.duke.edu \ + content=linux.duke.edu disabled=yes +add action=accept chain=prerouting comment="Trusted DNS" disabled=yes \ + in-interface-list=WAN src-address-list=Trusted-DNS +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=vk.com \ + content=vk.com +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=ok.ru content=\ + ok.ru +add action=add-dst-to-address-list address-list=Instagram \ + address-list-timeout=none-dynamic chain=prerouting comment=Instagram \ + content=instagram.com +add action=add-dst-to-address-list address-list=Twitter address-list-timeout=\ + none-dynamic chain=prerouting comment=Twitter content=twimg.com +add action=add-dst-to-address-list address-list=Twitter address-list-timeout=\ + none-dynamic chain=prerouting content=x.com +add action=add-dst-to-address-list address-list=Twitter address-list-timeout=\ + none-dynamic chain=prerouting content=twitter.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting comment=YouTube content=youtube.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=googleapis.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=ggpht.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=youtu.be +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=ytimg.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=googlevideo.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=gstatic.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=googleusercontent.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=nhacmp3youtube.com +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=rutube.ru \ + content=rutube.ru +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=me.com \ + content=me.com +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=icloud.com \ + content=icloud.com +add action=add-dst-to-address-list address-list=facebook \ + address-list-timeout=none-dynamic chain=prerouting comment=facebook \ + content=fbcd.net +add action=add-dst-to-address-list address-list=facebook \ + address-list-timeout=none-dynamic chain=prerouting content=facebook.com +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=comp-lenta.ru \ + content=comp-lenta.ru +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + smtp.mail.me.com content=smtp.mail.me.com +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=gov.ru \ + content=gov.ru +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + r78.fssp.gov.ru content=r78.fssp.gov.ru +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=api.db-ip.com \ + content=api.db-ip.com +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + api.telegram.org content=api.telegram.org +/ip firewall service-port +set ftp disabled=yes +set tftp disabled=yes +set irc disabled=no +set sip disabled=yes +set pptp disabled=yes +set rtsp disabled=no +/ip hotspot user profile +set [ find default=yes ] address-pool=dhcp +/ip hotspot walled-garden +add server=*1 +add server=*1 +/ip ipsec settings +set accounting=no +/ip ipsec policy +set 0 disabled=yes dst-address=0.0.0.0/0 src-address=0.0.0.0/0 +/ip ipsec profile +set [ find default=yes ] dpd-interval=2m dpd-maximum-failures=5 +/ip proxy +set cache-administrator="" max-cache-size=none port=80,443 src-address=\ + 0.0.0.0 +/ip route +add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=WG routing-table=\ + To-VPN scope=30 target-scope=10 +/ip service +set ftp disabled=yes +set telnet disabled=yes +set reverse-proxy disabled=yes +set ssh address=10.30.30.0/24 port=2222 +set winbox address=10.30.30.0/24 +set api address=10.30.30.0/24 disabled=yes +set api-ssl address=10.30.30.0/24 disabled=yes +set www-ssl port=18443 +set www address=10.30.30.0/24 disabled=yes port=18880 +/ip service webserver +set acme-plain=no crl-plain=no graphs-plain=no graphs-secure=no index-plain=\ + no index-secure=no rest-plain=no rest-secure=no scep-plain=no \ + webfig-plain=no webfig-secure=no +/ip ssh +set forwarding-enabled=both publickey-authentication-options=verify-required \ + strong-crypto=yes +/ip upnp +set enabled=yes +/ip upnp interfaces +add interface=Bridge-LAN type=internal +add interface="ether1 - Unet" type=external +add interface=WG type=external +add interface=wlan2 type=internal +/snmp community +set [ find default=yes ] addresses=10.30.30.0/24 read-access=no security=\ + private +/system clock +set time-zone-autodetect=no time-zone-name=Europe/Moscow +/system clock manual +set time-zone=+03:00 +/system identity +set name=MikroMaster +/system logging +add action=email disabled=yes regex="* added|changed|removed *" topics=\ + system,info +/system note +set show-at-login=no +/system ntp client +set enabled=yes +/system ntp server +set enabled=yes manycast=yes multicast=yes use-local-clock=yes +/system ntp client servers +add address=0.ru.pool.ntp.org +add address=1.ru.pool.ntp.org +add address=2.ru.pool.ntp.org +add address=3.ru.pool.ntp.org +add address=time.google.com disabled=yes +/system package update +set channel=development +/system scheduler +add comment="Scheduler for Update Certificates CloudFlare Quad9" disabled=yes \ + interval=1w name="Update Certificates CloudFlare Quad9" on-event=\ + "/system/script { run Update-Certificates; }" policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + start-date=2025-11-28 start-time=05:45:40 +add comment="Every Day Set Global Environment Variables" name=AM-SetGlobalEnv \ + on-event="/system/script { run AM-GlobalConfig; run AM-GlobalFunc; }" \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + start-time=startup +add comment="Every Day Check For Update Scripts" interval=1d name=\ + AM-ScriptInstallUpdate on-event=\ + ":global ScriptInstallUpdate; \$ScriptInstallUpdate;" policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + start-time=startup +add comment="Update RKN DNS Looup" interval=20m name=AM-RKN-dnsLookup \ + on-event="/system/script { run AM-RKN-dnsLookup; }" policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + start-time=startup +/system watchdog +set watchdog-timer=no +/tool e-mail +set certificate-verification=no from=MikroVados port=587 \ + server=smtp.mail.me.com tls=starttls user=vadossio@icloud.com +/tool mac-server +set allowed-interface-list=LAN +/tool mac-server mac-winbox +set allowed-interface-list=LAN +/tool netwatch +add comment="doh, doh-url=https://security.cloudflare-dns.com/dns-query, notif\ + y, name=CloudFlare-doh IPv4 1" disabled=yes down-script="" host=1.1.1.1 \ + http-codes="" test-script="" type=simple up-script="" +add check-certificate=no comment="doh-fallback, doh-url=https://security.cloud\ + flare-dns.com/dns-query, doh-cert=DigiCert Global Root CA, notify, name=Cl\ + oudFlare-doh IPv4" disabled=yes down-script="" host=1.0.0.1 http-codes="" \ + port=443 test-script="" type=simple up-script="" +add comment="dns-fallback, notify, name=Google-DNS IPv4" disabled=yes \ + down-script="" host=8.8.8.8 http-codes="" test-script="" type=simple \ + up-script="" +add comment="doh-fallback, doh-url=https://dns.google/dns-query, doh-cert=GTS \ + Root R1, notify, name=Google-DOH IPv4" disabled=yes down-script="" host=\ + 8.8.4.4 http-codes="" test-script="" type=simple up-script="" +add comment="dns, notify, name=Cuad9-DOH IPv4" disabled=yes down-script="" \ + host=9.9.9.9 http-codes="" test-script="" type=simple up-script="" +add comment="doh-fallback, doh-url=https://dns.quad9.net/dns-query, name=Cuad9\ + -DOH IPv4" disabled=yes down-script="" host=149.112.112.112 http-codes="" \ + test-script="" type=simple up-script="" +add comment="dns-fallback, notify, name=ns1.unet.ws" disabled=yes \ + down-script="" host=91.192.189.2 http-codes="" test-script="" type=simple \ + up-script="" +/tool sniffer +set filter-interface=Bridge-LAN filter-src-ip-address=10.30.30.50/32 +/user aaa +set accounting=no diff --git a/MikroMaster/20260510/20260510024002-Binary.backup b/MikroMaster/20260510/20260510024002-Binary.backup new file mode 100644 index 0000000000000000000000000000000000000000..c141192ac88644b01f7d03729922eb786870eeca GIT binary patch literal 297972 zcmV(cK>fe(sF8E@iv$1w0000iDEby)SjJ~%+WR8_000O80004Z`SAPzL!&4R-QJ|| z)MIiVBa{pZF-7}0@5LMMMuV1+D9biL^#cE1mo391Un*IE#>fDI=x^$41wF2G6gMsY zbAq%j(AhcmZ(Et&yl~yuUib4%W)#+>%oF9BNi59=NCL--^^-t-qnZ^}xEd4A=pxG>OK$?^HL)Vp@we>kT3K!g5!C1pqdQZ&cC zvmxD-Kb8va`(k(`^|Q>XZd{=fG;K^$Zr5q4*=SJsatx|dSb|!(FoW0Y3);+^Jd|`p zX-R?uT&nBFn8Tszl=oa}j{$kX{hz1*3u z3DX9Lm?ng)t=Ftj>8WZe_mBV^KwNHwu8ZEeclHpeK+832T&$3>L5RQ-LvL2~2aQc; zvmZ(L9)?m!$sYV@ICx+Ino|ZkG=a<|>q3k&YnO08Hs&RGgU-0W&BCfSLjF=ctO7?j zS?hiInXzdn15e7cS{>hdRUJbjkkG*8Q+O{Owz)1zo6HBj+tug|xgDfab>t-G>rXC( z<78?l-a`<$!`OMGgyipwswMl=Ysr*_sx2E|k_KoZ#d{1l2GzAc4fmo>}WK+3iy$&FW3ilOpyr01Y>?4#17;u&h zuahf@`i)FTz&e1PyF3`3EhC_FNsf_C?H`Pr%2fTxnv_5jp_xD;U56;pzJP&LSfI{a zQh#V`hc^}kFSXmZCLqfwVPc zD;UN`DtdYG<03MF`PE*?tFP_iBt&e}HmM@r|s=@-IIUkLs1g!CH& zpnr-xb87%zux(Kse$=$Ip@%FB+nLjTPUR8Ru*2YHdnn-AgLu$mU45v4KFL_Dn7YqpsAgFVg!NNf0R!)1Dj-O{YxcO8n`oDVdj(#4xZt?gV@PPki*H!=bR-d- z+;0-m4L2k#lQY-EMav)W_Yjyth~i*Qv+?Eshi>Ll-2awI*r=Kt#y_i103<8;ANhUo zfl>LNr~2@`yLQdiK8AvH;S*JlE_UuiJQbJRc~OKUeVAX=yF-W)*RoOdU&+?UQ{5vI zRS2`1h6le5I&A7(Gpg@XketavP~&a+1VX#2QbvK!^zltm%w8$*Uz)mA3TSYy?AmWr z=WeoB?*}ol@p0%_Ih39@AxDc^uCcncqNxj&_!<@bWQk@6axy>~j=%2C5x`S*94k@z z@I6_V*ZEUR%YDom5rNxn$bjGc__Wa6fY)T$m3EgpCT%S|MVt66Pn+_m*wI+C(cr*& z8y~F4@t&Ulb*OKsq_Sz&6-U{g5dZB2^xD|e`baew#Xa-Uy)u+}UYu@F$z&l2IIOY` ziff|%8o*cXg1+2h{4|F0R(4w}HDM9AxZtuPbK1OET;<1^6EG&WowT}rB4gE#H0Iq$gE z`ORm3`3(QQ0d45`Ud%&EUg|$}!Iw`g^u7FRk^14*G}%nz+ez6)UGtFr-4i_irlSMu za@b=#*@eq@#k18x*xY(p(bF>&?YQc+Cty!gMMDbsb?BwB9dO~5u)_e#ZiAhUp*#+r_6Weyh)>A6x+jGaz!Q*9ZR8iV72&Wl@aN$8SNG( z#jP(NjdUz@`Px*cZ_}29ctp6D;3&trlrmo3qoX1?v9f+eaZpW57?<{9qQDB&p`O1m z0_WB3SolLujR6xl2AebaA=OqOG<}wEh}~UE>D*Pq9KUOPBVCRBT(HfM(CW-R8wk7r z9_Fvgcy=;o_5Y(z7EJJpi~$WG=5k~4IhpOH4}XjC^9$}$g^7gEL#WG;+i4Pa zZYbL5T5*QmXK-c~nPLziafwcN}rQ2561h>um?3hK3B?!z;5*u@V(kJm7y zya{-G!fqu%Ezc&co=ZPjYoVpIgh1KAo}cMgEylz~#T1Ng@&Z4!ViWm`=(OpPINLAO zq#0dp>+aL=WjfL1M0A7dPvX-W7;Lti-wAnDNZG)83YU`3@C2TH`RWq#+F6>#QXSPW zX8~bqFE$j0Gj}q>Fe0%(L9)K#|B(LRq40r|Pqon}S#%F;wyqA1@0Co#UCB8bzc~Jk=Ax|YW7Im-6Ng`SMiB!4G^Lyw0foh zt>c#6j$JgeoGu~s8vk~Z0bstC_+She%jP#YBIzYUdEK+fGV;>F|M6b03!m;RcA)2c z)F8j(3|BENQEnwC2qdQCqX%K={(3c~<)6P-pE(6x`h_vcj1DIViy{7Cp#e)iPy9V! zuP6~*xP80UZ9`wmO5eBVs&$g#Z2zwe{4w$%-3wJH$oSBo-sJddC1dV4VcTjMK;zp@ zGU7QOfjv8~;(;@V```QYs8S0%x}D<42|x<=E0YBS@ULN->(Iw0=hHADQdOIhnfaU|Y2Iu8hjnxwoh~=s@6vhoG2!u+Q35J$tv(@+gV)rESmqM{r zBd`EmJbVrkPJe5Kgbu%y653jRY#qtm&4=yuOSvb$J#K5@3LFMDa0Wav zM;L)W@kpSWvEH7?c#%?BQa@p?|oQKOqFu|h&dSB)hHw#t9) zfiZrw2mQPLzcL(O%=N;2m>22i%Km9N*Mn=HB!#)O24n(>n?BpXFgOXhYUVi%N&749 z9vJ^4m>jQDFI6ADKMcoHN{;VFaHTwgrRmH8VL?(%?@FrVHF3 zfQPNd068i#&Y`MaICj??%Td1fBi2UQe9Ls@QPP&3UiozJKnbaf0-pFDQ!ShfWpBZL z+_)zk1{t7p?v7RrKYk>Ih#``zSg6^VJ$3bO}vNYbrJRZ5T1P5kqe;UW9s z=aU^J5Euap3tR_LP5~^N#gU3QU!?Nx3yA*1gC37I-Ra9@e1wz(M0lIH!x4E%)~KVv zeEGZBF~iP%J~9^n6oo|P)q0@ZA6P@XLf0ePrXgNUucu+)rI2=kZ3bu9QBgVjlzMj0 zS84^Sa+zR zf*lag!|^&oDBRzEc=JvIdJ3yUo7wZL?g^cjki>Sd3xM_pFbBs&hH64;M$J!ya@B## zLzVpY>>AP`2z69-KXA7p-NUZC7MP(G7br@-$RA!o9HbMaM~8{XSV*mCs-W4%c=H7F z_J$=8DT_@3{m~!-lNn`YN1!j03jkjr>e9JYgjHg+O0d&xYKEdB2sr>L)RgS!x z8huFjq&O3IvZNns!H0#JuCr4s=E|K->3j6sl0$I~wC!a2fecnKy||p!#+Z@o0l&~j zQ(XE{UZUaIoh7R>+BS&`Gc3{wKRh8x-}lhi~D*MIL3S zHMD?Y{&{gGKrW8h-k#jXH`|&#{j&scw(&L4(Z{QDc)hr&(J? zJp`=Q;UbBnu%VKvoTQ`YvSc1UyDaSob5tCKzzpe0I&qj-)tf1zAULz{3)(62{RYCo z+g!R>-GANaxS}^ob1YT59}2i$Gf@-`h~=28=M?h2Hc89XZm=9FJOcSg@44tb1_JY1 zz}m-@Y#+1WRh3^q@nc}*23vBcF?^PPRb^pA$*LK6Fr^W`aZ@1eZfQG4noti$X>}+a)SaKv`#ggmQ&S z;n{m{?Zjm-O!_WG`&cajLIW%m#T{&Da;+|fj?Q&+c$(vT{fLTSG#KRLhJE36&jDc2 z1BEGB_&Hs(qWQM>*V(}B%8kpU)!g<$0^8)$7s117OTtYKp!Ht$rrgNl{D;nU5F4I zAWMN)TglYsT=Q~u6UlN9F~FAx-ZT2czSg~G16`^%m5LBb!Q`Yq>i|54ad@tKbWxgG zifM6f!FuC5<@U>!vD=H?!mDrO_ExtBj3sEuYeFF7X63zWBC8y_6N3f%w|}7LgF?d&dLUGjc-XLRK9eN{9wZzljGS&HcAXefB-2 zMjUwsEI76L8;bfGO-Lxp!*R4|F`v^Gehc}Nrt6`UuTAW|6;3RtT@|H7C? zzz;o$1bPZ^MXMy1lbOB(vc5dJ5$uR>)Vg2O$>t+-^`OKo&df-r9ybpa$+57L+eH9a zYNzv7lwzk}+0r(7Z5zjU+28!ZfrcKZt;Kd%z}AH+(5#RycIj$r>X%qB*+ixp8g%lL zJLpgaq^?;$4c+s*U*Z3}2oSR34;N7X$8T!WsSGvLwD=REIBkxzxLb+7e^)Sy$^(exC5tW$X0j*-I6SJgsi+{M^$b($F>fkWw1gio(;HNCgOX zI^ka9bD7uipj0Q5M9-Cmw}?($sF$rdtO;hL;mz%61x6knfZ}Bo6 z^c4GS_5Mqc0Of9JZ8^kx=-4K!E8U%`wjB6nH;Z*?6gtZd>!Jl;NtF(tyAvCPlGt#Ak+V&elm}=*_0hU;Bu47#3E|GXKQ-c z(PVz4DJMyl=j4F4xk_ZtMBx@)*Z5T~@?ce?APFxW;Ze<2pd0bP0YG6Q%>k(U%uL1Qp_s>)nXB`4w(*8rTQq<|i+!0i|*xLS{rgp1m?QaF4}s z1S}!puiz~27h2*7{6}<*gGkQwGl411!VI?_S>C0 ziLUkg{ko<5oM*BmlJ^8qlZzL;MUR{V_JmQkBIOt~mT zL_zX7E@2xuURd~dZO_{%ekKTW1LtxblfJl!-^Y$qNtKLyb-sH-;rSuVq$E|}E6rW~ zw!{5xVPhDi(743Abxhg>ql2SNKi2zJ(k-fqf}-Ga!K*cYojnB&c*M;H@g!7E`HR4bG8r@1s~q@_so?_MvJAP_q%uw6(C&k$6<| zB%Pf_xdBMHIa5?~?aG%dGAIcbX1UnN!k}0O5wPhKMVWds>s_O$Zy(iO$nmhH$0vt@ zV+dGfXAdjoq@pUeG^0@B6@*hOP)y>^SCddYO#)AtNc;e}3k=(Pnf_SY(kS`!os>!fh-A!wXv4t6`3>9S>Hktb?@pg2TPDS)ZjCls2Y10wREatRP z&}O8}tF+*p)gQmCl2V9^+u-SDrpMCcf%Dnt{}PJ^`dN7Ksr&fe^&TIiO_I3?XVtO> zkw4@Ph_s}P;^riz*PC-&1vraf$+ug{!5n#q=1|R|(l?cNBM80yVoY;ly|#bVYE6`k z+8HRCJqq*Wj4R0qoZWJOXBnz&g3lgOHrB)WPzP;yJX7BdyG(G9Az5`~=k@eQFeZQ3 zmteZ>@y<~7_p{n*d#;sapPpz|!I>NOtbFIGjCgJ3zauCpTuuL+d2p%3W}=$J8LYiUab7cM5`$qy%2CGSI zGJX&>MbZ8WRe6)YYe!spI3rJmKDeGdzDTxpqD-m?`kZQw3W$`5m-txp1Zj)p_Hes} zB`-Mw+vXI#Uli2f90Eb!Py5&2ZG&_osR;&qtj`2y6d5l$-GUcgZiv*iZQOC_esk() zRpO!-1O72kp!j#FAk{iNMXV?OMX*wsIrq4@H&{c#>}>wH z=RPoVQs-wemtTA-1YoY(vKS&L5G7$zhAUdm4P7R4qSg-y zUg)Pty&PClQgNpBF6*CT!W9V7q7lCe%*V4-*EN){bG?F8TX8*GB4lf1e2jr9AnXJ8 zy}CjT^FV5r`tP;tQ;7)OP}6qO=nDQ#dj3hm1!h_IKX1&x9Smfpdb{TZTT(y;Duv&h zzRa%|98Cp>n<#+H0Q<}}XjW-ZxSHO&t#-w(4`NNO#=nrBO?|XsHvT?@HtscJ50+{D zy4A}`&r=p3AGATlOkM>-RV^l>`Ayj-_0da;m*q`SY9N9ZgtV%qpIX>lK|hp*SkCBp zU-}!3%`;gPF@7l7&p+n(8wCmA;BmTGc;~xMA~|?`X`6#pU#VmsZpTxDa^e8PEvWAh zm!$(A2*!D<*1zzNo}%$6fIS|P6pr|s!?)7Kn>H6v>8fK_bX^f0O;W9nPyaM7RW2Hj zM)Bv#Ug^F_(jB5Ue4l}sJ)Th5q^SFV@j+$sLdG|M8ld$ZTYnyQpl~@E7}w4qVoSwm zQ--gQE3Qnfcw?BAiZ!YEDiHZio5vKTE~s+zij`Pr-~fB*ktp{C%_)+<^WH(Y`8~ZC zfJ){i(VhG=pg(z1i7SwYV64V@x<^+V$+mJd|3g$8}wI zTJPq&Q<6?7BP`vayhn;Nm=7t6^K?DXfyRsJ*`kQ$0DYJXd-O_@#Xq)erMP{sC&Bmc16jDgn zV!}Ea>_bvo zJ{DaF$qL-CzsOXY>#+IS-u+p;Nr+q#Bf$g^xPV!KUy?EFpJ9J?E)qg(4F}^X@iLP% zc82FuC)`EJh^g;pm`H^6h zh(}~gI7uirx5xKvh)lOZek4$oci*xacb0$==a7n(J)lAX|GTU`Z?5l8+z6^VP=CV| zUj1v%I|u-gkLUK_$t-3bpQ>5$b_m3*S%o~T6ZW2x4>Yx1#-=HlZv?OuDO+$WQKR7L*$^zRB z8jG=&yH*d$4RG0Ua(tFvD+!H=qZ1g$b`>2QsH=s5@mnAg2cznP1+C(kIGh%7_?h9K-7_q)n7PBB+Zoda+~B8D>8199lQpJ& z!zBC6vr?TbeNRQQ8IXDe&}66X{5hFapJcoS$i-$Yp1M9y@!bTD-@L+>yrD1JB`&Bc z&k)acF~`eo{o}A?Npk7Rze+9FBBC4lW3(LAs;;Lch@Wg&aBM`z<~z8e=)ieY|Fbkt z%1cqXsL?}tNJ$qYvB<9>D0^AX)d;+vwY50b*8ygwPvJ8g0JbVIeSwV#E>OdJp7^>A zxdEyWW9!>>EwyZm+$#IQOew7sAcn+^!vtsfZu@|i=MxRZQP1E!=D1q1KQ^R*J~IFK zN-T)aQDxgWynJD?arM~i zapyH8k`esL4zI8Jvnf9=$G($mr_tfv9p(m1U`kHR0TWNiPLkKpR76cdyW4~=dUEsg zp`V2`3Lg3Uv3ILlXQZ#yK6%UFmUmUNU#ATB$VS=?G+dV@?M##Ok)hy7iPAZ}^!^E7 z@3Ct+gfV#Ag8(+2B*ZXbaA8;r^_}=AApPnuwYW1Yuyt^_6!(U&KNw22I4aM5RUH_T z5EUIp6>}U&7_F-jT2Ge%24ui_B_M^EU zg3JC`KOykstYuM^Z>xDeZc3Y{U|HoumJEGh|gedxM%U8MZ>P-uv5UV zd4)kEs zClxl(BW3v&x!siZYY@o2;;>uT_;*f@%7^gz4sg<`%KbR+yhAxMniZ(s*^xYS`8?A< zY#huWnSD}7J|=bhMZf5)Puf~TwomJlhO??%0`)egjN)}o)G%l~x$%_K)^Xx1RaKfogP`(&U#SKL2JFyiyC`W{P$BR@cN7>Gjg)Y4>~RNgYju z93Bu*mgQrN!fH*&=je=@DRnVumbtm29J~VpV$Y@?s#D6Ay6inz|Fh1=k(p^irqam0 zrMbcCbrDM$l;-vXplTO{B!3mm3~{uvZeVa5<(22?bj6HHK@a)|O!^(;WMeDSC;G41y#Z zxQVMs(4@Feum(<#vG@s^sFR!yVR~C)BHQ`N3g4J~ zdzin3nq_lQYWCsQ4OpiH7|z~kseDJ9CCBj!dm0`$u4qrDL+U-$7d&0X4$m3D{_RE7 zUfMroI=0gXtQ#2zPFl*G?<+=VHqf1*NHgBJfp>oQcdjh@~^ahac4I?_zD zt;d$)IuCc9GTokhOcS%7Dv+Ba`dGQu>#J@8cemI7ckd!z)*@ z&Zb7D`DtvYM}s(NUk;%c47_LI`_x3VxWaX*w2gsSC0LhUy z*}=n3%GKs;40Jmjg-eUaAqPB-38aI?CxFzPmUV-$_bX^|1es0Zv0YOY0$f<;iK#7v=>bV zl7JegFPuwaK8}iQx>%Z(2E{FFo{7y9=G;w`Cl22APB$|1sJ!VIWvh~BJDJIAIyQZ9 z6tKZT)JU0%;?h~HGBcyAP2?2WAO=XR{4wm5TV6*hO9`={Mw>b$}>g( z$`AU*5a#|p%XFfWkDm{W92g5?N>v|(BiG)L{?dZsIAiE5DjW-VBfBY?`K->9PVl)} zQg>*H6ZF=9k;7iW;U-OGh&BZ2dMTFku}1|a21t9dlkfEj!ZL9+YssfcJW7LYmP+ra z`EJeiVp4lIh9>#cxjzH5#$?+`aKN(#r?OJOHmyPoS~n1-WW_BF{xmF1Wdw>1|tXC|yC*s3#MqN|GPlkrO(64niKnQVV3r82fuH zaPvw$UR1RqYgcF}iw6abR9ee4lIvzI0a!`%Pq+F9nTT1Nd??cBI%YGOfhbsRgBwCa zw>`AQY$^&6&Qx_WegU& zs_kR!CJrCGG%nj(pBEe?;HDVI1waG+K>xngJM5ep3>}X z(25pNsmm@L=n|+4zCJ-Z-8`@pgTykM#T=`7_$Ss#tXAux-OVd%cS8t1@HRzPQ0cgk zB>rtjj@TQ12p0KYn!T-qqWXDnwq&Q9^pO}<&pA<3XmZ)nke^-AoipHH1Txry)bxQDnorvY=+tgKpQA0@YS`!6Gln~i zNb~mv?Qsr)Z>8qShh?XCy`+ng=5;P;{4_uKqC{%LhHkCFTgk0zzyY-H_mF8#29VVm z6(wl=l0AID@6f4Oz3m1IR`nSCCBXI{S1npK>K=LIb_Ayi8p(-rMu~@EI!vlVzoFbr z$grsdU4GU!=#OyXh+o=B zZ;Y_a8(`4Uw@7@O5~)SKEhP?W5rpMZ9%uHtd;Q@_Awb&5m#B?fmLg_`eu0Ah+#~`Z z%^2%njYaCgJMH&U-7bgx5a(%G(C3+Aewmg04iMn4p}^&-+zo(#hRUdS4m?K7@6X27 zPW&q}k>eeQAxg1oG(KeZT%e3VoL3QE!a^svlSXKdl#|o!-~cToJ|)GiTVrQA$|1SQ zFAoN#tIirhet+mlwtX zRLx@AZ3LH-?l%RS;zNfnuk&Zrrag8d>l%}lNJZq@g9zNqE(F5dKD(a)NrDu6h-|Uz ziF9FxrrC2;>pns1v42!>5P*ud;eEbbf$5nUN?M->)j zqO)gSSte5z+$y;(do>{6`r#~y=ZUD0?13R#z75%1flk=o=8&^sYi_f1mYiv5Qwj9RQ!m7rF?=(*(aqRBUqURa3;U8dBW{dV%?D^LxCuN! zKyUP~!;AyR5N&7_+_9NQRrq@V(z7Z$`D{+aRD9%CsyGyy)VvB+wfmbzdx&+WV{bbg z@y8OT8CxB#ezYGDFTV`Yry;44Q?LLxhn+oE!8nTPHrkGb?mcWncV-qTcNE+UXN%; zz(`k}Sn5~SJSYASHj`X`w$HBIt=5_7S>zN_+vfueu9$`-RZlq85mvd%oc33Hu2t6n z_t38uwc;`<>tfsx_vL@?kY&ozJGAs;FDtn;vwPvR4`$*=xr%p3=*Jn>!C<^5IZ^BP z&X~C|-C*2<1ojF$VCYJzQe7qWj=5pBLJzyGVrU|#q@okv@qh&$*T-z(qV;!|2>)~2 zHk#~TL-}fm^qZ^>8$n~bp``>wxUOh!>mjy9rj;J8&?Xm*?<+Is_>ii3jbJvJi@rS^i+R zrUJJ28WEc8mRkLF3FJRoozvsrPV7ttV>u7XV?xJ`U8d~UZ`yY)N&TGRES7J-kqJr; z18R$;aJADnTQ7p*5D$@Zkae`;|0&AFn_t1N=}*ycSH^xe!v~irGtIZ95@pfj4-LDn z{ZsA^a=BdXPJ(6!+rw+L_ti?M`>V)w*Zz+2_-}Wgrz*`%@H)`4VMYp{qwrJ{`?s+` zC)xOu26CMNzxNABwC$g`IgEVER1D1?kLM2K9Ui=d?`xmit)OFS)i&z^eLNwe#EwWt z%{U;T2C->HuK<7B6sPcjsnyL1?9gw-7GV7DNoc3Woz_H`v-N<#&%b}(9=2%ec*DvLNGo2X|Bg} zyLjFLHq&eK$VaepTW)M)92_vyLJ%&$s$+XydP|8lceSc))pz8^)&)Z4_jd&;jb^3# z1=W#df+oM~BE<4rAQqPUzf!!K`gR*`4&j5mo(C*Gfu_rTe>HQt{`P?II`XMmH7Mp#aGF_T(1McWfA63i zW3Z{pfLznomRW$^z*tkI|Hb`y<+%qo7HmUwl+@U<+2>>$I@*agVz=#6Z@GKc1e!In zBwNM9ttC}n(n@q`{<4}y5Q**U8{M%}EK0j?!;l6Za}i&O|BIW?8GZ6Bs~aXFSC4{? zOIcPRmuJ|$+rg}QCW7A!j1U?A75|HBzKWFqG~{*goj z*-7K~Wbt+sZE&#X^WHa(VSgMjh)$I`7fq_;n8ZMjgds}~et{0G&!ba|Fh?l}<6lp! zJ~=(P*gU1K=V)QD+yXX32DLpdE9grmo_HI1YKp9mR9IsC&kD-UC)Rs8#`NKbCQhYL8@Qj-= zb#5jPji0Z3{G+OHjf7Y%XdPTvB;v-X;VmgWHCN&RLxBK>eP}_SHO-25>6fO@_2sZ7 z{469dGz%K{F#|%H0}n(e^8!e!B}~R#`RTVlrRdc-yNK!wQ{Lk8E`1Kp>xWeh?eE2P ze6}x3;cm_zARWLaIo+)H6#w^$JZ5Ln6OA@MS^eMBp}PJXR_#a9FcM9*3f$+|rk*+B zEeqW-*jCU2Vx~4(A;z2Pe1uDiKcype!Cc=TI3rJ+E>d4>@)gHNr8%Lk0eN-oAvo1O zzRZv^l4pOk>*Qb+K)P6{M&3$G`b@}Mt*C)N9p-5COsJX_cnoYy$SZs{`n}rE#$(h0 z-uYTzAmt2rIAU@`$NFKNiS1Un74pk8>o^5;bv?3sfAdCe==SuqIypYr&zxF^d35c= z;b9qx$JAn3jm(=&oY+3D&s#Sa#Cack@NY9fw-szi^bSO@ib)i2IZ5XW8w7(;YY*$6 z@Yw^OY1YCuw9JRQDC8e)sMZL?ubP2P0Dkv)?feh9P7`U%ERBr=7^gQ{%C_y7uRwPy zNWAoL3LxBFOB+T2bXzG+fU^N=EinI3U|MchY69{MYwfOje@9$n}B8@26oE9oH z5#)C5Q(ceugy+=*(L?gm-~Wp9lJwt!i5kS2;uh_fYoZS7;^U^qi@t(DXf<2y3db*} zH}pti7dV_>#d9O++&VZ+T71JxK(2Hzz|cvn&0o|jjZW$*Oj*2&J!I_(^dZ9hU z66wCQH_&`4f_D}V{?RSCIP%hKNh&%+j*4l=$JuVtXk>@BCn*qY2aNRVMb#dMQMfR2 z(*eGsxZq~My8Atbr!$p->H1S;2amU35KW~6ln+p5=MUaWSY>1(3i9MeQ{i8p2o3z4 zS!KBy^_R*HX?NQZPCc81W8>8A69p0;5y%F0V7h$&uk{Lkm+tplwP>y4_BhbOJnViT z<#*1dC&x;q5FNiJs(|S*{q8hnd8|xrnKsE-PUrxl?f!P=XY=H*q4udej)x&+ha#kGS@%e4LQQ!32Wz#IYF*;THaJ`&so6OV~W0oeM|TbO;*=!+mKr>fe)9e-CEm&0VIsL2To@b0zDfI_CzqlmyaFczx$ z8;U11A#6)%iTBojCM&KoV*SS^kDRhF5B4X;>pc<85;^QoSciVHP-bt7{rWfDrD&)WGv7D0$LNVU8J?rS6 z!dQtk*x_<+wNB6OaQ74Vmi6re`NHK8R#OdxGA9Gv?lQ{<_r^u3E&=JLKz*Sp(YXmE z*3H|Q>|IG$VYJuIKC86elR;r|MH}GawnK&zx9Cia?3|MFa3?5SeFsv?YTOUOGuM!Z zr)mKf3@&)f;qQcG;xa%VLkBA?U(!uxUb&4N(NIxjg!G<*zi?SRLiLE1TEO;miEmT; zr}N;xY7bbQP%btPKX%V*2{oQcR7o-o@p@FwL zd_Yh)_hOZ=!q^mMX7+_8onhcaPu3KGkG6U;fifhj{#`_CdE>tAiJ;RN#~m75IQ%o{ z^88f_ww_!_Yd9iYr!`>B^FR1iqG1{a;`8YiGO<4q+^(dPtw$MZCN+4gOJ)?av9yoH9&K7~(9BgVDwHw0!GuqMw#x-~zVR_ilYLbe zdEX9hT(K69O~Hh!#hUCua5SKg@O%S;lZX|EOWlz(x$a@aA$%X(5&amrItl4uu~xV9 zuofmhXC!}6mRP!P z1HI;pss5}u9@8z7bju+vn=EauxHTTdW=}mo9PK#f+CQ3n!iQ*hk0_}9<4n79o3)4_JWkKy$9euOU{?_ zN3K5D87EE~maT+?@0V?^Q6kKE=@oy%v5gYXaR#*o&z@kOy;vS0s2S!%4{5;@ClGXfHMGY~RG^j+2tiupL&g|33&nL}&$yyuD6#B|D z9!t{|Ga!|wNKJQ0NZ$BWTons7sP%QoRI>j354(r(9L{xYum_wQMCWnVQUQoNl$2_> z^(uj9C^JzjI+Okw*4nqVquvFu`Jh%GGI6~Jf#pmMg%yCzR$7D(3;jIz+fk=j7!IRw`B z%i&*@xgU%}{sn`5G4&-8;ValRb$z^fMsuIJO zUh58SEBSMR-nr~ow`5PYUbeuZQG8q7(e#Xic>$)};^3dY59OOb6cq2^GjI<(`WL;8 zo5D|%LK{+H0)Mp@QQ_(2xa|c|<127;}0qtF@X{+Dlm)xjE|kb5JJZ86Cq-g0KjG4K0rq~$tf;QOmknR(VY>@^Gi*WS&h*QTnO>AZsfKw zdcb|=;h8!?B*E$*GS8}n0VNjidt=s)FlSTwx)b3ZnGL@#(*~3B$VeB8u`Caw@?-=0@y2=MVA-z zx&&Hy*&HeH)xP25Y+`JhBWJ+?$KJ20*gdoYCX)sPm3|?t4R>w39$_wv0O3p)vrcN^ z&@@{2sJyFsK<6g*f7JFqzI};0AjF|ZnnBw6ALWV|`b*x0t$b60<8MBO66Ga^6dNfyk;o6cp1Rtf zkH;_0o<0KS4$w_7sa4jQ>Rk=LF8p(dagz9|S$|35IZL&z*{@S9u7?^M2noVTLN8+jSSbUhE$1n z{Vyjuhfm+z_+5Q29 z{a6OLV#mSf*uj7yo-ubhuF|uMX9rM6rg?HZDO!zyihOB>SoTw(C3+J@{ubcMa&~%p zjg_mrlV6Kb=kOJf)ef)x;MsWR)NbH`o{2mgqVtiF4amKbw$VAg_L%#L{YpOyMmSpT_&1Jk+Mr3Hl!^~8}>kf9wO*a zHY}4kiTdgXT52pY=IwKY`RjE*Fe1ghqe^3^I+lY8ce=s5K5O=yVrj+(EMY)aFLdM= zyVNXhcAh&XX|8s@oEjQ(>dsC?VRAvHx$E;{q$AhBTM-^I<2#R@Tkr{QkzmAHEDg$5 ziH)Sdw8CRgguM*zW9h*ICN52)XoMN9TZKmEIHqLiN&&bMK9UX5*b<3p@3RX6r_}tK zpwN?+{slx6dKpyr-Ca-XUE34;4DRM0b!u#!dJ_uXi_Kk>!Suyd`j^+fB{7c$aU1=| zuja$i~8_}^PGA>mgxz=#N zbT4rfc@wwADaLnqaXxJ&0~9r9YFE{e=A%XMH*Z)9Pq3~^>-4fMJB^*bafcD7{a$jY ziAb_@Z`N^=-E2$SAVbNy4S3dZ0OHS7k*hc2-#kO@ah1`7TZgiGECeaVxM*_DUX=C3 z&#>2#XXEipZ<9$>CAP!qCNy0KQYAzyito~V;4?*RJ%%cUCF2$GlZYey+qi58JPgga z;-Z!gJJF#U@8){HK}fM|IL!I<6gEUq$t5Y7duhk6x!2~upK@Vxo5*GcoF$ z4XGwhxqW^cA1P~*IiKU$v(_KQf3k|7*kn2s$rRNe~ny= z^0)LJmis$w7YSiM>>BU@z73f68A!v@5}iHQ#ot$eYeHzo=-8@w_?Nnz>{xQgmijNF zIOd&`d}3BZl`n*gK=^pp65X(34=`iPVgdAyq{eku}0UQmoS6@>?ln z7<kD5Si~JNV%O>`v8a+ zG^2NoSDrTCvQwCXAZYh9Gb;E~A9(0}!gW|Woi0zOcyED@HcVQod_!*QZLg}1zmG4n z0-3cq)B-V-!D;bn>^dLK4su$@S_&psA5>=`Msc|a&Ma9&Aj97 zH+nHRfGKA{^ZB(Uczth=Ql*8)rRBZNhMVX%@W(AxaX)8$@V#Q>62Y^ zu6^4w$618#H+q$$D$uVjRpqCo1&S9_Sy5OyZ?~pkEr&D_7|v1aeQKV~Y@xkR_6NS% zcQ|3%O;ojjC@(9NvHeSHBEqG%CwD)p!hqfrM4`GvBH!yt0FhrUa{N3`>8;~k6EX#( zxt@5|_O-E3w!%o4sU*yAQh<+Lvc%A*JvNneVT8Mea|2HwcKB#t9}S4%RztquE-X-E z4yX@)XLN5_v?WqI_CvmC@L&0so;UX3}~IG+2u)w#H*YBe*KaD0G01q@9ws_P*#mc0@wH%AzNj!tYZ3_Ff=F@|tZ zW#ZQdaB{Wun1pvATL>K8lc+9LHrPIEvEpxmX!srRayp8GhW?|fMtqaXqL#5A!1#-* zhPEyH^<7>9mjy^RgJ1GUS4@+s!zHqM--Q}7&So0=*@Cvy7e3LehLp~2eRsnGs%l@# zedj(O+ms%-YE!HP^2#;ljf*+v<`D(DMsbnvyW-%5aRmcyk zxmNl766aj(yWlunGUHs{!5-K!4r+ZZY@|X6XZX`(N4^U0-hr#yEY2*!}}?mR9%0KLbY^QEO@ukNpjej zdcd>`KjP_R`e58PUL>f=1*TdQQA18%%oH3YH#00Or=f)Ay4ZAuH8j^H#-bTABICS+ z3@^p}q03`b?`4QFeFJ5tQDTSVR7A@5X@=C*zvckQIV_; zyG7F;ZwQ++jq=m$j45VTA@P4#B|BaWjs_Sk^=CWjE^$3~bAmfKQ911OJBAyDhvd>u zH;8?@-@u`~%*XX(#wtA68SWDX$>kKR6!S48fw-36bTd+@ANIdTCgHr;uw$gzu%-Ot zm$&kvnmx|5_%1!0LV-CHXp@lG26{2B?U?gw9^&cIPRW{-b%&YNI7O_=JKdmCN8lOq zpvU`IoG#2^l5oGO4t&3!K=lJ9ycVm1q&z*Hn_20@7i0|Tes2}##WVmMPN|dER$80r zLH}Q4qYiqT-&j5G&Md1XWT$UrWp$Z>sA*4lp~-?*?NS`AAqEoTwmEi^Qk6jrYiOwS z1YeRJmMcX~>YtPrUv6d8zC$u!6WS;@3RT8wu>bLgbs?n_5sbeU4p^@CK(5+*UaA5) zU|UeIC2tRy2v88-#mBtS=QTI|Zz4ESe=jgJsiAoCL#becmAFw?OSMm|aS*?$@*z63 zGm&)YRmL{TZk2YW-5fC@T6bB@u-nkhiEKkJg9p60`D>$z4d>bcpP&bbZGKO%-U|sw zRF7@^2Hd@f?MX*H&Ct0lu44Kp4^Je^UaCemsYH`ZgW~UBQ){wWW8(N3Bhyv4MedDb z#5IM=ut`^>Q4RZCY`aq2kIvOYcXem-TiHOUAN$f)&35Vob#tc3Q-aFq^;`6CLixSB zvr{Y>sf^(VrK!^ChIRKCYT0SaWzj+rKJ^g73G%4ow>$_$XW(5#7ei3t5`548_h0kq zIN|@h(Ffx0fOFlPaAim|2RIUI6eHSHHe|>b@J&msQg`u=ox+-;x;FG`F~<`{d#zeB-Igs5hL}QHH!}H{Prk$A zqP^r~@h0{&%}lSG{iEax$d!Np+~w0KR3s|yU^$<#Kw7zZU26A4tJ%}VOZTQqef9N~ zku&=4N{N4fXUc>4+g!P}+ek?&O|hXxgD?D=V<2O)d8M0KGgg4wIDR=35yh!nEuk`~ ztPl3|DZWm>JlPrdDekrJ8|+q3NC_Les1uZbrEd4?HZYav2I%3QMnBDxO%6T%O%9NnJZ@sZ zGd|#C2{PDzNPkmiXTR*x#`HTA0(UzmDV(d2!B;L%L~9cIItq@gz`mM> zv+gBAq7y%oISDUbQjj(Xz4~q^+iBJuGuD~N!F^(lKJ4; z_|K2wU4;loyBA95$$oHM5;h7gPJ-cc#h(!VU>LDm7_r6(qZ zz%1P@>V#JbB&P7laou^Kdl?6nPfk|$>krZltK7(y`k+XHx$dsIRjLW#LZwgrcyW5u zOj0Nk3<*pnz)Wtt%gAHIcovfSdGIVF^ns73^M*H!2HKTH2olh!^3fQS!Xm_Ub4%)h zUq=rIofS-$r;SoeJuO_>Rl#;E9`kpc*W>fa5!Aj;<2O(eU%6{SD;I>L){3y&4WTva zWbg(N0hZbwOcZYT%aE87X}C4~vu9QK#V`lDal-D!rww6xLCo&8Z@j9thd=ZW34Gyv zjz|7fdlj^{T0=)CQJOM19x&>dY9x`?|kqs7I z*e-+NxJw2UKO0v?+VX5|X%6%$hDZR8tk0b3M8B@?zj&jeck*~SMXj#xh?K>+LfOgT zI32JYSeGx*>JT*XRU{aCj`UvOyHTA52qtmcsyW%S;l-s1pC(Oa^8#(wjlNare?I$C zZQ|en^MWQO%>)xaZzifGvby}Ia$JwKipWWrz5i4gC5Hw86p~2O)Ai7$tDI$-BP={8 zl;p^05RUudp5`%O{g^Zn2{p3-@X)fn|ZEPF+aV zixzOl=!Gly!i6u0R0~D1U?A|?d^w=RIB1}{;Lz?XQTY-A(I0xk*a73#AiIn>MB0Gb z#*w-LER!4SLE}71El})CZxPD!KGw#)if_rvoCm{W_r;T8Pms3d{*(M#OyE0^$TBDF z;)?{eev7os=-3{e6m9qB=Y?HJ9T=AUG}(36UHEV(u4Bb>@ddx%5v5c(0CZVnUJJ& zAFffjm!IKyy%Y4#);4Ge_i-rNQJ)Y2m$kAq=v~Q zHyFS~yw@!CpE$vBuAp+X#P(vnzM8Jg&&Tf|AoKnNtc})Uq8mW440*~iAKJ(2SN=Ba{sx1~X@1Ive)J`es|9VJ#%{ElR8-3+# zWx*}NR;#i7KDRjF)x?*zJShzN$C)Z*x7)v!x#bzy`YDv}WAuWy4s|k&-1jP)rEh$h zk{CzmI-+og&Z{t5&RgJ&hAPoG%MmSOaV3^UATf}>L0G6O;EYl1&AdJve!I*kyqn?dOx4;3 zt3cP)h@RmJNuFy1q-w2Kf#C*)B*nv8&?ry*72v8+=Dtdp+3&vRwRK@|bJpXD89-&G z7q!zCo~FDz5*6cejgd4Np1GdZ*t$1{7T|VF(#yxG4shxMU4w3?Fgf*(G(bj_=q+lU zieAoTup~xX)x*?>3OOA=_0ZqQ#Gtk0p)@i)D^ckcYvv|H{AdLz5Vv*n;!_5k(D7DZ z*6WgY>K`3I78La{hj$$CHRj#I4Zesm1ziePSFnUy%<9R|cg`V&-UBQv5;Jiu|HEBh zN+EcV51*eeNDF)kl>OHkSOH{E`+@|>TogCQHj|Covs_TKJQns&nWC9Lp4IyPVm9E8 zkW2#MJLbUtU-@?ArRX@4d9x7MA>xMSqY;k~Xw|!2X7?SmE<0rm+!rc>ELF~ajMFgY zutH$~CAYImYvoK7e~&4Fj8XNNa#gRG15yyZV1OTqUM0+v`{zWf%&ZQozn~JnU|}vS zFetXhSNEw(;;2h}M}ZzI_%z63>ozBDVn96tyb5gWNU0`bCBU`wR6TLVs$UG`G#!AB zY;aViN*$b9QEKO;7Sesk_8ddmHIy#xzk9g6z+Eqb9*#%0pXF<8vrPAlN*W_)M`*#0 z-vSIuUx;wz1lMXl{z@OIlvW|-kl@VV6^@D4Y=6tM!ato1cgCul>YJ0hXd>;T<5s1B-E6=jJ`U&}EF}&*3!D~qc~5c9YF*Zseh7MI(bA|w2{r?-Ck}7fiHyx{ zcg@4)m~M4@o8w8SMn9#IE~mUid*-DWEDE;8X_1|Xlh9Nm>dCdSV(!Y|^d=t){A-fY(sX227repsfLuqAeEV}wF%-0S= z*v~vm_T!!_`wjvc?p9$wEz}+V92JbqWFge|ZiLH&J6EyfRU`qZEAF6!^)Oy%qul6# z|Bseo8q!1febafg?S5&Vsf6a4X*3=RQI1svC^0fD8IHzxUSGL2mH?|VjA4`2ux*EJ zoD{Vq)$kHu&QNlXJTb?A7NX2?_*j=ETYC`ihY=-8rmvZm-b3J6u>xo1p;2Rn8)u^L zZ{w35_&FDQ#yZJ^{6tFiFFuNUZTOa7m7?GjcCq{ABmnH@TvbaApciR{D}e-2eNh#~ zOM>2#gwr*kHev?n&l?v6Efp#&mjJM)I zu{{I0Brb)yLx*h+{?eub?~gT>8)8!uu47pqoC_ke|MUR zeq?us2~ZT!v)}GC;_Ba<;~W=U{afCzj8)P_DJ;LCirNZ>!m677#H-`q0{bys97K~veNJ`jSf1rMJNBUFvpiHaJc<|d>wHkX6tN?lV@{xwXr|@YbLiVIa~C?| ztPyv8+lhs8)Mr2>1@8zXg_s&eKu4H)WSyZ;a`VP!Bqhq*YJ32t#O|{SUQO+Y$U6bU z?d%d^w<61_(aD}iAduAJ-O>W{oFU)fO1)$fLz4s{htRy}DBg=+0O-Od6jO`cs{15a zzDAG0H$Kbv$>#8X3lGb8(*RpTiL>`~8o7bCiFn}_OEkEo8T8;_JsnGckq9L$3 zxA`GM zmAB;v7kbKxFt5oOn4Gzo9!-(iXoRuTXs2$LV&%5y)0MFX_CqpBnM)=;-CJO1hRd2~ed`ltuE#|NGbeqpTJX zUiDRaaa-;qge@fX|xttAVe@=9vD}&_suurn^tcP zMVWSC*i{dJq(dGPh5uJ~kfE>6Sof!!nipB026wU5;Z|O;bsvpPNR{pce44PWNIpvh z>r|l_a}X%7t(Tk(T+y#=Eaozta!;>`xlPHKaBd7pZqpJkv@Y^|tFeTYA8lm;V?0@PR`A3~jEMjn#N-LIcr=`BIky(U?gmWC3%&?1N zd-r%v$O86vBUW|O#HsLDZ{=w>)6vj}LF`5|Sp|V&oS={Cqma%N5)2-FBM^b9?x3GT zES$X`n}W!F?YJOyh-`ajKhXb+#Yf-*5w9S9eOhdH-^QpNYg~TLUK^4pe0ceQv5l5* zD%1Pj8W~t9$7A1JJ@tI6sfzq@Tj)yir9aPB^HO^ze6T#!)!G! zJj?`AnasET=yE$eL7TpeF(Pncqv$St{FQqq>snbf_Z$J1HG4pbA9&{0n{ejNWx=Wo zvTw%(;Y_7LQu9WQsg{!nC-0xUDaNGI40PXbo7nC@%uP~_7gz83qlE@|5$v*Q@c}Z% z4a|C8w4trNWV4q11yjgmN1$#S1*_u*<7D0$TB(NKG061d)-yQRK08DBAJ78N9^q|o zdI;#FS-m0I0`n9bkjR^SK*1sAWR6p2&yW`6xkjVXcDxwbM8hmDEuHfC)|b3=fqoMX zGLF8C`cNOC)e5>4+b+46TrG(%u*VynB1jd%KIFLLAQ8D0*vrn9UV-*@?+&i64ueDh zb`c#7Lx{LI--cbb@_5fX8D7s3T0PUVuqrgjVFDo~@p!c7oswaPt4Z*0t zI&@^BChxa6azAgJcdj`n0=>0Csqv>K^~bxI|H3Gfw_^H%A0tLiRaPnWX@j0uA?=#S zoA~-SQ@$MFK_*oE^-Bat-QOkCt}-6ImE04me&gc1wrGLRG5b75;xWPDbSHe%Kw7Y# z!(Vd!!=~AAjS$^r^yw1tNwzgY!3hH~PSZisUaDSfe$v_)u(MNXJmc+uva z(x+$g&L*rW_wPtj5D?zgMoQ8=>M13t$Kw3NI@Xdt0on<`yvx^V~pB)wIX=GZx`D7cKIMXeabEHiZAL%yehSGNeaMcXK?2%d2L(M8NC_H83{LEfO+pzQwCPcHuE4wjx~Y}{y%?iiXYe{J|uh*8el<4C|x z%HMdQ$P8?RwKCV`wcm!|bWw%PYY3-~O~ySTFB_2Ck+?LPtFE_Hzpo$rc@@)q7W%#= z!jnVSuMwcDJvTc9^3$!6FHnoyOYNuu+C|>3QC2XH8$?p_+G_yq24yL?j8z~+yh=L~ zRFi4+2bvMfl(tkt;cP#`Fl<{lKb2u~H+R^Dbo<#NP;#CqIy-FudFWw={5jlm%MvhZ zA%cvsr}VS_$BEzx`aCpTA42p;Bc6R|hpjP8cv+^}Qi!hX=kbX54k7NV>-~uoN&J-2+gM`5qFAkqLHL)$>IXb)2rYqk2_)tZ?xb79p6eNu5&l^;XPMY+aO?+@w7_9?J)PeV<8$1Zai*%9qVqM-himr zsw`Rje^P0TibPBoad+hkes;1$h$ihvSMLnUu4f=Izw;#1Oe$&XRq~;Dwa(9uQ@?E1 zoLqX(`HNtXixLBpqg6+$4v~P)#e`3xMQDUjc)OzdcgJ+ARk_yn_jquxFTKL<@x_Nq zC1Y43_fgpwn8GRxNDv?9$TRX_*MmOA7zky=bIeo9N-pE%Q(^Chuf>CFvgOV7|Gj^TsP7A?K;CJ13FdZ0yL2c6)b#4{QtQMV8#G%K-5E!E*m-@C)1Gd$s-ad(*WNCvijT*y^yfplJe)ghGLdISwLqzypkq>3BAR+v(`luj43!*-e=b z#`X3SLGhPbm0dCzrADT&oY%4rPYo!!CA_%peJRpSM)6odwIveVOdif+EoKKM3u&no zRW^^iBWLpPwJvx)AS2R$1?fMYbqvFENhMPbhP3eoEgdWEi2ihCZi*1V60!as-&l4} z&fg*buC*fN-i{t`W{<7q^Vsuw*o!iCh)L;bjPwKook&voT^t`$4m^+N%2L-Px-5J9 z<0nw(FwqoJ>`cF#Xep(p?yXh#Cy1g%zRD#MG}tDj_g&bp(51fBJ6Y_hT-iUvbFI@u z@x|}O8Bg*u=DE{?tr!DCs-~h&a_uvGl(XriZFZAIEz;Y*lNLSS?sM0BLOIJ6_t1?t zY8r3&nNTa^8h2Q-wW^Z+0kG}FKBEZOPxmY#QaGSt0lQOBGL-LJ?zmGd5Scx!Ylyc! zCGW5r=L%RRF2-|q@VtS$^W0uDi~0TLik$i5wQ`cA^Vf1fpk3gD*kvk(E`%onE&O^r z$g3%FZ%aH|LSTqTCOEtYT4eb zBUkG+FZ=r_=T492u>eW0V3794);f?Ftt;noNVTrnvvDje(47*$hfVrOxq4S%Sd<3k zW})~G8^bT`$87LavA;X2XV)&)^DRLe_AR~tn~S%5re(~XW+=9f0@#3;W039$s4FNB z2#vY!I?nG%2=?2i6jq5YF_pCC;gy(LyP>@sD~}UH69uii4t*e=5dLQJ0AHFvp5W^8 z*kuX3X;K66!aC-lBKkEQeMCOw7Mb0nYBeI;9s6d3dD2+q+dv}Yh>HZu8og<7u+Js< z{LNcgpJfc5zf;&3b={+i8jt=l3rM(mqmmvf{qC$6FB`Xfx8G$S@}_6lHP!J}TUSsc zI{j@qZW5XuH{O#9HI#Kdu{HQtC5mqguCoM1VJKH1cRo6jqTyC;Lee})aAHiPWn2p{ zytQGMUo!37a~fBcUo*LP-~FiBsr(8TEOkOp%DuVY*=yUq!2C(s=>IP&Q*|+!n z26&s+T)bu4h4`q*9zU7?n7*^*^6Q`qO5(K|IcPkaPZ~EoAs;Nl0Qm0Lq6;#!nim2F z=jol<$>eUE{_>;XJE3wkI>%jsk!>Jz77uVoSo^J=AOez$#T1VIbC>Ql-Ry{5JP@B1 zzR9|V{K|^d$b~Kk0Hr#~$-2Eayk+9F{`?3hr~Em(ahkm6q)S#y)mieu5i4Z(FI&HQ zqTN;N$A_T-!m!zPYYQ&HY0P%1JFk-*)lN02gqm(@JubWIh~k_|XAe-gBf>_WjE-8m zV2^ziuE}NqKE(?s(8n6~2k=ZP8ETHnbrV%-IHxw`|Dp$XDUxj<){jq{h1naUBi|;C z&g-1=Mot-t<;$i9+}_x(HH$1Z86?2A<9-R{nOmjH;tB!Nq=*_#CoFE7b5Dg>!P-A= zlsyy_M-K{FmgxF3L^GGQwX2+KvXL#&cv|66k4dUol$I5W5WcFFY)w(jr_{)+zc8V$ z0Zi{DadgYPH3Xn6*p&x&0%H;i5f$pL!BO1XoCq6`3^RR`q$FvD3axux(KF5kYxC{S z%)_-*^P#n9>7Ycb4=yI2oNrQ@OpVQ{?{OjPlFeE=mH(s7Ue#X78h35c4e2MErK3&P zYpGOKwt6;fMOO`E;{K-2R)>I;8$4G~gdo^2W2k|F?wYNOqw^2xR(rVvI1FpW=>1t-5?=X3NA;}2OP`w66!bT#hwc$ed1`N z#;2}eoc4fZB<1SNV!oe0eiU%0K}t$F)a85AIhPz0j7EYt{Cg@L?)LykjsMO=WS?nq zG9WG6!inPUPH?+Gs5Tga_`A&z2)a(qd%Knl|Cp+7Q&i1`vtT;pVJXh&Q_3gZwb)sk zq9j-3ZPsCc(!Ce{mDemd?V}m}KbOnB+s1Qapj$TutvECoRj5*2mTTN|M?KAqpmS9? ziDVQ|_6SNixgyj_2*tawLjqw)5~a#Da`c?TKpE@S(;v@ikeFo?@q6zcS)wNIWAF^) zL-A5YkPkzb5y;KYP!J)D8Bglb9y5{;DqQr8`Z>7xmck2xA7{{TaG&9W7V{WA=jfCM zL$^hsmG6K>$mi!w6?fD=Z#@PD*5!|X*CiWD=pRo$ft9P-!rG}P+=0ev%q*{m0EsZB zlj3(90BxM7%s6~ax-}3nbW(CIP+Eh}O7M9@gFbDssXU}uh~2at4*phba|LYhV)~Fw zdX(&xS@D%tJ!qQbUNdDBGh)^LDOVc+E!@kR@_o095n(Dcku`kTi6{3&nC^4%x8;2( z(@y1a#hEC(gT|L}htPwpL)`k(114IfjRrI8Z3Hx_oS(|7u5>UrF(be0e^@!5a$kEH zoEYZ)D*z$F0bW3b`!xnl8xlWM=F1a~Ivr^MEIX*l%Q1r7-+CPy>P5SOqEapvT736FY$BxH{^h>%Wz$UK#5{Iwj=Sx{EDTi;pK-YHn|2 z8$((Q{A9BCr}|i{d*Y+LU++=2o*`M}M9?^G;_=4SN(P`_{@k4BQ0~bzA*dTkt7O^e z;~rBYhFA6gZE=r`B)@wEs;+3{U5Jw5-)tW#d)nzZ2U%rqyXdW~fN$8{X+yy)w# z2t=iHR3q7%^uI8}dZnaY=cvGo0+9WtxeEHvf`~TEE73yMQp($m;!24AlX@zOs_6w= z`6fczf}@0SDnq~RvsYuO%fY!pqqE#dcyFx;Eq3hx^;QfsiHe{PP=sXkOniCtBUapO zwF~n@4F|MeD-alQ2z9=&=&Pz<=XF0`Z8c(aU&c7BUze3dqOy_;8M@v}rIYEHfEcq3 z`k>MBHiQQ`$cRnoxH?sb5cRbdFmRXC0K0(u$-);W*`*hp^;qVy8BOj7W*^5hxu}1b zXWBv#y(-oFGaTGF#f?{iW=fO`(*H{bM_dtHfy@|NTlJ=ekOSwZn^csjovX_32=WWB zW)XBZvUg!VVWZcnQXry(Wjl!n94x^%hKS7n7en`Up~N;9(r2@T*sutL>J>81+sy<* zQ{c4ZH3Q-(8Sd?Kh%qt(A_ZpmGZ*~#z;?d9BV;2nx$iH?kxT%|DElSCg6r%J4Sj+g>jgdSEc ztQYQh{fMHz22!dVkyb)uHZRkaSVQ?kT_h)*T_wkUF4)Rh?`}QRlcHG6r9>@% zj_Scw29oX~qHF}kgH>oGARwjvhO6m#d;%qdI-i0Xn**cF5-#|#HGXehMgIrjC> z73r}T_FIrFviB@1429+kr( zZKaAFAczXBXtWS}RCBz|_6?mK(u-MZ>{Jl=A{%)WmibS!wnl=-#2Ds*oG#tx4R`Q= z|14zjDF(zq*f zyr)qacvx@{8s__fAK3t&A`)>)85D1vLJ~fke26<|L?h4fvdmcGXjUgh8%E1X2x2;v zP`(%6!qWvpjhu#6Y(Koq+6^UBNs)F;3pCR~9F}c%K()ZR7;C!T84$fnlgQ14%bP3Y zNSf^MqKdwUK9r&}O7Cj(Fmy&vNFF$e*-44Jxua9;rH{Q;1+L@B5Yx$LpDH+Z;zA$k zNS&X40Do%V0~4&-+M6`@GbW^-@-a7A!cy3)Zz^Uz-Am;<&QmKw;^$J{b?(0D*q^x? z{dVRQHy^uVUoSAJDll{KoYH+o*j|P1`nWMF${rRB@!q(*;G2FWattEvCRDXfQ2e34?j-p(t(MzfiQUdVTr!NNtQk+LH-j$a19n_I>l! zZEt+0Xk^$Y)|Erfx@-VJTMYOgnlk8ANPCAq-8?!j{!cV2COue;NYc*Jr@9)Qd=^DZ#?e5kjC^J*NFYZK~PV^ai+%rch5e%Bj z>Yh3u?=m zs9#>(xjOJNuEjIdNVUQY;poNo zf-ztmYLLa2Ae{kQU}!DS&nI0`WIwY(VunlUy$s(R!y`lyJrFAo(bEy5r(~$! z6kd@d*bi~>E)pwCjA&59h^f37>In@jBmugX4*MyqOXr_{T4z6P$RG=|hClCiL)Pui z&nv6A1$BsL>%8qsL7uxiApy8MThH_H+yTE`m289Fy-5jiiiNv&OSnq=11Q0U7tY^tmxjFIs%fH23+FbQfYZg)En;Fs zO8i`pOhk^(?N3&E#wJ925^ab+BZHd@qIxe$nY9}{^QP6-7JKR?#Hq+RCc7-tNXdx0 zo3-7l6??hO{+?1$c>c1|{gp@Ud&ZM(<3!KVueJ?T1#=PlWnJAl?d|6?c;xKn$9M?Y+k(2-d!&-4!@>Kjy+O9N{B zuINHPXxtilk)iR_#cU57_qHA$DT_3EAR-jGwSKQC+~OedQoma_F*twZ!@AMNFt)EF!dI9#@672k%5hVKEd=y1 zLZ*egxh`a6Dx{ncYFBHHNE0;fw~Mrhg13vMQ_8KA9ke`H0C--g`(>I1t*;g#d4b z37e>K=s>C~2aGHS^4+ShvS~mdeQWFEMx>_$dY7O zTA0mwTPM6wkf1wp#NRd6BVwVI!XHsaEOu`q z&u6dpJV8!0s+=d-{%ntu4O>LyDL%{j*MLU-aiox3nAHG7kd+CA=PST((pu9g5AtoH zkk|r9t?wfR1D-zhR3>Sr6+uB5lY#7Qe%4HHEuOuJwjv!9O(=top|o%LGdL^zjrpIC z!`O)JKbC(G+pC5gFx}S&9jq0n*d%NbH5AocZmEG7^eTTiZ$yPDAVs)t++~Z}R=7Ic z`H0~<(k0e)_Wl)(amVDx-)?ajx`lWiO)gBAmOy2$vUx)KNq<15qdT8Ci{%<}!bmCB zSWmBP_shFd8U|yL-P_zv1%#XE%A|tek}O#Xm!c&w0Nnssh@^n}{U@p6Zj&Rm5v{6y ztl8cmat(NUz@Foc!3D%l{G)U%(eHMy5cc4@FTX?0hAw4I0I{~|aNnM0}(X5$?c zAxNFcvJ@W(CgP(r^)QFBwPdWva?g|J%e)yv$&W7d@hw`UG5En?SxW_+rdyGWHAcbj zUEB0p&0N;nw4}(a5}=j^)%fmKML0xGFhQNs&`{01dT6^^5()UML1}d_`S)%dPZMm8 zmaLbd;%Ahcp(7@sO~6m;~8pvKm_FE=F#ocXiCR z^QBo0JAgrZv|3`WK^stkXX)?0m;EQ=6nZq61Yap%Q9I3_fNgxVYU z3hqaIc+c_-&%fre^3!-lI8Dzfd-kDKHPKI8q+YKZaXhX!g&)}SI=A!*On_VT7~GWH zB62BL#Q;I0yJR5&8#joA-5g8HJ^PNHd>3U9Gn^MI>^2@IFnsnGi+v^IaKyJ3_~ow= z5bahwIEYyD4;4h}Pn%0NuXZLzopbdwHx#PIDq){ z1q?k5AcH3Am!9Az)*7|7%yq#mK74;=e>%_HYGxjVOFLEO!x`qO>Pbs3>E)fpmW|I2* z6=CRPSOAr0GZ7_uJCo&BVhV$SBx0rIiOr=R#od z;kLN(MZ3uB;R98Z!7z7|hV|!Bx~CQ8A2(n`)s%T2-d6Ne(F5gL_Td_?2$i4sCm38? zW-oe!amuTv@8@)3o$nr&-^TJIm|<(u`W-O7MZFyumyk}_@2SK2OhXDUxv$V>oISiL z=Zh0)@5)&g*O1NIRl7G4+Gl}=ATe$c+B3#R3WjhaXnUeO8^ByM-Xk!UUYu!!hbp>C zRYuR__Be>iog7)3z}6gW*)K(g2)>1jbg%YBd%hfgN2l;j!Dy$dwbu{_MhdMN3j=8}%0b(~+5 z#&~|7KQFwV@R5LkkYX*3)u^qSXuwrp_JP>O2vPBrs`<{zabZugM7E< zA<3S#5qgBtSLw?Q9x~lRP9xK@v5lc2!LZWXbPkYcI?aw9b+ZaShv=}PDYkWBJ^5i! z_e`)yU~I=YYQZywD^veo-oMM7Svmba6wgDTren`0X67jZI>sw~TQhdRgTM$!d>Orou zL%R8k=BF-dT=0YRnCVSLdbX zvt@jj+1aB`l-D>1VAjTtCc6h*vLPY6lC{Cq8CSrsq81ZURzBwTx#S2Ef1f8TN;19J z+(OpSOtCYgS`C34WY9%d&j3v`i4!E!KQS823X!lVR%8M72B8kBY%yFt4xI`&v*Ej! zo?#-C0fdi0Y&AG`6?;_UH$~wp36r48L!d{ds{<4kF2mq)x z?OL#mIK*xWlZ5rYxir|lOD|BTS!~Th61@`!H91URu$y!oBOv)HasUs-J3N4mXh3bEtrKD$v=zbacK+V=a_9yN@UUBKicAO!7zT~(-pDWGQH4ky zG|IO$xb*$!0wlIx(n@PFSg7u^ZyNz#3}M?6HP{wZvE-xze83aaHd5*o%S zf$EdpBW{#eYfeL28#GmN$F1*&tZRmxgH%td2ICx$=K&bm*7q^0XksQA-1OK@(K*X{ zDx4p&JAi>nXcGb$6L4A55C*S7yV1$Y_J_93l)$VlqKj*&ZEwR zo$!4lP92+B+Ixgx-V?oG54#E8!hmR=nc6DvDq|j-SPqV^d`yT3Uplk~W*EY?d$<^l!>u6YYX0g9VLDT4+y$v9 zC&>5MFq_>0&4W<)g`1z+wX>&oRf3R}b?Ia<0pgb|n1nU-L-R@TSf|FQ|3<&~K-IG8xis}pbnqL=#!`b3_yK9|L z7O_vnzg@3z>0efxcZ{jQl3LH<+m{Mo@C2X-SP`<$8P}YYoZGrHMn?MB{roM&C%rl# zhg=Zlbseic(zjJomBd;KbbkV60{2cPL#aWQ=0J7p78*nWKl{H)HQ(sO^O4hICrCEa z+`&x%uA{0<$i z6B{u}H9za#$6qk+6eBM6fFV_7SSz}tYeDL{8(Aogt=ImBCZ~I^cDXy?MXvS(}bHtKB|fjO3Yl1 z>{g_SCR9wM=u_Wbz&Xz`+LW54vjW>CsOSm14h?!MQL$WobkIKz9v)3~_ohmilE5a^ zew$6{j0m=`bf|t($*thpE>8y|C)=s-)hR7bx~3ScR!ybXIIAvu^~=st7LqB)-b=%Y zx(Xc~IwQ(2|Kok~*Q|`z5B=_Ibaz1Q3_oYuf!Pf7>Fbpytd=0bl$VAM0GE-t-u0l| zAKzZ-NE-_p_o4!3fF1o?G3cv~cV2b5<3^uQYmj6IoSaLHwDJ5ZTB{66;DentXFOJg z^kVc)u_w*^!dM&Ch$~4aa;S$XoJe=P#upf>_|W7|GCwZ^AifN8+`>O_UKezCX+D0M zjw;Ig;AA57ithyx*8VI;nk!p)Fa}O}TWYLJB`_v)ChC7v`}oT>zipo3j|r=Po5!1=P<5P~kxet?Ero;0__yAl1&+Qydwe$B z-EQ^cjqO-17UMCivxJM#LG-ame!6?X>1zttYsm#~Ql4o*N17iI&`XrAY+2Pc#>sRcG0 z3-38#R@w_(A}Tq<^%jW!O*`AG5*1+?H_?EatdHaWYty90qs#s)hYHamTN>39JMpNDVdzQehzm~%h1Zd$%P^=QE@`t~%_ zVht9=Yznjda#$5*tm6=N?x>J{NCXVTF18V4J&V<{I#3KpbvOG>&gnUnG1I&Nm6C6lAXeLS0K&;@o<0&H}tXY#3&WU*x z6#hMM`eYO$-zvuZ?xnUQ0Be^Gmqh9RVyj$WTOds)oOeMStJO zPalH>8QGf^{YS}X#7o^6qbo>_Bl{G@#`?z_!##%e^czV6o_&Pw2)($vi9I6;KKiNa z6%G%xz6xbjDT}>-g5M#V^!Kk4U2vHD8Dudx;i|bdv zh{7ntUX;=q%W(#&7vzScs>2q)qkxJr${@YEN{Fk*=z< ze@sq1iMbPQtvU0Qc&)BbsI2FgczeHl#dH-MXTY0lY2&4VBIvfvQWiKQXb*H}kvcP< z{^mmB2t+R(t}MozU{$~+O*dKazun~|pYet8I+}K$B_OSZL=${rBROh6aX_fU;IZnYwP>$7rUU97kxChxxEVx$8uEw-3ld^53jm&5 zCAuF0XNndEq|{iQ<^s{q4}Y;Ia-mV?dqsmbD%2@6M@_JqM;N=MTB4S|T?d3tdI1!-CUB|C#k-e2%)ld*geJ{|FT2HEw|FPj zrM4=E2`6B2N3TlnR6I;Y)6NX0mB+K%Y$jE=i!+#(AAX2b`)PYYs)_Hf!t3;d$I?M6Js|;r0Gkov+Di>C)zI; z+w&^KuI&nv#=6USk-4&mD42zC|L!L_@b`cQWjQ^rLJ|mmMFqI!X z((61iUW23X-{I0)b-QjHiEF#%bVYojSf4ufL@F^+e7@r3at!s|3ZS( zs4Os$tlt;?oOsADqkXQ$VGf#}?-JJ!gCx{WPOr$XG`KeIDaBt6eY0dTja5^xngWaByQ||#l~nj2QE-swm0}eadU)hxL2oX zO*+4;-oT}PTyhS!FU}TC@`p;)b=ju#JF>dfXt<)TV>hQQGJb-kr!PRhW6TXEtWWA! zI0G*mz~4IIdb0G17b#~i-kHa+RSqBtlxEDh7_GUB__;Z9)w^e;qya@_7-TX<@JaT)!ITGn<)3+@i_#XC|ep+F_ZWzCcfo?-+wdpjRq94&ePeWeC zoPbm+hmb+?bRXtFsvtw5vht9!l?}5S1?iVO2_EmWn~2(EY0?}SOGXR}7SE!BumVh` zl40KGFpf%dF{=!6_73u*;0}S5*Tn%rM0Kxx06onvyd1W+)ZeiZ<{DVjDMQ;DJkmQa!N{`u{C`RB02lU@o zjzWe}U1xBY%JGmG5@)Q!G$eU+go?x=iH+~~nX$vn*gN*i@`DJZSC93IG}2OkOLW%p zJM5P$)u33muN8WkybdqB{Q@1 zO?jII6|wWkYYhD?jyL;P;p41m!0M6Tr+&&OhHWi8T54G1h%SgTLUO5+#i@90;_7D< zeNN}-$}K(v?UVI+=&JG!H-Iqswm)(9Jsk@;&_$r@VJ1B@{X2&%uh+hs`NS;XmMaZi zyHLDdzoW+fVl@&f_do*zPWRMN#m@knJC2V34O4>~krB_%`0WY*OXRdkbB=rE1)MI7?_9quDVN^ zx!pehH=p%hGObc4uPTyqHx{8u!1H`@V;OXY>1WO}x^?DS?Jd9hLrsz0>&Mgg>HaF0 z<;t|_=qQ0GwqH+_j+G$or{!w66}%`6;pS6dcTU z0TG`mY~ibIDi{wmWGpOh4E|87g=n zuCwO&SHiSQg#k-XS}hL%Rr=@k^57PpTNK7Qz7z~sxn|9ghi>+ohsL$)GNtn*03cQq38 zM5P~y;G&=~UaWovxWh^=#SUe8l$otvnGjg*#J3<&6}&=&-`k^jsHt*2PqqX%~0^3CgYyI@q1q+-6OLB zHU+cI)N7MP#vLOe)!vi1*_P3ev{C)~FSb6QzPRbl0&x3=3$k!(x}0rOyE$4Yngl%x zE!VcQ)=9qoBQn0#;=qVn9SyCPQ_tzq1ph`_#SDKLFeYLJ>D`BaTi`Tt)~%obZnZra zt6YU?eHmVq(>&V|T1(=4AgSL7bs)&O^|!-nSM21}*JK}H+m)Qda{x-A0~18nJinIV z1APr7w!^_pO-lGqC%5J#TiZSa2lh*0z~TgwKk zr8o)p-tS?zz4=~XrRC8eDPW;T@LT| zDBGgu)?$EBH(juBSuiH(aL{o-$%-B*7sW5N5CggXG7kFuk1TS0M=&wr#j?0pULpB7 zZv0+t&$yVNA{VPVy2qyBrkwlMVq|)0Yl?O%V=|c2dRb}5FjiB)?pd5~KDb~=R zE~o1HHP|0v*tjMvz|(K0MQY^^ctXWz;18eFpE_|{t?%*lp}yboPAlmDzWzG@+N~ub zFb8SdKFY_y7-y5VLaAT`&Z_UApzA-7wdM;fl>s^c_>VYI*$zWabHzgKi=phmE1OAU z`~>-rtq=2Mr6+(jz535%<8mBwb8^|?OEj+ zB4*l?Fs$>NK9btAHT=8U@eXd*MMvfHkOz?`O@t7g-8v;IXt=qBM1Dz@`C}HBTtnfC zRQZS^&zJo^K+i~KgK~A{UxOWeslLUX%KLz+N8c6F8nYc3P>FXY)a-ic9v3#Gn)Vp$ zE}JWHEk#yX1RbyI8ci(k5k9&|@BW$r^lR=FH&!vwE{sq=Ro z{%-q`ZWd*sR8uXRAK6~LkA7XV z5ZlbeiI>XY!#l;_wLK5j#{Pt455;rP-K_eUxZ{XUpUsnsng&UXlGZg*c3~1;ciEBe zXksAU6rt8?GW1EMg4Na;$;csn(V%VDfNdwRim)9c_2^oAtC(w&40y{{&Vos2@whPE zq?QR84&TIqHswJ!8#m8iOjEm{{loW6=0j)Y8S%+gYX- zYKd?1%EmaID8^}YH!Az&Gbs4T-FGqnOW9NH1}n%2`#(u-#k}xrj-t2sW_4X?s1nb`Pl<(Q31W9R zV`CQrF$2^r&e$I~^jd>e{)mQyUKFlL$Vc@>LEL}mP>qsC<0-*zG+@cxLL3-jOS zvp@fRJ%g+eeG9DJh7LeRXc#!yBf}TS zQK37RXs;d?NfWqcxt_;uSEWJ}C(4e?&6ogH&WPUBn%Vn7=gS~C3TDF)VQka!(a_|y z#c^MrN?o@uufdrpj^!~dE(*qMB;}DNC6)S!&MupZc1Zf{6wa*hf@%F4V`8UgeAun| zXl0V+9$ft@at9=~LiyI6nM^_(ZuZ=y$)}2s@-;I>M|ttk zbXjts>Mg+{i%Stb(QqJqkxwvmjyJgvn*B+66-Ua8hjA81DunVBT zn_-#%dgwiejE>INGBW9BTqgTIejCZOrZbxcGr5>7`!O=;qN-ZA?^)2(@bsfNm^$zo zcS$uU7i(yV`;P5#_KrvsCi*PgfY+ypy2a0yaU@b=yFOFn zW2%v+;nr7yDI>U~e>5(&u4NI_?IEfT9_{-XE?0BagF z+=dZZI8>CbMD2R+gN8m7m-6sGX@=3kA)ClceqI!m_LBp#<=skNfJn$r+k1vtSE^ll zkkndcvjCbLC-OX?8{TTvr0QX%dhEUR8g+y@iKCO5=XX)-Y2MbYIg>om5LV;H7~B0( zP%RbalQK!wKrET*o$N-1V|rN}3Q8oYirD=H5_%o1KK>vh`jDg>R#8-J&PfM#CFJtk zO7GQnCk1)mY~#ubDqNdR&AC*j^{V9xDIWs6&28h7WxpYe-psj7=)?w%YF(lSpQ)b= zK76y*pZrFq^#!K)B!(cH^pEczIj1dH3R8+V=WsTppRlISm;#SBNJZ(H30+~w3?n(n zN4=DbvAYt1Q$pV!)EnZL&iXSV%KN&CQZ&=^=l2bCF>~_HENMN$LenF>q#Mk8lh*1p zu-Tj5Cy26X&OQRweak_={?7V#Aoo#>IeW<^sQb$dEegGegEc>Y&z!MhIqSE$T0kH7 znC2h#QP!>LC%2FuQ66_ogt+0mZpE_h|{mYe+-xJ15| zomGX7tS~Y=0UwwtYDWKo9_ymkQr|E8>^+{ZA|92o3;DB%Bz6rCadODgai$az*DEnw zIkq>}vTu3dO)diLqHI30J!g{kamOTw`Q^N;p<4_mfyC#yR8d)w%G>{rAE72bNY{P> z7xAFV@s*w%H)5jS*(a)@zcK)0x$j%zeX}C^k1ZQ=Cl|gB@->JB(0kyvzfk9!pVjbw z#GZlp^$0CG`ZB-61(<}Lnqe3jqX!de^WaREw`v|V#r3*R4CiR_SaYD?5m1Q-(rWj7 zEj|wcDf=~Nz$&dc(2o_ZecX{7=*qHv?&NTr-PZtG81ZshH_q2<1lcB7KydHSY#N<5 z`!eQTZKEoOK^<`IR3AaR^1l_{X`3Y^Gygyi$R6bBqc;r#=9^{H<2&^BmbnMo47ql(ID#j&HTEC#E4UXH*J$SD{W<})>VjyW{v zszot<4Gnf-KC}}ykhrXnG(opiN$DA|556141gUZP)%vK8@TVf<_Cy_UUhXCC@?udU zle9`=9UK#TGvcH?p}}maq1sJXR%6UaZw$I0_22E;E*%FPx3a`{$w;G%B%^PT$j*YO zoc9m^sNx1@awuxIz}u^*ZeDPkV%-X+{a|eD-}&>YI>TeXp}ZrY4{$IJ_u#H zV(u{F{oK(1j!8ah*`}Ra!jCUPAb~7gQ;tI=3N4|VAoo}xkcabH&T`s~h)_*Nbh*8K zre2)JB9U`v-u)BJ1BQ6fX%*GFcmkmAA=WQ!;I@frM%`}4{LtE`D{C6!1IBJ^J-{A1 zJqF#d82y1t-nXR;B|iBzd`W<$&YOJ3?$YFuh)Tl)_cQNvB2cVqt*=518Z_ocD@T;( z6k*B(_!?10d(*3;;SYr||@3cDi&tF>Oj%wO+9!AB2n6-RRcpvXiWr>$!p3;=8M9ECYVeJw>6n(uekb(X0YlbeojF?rcYeb+0sVJx!4ywEw`ZKO43-=1d9(S`>b96+a zuh@t-k>EeMN=xGwMH>Tgm$6yu1Z>H3&$)iq&_cBB`|N&XW|#>NVkZ0|B*=Jk#uT#rXbz<^|80L*l=TjVRLY|R&??j*&Z`}e_Cd%E4fLt$qA+?hmzL#oW=#y$3!8M=f63YZjx%CWZpH=g+61W1`O%rDU*O<(k zjE>Pd7$i{-2XEvs_jp|mrXlo0&HY-Cl+V8d?lSPf-2qhEEx-@jlZW@t-+@K8;fTev zQLqQ<0TtB`~;LH=AG3<7XE-h#GlQ)c9n))_jO6fFUQuwUxhAkPzYStTIRub-x zjY*@`!E%!$;sQpox-&FxjLNh*sOeC@0P%@8nb1rhc@YgMlZ$aEn4$jKF_-;!&7#$^ z624`briZLD1-^o@BH7GRY{Q9S(=IST4YSbFZh!1z(i?Qq5mI$N+Jv+x@A5i7JpOT` z51gDkygHNrD?cFpM~xj}V!A=p;RyoA?ckc+S#i~XI8JhLF&L$Ik*KIUzrYvRZ3$zu zulTGi7JX2%*pvyS2X!KWchn%Tby%C~JvmUuK5nN{Fd7=fZ;)Bo6 zHy}%kPYtxxMwpP$>A$@XFiJJ+DQc;zwM<%`9Y}HQOI!P1*SdiLBF1)lijZ5l;1sgO znp_q-HhttFZXA>?poe#_R~oQsm1%|Si<^J#dkNOVB6Z#APNy5A4#+Yu3^)&y=$kBC zfWvMcT9(W`@by-iyuk5-=Z*H(T_*s@Jk^oKSYk6HRrPnN!#1 zkOvLi)Vg)+-CotU`Fk45I-b9yQ@GnI%$TAmNn>*tv$QA;Zd4Mj5?M%J#WixwN6NU^ zRz9G(b>?(<2Q2jCg2VJ#LE&6}LpsbhvZw*(0>+@Z($HiQY8YZ$r}H;%0=L!m$`uT9 z6lv8_;xP@+U+3}$ezzNx8c!5aUL$s!BT`5zV#~Ty{nF}O5JZrO+rH+tVH(JznjvH& zr?I1C`BrX-_G}Kx{Ug9q=&ha`V8*Qaz#_b<4?Zkv=fGXggddqoCh!cen{FvbkCG1h-iZT zc6MU4TJJl(ugRYR{Q<#$Mt+0}MOf2>WCw|{yZ7^QDQ}N|Pd_A(6PA}M)gMOq*!Zr< zIb3)+ED#aql!`QSaiZD_hHfgVdwnV5QyCHtHG(Ww#-ByQ zmI;v)-jI>@!Oa{Nwl+fHaB;w=&a?K(uF7(EnIT6*ufw)@>75$}fvu+`S#4@*7dRxq z1mFWQm9RTGw?>YsR%dxM+J%`0wj8bprrvFEFC4KYvsIJPDAthO3H7MivU#gTZ@ME- z@K2SnI4M^HV&2&1zqSmlBw0_AC?nPkOO;-(9QFN5t(ZuCmPk9YLS0Y}iALllH73w+ zsBgA+$OX)!=XMXq_61*K1 z8X?7-EBNBflDY7h4y}|n(?HJvSc&nXLvcZ#P^Ce649t}9;Y!p4i;ufr@((&i0rAO$ zj`{`vmO?^s>O5Yxk4Hnj$qmu!V5)8m$oH=Oy_Xd4qH+OnolGg~(QM6Dw#Hv+TyG&0 z#xrKj>0pbKuUefJKE3#!&KvzP@Aym3f@5=X?Ww)wKaO4vnLc{>?TFfmcu0g-uNgiV zt6}3#54DRGoPH-uJBR;}eZgV2aV;Dh7F>~0??4qGcGdL{Wf~sfctSrsu+!jx8j<#% zrVl0>_`%EP3MV&&=ZC|rR8^x8PG_%7qd{)+umRCRm9C#aI~B{huU!qFI1w0nmf-9Uef)q9I7E}iXX_aTW({;d`@@kAM@=XQbU_T^@vm3f`}E^7OrNJ6OR zTp`blkdgg@C(^OK~~)7K1kMud#vd@q`U`(A%S&)#m!O>S$3xY`ZmSu2-@&^ z7sTDYbbB$o8MvkYnewU z=rUae6ka@r%n>*r>~I*Un6w@;sUuujNfo%V=d_x#{l!r;B!p7Br#bwVN&TTt9D0nm zyA@k$M(F9~tmVyZo!kaLLw3MF21)THkq%KsE^+{xxv42P^5;(de=%X=DcZMyNVO16 zW7wE?vBz(jc6hOnIJf4*>1Q0-Kx#c-uUo1{{v3@LZf7S>!6n(Q20lCM-QGED zf{CUd=R>IuC@v1hWp6T`t$5IyU*P=1+Qb8V-+Syw(1p*E?+ISC;?!CD`ll!COJFHg z+b9V6e+EZR4V61@-4}loVB!oSdZVZ2Y>=wNMp#+uPwpK9Pt)cIR%lC+^`Gzq?D&-O z*8I8tLa}U3HvZRT@tVY5#Gr^dT!rFh<~uc>LMurnxpx|zcc23%+J|%0pg+1{U;F{P zc(mS{FisKV7TPQn>5&5vzoG<}dn7;72h#u##mBH@^RmD)v2?+FOaHsPy3Zj+8Pjfe z!LOLKt<2I7# z$y1)0#=Y_w1^z481jD?1Mdr0tH~)?7Tqv|H#X{6FuiY3=`X~fCJHn&^K25WQx#xJFFuZ5E0oZb?M zyPXb!>skKYqe;G0W|d*_PX0MLFH9N)CZ!rnJwO_xB{a+!Pc-L6HmXcxsSJ(TA2k}} zJqgM&l@%cD6u}HHzFP?(jn5^vqcvBS+3~7mYscMLQ+_`Q z{EzrXnMEtN0mLzJK(kdi#3vBLMGtk#Lvl_C6th+hsFY%}uoKx3zYq(gD_YpMuX9*M zBs9P;Lb`Ini1wF@j7h*8D94Kz%o3Ftl+Lf*pgJj&ue-exR2g%>Gk~^;~_Bw;r?+5B1-chrzKAaF%He`@$ z=o6}kdD*Q9eS}M6hYuWW8m0irIvHOKl$;2^e|!yO>FQ{%1vk^t2JvX%_^ZEsalGth zvYm(TK}-50k+K041E=#TTL&CW+Qr>4Sah?&u0FjDAnf|x14ud1kqjsr~zqX%;5sRF?b(3@Q-HG#7*)S^ZS4TM`!w_rAy*3 z?+4G6yGkD*(LyEnO~2qLoCrm4F^+GOz@9|yyVH^m zA-2|5JB7?E#9sAi?|?NJ?vWcG;8F&$DwUgARdQ;L*MG{3W9yO`n(!fRx#RjQ$`&ql z)C*uVjnGJFHaXvN-eH^Fgq+)&q0G?SO1`QGs8gnq` zj5(f}+e>xM=UDRNOqLwpw?ltiMZ_i%FV=|y_6D5+=`{M1T*4Y&lD;M&F>&S4h+Uqe z$iKDUxSAAJP?J@TX|n(5R{fjH5yhh3H7%=vF>HdNte?B3udb9rJbs}vGP|xtB2LD3 z44>NgRXa6+nnaaaE_j+>BT*`su;%T@;w9n5&#aj!Z4SFM5k*!)59W05HbmD@0{K^khu zM*{4OLRku3EK0=XyvLvplPr*AL(Yv6v?JxlPz%n06pGH%cfJ@j2Kr;R`JBcqfgpjE z6%N=X5bRc=guZIIZGT$iua~yA)|;L0GC7$3NyQ=o+|^5kzC6 zM6U`j$)Lg8?|5$Fb><4jFTD0$T2icS>gS9&+qH|DFuTdDL`5W3lloE`-oxL8r93q@ ztJ-{}M0X%Ou^U;QlT&2Yph70ez>of^!BQLNEjohFZ<6!FhTb4Qa{#w0cSK0?@Mfjq-j z`cI4##`bv10Byg2w?~GY?;@q1sgXi-uAye+PULFH%^owtf-==6oyf5V7I3Y7@x*IZ z!^X0%n=|FLKSwKGG7D1>q(pSt5e}zF7AdUE#w3)6)M?;^@7CxseJtaR5bz&5BWJs& z^?aJ7C5qJ)P0p^*IGSPUIsB?f46@1c)Aj5X%+IeubIO_a+1{MF2OjHQ`zdgg^gV8e z&{e1dNq+%Z8{X{*A?}pzS(&yQeEk{T_hJ0tDa(K4W0t=l5~NoJWf`$(Nwa>Q)cO2 z7Uaps;L>=nCWgIbB`5)%g!^&|f6S@C?Hafdk%sGKp z$tuO~4gqCaGTGzcje#THfaft=%7^mO-E1!lJK7;Wx-3R^#h%Tk1ItaE%45j#Bj~|P z^PP_LK@^6&4i~H^az`cOpJ+GIl%=Tm{`#c zvB35a=nU9GT7D>3VBoqoI0m(?H;{zLm`%*OSVVJemdlZFbyy-|YDq^5BIZdd` z+!4j(QBWtTJr`MCGauKsYQYeWP-S@$s$DDUpJFDQS9a z8bWy}wWs==ki5^yU*XN9bv{u`sN37-nIG8qY7inT2P$XxlCmm%T~fiC?n64;N40mLOXD}9%pjoZUbP* z1`tj)>Aew;t)dwb`3fm>{^2CZapF|+)CwaAZyBepZ$hrg+6b%sY~28qwyPi-1FT*B zYzg{IoPxd!E7IBo2)KJ1@o~gH#O_LROqXS0yYuL-;d&(18d^&o!W&ZliRe zV%L}8k#{g_uHjhn!YgmK=odJOk`n`Q^=0(H`c=P{bPo3;JsN&5@8nZR&>$K5@SE9? zh8;zF^*HBdEuVM(Qz2BH1bKy$|Lm~|ndv&NXfvJr=hw){;P==Jz5O3xoHlLgy--Ca zb@cSdZVNLlIG}E@bZS%9rDGqCWb%GfjwRsTjeiwF+}U^L14tacoqz>i>rv}Mj0X*U z1Q6ns12^>1ccI;j&MCaszt69vbJ8serIpyh`GlQ`0#DQe3N5T2&2&k&t2X@gR|&Wp zo^K~(iNkKlP2Qw0=JSU2&2dkQPz2}wfKBl7~HaImW8IVB8^3B z^afF<*(ZL%kH1}LpYrYAdML0H)BtO&F114WQ=i+oF0^P!djiU6k`ucpMT(&XMS2`{ z^7w6rSsol3fz|!MZ1FWnMTQ=bI1bpgrgCr&Bu~2)?MYgiX#K2*eb$|)Lz9dq?nC21 zx8y5NdgWt;cNT_UnHu%9tu^HX?Bkz*5Ad*6!8*my(CTGXppH6+081$=(gmE_GIF8R zKHOta2VqSb^-q>VS6-MY#AN4wJo7ysP}v@h3z3D(%^a?f>>3!4uDXZ)!Q~$fb9=ld zAh!2R+6Op?^oELc^-RiOLQZbuX$N;e?z{&kLUY&H;%WCpV6 z*vF&UIeA(<{}nFwV4YoYjkNfrMw%D-{VjWn@QQdB{cLE^IFcdjh zNbfPn6mms(zG-iVuQsFO*>i{?m~#ax4}s{-Z-wHVJ)2icR(GYbFs}aTaR~~Ivq79B zR;vFQ+E9pN^_ZlhSOCwpchK4K4EyD>w-i<1I?#=55ID&?=^b1XKzT%tfaO>NLPAI% zN%DXaA7EGq?^;)jM_QTPEC=zyP&bm?lBR4;m|6p9Hxb*OcePEb?N>cByah46z^|D6 zlK(XAXx4an_Yc={Q9g)LB3XqHKsTtC&^irDhHt{lNlcWd2Kc1_Nz|cn#n*LYLWrTI z!80*p@N2YbkKF>z$>lx}a0Hq6OWt?l89^_VsW?8P$7ju?xq2nW7&{vW(5X!Q2vi=Y z-^+|8ti=R7kNkg)PPPEzrmelOwO zs#JHs7@E^&O+~Z7o7zc{$MV$;+H`PWv?w^WdT!Af7Y{_QD1ru45YLXrtl5NQw^6>| zL&9kX8Mz=k0BB+wG=7`{*b!XAulnVAvd$}B3y^wFgzT3*@Ei{y{6}{lffJOmNwImU z5D7%$W&+U4W9RzJY$lr>Ko148Zd3z%J~u2;vVSYS#->*Lr$jixbBo47HM#g0qxE*@ zEQ?zVu}SZ1nyN(O!>HUZWpyBExC7KGXCb3DKTs6bgNU~y5XaK&sBV7=;I5Ms$_H3C*iy#3xx_9N*zvWMitoW zNSP;s3#ewuVQWmg%Fs71%6Dt&dk|9$umPUHpu3yc67afRo6>@U-;hxmNgbe(I&6Jj z@qJ_t`=PwB`yi0jd)-n`FBW41fNd4FEacJd6&P}gLAkYWJfip{-BC|8Q=REdg71I8afo6RCAL`}Ba*oO5VByf zR}dbvZwe8!x3{Vq&Dpu*5SiCI$pp>xnvy^Kx(49DdGbx5_<*S%_}ZuoF?H!@-sFAH zqiTa{6{%|v56kpPHb*3-f0i+uTWy zp97cDQR(#+X(*22^Y*hcG}*my^2huPHk>2z&(C~f0imZ{=B~*#rKmn*fX(=l#O~7&II1Rc}pw|Nb$Z-b?wFH+cE}eZyhyKg&w^^Y+ z*=BeoIp>VT%@?Nck#*My-;llA^+0dB0SKZ}igIp@#>cUY2be9)s60kbwEcGEU@^lu zZOlx|Bpj47Xy7Su$;0EUz5c2yU_1hCD>l4aszJW$5u0btO}6afc+$0X9kjVcB@<}V z$l(GOV!LgPHCY&``dZ(Ro7Mf784_-nC-=U!cekm-)x2-Zz2c3>nP~=51_bCwqeoI*^Hc)>s0}N zN_~GP7822FnI^nm*Pshqibbz=QTPLF(u=HW|EvZxUArO_2Y&Ts3&1*Au(XI@34VnE z3XkV2KxF*~_29^F#1cbj36Jtkt5+P{>@s{N9|tU8aPoCt*U7_x@^cEP!)&|Pk#Yr~ zTCO_LF2Sa0K*_%~EepGKTMvEv0qj#1l3MH41)t=molIMq6?a|o;%7coV znP)rga906ka*zo;aQ@(fpdVl$c^9G>iX_rmtIVD0(KrQYq6G*i$nd0Z5_9hQ0BSMr z%*>LHn!3rwxthKb&!IZfl(FyN+ZDsp{eJO`KS^-J%H-!z53~gLaMz^1zjp4nF#-mP zOU*Gh%hND@dN_Wk#eT#|zCi$96T6BuVJGP7sBHe{G%TbkqQbTNxg4>=n zwt8|Rzqa8^kX5rFva7WRHjJA8$KbpcWrg!|3yhe|d~mvQ#&9_2*gEsbUdKjWI3n%h zSNvjF5hlyR;1%Rohk0pmHK(ky^{IDy-U3)nU(};m1$@;i6!PN}C z(GMiC9anzbKOVjuZe;#U%MBl7WP2rjW)27t;a?jFPo;+|6^P;OBFzr~o`^VQ>{{=b z!(^SUx2gaHA}ueNnQp#!jhOn3)99$9@GRJwE=!$jHbo!Y3hJu&r)@z&SCdIb`aZn& zM7q_yu`14tw95xK-XB+ti6ccUN$x40+u}A98fXgDn7@!TL6U8y)W`T8Pe#R2qu9hsMh&hCYNE@r`xC={En+e?8v%VU zZ~Dm0+mt;#Sc%BVK%@@To&;Bi+0+=HZTasAX}z85%OqR+!M{Iu+TK-+@Uknvtqk*p z?AtvD)17rb<82a5K1%(0dPiL(3;Ku->ScS^lVMT!x=7 zX0YdFqkFhJWODH8lRAUiGAi?vR%k=FVLAtX;=kyVRdYf;CU9!sf7iVG=JM8e2tTEb zz2>nLTL>5ys8&SNRH)qa(i!Vyl1#|8a*Cloy3iVsh#L2Y;Y7(owjpkd zNF}9zz5Qr&nH8}ks}=WJHt|j7&CSDN?(IAgxK4IUuagBcui=nlVzkLbb|n6wO}saZ z9@Q#VKGTSYa6OMjjA9v^UgRi^&Y!Jn>p3o2);m^&g)EoPRTI0oo<*9gFtClqdCcHL zeaUds34!6cijSd8D|?sav28nIALAvOHpupE!V>C2#9c3G8}IL?$|V7=h>E*o4X{aO zh!{%wB^)#9%-u%}G+jPVe9Mx-)1QSZQvFW!so>T>`2nj$+%8)&e}ozBO6Z2x*2+UW zg~M4GIEF+kNWv$6L-y+PeD@~vA17S+^6HPA_t&4?Sag-gvmpVN1HG#>Xg7`#?wJ1{ z#A9njX?mHLxcN77ECq8&#u!su^RbQVbL0He85w6s^CJ5ct@XAx|IZpN>AakA=z!%Xe(du9NstbWcy7Ao z6H6|co2ArDni2t6f)s6Ie;i~ZNEAW2FKgjdudtefr}j?Vu8WE55bJU!Sf8inZTCu0 zA<_MkopeveGg5Nt>JxBN!ptD%A8(VAk>GTitHGuCpWg|EyDsKhhs8k<0rj)W1Q1>5 zasEDYAb{@GyJg|-A=x>WvhT5TC%IlB$HU>8jf@^Z_V;&^9(ym;i@VQ?g{}1jx66fe zZb1C;C7Y-KiKgkoV|&AC1T+)QVR;ppn>g0(zi(U&3Yx+vV@p5&TveVRisEt50M(@f(k75aLc%qGxeRsq~vm@DbD4?PRKntX^zpY^rjbp_(b| zZGdcD^s6~`U6cW1;Z;zZLjVs=4H z5d;S4YXtqme+6DU)T^dr9b-*nE(Ks4Kh)-EqW%T%g+jMcPme$!P<-{>1u?mWp>qCT z?+EJACY=}BP2X^3XB;7C;p=I$gLg>7`AYSmZRk@o@`mHiE>A@FtdhUaU$14^nAg-h z_9M;!v3mZ^{;2|R>`~>-zel%rMl1&V-9S)KpA>dP5i|dDgwfB)7QiS#?Bb?$(Lw=&LRh)epyzVX_*Mg?UiHwYIOt?|~PGeqql? zr%zBXi+)u$J!>uQZ?iYTWeluaKSvBgl8DdxMvmNX3Pf;|y=R2)`dP=^zR5gWh!uN0 z6br8HigL1WpKjegeaPzXows3p^Z4C+(Y0avzCVZ~ic!Aps)c{yxF!S4VP)fMvXGH=r!BnlXrRaDy>?f*2sSS3D^G28dsr`EeFh%ZZxf(sz!s%mit z9S&5d=?G9qCP3Obt@r^J3#e(HthjGFRqos8B&G80AZtpO2abs1FL8aWloQH?Pb8<^ zGWkz0Z??my1*i!ZV0`RUIolTPAV=rGJ~qB#JELkwWGPNApV6)^7Eh^1KT({lC;euG z_bK(es3d`TeJwAH(-uh*=C!K%q(DD@gT4}`akuiRC5)SmK4kSV<|uk zn%dK^@C^FhxXT;}1NEV^!QvKs(^fL_^;HD^9=>UI@k$Xk#QaQ_5 z!9>o5=ma_Nadko_JFq5?BK+Yu$bKZjCx)osJYF zUZpX@A+i<1fK)0Wn{UOeLEj8^Td3Nd#L%*dk%{GDH}urQs0{|udvRBA;)Ur8Wo^A; zL*k-MQ)NmI&Y)|_^Ab3hVyVFuq2Qa8X>-k>J4k&eD1Jx>?4yl;ltYv6Ls4=sc)&F*bwW< zvcDPmP9@H!nMYBVtwhsm9hJxq;MZLS{;lvX2NVp5m--JcB!^&J#agv9>kWtu?26_E zj>p^nO1VU@ub(WG2cW_@^3i2%h=3!R7s&;N^x|8{7L#I0gJpihfXNy+k3nl(5%4Cb zKoKhF^24c*tWd4zF8EST`NF8fMcJXg06H0Qu1-1v4^ZSvP+W3e9)r{XPT%ZwQI?kW zml2wg0U}F?a3I4H!EJI>0S}A1S7uU^py?%;KGDb?b^$9QU8DC#23%EHZxET}nRIJb zd4=GpzLb;BEVSf-ktAnSPGdjG=8#Jvi8&IVE=oKuW{eCLgm6J?c_^`3^&3nu?EOGl zpAsi+KwQ6?K1sLjsSNMBe>_cOId~FYd!ENE@_+5tPJ=(o;C#WyHZS$*G&`(O!@kV`@sT#?0S18&~w8>OT>VPdK2tWGd;q!zzN!E)^S0dIXQ1t)Qc@$hk@Rdia zhkqU0@IrnzCCYjeQxgBEHH!P7V0h6X=kI0^=_)7>lQyymJY#iU8Jqvk2Csg@1Q{E7 zqE{f(&g(BQ;a2OSY;5IGG{ol5LN*i&oIEmjj6?lhb!sAP)H18$)@`lob*A$)^*+(tEpapD6u%HTU> zpmwkaSa!)-YaeL!riUOmCD>N{tvoz|`|pg{YM%g(g*67B{O3IqjzMgMO96 zo9>~1NXYb}*f-gVb3<(<17NpNnniU}&W?(!;lUWaRLBWxJvA@V_2;Q5a>&?BZCwKi za#~nf$au9=`u8sOlOw3cP!U}9$e801iTsAWs%YveKSkXnXWu1v3`oYrO0Aq(SWumS zyUWELtVi)j(B1X6;m?oH7MgF<2@HS=70Q(Y8#v!O8-mv2>5+jP@zVEHZ#D|q(}CB| z*}rQ!CukeGo3=qdvPG(IN>%vM*TJ%{lI^=l8;Ayh9v3O86Y-%~Fa5(Uep8c)-(#%-H z>q1&a*n##IV4Z7PX5zRvZOE zR;tLP!tyo_L}6kAP%Oa#X^xc^8>`i{6OedLWjDN<;bpvfLTgjL%GK1FUH-1J(wA3Y zRm_FqJy?ibu$EzNO`~8cgI8&rUBgU-BY?R zPWCIvlX$_WVO;WIRV*7}ri_G@xf5wVj#c&yUG+i{zg!QB+17WT)Lao^FEOAEkZ!fgqknS+IK-~tC&HqHW0BmL!e|IADRp? zu2VEeN(~QCaBYuen&8NK^}xoLKGyrt1%w!iNt|r7-5kLE+F+C3H2CMX5vp7qgbus8 z7n6n|P}8>y_9seg>|zoyiCEWzuQHij9!8_Ra&G6d3h_c0e_r_X0>`Vf_80cP&WO+K z0q6_KqkMz)KxZ&-8+s!q{|7iIMc)Hzxq-aUv8fQWgr!6S>v$qFu$F+4((@MOy0eb> zM}>?J1H!|Lvph~q@wQ9S6_4GHhkW(lx5ETkSX~4JBV`qhqxv#=TQ)=KQ8tlq zDiWl{w#OW$duet$j;Wwu%y}82o(exm2yZ)uD0i6h!1D$~0SvrV#vkb+vWLXxjTgI7 z=b$f$_k%Wr*)JY1#dD!`uz_42;}M&N3}c`B#R2l;VBR)woaJK7j_vL$^JI{k4)ej! zBr6;k9L%~hOB<~8H@m6&+n1+#djWfn+BnjX0bkxyi2til75Q#4b$B(-)Y?RtjVLL9 zAo{?^joGDDQys3Nx0%PUTF)>mjYxoSFAb&*i9kVTvqc@F(-HLmCpPxvag>gzd8lpW zYY|^*18!ofH~mo&V0ZUd>@^oUSL1IW7NiuZ5jL2>tYck+B;dJ}-luK|UyH7T?|_lujwCQ>r>aLgm_Z@N}0yX^G>(d!RBA#~6kv zJ8L*?%P4PD7zUiF@Z7S~SKTqXc3}oP?KTpn@m@1ac*h91Z|Hs(!NQQ2QFY?L**>Z{ z5v(-SOEQje!2oMo)Pg+@!A??iwM=2D27v*SJehhlZNj{GeA=nkWS69b#!yHJ3h)tX zYie}wEsXwi2{w~sA7F%9W}GU=nMnPO0sDYXlE7v7}FOmy0P7mxVQ_bAcg8Z zb3p{@^|VG>zPU_vui`vu^!1cWxwfiylz(6;ULF$IBlMu0ssf)O}uDVa*@=5{5Qp4YR7tiXlUN z){wSxT5-%@OT$k8e!4S91UQcJbo7Hm5@L(1en8rcF9u>4QYj#VS$bLlvN|y|66ss@ z#~%LZt=a&z6&K!<7Q5k0D3opC>71c(0lu`iy9x2s4#4t|fdr~Dc1-ITy-9Mu=>lKP zZS@GvUp3)5PYR?=STKU?5IthHQkEy~f z${wRKzOVF9##X#2iO;RH1U1niQt8zVOITCt>J>l2Vc$whE~%XPPa{vP;q?oJ&N-Q^ zj6hInIOo~Po)n67XyCL#HpK=ZwPi#uaXtSFF%x663Z?LqFd^?nh;QQgSEEW=TA$6g z7V|70Bv1jlWmy%JanRpTjT(=eWclX>L8BDo?fwNxFq$REVBCH$)Z>;-;U2r=`9|UO zK{^beya`P_^qdD15zw=(jU9E;B(i@G(JTe8q0Ny^Ger%JE;jD;%+*E`1#+JS*7!o| z$u#-q>q7=l0!bSI%Q^{sMm=1Wnxi$s#ph!J^H!(3656b6_ResEub)YF*FTAmiszoL zAF5>I{;M8lP6`Ub7~-h8=Uh~Gebw=S zg_p7Id+0H?SF#za{`(ULn_5)?fZWRE$$u)^ zk((9nfwg$TM>5qJ!u&&6l5s8%N!~^`oVr2f=(_?+Gkf~>8uR~nz_xq2E3q;(rYbR0 zPaU{>A$x>$Wb=p<4-19wI{vkLEZ!p**8s!Ew&!w)h_lnq;qMH@_`t?R&t+&yRkq$Bu@;;` zKJ`xH#W`RwNKRbOvDMf|UW!EJcm-!h(Xm)I4w(7l&FU7P(+kU6L|W@?o1^X<2r2a1 zGiXkGzPh^#!-uPYG`Js;7roGUG=WM9*!a=kYkAwn|Cp zYrbAZ6a7j5F$JUS^3RJ{+GgR<4RH$0V8axcW6|TkP1dS$fB`3MSqV6w=kqI$qhXTj zr$|8m!t!Yef<>FPT_xKwy#YtJCVRXLHf@8DpjzB+&-iHYA~!97re+(LLRsa;ow&c- z_QN>P=bWNwd8x2xY_ei%59c+VIUjkoCbYfux49lGgB9gLREemu`YctXxZ64m6`8lgOcO}~xN z%u%QHeD_bM+1Ti_7~bXgptIGU4Tf7s#QtN1bzaYuDV)Zvuu9i&wIxPq5egIGzoY`Q}is#&J82?re!swgCkd+Idpmp`@#?z~6R*%`6qwYm7)F z{{}waQ!0E1aN%;U{~gRf5w8zW;-^aZJ`RcS#|s-7lBc9!R&+*{*2tG{HDad2|snuz^O zCO;IXCC#GcAIT3AOCQvsE!f)C#hws_YQmfGB(n18g8hB zg5TL5gN^;=hZ>uoFg#mc_$?VP?F^S!K|dMX@p~;n&WvI8`OMmzubA^jz%O_`o@g~ z7IrYiHiJ(O&%252@d64M#NU0u_|Jh2-h~y7SJ|x!A~qE-ja5|7;h*5ahly73b~Z2a zvnpWXT4EEanDd)q=0?v?uFFXJoC{(!vNYo{Zr6RZoT(~?WS`4quV>G-@^vnyWz&G+ z4zJ9g&@XnW0ctFO%YN;OSQVrVX>?(1!Loa!(;krUY&ZP+P73=<7T4RQC-t9h1&}V; z>E?f$%mrbr9(3?S)g_JUTTu!8kd(w__gmdLZY%=tEG>s_-&;e+}NDRN#qaLJ@&@PXQhXCiIyGGT^*l#Za5P%SVYY1xNFx-{iq`N>Lzgh9xhEa$xDFy zC;1Z9p>`4kApbxjf-OE^R<)7)%%AI7Wl6;~-{mL>wg3m3^I%k{1R2;?D*}_NY??HI zv#}d%(Up9JYx!I-NkN^vF7N>_-m(atGeUsA2VIrPL1)Pk`Ssz+5CvN4fSPb4J#*bG zhVV4U3gKzdb@pDMk?&CWSN7*@*U7U4K*)h3s25^zMJL) zN?*88Y7-|7Xd&Ka|E@U%e3wLX3A86wv!&J0Dm&lf1`WdaXEYNw1Hu3`{MLi?Igt}w z%%^`EOcv#r19qN)?^3Pz2_?Z^dB^rC@6;(Ym!{F%3qUM!$Z{sTHtC=noJ_>}K$P*U{dy z0InO?O`oSJhx}szsKH)C9(GMNUAat@V42@cbQq!$5O#7kNZGVMem}%O$cyf1czDFX z7N!BjQlb2*$O~rt?6G;0;Jq-6JdY}J5_Tg)042Lu#H@R$H$+_H0~W8nr0<0MHKFiO zoM+)&f1xpK)}d;Vjf0bRUE=8qsvNnFj?`px!YSpaJwX^fkBO|e@M!-}lVd8;uD|2G zl<{&A&S{)ik^T!L9UxwXyo=mE$4XWABVGB`Lhcp7$h1>b(^M{dHVHpDNDj4e_39aj z(Sw%Ff+T5=)v{OSfqjRl=f`6-X-#9uj(330-YH4TX)NYP)l1m*cOQyAWH333yg$AA zAWE2CiY6!V4Gr-uOKd889yXI zPpGp&FN#{ClN+*><`ndVMIlXdwqnN>ao*CbIz0FlD;Xc^!@7+KeOv#hmW zhd3uDRnAs=fr4>M9AQh+mMyuSwOWY%f}(%`x1{7(SW#V8dSg3BwHpXb=P1;t zhLf2VrA1W2HtVm=F-5Xy3k0lUXaS9{i(#_Xmmv7ucVtmEkqz_wYyVka^Xt-qJZPlEClQ4CSa zm;NXPo9(;i58I}@XW2ndZa*G||7$*XNPu&g`kPqb80wK$b7b?d{S_NRq05$F68w+F!OZ0K2N9m-5> zH+Q>%1uot$xwTqL*}wC?=TdrgFB&Y+W;K zi$=-lpsgY`^YakmLnqV1g~e_{t$>Vp-@?0;5bq8HVo*o7x0VRhZ_EI1nPo%QrWBTv zDL8YUEmw6FWvnGR;Hu+h_4Xe&<*%((7fo3YRvy&q^r{&Zu4kI(j*WDGcI0*KNU!8B zW1q}dd%Vr9K%s;!mL%yRB&y@v3BzDxSYr5oTZdnysQS%pF;+2QYQRhdT^qxVD+Vm9DI?Xh84V%i|9@Y2{|fSQD4T=kPEbu39zA{j+?+_c}1Du?17wwTG~mU*4I{uT=c`>2?J zGQP1R34KakI|(dFCH>i#i;04^$b+mFTIrS<(>Q5$xie8tFq2=ZA>d^+V=m7{oRBch zf0eXsWE@@vi#AaXrajJEkE_1wD5U!I6f^0kIq|nep><#2 zCdOh_4-=o=--%;y2Z=6m*7SYT^J)X!?TE|3^qmapH%ZIhkI_a|UE)c=s%>ye$E8e=D;z{o+mtTDc4TSR!5$tmFf`*+-uUZ{EI z0F-?rW+Drd^*DDB>pob*$nMyKU2`2(a4Rw)!nm;R#H*|YKE|H0@Q5iFo@FVATu3+^ zOpsoo(rUO+@UM%x{7X-r9=!|vyt~uSOettYlZzMHUaHk~;WKu&s}SzKT!6u{{wF@a zqRDqQLPEQE7>XlHNUD*2vKR@oXuZMD`DrQf#yFLMFtj~?72?XHV@&WYG1>vGT>*06 z6Kzy}T&C3zhgDsZt%ffTWX~>2gArxF-gB32uq3#kSo-GDZi~0iB^kKz1`^;UW6a)K z7B9rHA|ya^@h;0k^zxhC%5>;IX!8=V2Tl`p@}zmd6qZZBY5HfqbS+of+cvWC;(qy> z7q}E{z;p!DPjHnRi;kv3rfCD~eb>h#g(N%S>uK};H;;j(a0j4X5j(Z8VQKt&NAekV zwWe0W0usS-+Be8v{VW<+RVROwNU~GF8V4)P5Ru&D>Dvx$1n%D-CGr>4Fq@D!w?*Vu z7{IT?fgLA_n@Yh1ZIQ#GZ$qm9e;?{dI)fVr)eAgVb1EsD*fO;`AaQtCYhiOs-3rTK zq|oSrkE~5OH%J))l?OLKcW|HzK=_9Dm*L9nH45!jtv*u0piZG~;Hsc-AU}Wv7UAY8 zjT{cD?B`|MfBmG@p`rVo+G7*?e&IMYKXBkdhr`sh(Lf;W$9{pO!U1yi)KBi)F#uD`S9pQryA^8Rp1c5aNLR0qJ0_rgd zu$0#adVtKTw%R*!Y2BLwOGb=Ln|L1}ik0y|Z5C>&V;3Y-|7}FbOLj1(F zDE!&878|3M*iI`j<##(-^B_x(k9aQ_OThm$L9okJ?QFR>3{&~wgG!n?o<}^_%@T*c zA)K~iF0uHA{R>C^DqB4?Zo|bj*$jNX5!}YyouMY*%%WNBxV3zZ>(v2WKHZBWFm==@ zNw}N!cF~4piaP@6F;RNfFiH6KmJaf65{oOeH-{~x9>y3ap-zSK8n{?iP;I|7gyI3( zwGoYH$j#{S-i@L~<4A*o*q~1K^rlo%@no3VO8L`B22=5UdPOwENZl43epy4HGNjNZ zz%1PzS!<}3hrOwC|Kde%pswVipvNT)1 zcL$&-UKc=dkDYecPYlS%@Wu0l4rZ^XdXQyIF6naWHqz3y=BD-0lbcFNpw5!2+%;TU ziD@~n+jGzvhXxTX?WK@}Yi9@VnwbeTVyLDkd1l4ZZ+7nXl%P!^)EcOv&G#R*NHS8g zwVkya|Lt<4LWnU_4-b)?bQEK1ne0#Uyhf4n8*cs%AZLz7?<-2l-E+3JSpjWf-CWF%LuUeX zxN#RS9wjtmgJ%pbYmTq3Th2)D%SvFX+})s-?V}VTO%;>e8O$f7GQ7lMhPl_SeRS2Z z3#}=ZEPQ>e(&@~m1zV72wI%>?2HdjH^KW6 z3{34b<^a11a_)XD7`gGjDSR72hnV4`p}|*a>tr6FbXr@02CZ2rV}=>xD^u-Ozb1Ee4U6AQ zq%N=`h0ofvSZZu2XUbP)0Cs>Xdx1bDjNdQw29FXi*Z#^fit?cAUMw>kQ^mM)`Y8_K zIGU-RtQZNs*ED*o1W)b0It(_{9DKkQTo5TBD)$;d0uamy4`-1wusS_|Ue*4JzO=k3 zk9kng9<4vY>Q%N&g~uis{p^XE$dGGb9OLZm5&6yE5M3PFsr-8=WiZ>p0*xGh-8QpC zO*|UScgx&rd!(u*lrsKKzD7?sQ%aX8L1LGmqTiH?Mo=yT_#;7`XkaoG{*s{%0Ba83 z<^;O;(}cBSYYAUC&&p$R6pi+rLW=_uJf$=t3fm>9T$QOLPpwS)1kQ3)NsVn4^IVg7 z1shO+>@oxiSDULyJ*dxJgwb)K0sk39)`SY&0B**H;5~G1TpRbSK_sAO74N0CE1sR# z2rPGTQY;1e!&dRSRnyeGkPj8IQ5ASpp-Lq(;&}RT%Qj<4qt?vEC*dv>k4`B} zNh2b+ykER5`WPV$C_&PBFu-($EE21HE|Lt1N(X)h1)hX9&4m{w2i}Vl&&A93 zip}xKh)iFTfRbONuWoEMZ&EVbb(IDrWBqJG`^D0{ZZ*-H|X*ye2zwj{~LhB3M*^r6TpC1|Vfvlpr*j0YLl6BZ9I zO>vpHYdIZ1d8K2=EM%a|2LTCeFWjUrxUqQDIb|2Sw zE--+C@gD-2`%ufFyTg%C+*?rvh%p?$Te)sX1kUwDSLSOHQCVOBv_BvK;R!5Xt}8x> zbLmLB9y7gFvUO#p-?AL8coN;;0x>pC(gg>*h6>M1jX0KY7 zZUTJ9Z@T9VK?HDW7Fvn4!mVRV@U00!@41J{)&tdn8s8=ru9mO7k$zx+^*m~pBGE=V zUdS0!xs=3H@RC1%Gh`aJ)im*2Ka=vA!!tSDkaN-l?ukd43rXq}>>#hf<{~y)Cr!T> z+PhS_?Lkx~onzA*e@qv6cuNu}?A}9C%j8Fotc0}ms_iD=Y1Pd`u|cJy%~k4p~0prpq}LM zRGAoZm6s7?Buejg4Y0V>I>xB5y8Zg6WI)gC_s~oC1ZmxjWe0E>YB}LB-t=_3FRWK{ zM+fz=WY*3PI^Kg|5v5*o=cTyIb%zB;|5^gG`bbb)GC+Gh*(*?7DGTpEOhj#18e}MT zvNU25xP-mrJjxu#Hsops&nx1VG@|9=H_zIx!ig>#t4e9r)lNv{ZGjoBzAA@h5p=gE zIC&(JPSABZp2HHtHNven+o80%T(^{fPYJ=3{&%^-fiFJrSM1O8A48L?o6XK%miLp_)rKB{LiLzke~p1$Dk2Lpj6 z?2@r8YfO_`xNDjZO~Mt6Vckg9A5!+>bO^-b1y29;yqP6<4yfe^ze2P*;EMpST|2aP=dVZg!Kxwr?*L*>~YMWy*g#9a+)qq zNr&zbt1-w*5L|t$kEGueX7#nr1pRmb6lL8{jqUFqd-++q-y-TcVTJ~24|Pk9^?)8kD7qF>g=z%gvhxli`zjxp$LSTgJGlkfx- zCbvhxyPj>A7`J!Q2el33dkB46CMIw9%iG8KN82=ofk6>}OL5bI$^|BFNj1YQkAnmi zTo(;$NCtfqj-^v-Bks@I0(7g=`iQPOTOk*0ccqIS9;VMd(t%}k*EAV_Ibst5QfwJ-;Hg>^hLvHjriAt@0Kw{%nwCHZ+sSZOIC-4^}8q$j_w><&U zl|{Tb2@82KN#5ukkZ&OR$YCP>lR%dXLfBY;4b(i zQ2AkOax4rD?_X8!OT`{F5hW>_q%NsIA!mgX9@YDPYo7!{0VlURR|azU*posi5vT@t zOs{XPP{*4~01vN3^%xlVum!`p!*xa57<&oZc-r8-{tO zSw?U#0AGH%V!kwHV9?*{Z!g=kELxWO@MYOEfmULA440cx^?`W*`Qy%7wdN^(nolTS z*QlHxUG5=q624PwFYXY~vMw%dSg;)?Cpu~*`+%)Nh0|4{-^J=WEIZT%zn1Q_sL|jGXx8w=QuS?4<`;o zarr-V;AJ&=fLjv68O2Z*CXRfU(s%@2Cz0Lec%B~9C7&abP{C*!vI@LYHANLPl&xvo z&bJJY$xJrh-10E!xPOp_oBPsIbug%eeUFlkwKFfu#Ul97zx%<80^A`T+_%}kLsKF< z?B~s!WyZXht(&2MJP-b1XbPzlQZfu93qm`JYFQmxKuO zgx1M<6v~kRwPW4(t*_Bsyl#@GfZ-cJGF*QjJc zKlrf-DK6pmoidr{gmT;`Jlw@XV=gAJHft=9dj9uEhw1eh*vris!CkM@KZFFthJO3K ziOVO0&m1PTinr!q7QOieTH3FPC_`R$0$@SNVIHmjHJhWKG`Ca#;Xq3ZX)DTPPA=@c z%m_-aiy6kMgi=3DwoWp1wv5u0#f=VcBanOQ@$gtqI4_(fSOP&-ZAaQ28z##`($7^6 zyhUGGL$v8nl^XkZP)ZFQUgJ zTC?^V!M-_OxXNhm*`G1jUXDFSsBF-VF5h~po!LEmO~`Ib;{n^_mO6BWqBQ>3l; z7le2JhVX15Gx6FuO&<5C!zU%fh_ROrq~_a|L|s&Wo|XtE(R z3b(vm_OtpHsgCNdw>_XJD@FWyokrP*ErBh5z>RfXA8nW0fZyQq=$Ko3YzqfL{;164 zqB$;&gFjd_SLQ)N2`g)x)ujtj1hc}xH^Jh_9%TeOqRt`ZJG=vR*wBF{lBT^n9MJ10~0j|IUFTU%P&Xmvfk4%r7 zN{~jTshAMR`AipKDx%}Qn$hybHTU@a0lyOxlI!oB*@e%z7GzBhQI3YDtVr^p@a9UlKrJ}Yd1MJg9Z;xiE*P_6o?*dMuBu;9CSaKJ!- zzx@bD=eh24=9%LGV)1qWgNpM{-+S7 zC6pUoOUmfTRG;M(DRrE>;X1l-?o6d2Kp4Lz^g(&d_#H0&gGNHRu+lj4{4p0{%DU^j z@y61b>?pIu!*;u&%SHRz`zn(wU+MFWc}lBDFC+hC@d^gU)fQc{ur!@PYCS)lNs!Y+ zY<{QbtB`vs#5n;}C<8{}UqHaWQ3b(~u8=>oT@c=9)g_sh1QU@cMMtMw(++EPVaq&q zV!7Vi2^5uFnb2U=86p5xwkyU+c@}=!*Uh1N$Oq18W@MwB_S6DWHdS3Pq{2(AekC{y zqt-OECm26tQ0XeVZbusKl7&RalL^mZ#F|e^SfiG5MyO7|K0-g3FMAYo_Ceuuuh_IM8 zKo0{uc1&yxE-5q(^W&?Ab+@)3qJOj5UI$}82S-4ybox@sU)9~oR{%oibSJ*Ul(;kw z@LetDKG!AJIZ(2h8^PE>>3vwi!+0c&QPa zibRQ8j)N2SX1w2M_Zv-d-2{7(Fcz=MfvPiswYqjHzG6H{7Uh(MH@O6Hnr-~ksi^~I^eL1gJ>YxD^!bPOT%Ftzh6GY@uyP>H{o%!FXMUxKHyEk_{ymZ7|a0@4w z{4ydC2dwM)i~o7=-A{btJ7$U&I($(>9*DZTWN!D`A0W7E3E|(Sz85^8co2r|0p zk?e}JhYtD$vH|~j^>a1)I+EPC9m~R&ZZ5J^Z037Bd;f!m6^nR?hyqZs-^fM5JcE43 zmlu~QHX`4`fZjITW{Q@R?e-%_3n|Nqc%w>5ZU)6G{)tYg#Z8-6le54mBHk=ykmVnK!h z`ve+XX}MA&jYlf}yw(^oUCq=*Krd{BGxn*tDPpUdxB8onmg1A+C6X#(z>mi77TRWF z(}n&pd~la6L80#kAQG~{K^r`felSsw8c@FVRFen?nEH{24B9)2R{U8iQvmH)0!kY_ zeOucLoA<}!M<=EjDTT8mez0Rbqf}N?1>2?@9ET!w@4<6>vstULt%v8ReaC~(iHbQS z#qzjxf#=IjV!Ms@8G=YH(B#W46q`yVN7wD-0r)rl z7yE#$*7r96z$zSDllIglC}~FlwU&guWjj=Sb6#%mPCWX@@=tGA%CD_3Z3=L=198g{ zgLdW$HQVop5%Pv$7uRVe&3VP$T@9#%)DAOHl2-tKyqsc_rq8F?ek@cDgmDM#0aa~T zVQnIbBjeS`g6udnz$i3lL5`q&5kx8tuu2&#&MEL?(~2O!lmU%CxFm7?B?)a@lo=bi z_02cR5dMlNwny?u{O8tZ8;2lK$rHN%eM~CV!G?*JoZv@Tc`@=P;KC299L9v>02p5W z>lDq{s~`vT6_~x1A;kbUM_XwxNuK7p>lea;mPr?25>;|E$)Eklw~?JVKA4F%!s=gz zv~D&ibb8AjGXdMczf$-HvJq>#qksRmkuUcE{tN@zl)JZyu zZ4S+{C?4h+YJa2D4w3P2U<398X6WF&E&Tow_J}sNJR%lgISm|d?>fSWJ>&Ok>ZP+s z&J;0@<|$9(&EhJ%ofg{Z0fl|fmXuHU2mBi#B~cb&qXUpOZ{V6I)_iOpjr_}tQ=F>; zaZN9?Ro1(lrQL_HYZ|eKiwZdPVDP=ip9s9q07l@hwqFh(R~hWp(U-^1j!Ye-q3uw| zI_+9l8YfZCkT%Y-HD_qd60ng!A5O2mfD{vaf`{nZSS3|w@Bjip{lDP?X|)2*mBbiW zR93L)sVfW8Nb7wxWpDJk%{A+5H_!&s%wo??C<}RZoPB~e)zu-onasCNB9}u@HdRNI z+mkTs%sI;k?&mVJROw+F#S6%2RBxEbe@>c_#qxP03kiL?F&GUsC& zci|tx4dCT+a&`kn7i&d)^$P$WRB?vl@(3y^j+A0BOKLWfCL_nb9=?!L#y2|6O&8@x ziUodChik`&Ag?K$+yt1f6WWEEuwge3Qga(K|EfoeKZh!=y8cjA%6%Fcc5%$@BJ^<9 z(7t32+(8S*i1oWvLX(%}=swx_LQK9wQqjNsfhobeH=TVbxe4znUytfl=C@+cuvh~U zC*>~n8HeSf#w%DLg@T<7t1e@qu>ten^nCVrp89ENLb(V6H~vg>Jw%YU9`FB_w1!vv zJg?!Y@$WckdSw$ShA~`Ldi{rYpAPCAzWQqrxsMKiEt$I;Zhda#7|;WBB6+?0(c(wIn%7wa!077A~36? zf}E}`+BN}^^v*9UDw0ytdSD+Bj*zsxt+YeoV^ZDlY5yG{w zFD6=snEMyT0AxB5>&Z4%S5gxieFX{jMFG$9NnRF9uDHrd$J(^CT{G|}qHZy!d$F9C zOv{55SZ!~j#U}FLBh>=aQn(yy^&md%(3I@yP5(5c^2;EAapLv92|kDV5my{ejCU->wJ$u

87+-d!w9aG>$MAa0D>5%lvcUhL4ZbEbO`*A2m3YHqe-BXA z;(4R!^TUeUwwXJ@#mHxsi3QX^v)_7Bxw#_(`B~?D4Fb`F<&sEd{ak@wMqCv7XOJwY zM;&W&Uvm`a3xO0RoFcp_QO)B>Jcv_p{ry%(=~Bu+xXBIPMpe5axw~3}^W6H>dYPA0 znDrHyM1*u`uCDby+XTd})v{c4%{Vte@5WnF;-)9(2eIK2b?IdvDRfQAJKnwDCrrhl zTC+0=Necad)OhW-&B^uEpLg(eQ4Uk z=QF2_2gs4`123EaFW(O>3VCFO`f<&<5U4P~U^o|vWovvSYv+^w)B zktSs|99*D5egb!zA$HSh8N{e&e1bgC#k}xaFQuWDX|_+R)7ryq0-r&6l;bLZWNC4V zt|1WT4BUEmlKGg_)@%@zeLlL~?rd=ZvNt8UUP3@?=?_oMRcBR&3qhP z-L+qLE4s9}$b(?Qu`Fe`KT_cWe`WZa?o_1K^nr%`CY!QmoT2>_{%;aH2uKF~rY2gx zvxTM2+r2U!= zvGD&5689Eeht`C;*fI2a-|lG&|EH`cdKUS6g`clMT;VBfGnD{?E=wqM;^0)1e%xLs zI9j72tAym@$|CP<+ci^6*I+K&D=FRE)~pwqn|R+CNFGbrMy%pU>z10Xmkz-8dH;2a z{?rUNX#U;QU3eK?Yv3aQtf#AzI(U35EuJFX(rtK>L;r?2PIO6wX07OCcBMpFTGSF zrTw@g2{BtKj>TD6lqbKR2BR%Hu!KtWDtofal%oTN$o#Zj2XG~s_Rth2y2O=Z&w&m|RWNpSqC7{{ z0P$blSsV@X8xx3srwj3deuD%N0VNxelU{i#rr!@2kus;#qy2%tit7hgK zo>ceFqZLZG(dR0|1)%yVk+zJP$j32Hvp^(CD*~h6$x-iRt8Fu+W>GWhK1R?j2}{W$ zdP`TAhsg_Ov8H=@M7wDw)8Ld9p)ox1%8(lyO5o0G79b(!HbuMMR76K9X(TEWb$QoF zpRbbS!coAdA6{!XyZnsT6gq{(~W z5Z`&aDhn{{dR#@}C5lF{OeQ@>1Vvn)n^^{t_d%Yzd-9ZQq9#wEBM&K*ir)?p)p~i^ z6R_<2NnTCS%k2D zKO9YeFqXtnpKytEz|F#;pMsN$zNdfWWkK%Lc!A*1jBbS-;{7=!B`Fp~H1QlG7XiH> z_U)UoUFcOWgWHK2j~XafSl^~d8@wdTb+yO@SZ@PKfxj z$N%;jY|zHtgahbOz@0Jv~UF8;^RZ*L+@xOi|>i82@KC$S*kYFGkE*7z>Qlqd@G;-RmMuxa% z6xeD5@P6B*ayin9Xq1+T54B>KX_mWRFcQU5SiRsfVWf*b3JFe-DA^sj?pC9nXEZ4y zAk`Hi0Ukc7sqY_yQe`{rI-e4g|J5Nvfs7x)C)CM?9RVD;SY<@V(#gIQ`0ANe#mpQ? zfX3Zo{k<9E)HDIfQ(|(m{zJ;36cQpT+EqfH0*8_G)*mrFlfJ$;bI`OrbkX+f8%CVF z3t2()nzU7eTUB3MZCEu%9GL40@^D+xG}0-WFHHNUSwqe6&|eEs;IQXqzLZx|v5~rH z;Vj$UU89#bMT!?kN1B{&BkjSSjc|vft{9yNr1yV|U z3<8UZ%S5C>>o4zJt8SBI*oy!S(@|=EzcfXmBFrM#zyXia5wC&0|C~?4ywD1t-HClJ z1}={S_ffmn2ne@Nm4UIss{?O0`wcDkDI$C}%9t;ZxZNGpdai${p2Vs^aaPD&7Ezqe z%3MQw@a1ea!uVy55;4xI>0u49UA&pPftr-`q#N|BT=Obx(j~N%EE4d9xA!)rSh^fY z7WGe}C3jFV_4l>d_-U8?!O5!(cQv?Q`0Rs-kpgoeQCApH3wnBcf1r&gm~Lbq<+yvd zjFD*J_U;xV<@|gDX~4KOfSBR?OHOQ5V5Ed zh3}bSD7y8L=>IIQHCQRnp=iMTiD6viv1ckfs&DuAWa!|Y-r1-NPg;%}PtE<_39i-a z;N@|$ePbh^``z4L)>)K`Cq;7F#n@@D9%LAMb$l{IR8Rh5(uMLV>Wo(zBe*c@$5)tZ z5J==7iuFRiL#(RMMH+=EkIP!Jwf8%Y5uz+8HG6yFcVFLbj8l0#MOB{`)2o|?#DD*r-Urc z&mf-&j5wKz9JPIRDs{{lvYFc_DAU()V8kzpoUhmjb zL#o143+1Q7WR9?JXKahiW*?Pq5^e+u-Z6PgD^FXi7DEIk0*F=Y(nuA=6t*gR7cT@) z7xV_0kjMC#gnfj@_ei$q_e*s#fe;9czu?WYh@JNZaO&#F)qvL64*Wq;>6#cmFiECibaJECrZ!v1X~ zKQs)F=+O{g5xDEl3i{kC&z7I3ydw+ufps&%-(b`4#_RZpq~!u&SvE~SNL?ON@qKCQ zgzi=JMQVBJ*qs!gVW=I0pU5|rUB1gv=ke8(F)S|7Dbhf8=QqewFbL+Qp`1FlIlaCw zAT)w-COc6%u7Ja?h9TrgeeB3LL8_hd7W;B{Ep-^hIv9<+*0d{}XUaeY%2TMpT38^~ z)3agnhefaW;qG+dt(UkFgStqa=2fRj2;lj=Vnw_|w=-S4vBMxj%1hE5Z5{$ULX9V@ zatrO;riC3U@=0qXas#9)K`9;&59F!0TjE<^NVZyEX{rCLJ1Zb-(^{f?*Mr;*WtRio z1t#Hh>hQimCzWW$CN^Y|Z%NcfnfQ<2ZimTkdYhaPLA;LZUHkFcRJ5bHp1>_yQK1WX zrt0$&Lh21mx4Mbc#fJlGX+6bZ0p&j-(|0pqW5YP6_T;a9MiFXpxVJNoe$K}leCy`k zz4*=;oylYr&VR~Wtf!>}ybtT_JN0Focuh|mr^~|)Az`cPTu0Eb1OL&G%+>M3LD&cJ zUi-?dB7t1WylOo3#7 zO0xuo0|vCb9g5;^9#8W*HwuB4I^LTQx~1amn#h6+uA1ovJK|=t<1;y13l_zXL1B`W z1=ciB2xH@*Iy6Cre`;@&9O3q6aO+M%Se}YYGG#CV+;TjiB*)rTML)7dUpD;ieF;JV zgfRU6Tl4fg?p_+>&u@J6L<^WGp2|{JgYdyu2IX(^Hk@okL+EXj_5iYxrKm3aO8{I< zLQAk>?yPvI9}|GDUYV_sgdT?0@8g?eaSs$07XYfSdb2#UW;;%mdG?JHFhv+8-d&_z@ z*;Dtc=sE~neyLcof47&WM3SXfB>N~mfYSP!5wkbXGh2MkK#ngVC|%#MPDe6Xrbeh> zOsmiK_qBPXzifut?2My~SLPs3w3o8u97c1C?n7YPz9qiF`s^frk|M5EmbVg_Q7h8G zzt61bRhyHVCKT0QV)*T1wIrPT0P!R;8d_{zhe_cZSd z5rA$4Z?9v_2$)4rT)E`pOi39Z21;%1VWih3ppN-#QAxh$Rr3b|j8ReU?eRX54>lGG zxN0w_V7cLfw&pv>yMD2ga&(@G8QcCD&yY*C_>C z0gw;#-}VBrM5Y}oV6iIYD*6jpX!=^#DXa!OPe@92L_k5qQ6LizSJ&3iCZiJ;H> zSDBU1cK1Zgy;YQqMnca_@L8A!6SvO{6}GBL|(@1(Pwg3FNXLR@nDy-b) z^ROh5T8v$it&W$0F?JYSI5N9&D8O)X=HI{7i3Fv3dzQ2yns`I5xqgDcFUPUjxl5x( zqX9w)E{5bRD8!$OiJbhR`OIO@iFj$Z>{h(0%m-vWykzYUi}Wez#oiF~Ah`~C9}6a^ z%=5=oBW^1)CB|-0{l{NAo`eduK_DagA5lW;d|ZJMz_~=BMKi+^3RrMwk{g@Emb>nn zgGghQzROJLRQzs?yDvES=%S(8;RZVg`P41MpITSrj5$@h?Z#zf#lW1~Jy$WA{o6Lq zUO=#&>WEG5eXwChX1GPwacS3YfcFKl+_nrzCnTb2Ili;S`qEl&z{sdsCON*flqE*n zs$o^(*LlW;%*1bXdflYNgJ#Ud`!G;b=hAP+ zl;jqi2ej7dj9Biku-#Q#XBE9jVn}}J$*ccV8b0=$G9Dr_eX0l17421?$+%cSl|gZ| zrX6!Tck<#|%j-O_u$o-FjE+;@DXLe_Zq?8-190CQnQR$$y6`BMCH#V_>ELSC(XkJj zo;?WpS7~F#ePt;F%bu&r0%Vd|1H|dkrE^?9SJe$5E6mC_Xf)T*s?X*In>gx@mr!+Y zMRpT%P%*UYZJX$fGg`ZquTCImy02WD9mWR~5t{t>w1JG_i;gvR&lMn^@BvT3qmBk9 zGr1vA&9W!86rEBC$w4tNm;(NAOo^J29SB?l5tl*8S~6!b+txI?NGYfoEbYrDi?_F% z<@96!6+$iH#(Ng%z-GNgxWlYH55_`Cf z5ioyJBu@IygmaD*L^G?Is>qta&*rJa&3C{UGD8lj2&h4WPYPbzePK~)bkL@?NQSft0Xq7UB&FR` zamAK)mZgnxK!!u9Xv~UX+a;GeqO`kQEAxkH5O;rd)=Hpy3A^va&ef$Me$2TAct28MXNGL*XgWo54K|gzIB--c;?f2EymW`IPPRVb8*-cV8Z~jlUmc=S+U4 zihxr%dO#vei@&-rXrDkDcX>2C{VOQk4VZHKzO_fN_;RYovc|AI)xqdC_&fv-dJ7a5NhmMuW@q>d-eWxEF(3Szstb@p5dLV z0Z_F6H~EG;EYWG!iEQaw6#h>4z`o>Jw^uDzb|G071R2zer@z`7(mwRnFIZNuoL(*U z<#f`w0&f6;CHtPUe3Hg%wpTV2x92WGL)imw3qeUQqqydDa-mjeUCvz2$>L#QTuCr| zj2BT69F&0axnrbx-v8mce*=vIL$HM?ek%fOxjRE_J~3m=QXaj6FY1YUDXLy zni-rL=6*#jQZ`(`kfve$x_HD*e!pfGWymO3#Iu-~!9qUBzFeHTpq$Vd4(yu+}t! za^_fEfJdV~;(usSsat4d?k^|7jQN{h31arYY(tVMIowll3WH^G9|1klfNNCT3Z?<< zAH=OIB83IjiCCDb&r@OecA$0fOX2cn$uxZ8(HPK-a@c!$Z+!>uKwtpdC8!K??yX?Q zA!}+R?oDN?bn((X`WPZUvS)`mJ^Ei=c5Uz{dbgVO8Hem1AbINM+NzViB=G>3FBZ%vu1<;2(guEq@1y2VORbt zqc2PMGzlY3Q5T&TS7IMesCPp~VpT6Db+Fn~x^~540>iDgl0rkLnS}HWFc{NqYlXrL zcV$hgR(ICcLL)}OW?TxqgpOSMkV1Djq)eapx2i;NR;TMWVT(!o(iAzMbPB9=EE=H?An&(?qPc- zszw!)zYE<7ubnCM#_jC`4+l!2KguV#`}e(dkImlZC!1hQ$&TYwMyvat(SfuHlHSRq zaWyp6^GlEJ+gSm z1rOkFqRgHj%Smj$z7`v(2ck(Qj#7>A*i1|*(aEFOP9?ZsH)6f|k=T4e_^1e4f-RNQ z8;GMCY#eeRcG$S&pdC~Nkt88#{#2!S1v_L^*WMP5IJzx7Cgfnt4!t8$q?P9QRWl4r1n zd{LmyE<&@WY@7NNt`wD#0N}gyy~&BGmvYj{lnHZt_2)M9KjjTLT?A>m+P!%x0ggTZ z*T7Yje%i~a{!-DCOCdIrm|Vbl=RQqZ^fx-QqC4-I4KR%Cvd`c)(H$@Oq!4!w%(3pc zmA@;og;}UZ%#M_EMYb9E2 z(yqr8L`IXH(*6dzT6sj=anQd3ufOPZZ+Fj89xL%Xcoih@KW5FIHP3cTdRfgf;eo@; zw4$b|*1(Kb_Upsl!y5Jk!ofop15t9&a_i>lD23@_WGVK7$Y^`=ix@*`4Z@q4`d~|{ zms%jIp#rn1%E(cVFfFAQW6i&g9|b~Yg^j?d z9GP`xupB+$y!ZnHTu%ioHsuNC`j~d4=vOu~6&+G)FVFyBvcp)Tz@Rr&W;e`MPl5mU zZ42#AXBAe;tk(}rdduXSlJCVdw66)}nPx{9wFmLpP;JexL#W@o=e1a~_jruS&AXLr zqTfgq5VqZTp^t69%VDJs#on#jos`?yb@YI2|4p%T01T42jC(_Sr0y>Db7TwI9>w%# z0+)ULC0jU|3#cyQ&X*Vo?UvHfl#e6ulSJlyTdbxA50h3)6x;AttVtuCugY$t2B@_* z$R7rU{UgIB@xXu{P_4D+VwQKJ4}HoG7|69r01*8;$e5Wmg8=8c2_Q8TP)`Xv4FV|< z07e71O)#Q??j)k70V>}=RO5jLo=PC8Ybx(&vn6fAy0a1-)r3sX2|;3k zB-t0yfRHu-$tnlSPLwVMn@Vsw8jzaH5jeD#fa!$VUuK)8HAt<)NyfnISZ{K7%#1@7 z0<(rO$IZL}1vc*vlgyWa#&EkqU{JLyDTdKZvIVoIvERn=ZZZOfg${uqScC-3|GvAG zl#NPqYGmIcGHx$QrFI@d^+81FZ#$#Oc1E0t<0-Gq`Quz=@{POK_}|a(;V4g2q0Iga z5NPCOXtObr`x)Q`Q;HySQxTI`6*Cg`_*AxEgJ8`LaOS>Spgvu=L!8?Dcx68uz1#LU z1*Z_sdB#pp6f^aq4Nu(G{yU=tA?gy<8V;Fzt=$YR7h{^;!VD_zef*nLx*+_x0QBzEPpi9p5{}pi77E^!X3wHD}`tmOnb`ep{eT zBoz9|ce(@>+T~`P9`;j!j~alA@c51B`)iopO)kk@?}mQcZ?9ik9LaT>TAmWN*Jx|K zfE-ulF~3{1pq5DLN$4_G;b_(wZ-KDC+?=3S+M(hQL-q&9)q+1e$&keYMAfsPgd0@z zx*gD_WlJ!46Y5U+dMUbq5~Xs}MIJB)iXGc%@=va$5j`v<(Z|g#+4Hb$5yi$eVt&B# zG6C|5rq$Zr#R2L`CP>w`Hi$6VEe-Xy|3~f|WtJ07D_N~f+{ePyceDh{2 z3pjQfe-?9hoMxl^Xk>nTqMh+)_PylC+xErC;I<*K&D5$(v_jY_KFtIulKbMxH*6Yo z_kfl<57QVrW$Sh6CfDT)hWHfWi>qhteP;HcN0HXw(w_7$&P&lJQFoT3SL5Jn5|sLt=!jP z-qLZj9@@5WK(~J4q&MlvrTiO${4kn{xyd4>kK~AoQPNd7T@C-b#Oc82jZ_6Q}e+b0bU+dH7If;0&`s z*v&=Thv?1iY(9Mx)(3276+0{e+^wLZA& zil2k-2?6aS^d-i}B84PHR|fq&H#&TcY%N4Fc)l!c%x^(*q@vZ8?4c-O1R+r1Wc@Gw zV|-rw52FMCb*vfoFNFj8S(Y zA^8opXh%u1i9XerY*9~**@dJ!-Q%p=u%`^|c9 zU-RRW-n>pyqeMCw4=a9_Eyl@{3;^{lYubmd1NI&@;75*7mNq+Wniww^IHiSv`{#&o zGngYp$f;}Ck$;Oj`qiT=1F|$M{1m91N%ltDFN$)Af%}WRMBeU2NT@otKw1uFaE*AG zdP)@EVvyuMp|WAzBN8l!(L0QZyA2>P0EF3O;i=_(G^c>1;WR?aQt@1D$1A!Z4-F~~ zyMeD5Mpw*F0VH=SX;v**8EI6Udq)2FM#YCNwj*RVK}2VI>8g}zMO|)nrQ71ainqE zSYR`ynTExS?g`1h)h5aue;qK0gXh;1JO0{ffz|4(PBI}EMPKL${=lLeI0M7)AhX0k zFXGSU>CN1aH$p}HYy~3&GZk~*Q@K33KD6pNUysfH3gQY_~2}>M_bU zBQx^wwTszp#X|75M;M)qL&XMMh^XU0s*82~Jo;|Tcj74Pucbq{h#Qa+u-6p7V zu;PJS?nz4aXL$X#50?~vyvJclM$G0n32C~}xA+ncPh>!FpD0x zL&?86yR#C6B>A@VFUFVc1*bXszmo&N5be;o=I=MfA0|UkrDHnm15#t8v;-uZ=HIMN-{H5~*GJ7mP z9SxDoe-BaAB1T}(zWyfwuS^Q(rl!4NVH*J`5ciZJjgQavq&D4g^dr1qtKKdWC(F34 zIV2|m)Y|zw!_gM8edD*`wAG?qC`c-7yt1DmY78yhb&9FKg#%mQQkxkUppcW{UxGdO z6ieFGv`Z3k9h^aoUw@dxDF3*#X3{@Un*}Lb)fTWmCE>A~lWgfA{2g1MmHaviW5Io7 zAB}}jK$Iqj`4BAuT&Vx{Z!Y~kGWU>CEhHvUph`n{n)8JD=EUZaDW@E>C5=YmPS*dj zE!d(m&|%;<5{LQNi%P_54GZ*ju7ZJJun_kyYKWi5ZGT)x zhxn1Cy?~&HfhvQXASk1vRZnLVfBkNsGHLpYp@G#157WmGMu1@nq?4+bu1jXh5U>zf z^9Szcct*V7k)I;0Eid#d>63~56)`VxX`87=quQIMH%IF27JSHwH&d~kHrubPM4M1cLfLX&P@&)(|btGVT z%Z@9vg(wq>oPj;BJj()7C8@sIZWE}@%zp)CHL+g&!F&e^kdN;8C-B}(BzMn5VRGceEC1&|urI!|&qmhQuhk`{7PU50z+?><(SIbWlBfAf@ zvE#MVsJh^3kfDIGvxby)nknY`1T;`DgN3-rY@=f&3Qbc^0;F~$-N4-v>PY4SC|J*__@D@5`IN68& zpM^-@0^GV5E2dFS+shJTlh_fa)!Jf_J$+SZHBB6bkNB}9B@Qp(mdoLvUHo;Q9_JE% za8^V5k?d|gAPZ3p^#VX5yW%y)@*Ne67?5vif)BaChx5^W~Hwe#yT(m zp$H7xMP9(@I6v1~F|IZJ&#CDT1p?F9)6*{^i20$LJ~0Jsc8ZOASn%iWZ|&vq73dw= z7qw>@Kttw3;x5kQsfhXM8p+cY)UxGjQuiNNtubX9PMv32@^94Li0{cQR-4;LXfngw zn))-MRt!i~X^n+BZ-rsIWBw|%L{}27i(eLGYV(=3sP!R1VonYTp-l3HdqW`?AClaz zl;R%@&%hGW7*6mJ8-!0~IsishF@hb-Pe+FAPoVV7d(ppFkL^B8Q;@b3D~#bIU~3BI zgsh!bJaV{Lhy*=|#_7`@4yT5ZU+l43%PEdh$Ol9$AA)Pu5k96QQW^(gaH%lPStIve zL$Sebyaxf9w}ymxU~poaoX>mrS$H`7anzEHg(tbc34VFPVegJ0Jdo0Rob_E!_Z39? zCrj@6F`^z}05P1)R)@ELgWe_PlNH7II0_dx5F9Nj6K)$PF9NeLzrM-!DsXze%iszQ`S5auJRL<) zX=`SzvBM*w49z&{3(*SNx1TXc-n#>b2Drg0IhrB2N7`WvJN3rt31vkc(hA(sXbjz~ z(o8pvo{FB~@PWUE?lHyTycd3vMAEf$BBq2lBog@GJYO+bo6_A1F zn3=w9W00R#0({sKC2S|5${P}d^5T4LGyRh`YYV=mKrGz&_7jHWq|@l3^BD0el|>rX zTZRL6MsD+ZdgymFe}#M92*KT)H&=h$-lylO2qF>p#i_966>CY!zBxt~2tsls%c-7vn1x!5(0vuD zHh-$uom!+4i%_D8UILWCj5v)p+w$Rd!A|y3ZJsH`fpd= zj9GJ%I}5)7GC`vFpRV`zF{a8KdtuBzOL`aryaUq^lW^#hKx6V8cE>EPdUOsq+|5fK5@0~ULEZ>snG}bYgMlJ<ql3Ev!rcTReu(~X+MX2AhBfw zNyamUn5&2d2qjE1usRjr*YM#c2P9TpBbXL|KH!Edt#v!=nn&wl+odMQZ1Da$;mrGh zKc37dYR?16_UtZ1YxZY>nYh*LBbL0I3vCcjLBbidnZIum?F=xGNyHGJR!V@fIgAFg zUdOGXQ8GkbKAFTx#T)h!GL7C^Ce42~N(MChw$KDkWcWWh{N-LhaBruVozE){FYve- zc2q|}-N4Yd4k=Ev#JViDkA|5z|9fW_G7W!o#d<8m!0eZB>bgzIfZ1pt&N(A5FJYxK8NA=lH|ScbfBOhaNe6i z(nxMoOk8bnX}&HafJ~hQB{F3TmM-0U@+y}vV&ycJ(1~I4> z&~iljn*a5BAM}(9KT_>ADVZ3~Ubh#nl-13iNf$Brma74gRe504mlTd$5MY_Be@#(U ze)A)h->YLBY;My=)JF8>R+dLGM>inx-;(15P zbBv&9VRNEFY8NGj)sYuXCa0r{@In|0A=`rdWIe-*gWJA9}Gs)4&>GoT=-R1lY_8eRwN&UwFD7$iK}z#90JqO%7f zj*JB2hFJBdJOoL9M9yNlN$f$^;A$Vqviv4jy%T%_*@wlzeS-_Gko0DCMEwc-@oKQw z6|za2@JWvoUemopQ^Nt9Umi~Go{n9%J926oiafD%@`pB_6ZMAY$5WyGGqr95n&6}+ z)M&XCeG^uM;ok(bA8bE{Gqu5n(SI_+{}ax zk-OpoYToN=0MO6WL@TI&3nOG;gz$|#8nv{ z(NZ=eey48p6VM1&1|h%EM>B&rem5zj+Eb~GqIL|yq0t4c3i1U6uBvoE$_!)E1e}+&brihU}-e_>C16!;B^vZSkgNw2$ zU4xAf<-xXwGPprMuNU_kSQDad6D;?3edU(>7iLH6tcUoI)*yiR^qI#zUETgJ#=)S7 z77E&RYvl+!!yS;UPAVMKtSI~XX0(5oIXc2 zDt_nIyZb*=boQLhK*|LS~6pBPC6NK@QcOz}sGkA>(eB?DSY`l*B09&|X*7>!Dwv3&B^+rzO-3+4x?+uz@=67@ee7h%uX zp}&_&V-5$pRCbiz@{{m^h(jLLG8sDzVF~y~!hq+jBCvM{i0GaHaH%4qls*QPIfj8n zB-5sW6{dovjQmoB-)3B8yl|dsJz4PO=w;e!F&IZd4#QD6&f;n?#e!MK%?7c9VG@e$ zrg^UIeSY2K1)rL?<&DpTp-~b*13|9@{|kLkc5gkc@aX)GeO+%6DG`;>T;$P<>TnWw z>an3&(j!78)t3rODTKPOV<<}BVQFD-zZ|`Tq*Q+(T-PEl^`H}v$Mp7@l$-vvIL@wMgR z61a-xc7#-nw~DWMnpPXzYx@p@+xUE{qhGzl2ym&O8X~~RLv_+-JGt0^BDfJ0FOBLP zF1yBsB~?A}=OWfP988v{MOYY~>kuM#hEu4i&~KodYU6kqm>8{t?!Vsj zzE1{Lvo+HS5nr4ZX%H4pUuTj_89Nx#C6f5@$2A)3|)H{1EIboODfap{#C6 zL9TRF-BM@|f5RA(-hbZz@bLWfxioI?lskV5rRb8BivhQSsx2nPw1#sC4Ppgp?$&b< zU1Ai77|{Lhb3aGXB{J81W|9AmqI#)U-aV^k_w1+21}Bc6PRBNOH`(^?hi6W;{j_>@EcNDKnGc9iH^}v(mDa{CJjja}T~e zkNdu9g8IG8?byHG?eMYKRwpz!nHTT;&N3_>o9D4PYxy}MljVh7^H(je znH-z*tF$e`|50=9+)~5-Q~FHs@~1w;GZ~lLJ^B60HoFZoQqmJM1FzCu zcv7?ErD$ZnH%$560;}ULEy_VRSs!Pa7!{wcFIilY9b1ao09%!E| zWMck30sUfjm2n85^ZHBq7o4Ii*LrG}6N(p?y4onLSd8?tlkfLb_Usp#T}(J~Xu%~{ zZeKLUbxxsc;`vpQUDp+5N)tQm?e|^nwuX1 zt!O!gBQ63sIE!so;p`(wo~`?a5tp`YI4hV2BR+rFmw#&*iTt1SoLu4Dh&JsSduBK@ zU|}tTo3@bOQXiTcB3iNA8c^iIOoS+6yoSwg*8-H^T0RKM# zz&Z$K4FZAz6e^&~9B)3kmw+G5-(L8{Mk7cvXl{;r{)V*6$Gztbrt@THewf)VYPkb> zWC>jWHuB@?`X*NLWGzbnrGbvoVgXuOF_z79-$`Uyjt|7C%j}50I)oGtH1X4%kUxRq zQlPS|jF3v8{wbpu^hr(8FbLkxEn>81eQFTE;^%`xzD01UnvOTK7U;)O$HFGWD}xdB zeu+JhYoc_-epU+QB+doGEzn07e>aw1BD`F%u*Oamv@?*iblc(E<7Eq?x63rgs}t`JZvApLE*}r-fm=&0X#Za&sN8DX{lqwnx+QqF|#3V3uR2 zZ|QN>uOWICz@{AA2ON7Ji2pbC@1158VU5JO(D_tj2>6Chlirmr?$rgWYEFe_h5aNq zNiBmro23d~ELJUhr3`yX;87?W6h*9tMqHs57|4K7y9#lj#9}2s>;~ig^f8QTJa96` zgo_27Jj`3y$txcRVGm~vczAQrsmim&(b2};{x};WO&mh+NRuQ5t1x^T3F$E{!qzds zp8by@Qy*jl8%Qiw{G^qI2*~JRcAxrYU+Hj~6L8Jh-FW)91nG}tGf76I80@K-9I5)H z(rs*Nd!49a&@MZy{#9t_1G#n#liZ`qKlA4N0{!su2urY|?AO*JfCh}3>hX@hEq!Fr zix`038r17`^s(!34-&OBw=d~K8fwKKREC4^3IEhCP9$TA8=w=>eIQ}pD;%hiY|&U# zBfp2c0t9F*nvqW497Ic4j8EmA46@Ar>~VlRXWu)L2OBkn$j^T{+LSO8XZ;oRFRR_$ zv;dRvDuf=_$gjB+lZV2J1y}S-Zs$?>b^<)@H9O!}%?|?)S?!lxA$C|OCVm{AQ`Cc$R~{%f%+uww z!JYw=PF_RwFa&A^?}axjw(YdPkCS`BZIj8-RSqFWhz`uT7}VU<17Kbl#t}>no5K;% zH9f;TGsX%FKI8JP!rTmJPB$|uCb^AkDY#tOSDbF#VTOk>%=}KJ{cvLtLoJkCpqH~} zF2EY*YIrs>xM0gWmY`3zyh+?V!F17&dw`nIhOT*SrB$ITZiGZd-v|*Tqr&wB-M=^J)ew;Ps3G3drqD(zUnvjtdt|jx3b60-sa9DTq?E!qWA(~3FFT-Mzne zk?$@l?HrDX#yUSzxIUOk-962?K-_9&)n|!wixe|kCr=&-4b-Ev+Bkt2rEbiSCrh4C zI?xuzUqRWXLhOGWYgTFkkch!ZVIr}NvGD*n^JY6nD9{Egdt2lVXi9(sSfZBU`2C}e zx0MRuhxr~ZYt;e9#!1N)VJdZ19uy@JzNxz=6jKFY%!#Dhs<8UXVN0w8*|?ouB?+gg z8L+I6!xVItho`G3!n9W$ieLFf+rPjaA{$fh_;!aP(n zLxJ$syiST9=U&1ayTY+|SjzLEmz5ST4kdm@sg_3oaM)bXY-GVeWC5#BCq1w`$WLAy zlQE;Lfh|+b`GSwct1uEj8`2x~)7)4zVQh=6uQ@i)qlZoH9MPkl3PY{%);Xk?P*6!= z#xJ@7f&GYas7xxcsRS-)g{zF3Vc|YV@N=&?LpH_7GceghylhXd2Tm8vruro@uQyhn zc$1rKn&|&B*W#Z{pJ!81gbrP}8= z=00FW6n~Z9=8QO>N+^!y=mJQsUO;Z)Hj-k$UYL8@oZs@ zUXo*G&9%M?x}?z^8ENJfn=Wt#!fsSyJo5??#$nf2jX~H`9*j2DE0TUky`zo&8K!{U z@ITa01>vo6cEX3MbF@=hC&Pxf*;li|g;@ahmC`Ym_sQZCtVAOl)fR$R?@dv)TKX4} zvqp;8Mq^|ZqLLQ{Dj?Kb_MtA|_#JwoH24Wp2zgeo8bd8Pw*h+NG1O2g_5D)EuTr3J z;n4N!V>4yU4lez16`UALa9N_P%3~FXA$MA2Pg?BM_Xs0N#h9y$iw$=SXR)e`$&sdo z`#O15Y4N*Y&&N*+`}r^*M~20kVceUUO2bAV1(`_01atgD*+c;hC{8Q7w#_ACDDckG zNd|2w;7Itl;f}_Q;O11_Wk7CmT6saet)u#)wK%hWKDfN~>)?ff){>qX$C$qoIVXc4 zx*YO|DkiN1U7*`c>EL(7LrEcCL4(#8AWAU3C!s2y1T}z_L&ljZEvWm_vtBX*+~nQ3 zNA8MeG=-hicmLKlau8Gk&J`|UzsXlrn56iO(eYI~x>DP2e~s$xcI(^WZ@?agealsQ z&q~UrjyKgfY5jDQ=6Rev6G|YUyz`JF|5_g@P>BpeS(P9|o$rG0aU}0O!-|9)T#VWH z$~7>;kwH*;7D3jA;Xa_wCwY12b}|cw3Sv5_N8!FCql7o#=0ciGXPq(`EhNubXS^!_ zk$laHq{TWX1G`?Otg^53wgBEipCp4Z-}x?KohLH=t^u`Wt|rtIhCbS}U^piVv6PKR zH|^9vDoMC9~doZ`;|Nr^q{M?7f6B{zjdDTjotqrAf)>K$Koyh9g7ONuM@l>37s@{auGpwaxzZ?!|Alx+?w@liXHpiLTC{E| zUK;e@o!`21GAeJ`pWvZ-e(q(@ZiP8RgqNER#}=lPW~93d)5basEiLKZx0ps+wo4}0 zqQ?p$J+g#pjAyEr8*LBIi5!Jm|DHK4eJEd=De0^MiuXP&=>;+_HKa^6ipj_+(0VEDZ5k>uuNZ8sHJ%*fWU+{GMjv zY=QG(%nsrcu2J&J!In3vls8hsLhzWK@$C>6@jXupP=PAw;i5Vb@5!OY?29MgWvw~u zkt3d}u4ShSgIV%fb15#vRI+yn%Ia-tN87)!%FcbY-D-5A65)|;`@Y_oN`gD$m6I9+ zvyYvIEmcAqJoSDnuas8x``!6;kK+3hRUG)YqwqHo4I;C1T~63rWy z!HP|B_l-nZm-h@jJpU({xs;)yo+Z$y3;5~7kGF9FaGn6Xjk;MCmAWgQ8L@cjrpbSW za=87h$I{_9eJJ%n^uhDk(K~E>5MZ6;Qzs1cgVQa+;^XUn_tSeD9rw0_%+Ik@AJuHF zXAhO3>;EbSZh&v1-JXoFt|RuVv2BgT&KmPYs_=hATF7oMV=|6Git)8Pm}lHFMgE`Q z(YS7n`q@%XkLfj{w+!?!6Uet(A9#X$8Zn)>U4O&TG9jOeJxe7+@K3T=x%7z_y+%^O zF07)cbH1GM1RWC;G@xnrRr%N`ETz8Xkkp<%Z6As{v*F23^%_(#;=|2qs73Mo`=(BY z1d2U$pD02*oYbe4ax}!=>Q{b4K?n;H*3O7OL4N*TA514N5UV-=?)YCO^uQ8Xg^}tF z3}3r8=gSGq1l>+B)&?Tj2xL#UVVI;qQ1yf!6RXl_EN$h?JzA`WWf32~`|DJ@e~i;a zZp}5ISl?G5a;IX5M+D-L%-g-z;Os{Bb=?w}SJ483@n3r19!n|Eo@2`z$Uq}oP!%wU z&kGlJ`kF;`8R*mpQoi218O`XsDhKub1J923q^PO$W%`WY*|Y}@mJVyW#Q8s127Gdb z%Jn%p(q*s`7{CPjKVl{6>DHu_is!rH-0RukIfXn|XfA7!s7%W~Gm#^ywyyV-I?kT0 zw%La%cj%|WgxNWoid8^P-a}L!7kliSoe-K%_JLxgH-z@G{Azu+^i7^cq+VLv-kBqa zYF12yyZ>0Q(mk{2{iVUQNOkRMDHHVYrRl(YhxFQ?4#C~A*n{G#!nY7KweRyyEsl$T z`J00Ysj-Y@#y*T~iC?m(Cejc8-b6D!l1Erj8KtCfjfk&*L+o@_chemvi$T(Yv4R?> zzKvmS&+=(b_J645=OKB(=^YrIJi1~KZOF&uaecytYeBQjdz0TSvLD9dV zWMI0K=XoakO5RXdDN|&sw(h>xT_L}`yRC> z2Oaub`%uSYx#jC#PI(_UezCP3164fAe#_KSRw_8uV`ac&?_K_%JMiumi8+j>w-Lkd zBm+sZ9DK)g)!OiQnI#6H4*+Rwds|VtJ=)jFyiMgoh1_^U)h^Z;dTznqS^1|fYE0rH zi5pdnx{KD2NDfZwhz>VR!%x$3@QKxwXk#CRvrZSy<0KP zj;OSIyEOkl-nj>e3FaW|ChB0Qn@-R4Fm_Y4pNeCb0I%B`lZu{Rv6^b95bUkhOK%yJ zKIvOVmaT=DK$GGzIZwm!@4LurMI>rxC6#6=-aSUfxRe_AjxL=wyZKgrf)|^95qA;{ zUM!7Ob%DK*?>BCSQ6C0702*{G#Z;a#4w>m%$s@CKiuu3{$ z^qx1;%}))^`?&D03O;k-$8=8AGOMhS?!2a`hP|UFfI%i1! zS3ukJ5BVI8!C423E825^woets&#GAl7_zDtEOWR1(QHa9UN>LBN`?b_K3+tp87X~OK6=@1*hoIn{Q!=Vk0EsecR}xdx>V~(AbK| zc1Gtw(1bHpZ(k0s+k!@RNI1UKd2bNJC6-<=ZpPng;pV0K>hK@~%Q-)CqgI7KJqf3VQ zmsc8FL^Ct87H)i;pOw6Folw`9-5nggnP{8O<_?G4cY}d8PqS8JysIa;J+{srl1;w(VntFp?kqp%vU7ZOEr>}1 zA0D?-0#=_-2o}I9CKg#MJ(5E6l`LnAkhM_O572o+pV%6^r;&a``#?Qyu^pNOTaacE zl`<21_wB_BJztlcc)CcX;J*IQ!&Jc<&3hz_cu)PF($*yRW}}-o>I;rQvHKgM6e_D( z5%e1%b;deZmG!Po%%lg#v^i0xJ8o-~f16*Tj;x{Q@7;p!mpks!9bUT7Io|P0Dr%!O zf~@jGpzL3)dAQx<21td!l1_thh<>E3#L|0)z>l!T615R*g+Sf3xx<1FuGynG4Z3Cg zpnhO9XIlI%Dg{+xgRlXTnIMRDHN*OKdaqKS{Y7p}OB+@tak(NpO_ljo*JvvqrW$#d zEeRds-B9r+`-q<(nau#KcBFQtSuPM2q-bId?$Ag6u{v`4*yv7;Eomi9;#jYV!7ckY z3>p!>25YqBO=Q+5V$Y16(=}HV?&QmI{}=d};i_1zSxxaU z2w9R0Iz-f^a?$)f5}R~V952o98xYlV%YGH&^3faM_g~lxcDNA@ z{lHwg|1Mkrdd7@=5Y zQZ?eiX)IVGU=#$yrBfnBF2(WaG{@#ig1vp5>HO?Wg}tC5*nQ#=ewFnA+fVJH0d<6B zpU$RK)R0~5@k#n)Qrku9A3c?Go^dC2ck6-QWm_Nd5O0y5@+T+UEY#Z;rUL;|X>VH0 zb)sqN&B@|^u6CGZGAwh3ZkQ3kic#HIVdT1JY7xYJNGso3h<6&Tyx0-B(TAhpY0v>+ z`H_!*K6;JpC}xoHr9;_y&s5Oi2U2KX5F-M-Pnq*U_;+DKc}46Q7*IiuR^|r%XW;hH zh{$nj8n}p7DfI0VkxjI}_V!^H2W*S$xPho6_+Ua&BdjsddqELm40w@p(%P%aWSPAd zUgR!mfvdznjU6%S5;x2%zylD+QXWa0=dNAL76-Z?kA#XiQKd8AkV6KN-74-wLT<^+ zJ7CpU7JHm=d2nJ0r{6ud5}#8Pl$uO}hYB{gRxESi%@k^+fd3N2F`CMqm)g$6@aMb%sb>A*(I1cwaw}Su^KRw@=LE`M;$frZ z!2_EH;YUifZ%BAMN&l^Yw|(ac#_U%AYB6tcc3>Fc4<=X5ut8WGV(PW=Xw=>QvVr5M zZgbQa5KQ30n4oN)#^n7Uf%jN9|c=^R4O4>QvIVKeVJ7$)SG zYbAW#HNe0z0}cG9#B*G>Ru-Q_gH($Cqs&sAZMH#$5mla!owrL0F~s9dgWw^4R^;og zRgC8`-ReTZ48Ov^4$=&kKdYIIrD^_ozPmam>aF8@f&qFg=>+lB_;!WkONJJ@S8%sT zbSfl^n+tjWoV=r6`rrzx^zrb(&)!VUu0eiISpw7M*4TB09&;h6TUxH-(CUpmaD&y0 zZbjMdEP;Twh@)c-STLCXEKM-p*T@|F%ETC!U}wYI|GGk6vPJl>ODV+jf7Ye7bQFtJ zKhI=A?9-4O_{4QpU61y}JrTS512qu@fduceVn$Jq%>=My0iDHU{aIWPH!~Ml zj5`BmaRq5U^r2gcfJkvX^Al@S8-^b6<|6wP2Iw4@bz}1kwMOaF>UqF)FJND zoR~I^oLhE*d}Y0wvX!-=eEp<)oGuPH$^>fKLaXjO>ELo5qVGg?C8r~wOMpWxYW2YQ zUp3r%2zzq~3Mg>xj}?1J%wkTl_>rhCc)KGcGe)x31Xy=qgz2Q4&?#%%A81-?p_uj` zpxtoM@ovW~EGtqEEsA5{B8>Lc8l^S3ly4lcIk0O{Qu9*_rHM9%_#_q zleP}j&MUX6<25Nu0Xy363aA)l{u6{P0JPO+%B!w04Kv(?B*ur+9uLN!L-%B6m^^JW;*?9cUrG>%3ud(W zOOV}^Rd_weGKN6V^jwush;>%$p>ID8wBQ7uo2-RDGem>@f`lwaIs&miM#pNVInvds zCWBpK%xq82$y!XHPsM8aW}tW&N#DXNQ(9A-;m@W50acGdZWHIz@8B^g8!#b%N~)}X zb6RN(HPE*NR#dY?u@R-=qF#%{KOEam!V#*8ri;V8qr;%4Pi|yreQHQCEsL|D?HVwf zNpVgu9R@0?kN)`g*c}-}OEkh^llVr^P?gg}pBxm4N`=Z49XH!e7)qCIKL$j3C9t}O zYbEHM;LohQ0|r_)`iqQa+($pfDQw`-=c=j!Zq?nU_$(^%@J`31JJGXsGXq^d z$WA%m2%Cy;rkwsbpl zCdB}wPR8u?g{<;_d?v-T>>y4Sw13CALaqe^ScQ6&%H5<8?K`;#UK|w1tsxg5U>upV zYo2Lu3Wn}AN+>}%?Hz`%3x}>~9LU0JGWfdE${+cEUK&Kf@iGE-%Ly~bpx@|kt$;*R zyKrHOk^WDj^Q5Pag+?Rn?7ScTB-+xNcn#SGr}t04#xc3JdPzfRqtDGYp$|C9?hu)i z@dGS*a_yQi9t3aGxI;SOrq($9aZ4##r60m7gez7NdEPD+75~mbrm(M&jR#4DMl((Bv_sxaHtC_1tx*YC zKVKji0F&AdF1gsEu=7$BJzPtH%nhwB%8U@Xxs@M|`jCUN&6D5Nma8%H>u}gk?_4VR zjn-ZOT{n)ZV+03Yu%rE}tZDKT&TX1L9pq8J87G-$&N6^o zULszgxkI(gny`s*t>E<~q_PCwl=G&8)o8ufuY41gtJsY3om2Q;qforf-sSU|NMpdW zzO}{S>dOzF>rWah+2(6f1X@TP9?VLBWkxbmB1{GItrET<6gCR=~= zmpNr`@AQ;rc3qORd>_jrgW{aWo;8f%6l)ea?BSvZxM-6qx1=BIdLE;c0y_xxvLo{O z-*ZrbBh>?z15~Y^wd5ZP{O;XV3$CAD&sCzXKv|8a=Y2S(`jnVQD2Z#!ZpD?u8*YtQ zn&8*#c1r0*!VUuW6nBUoy#aXC<&v`gFRvK8QM|?HHa=#C=C-eo(k?;p9h4EHi?^jDdg0u!gk*E%$_Z&){;e%Mykh8u3jrOY1wv zBUqN~X?`~gnSlQe4l6;Yqe6_JFV6Qb%Cp(>Ej3ma1CiP>{RpDLED`pXOAR6{y$CM( zwrGYD3t%WWF_zt|-m{Wm1WBuMVY;KGsq8e{S+6}$=$bPV4YZP;^-dhR2g&cx?A!Ml zP4TR}uMynR0T0%g!~5xIR*eNspyG}gtul*-RIQe923Z}9X2jYGFJsmt(=`D7>B=O| z@l`%4E)?;FCP#6L@d}g1H>7(*dn^s6nX@`rW}IDhKrF|{lv0tjOl~fT3sN_-a0zF* zc)-e!h{=^H3Ch=N9Zi!*yCEvHvmR0x8bWHmFaccct(4kAp%gjjicWVSsr6RpLM3S* zLj@i86jvkkIG)+AUFgeg8!_m+z0SEqAra<%A@%j`Pb-|utOs1l>gWIRMUNZ5PUGV! z8zh6xsje_nK~8S=#M@?YO^QsC_w|&z#RW}MUCV^4s(FB$>5U_#lV|Y_dHk&WH{$b# zpRwUXhPgg4J!%!1%K=|=LbRM+m;FN2Euf=)ov$5#(SD_xLe=Jw>i5n%khss_CCd9gvWVE3lABxPlDx|Wj|uFS z=VNwI7S5apG#VO2=OwE1{}d7nY?pB>_SUM(h8X& zDajfVUj6>-q9HMye>_rfk_tij;WG}lgC|dZf@RY9jZHH4SB2J#$$J>|gi_E~%B4ps zoX$PS?IV5V%747GM}MNI1a&@SzWM>n3$y^grnF>)3XJ3S{Ai@I2O`ud&{GN%Qft#) zyg{&4miIr5g$={q(x}q|>baqv47PbBEYh+1sN_zbA zMD85-$W7M_$bHp!X`#k1O$4aG3XCjKa=#lHKNdQpZP&{%LTO8MKUTYwh*Z~6V$UWM zc5{|7xc}xMY5#cC=~C(-lA!U(0y9PvU<8`1uB`nYJIta7OSq117#W)?yO;ol)wG?( zxy-+JgZl0nv{&*H>rvPjD?t8hMi33M*@NsG3ijul6v|=(*O&)cdm1I@KMdMf%u(EL zvkk)C;;_*BCjxHKb0pQN-O2Jy%iZFl=@Y2nvF{a9@3_(p(?tI5&;Q>OBmIgR^~PMb z?u#3;&Jnq9vn$x%?E)I0qhzD6n|+04R;r$*vMXO|x*}+SEwQQ1Lb(gynaKN9ZEN3X z)(Z6}6)-1w85=OGwS{yE4BG0QND@|xw81uus);G=Q zGuK+lv<GF4e=EnLtiVyVpM(Zi$a(R4eCO{W7R zQv{f1C8&?T1i7ZjiXf{>3X}IG4ARPdt(|*|l0Trtc#mkp_NuOie@c<+k}}rv%&&26 zjunM*$#Wr@K;+xRn%bz0(vTQs^TRzgJX{`d_-T-Zqyh!Ot*?7$7U&LQ+WSfo@>^0{ zHh-=ytsLe~DB}Hy=!u8y3NkT6e?qpA(8x0`EBS}FW$S=n(GIutI`U05Cxqhj8-&C+ za$O2I>VXJGL*1+Vwbd+7Oc`z%D+?JAMIW?l*eQ)Nv@RNq^OmW#CzMO}ztxPm{_}SU zz~>EmX$v-4kP4r#uZwTPQiBATu&KdYZLB@w>$rCt;-)4=(w))Zg5D=B-zJfBMi9H< zFgbrkyj$Jzs=_5jN)LT7j;sOd*z6g4cG~~tZ%_v_?l~N0#|9$X$O$_*+6Gg5-zv+o z9wnO5ICR*SP``H%ee6k_0BXNox@yzoE}9ishgd}Lifkr_3>6=2(tS?r4TrixE?^&y zutjmP4mgr|g`i#gxt4>AiQNe`S>7IyWCd&qBLJSycWD#;U(Wr)q@Wyq{BBU>5jJFX!Mk~QWdq1s;NYP?`s0#f#IC$g&i>0a3Jly&z^>HDv>P$r2 zy>JuWZ5vL~z4Ki?yPe=J<<5pWhJ#ndNkeRNe~lG8zkNS~ZUGPfNuLF*2iN6_2+AuT z&fT}hi~MPT*#!6#`+{v4Lq$H{fHKZI+QTBOP(5^e0_U!6z=P5}MZWi9nYq|n)(Iow zq!}|esJHAq1@9l8$wbH60w)wE5iJGCr6*gw1alOxsPYAmZQ51J|5qrWxo zR7 zW34FKIEGBVh>y(C-cp>ZVvP*|^jN@9js+Aj6(XU&Ri;H4Mh@~#7r0pa=f8np+b>I) zmBApRV9+UgPZhHmKy?Q$B+Tj2r(e6mQVsB_*!84MdSisv)DI-o*`Pl@(q=vU!CC{p z*E;zh8e#k}jVDpS=qOqW;U+e*U1(5AEdX@!$#g98aE0IB3VM(z7sZCa*DQiq1T~p~ z<2&8v*nBqjsDOdI1UPp~cnc>wwJZ-4?IOy}(VKxIlH-zPIy}b2oM2G-##3z!m*$0r z);O1?Z+Y!+3VN}5kd!T%B&8)%)Cuzo0E5Mp-pEY%XNKGx*|?z;Bn>uaXqt0hbBB|O zTI)RbbFb&0$Bk22dE=gUGfXM0r`K1mUtj^&%@}&#^*UL9Yf_AJWUp~7g$Dp#=;tL0 z+hGfHd-zB_1IQ>?4NK76C)&LqCbCr5;H;p0SfwH zlvH9OLRkHNw3YX2!+ms~n7wUAxafE#lZY|=i#G-ctd74ZUrG#6Rx1A!oOg-44Et1M zTUwOdGcxgg->#M=NP%8`AQPCt{k!v9MQaccby@C!b-9$C;#pPKNm5B4$T)+D7zubn z2pwWL-Eiq7;W6@T!&n-x(h}V3l_RzAETyVC9klI(u6oMZj3Jp2WW>Y$WnZtNx;^H= zg<}LF`f@i+9G;eluMOA2oy{Gx&M*>Lns>mn>nlGHN>6~urzJ=r?Cw}&_(6-~QscD| zK3ZY9o}thqK3m;}eB4;eB3|#W*p7@y$5X6IB8kCnQZQ4qWqx$XYCH;#B)CR`N?Y1X z@AVJJf&!OW!_BhNmuYxjURQ4l<{YsC>8}jubfc!lTb8^?DlZT&j8W?I0p$7#)nrHQ zFtZR%-)xuN_`UZ?%zq;|4Tp7RpNJpdqyRb>R*^P*zAl%VNA75wT2e?x@lS1i34AtueL;3x8)*;62S*n$Voi@5X$h@?nQARIf ziIU}KKQ26jcP3(5P$D^`TJR{5JP_7DrJh{4k?cs&#~Q`}(({hKpL_UR_8U zH}`h665ogfir#k@_7si_7Yn)+^kv;lDMYSiR?CI!m4iFa8{!a&9WfNYMr~eD+A9dA%zP1R&0OiCAT7$=}j+PxLMqO(_ zKNO|2s3=A9mM&c48!fNaO#~*wTdLeyWIaq!m!OKPv78m+KMmw*izHU?=jh2d%GEa? zTX_u^9s>l^A$q$!MHzGG9&jkINl+Ffn<@b%zY{&oe7)}_ZOVaII11%;*9RBtZrqoA~}^W_bhF9Hp^y>j&|&)$8dR# z2RJ9&fU&?)zUi{dsR@1h)s&d_I#oZTwkLyb4R zo`Cx<-(4(I0c9{GH=MpI_Q~z{XC};`xl$K6vbMxP73ZN`vX~)SfYvOwY!K37cmdA)@C4folll`fk^R z7Mj1yr%o+KAQ2M0X2Z+zSfcAOvC|;s=$DNe^lHxPjY_56;K=|SH^~mpFcBshM_3v% zk@7g`*H>wE^fUkTzySMxI#6JyO@NnQ)EVy3Co$QkIz#(lU)*q=j2opQFbUx{t%f~0 z;&;=@;>lUz_)HlbDWr=7J!DPv$I0r)AED44G%O1x#u4bwy|H2et*%Djom7YxQCqA~aH=(u^+8@Zkhr`}QfWOG z^fYY!mjc)cZp~k>=3LW^nNPDj<;WQzlKZNkaBS zmq`!$iK&NEU0SJWc1#&|+O{##X^=zLT=g>uku%Ro4~U1DG0Sg((}19OW;hG;7Fz zD3uhgPqZ?r9}S&#E?pLZO+HZjg2eZ!q1K6oAPu|2n!)^zbUPR2+M@ejA1&KdC(I}(USz} zokFRGVIImca5kJ-3{w7#7Tm2)Tl}yp1o?aw`?oFX*9x9b^Sz2D7p{)fKX5DLMPwQ| zR%;Wp;>M)Ao1Va6PHG2cD;*QLdHDG6V5hI&5?N@nghoH5hH%-vT(caMlR-1%@N+`e zsEA@YW-R5mIDP~WpX#V9EVlK2YXCdMJV71k;)8tbxcuMOaAkhvH!D44?6ZQKvy7rb zsWmuPu)qiGkAWGA^8hNrnuy}E3VCoJdDTj%Ec5dC`7LYDQCaF+&hJucitb0oJWZ*# z?%J@Q$JBGia!-O;Q2l}DSo27Vej~%^;vwr)jrI~XpE+f69vNnt@p3s&*k4of>vaSL z1bv%504SH(@7NgE%L7{|V8X71!C5F( zUY|?Z`gjH^l21GpUYOtZ65j{oD{6CjF`E-zp(crNO>X_p!YUCptoJKr#gDK*t?>5P zHR@&be-eI03yGCHieE@TbBiep*x2(u!4wh;D9sfLy;VS^6zF_VzfuIHrCX%+57c$! zBz+MYJT)ISDZ+YSCry%#kj~*$!XeL~- zv;Dx+rLU}-o_BcceMJ-fX#S8?N2!*+H;NaNUgzVd1qLSo!~a*p5O)bcgtGD;UtK*) zfT$#huO)dkL`;s3~;7nAs0;Jm<({@%bP^;BQr2`aX^+M2DNX~Rr z)8t4`qR=LfN~mS(ICloTZKDZC9b}#_>~+`drn%qRC$Vpg?GCz_>eX`;uCKs7m&AD2 z$}x`6q>&~`EIIOgS(^duXn91Hqpu5_Q%&wNEA_>m;HL5Zg$|-``{?j$Ja$gLWMHki z1n2&v^+jhcuN7#n#=PNSIJE3d2nM`QsjDNRe1s?v)D=sQXqRrIdNyjlJnR-29MJDK zcz*6;1Q?PYH*^)cxV3V#`PcH<(30JWlJRGP@zeHOPa(Tlv2ZgB%Z6uS?_`X6%}T{v zkqv=G9pq?N1gzeHZHW3eYuj_2bu;2INh&oYeEhQ49fPRo`kFD*e) zl-sHWm=&c_%Z8ug+nNZVrTi)W|9*JbhjF;2lTEt)Ld5!v$@KYloUP5l_zcl9#RMsI z9Ti}%80j!n2(8cU3pA;ZJgv2T>3u!OV$GL1?E0ZOtOY&V<1BOEjk*}J4u|D9>{&03 zj*j%zZK+wcu_#C-*oQ_uH7oW<*RyDWqYQuKw0iFk=mI{Ycwf8o89XAe?E z`(o0O;^$Y;bp|!Xn2IH8dAvWi+=wuI=uz9F+Ox^HjtFRbEkY#e#Mo`^|AYXCQ5gXV zQ9ID@Z$fh4h4b>jow}yGH+Wd|w)RsUr`>mzd6dO%=<>Kqq3`A77+?i};ZDCC<@`*# zEKAL=M9sy$W%&8Ld=8&@Jag9)s<4sAQ0jF6HSU;0@{4xl=;IP=DcSaEk>-By=Z;%Vi`}zCs$Ln z4U*c-i@Aj;gl}^?46kr)9lsx%)N1xHC~Cd=sypS!V+rPboq)kKFg;R24TZXUP*6pa zDhk?!VuE2?2|@~t#H&)&fImPlb3~1P^q*OnH6W~o;kpev%OT1B-jj{4R7c>oGsx{N z>WBhoa?w1bNh{R*X72g83h-mYbp`w&H~T6S&vAVQQxTg@R0!lGOEX*=OAHk!*}|-p%;G z1m4Y(ZzY+22_T;+gI-?W#LE>HMdngM0ImaW(u39oGlW!qIC3E`*RL_IguNgI#w$+? zi8qa&O6|vOhE{rVJ=(^2{=tsC zi%8G`>4%%5WH=0M^|kuUP;j|HE|7dEt??K`{Pd=cm@je%Xv}pne;0weWU=Ouc{L9` zS@o~Yg<+Qr^nMf2O-)Fj5!hR#>>4+BekZhOV&;_Km;{&6i)WGz?M-wsu!dp`#b)39 z`1gg~Ir5me+}AxKG>zeFm)6~Bgqo}3({=M0T_`3Yv!U{?nF8D{UF}Y${ zqR2T50?1x(3!+od!$)NMYcPCFb|vl9z|*-SaXsEN*rg2!@~~HFVC*eS#)*SL#5yA( zHYcPph7oX(@%sykd`T&wT)zKEWlw_8$7Ur~)@_Ikkl^p;MvnO=Z^&}dN?uf_qBDuw ziEyn`NFsfOW)t0qU&aNX)KngH4)V0WOO(!%-;vkJwq^~C@D1vm7cj^}^+bo6tLT&A zG~%W^VoD3vYe(Boj6CS`6a09TdUnNqZbYC`9gX~}eym%uzSJP!5 z`mD2y_uJ;X1O~GHGuq)Yj-oN)!~N<%{cJNb_7GNrvi%*U9f3$WaPSf2f9?gQ3E)3K z2I9lsP5HQI7|q_tq_#|MCFpdPypyo|qLm7wStB9`%9HhIuryW?vC-e;ssD%&0s9`8ax4w4d~33TQ@6qqGvPA z#KrSt#yr$g^(o12U&}9Xbb4?TjLOHh%XGCXvVL_Ps_rXSIUep)oLFNEygVSRRq1*j)R3~%a1l1^7=V-gKu;6oZXD* zi4@?Mg+Xe@XC6Rz(k_-dT)r_g)%!=q*CYy4S(q!%C5M~PO-9qMpYShN|EQg}V_pQ_ z&7QNZ)TfVpRD}onpi=TfL~NmJ+9(f^Ueq$P$vAnu##F))c4t~^na}FA8iG*eM$mP@ zXSKoxh)^n^DDZA)6du#Z{;-RoRB_UVv_}X9$aijV?gE(Ah%qd8SbeY(-l^U$WUqf2Cyly^v8!J{uAcM|RJ*W;!Iy>-vf*$vV;?kzDjA5lP1W=L_rAHP{fcN34nhZ zCy48D2Ve0mL7bN4B8N?WXM~rA!{t*rctzk|-ZA)54+vNifB(cW709BBH}|Xh3zc#! z(W%8}2VXE~F|lxNpbpRfsrJv{I7X;V$7{BsqmDv6$K`slRt6QSkR}Uh_oUVR>NURE zHR>AJ#ojHGdE1@-zmBI>gTpD`UC1fUbJ$q1zTjFhQ&OC3R94|B!3vse;P-pEgS(4Z zz==*+@dtB${-cjz-}#czeo4y?ygWA@Dk{!!-aZH<9Uv+;g+t=(zTk)lH9jl&<(zz$ zB@HC<3IN)58K~cOk#j3H<-VUiS7`4s_0f6Scw??)$~PPVJYTxF*+s*3M~uxI_MFK% zKTED$=ydvep&oK$wUuN0Q~kQwgd30+)k+QGZmOHk9xS)wdb`sqcQ@27*74Qak9{BG z?&#?EP;Jx&b*KQf4aZ36$h^OSktM6~D#4+5CY5ikLYMEPxuZ_*J&fwEH8G=MtZCn*ap7#pg+yK*}STX8`Dh#4J&17zF?=JH48)UB`r z7RMHD15)|G2k@yBbeRukK;q6G*kdx{2@`b}jwj^r*a7W}e3XBg>ba4R1J=sW9Db5I2T8D!Gk)sU^D2z_ zF6%bS{!x)J`QfkIMp1QrZ{%U=Fl_cQXi9W$0uG#dmGLB+@2c5B^e5h}W7{AXr+89F z-F&wJOD*V=VmUM%(P>5Wyo`QsknMvGp;4fPT9;*k1g8 z>UBgg3UOp1{bH{QXt?lT#giO~!jgG!DQ-r7!|_!Z0>O7eDDu&zDzX}3rnR2OTBX%Y1PlEBN3AUc_N&t$T~TT zEvSWXdMx2<;?rZEol?2Oi(mQHcq<|d@9TVNjDmgos%t%p&qgf_Kyxej)==aZmqFCp zfd_==gh~m2;u@pNZx1z%d~~YqziRH4aW^l3K@3osA^eem*CbKeC|3IZ!dtZ8@T3TD zV6K;P0RKM#z_=h-9bg?03Q`9fO#u?}v`?Yo>k8NYKHenRibaWiXHo`VlTX#0X(*Px z)})CXcnAsUP2nUcu7gS;mZszMyKPlLHtkTC;2jWbPbqJ<|Iklfq75`e5G|RHIcM@mtuPVE3~Z6?jDrZ59H&2gL5AEUp|i*ER8r7-b*_^%+B zXQjw2M4Gi|A|a<1z~gfEY_-KK=#rajiCj-RwgbY?4MHdf1KG{K_foi8etI5~_jQwI zQTbPdD$O$`96b|sCd*V+mtU8%c+0K1E_Ipkf=l;|qPo8t3ks!uXJtO+aoJcS-ex`# zG{QeJ_Yj!}^5v&E`YUDKOmRRB7^UjS=d@XB%Ilg?-1TR9OwivJ#e+s6G7A9l^IS2D zD~oQ;uGEkXWt{O@tf`gMoG4D1>u00){vvZ(DxTgoFHIJrhI(mV>GH2jBJjRWWgvH7 zvqH?9;; zrPAU~RG_=)9f%K(USkE~G)s9sl??;8EBf6KsYo&Zx=k>p1me;cqrDcyBj2MO(}sQ> z81jpPM0Q>rAw>d%TmfSx01@}kg`LYdU zxEYi_>faD*ZJogpE*))9@_?9cnvSVIA@8zS2Z{-gc;8Q1qLL^abxd)uq=x_si~tqW ze#JX!GROKy!68tz2aT9cUCG`wnQt$#pMXoe2M|IxwUHP^DxfGHRidkFfH+EV>8{O_ z{+ykOXptXVmNCy8oM_3$G=4Zd8f^7Nd9&qBRGFzwz^g>Fb{n9%XOsa~5>j1qPI$+C zD-IzS4hSrK+wHZ2?uS|GDCPq~Z*mIg{fsJR1pd&859mgo7~xaJ&Kwwx>gNZwHEbfT z#vlXEx7ls|_c)mGz>-^uvFcG}Y9h2YN7_ynxoK$UmZBQ3RJsZ?AXb?`x~U$bJ_G04 zzco46;=snca2PX#4_cHfl==WH@2fiW*Ku+J_M`;3N2n=SwAL56zc5Q z+5n-Sj2N%^8(d^)7Q0IM9NcbvJiuc0)EE(GazuK%T_=@#n?EY;wg*O<2Tvuxv9-$s zFgM0QiPAzcz7azSOv4YkcBkbI(pxgK>Y}v+0GL!c^y!uuAZ!>gNBWJbs*J5}UpD*Yks`Mfms;4dZvZ7@2Sf7y$3V=@T5`IKv;)-5j|>%f zO3l^e%!YSl%(tCWt)FKB46OeIP5|76;@k4_2|8gZu*;liato~4s+zm)ECrH?0L+`plBH6{d#I}ygCY`Oy=v*oAW@Ao!eSPkwI(7k3AM{9oO`F2V z_xh2xsA{_Nt<9WimhG#ANgXfPCO+~zvjOba{Ius9o9?Av^{qu)N%8mbDa3|AACBl8 zW?uB4oDRie3R06A&KD6RFh?AO0B{oH=e}AB|Uj(-k zC`O`=ukUN#FqhP++P(K;fo>^n%9NJOn(7Qt{l6dskz6CDBNr$KmZkP?@I<53rjl=d z3@2Qu4p^IUAhDP=L8J3RaAyDp0%6;sxgdJfD#eNM>i)1fZ1dv9&TjJxE?8MXeq@m< zM#w_hA?Fw;{o{uo2%s)=)kPUv^Hzl2$(6x9Hlmpv&xMFJ*wdCimBt=eF4S zhA*Lz{3tP%$_~Zl2l38EXyYTqp(l zh;n;x^-y73EJ;~`Ie`<{d@^~{;b#Xf4WW3gXkJm|Je0CEkdoj!6|<30w2|dCj~94z z!jua1j`ZUzx@FCw952!_6}p>N-1T^T+)Otf)exqzN(`3LpEWXAq51jRU($v{k91XOQ<0(#9q!w zU@@*d>qyR6suDGJw$v#MsV;`e2Zs!<_B`a&9d7%?DTCOfBH)q${>%&dIzorU>b5D< zlO48VYUy^N-ZWubGx5L7I9^6Dz$`i^y6)QWqR9$IC1kRFyY z^Sw+HL9Pt#a&`&)>9s-aR(s=)KE?aq=;!--JiD{(od@v8xd_EtXNV!Ag02a7mi+pL zJBl|tjB=nMkXH)~u#&z(2#rNF5|Xp2Wza=~(%qbc(C%YHC{c1`YO#Z%lkZ?eA5~^v zb7t3|4u9_5DcV0;0UdL_%ut3?5VP6PfVRq;{V8d-)4tM6!j4e$mwk_1)Ki%_EK8@n z-;YxTc4nYL9ousT_lPh4y;FIxX?=g&H9mOv*prP@K8bP^*Gfe>9=n9U{+I<#{oqN` z&y`0+gJ6{B%CoMcj>s_)Y_FE5aO=O`w{CLPJvMT*@uIRcDpGddM)pXjqYw#Lz3FLf z0T*ayhH4>v?y>0q;pyr!f%Mwr^#cdiCsPE#%B@wcO9d(1nIQd3*qFjebS~)dMHDi_Nqzz$0^6rYL6>FN$nXyk zyf0n&tkw97A}2H9Vk%^nd%=im`Uo#JcfSi@Ne;IN_0WIO%HN{o$me^JoIVGQOuK&V zM#77D#g&rs-3KWMQ&Au}Cr%>83=?20HpqAV-U}7^!}r(MV5aBssmA(9gre*zasJrZ zm>HDrT!Skyse;|2aJP#o0apl!$nJv(BYWa~oeV3A3g)|wR@szV?}1Zha#1Fe4dwr2 z80JSN>+>22iBJe-;|aVoj=>0lIa&BoGFMF>xG6KLVOS*)Uy|Vlzvmj%Ol>vjJ4K+e zHDff?jI|oFYBJUdI>0c#mh4mVOl}j$flW;ofa;pJK}68K``v?CTTq*QoaO0+w+WLd z&xV*e&Vd?IsE#|(52I) zIo}}R+j89nF{yU6WIK@jdjEZrKliw}XU1~{4Ju(<2VUmJ9o3<8PkgR)t50LRQKZSq%!j_2A zPvyiIvCuqwvIS|nL)~3-dS-Bn@fOIN#R+$Ac7uR z<0^Ik-}iR%zttTdT)-q&R%bPrLKYgb7V^9ToNh$M{AZ zKQ-;<&5y(F+=2rJ*aNr6YPE~N8$u!P>C(k<6_0O^^K1d-x&#h`I;+OC@{-H(?+x{g zu#ruAxeHBv1^=dvQ3r`?MNd9fa=02liV35IwPIcKwo@ZN)r}YiPl(*lbSY+f5kL>O z42%vku0$G*tO6NC5^mppApPkdqt~$&Y|i^WtxN8MFerdN4ZwFsfC`1$uQXAxmC38t zTC2Y?@yYgy8D;x>BCCF{K!I)TiD8=@Ya=!4Sy3L3vGj-auL%LiW4#?aVGW8ICY+Nm z<&m!Qes_BOz@0!b#-G2WqbB8`--RTe^`w75TLj zcQ!n-0@wNCy$J?EpFXN_{?^abnHlyD&rmZ^IrTPQi*DB{!yhEPmw4=WyQO|(t`#Vk z@P_(5NvMYvm)3)~AT|@(qNwlV3(RmS6;aOh-}}CPgs1>pnj&VIm`mlaY!JoWB5)@c zFKo1nDw#Uli&geosR{J4mX-hpz7U){UUtp_3KL~V0}=iU?NK7w!|P^cLz)@9Q%s)4 ztB+?;k8_|}LCO;@hqdrHnmO{i->gqZr4xifynh^_7Ns?PZx zJC~cL0eRUcK{sNuwSw$M7A6d-YCnqlnKSs>{r>!;gM~6_v`^HJ;T?@0asPrj>g?VM zo(E1Wa<^K3313fT$nHO<8bF6456eeJe|I)->=+TXs+<77WV4dW5Z@!t|9feL-eKIY zs%r=Qfhu&%l{Q56+7W-A9~VoVrk58V7h-+c0iXu8mVMH9VVP7!WoB^L(Wbv01Vz($ zoSzfUk}vws%NJ))`xG@1PGx6N;ggTE?iYmHcW6ese}`>*egwW-&}q;Jw0N7fLtVG< z@`@NNozm!6AJzAhL$v(xa6x~i2Y~NT+=*mGjk1H0l!#=j#=5}H9Og3d+5zn5_;8cc zLVJ81fYd_EQj&%4m48|jXAb-N^#l)@`^T7@-?33|Rw4r^z3%faX-_${AB%#R7y6`B z0VhO+MJKmf9e@qCDV4C}!@2l!wtnul;A%_hAE*;;h`C;Li~QtGX6Y5Gzx_f1koZOj z71as^aCj~WaSqM|XnY0gb5U}dh5m-pEu2pVxp$k9^eQVdWV`PN<+VXw{Op{GeJ=u%@xHAKmh^jyMAMYMiR?J>xu zl4Nt2=Gs*zl(?#hroDV<8gEJ*eUgz0I$LvDP~8dQljP1!hXtj`s3fyEIt0uwGe$Dc zWPn}em^~6}g-V~DQ`vMR&)o6Q)WrQJ`BO@arz)B3RlW*+GYxJ4u#JM7K#`hr(B+vl zNw9x1hiuX(gMH7nspnW*x*g1a;3_?J0Z;@ad9pz>!hrI$8(z{U5T(}C7-)p3I)-myDJep zXeV=ByyU=HLMZstU;dN}D%gPr2jfO$k{psZ>;qZ(1&zcVEcI@7|8OU5(dQ;TS^Q>N zP(1Ial&b9M*eckoT^7-(TP1cCxCG`$j+5A?JSgDPN>ZaGTNJ@e1EWgAVEen(vym(% z5_O|^yKSc&C&nxNzcTv}|w?qpaNIb_PIYf#?TWq!6T1ud^4q~HTmpQKps2tz7y~2an9L3;z zlhdPJ>MxH6u%V=qf27G_h%#B9VX^DuswsL>F6 zp-c5VrZ%4z8H07Zyj%1$G&Eu?pg;W+KHfyQMqxS44gl-%4IwZ7Au~nhP96L=vK-{z zJHPxZv~4tz?abyF3E&+r*ugWHHP_cntA9UcHL@qG75Ub~3@{?H<%!^*!ALN_T6V(S ze~!WVhq)dj;ZkqVJa!yp#eC&)oc^uwm3?@#Y|W?UQkC?re{DimM03YB{p~KWyNW$B z-G+IM0;!YK{-dqb4X-qb_OW&M31C*Fp=)sAIfNEL{97K>@AsTIB^d=5Db~*Iz(JIY zEA5HTHX2lJ&uXJI_)n4JmelbXflVX<62l1b6j-OgC)F$xVYbo!pQq)pq76-D+b%AD zpiNK~RWr#jU^WPDa@q7=hehVkQ%<4c>*k9mt5N?pi2K5rB{{@KnyE%$p6sWbyGmA zV3YZRxLN_}t=SEa?2~NBNUAXGZq^fErYHa}gV|CZnzJYQnaAxjOwAhsUY$_@ttXM* zP7L|>zE{KCM+2!93S%S@S~)P#!!BtWEGf^#uWJ}{q>EJnB_BqLRb;Jsdv7NWYET3< zh8L=Y;wJ>tU>NyAfxo~i6=im z`|w0-br%8(m-ivS%iNgFz~o06bW2|B`eT?3nj33q$oNu&M+!_$^~PhkB_HHg(BbMb zckjWxFS(;Azl!6N#U>PC6Prz^FAsoBv`3VL<^Yp%cFa`%ihMGBu~%W7TN@fo9GN}+ z670C?=xpRerQgzf599S{q-Q>(0lsiThuHLs*0=o#a3U{kKF?{$?LtR@e;;CWZR8_0 zd0_r6_6KmKq{h>?j@r$TJf=+P96rao0DSN|-7u{5Fn0U4>GdpqET-)07%>?mm?~L- z0Y6cU&FI(0kE$|%k(2`NSlWsY)!Pe;n^@b=*jb3{%=aQ%WL<~zxau`zQRBOmPRvJg zbtw|G5ppp6>hp(RLf+Xjid?Yv)we9+1wVSk0Ma z5Y9>4WzrMaoZ?HYm{LYak#p7$ox|0g4zj8w(RGb0-UqL4%(x-)3vx@QM|GBEa+I!O z$Oq{+Z+;BdIEx3P*2EoU!{6LhV}o3=-Q3GOxa+`+i47kCQw0bA*#=AwA18u|kr?sOpn1vXZnE47foB@%Gwa^PiI{Zoe ztt@P*G-M+NiZO75zt<3myLUb=h%&n7;NwXHppbj}aK2}3u6IfCdg06+zvNm9`kN%9B6u)j4=vk!pw;{kNmI zBVAb0%xG+pB`jyr;LbGAcCoH-ej{(S_RV$|8`rvL7KTf*s&m-N)f^I&amOc}_8fV%+y1Ggp<3_S%}&i4ori9m_V zGy9<3mj0pV6nL?8x$7c9iCZ0DMN-Kz(f#nH({9<7$0LmBpA@sg%z_lPNP66STeY`h z@880+vJS8vvx3{E_HFr{Fp1DTo)~6Rj&7iAzE4lLrt}!IA!}ZNcpZxl{!$wl;WcAu z+D1LA)Ln(KE>%o)67DcbvvLC^(9WIj&OlxIQLM~E)HNq3a!q@g5;sjEP}k(>#jTTa z=jRC%TKGjJRtI^T|CS`{AP%TQOy+J@h@%pPNKKkbTx6cyT|?Ls5ABIKrIYWPT}0rR z5hp}X@Pu@0*gasdu}ma{K!<9Me!c;-WfP>?-EpteFx$g-S){j{62c53Lt-gEZCVAWT4bzpj-|2i=ka3S!3a$bokxybUA35idjQXgI!T$ATEHdN z#dz6&+F6&v9>PAf1bHB_(z?Ba`@<<&T8qk<{mJSr0N0b8sfwl(PL;76bR&wabzsGr zydw#)uw+p_w2%Iw3qKq`l8Uptd7~+1`;swg!R9avRLBI zmkpzywyVu4qvu_9AlPt4WafEM*b{k3X4S`^E~Im=DEcH6RCagM^c%`W$k_mO)B;HJ z+1}0K^^E7!V@Vgm^{8N3Pjgc{XKbqgux7HeXz|>0tcsJx{n0pnig#Hi=id}KyI7PLjv=#!<4$>VgNuQyLnHSBLTDQ_ufaeU~a*=>XE@ zgg`Nr$^E%?{Y5TNq6)CdM}3usV_DPKo{cx$kEYiFjFSuDab&wwtx(qzLrGdG(OWlE z+sMHwHfKhMSP{HrF?Hoa#_lt*Dsop_K-4{&O~~D8V*<6iz?=K0(1zN%ukBF_UfRl8 zU%=<JZbh)q?5;}+la8OJhMH}7d{?dq&&!St_abJ#Y^^y*>uKb& zYHA_wPo+8~0SkIYYlrMo8?F^UQ{-bQ^(2r!oz>GQScYnp&$XD|c4DoCQxU=`4y_1$ z^vIDG3fv5035TQUTQPz7$i(>N1KOK-RSaHq6O&Eg9_osi!CbQjt}66xS|Z`+@!_(R zcE7#Ri?MozGQ|d%oTyV&llV`;2xw8$>iJ_co76?ZHN1f1`X)VEroz-r8Sf8g82t~a zzNmgB!~;gTj1I?Jzue1e$lJGtr(BZ^;m=aCOvk07E1Rt2?fwZHJt9eo`1N{d9x9B| ze$NJ{(aBP* z6NCzwR7Eveej3b>GAj7ZnhIjx-1E4Rs+#Bi85C&#gStXPC?u{`+;?^S)Y<>eM=3M2 zZzAM!B2mUpjNwY64`iRUU0vP*4L}AFd%q){nw$pIUE@<%NM0YtNj!zX??9O|IaCjq zO=c&F#e%TMp9Cfi@+0ZS0p?)Bp85noD-2h*rzn)7Xd$!gCZYv?_sw^eLI)H``$yFzIg@5{WqFvf19-hNr$`)eyj0?9G^Rf6=B05`ZeOG`jJ_ zx3{Hg5dc5gZaMdNe8OvkzqeARb$|BqA|hX4N~7T+8%g2X{Vm=%>=RV{2NN|3jR+&~1!i$lTQw#`Fx&Yq%{Kqs3$R_d7nRv%5{k6!&xfgEf1i1wk zb@`s~B_C%`SfXVaJHQ{obt`GED1BcD8BQ=vAx5780y5X-c+x(<**hvmSk}wXPB_GH zIeSRtw0s(ck}%}~=K0by|CK!gO-50I4VtR$z7a?^EM(o$>xpOJi5jfCWc0oI7wftlB6>aSJ4iwMUo zGY%HH!rt6CMQKg&apB2~=oPjp%@~1gMy6qKC8g)Cb+Gr&BLi+^Gy|o};_t4ddO65e zP!WJ=69-5tVQ9}(+1EHx*mIE%2J}|u);zcH3?vWIcJV#PxX+)}W6q7YU?v;Gmv}R+Iq&d8 zHm@wRBSYQc%4D#qjt1$8C7v3?;`H1&EzW+b;Uh#B9e%CCvY`S00pUVNI0s3s%?i@K zehdR?oq+BDnDhxo`exgkndq9NK!EOXHb?W!t6ixY2^PCITF1lH6l+i{QC%U0ZT%3y zQ=MmstrUe<7Z{pzCY-4L6;$Kzk&7mirTmZ~qRVi~lVQh;tnaN#gkl|T7O7zohc8bEQIgil7ha?i@-Ov{0pyNz<4=y$ z&Gz1Rd~b0yZ*F%<(98%e_P(asG0Lf<8?pCbtLtGn#0@WON69EmQ%5Tf9$Djb2{p<( zk{xEkl~38}u;a?j5V*^v`6k&<$0Yq5Q{4vLG;&1zCo2D2qIszjysRKlup2BpO-KIK zkW0Qul~lWV(_WCA&C1_)bFZ>DX1r2WS~Lhd3dFH%IXW=F+l0@ZlynG_0UW4(1v?whx>Y=VgIIFdD2;1+T%lNFF}`7% zM_tHYDDwV}lD1I@O&6Bhnu_ePXz}tgk48%LZbwG&$27kqRQpIfISHpyXOfVR``z3s z7uV3d3m8E8a`Gxj*hb-qXPX|4^n2(4`<`>f8{2)7d_h^M3zePIz;p|$=x z?uu7ct$nqeME}lqZ>0ayf$QHW_SIpwl@$N_QkQfb2F-1Ut+MXj{y7EWMHSkT2i5N& zo8F&nMjzAl7xFlwtg<@B&hHZnGYy*hrp#aeT4-p;bl~tSB7RMl*OZ~vv#$(45^cM> zVn-!Hoko>7MtZn}&$s=}d#^mkX>2@I^Cs76jOKtz!OBT|SkpP#>fW;ML-q=;^P}q= ziVc9vP3Ax>!cE}n#aqPD^0euu1?8i9DXLC5iRb4jQ5}1zGTA%;NwGhOAajlhIuqhc zv?6naax?$)lCVkJoVLryX8M?%aC++Nk+%GqBqj_E33!Zg4(kSB>16fwG=#u}&et@p z0O!?)CKb3bAxFFk!yBx6pU#>%@dhmLV>)(|doKFv%t>(6P7rvaWNN=xFXm*Ga96iwv0HDB20nMs-|)3c7^XWBE$DYTfDC$d24t3Z zN}!Bhm$jgIt85z};T@bh%?@_NrTpv;LyYy|Hp<)0hxr{JE>U!HXB4KQ0TAi#8)=9D zErz!kEc9gPF>(c907~&M6=JgwY}>#v@#C(Owae(d3&OI1;c*bEdZYVFQ5~V*#0#g0mFl2&WL*Tt1 zAOx?uYaJvFu#o0tWh!(#`Q^Hh%CRcDH4Crb0css7Z}k4#g>_6L-cSRKC|DXQDJ_qE zn&p`%tX6x;2PMV8dg2kEeNZ}FC!{Oilo_GbBitD=dm2`b=roP*;8 zze)^JAxl6l2I-}%3%-jQ`ySeyma3amA3X(%DKNYDG53AgD)^dMQlK+(Ff{nY&$16k5zi#x{(OX+Nyp{c5nr5nzOyi^-#H#RZ=waXOQWR=$_E&G@-#md?>2VBGE3b4ANY+wqOG#au&>3~t8s1Oy(JC^H4 zJVA`jjMBzf=c-CxT3K?PxHEw5y;`~CiX~S=qzc!ctE1ZJI*2QC)`rSr$^T8JeF#YL zQzLe$Z}bF&)cB$eHbzbcd>gk`b&s^F?^UsN3dYhBPrsdlWs0u>}VjYoFR72V_M6g-()`g}pS(|GhQ+ z^(sdk->f&a3f}$IUNxE8UOwa+A3UHWS&3%{qxgLzVd;Z>Rj_V;1thpPte(zBM zM|^y~s)G9S$4zxAv^1JQ3p~%DLmIf>Qr91q`;lW&6wzNLL6_^I76rCpnHAN@DzZQW zt&AC9U>h|daxiy&%tl{`Bsq!jzi!{X@Q@rja$e?SUTyfy@MZRD(Or5|JtQr5NznI$ zhbHPNr8yu}G^i4$zf9JAuSLbeU*RYjhE)XBf8SUV>!loe-y2rBh0_pQA#6AjNriwJ_ww8d&+mi0Yg|G_Fvz9 zZa1?W@a}`fVzzK+5C(`aGO50g?c`J#f;BpB@81*Z#xqyutV1PIE7MWM;l(LdM?c!S z3>a?w^7>f2Dsntz$SP2t^0kKJyb}EWpbl@uA-`cE&%1X#XJ>tOvVUz<{%sUBX-q=`JU#= z4NXQiN;6&pTJ=B7-!OVoiZ;W-+>FPau`i}|^q{xo+Sg_OrIQ|aX-6$Zj;^CLUil;X zZG8k$a{V9_-sGJd@Ev zz*i!6AZ_ioZ|OtebQ~KXM=%Tt5i07lqO?9S6zvU92ExG*F?;xN$ed~h_GKQm<#$+hscsp*ICse^V%8;L)t=Mbo3&AZl9 z7&rK4_3_oY>$8nR_W$eFE=f!M=QRP#po*G6q?k)OgP>vp6{qiw>+z*+g+(WvX2sYe zvAJMdQ3`W{HRex1T4Mi3i}@P%B#DNr?cc4ZB&7?Qh@%kZY2}cpD#~<_&{K3FWL>=( z)`?c-x=U%U@PhR^Jc^}>>!`Le7#`=@4_fz2N$yoS(UoT2!oFz zrT!1Wl^o5Vzdn%UDLdi_A2kCEQ=DZXAq?-}II2_X2yufFxyd@nN!Gx@><->O|Hn^D zSB0Sdd-0bA1)f)_RtR!}x!rj_I@efh8HQzgF7J3<@F*92HoAG;(=8)7y*p?*qg)&c zYwu(DBf7N$RrSi3+>G|2vE31l61zz@E~lEVYWBqL#&rSN1mlBKsj_a_NK;v+-HH!i^)Hf8<5{b>xqkYqc_&BGo_vZ0wXH$ zVbwtLe%?nmHvQG2W6?LQ(@+;@l%j*)1sW@emq95Rd!&M~j4pUqTj8yk}>iU#oM-uIr- z2NlGkju>8Ii1ZwTkk+8f6*tS{rZ4|)kTmCTsuB%n5-FAgF(ZsXR8{~T38a;aYnTRk zkzFwFfvQqFBUTFO5VcKzdjE7e+kQuST|xs)>K zQ6Jgx(UYG{c`C4z;&@t&185jLagesn12j?isQuIUGP6T(?A7WCK=$RNokALl*EPq*Oud|2(opaF9s;hu_YbGaFodQnfS#*tLMIorxzy@>e zu}`OtW)C@t!BdZm5bTIRA^dF2NsLWHc}sMLJ7!%#cVqL4?I8GOYaJP)Be^)vwu17s zEEq>Z?gnkkGvgkD56b_B`8A}ps*KPB;k_ceen_CB)*&|_=?U*9Rfj3GNC*&3gtjkW z*SKdu2(}WTHcN4>DBCQ9x-9Fs4RX|`tiK~*TkL`|{?pWViYG+uZ2(>((y06D1c0mP$OhNxxK-*r zdd*i>dfI~VWybGqezstdQ$cWDRoho80h{&mWHLhi)qU3Jk!+IN5kmM(bg{>T$C_vG zLWEg+ZEr^U=f>P1ikxO1E+03DFS*Ahne%ArMWf}}Y;5^>cC2MpMl)M4B#JnPPMEnJ z7&(SQ{Tx(d#;(nnRhXTzEYgaty@Z!aTCcr|FCa{TIbPLe;#(ap!AsL5<`ww;$gB8} zyVh_3{};u<_*6Ew3C=>f_$B#l02bR69nvyZk7P&bDPTHqh-#+KOlO!>`$7HhN$^pq zt~YBwKht%-S9|}tmSrGlFFC(%)CFFrkuEb&N=MK(s`1F{uyMhdzg4L9fp%sY1&{Lf zu4-kBoHpD3&JUlQ;N{={G|7X5Ln8#eDd}e-3u#Ll-E~<204+(fNW@C~-eXx!N;!p006Z%t-4-9{1ECPF@4C| zVdfFRnYPYcRj%gE6&BDy8xcQ(IF3<*CMXVbLv27dg1`7Lkr)25!XuCRG!t@{)ls`P zw&u+@M}0pw+D-v-L6B za8$CZMkW zxAhO9;!&6xe_OlNg#jUew+5K!Q47uEW_8WlZdCi5RJ#&H3F|`W@NARV(q&qW#2Bgf|VH?@{)Ht7pM z#D_Mw{+u^R1W{D)y5)%I$D=?P38Yyw9=k_Vu}F1Vru=F{P&kJ;g!vcOv7k8MVTWG4 z29<{4IyGqqw^5%@cpcH*ufY+RaJp0;f@xmI?n5pS%o(2@hY-dQI*uChgQNL2!MIBZ zRwGbkd?a8q=|-)07sGO@WdmKj;}1Qul8u@Np1i<>r^mxUkA%0%TF2U!Km$^>D~T05 z6eyb_0CNMA&g3cZ38w&6+!FlmS}m8|46SI8T;bi`=|TD;$V2+QJ){CMrp^&$>lzB& zxl1eWOVeJ45JHkX22?ND`3v&$@*rMEvWK#N&L5cDwCf z%?flg3WHR|p2o?MCL*ej$`uiX0oqth;<0BM>T}d|A?DqQBSTd*Ns%knZQ6-VuPcaC zx1R_VCkbt*n^2~{salOWc_cf5>6Zj_S_6piU#a<}#kfZ|VS?L?l6POhfM1!eRMMwR zgp>5B(!n}|_7cJx$ufb?dIUJ&bZlPbynY@~WJTfP!y8>#M zkero&_>mhwdwL4f9@M|H+#@>S2k&*58{O25i>+b_ksV_%N|C!*`?Vs=%%&nPDR_NY zKSNTLr6whc{m=*B+UlJ;Jd+54aOI&l<~nw|zEzT{hY@6N|Gc&z=yVqauj*3ey(8Bb zgld5ielbw90(`!6$$;j*{w7$hpyrDUFnC>+<$b2dRxs z2|`&LPPoaMEhii>$vMMBsVOqgI$od80~nnkIvoppBl3+#uJfR-g)jj0qab@Z7+`o1 zzcTQwIPlC!T>egz0kpP}gT9{iWRbCanV17C*}_BzJ74#N57pB{=6=+!Q*>WaW&U)-BMUQU{%kk3%vM={}w3Dn_@ zHCTiKx^%a=tL%;2%M^71$9MNem55MRFFR~)VVQLuM|^yusf+i%5`+AjPHD2Citw^m z_9Z(4;SG zv7kr?SZkSfNt#Bh&KZCFT|8px4jaaqZDc-VTWKPNBW#I;>~^_4VnfkLJL>s0Gf9=E zF>u-Et4G|sJ^NZ7&c~SB1d>+mTCadM`$B^<_Y~YWnhA03>_|U^#uTX?HepcpzRNxU z6|}O6gG%Z7xm69*@lw=|BpSaQqqqKCUO~isC=L>MSJo+}z=b-7Sv}NZxbE}9({o%0 z-xYq-Qk}Ol18*-7X3whI&Ebfp^yx-$4-a38N$Xp~r*qLF^Zv;G&7pSLf6PKxyiCR`)MPoO2;k!~!vkJzPtzJW87pcD!de zvU#=hAUxg>;s+pX^$Oqx^x)~uwAf_crdrM)=jTMp9|a6!1;mJ)1H&a(;Q9}k((aqv zET7<$qUy6hW5N*w_5kEK4uHPKt^ z@+4dv=dMMaTfKv~2Q~BMtjZmgws^PUvZLWGVWWQoGyQAk>>1au0CasuP6t);2Ij7~ zEFigSUf^|6bv~MQF{~hbi!({co^=Veyszk9mkIgTgyt&y*%0b^RVjek<5}YX$9{Mt zLFp+|(}IaKtd@~QOR-tf^9btQOn+17j}g}AcJ7EJ_x(XlwrL`UOl)y>8Wg5E+UN6E z<_(R+b5dj}b9Cdzl+M{E!^f9;nFs$c^1?=H$JS7+u;DI?{=BmQujkKhQw-R(4Jt)a zuT2FI8ug?R$F6o9y6so&#*idwhEXbm@j2z*T(LZf^`IL1E|5783gI(Q{4uN=kerjK zQZCVpnj40XLxv_Cl-2#F;&*@)n2uc4IC|Z_?>!90i@?@na3~iKJ=g`cPRI-A7bXvv zmW>jXZX!)#j>9u$n%GxIf96wZ-!9x*k zo)7XaLeYx0Ol;q4ZR+aZ~m>*7LJY zli!04JD(1^6asX$tHE(@*|yEF>qxvy&9oNjs4~v$noXJ8AN?Ut5&?0{OV|I*?Gc6O zINM{rdYp$R6$&L~t z21Uy20<^nY(ca)uKtVyE;xaPv9X*v?`CrK2yf4x@nBZVHrLAL+t04s;UKu)W#JiN$ z#}7Ao;!&W?cRUkkIKX;a_3tQndJq?-`emgMlCb;bQY1;qE*)JCz`N2KUNCmi-9_iU z6HE~Go(GLwZT*)!(`^e^USKXiuE3om7$et2^s1g@kmmyVLu|BWr|HQ2M zIFB6rN)IU(2i_-20RKM#z;i{>F`2RJFMHQ>p)T^ugmribc<0lDTL9|bqW{|Sk+~90 z&3l=%x4_%+++sUD!ijSrJuIxty0io{k>}LV~fcbwk)zg8ya(A`E3Oqd) zN3D9$TYo{M-SD2%XZe=X80fONUd5KbAhxL?Zm^<0Zo8gz&IL4+lIy7{$}4Wi3}<;R zIJE$sEi~d)_I}N-uKKnIkJOQ-F_~1h2cP{-=s9w>!JT0WUzUgmLs=g56r6}U68ucqp3zr|PoPxxUk&SuTQbJ@tl3u7<@J2`wT6z8+PHBE4PD7k5vG_0 zWO~njq_78k5V*bFpW^t;0Yg;jmrAjU0u5c>f&MGzj_$$no^{8L?vfpS?4<1K@?x(B zsD_z(boE-;E6e5ndar5UvW2v4snKB@t7EfbnPAM2H{reox^QhuiL#)@w?H+=W@dg3 zBCx8cb&c|$?UunHAS!@=f)(CAs-In1&0DX?_E)Uh(MU*`=_#-Pk!?l|m!^@iZHXrh zap}y@h?X!H(~{@7hpej_)vZrW+g#+m&bd0eU=jN{;JO1F`VJ> zh+9H2jHx*B3-j~~+<3?$8FzMyDB_{7cWIeMlKa%ITUu?P%lL8Ju|)R^2X! z`vAe>=Myz%=OF0S`hK9JZQ&f8>D}+II65}uTKueqljmECnvEfPQI~ZR5kA&OZUCM^ zdsL}nn!6aay-M@w=xQYmU>?b#o^mb%f*g&-SZN<`XrE!}aQ|CoHI&=RVH9K@$3-Q@ z;?wb-#>i|?m}s41nOEYcEftfH8<{F$5OTleojiee3NMf@?hOM%Bupw!jFXRlmdkZ@ zaKEf+^EKgw9=4r}V$4{LjG5@Thn!4s45WhZmF6C8;3RC7v-=?ISfXOp7dTv-+-?rE z;weGsO7WOtF}>Lnj*=}{pmmCXC+fVE*vyHb(MVU~E78?X50k!cn+9OJo##er{d0fW zd;~zizj0MjZm$SOr@QjbTobZM)bT%h*u0qt8w!`PxH6{3I1wwjP3aYXhQ8Zw@n-nl zsUP+_{uTSGM=j{V6GpvZRksRm@sQWGl@+@9)4B(wy1G+lP@0^&5%qvBiD8-a7=|g{ z{@WjI#;MT^<-)NQnwskBsFV-)!0&2U5L@Gw+K^WGHfqo!lwFVx7If<^#$%UB-=5^H zu+u2nPNug!mO%f~60apbD2Q&9$3SPEkiNE4$)d{uIyaP*geXEqS;r@1@hC4`Vtpq? z^ZdxIR*rOVy{YuF-(iG&YA>{|B@V&gpDA}X|6v!03mP>3LrA}Lu@G^UqMr;6>=+5m34Fnr&CHHnJx?08DcYadpR*Dy%-H3rwbc~l@QjJWMHyP3 zI7|gI9&<(~#0HyiZVC|ad27G($}LX*>#zz%d$95VL+r5Yo99b7COo*#OQ1Fhz&LX8 zpXGWCc>{0mPs(8?K`8rrj7Bo+>0HQr%*C(?FpOM66UZs{&T@e5yL6{*FlLk@eA6E4Aka{s!Dyb zXE)c>6}iRDC^JnZmoStbx3bp`Q;xS(fF!RL|^G zA#L#DK&6UQd!-HB4AeS-7{*q&x^xouvqzMIjV#@z^_7N4n@d@hz*BqodTuU;Xk@GN zCS2b;f+NK|zGk%?nq!_2$6NOzvIobw5hh~ko$hS!f4+H+SUov&N$Shj*G*BN;TS@p zKFKkn=Anpe^+#Q7j@bgWlwH}XI=oGr+HKGqX`gLjwh0r;hOd;}ZlA5SzoYN(kl^;5 z&>?65Z*?GSY3>DwCJ7Lh1ugQamTvHSXLc^mkxgZM@5}`pPAHO6k{!drcL`ayEP1VP zT=Iej#c^J^~$ycU*v-}uOZ%m&amZ67QOSForP(1 zojg17h2M#fO-ukR8F{-m|5keZybL&wywX4f5|8Q5brwtQ(`G%q%Kmr5VgQ`&``nu9 zHfhu^AMli{4;g6@tnUj;kFMkjK0vJL?WLt;2&Vvrg27Y56X09MII&b!iZT3xSZJrh zkT#Pc1#dUr<~-#EohsXo*-`;$XJ}h3qZ0B;><)y$6i3|ta9=wf+TIvqIk8i))FPj@ zHngJ%6fb-f&BfvQ=Dh@Bry|Yc*99C1$P;%KmbLS;dyK>lA>#3Un2ts1$A`Wm)DUlO zb)Rd=+{y<(F7!L`rBSKWC^1||MG;{=Ni{v!lD7cFN@cLJJArVe;45q6?mm;#rUZNv(MBkW2m>yOz?-1n&f|qLH`|sMQ-daX zZm{-soj?p=dh^BBG1_*sxIzf8njHu+ea8r}7@<_FkVH88kmW0xf4aU6f$u^VF3wgE zL8c7nd{kN`PY*cTSA^_KeMbC4AYoS~GG!j)9lpbGb;!)juiN@i(m>E`@zQcL&8~M? zAP;9cRsbI}?}Y#UCPC!RgNbz}Yv?L9)5Lyl=M! z6>CEaRN+ zaa-RJQRc(fOs5LjzIpE+fQq`de{KW8n5Y)7roz11Y@Ne=a;nfme5Qlk|e|1>y`2?~9=3?;_ zz4bsBYNTbLoVnoc>zV3=LaR*}wg8N#7W`3BqJ+4-`&n^}vTe??^EMejIWo~1=g;gQH)JL`F zd*Sr#!lSbsg0(HJ>yV{W@HgVmY*_7He-S!|Z_%!KPyt)W)Z265Ugw7%X4rB|;xkOs zTMn5}c9q?Ned%Jl#sxlpP=8%4%uzS`==-Veikr?&WRRB?A>LT8t-}QVsN)Fo-c+(~ zyp&|IQXNp?-z}_+i7QH{fJQj{!^q>mIVz0(;o_cQ;1Pl^v)ey?t^2X@RIH=VM}`vnmPh+g0?7{b39M^ z>)GF#y{34|*2r9UAozN(yG{{QzUfF_9hx#zM0g9P;?9pLZgUQ>+?yXujbrZK`y*MS zbG>-_j#quijYZ0+H4jmP>&}|vo2Wxb=X`D>+QVMrZNCG>wW-GGt0R~ z&9%jds2WZMAedIzM~Po`uqeESFvtfceSGVxD{f96NW@92?a%*IMp6*HmkG6cx)gy7 zqH9(gd@lzr)!>;YH*{$Q>)ES0TEjLSF62*X`D2-6W**TNXFoSsZLs1S9LiTxfjW))wmpRR|3+In zmU{{%8lSAvPWh&3-bURS^@gW!kWu$aUwqfneoJvpDsk8#x*JmeQu*bqzg&8T12FOQ zQ;b?$zUdB`)jb%?+}uCuEbznMW7H>^pbiJSr1PBW1QZe1VBVl|W&x(~7r``PNtb`m znq*eORbMRcHLmWbV2i=|#x?W57Y_Ou5DQx?9>ivvr%XP~{7U$0I~TDNmo56dgUg^D zu+ePwth2Fe5T+nY`J37|2VWW{BgPy!RHd!?CLAxjw%&70_Kp_1f!ZZe4O3@Rdo27= z0Lv{f;!12H2baq+8xa1m%j7oIY_)STR;awr&I){vT6D6M$3*NfTv}B5=cRnejtOF< z-V<6~E~|w$%l1tWUl9ZLE4r=*+GVLE^B>S(=yGrT@2^{=UA-EhLnST`{Ar^GbUw>$w7V0`~3_)WTe1zxdqZvnx zS=L+FkLSS6V_np#9P_9dn+&--g0$Z@+FpmlcF}NLpqp4}Vy6mlI9l9Cb|UzeXWE=i zw(3*u7V`}K1pU127SYwh7;D7p7c@w_5@up5 zzr9*G+u@pJa5w|mD%7b$%Uiax8M>|Z#Kxk>+hY%9%3?HJp>f*eALNpZW0NG6@ocj7 z<>ugO9e$etmM-i?;}75j0TE+m39Mb+9vF7%eeA^Q(Qb1+G*ks($7C$faw^GOd6j~ z_(aN!3B7jRO$h9e;KU#8`oa1ljU=%N+b60`^h8+DjK!bM5QuY=ap3z8gxYLc0X zd{c+!BG`oY)Q>-DC2S+?8aOlUDYi+DzEg@2K=Huakv6z48A%hZ`i3=uBydUw04qkw zQZ_8yq~T)}da?EFycv#pQ#d=QUhGAUN7Pyn>Z#t_0{)rcPTeycuSpR1FB}#rTdj-- zIzg^@^v5fK+G3H|tcW1f=p+>l5}qRldwzwcfts^WHv0f+b*_mB?s%H+mId1IbH}!85>rNlSq9Gd zbC=~VD0sZ1!a+tW|7RM4dOH$ZJ+4__J~_k+W3#(pzs3ch)k-828^6HUZ&g9SPO9tNV;5~9RMF%e<@K@C)++iM?*v9KgnV^qK(}EP`iy6C{C27?_&DxG z-SH2H3Oa0@HHs28ve6a;lgg`?&ytS5(|`Q=$QL% zGC#sQEU!v~`wv2oJT$Sk8trdNAcctj)N=7p{NC{|2`Ln% zUN%Fqu^CB)HbSehKs%x4q`<%b!uL!ljtrmF@J;kyGX@RvI={J;9i(Rg$zNbJ^VS!R z(Dl^DcDOi<$E2F>qt^%od8@83G)=zgV)d5+keR3eN7=z-uHzwbCL~6vKIi)l2zevqDfl~8FDpeidP&ldx6L&AZjN+r6$=R4qYvn z3U|tl!w1R2>IRM=RYb%kBE-Jv)@N~}zsXdQ zqN=R`m)l>J{sz_$3Ezj!44ZhlyR-P8CIvefXf8O;!FKJ=8vUUw6D8WTiZA?olN->x z+~rFz24WLJFmxz0Zrn#$T|q-2MEmeG(WBNv2ZfFq2Gi2)P<0oLa0|5Etk3Hgj-LOQ z`OYu?80PkbntA)R!`yDyKba#QUDGWvc~HD8Y{0vAP6@6{a?w63hHd8mJlh9%x`z&U z8f)Vh+sMYHUMh|Vs9!TREIMJD9;xxh_@5FY7{1>4+XiI_LGqA70m^sIPw)N2x3c-x zt7&@pE6rR)*bUr5icN8ua;aXY9m@(-P%Nptsve()SlHTj0iL(}Y`o5kpChL5`nrL8 z+Q&hHBI**GV-}%reIO+pS}>2@eb{Oe1taYM-^ZxoAG!&+B%mqh z-Ann4Q8bY)5}70o?&^&j@xTlHE5*u23gpMXOI>+j?GkGuJA#B*(ubwD@(N(>4GmShlvu7gGt)@WZrOK0v|59UB}%Kl9t6FY@I1KWDp zmxc^{Y1Krjee%nCDZx-UfB?_3N`Phb_`HU#(~lm$PU`Y>E%{kFJ(HuJQ|$ZK$IlpJ zbnTGCS8N2g_uO2WCcPyGoQ3!;=wVg3lj42!CY3v@k(5v$#ar^$vB_JVb&hdfW*q!t zgpoCYbSj)^{hsTTbOHr{4D zNO@7WM#c?stBXOZu-LkG5Q;CsLvDs)#e`N8NU#}W8X*=g`S1XZ{#Djj%2Jc0P+g}^ zoe)u%X2lzfR03C>UY~`>n1q4yYMEqHdrq(|dpuZ;ZOPavPrmN>$UM>QX|L6WOgwYe zgNaXcA0}^s4$lTk1}{MZ^{Wj;RiyxrC{)xyn@lN>)j#S`Z!GIa5b_QU5^dvi)MSg1GJWm4@?}qZODzy}w-0QK z2w_Dv8l~Sf1hCaeM13y=Zc(IF_$$nTQn$v=x#cF+TSxzKb0@*ktlq2Iy4ns^aOSl+ z*PE;0J|r|suW~8JjRcy|f5ZnQlo_}Krw$SGOk1!~+VIi!&$LsTGoP3^H4V1aCOEYD z%HW~?M|P*QMX*Vtn@qHpDOp_@msZ1R2ef{BKe^li;#fP$Y{*UA?n&zR<@}f@e{TSi z^4ElAFF=h3c#VuzJ zCdN@+nSpzoAVKTmuKDRvP`0uvRxkRZWX)f@XWIzWEh08<(7e!|zrkOUV()EBS^aQ0 z($YMe85e6y_=zYb>VT|}#*#Njf0K47y5*Oo`P}xpQDDH~{I0C7?~#cC+zXUW!wEDu zp$UfD;^gQ6D}7|FHrjv8Fla1yr(h zAu&U8Zj2=aoOJ+rp}&N;R^OO7b7K}5NPWfqFkO^U&&1t{rxbl|Ru8^ky2XDeG7U%XQ~F!yi06l>#-fY|_jwF5>%zj^v6PnY4~QJ>CuW-=xd9*fhp z;Q1P-EgZ3GT6^^~r-(q}eBXJpdcCD^3X9Co#J%m=1)A27LuetTi!;YBC~apZ=djH0 zl*KVhnqoWZ6f;(G1!TzQCdmpX@T9iw=oPqAsG?)EZWJ(0)g!hdkJxURIrObi*O)`p z5`S^enZiCg&XYoRg_q&(qc6-y^CJL^a`%qAG{vpIlk;9V7<5># zHtM{#_F6{iAE|Gc$>pIF2~XkLoD_hDlo=#R&dP0nG5TsJebRfG5>i zgPbl9%LY%4uxkv$_7I)SIu959NNQ7uj~3< z5<=N|y)&tH%cT+!jEyNR{dvzxI5moL=_DEVSp!(L-*YlD$(}R?&FW;7+PkB#EJbX13R`^u`5k*NEI=et)`#345 zP|_(!MGa8FxDwHXOjr?`8J+Fp^2wdkrLj%|3mfVp(J?|h?Km1n<=0b4R;1_kD`B`f zF46Dg$Ivbd08(HJBL)9YLtDE1_-fJ*L-oLmYJ#H5k9|qqm)f4Xi_nnLmq01|j!4vl zvD?xD2aLu*_A9&ohA(M5R(|Na=~iWfN`>_%10Hv>;IY%}MJf*TeaO#l}fUa9>-7$42BsqYiQ(* zw%@jTr)}E{7d5U)NFL-tA01HCattfb3bxy=VZs8TrIEs<7DLk_oSqU~ zQ=wxy@WiIKT4;R${_vK)1*W~zcV|uJnlo0teGNf^&@Rzv0Z(f1W? z!M{^4q5eWY)y;rm)mBUkflUMBXt6aXK39xUr;{u9SHqSETNtTH{$;gLND+f{_P>SH z|FZZ>{ru@~&h0u+b5X<+?;Zby$j+_%?(3F{gFVvl7k~^JK^UWRUYQDzX6$H>vb*K7IG|g-EU68SOX$$ zI}yWMVLMY~iS|o)b|Lg2!}@uQKzT`)K25hz;wGa}(I3=rTmDOZ0v5eS%qC{PQi3@0 zm{)1Pby&=|j$Bst8MtOD7jG9IgbAm6_QR>4Rb8NbeowTrmk^QOO-(kM_H?iM7*E=Y zk!6TT->dtl2pt-eMzIo~|aRFHr_4+6OMg zUCmskpPwg<0?ambCKS1C0ZLMjIf5azFYjj#F7pUvV7%G&a4<u zhz+IPV94FMzA&|~SU&gIbeh8K*W4iN#l;F5Kkj&#@I5Bq$n!gqtL(A%8nxqP(#ON8 zAXiXb?b*3dQ&k`_<{L~EVH{(JG1sxx4FjBYzba78-lK&7lu(}rczz%HjWnDQK}RX> z$nKWT_!@|jK3zDly;oOyhanUKR}+QZT#a~BDwU8o(TA#0e}(U@&bRX|ls_}_W?6;o zi(wkYM>77vLa!NfqH8O6UKY}t=Y7c_H!VDfKW8;oL{qD{eeuTZ%m2)k2LSENR2pn{ zhLu+kYqKGAypihn1hidr=Z(i_;k3@DniQo+e!v`~F7$BGZ~hk+tSvXF%NxrZmu!$9 zQtvV0@IJ!4)pd-ulTOHNC0zfv|C^xB1b3vAz@Rwp{&3(slMR+XHGI1ZdKIGL%oj;t zGKjf3$n;gxlZkxN#{WD&xLyXXTibf89h@^nRaodod?H}g<6mXCg;~gw#E$EQlVZVY zT$1&O~jN-AB46bP?9wGbf2P4eIHYGMX+4|@i$d2XR)u7%Mk@TIntLGlq)!MiG- zTx8m)9w%EgO>TVOA%K^M&4(AmVww)nW+a+P513&0_^FWij9?N>6EtvRO&!BJKy0K| ziUKb?qS`8iZ{*ahlAu2H^?}Xm|F+(Q*8v?8Wd2G)-aKJfS}SYIo2+c78Y(qMZ4kAj z`iFcSno*!G<7JZagY%vyTSC6yhHpAGXnR-<8vl;TDLDkOC0NT*kxOo!f&uT$AX{S; zQA4R-au?DaM~sNrzw2&@?Tm3Eb4jV#z3Bey+0Z4Q2y1<48L8!<0ZP^?uBnf4N9&I? zkKb^3sl}Hzo6!$;;JTn5A9q=KuJ|Y0<<28s!!*B~3{?w4BW-NFfDmbMK2Lv~NAh6! zu?I4h*~Nrqg<7$lT9OceXL^8)-rU~obe+dsI;ooJjUINc(l;bSr$ti*XW)#6WWjt( z9$=g`#RmZ)jYn(Pm3mCJlE&X9)+j5aYE*~=uF9!9s*#3u{ejhUk_Pi};hBS2hJ!rk zYt~ls{>gF~>q^d&J1L&{ak8hUUVJ9t_-*-^$_A!=yK6>{kvLdRJu#d#@-g=!wU5Ta zv17Dr9s~9MCGFyegnJcN=b_P_ns)Wu0JBYWgMZhw&SPt23CI8_dD$YIM@PLO^1?I< zO8I{t8io(>9xj7=T09>@p4bo|HW8wYgfPQHtD%0cG7_ z!$i8apsUsd|=5!$GRx%$u)NFvIm z=tf_tSBJu_m7^A2y3_))(Zn5c6k{$dA1c0f<( zHwMQ&9dew59><~xxMhqjVThy1!LqNtDNKb?lFz5Obajzx7Mcjb_W4o!tJd5HPx;6t z@E-^(Vv5i1+n`KCFjpN6XiYfK*(*XcGrK*;h)v??fa$ivQ!A1Aw~~!L`c~s|Xzpe0 z1e1Tg5-+fxlEz2q!?s3F5nAVO{gO42SrvWP?x44%ugHw#c9~yeaLqQ7d5~OAH)Y%RGywjd zWnMS1`2e7|JS3_fl%g)M5kMPE6-xgREr+wL!SmO`r&0N@1|3s0rdLBPsga7 z2(FSezof*oL>J|e$4qe8eU^tF#bxh6&(VU%fVs_P_cbxw8OAKD=iu5TMvr3P zFob#N=-<$4b2#T3?hy0U=+_QPFu3Bi&nI2sA_r$XW3@fiNXj^0Sa3@@OlqndL1zC% zy(tgF;G;Tnkd+)?Y+xmHj=skKp4-w`*J-DIzLdQQX#3Ud^#m`%?W#>d5rbmk+kh3s zv+xIY{s+G32X){}G^6QY={I$tYui=|!-HgaTan6GXYX)VQX;H>le3zbeX&!DZ~0>{ zW*CGr3q~o_GN)+~#0LNR5IstTcs~Zr9dJ=+i+%=2XKNclP{5QsBP-%5BSCj)Ru%J^ zr(v?ufCA)kjB6Dkfovw?$D+uFlunHjju|7*=#9)|Mb!ENMm;L$^M9GPBtlvbA$4(_ z>8|~rCrc#l+>7?jYSDWcaBzO*b}(TfR-x9x!vZpYIs`PPSR?Lz8LSZYbB~%X*B&75 zhPH*!<6gnKLg*W{4~;VdchyL;te%`cgk%{5v{ELmV~ann`lXWW>zN1^D3<2fSX8>F z*owH>L3;4QSi4dvzJnc$3~*PuDRkOGx2tlCwy*8`%XPA}nrFxeI{hs+s|$_DZL_ELZxXeUnD=^PT^lo4>wDk$Mi@`f&DA;O z!U%jJQxe{%=f{6*92%W{+W^l+fC&{VW7w<6yh<$6q~s3#8-3%VGFl$UK!f|V;XT|b z=T^e&^w6%AOtZWpzPr3Iq&%gk*kB2Y=KPd4uQI9IfWP$Ye{$}RV)n9_)*hm^PFy6H zpr(H~@NGLQSi{kbn7)ge#5p1mTa^Q7=<|?onP_nK3PL_8QBO<58UG8%IH!+RIry~s z1}z%Hi3zgE7&plqx4o!fX!=08oPTBs5iu4~#heOhJ)aBk1ASr3&-Mcap=>xna59Z5 zkaPo@ll8GKTI2|C>Kjb{ynJVInHsDj>v@>gA*dU>NHlae%nrzV|J3n-=cayeA!#WQ zfC|v;$#-aO7n(52J%-7}Kkc*FnuV!47e~?UX69z8)}2`rzr)KNi>$k~r5)y3mu1Xj zB(8d!DHRyJWm%eESPIOKA%Dyr&s2fsuut6E(Yuwa#nx|y&es*|X(}mJ-pvg4(yUo_ ze*@3bWIoA%#uIluhLjaY$)vS475xWhh~_Cy9AqEoA-W^B4iO}$Uiorw{OBZDvdSN* zk=9R2E+iL3b0=85cXzJ;B&5!K&Mxg?*$i5y_(Qx+?=X_`nC*NtPlE-^+1~Jfl!sKJ3CNu}wqscK zV#aS`TAoJMD_N#qxfG^lwx9T~ZOr}SVtoAkJK!b-OX7v^=l)2@QPv~ORWsW~DX7t; z`THS>JC8@fv^1wRS2sMAkTxf*`a=OsT>XtSDLI z_d$MYB{|xT{!5me@BmQLc#S&{4&gH%$`kj3MAY7}Fjb_(WXvn4{m_Fciwv{fe_70z zRBmx-yl?EtkpR|$`0i8)T?NPTPjU!E_T#H|NMpw=KII*=@gga2%2%>BWO$U&r=;L6SNiDg=9J`cvhNHN*>!_+{yki@5mv;Ub2-8(fhe= zu?;*j#-%My3>IbR3-+~#jey=bwEnRsRd5p+w0{ly&bdC+i(<-zpi%CwSGE%kCqk+9 ziOMocG8*%gVzEeuQV1_jiC>$`JglJ5Y}{W99k1*~+~0@_{^JT$SlpxMKJ+np1lL4n z94fa~psI-v=Nu-5I9Cr@nm0dj*}7#7o62w0=CyJ6A&m+fv~AbCJk2&D6IJtw!{F&g zl!VPo&KGMlH2fv1$bNYdW;MNNGJe@Q{Vr`f7MH#P_x0>YRbrl3;IWXu#P&GUV=rJC zKSugzg%JJDVgxdPS_Fd$k5~qv<%xb3#_mRZo<)Mrfu5$#74442ZB3?yu@}AE?pGus zWdh)wDf~RfHr(_cRKXL0q}V^}91`~VD*p<-;M1`O<`m4nCg1h=XF+OIkykPlH8$@D zh^4i1$}F8{#|CA!6HRGOi2X2Qvboo$)izg+{5gFR5ABB4U+4}JY4yl!UU2wb0Kfg* zdU=hSOl4O_^zd*!QyLK3fJ|iq$CJ!Y1P=zTNOk8g<5gKCUi8F)=~pJJ>A{Y*?dmTj z`uTxs)xwZ4)Lp}>3JUPDa|R|_*z{7X=k)Dy^|B{QmWM@hW1?j-CwTBTki=H`%~y_K zc_-$?a{~u3-eJ1#0K>V%UCt?ouLu@TI-v9pl))>rel!FWP9TM%6c84aJ^N27dSe%U zi=1%bS#0R*`Ml-pMryS-;KypI*+V%~wdHB0NeMbLmvG!->&FbG8zN$7dsJ1(=;c08 zP@MDibhNvyo~*b}crdSCpUT}qf&cAq%8T08{GLy4WRNNq8bZ}Nl@>3iO(vOh*Zv#V z6!6+ISS45uVQ*OW{OM1_{hG9+LXTgZa`0U<5aE9*uj3@ol|i=>#S+5pst1gbL~`KZ zF%Sos)Z&xIE{>7V`fm-M5OzeKQZpcW+n`i*-nx?e zf$Yz3*(wzECnEGw1o%e>Ky)jjS({Zo?-U`R=?SyBpWx!20F3e_wvjP8xPF7^>- zv-hQ+=Xd}h1S3Sj!DE{)hrpljl}HPwOGYckY`=P0zRw8gTOvh|E4z;V2T*FidDWU^ zTBo6cP-)RIkuAnfu*zROzb_V2^y!{Crqm>0-zFhiH2>2hu1b6?+DSYqm5R1w4Xp&vf#oun3wTxN}BA}b2!ITI3_A&ad90wXQD zxIjNS$R1+*8OnyojorS>)lVdf1yUGn2Vx)~ZTgK!*#IX>X3KoH9pw^+uX*f(lhQW3 zul~cM?RC>HiV^6KHQ?`Cz)6Jf08WLovLsr>fexCNJK8F}h0_m6ys?BQ*k4>TIMnoj zgpP2%sKnWE9~s-E<`1$edMdwB$#?vH2#6HnwlzR)NiafHpX70AV9u5<0Dm|cnCGZk zQ05(v@Q`)wZwS>q>HKmIyp|(2ds`B%lOyUk@jHJ6@ z%*6rFTR1d6LKofRcybKOZjWz#iaKs^uCAi&T9`A(6W72#-#zbQVSsiY`CfV~kphjq zD) zEl>K(MQ(cJGs#(A*tkX(_%=dDMT-y|>|*Zv3T2aMlPbPNF4VWfqM@X`A{3FiDl%uY z*qMBc1**Z>WfDiiO)xs)7$uU?XrNR%Wf3STz~h(%e)|^be@B*7StU}nBBKf^0O3kq zJ)FA{tH~;L^oKVqzf=GH0%kX09W!jDy zMUh%bNKm769K3waE!E|yjQC2REAY62DhARl-sEDNs|Lha5~3+d9<5414dRmxeLGCktV!W3!guW*I?PITTr{YflLzExB3_s_)b^nu2e xpE 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

g#qvb`&lF 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

{*o-9nSK@v&pnEJ8N^^Piz|xK>KuREVea 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 IL\"data\");\ + \n#/usb1/mikro_bak_rsa.pub\ + \n\ + \n#\ + \n#/tool/fetch mode=https url=(\$GlobalScriptsUrl . \".bak/mikro_bak_rsa@1\ + 0.30.30.10.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.10.pub\";\ + \n#\ + \n#root.mnuc.backuper\ + \n\ + \n#/tool/fetch mode=https url=(\$GlobalScriptsUrl . \".bak/mikro_bak_rsa@1\ + 0.30.30.81.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.81.pub\";\ + \n#:local Script AM-GlobalConfig;\ + \n#/system/script/add name=\$Script owner=\$Script source=([ /tool/fetch c\ + heck-certificate=yes-without-crl url=(\$GlobalScriptsUrl . \$Script . \".r\ + sc\") output=user as-value ]->\"data\");\ + \n#/usb1/mikro_bak_rsa.pub\ + \n#:local FetchFile AM-DOHCert.rsc\ + \n\ + \n:global GlobalScriptsUrl \"https://ros.vados.ru/tmp/\";\ + \n:global MkDir;\ + \n\ + \n:local FetchFile Binary.backup\ + \n:local localDir \"\";\ + \n\ + \n#\$MkDir \$localDir;\ + \n\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \$FetchFile) dst-path=(\ + \$localDir . \$FetchFile);" +add comment="Example add WU servers to AddrList" dont-require-permissions=no \ + name=WU-add-to-list owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + \_Script to add target web sites DNS IP addresses into address list\r\ + \n# Tested with Mikrotik 6.4x\r\ + \n# Syed Jahanzaib / aacable@hotmail.com\r\ + \n# List name\r\ + \n:local LISTNAME \"windowsupdateslist\"\r\ + \n# Web site names which will be added in address list\r\ + \n:local TARGET1 \"update.microsoft.com\"\r\ + \n:local TARGET2 \"download.windowsupdate.com\"\r\ + \n:local TARGET3 \"download.microsoft.com\"\r\ + \n:local TARGET4 \"windowsupdate.com\"\r\ + \n:local TARGET5 \"ntservicepack.microsoft.com\"\r\ + \n:local TARGET6 \"wustat.windows.com\"\r\ + \n:local TARGET7 \"stats.microsoft.com\"\r\ + \n:local TARGET8 \"mp.microsoft.com\"\r\ + \n:local TARGET9 \"ws.microsoft.com\"\r\ + \n:local TARGET10 \"sls.update.microsoft.com.akadns.net\"\r\ + \n:local TARGET11 \"vortex.data.microsoft.com\"\r\ + \n:local TARGET12 \"vortex-win.data.microsoft.com\"\r\ + \n:local TARGET13 \"fe2.update.microsoft.com.akadns.net\"\r\ + \n:local TARGET14 \"statsfe2.update.microsoft.com.akadns.net\"\r\ + \n \r\ + \n# 1st time runner, check if address list is not created previously and a\ + dd entries in it for 1st time usage\r\ + \n:if ( [/ip firewall address-list find where list=\$LISTNAME] = \"\") do=\ + {\r\ + \n:log warning \"No address list for \$TARGET1 found ! creating and adding\ + \_resolved entry for 1st time usage ... zaib\"\r\ + \n \r\ + \n:local FirstAddr [resolve \$TARGET1];\r\ + \n\r\ + \n/ip firewall address-list add address=\$FirstAddr list=\$LISTNAME commen\ + t=\$TARGET1;\r\ + \n} else={\r\ + \n:log warning \"Previous List for \$LISTNAME found ! moving forward and c\ + hecking if DNS entries can be added in it ...\"\r\ + \n}\r\ + \n \r\ + \n# Check DNS entries and collect matching names\r\ + \n:foreach i in=[/ip dns cache find name~\"(\$TARGET1|\$TARGET2|\$TARGET3|\ + \$TARGET4|\$TARGET5|\$TARGET6|\$TARGET7|\$TARGET8|\$TARGET9|\$TARGET10|\$T\ + ARGET11|\$TARGET12|\$TARGET13|\$TARGET14)\" && \$type ~ \"^(A|CNAME)\\\$\"\ + \_] do={\r\ + \n \r\ + \n# Get IP Address from the names and hold it in temporary buffer\r\ + \n:local Buffer [/ip dns cache get \$i data];\r\ + \ndelay delay-time=10ms\r\ + \n \r\ + \n# Check if entry is already not exists, then OK, otherwise ignore duplic\ + ation\r\ + \n:if ( [/ip firewall address-list find where address=\$Buffer] = \"\") do\ + ={\r\ + \n \r\ + \n# Fetch DNS names for the entries\r\ + \n:local sitednsname [/ip dns cache get \$i name] ;\r\ + \n \r\ + \n# Print name in LOG window\r\ + \n:log info (\"added entry: \$sitednsname \$Buffer\");\r\ + \n \r\ + \n# Add IP addresses and there names to the address list\r\ + \n/ip firewall address-list add address=\$Buffer list=\$LISTNAME comment=\ + \$sitednsname;\r\ + \n}\r\ + \n}" +add comment="Add Hosts DNS names to NoWG addres list" \ + dont-require-permissions=no name=Add2vdsina owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + \_Script to add target web sites DNS IP addresses into address list\r\ + \n# Tested with Mikrotik 6.4x\r\ + \n# \r\ + \n# List name\r\ + \n:local LISTNAME \"NoWG\"\r\ + \n#\r\ + \n# Web site names which will be added in address list\r\ + \n:local TARGET1 \"comp-lenta.ru\"\r\ + \n:local TARGET2 \"ok.ru\"\r\ + \n:local TARGET3 \"vk.com\"\r\ + \n#:local TARGET4 \"smtp.mail.me.com\"\r\ + \n#:local TARGET4 \"windowsupdate.com\"\r\ + \n#:local TARGET5 \"ntservicepack.microsoft.com\"\r\ + \n#:local TARGET6 \"wustat.windows.com\"\r\ + \n#:local TARGET7 \"stats.microsoft.com\"\r\ + \n#:local TARGET8 \"mp.microsoft.com\"\r\ + \n#:local TARGET9 \"ws.microsoft.com\"\r\ + \n#:local TARGET10 \"sls.update.microsoft.com.akadns.net\"\r\ + \n#:local TARGET11 \"vortex.data.microsoft.com\"\r\ + \n#:local TARGET12 \"vortex-win.data.microsoft.com\"\r\ + \n#:local TARGET13 \"fe2.update.microsoft.com.akadns.net\"\r\ + \n#:local TARGET14 \"statsfe2.update.microsoft.com.akadns.net\"\r\ + \n \r\ + \n# 1st time runner, check if address list is not created previously and a\ + dd entries in it for 1st time usage\r\ + \n:if ( [/ip firewall address-list find where list=\$LISTNAME] = \"\") do=\ + {\r\ + \n:log warning \"No address list for \$TARGET1 found ! creating and adding\ + \_resolved entry for 1st time usage ... zaib\"\r\ + \n\r\ + \n:local FirstAddr [resolve \$TARGET1];\r\ + \n\r\ + \n/ip firewall address-list add address=\$FirstAddr list=\$LISTNAME commen\ + t=\$TARGET1;\r\ + \n\r\ + \n} else={\r\ + \n:log warning \"Previous List for \$LISTNAME found ! moving forward and c\ + hecking if DNS entries can be added in it ...\"\r\ + \n}\r\ + \n\r\ + \n# Check DNS entries and collect matching names\r\ + \n:foreach i in=[/ip dns cache find name~\"(\$TARGET1|\$TARGET2|\$TARGET3|\ + \$TARGET4)\" && \$type ~ \"^(A|CNAME)\\\$\" ] do={\r\ + \n\r\ + \n:log info (\"start entry: \$c \$sitednsname \$Buffer\");\r\ + \n\r\ + \n# Get IP Address from the names and hold it in temporary buffer\r\ + \n:local Buffer [/ip dns cache get \$i data];\r\ + \ndelay delay-time=10ms\r\ + \n:log info (\"1: \$Buffer\"); \r\ + \n\r\ + \n# Check if entry is already not exists, then OK, otherwise ignore duplic\ + ation\r\ + \n:if ( [/ip firewall address-list find where address=\$Buffer] = \"\") do\ + ={\r\ + \n\r\ + \n:log info (\"2: \$Buffer\"); \r\ + \n \r\ + \n# Fetch DNS names for the entries\r\ + \n:local sitednsname [/ip dns cache get \$i name] ;\r\ + \n \r\ + \n# Print name in LOG window\r\ + \n:log info (\"added entry: \$i \$sitednsname \$Buffer\");\r\ + \n \r\ + \n# Add IP addresses and there names to the address list\r\ + \n/ip firewall address-list add address=\$Buffer list=\$LISTNAME comment=\ + \$sitednsname;\r\ + \n}\r\ + \n}" +add comment="Flush DNS Cache" dont-require-permissions=no name=\ + DNS_Flush_Cache owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=\ + "/ip dns cache flush" +add comment="Certificates CloudFlare, Quad9 " dont-require-permissions=no \ + name=Update-Certificates owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + \_CloudFlare\r\ + \n#/tool/fetch mode=https url=https://cacerts.digicert.com/DigiCertGlobalR\ + ootCA.crt.pem;\r\ + \n#/certificate/import file-name=DigiCertGlobalRootCA.crt.pem passphrase=\ + \"\";\r\ + \n#/tool/ fetch mode=https url=https://cacerts.digicert.com/DigiCertGlobal\ + G2TLSRSASHA2562020CA1-1.crt.pem;\r\ + \n#/certificate/import file-name=DigiCertGlobalG2TLSRSASHA2562020CA1-1.crt\ + .pem passphrase=\"\";\r\ + \n# Quad9\r\ + \n#/tool/fetch mode=https url=\"https://cacerts.digicert.com/DigiCertGloba\ + lG3TLSECCSHA3842020CA1-1.crt.pem\"\r\ + \n#/certificate/import file-name=DigiCertGlobalG3TLSECCSHA3842020CA1-1.crt\ + .pem passphrase=\"\";\r\ + \n\r\ + \n:global GlobalScriptsUrl;\r\ + \n#google\r\ + \n:local CertName \"DigiCert-Global-Root-CA.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Global-Root-CA\" [ find where common-na\ + me=\"DigiCert Global Root CA\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Assured-ID-Root-CA.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Assured-ID-Root-CA\" [ find where commo\ + n-name=\"DigiCert Assured ID Root CA\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Assured-ID-Root-G2.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Assured-ID-Root-G2\" [ find where commo\ + n-name=\"DigiCert Assured ID Root G3\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Assured-ID-Root-G3.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Assured-ID-Root-G3\" [ find where commo\ + n-name=\"DigiCert Assured ID Root G3\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Global-G2-TLS-RSA-SHA256-2020-CA1.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Global-G2-TLS-RSA-SHA256-2020-CA1\" [ f\ + ind where common-name=\"DigiCert Global G2 TLS RSA SHA256 2020 CA1\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Global-G3-TLS-ECC-SHA384-2020-CA1.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Global-G3-TLS-ECC-SHA384-2020-CA1\" [ f\ + ind where common-name=\"DigiCert Global G3 TLS ECC SHA384 2020 CA1\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Global-Root-G2.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Global-Root-G2\" [ find where common-na\ + me=\"DigiCert Global Root G2\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Global-Root-G3.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Global-Root-G3\" [ find where common-na\ + me=\"DigiCert Global Root G3\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-TLS-ECC-P384-Root-G5.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-TLS-ECC-P384-Root-G5\" [ find where com\ + mon-name=\"DigiCert TLS ECC P384 Root G5\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-TLS-RSA4096-Root-G5.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-TLS-RSA4096-Root-G5\" [ find where comm\ + on-name=\"DigiCert TLS RSA4096 Root G5\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Trusted-Root-G4.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Trusted-Root-G4\" [ find where common-n\ + ame=\"DigiCert Trusted Root G4\" ];\r\ + \n\r\ + \n:set CertName \"GTS-Root-R4.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"GTS-Root-R4\" [ find where common-name=\"GTS Roo\ + t R4\" ];\r\ + \n\r\ + \n:set CertName \"Go-Daddy-Root-Certificate-Authority-G2.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"Go-Daddy-Root-Certificate-Authority-G2\" [ find \ + where common-name=\"Go Daddy Root Certificate Authority - G2\" ];\r\ + \n\r\ + \n:set CertName \"ISRG-Root-X1.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"ISRG-Root-X1\" [ find where common-name=\"ISRG R\ + oot X1\" ];\r\ + \n\r\ + \n:set CertName \"Root-YE.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"Root-YE\" [ find where common-name=\"Root YE\" ]\ + ;\r\ + \n\r\ + \n:set CertName \"Starfield-Root-Certificate-Authority-G2.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"Starfield-Root-Certificate-Authority-G2\" [ find\ + \_where common-name=\"Starfield Root Certificate Authority - G2\" ];\r\ + \n\r\ + \n:set CertName \"USERTrust-RSA-Certification-Authority.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"USERTrust-RSA-Certification-Authority\" [ find w\ + here common-name=\"USERTrust RSA Certification Authority\" ];\r\ + \n\r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n#:set CertName \"GTS-Root-RX.pem\";\r\ + \n#/tool/fetch mode=https url=(\$AmScriptsUrl . \"certs/\" . \$CertName);\ + \r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n#internet\r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n#:set CertName \"ISRG-Root-X2.pem\";\r\ + \n#/tool/fetch mode=https url=(\$AmScriptsUrl . \"certs/\" . \$CertName);\ + \r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n\r\ + \n\r\ + \n#/ip/dns/set allow-remote-requests=yes doh-max-concurrent-queries=100 do\ + h-max-server-connections=20 use-doh-server=https://security.cloudflare-dns\ + .com/dns-query verify-doh-cert=yes;\r\ + \n#/ip/dns/static remove [find where address=1.1.1.1];\r\ + \n#/ip/dns/static add address=1.1.1.1 name=security.cloudflare-dns.com com\ + ment=\"cloudflare-dns IPv4 1\";\r\ + \n#/ip/dns/ static remove [find where address=1.0.0.1];\r\ + \n#/ip/dns/static add address=1.0.0.1 name=security.cloudflare-dns.com com\ + ment=\"cloudflare-dns IPv4 2\"\r\ + \n#/ip dns static add address=2606:4700:4700::1111 name=security.cloudflar\ + e-dns.com type=AAAA\r\ + \n#/ip dns static add address=2606:4700:4700::1001 name=security.cloudflar\ + e-dns.com type=AAAA\r\ + \n#/ip/dns set servers=\"1.0.0.1, 8.8.4.4\";\r\ + \n#/ip/dns set servers=\"\";" +add dont-require-permissions=no name=script1 owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="/\ + tool/netwatch/add comment=\"doh-fallback, doh-url=https://security.cloudfl\ + are-dns.com/dns-query, doh-cert=DigiCert Global Root CA, notify, name=Clou\ + dFlare-doh IPv4 1\" host=1.1.1.1;\r\ + \n/tool/netwatch/add comment=\"doh, doh-url=https://security.cloudflare-dn\ + s.com/dns-query, doh-cert=DigiCert Global Root CA, notify, name=CloudFlare\ + -doh IPv4 2\" host=1.0.0.1;\r\ + \n/tool/netwatch/add comment=\"doh-fallback, dns-fallback, doh-url=https:/\ + /dns.google/dns-query, doh-cert=DigiCert Global Root G2, notify, name=Goog\ + le-doh IPv4 1\" host=8.8.8.8;\r\ + \n/tool/netwatch/add comment=\"doh-fallback, dns-fallback, doh-url=https:/\ + /dns.google/dns-query, doh-cert=DigiCert Global Root G2, notify, name=Goog\ + le-doh IPv4 2\" host=8.8.4.4;\r\ + \n/tool/netwatch/add comment=\"doh-fallback, dns-fallback, doh-url=https:/\ + /dns.quad9.net/dns-query, doh-cert=DigiCert Global Root G3, notify, name=C\ + uad9-doh IPv4 1\" host=9.9.9.9;\r\ + \n/tool/netwatch/add comment=\"doh-fallback, dns-fallback, doh-url=https:/\ + /dns.quad9.net/dns-query, doh-cert=DigiCert Global Root G3, notify, name=C\ + uad9-doh IPv4 2\" host=149.112.112.112;\r\ + \n\r\ + \n/tool/netwatch/add comment=\"dns, notify, name=ns1.unet.ws\" host=91.192\ + .189.2;" +add dont-require-permissions=no name=script2 owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + \r\ + \n\r\ + \n:global InspectVar;\r\ + \n#:global RouterBoard;\r\ + \n#:do {:set RouterBoard [[ :parse \"/system/routerboard/get\" ]]} on-erro\ + r={}\r\ + \n#:global Resources;\r\ + \n#:do {:set Resources [[ :parse \"/system/resource/get\" ]]} on-error={}\ + \r\ + \n\r\ + \n#:global Updates;\r\ + \n#:do {:set Updates [[ :parse \"/system/package/update/get\" ]]} on-error\ + ={}\r\ + \n\r\ + \n#:global PkgUpdStatus \"undefined\";\r\ + \n#:local Update [/system/package/update/get];\r\ + \n#:retry command={:set PkgUpdStatus (\$Update->\"status\")} delay=200ms m\ + ax=5 on-error={};\r\ + \n\r\ + \n#:log warning [\$InspectVar \$RouterBoard];\r\ + \n#:put [\$InspectVar \$RouterBoard];\r\ + \n\r\ + \n#:retry command={/system/package/update check-for-updates without-paging\ + \_as-value} delay=300ms max=5 on-error={};\r\ + \n\r\ + \n#:global arrDeviceInfo ({});\r\ + \n#:local arrDeviceInfo ({\"section\":{\"key\":\"\"; \"value\":\"\";};});\ + \r\ + \n#:set (\$arrDeviceInfo->\"RouterBoard\") [[ :parse \"/system/routerboard\ + /get\" ]];\r\ + \n#:retry command={:set (\$arrDeviceInfo->\"Updates\") [[ :parse \"/system\ + /package/update/get\" ]]} delay=500ms max=5 on-error={:log error (\"Error\ + \")};\r\ + \n# [:toarray {\"section\"={\"key\"=\"\"; \"value\"=\"\";} }];\r\ + \n# [:toarray \"\"];\r\ + \n:local arrDeviceInfo ({});\r\ + \n\r\ + \n:set (\$arrDeviceInfo->\"devUpdates\") {\"channel\"; \"stable\";};\r\ + \n#:do {:set (arrDeviceInfo->\"Updates\") [[ :parse \"/system/package/upda\ + te/get\" ]]} on-error={:log error (\$error)}\r\ + \n\$InspectVar \$arrDeviceInfo;\r\ + \n" +add comment="Script for setup routeros script system" \ + dont-require-permissions=no name=AM-setup owner=AM-setup policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + !rsc by Vados\r\ + \n# RouterOS script: AM-setup\r\ + \n# Script comment: Script for setup routeros script system\r\ + \n# Copyright (c) 2005-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n# requires device-mode, fetch\r\ + \n#\r\ + \n# :local ScriptName [ :jobname ];\r\ + \n# Additional commands:\r\ + \n#\r\ + \n# For scripts:\r\ + \n#:global NewScript \"script_name\"; \r\ + \n#:global GlobalScriptsUrl \"https://ros.vados.ru/\";\r\ + \n#/system/script/add name=\$NewScript owner=\$NewScript source=([/tool/fe\ + tch check-certificate=yes-without-crl (\$GlobalScriptsUrl . \$ScriptAdd . \ + \".rsc\") output=user as-value ]->\"data\");\r\ + \n#:global NewScript (a);\r\ + \n#:global ScriptInstallUpdate; \$ScriptInstallUpdate;\r\ + \n#\r\ + \n# For run from terminal:\r\ + \n#/system/script/add name=AM-setup owner=AM-Setup source=([/tool/fetch ch\ + eck-certificate=yes-without-crl \"https://ros.vados.ru/AM-setup.rsc\" outp\ + ut=user as-value ]->\"data\");\r\ + \n#\r\ + \n\r\ + \n:global ScriptUpdatesCRLF \"LF\";\r\ + \n#:if (\$ScriptUpdatesCRLF != false) do={\r\ + \n# :foreach Script in=[ /system/script/find where source~\"^#!rsc by Vad\ + os\" ] do={\r\ + \n# if (\$ScriptUpdatesCRLF = true) do={\r\ + \n# /system/script/set source=[ :tocrlf [ get \$Script source ] ] \$S\ + cript;\r\ + \n# } else={\r\ + \n# /system/script/set source=[ :tolf [ get \$Script source ] ] \$Scr\ + ipt;\r\ + \n# }\r\ + \n# }\r\ + \n#}\r\ + \n\r\ + \n# /import verbose=no \$ScriptName\r\ + \n:global Identity [/system/identity/get name];\r\ + \n:global SetupScript [ :jobname ];\r\ + \n:global RemoveMe true;\r\ + \n:global RunOnce (a);\r\ + \n:global InitSetup true;\r\ + \n:global tmpfs false;\r\ + \n\r\ + \n{\r\ + \n :local RmMe [:tobool \$1];\r\ + \n\r\ + \n :global GlobalScriptsUrl;\r\ + \n :global SetupScript;\r\ + \n :global RemoveMe;\r\ + \n :global InitSetup;\r\ + \n :global tmpfs;\r\ + \n\r\ + \n :local UrlSuffix \$Identity;\r\ + \n :local UrlDir \"certs/\";\r\ + \n :local CertUrl (\$GlobalScriptsUrl . \$UrlDir . \$UrlSuffix .\"/\"); \ + \r\ + \n :local CertCommonName \"Root YE\";\r\ + \n :local CertFileName \"Root-YE.pem\";\r\ + \n :local CertFingerprint \"e14ffcad5b0025731006caa43a121a22d8e9700f4fb9c\ + f852f02a708aa5d5666\";\r\ + \n\r\ + \n :if (\$SetupScript = false) do={\r\ + \n :global SetupScript \"AM-setup\";\r\ + \n }\r\ + \n :if (\$RemoveMe != false) do={\r\ + \n :set RemoveMe true;\r\ + \n }\r\ + \n\r\ + \n :log warning (\"\\n\\\$GlobalScriptsUrl = \" . \$GlobalScriptsUrl);\r\ + \n \r\ + \n\r\ + \n :if (!(((\$CertSettings->\"builtin-trust-anchors\") = \"trusted\" ||\ + \_\\\r\ + \n (\$CertSettings->\"builtin-trust-store\") ~ \"fetch\" || \\\r\ + \n (\$CertSettings->\"builtin-trust-store\") = \"all\") && \\\r\ + \n [ :len [ /certificate/builtin/find where common-name=\$CertComm\ + onName ] ] > 0)) do={\r\ + \n :put \"Importing certificate...\";\r\ + \n /tool/fetch (\$CertUrl . \$CertFileName) dst-path=\$CertFileName\ + \_as-value;\r\ + \n :delay 1s;\r\ + \n /certificate/import file-name=\$CertFileName passphrase=\"\";\r\ + \n /certificate/set name=\"Root-YE\" [ find where common-name=\"Roo\ + t YE\" ];\r\ + \n :delay 1s;\r\ + \n };\r\ + \n :local CertSettings [ /certificate/settings/get ];\r\ + \n :if ([ :len [ /certificate/find where fingerprint=\$CertFingerprint ] \ + ] != 1) do={\r\ + \n :error \"Something is wrong with your certificates!\";\r\ + \n };\r\ + \n\r\ + \n:local MkTmpfs do={\r\ + \n :local TmpFs [ /disk/find where slot=tmpfs type=tmpfs ];\r\ + \n :if ([ :len \$TmpFs ] = 1) do={\r\ + \n :if ([ /disk/get \$TmpFs disabled ] = true) do={\r\ + \n :log info (\"The tmpfs is disabled, enabling.\");\r\ + \n /disk/enable \$TmpFs;\r\ + \n }\r\ + \n :return true;\r\ + \n }\r\ + \n :log info (\"Try to removing directory 'tmpfs'.\");\r\ + \n :do {\r\ + \n :retry {\r\ + \n /file/remove tmpfs;\r\ + \n :return true;\r\ + \n } delay=100ms max=10;\r\ + \n } on-error={ }\r\ + \n# \$RmDir \"tmpfs\";\r\ + \n :onerror Err {\r\ + \n /disk/add slot=tmpfs type=tmpfs tmpfs-max-size=([ /system/resource/g\ + et total-memory ] / 3);\r\ + \n :do {\r\ + \n :retry {\r\ + \n /file/get tmpfs;\r\ + \n :return true;\r\ + \n } delay=222ms max=10;\r\ + \n } on-error={ }\r\ + \n } do={\r\ + \n :log warning (\"Creating disk of type tmpfs failed: \" . \$Err);\r\ + \n :return false;\r\ + \n }\r\ + \n# :return true;\r\ + \n}\r\ + \n:if (\$tmpfs = true) do={\r\ + \n :put \"Tmpfs variable is true. Checking for tmpfs/scripts directory...\ + \";\r\ + \n :if ([/file find name=\"tmpfs/scripts\"] != \"\") do={\r\ + \n :log info (\$0 . \"Directory tmpfs/scripts exsist.\");\r\ + \n :return \$true;\r\ + \n } else={\r\ + \n :log warning (\$0 . \"Directory tmpfs/scripts does't exsist.\");\r\ + \n :if ([ \$MkTmpfs ] = false) do={\r\ + \n :log error (\$0 . \"Directory tmpfs is not created!\");\r\ + \n :return false;\r\ + \n } else={\r\ + \n :onerror Err {\r\ + \n /file/add type=\"directory\" name=/tmpfs/scripts;\r\ + \n :do {\r\ + \n :retry {\r\ + \n /file/get /tmpfs/scripts;\r\ + \n :return true;\r\ + \n } delay=100ms max=10;\r\ + \n } on-error={ }\r\ + \n } do={\r\ + \n :log warning (\$0 . \"Making directory 'scripts' failed: \" . \$\ + Err);\r\ + \n :return false;\r\ + \n }\r\ + \n# :return true;\r\ + \n# [ /file/get \$FileName ]\r\ + \n }\r\ + \n# :log error (\$0 . \"Directory tmpfs/scripts does not exsist. Remove\ + \_global variable tmpfs!\");\r\ + \n# :global tmpfs (a);\r\ + \n# return false;\r\ + \n }\r\ + \n}\r\ + \n :put \"Renaming AM-GlobalConfig, if exists...\";\r\ + \n :local ConfOldName (\"AM-GlobalConfig-\" . [ /system/clock/get date ] \ + . [ /system/clock/get time ] . \".rsc\");\r\ + \n /system/script/set name=\$ConfOldName [ find where name=\"AM-GlobalCon\ + fig\" ];\r\ + \n :foreach Script in={ \"AM-GlobalConfig\"; \"AM-GlobalFunc\"; \"mod/AM-\ + Certs-By-Ident\" } do={\r\ + \n :put \"Installing \$Script...\";\r\ + \n /system/script/remove [ find where name=\$Script ];\r\ + \n /system/script/add name=\$Script owner=\$Script source=([ /tool/fetc\ + h check-certificate=yes-without-crl url=(\$GlobalScriptsUrl . \$Script . \ + \".rsc\") output=user as-value ]->\"data\");\r\ + \n \r\ + \n /system/script run \$Script;\r\ + \n :delay 2s;\r\ + \n };\r\ + \n\r\ + \n :if ([ :len [ /certificate/find where fingerprint=\$CertFingerprint ] \ + ] > 0) do={\r\ + \n :put \"Renaming certificate by its common-name...\";\r\ + \n :global CertificateNameByCN;\r\ + \n \$CertificateNameByCN \$CertFingerprint;\r\ + \n };\r\ + \n\r\ + \n :if (\$RemoveMe = true) do={\r\ + \n :put \"Add Scheduler for remove this script...\";\r\ + \n :local OnEvent (\":delay 30s;\\n\" . \"/system/script/remove [ find \ + where name=\\\"\$SetupScript\\\" ];\\n\" . \\\r\ + \n \":delay 2s;\\n\" . \"/system/scheduler/remove [ find where name=\\\ + \"_RemoveSetup\\\" ];\\n\" . \\\r\ + \n \":delay 2s;\\n\" . \":global RemoveMe (a);\\n\");\r\ + \n :local Comment \"_RemoveSetup tmp scheduler for remove setup script.\ + \";\r\ + \n /system/scheduler/add name=\"_RemoveSetup\" comment=\$Comment start-\ + time=startup interval=30s on-event=\$OnEvent;\r\ + \n :log warning (\$0 . \"\\nI've done everything, and now I'm tired..\ + . I'm leaving.\\nThere will be an error below, this is normal.\");\r\ + \n }\r\ + \n :delay 1;\r\ + \n :put \"Loading configuration and functions...\";\r\ + \n :do { \r\ + \n :global ScriptInstallUpdate; \$ScriptInstallUpdate;\r\ + \n :put \"Normal removing temporary global environment variables.\";\ + \r\ + \n :global SetupScript (a);\r\ + \n :global InitSetup (a);\r\ + \n :global RemoveMe (a);\r\ + \n } on-error={\r\ + \n :local ErrorMsg \"Loading configuration and functions error!\";\r\ + \n :log error (\$0 . \$ErrorMsg . :error);\r\ + \n :error \$ErrorMsg;\r\ + \n }\r\ + \n}\r\ + \n" +add comment="Global Config Script" dont-require-permissions=no name=\ + AM-GlobalConfig owner=AM-GlobalConfig policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + !rsc by Vados\r\ + \n# RouterOS script: AM-GlobalConfig\r\ + \n# Script comment: Global Config Script\r\ + \n# Copyright (c) 2007-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# Warning: Dont touch this line!\r\ + \n:global Identity [/system/identity/get name];\r\ + \n:global GlobalConfReady false;\r\ + \n#\r\ + \n#\r\ + \n# Global Url For Amster scripts to fetch\r\ + \n# most be defined in AM-Init-Script or AM-setup scripts\r\ + \n:global GlobalScriptsUrl \"https://ros.vados.ru/\";\r\ + \n:global ScriptsUrlSuffix (a);\r\ + \n:global CheckSumsVerify true;\r\ + \n\r\ + \n:global ScriptUpdatesCRLF true;\r\ + \n:global CommentsInScripts true;\r\ + \n\r\ + \n# Debug output:\r\ + \n:global PrintDebug true; #false;\r\ + \n\r\ + \n# Debug output for specific script:\r\ + \n#:set (\$PrintDebugOverride->\"AM-GlobalFunc\") true;\r\ + \n\r\ + \n# Debug logs\r\ + \n# Other actions (disk, email, remote or support) can be used as well.\r\ + \n# I do not recommend using echo - use debug output instead (https://rsc.\ + eworm.de/main/DEBUG.html#debug-output).\r\ + \n#/system/logging/add topics=script,debug action=memory;\r\ + \n\r\ + \n:global MikrotikUpgradeUrl \"https://upgrade.mikrotik.com/routeros\";\r\ + \n:global Domain \"WORKGROUP\";\r\ + \n\r\ + \n:global EmailGeneralTo \"vados@vados.ru\";\r\ + \n#:global EmailGeneralCc \"\";\r\ + \n\r\ + \n# \$ScriptInstallUpdate mod/notification-telegram\r\ + \n:global TelegramTokenId \"8390868324:AAG3_d1hfVR2M6pGAgDK6ZvhOe4J97nyopw\ + \";\r\ + \n:global TelegramChatId \"-1003631309063\"; #\"454403445\";\r\ + \n# Use this to send notifications to a specific topic in group.\r\ + \n#:global TelegramThreadId \"30\";\r\ + \n# Using telegram-chat you have to define trusted chat ids (not group ids\ + !)\r\ + \n# or user names. Groups allow to chat with devices simultaneously.\r\ + \n:global TelegramChatIdsTrusted {\r\ + \n \"454403445\"\r\ + \n \"-1003631309063\"\r\ + \n \"-5124482807\"\r\ + \n \"1087968824\";\r\ + \n};\r\ + \n# \"-5294757340\";\r\ + \n\r\ + \n:global TelegramChatGroups \"(all)\";\r\ + \n#:global TelegramChatGroups \"(all|home|office)\";\r\ + \n\r\ + \n:global NotificationFunctions {\r\ + \n \"email\"\r\ + \n \"telegram\";\r\ + \n};\r\ + \n# Toggle this to disable symbols in notifications.\r\ + \n:global NotificationsWithSymbols true;\r\ + \n:global TerminalColorOutput true;\r\ + \n\r\ + \n:global DetectIpAddrDefault \"https://ipv4.mikrotik.ovh/\";\r\ + \n:global DetectIpAddrFallback \"https://api.ipify.org/\";\r\ + \n\r\ + \n## Update channel. Possible values: stable, long-term, testing, developm\ + ent\r\ + \n:global updateChannel \"stable\";\r\ + \n\r\ + \n:global CertRenewUrl (\$GlobalScriptsUrl . \"certs/\" . \$Identity . \"/\ + \");\r\ + \n:global CertRenewTime 2w;\r\ + \n:global CertRenewPass (a); #{\r\ + \n# \"\";\r\ + \n# \"v3ry-s3cr3t\";\r\ + \n# \"4n0th3r-s3cr3t\";\r\ + \n#};\r\ + \n:global CertWarnTime 1w;\r\ + \n:global CertIssuedExportPass (a); # {\r\ + \n# \"\";\r\ + \n# \"cert1-cn\"=\"v3ry-s3cr3t\";\r\ + \n# \"cert2-cn\"=\"4n0th3r-s3cr3t\";\r\ + \n#};\r\ + \n\r\ + \n# Script BackupAndUpdate mode, possible values: backup,\r\ + \n# updateOnce - Update once as \"osnotify\" and back \"osnotify\" mode (i\ + n terminal run :set OSUpdateMode updateOnce; \$OSUpdateMode;). \r\ + \n# osupdate - Update if available and creates backups before/after update\ + \_(ignores `forceBackup`)\r\ + \n# Set `forceBackup` to true to always create backups, even\ + \_without updates\r\ + \n# osnotify - Set `forceBackup` to always create backups on every run\r\ + \n:global DevInfoIncludeIP true;\r\ + \n:global BackupAndUpdateMode \"osnotify\"\r\ + \n\r\ + \n:global forceBackup true;\r\ + \n:global BackupPassword \"Peskar55\";\r\ + \n\r\ + \n# SFTP Backup Variables\r\ + \n:global BackupRandomDelay 0;\r\ + \n:global BackupUploadUrl \"sftp://amster.vados.ru/upload/\";\r\ + \n:global BackupUploadUser \$Identity;\r\ + \n:global BackupUploadPass \"root.mnuc.backuper\";\r\ + \n\r\ + \n:global BackupSendBinary true;\r\ + \n:global BackupSendExport true;\r\ + \n:global BackupSendGlobalConfig true;\r\ + \n:global BackupSendScripts true;\r\ + \n\r\ + \n# Remove local file after uploading if no errors\r\ + \n:global BackupRmLocal true;\r\ + \n\r\ + \n# Local Backups Root Directory \r\ + \n:global BackupLocalRoot \"tmpfs\";\r\ + \n\r\ + \n# Encrypt Backup\r\ + \n:global BackupEncrypt true;\r\ + \n\r\ + \n# Sensitive information in Backups\r\ + \n:global BackupSens true;\r\ + \n\r\ + \n# User Export\r\ + \n:global BackupUser true;\r\ + \n\r\ + \n# License Export (not for CHR, will silently skip)\r\ + \n:global BackupLicense false;\r\ + \n\r\ + \n# SSH Keys\r\ + \n:global BackupSshKeys true;\r\ + \n\r\ + \n# Certificate Export\r\ + \n:global BackupCerts true;\r\ + \n\r\ + \n# Certificate Password\r\ + \n:global BackupCertsPasswd \"\";\r\ + \n\r\ + \n# User-Manager Export\r\ + \n:global BackupUserMan false;\r\ + \n\r\ + \n# The Dude Export\r\ + \n:global BackupDude false;\r\ + \n\r\ + \n# User Files to export, comma-separated string or array of strings\r\ + \n# User Files are not removed on backup\r\ + \n# Any directory paths will be removed (/ -> _) on remote file\r\ + \n# Nonpresent files are silently skipped\r\ + \n:global BackupUserList \"autosupout.rif,autosupout.old.rif\";\r\ + \n\r\ + \n# load functions and any custom scripts\r\ + \n# [ /system/script/find where name=\"global-config-ov\ + erlay\" ], \\\r\ + \n# [ /system/script/find where name~\"^global-config-o\ + verlay\\\\.d/.\" ]\r\ + \n#\r\ + \n#:foreach Script in=([ /system/script/find where name=\"Amster-TGglobalV\ + ars\" ], [ /system/script/find where name=\"Amster-TGglobalFunc\" ]) do={\ + \r\ + \n# :onerror Err {\r\ + \n# /system/script/run \$Script;\r\ + \n# } do={\r\ + \n# :log error (\"Loading configuration from configs and functions\"\ + \_. [ /system/script/get \$Script name ] . \" failed: \" . \$Err);\r\ + \n# }\r\ + \n#}\r\ + \n#:log info \"\\ndevMode = \$devMode\";\r\ + \n#:log info \"\\ndevRunning = \$devRunning\";\r\ + \n:foreach Script in=[ /system/script/find where source~\"^#!rsc by Vados \ + GlobalRUN\\r\?\\n\" ] do={\r\ + \n :onerror Err {\r\ + \n /system/script/run \$Script;\r\ + \n } do={\r\ + \n :log error (\"Run script \" . [ /system/script/get \$Script name \ + ] . \" width marker \\\" GlobalRUN\\\" failed: \" . \$Err);\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n# signal we are ready\r\ + \n:set GlobalConfReady true;\r\ + \n:while (\$GlobalConfReady != true) do={:delay 500ms};\r\ + \n" +add comment="Global functions" dont-require-permissions=no name=AM-GlobalFunc \ + owner=AM-GlobalFunc policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + !rsc by Vados\r\ + \n# RouterOS script: AM-GglobalFunc\r\ + \n# Script comment: Global functions\r\ + \n# Copyright (c) 2005-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n# requires device-mode, fetch, scheduler\r\ + \n:local ExitOK false;\r\ + \n:local ScriptName [ :jobname ];\r\ + \n#:global checkRunJob \$SriptName;\r\ + \n#:global fixCRLF;\r\ + \n#:if (\$fixCRLF != false) do={\r\ + \n#:foreach fixScript in=([ /system/script/find where name~\"*\" ]) do={/s\ + ystem/script/set source=[ :tocrlf [ get \$fixScript source ] ] \$fixScript\ + }\r\ + \n#:if (\$fixCRLF != \"LF\") do={ /system/script/set source=[ :tocrlf [ g\ + et \$fixScript source ] ] \$fixScript};};\r\ + \n#}\r\ + \n:global GlobalFuncReady false;\r\ + \n\r\ + \n# Git commit id & info, expected configuration version\r\ + \n:global CommitId \"main/633/2f6d4158\";\r\ + \n:global CommitTAG \"unknown\";\r\ + \n:global CommitInfo \"Autocommit in repo: ros.vados.ru, generated by owne\ + r: root, in 14:35:03 05.05.2026.\";\r\ + \n\r\ + \n# The variables are received right here.\r\ + \n:global GlobalConfVersion 140;\r\ + \n\r\ + \n:global SumsDirAndFileName \"tmp/checksums.json\";\r\ + \n\r\ + \n:global Identity [/system/identity/get name];\r\ + \n:global IdentityShort [:pick \$Identity 0 18];\r\ + \n\r\ + \n:global devBoardName [/system/resource/get board-name];\r\ + \n:global devMode [/system/device-mode/get mode];\r\ + \n:global devCurArch [/system/resource/get architecture-name];\r\ + \n:global devCurVersion [/system/resource/get version];\r\ + \n\r\ + \n# Variables defined in AM-GlobalConfig.rsc\r\ + \n:global TerminalColorOutput;\r\ + \n:global CommentsInScripts;\r\ + \n:global DetectIpAddrDefault;\r\ + \n:global DetectIpAddrFallback;\r\ + \n:global updateChannel;\r\ + \n:global Domain;\r\ + \n:global EmailGeneralTo;\r\ + \n:global BackupAndUpdateMode;\r\ + \n\r\ + \n# Single functions, without nested functions.\r\ + \n:global MiniDateTimeStamp;\r\ + \n:global MicroDateTimeStamp;\r\ + \n\r\ + \n# Include globals \$PrintDebug and \$PrintDebugOverride\r\ + \n:global LogPrint;\r\ + \n\r\ + \n# DeviceInfo and Updates\r\ + \n:global IsCheckUpdates;\r\ + \n:global WaitCheckUpdates;\r\ + \n:global GetPubIp;\r\ + \n\r\ + \n:global GetArrDeviceInfo;\r\ + \n:global WaitArrDeviceInfo;\r\ + \n\r\ + \n:global devModel;\r\ + \n:global devRunningMode;\r\ + \n\r\ + \n:global devRbRevision;\r\ + \n:global devRbSerialNumber;\r\ + \n:global devRbVerAvail;\r\ + \n\r\ + \n:global runningChannelVersion;\r\ + \n:global runningChannel;\r\ + \n:global runningVersion;\r\ + \n\r\ + \n:global devBuildTime;\r\ + \n:global ROsVerAvail;\r\ + \n:global PkgUpdStatus;\r\ + \n:global currentUpdateChannel;\r\ + \n\r\ + \n:global ScriptInstallUpdate;\r\ + \n\r\ + \n:global DeviceInfo;\r\ + \n\r\ + \n:global OldMode;\r\ + \n\r\ + \n:global ParseKeyValueStore;\r\ + \n:global RandomDelay;\r\ + \n:global GetRandomNumber;\r\ + \n:global EscapeForRegEx;\r\ + \n:global CharacterMultiply;\r\ + \n:global CharacterReplace;\r\ + \n:global CleanFilePath;\r\ + \n:global CleanName;\r\ + \n\r\ + \n:global CommitBrief;\r\ + \n\r\ + \n:global EitherOr;\r\ + \n:global FormatLine;\r\ + \n:global GetRandom20CharAlNum;\r\ + \n:global GetRandom20CharHex;\r\ + \n:global GetRandomNumber;\r\ + \n:global Grep;\r\ + \n:global IfThenElse;\r\ + \n:global MAX;\r\ + \n:global MIN;\r\ + \n:global HumanReadableNum;\r\ + \n\r\ + \n:global IsFullyConnected;\r\ + \n:global IsDNSResolving;\r\ + \n:global IsTimeSync;\r\ + \n:global IsTimeSyncCached;\r\ + \n:global IsTimeSyncResetNtp;\r\ + \n\r\ + \n:global WaitDNSResolving;\r\ + \n:global WaitFullyConnected;\r\ + \n:global WaitTimeSync;\r\ + \n:global MkDir;\r\ + \n:global RmDir;\r\ + \n:global RmFile;\r\ + \n:global FileGet;\r\ + \n:global Unix2Dos;\r\ + \n:global UrlEncode;\r\ + \n:global WaitForFile;\r\ + \n:global ScriptLock;\r\ + \n:global SendTelegram;\r\ + \n:global NotificationFunctions;\r\ + \n:global SendNotification;\r\ + \n:global SendNotification2;\r\ + \n:global SymbolForNotification;\r\ + \n:global SymbolByUnicodeName;\r\ + \n:global ValidateSyntax;\r\ + \n:global CheckSumsVerify;\r\ + \n:global GlobalConfChanges;\r\ + \n:global GlobalConfMigration;\r\ + \n:global VersionToNum;\r\ + \n:global RequiredRouterOS;\r\ + \n:global ExitError;\r\ + \n:global ExitOnError;\r\ + \n\r\ + \n:global FetchHugeFiles;\r\ + \n:global FetchUserAgentStr;\r\ + \n:global FileExists;\r\ + \n:global CertificateAvailable;\r\ + \n:global CertificateDownload;\r\ + \n:global CertificateNameByCN;\r\ + \n:global CharacterMultiply;\r\ + \n\r\ + \n:global InspectVar;\r\ + \n:global InspectVarRet;\r\ + \n:global ParseCustom;\r\ + \n\r\ + \n:set IsCheckUpdates do={\r\ + \n :local isInfo [:tobool \$1];\r\ + \n :global updateChannel;\r\ + \n :global PkgUpdStatus;\r\ + \n :global currentUpdateChannel;\r\ + \n :global ROsVerAvail;\r\ + \n :global arrDeviceInfo;\r\ + \n :log info (\$0 . \" \\\$isInfo = \" . \$isInfo); \r\ + \n :local CurrentChannel [ /system/package/update/get channel ];\r\ + \n :if ([ :len \$updateChannel ] > 0 && \$CurrentChannel != \$updateChann\ + el) do={\r\ + \n :retry command={/system/package/update set channel=\$updateChannel} \ + \_delay=300ms max=5 on-error={};\r\ + \n :log info (\$0 . \" Set updates channel to: \$updateChannel\");\r\ + \n }\r\ + \n :local Update [ /system/package/update/get ];\r\ + \n :local Channel [ :tostr (\$Update->\"channel\") ];\r\ + \n :set currentUpdateChannel \$Channel;\r\ + \n :log info (\$0 . \" Update Channel: \" . \$Channel . \".\");\r\ + \n :local StatusPkg \"undefined\";\r\ + \n :log info (\$0 . \" Checking for updates...\");\r\ + \n :retry command={:set \$StatusPkg ([/system/package/update/check-for-up\ + dates without-paging as-value]->\"status\")} \\\r\ + \n delay=300ms max=5 on-error={};\r\ + \n :log info (\$0 . \" \\\$StatusPkg = \" . \$StatusPkg);\r\ + \n :if (\$StatusPkg = \"New version is available\") do={ :set PkgUpdStatu\ + s true; } else={ :set PkgUpdStatus false; }\r\ + \n :set ROsVerAvail [ :tostr [ /system/package/update/get latest-version \ + ] ];\r\ + \n :log info (\$0 . \" \\\$PkgUpdStatus = \" . \$PkgUpdStatus);\r\ + \n :if (\$isInfo != false || \$PkgUpdStatus = true) do={\r\ + \n :log info (\$0 . \" \\\$PkgUpdStatus = \" . \$PkgUpdStatus);\r\ + \n :if ([ :typeof \$arrDeviceInfo ] != \"array\") do={\r\ + \n :set arrDeviceInfo [:toarray \$arrDeviceInfo];\r\ + \n }\r\ + \n :retry command={:set (\$arrDeviceInfo->\"devUpdates\") [ /system/pac\ + kage/update/get ]} delay=500ms max=5 on-error={:log error (\"Error\")};\r\ + \n :return true;\r\ + \n } else={\r\ + \n :return \$PkgUpdStatus;\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set WaitCheckUpdates do={\r\ + \n :global IsCheckUpdates;\r\ + \n :global PkgUpdStatus;\r\ + \n :global currentUpdateChannel;\r\ + \n :global ROsVerAvail;\r\ + \n :global arrDeviceInfo;\r\ + \n :local Status \"\";\r\ + \n :local Update;\r\ + \n :local WaitCount 0;\r\ + \n :if ([ \$IsCheckUpdates true ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n :set Status [ :tostr [ /system/package/update/get status ] ];\r\ + \n :while ((\$Status = \"\" || \$Status = \"finding out latest version...\ + \") && \$WaitCount < 60) do={\r\ + \n :delay 1s;\r\ + \n :set WaitCount (\$WaitCount + 1);\r\ + \n :set Status [ :tostr [ /system/package/update/get status ] ];\r\ + \n }\r\ + \n :set Update [ /system/package/update/get ];\r\ + \n :set currentUpdateChannel [ :tostr (\$Update->\"channel\") ];\r\ + \n :set ROsVerAvail [ :tostr (\$Update->\"latest-version\") ];\r\ + \n :if ((\$Update->\"status\") = \"New version is available\") do={\r\ + \n :set PkgUpdStatus true;\r\ + \n } else={\r\ + \n :set PkgUpdStatus false;\r\ + \n }\r\ + \n :if ([ :typeof \$arrDeviceInfo ] != \"array\") do={\r\ + \n :set arrDeviceInfo [:toarray \$arrDeviceInfo];\r\ + \n }\r\ + \n :set (\$arrDeviceInfo->\"devUpdates\") \$Update;\r\ + \n :if (\$Status = \"\" || \$Status = \"finding out latest version...\") \ + do={\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set WaitArrDeviceInfo do={\r\ + \n :global GetArrDeviceInfo;\r\ + \n :while ([ \$GetArrDeviceInfo ] = false) do={\r\ + \n :delay 1s;\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set GetArrDeviceInfo do={\r\ + \n :global LogPrint;\r\ + \n :global arrDeviceInfo;\r\ + \n :global devBoardName;\r\ + \n :global devModel;\r\ + \n :global devRunning;\r\ + \n :global devCurArch;\r\ + \n :global devRbRevision;\r\ + \n :global devRbSerialNumber;\r\ + \n :global devBuildTime;\r\ + \n :global runningChannelVersion;\r\ + \n :global runningChannel;\r\ + \n :global runningVersion;\r\ + \n :global currentUpdateChannel;\r\ + \n :global ROsVerAvail;\r\ + \n\r\ + \n :local DeviceInfo;\r\ + \n :local Resource [/system/resource/get];\r\ + \n :local Update [ /system/package/update/get ];\r\ + \n :local VersionString [ :tostr (\$Resource->\"version\") ];\r\ + \n :local ChannelStart [ :find \$VersionString \" (\" ];\r\ + \n :local RouterBoard;\r\ + \n :local IsRouterBoard false;\r\ + \n :local RunningMode \"\";\r\ + \n\r\ + \n :set devCurArch [ :tostr (\$Resource->\"architecture-name\") ];\r\ + \n :set devBuildTime [ :tostr (\$Resource->\"build-time\") ];\r\ + \n :set runningChannelVersion \$VersionString;\r\ + \n :set runningVersion \$VersionString;\r\ + \n :set runningChannel \"\";\r\ + \n\r\ + \n :if ([ :typeof \$ChannelStart ] = \"num\" && \$ChannelStart >= 0) do=\ + {\r\ + \n :set runningVersion [ :pick \$VersionString 0 \$ChannelStart ];\r\ + \n :local ChannelRest [ :pick \$VersionString (\$ChannelStart + 2) [ :\ + len \$VersionString ] ];\r\ + \n :local ChannelEnd [ :find \$ChannelRest \")\" ];\r\ + \n :if ([ :typeof \$ChannelEnd ] = \"num\" && \$ChannelEnd >= 0) do={\ + \r\ + \n :set runningChannel [ :pick \$ChannelRest 0 \$ChannelEnd ];\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :if ([:pick \$devBoardName 0 3] != \"CHR\" or [:pick \$devBoardName 0\ + \_3] != \"x86\") do={\r\ + \n :do {\r\ + \n :set RouterBoard [[ :parse \"/system/routerboard/get\" ]];\r\ + \n# :set RouterBoard [ /system/routerboard/get ];\r\ + \n :if ((\$RouterBoard->\"routerboard\") = true) do={\r\ + \n :set IsRouterBoard true;\r\ + \n }\r\ + \n } on-error={}\r\ + \n }\r\ + \n\r\ + \n :do {\r\ + \n :set RunningMode [ /system/device-mode/get mode ];\r\ + \n } on-error={\r\ + \n :do {\r\ + \n :set RunningMode [ /system/device-mode/get running ];\r\ + \n } on-error={\r\ + \n :set RunningMode \"\";\r\ + \n }\r\ + \n }\r\ + \n :set devRunning \$RunningMode;\r\ + \n\r\ + \n :if (\$IsRouterBoard = true) do={\r\ + \n :set devModel [ :tostr (\$RouterBoard->\"model\") ];\r\ + \n :set devRbRevision [ :tostr (\$RouterBoard->\"revision\") ];\r\ + \n :set devRbSerialNumber [ :tostr (\$RouterBoard->\"serial-number\") \ + ];\r\ + \n } else={\r\ + \n :set devModel \$devBoardName;\r\ + \n :set devRbRevision \"\";\r\ + \n :set devRbSerialNumber \"\";\r\ + \n }\r\ + \n\r\ + \n :set currentUpdateChannel [ :tostr (\$Update->\"channel\") ];\r\ + \n :set ROsVerAvail [ :tostr (\$Update->\"latest-version\") ];\r\ + \n\r\ + \n :set (\$DeviceInfo->\"board-name\") \$devBoardName;\r\ + \n :set (\$DeviceInfo->\"architecture-name\") \$devCurArch;\r\ + \n :set (\$DeviceInfo->\"model\") \$devModel;\r\ + \n :set (\$DeviceInfo->\"revision\") \$devRbRevision;\r\ + \n :set (\$DeviceInfo->\"serial-number\") \$devRbSerialNumber;\r\ + \n :set (\$DeviceInfo->\"running-mode\") \$devRunning;\r\ + \n :set (\$DeviceInfo->\"build-time\") \$devBuildTime;\r\ + \n :set (\$DeviceInfo->\"running-channel-version\") \$runningChannelVers\ + ion;\r\ + \n :set (\$DeviceInfo->\"running-version\") \$runningVersion;\r\ + \n :set (\$DeviceInfo->\"running-channel\") \$runningChannel;\r\ + \n :set (\$DeviceInfo->\"routerboard\") \$IsRouterBoard;\r\ + \n :set (\$DeviceInfo->\"current-firmware\") [ :tostr (\$RouterBoard->\"\ + current-firmware\") ];\r\ + \n :set (\$DeviceInfo->\"upgrade-firmware\") [ :tostr (\$RouterBoard->\"\ + upgrade-firmware\") ];\r\ + \n :set (\$DeviceInfo->\"package-channel\") \$currentUpdateChannel;\r\ + \n :set (\$DeviceInfo->\"installed-version\") [ :tostr (\$Update->\"inst\ + alled-version\") ];\r\ + \n :set (\$DeviceInfo->\"latest-version\") \$ROsVerAvail;\r\ + \n :set (\$DeviceInfo->\"update-status\") [ :tostr (\$Update->\"status\"\ + ) ];\r\ + \n\r\ + \n :set arrDeviceInfo \$DeviceInfo;\r\ + \n :return \$DeviceInfo;\r\ + \n}\r\ + \n\r\ + \n:set DeviceInfo do={\r\ + \n :global GetArrDeviceInfo;\r\ + \n :global GlobalConfVersion;\r\ + \n :global Identity;\r\ + \n :global IfThenElse;\r\ + \n :global FormatLine;\r\ + \n :global CommitBrief;\r\ + \n\r\ + \n :local License [/system/license/get];\r\ + \n :local Snmp [ /snmp/get ];\r\ + \n :local Info [ \$GetArrDeviceInfo ];\r\ + \n\r\ + \n :if ([ :typeof \$Info ] != \"array\") do={\r\ + \n :return false;\r\ + \n }\r\ + \n\r\ + \n :return ( \\\r\ + \n [ \$FormatLine \"Hostname\" \$Identity ] . \"\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$Snmp->\"location\") ] > 0) \\\r\ + \n ([ \$FormatLine \"Location\" (\$Snmp->\"location\") ] . \"\\n\") ]\ + \_. \\\r\ + \n [ \$IfThenElse ([ :len (\$Snmp->\"contact\") ] > 0) \\\r\ + \n ([ \$FormatLine \"Contact\" (\$Snmp->\"contact\") ] . \"\\n\") ] .\ + \_\\\r\ + \n \"Hardware:\\n\" . \\\r\ + \n [ \$FormatLine \" Board\" (\$Info->\"board-name\") ] . \"\\n\" . \ + \\\r\ + \n [ \$FormatLine \" Arch\" (\$Info->\"architecture-name\") ] . \"\\\ + n\" . \\\r\ + \n [ \$FormatLine \" Model\" (\$Info->\"model\") ] . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"revision\") ] > 0) \\\r\ + \n (\" \" . (\$Info->\"revision\")) ] . \"\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"serial-number\") ] > 0) \\\r\ + \n ([ \$FormatLine \" Serial\" (\$Info->\"serial-number\") ] . \"\ + \\n\") ] . \\\r\ + \n [ \$IfThenElse ([ :len (\$License->\"nlevel\") ] > 0) \\\r\ + \n ([ \$FormatLine \" License\" (\"level \" . (\$License->\"nlevel\ + \")) ] . \"\\n\") ] . \\\r\ + \n \"RouterOS:\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$License->\"level\") ] > 0) \\\r\ + \n ([ \$FormatLine \" License\" (\"level \" . (\$License->\"level\ + \")) ] . \"\\n\") ] . \\\r\ + \n [ \$FormatLine \" Channel\" (\$Info->\"package-channel\") ] . \"\ + \\n\" . \\\r\ + \n [ \$FormatLine \" Installed\" (\$Info->\"installed-version\") ] .\ + \_\"\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"running-channel\") ] > 0) \\\r\ + \n ([ \$FormatLine \" Running\" ((\$Info->\"running-version\") . \ + \" (\" . (\$Info->\"running-channel\") . \")\") ] . \"\\n\") \\\r\ + \n ([ \$FormatLine \" Running\" (\$Info->\"running-version\") ] . \ + \"\\n\") ] . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"latest-version\") ] > 0 && \\\r\ + \n (\$Info->\"installed-version\") != (\$Info->\"latest-version\"))\ + \_\\\r\ + \n ([ \$FormatLine \" Available\" (\$Info->\"latest-version\") ] .\ + \_\"\\n\") ] . \\\r\ + \n [ \$IfThenElse ((\$Info->\"routerboard\") = true && \\\r\ + \n (\$Info->\"current-firmware\") != (\$Info->\"upgrade-firmware\")\ + ) \\\r\ + \n ([ \$FormatLine \" Firmware\" ((\$Info->\"current-firmware\") .\ + \_\" -> \" . (\$Info->\"upgrade-firmware\")) ] . \"\\n\") ] . \\\r\ + \n \"RouterOS-Scripts:\\n\" . \\\r\ + \n [ \$FormatLine \" Commit\" [ \$CommitBrief ] ] . \"\\n\" . \\\r\ + \n [ \$FormatLine \" Version\" \$GlobalConfVersion ]);\r\ + \n}\r\ + \n\r\ + \n:if ([ :typeof \$NotificationFunctions ] != \"array\") do={:set Notifica\ + tionFunctions ({})}\r\ + \n\r\ + \n:set GetRandom20CharAlNum do={\r\ + \n :global EitherOr;\r\ + \n :return [ :rndstr length=[ \$EitherOr [ :tonum \$1 ] 20 ] from=\"ABCDE\ + FGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\" ];\r\ + \n}\r\ + \n\r\ + \n:set GetRandom20CharHex do={:global EitherOr; :return [ :rndstr length=[\ + \_\$EitherOr [ :tonum \$1 ] 20 ] from=\"0123456789abcdef\" ]; }\r\ + \n:set GetRandomNumber do={:global EitherOr; :return [ :rndnum from=0 to=[\ + \_\$EitherOr [ :tonum \$1 ] 4294967295 ] ]; }\r\ + \n\r\ + \n:global checkRunJob;\r\ + \n:set checkRunJob do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :global ScriptLock; \r\ + \n :if ([ \$ScriptLock \$Script ] = false) do={:return false}\r\ + \n :foreach Job in=[ /system/script/job/find where script=\$Script ] do={\ + :set Job [ /system/script/job/get \$Job ];\r\ + \n :while ([ :typeof (\$Job->\"parent\") ] = \"id\") do={:set Job [ /sy\ + stem/script/job/get [ find where .id=(\$Job->\"parent\") ] ]}\r\ + \n :if ((\$Job->\"type\") = \"login\") do={:return true};}; :return fa\ + lse; \r\ + \n}\r\ + \n\r\ + \n:set InspectVar do={\r\ + \n :global InspectVarRet;\r\ + \n :put [ :tocrlf [ \$InspectVarRet \$1 ] ];\r\ + \n}\r\ + \n\r\ + \n:set CommitBrief do={\r\ + \n :global CommitId;\r\ + \n :global CommitInfo;\r\ + \n :if (\$CommitId = \"unknown\") do={\r\ + \n :return \"unknown\";\r\ + \n }\r\ + \n :return (\$CommitInfo . \"/\" . [ :pick \$CommitId 0 8 ]);\r\ + \n}\r\ + \n\r\ + \n:set InspectVarRet do={\r\ + \n :local Input \$1;\r\ + \n :local Level (0 + [ :tonum \$2 ]);\r\ + \n :global CharacterReplace;\r\ + \n :global IfThenElse;\r\ + \n :global InspectVarRet;\r\ + \n :local IndentReturn do={\r\ + \n :local Prefix [ :tostr \$1 ];\r\ + \n :local Value [ :tostr \$2 ];\r\ + \n :local Level [ :tonum \$3 ];\r\ + \n :global CharacterMultiply;\r\ + \n :return ([ \$CharacterMultiply \" \" (\$Level * 2) ] . \"-\" . \$Pre\ + fix . \"-> \" . \$Value);\r\ + \n }\r\ + \n :local TypeOf [ :typeof \$Input ];\r\ + \n :local Len [ :len \$Input ];\r\ + \n :local Return [ \$IndentReturn \"type\" \$TypeOf \$Level ];\r\ + \n :if (\$TypeOf = \"array\") do={\r\ + \n :foreach Key,Value in=\$Input do={\r\ + \n :set \$Return (\$Return . \"\\n\" . \\\r\ + \n [ \$IndentReturn \"key\" \$Key (\$Level + 1) ] . \"\\n\" . \\\r\ + \n [ \$InspectVarRet \$Value (\$Level + 2) ]);\r\ + \n }\r\ + \n } else={\r\ + \n :if (\$TypeOf = \"str\") do={\r\ + \n :set \$Return (\$Return . \"\\n\" . \\\r\ + \n [ \$IndentReturn \"len\" \$Len \$Level ]);\r\ + \n :if ([ :typeof [ :find \$Input (\"\\r\") ] ] = \"num\") do={\r\ + \n :set Input [ \$CharacterReplace \$Input (\"\\r\") \"\" ];\r\ + \n }\r\ + \n :if ([ :typeof [ :find \$Input (\"\\n\") ] ] = \"num\") do={\r\ + \n :set Input [ \$CharacterReplace \$Input (\"\\n\") \" \" ];\r\ + \n }\r\ + \n }\r\ + \n :if (\$TypeOf != \"nothing\") do={\r\ + \n :set \$Return (\$Return . \"\\n\" . \\\r\ + \n [ \$IndentReturn \"value\" [ \$IfThenElse ([ :len \$Input ] > 80)\ + \_\\\r\ + \n ([ :pick \$Input 0 77 ] . \"...\") \$Input ] \$Level ]);\r\ + \n }\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set GetPubIp do={\r\ + \n :global DetectIpAddrDefault;\r\ + \n :global DetectIpAddrFallback;\r\ + \n\r\ + \n :local PubIpAddr false;\r\ + \n :local Url \$DetectIpAddrDefault;\r\ + \n :local JobName [ :jobname ];\r\ + \n\r\ + \n :do {\r\ + \n :log debug (\$0 . \" Trying to detect public IP using default serv\ + ice: \" . \$Url . \"...\");\r\ + \n :retry command={:set PubIpAddr ([ /tool/fetch http-method=\"get\"\ + \_check-certificate=yes-without-crl \$Url output=user as-value ]->\"data\"\ + )} \\\r\ + \n delay=50ms max=5 on-error={:log error (\$JobName . \" Failed to \ + detect public IP using default service: \" . \$Url . \".\")}\r\ + \n } on-error={\r\ + \n :log error (\$0 . \" Failed to detect public IP using default serv\ + ice: \" . \$Url . \".\");\r\ + \n :set Url \$DetectIpAddrFallBack;\r\ + \n :log debug (\$0 . \" Trying to detect public IP using fallback ser\ + vice: \" . \$Url . \"...\");\r\ + \n :retry command={:set PubIpAddr ([ /tool/fetch http-method=\"get\"\ + \_check-certificate=yes-without-crl \$Url output=user as-value ]->\"data\"\ + )} \\\r\ + \n delay=200ms max=5 on-error={:log error (\$JobName . \" Failed to\ + \_detect public IP using fallback service: \" . \$Url . \".\")}\r\ + \n };\r\ + \n :local IpLen ([ :len \$PubIpAddr ] -1);\r\ + \n :if (\$PubIpAddr = false) do={:set PubIpAddr \"not-detected\"} else=\ + {:set PubIpAddr [:pick \$PubIpAddr 0 \$IpLen]}\r\ + \n :return \$PubIpAddr;\r\ + \n}\r\ + \n\r\ + \n:set FormatLine do={\r\ + \n :local Key [ :tostr \$1 ];\r\ + \n :local Value [ :tostr \$2 ];\r\ + \n :local Indent [ :tonum \$3 ];\r\ + \n :local Spaces;\r\ + \n :local Return \"\";\r\ + \n :global CharacterMultiply;\r\ + \n :global EitherOr;\r\ + \n :set Indent [ \$EitherOr \$Indent 16 ];\r\ + \n :local Spaces [ \$CharacterMultiply \" \" \$Indent ];\r\ + \n :if ([ :len \$Key ] > 0) do={ :set Return (\$Key . \":\")}\r\ + \n :if ([ :len \$Key ] > (\$Indent - 2)) do={:set Return (\$Return . \"\\\ + n\" . [ :pick \$Spaces 0 \$Indent ] . \$Value);\r\ + \n } else={:set Return (\$Return . [ :pick \$Spaces 0 (\$Indent - [ :len \ + \$Return ]) ] . \$Value)}\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set ParseCustom do={\r\ + \n :local Str [ :tostr \$1 ];\r\ + \n :local Start [:find [ \$Str ] [:tostr \$2]];\r\ + \n :local End [ :tostr \$3 ];\r\ + \n :local Num [ :tonum \$4 ];\r\ + \n :local Return;\r\ + \n :if ([:len \$Num] = 0) do={:set Num \"0\"}\r\ + \n :local rest [:pick \$Str (\$Start+\$Num) [:len \$Str]]; \r\ + \n :if ([:len \$End ] = 0) do={:set Return [:pick \$Str \$Num \$Start]} e\ + lse={\r\ + \n :set End [:find \$rest \$End];\r\ + \n :set Return [:pick \$rest 0 \$End];\r\ + \n }\r\ + \n:return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set LogPrint do={\r\ + \n :local Severity [ :tostr \$1 ];\r\ + \n :local Name [ :tostr \$2 ];\r\ + \n :local Message [ :tostr \$3 ];\r\ + \n :global PrintDebug;\r\ + \n :global PrintDebugOverride;\r\ + \n :global EitherOr;\r\ + \n :local Debug [ \$EitherOr (\$PrintDebugOverride->\$Name) \$PrintDebug \ + ];\r\ + \n :local PrintSeverity do={\r\ + \n :global TerminalColorOutput;\r\ + \n :if (\$TerminalColorOutput != true) do={:return \$1}\r\ + \n :local Color { debug=96; info=97; warning=93; error=91 };\r\ + \n :return (\"\\1B[\" . \$Color->\$1 . \"m\" . \$1 . \"\\1B[0m\");\r\ + \n}\r\ + \n :local Log ([ \$EitherOr \$Name \"\" ] . \": \" . \$Message);\ + \r\ + \n :if (\$Severity ~ (\"^(custom|debug|error|info)\\\$\")) do={\r\ + \n :if (\$Severity = \"debug\") do={:log debug \$Log}\r\ + \n :if (\$Severity = \"error\") do={:log error \$Log}\r\ + \n :if (\$Severity = \"info\" ) do={:log info \$Log}\r\ + \n } else={:log warning \$Log; :set Severity \"warning\"}\r\ + \n :if (\$Severity != \"debug\" || \$Debug = true) do={:put ([ \$PrintSev\ + erity \$Severity ] . \": \" . \$Message)}\r\ + \n}\r\ + \n\r\ + \n:set CertificateAvailable do={\r\ + \n :local CommonName [ :tostr \$1 ];\r\ + \n :local UseFor [ :tostr \$2 ];\r\ + \n\r\ + \n :global CertificateDownload;\r\ + \n :global ParseKeyValueStore;\r\ + \n\r\ + \n :if ([ :len \$UseFor ] = 0) do={\r\ + \n :log warning (\$0 . \"The intended use is undefined!\");\r\ + \n :set UseFor \"undefined\";\r\ + \n }\r\ + \n :if ([ /system/resource/get free-hdd-space ] < 8388608 && \\\r\ + \n [ /certificate/settings/get crl-download ] = true && \\\r\ + \n [ /certificate/settings/get crl-store ] = \"system\") do={\r\ + \n :log warning (\$0 . \"This system has low free flash space but \" . \ + \\\r\ + \n \"is configured to download certificate CRLs to system!\");\r\ + \n }\r\ + \n :if ([ :len \$CommonName ] = 0) do={\r\ + \n :log warning (\$0 . \"No CommonName given!\");\r\ + \n :return false;\r\ + \n }\r\ + \n :local CertSettings [ /certificate/settings/get ];\r\ + \n :if (((\$CertSettings->\"builtin-trust-anchors\") = \"trusted\" || \\\ + \r\ + \n (\$CertSettings->\"builtin-trust-store\") ~ \$UseFor || \\\r\ + \n (\$CertSettings->\"builtin-trust-store\") = \"all\") && \\\r\ + \n [ :len [ /certificate/builtin/find where common-name=\$CommonName\ + \_] ] > 0) do={\r\ + \n :return true;\r\ + \n }\r\ + \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] = 0\ + ) do={\r\ + \n :log info (\$0 . \"Certificate with CommonName '\" . \$CommonName . \ + \"' not available.\");\r\ + \n :if ([ \$CertificateDownload \$CommonName ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] > 1\ + ) do={\r\ + \n :log info (\$0 . \"There are \" . \$CertCount . \" Certificates with\ + \_CommonName '\" . \$CommonName . \"'. Should be ok.\");\r\ + \n :return true;\r\ + \n }\r\ + \n :local CertVal [ /certificate/get [ find where common-name=\$CommonNam\ + e ] ];\r\ + \n :while ((\$CertVal->\"akid\") != \"\" && (\$CertVal->\"akid\") != (\$C\ + ertVal->\"skid\")) do={\r\ + \n :if ([ :len [ /certificate/find where skid=(\$CertVal->\"akid\") ] ]\ + \_= 0) do={\r\ + \n :local IssuerCN ([ \$ParseKeyValueStore (\$CertVal->\"issuer\") ]-\ + >\"CN\");\r\ + \n :log info (\$0 . \"Certificate chain for '\" . \$CommonName . \"' \ + is incomplete, missing '\" . \$IssuerCN . \"'.\");\r\ + \n :if ([ \$CertificateDownload \$IssuerCN ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n :set CertVal [ /certificate/get [ find where skid=(\$CertVal->\"akid\ + \") ] ];\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set CertificateDownload do={\r\ + \n :local CommonName [ :tostr \$1 ];\r\ + \n :global ScriptUpdatesBaseUrl;\r\ + \n :global ScriptUpdatesUrlSuffix;\r\ + \n :global CertificateNameByCN;\r\ + \n :global CleanName;\r\ + \n :global FetchUserAgentStr;\r\ + \n :global RmFile;\r\ + \n :global WaitForFile;\r\ + \n\r\ + \n :log info (\$0 . \"Downloading and importing certificate with \" . \\\ + \r\ + \n \"CommonName '\" . \$CommonName . \"'.\");\r\ + \n :local FileName ([ \$CleanName \$CommonName ] . \".pem\");\r\ + \n :do {\r\ + \n /tool/fetch check-certificate=yes-without-crl mode=https http-header\ + -field=({ [ \$FetchUserAgentStr \$0 ] }) \\\r\ + \n (\$ScriptUpdatesBaseUrl . \"certs/\" . \$FileName . \$ScriptUpdate\ + sUrlSuffix) \\\r\ + \n dst-path=\$FileName as-value;\r\ + \n \$WaitForFile \$FileName;\r\ + \n } on-error={\r\ + \n :log warning (\$0 . \" Failed downloading certificate with CommonNam\ + e '\" . \$CommonName . \\\r\ + \n \"' from repository! Trying fallback to mkcert.org...\");\r\ + \n :do {\r\ + \n :local CertSettings [ /certificate/settings/get ];\r\ + \n :if ([ :len [ /certificate/find where common-name=\"ISRG Root X1\"\ + \_] ] = 0 && \\\r\ + \n !(((\$CertSettings->\"builtin-trust-anchors\") = \"trusted\" \ + || \\\r\ + \n (\$CertSettings->\"builtin-trust-store\") ~ \"fetch\" || \ + \\\r\ + \n (\$CertSettings->\"builtin-trust-store\") = \"all\") && \\\ + \r\ + \n [ :len [ /certificate/builtin/find where common-name=\"ISRG\ + \_Root X1\" ] ] > 0)) do={\r\ + \n :log error (\$0 . \" Required certificate is not available.\");\ + \r\ + \n :return false;\r\ + \n }\r\ + \n /tool/fetch check-certificate=yes-without-crl mode=https http-head\ + er-field=({ [ \$FetchUserAgentStr \$0 ] }) \\\r\ + \n url=\"https://mkcert.org/generate/\" http-data=[ :serialize to=jso\ + n ({ \$CommonName }) ] \\\r\ + \n dst-path=\$FileName as-value;\r\ + \n \$WaitForFile \$FileName;\r\ + \n :if ([ /file/get \$FileName size ] = 0) do={\r\ + \n \$RmFile \$FileName;\r\ + \n :error false;\r\ + \n }\r\ + \n } on-error={\r\ + \n :log error (\$0 . \" Failed downloading certificate with CommonNam\ + e '\" . \$CommonName . \"'!\");\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n /certificate/import file-name=\$FileName passphrase=\"\" as-value;\r\ + \n :delay 1s;\r\ + \n \$RmFile \$FileName;\r\ + \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] = 0\ + ) do={\r\ + \n /certificate/remove [ find where name~(\"^\" . \$FileName . \"_[0-9]\ + +\\\$\") ];\r\ + \n :log warning (\$0 . \" Certificate with CommonName '\" . \$CommonNam\ + e . \"' still unavailable!\");\r\ + \n :return false;\r\ + \n }\r\ + \n :foreach Cert in=[ /certificate/find where name~(\"^\" . \$FileName . \ + \"_[0-9]+\\\$\") ] do={\r\ + \n \$CertificateNameByCN [ /certificate/get \$Cert common-name ];\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set CertificateNameByCN do={\r\ + \n :local Match [ :tostr \$1 ];\r\ + \n :global CleanName;\r\ + \n :local Cert ([ /certificate/find where (common-name=\$Match or fingerp\ + rint=\$Match or name=\$Match) ]->0);\r\ + \n :if ([ :len \$Cert ] = 0) do={\r\ + \n :log warning (\$0 .\" No matching certificate found.\");\r\ + \n :return false;\r\ + \n }\r\ + \n :local CommonName [ /certificate/get \$Cert common-name ];\r\ + \n /certificate/set \$Cert name=[ \$CleanName \$CommonName ];\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set CharacterMultiply do={\r\ + \n :local Str [ :tostr \$1 ];\r\ + \n :local Num [ :tonum \$2 ];\r\ + \n :if (\$Num = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :for I from=1 to=\$Num do={:set Return (\$Return . \$Str)}\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set FileExists do={\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :local Type [ :tostr \$2 ];\r\ + \n :global FileGet;\r\ + \n :local FileVal [ \$FileGet \$FileName ];\r\ + \n :if (\$FileVal = false) do={ :return false; }\r\ + \n :if ([ :len (\$FileVal->\"size\") ] = 0) do={ :return false; }\r\ + \n :if ([ :len \$Type ] = 0 || \$FileVal->\"type\" = \$Type) do={ :return\ + \_true; }\r\ + \n :return false;\r\ + \n}\r\ + \n\r\ + \n:set Grep do={\r\ + \n :local Input ([ :tostr \$1 ] . \"\\n\");\r\ + \n :local Pattern [ :tostr \$2 ];\r\ + \n :if ([ :typeof [ :find \$Input \$Pattern ] ] = \"nil\") do={:return []\ + }\r\ + \n :do {\r\ + \n :local Line [ :pick \$Input 0 [ :find \$Input \"\\n\" ] ];\r\ + \n :if ([ :typeof [ :find \$Line \$Pattern ] ] = \"num\") do={:return \ + \$Line}\r\ + \n :set Input [ :pick \$Input ([ :find \$Input \"\\n\" ] + 1) [ :len \$\ + Input ] ];\r\ + \n } while=([ :len \$Input ] > 0);\r\ + \n :return [];\r\ + \n}\r\ + \n\r\ + \n:set HumanReadableNum do={\r\ + \n :local Input [ :tonum \$1 ];\r\ + \n :local Base [ :tonum \$2 ];\r\ + \n :global EitherOr;\r\ + \n :global IfThenElse;\r\ + \n :local Prefix \"kMGTPE\";\r\ + \n :local Pow 1;\r\ + \n :set Base [ \$EitherOr \$Base 1024 ];\r\ + \n :local Bin [ \$IfThenElse (\$Base = 1024) \"i\" \"\" ];\r\ + \n :if (\$Input < \$Base) do={:return \$Input}\r\ + \n :for I from=0 to=[ :len \$Prefix ] do={\r\ + \n :set Pow (\$Pow * \$Base);\r\ + \n :if (\$Input / \$Base < \$Pow) do={\r\ + \n :set Prefix [ :pick \$Prefix \$I ];\r\ + \n :local Tmp1 (\$Input * 100 / \$Pow);\r\ + \n :local Tmp2 (\$Tmp1 / 100);\r\ + \n :if (\$Tmp2 >= 100) do={:return (\$Tmp2 . \$Prefix . \$Bin)}\r\ + \n :return (\$Tmp2 . \".\" . \\\r\ + \n [ :pick \$Tmp1 [ :len \$Tmp2 ] ([ :len \$Tmp1 ] - [ :len \$Tmp\ + 2 ] + 1) ] . \\\r\ + \n \$Prefix . \$Bin);\r\ + \n }\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set CleanFilePath do={\r\ + \n :local Path [ :tostr \$1 ];\r\ + \n :global CharacterReplace;\r\ + \n :while (\$Path ~ \"//\") do={ :set \$Path [ \$CharacterReplace \$Path \ + \"//\" \"/\" ]; }\r\ + \n :if ([ :pick \$Path 0 ] = \"/\") do={ :set Path [ :pick \$Path 1 [ :le\ + n \$Path ] ]; }\r\ + \n :if ([ :pick \$Path ([ :len \$Path ] - 1) ] = \"/\") do={ :set Path [ \ + :pick \$Path 0 ([ :len \$Path ] - 1) ]; }\r\ + \n :return \$Path;\r\ + \n}\r\ + \n\r\ + \n:set CleanName do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :local Return \"\";\r\ + \n :for I from=0 to=([ :len \$Input ] - 1) do={\r\ + \n :local Char [ :pick \$Input \$I ];\r\ + \n :if ([ :typeof [ find \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr\ + stuvwxyz0123456789\" \$Char ] ] = \"nil\") do={\r\ + \n :do {:if ([ :len \$Return ] = 0) do={:error true};\r\ + \n :if ([ :pick \$Return ([ :len \$Return ] - 1) ] = \"-\") do={:er\ + ror true}; :set Char \"-\"} on-error={:set Char \"\"}; \r\ + \n };\r\ + \n :set Return (\$Return . \$Char)};\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set RandomDelay do={\r\ + \n :local Time [ :tonum \$1 ];\r\ + \n :local Unit [ :tostr \$2 ];\r\ + \n :global EitherOr;\r\ + \n :global GetRandomNumber;\r\ + \n :global MAX;\r\ + \n :if (\$Time = 0) do={:return false}\r\ + \n :delay ([ \$MAX 10 [ \$GetRandomNumber ([ :tonsec [ :totime (\$Time . \ + [ \$EitherOr \$Unit \"s\" ]) ] ] / 1000000) ] ] . \"ms\");\r\ + \n}\r\ + \n\r\ + \n:set EscapeForRegEx do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :if ([ :len \$Input ] = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :local Chars (\"^.[]\\\$()|*+\?{}\\\\\");\r\ + \n :for I from=0 to=([ :len \$Input ] - 1) do={\r\ + \n :local Char [ :pick \$Input \$I ];\r\ + \n :if ([ :find \$Chars \$Char ]) do={:set Char (\"\\\\\" . \$Char)}\r\ + \n :set Return (\$Return . \$Char);\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set ExitError do={\r\ + \n :local ExitOK [ :tostr \$1 ];\r\ + \n :local Name [ :tostr \$2 ];\r\ + \n :local Error [ :tostr \$3 ];\r\ + \n :global IfThenElse;\r\ + \n :if (\$ExitOK = \"false\") do={\r\ + \n :log error (\$Name [ \$IfThenElse ([ :pick \$Name 0 1 ] = \"\\\$\") \ + \\\r\ + \n \"Function\" \"Script\" ] . \" '\" . \$Name . \"' exited with er\ + ror\" . \\\r\ + \n [ \$IfThenElse (!(\$Error ~ \"^(|true|false)\\\$\")) (\": \" . \ + \$Error) \".\" ]);\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set ExitOnError do={\r\ + \n :local Name [ :tostr \$1 ];\r\ + \n :local Error [ :tostr \$2 ];\r\ + \n :global IfThenElse;\r\ + \n :log error (\$Name . \" \" . [ \$IfThenElse ([ :pick \$Name 0 1 ] = \"\ + \\\$\") \\\r\ + \n \"Function\" \"Script\" ] . \" '\" . \$Name . \"' exited with erro\ + r\" . \\\r\ + \n [ \$IfThenElse (!(\$Error ~ \"^(|true|false)\\\$\")) (\": \" . \$E\ + rror) \".\" ]);\r\ + \n}\r\ + \n\r\ + \n:set MiniDateTimeStamp do={\r\ + \n :local mikro [ :tobool \$1 ];\r\ + \n /system/clock;\r\ + \n :local vdate [get date];\r\ + \n :local vtime [get time];\r\ + \n :local vdoff [:toarray \"0,4,5,7,8,10\"];\r\ + \n :local MM [:pick \$vdate (\$vdoff->2) (\$vdoff->3)];\r\ + \n :local M [:tonum \$MM];\r\ + \n :if (\$vdate ~ \".../../....\") do={\r\ + \n :set vdoff [:toarray \"7,11,1,3,4,6\"];\r\ + \n :set M ([:find \"xxanebarprayunulugepctovecANEBARPRAYUNULUGE\ + PCTOVEC\" [:pick \$vdate (\$vdoff->2) (\$vdoff->3)] -1] / 2);\r\ + \n :if (\$M>12) do={:set M (\$M - 12)}\r\ + \n :set MM [:pick (100 + \$M) 1 3];\r\ + \n }\r\ + \n :local yyyy [:pick \$vdate (\$vdoff->0) (\$vdoff->1)];\r\ + \n :local dd [:pick \$vdate (\$vdoff->4) (\$vdoff->5)];\r\ + \n :local HH [:pick \$vtime 0 2];\r\ + \n :local mm [:pick \$vtime 3 5];\r\ + \n :local ss [:pick \$vtime 6 8];\r\ + \n :local Return;\r\ + \n :if (\$mikro = true) do={\r\ + \n :set Return ([:pick \$yyyy 2 4] . [:pick \$dd 0 1] . [:pick \$HH 0\ + \_1] . [:pick \$mm 3 4] . [:pick \$ss 6 7]);\r\ + \n } else={\r\ + \n :set Return ([\$yyyy] . [\$MM] . [\$dd] . [\$HH] . [\$mm] . [\$ss]);\ + \r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set WaitForFile do={\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :local WaitTime [ :totime \$2 ];\r\ + \n :global CleanFilePath;\r\ + \n :global EitherOr;\r\ + \n :global MAX;\r\ + \n :set FileName [ \$CleanFilePath \$FileName ];\r\ + \n :local Delay ([ \$MAX [ \$EitherOr \$WaitTime 2s ] 100ms ] / 9);\r\ + \n :do {\r\ + \n :retry {\r\ + \n /file/get \$FileName;\r\ + \n :return true;\r\ + \n } delay=\$Delay max=10;\r\ + \n } on-error={ }\r\ + \n :while ([ :len [ /file/find where name=\$FileName ] ] > 0) do={\r\ + \n :do {\r\ + \n /file/get \$FileName;\r\ + \n :return true;\r\ + \n } on-error={ }\r\ + \n :delay \$Delay;\r\ + \n :set Delay (\$Delay * 3 / 2);\r\ + \n }\r\ + \n :return false;\r\ + \n}\r\ + \n\r\ + \n:set FileGet do={\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :global WaitForFile;\r\ + \n :if ([ \$WaitForFile \$FileName 0s ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n :local FileVal false;\r\ + \n :do {\r\ + \n :set FileVal [ /file/get \$FileName ];\r\ + \n } on-error={ }\r\ + \n :return \$FileVal;\r\ + \n}\r\ + \n\r\ + \n:set RmDir do={\r\ + \n :local DirName [ :tostr \$1 ];\r\ + \n :global FileGet;\r\ + \n :log debug (\$0 . \" Removing directory: \". \$DirName);\r\ + \n :local DirVal [ \$FileGet \$DirName ];\r\ + \n :if (\$DirVal = false) do={\r\ + \n :log debug (\$0 . \" ... which does not exist.\");\r\ + \n :return true;\r\ + \n };\r\ + \n :if (\$DirVal->\"type\" != \"directory\") do={\r\ + \n :log error (\$0 . \" Directory '\" . \$DirName . \"' is not a direct\ + ory.\");\r\ + \n :return false;\r\ + \n };\r\ + \n :onerror Err {\r\ + \n /file/remove \$DirName;\r\ + \n } do={\r\ + \n :log error (\$0 . \" Removing directory '\" . \$DirName . \"' failed\ + : \" . \$Err);\r\ + \n :return false;\r\ + \n };\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set RmFile do={\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :global FileGet;\r\ + \n :log debug (\$0 . \" Removing file: \". \$FileName);\r\ + \n :local FileVal [ \$FileGet \$FileName ];\r\ + \n :if (\$FileVal = false) do={\r\ + \n :log debug (\$0 . \" ... which does not exist.\");\r\ + \n :return true;\r\ + \n }\r\ + \n :if (\$FileVal->\"type\" = \"directory\" || \$FileVal->\"type\" = \"di\ + sk\") do={\r\ + \n :log error (\$0 . \" File '\" . \$FileName . \"' is not a file.\");\ + \r\ + \n :return false;\r\ + \n }\r\ + \n :onerror Err {\r\ + \n /file/remove \$FileName;\r\ + \n } do={\r\ + \n :log error (\$0 . \" Removing file '\" . \$FileName . \"' failed: \"\ + \_. \$Err); :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set MkDir do={\r\ + \n :local Path [ :tostr \$1 ];\r\ + \n :global CleanFilePath;\r\ + \n :global FileGet;\r\ + \n :global RmDir;\r\ + \n :global WaitForFile;\r\ + \n\r\ + \n :local MkTmpfs do={\r\ + \n :global WaitForFile;\r\ + \n :local TmpFs [ /disk/find where slot=tmpfs type=tmpfs ];\r\ + \n :if ([ :len \$TmpFs ] = 1) do={\r\ + \n :if ([ /disk/get \$TmpFs disabled ] = true) do={\r\ + \n :log info (\$0 . \" The tmpfs is disabled, enabling.\");\r\ + \n /disk/enable \$TmpFs;\r\ + \n }\r\ + \n :return true;\r\ + \n }\r\ + \n :log info (\$0 . \" Creating disk of type tmpfs.\");\r\ + \n \$RmDir \"tmpfs\";\r\ + \n :onerror Err {\r\ + \n /disk/add slot=tmpfs type=tmpfs tmpfs-max-size=([ /system/resource\ + /get total-memory ] / 3);\r\ + \n \$WaitForFile \"tmpfs\";\r\ + \n } do={\r\ + \n :log warning (\$0 . \" Creating disk of type tmpfs failed: \" . \$\ + Err);\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n }\r\ + \n :set Path [ \$CleanFilePath \$Path ];\r\ + \n :if (\$Path = \"\") do={\r\ + \n :return true;\r\ + \n }\r\ + \n :log debug (\$0 . \" Making directory: \" . \$Path);\r\ + \n :local PathVal [ \$FileGet \$Path ];\r\ + \n :if (\$PathVal->\"type\" = \"directory\") do={\r\ + \n :log debug (\$0 . \" ... which already exists.\");\r\ + \n :return true;\r\ + \n }\r\ + \n :if ([ :pick \$Path 0 5 ] = \"tmpfs\") do={\r\ + \n :if ([ \$MkTmpfs ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n :onerror Err {\r\ + \n /file/add type=\"directory\" name=\$Path;\r\ + \n \$WaitForFile \$Path;\r\ + \n } do={\r\ + \n :log warning (\$0 . \" Making directory '\" . \$Path . \"' failed: \ + \" . \$Err);\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set MAX do={:if (\$1 > \$2) do={:return \$1}\r\ + \n :return \$2;\r\ + \n}\r\ + \n:set MIN do={:if (\$1 < \$2) do={:return \$1}\r\ + \n :return \$2;\r\ + \n}\r\ + \n\r\ + \n:set CharacterMultiply do={\r\ + \n :local Str [ :tostr \$1 ];\r\ + \n :local Num [ :tonum \$2 ];\r\ + \n :if (\$Num = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :for I from=1 to=\$Num do={:set Return (\$Return . \$Str)}\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set CharacterReplace do={\r\ + \n :local String [ :tostr \$1 ];\r\ + \n :local ReplaceFrom [ :tostr \$2 ];\r\ + \n :local ReplaceWith [ :tostr \$3 ];\r\ + \n :local Return \"\";\r\ + \n :if (\$ReplaceFrom = \"\") do={:return \$String}\r\ + \n :while ([ :typeof [ :find \$String \$ReplaceFrom ] ] != \"nil\") do={\ + \r\ + \n :local Pos [ :find \$String \$ReplaceFrom ];\r\ + \n :set Return (\$Return . [ :pick \$String 0 \$Pos ] . \$ReplaceWith);\ + \r\ + \n :set String [ :pick \$String (\$Pos + [ :len \$ReplaceFrom ]) [ :len\ + \_\$String ] ];\r\ + \n }\r\ + \n :return (\$Return . \$String);\r\ + \n}\r\ + \n\r\ + \n:set IfThenElse do={\r\ + \n :if ([ :tostr \$1 ] = \"true\" || [ :tobool \$1 ] = true) do={:return \ + \$2};\r\ + \n :return \$3;\r\ + \n}\r\ + \n\r\ + \n:set EitherOr do={\r\ + \n :global IfThenElse;\r\ + \n :if ([ :typeof \$1 ] = \"num\") do={:return [ \$IfThenElse (\$1 != 0) \ + \$1 \$2 ]}\r\ + \n :if ([ :typeof \$1 ] = \"time\") do={:return [ \$IfThenElse (\$1 > 0s)\ + \_\$1 \$2 ]}\r\ + \n# this works for boolean values, literal ones with parentheses\r\ + \n :return [ \$IfThenElse ([ :len [ :tostr \$1 ] ] > 0) \$1 \$2 ];\r\ + \n}\r\ + \n\r\ + \n:set ParseKeyValueStore do={\r\ + \n :local Source \$1;\r\ + \n :if ([ :pick \$Source 0 1 ] = \"{\") do={\r\ + \n :do {\r\ + \n :return [ :deserialize from=json \$Source ];\r\ + \n } on-error={ }\r\ + \n } \r\ + \n :if ([ :typeof \$Source ] != \"array\") do={:set Source [ :tostr \$1 ]\ + }\r\ + \n :local Result ({});\r\ + \n :foreach KeyValue in=[ :toarray \$Source ] do={\r\ + \n :if ([ :find \$KeyValue \"=\" ]) do={\r\ + \n :local Key [ :pick \$KeyValue 0 [ :find \$KeyValue \"=\" ] ];\r\ + \n :local Value [ :pick \$KeyValue ([ :find \$KeyValue \"=\" ] + 1) [\ + \_:len \$KeyValue ] ];\r\ + \n :if (\$Value=\"true\") do={:set Value true}\r\ + \n :if (\$Value=\"false\") do={:set Value false}\r\ + \n :set (\$Result->\$Key) \$Value;\r\ + \n } else={:set (\$Result->\$KeyValue) true}\r\ + \n }\r\ + \n :return \$Result;\r\ + \n}\r\ + \n:set RequiredRouterOS do={\r\ + \n :local Caller [ :tostr \$1 ];\r\ + \n :local Required [ :tostr \$2 ];\r\ + \n :local Warn [ :tostr \$3 ];\r\ + \n :global IfThenElse;\r\ + \n :global VersionToNum;\r\ + \n :if (!(\$Required ~ \"^\\\\d+\\\\.\\\\d+((alpha|beta|rc|\\\\.)\\\\d+|)\ + \\\$\")) do={\r\ + \n :log error (\$0 . \" No valid RouterOS version: \" . \$Required);\r\ + \n :return false;\r\ + \n }\r\ + \n :if ([ \$VersionToNum \$Required ] > [ \$VersionToNum [ /system/packag\ + e/update/get installed-version ] ]) do={\r\ + \n :if (\$Warn = \"true\") do={\r\ + \n :log warning (\$0 . \" This \" . [ \$IfThenElse ([ :pick \$Caller \ + 0 ] = (\"\\\$\")) \"function\" \"script\" ] . \\\r\ + \n \" '\" . \$Caller . \"' (at least specific functionality) requir\ + es RouterOS \" . \$Required . \". Please update!\");\r\ + \n }\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set ValidateSyntax do={\r\ + \n :local Code [ :tostr \$1 ];\r\ + \n :global LogPrint;\r\ + \n :onerror Err {\r\ + \n [ :parse (\":local Validate do={\\n\" . \$Code . \"\\n}\") ];\r\ + \n } do={\r\ + \n \$LogPrint debug \$0 (\"Valdation failed: \" . \$Err);\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set VersionToNum do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :local Multi 0x1000000;\r\ + \n :local Return 0;\r\ + \n :global CharacterReplace;\r\ + \n :set Input [ \$CharacterReplace \$Input \".\" \",\" ];\r\ + \n :foreach I in={ \"zero\"; \"alpha\"; \"beta\"; \"rc\" } do={\r\ + \n :set Input [ \$CharacterReplace \$Input \$I (\",\" . \$I . \",\") ];\ + \r\ + \n }\r\ + \n :foreach Value in=([ :toarray \$Input ], 0) do={\r\ + \n :local Num [ :tonum \$Value ];\r\ + \n :if (\$Multi = 0x100) do={\r\ + \n :if ([ :typeof \$Num ] = \"num\") do={\r\ + \n :set Return (\$Return + 0xff00);\r\ + \n :set Multi (\$Multi / 0x100);\r\ + \n } else={\r\ + \n :if (\$Value = \"zero\") do={ }\r\ + \n :if (\$Value = \"alpha\") do={ :set Return (\$Return + 0x3f00); \ + }\r\ + \n :if (\$Value = \"beta\") do={ :set Return (\$Return + 0x5f00); }\ + \r\ + \n :if (\$Value = \"rc\") do={ :set Return (\$Return + 0x7f00); }\r\ + \n }\r\ + \n }\r\ + \n :if ([ :typeof \$Num ] = \"num\") do={ :set Return (\$Return + (\$Va\ + lue * \$Multi)); }\r\ + \n :set Multi (\$Multi / 0x100);\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set ScriptLock do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local WaitMax [ :totime \$2 ];\r\ + \n :global GetRandom20CharAlNum;\r\ + \n :global IfThenElse;\r\ + \n :global ScriptLockOrder;\r\ + \n :if ([ :typeof \$ScriptLockOrder ] = \"nothing\") do={\r\ + \n :set ScriptLockOrder ({});\r\ + \n }\r\ + \n :if ([ :typeof (\$ScriptLockOrder->\$Script) ] = \"nothing\") do={\r\ + \n :set (\$ScriptLockOrder->\$Script) ({});\r\ + \n }\r\ + \n :local JobCount do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :return [ :len [ /system/script/job/find where script=\$Script ] ];\ + \r\ + \n }\r\ + \n :local TicketCount do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :local Count 0;\r\ + \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :if ([ :typeof \$Ticket ] != \"nothing\") do={:set Count (\$Count \ + + 1)}\r\ + \n }\r\ + \n :return \$Count;\r\ + \n }\r\ + \n :local IsFirstTicket do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local Check [ :tostr \$2 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :if (\$Ticket = \$Check) do={:return true}\r\ + \n :if ([ :typeof \$Ticket ] != \"nothing\" && \$Ticket != \$Check) d\ + o={:return false}\r\ + \n }\r\ + \n :return false;\r\ + \n }\r\ + \n :local AddTicket do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local Add [ :tostr \$2 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :while (true) do={\r\ + \n :local Pos [ :len (\$ScriptLockOrder->\$Script) ];\r\ + \n :set (\$ScriptLockOrder->\$Script->\$Pos) \$Add;\r\ + \n :delay 10ms;\r\ + \n :if ((\$ScriptLockOrder->\$Script->\$Pos) = \$Add) do={:return tru\ + e}\r\ + \n }\r\ + \n }\r\ + \n :local RemoveTicket do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local Remove [ :tostr \$2 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :foreach Id,Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :while ((\$ScriptLockOrder->\$Script->\$Id) = \$Remove) do={\r\ + \n :set (\$ScriptLockOrder->\$Script->\$Id);\r\ + \n :delay 10ms;\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n :local CleanupTickets do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :if ([ :typeof \$Ticket ] != \"nothing\") do={:return false}\r\ + \n }\r\ + \n :set (\$ScriptLockOrder->\$Script) ({});\r\ + \n }\r\ + \n :if ([ :typeof \$WaitMax ] = \"nil\" ) do={:set WaitMax 0s}\r\ + \n :if ([ :len [ /system/script/find where name=\$Script ] ] = 0) do={\r\ + \n :log error (\$0 . \" A script named '\" . \$Script . \"' does not ex\ + ist!\");\r\ + \n :error false;\r\ + \n }\r\ + \n :if ([ \$JobCount \$Script ] = 0) do={\r\ + \n \$LogPrint error \$0 (\"No script '\" . \$Script . \"' is running!\"\ + );\r\ + \n :error false;\r\ + \n }\r\ + \n :if ([ \$TicketCount \$Script ] >= [ \$JobCount \$Script ]) do={\r\ + \n :log error (\$0 . \" More tickets than running scripts '\" . \$Scrip\ + t . \"', resetting!\");\r\ + \n :set (\$ScriptLockOrder->\$Script) ({});\r\ + \n /system/script/job/remove [ find where script=\$Script ];\r\ + \n }\r\ + \n :local MyTicket [ \$GetRandom20CharAlNum 6 ];\r\ + \n \$AddTicket \$Script \$MyTicket;\r\ + \n :local WaitInterval (\$WaitMax / 20);\r\ + \n :local WaitTime \$WaitMax;\r\ + \n :while (\$WaitTime > 0 && \\\r\ + \n ([ \$IsFirstTicket \$Script \$MyTicket ] = false || \\\r\ + \n [ \$TicketCount \$Script ] < [ \$JobCount \$Script ])) do={\r\ + \n :set WaitTime (\$WaitTime - \$WaitInterval);\r\ + \n :delay \$WaitInterval;\r\ + \n }\r\ + \n :if ([ \$IsFirstTicket \$Script \$MyTicket ] = true && \\\r\ + \n [ \$TicketCount \$Script ] = [ \$JobCount \$Script ]) do={\r\ + \n \$RemoveTicket \$Script \$MyTicket;\r\ + \n \$CleanupTickets \$Script;\r\ + \n :return true;\r\ + \n }\r\ + \n \$RemoveTicket \$Script \$MyTicket;\r\ + \n \$LogPrint debug \$0 (\"Script '\" . \$Script . \"' started more than \ + once\" . \\\r\ + \n [ \$IfThenElse (\$WaitTime < \$WaitMax) \" and timed out waiting for\ + \_lock\" \"\" ] . \"...\");\r\ + \n :return false;\r\ + \n}\r\ + \n\r\ + \n:set SendNotification do={ :onerror Err {\r\ + \n :global SendNotification2;\r\ + \n \$SendNotification2 ({ origin=\$0; subject=\$1; message=\$2; link=\$3;\ + \_silent=\$4 });\r\ + \n} do={:global ExitOnError; \$ExitOnError \$0 \$Err}\r\ + \n}\r\ + \n\r\ + \n:set SendNotification2 do={\r\ + \n :local Notification \$1;\r\ + \n :global NotificationFunctions;\r\ + \n :foreach FunctionName,Discard in=\$NotificationFunctions do={\r\ + \n (\$NotificationFunctions->\$FunctionName) (\"\\\$NotificationFunctio\ + ns->\\\"\" . \$FunctionName . \"\\\"\") \$Notification;\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set SymbolByUnicodeName do={\r\ + \n :local Name [ :tostr \$1 ];\r\ + \n :global EitherOr;\r\ + \n :global SymbolsExtra;\r\ + \n :local Symbols ({\r\ + \n \"abacus\"=\"\\F0\\9F\\A7\\AE\";\r\ + \n \"alarm-clock\"=\"\\E2\\8F\\B0\";\r\ + \n \"arrow-down\"=\"\\E2\\AC\\87\";\r\ + \n \"arrow-up\"=\"\\E2\\AC\\86\";\r\ + \n \"calendar\"=\"\\F0\\9F\\93\\85\";\r\ + \n \"card-file-box\"=\"\\F0\\9F\\97\\83\";\r\ + \n \"chart-decreasing\"=\"\\F0\\9F\\93\\89\";\r\ + \n \"chart-increasing\"=\"\\F0\\9F\\93\\88\";\r\ + \n \"cloud\"=\"\\E2\\98\\81\";\r\ + \n \"cross-mark\"=\"\\E2\\9D\\8C\";\r\ + \n \"earth\"=\"\\F0\\9F\\8C\\8D\";\r\ + \n \"fire\"=\"\\F0\\9F\\94\\A5\";\r\ + \n \"floppy-disk\"=\"\\F0\\9F\\92\\BE\";\r\ + \n \"gear\"=\"\\E2\\9A\\99\";\r\ + \n \"heart\"=\"\\E2\\99\\A5\";\r\ + \n \"high-voltage-sign\"=\"\\E2\\9A\\A1\";\r\ + \n \"incoming-envelope\"=\"\\F0\\9F\\93\\A8\";\r\ + \n \"information\"=\"\\E2\\84\\B9\";\r\ + \n \"large-orange-circle\"=\"\\F0\\9F\\9F\\A0\";\r\ + \n \"large-red-circle\"=\"\\F0\\9F\\94\\B4\";\r\ + \n \"link\"=\"\\F0\\9F\\94\\97\";\r\ + \n \"lock-with-ink-pen\"=\"\\F0\\9F\\94\\8F\";\r\ + \n \"memo\"=\"\\F0\\9F\\93\\9D\";\r\ + \n \"mobile-phone\"=\"\\F0\\9F\\93\\B1\";\r\ + \n \"pushpin\"=\"\\F0\\9F\\93\\8C\";\r\ + \n \"scissors\"=\"\\E2\\9C\\82\";\r\ + \n \"scroll\"=\"\\F0\\9F\\93\\9C\";\r\ + \n \"smiley-partying-face\"=\"\\F0\\9F\\A5\\B3\";\r\ + \n \"smiley-smiling-face\"=\"\\E2\\98\\BA\";\r\ + \n \"smiley-winking-face-with-tongue\"=\"\\F0\\9F\\98\\9C\";\r\ + \n \"sparkles\"=\"\\E2\\9C\\A8\";\r\ + \n \"speech-balloon\"=\"\\F0\\9F\\92\\AC\";\r\ + \n \"star\"=\"\\E2\\AD\\90\";\r\ + \n \"warning-sign\"=\"\\E2\\9A\\A0\";\r\ + \n \"white-heavy-check-mark\"=\"\\E2\\9C\\85\"\r\ + \n }, \$SymbolsExtra);\r\ + \n :local Magic [ :pick [ /system/clock/get date ] 4 10 ];\r\ + \n :local Special {\r\ + \n \"information-04-01\"=\"\\F0\\9F\\9A\\BB\";\r\ + \n \"large-orange-circle-04-01\"=\"\\F0\\9F\\8D\\8A\";\r\ + \n \"large-orange-circle-10-31\"=\"\\F0\\9F\\8E\\83\";\r\ + \n \"large-red-circle-04-01\"=\"\\F0\\9F\\8D\\92\" };\r\ + \n :if ([ :len (\$Symbols->\$Name) ] = 0) do={\r\ + \n :log warning (\$0 . \"No symbol available for name '\" . \$Name . \"\ + '!\");\r\ + \n :return \"\";\r\ + \n }\r\ + \n :return ([ \$EitherOr (\$Special->(\$Name . \$Magic)) (\$Symbols->\$Na\ + me) ] . \"\\EF\\B8\\8F\");\r\ + \n}\r\ + \n\r\ + \n:set SymbolForNotification do={\r\ + \n :global NotificationsWithSymbols;\r\ + \n :global SymbolByUnicodeName;\r\ + \n :global IfThenElse;\r\ + \n :if (\$NotificationsWithSymbols != true) do={:return [ \$IfThenElse ([\ + \_:len \$2 ] > 0) ([ :tostr \$2 ] . \" \") \"\" ]}\r\ + \n :local Return \"\";\r\ + \n :foreach Symbol in=[ :toarray \$1 ] do={:set Return (\$Return . [ \$Sy\ + mbolByUnicodeName \$Symbol ])}\r\ + \n :return (\$Return . \" \");\r\ + \n}\r\ + \n\r\ + \n:set Unix2Dos do={:return [ :tocrlf [ :tostr \$1 ] ]}\r\ + \n:set UrlEncode do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :if ([ :len \$Input ] = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :local Chars (\"\\n\\r !\\\"#\\\$%&'()*+,:;<=>\?@[\\\\]^`{|}~\");\r\ + \n :local Subs { \"%0A\"; \"%0D\"; \"%20\"; \"%21\"; \"%22\"; \"%23\"; \"\ + %24\"; \"%25\"; \"%26\"; \"%27\";\r\ + \n \"%28\"; \"%29\"; \"%2A\"; \"%2B\"; \"%2C\"; \"%3A\"; \"%3B\"; \ + \"%3C\"; \"%3D\"; \"%3E\"; \"%3F\";\r\ + \n \"%40\"; \"%5B\"; \"%5C\"; \"%5D\"; \"%5E\"; \"%60\"; \"%7B\"; \ + \"%7C\"; \"%7D\"; \"%7E\" };\r\ + \n :for I from=0 to=([ :len \$Input ] - 1) do={\r\ + \n :local Char [ :pick \$Input \$I ];\r\ + \n :local Replace [ :find \$Chars \$Char ];\r\ + \n :if ([ :typeof \$Replace ] = \"num\") do={:set Char (\$Subs->\$Repla\ + ce)}\r\ + \n :set Return (\$Return . \$Char);\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set IsDNSResolving do={\r\ + \n :do {:resolve \"api.telegram.org\"} on-error={:return false}\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set IsFullyConnected do={\r\ + \n :global IsDNSResolving;\r\ + \n :global IsTimeSync;\r\ + \n :if ([ \$IsDNSResolving ] = false) do={:return false};\r\ + \n :if ([ \$IsTimeSync ] = false) do={:return false};\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set IsTimeSync do={\r\ + \n :global IsTimeSyncCached;\r\ + \n :global IsTimeSyncResetNtp;\r\ + \n :if (\$IsTimeSyncCached = true) do={:return true}\r\ + \n :if ([ /system/ntp/client/get enabled ] = true) do={\r\ + \n :if ([ /system/ntp/client/get status ] = \"synchronized\") do={\r\ + \n :set IsTimeSyncCached true;\r\ + \n :return true;\r\ + \n }\r\ + \n :local Uptime [ /system/resource/get uptime ];\r\ + \n :if ([ :typeof \$IsTimeSyncResetNtp ] = \"nothing\") do={\r\ + \n :set IsTimeSyncResetNtp \$Uptime;\r\ + \n }\r\ + \n :if (\$Uptime - \$IsTimeSyncResetNtp < 3m) do={:return false}\r\ + \n :log warning \"\$0 The ntp client is configured, but did not sync.\"\ + ;\r\ + \n :set IsTimeSyncResetNtp \$Uptime;\r\ + \n /system/ntp/client/set enabled=no;\r\ + \n :delay 20ms;\r\ + \n /system/ntp/client/set enabled=yes;\r\ + \n :return false;\r\ + \n }\r\ + \n :if ([ /system/license/get ]->\"level\" = \"free\" || \\\r\ + \n [ /system/resource/get ]->\"board-name\" = \"x86\") do={\r\ + \n :log debug \"\$0 No ntp client configured, relying on RTC for CHR fr\ + ee license and x86.\";\r\ + \n :return true;\r\ + \n }\r\ + \n :if ([ /ip/cloud/get update-time ] = true) do={\r\ + \n :if ([ :typeof [ /ip/cloud/get public-address ] ] = \"ip\") do={\r\ + \n :set IsTimeSyncCached true;\r\ + \n :return true;\r\ + \n }\r\ + \n :return false;\r\ + \n }\r\ + \n :log debug \"\$0 No time source configured! Returning gracefully...\";\ + \r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set FetchHugeFiles do={\r\ + \n :local ScriptName [ :tostr \$1 ];\r\ + \n :local Url [ :tostr \$2 ];\r\ + \n :local CheckCert [ :tostr \$3 ];\r\ + \n\r\ + \n :global CleanName;\r\ + \n :global FetchUserAgentStr;\r\ + \n :global GetRandom20CharAlNum;\r\ + \n :global IfThenElse;\r\ + \n :global LogPrint;\r\ + \n :global MkDir;\r\ + \n :global RmDir;\r\ + \n :global RmFile;\r\ + \n :global WaitForFile;\r\ + \n\r\ + \n :set CheckCert [ \$IfThenElse (\$CheckCert = \"false\") \"no\" \"yes-w\ + ithout-crl\" ];\r\ + \n\r\ + \n :local DirName (\"tmpfs/\" . [ \$CleanName \$ScriptName ]);\r\ + \n :if ([ \$MkDir \$DirName ] = false) do={\r\ + \n \$LogPrint error \$0 (\"Failed creating directory!\");\r\ + \n :return false;\r\ + \n }\r\ + \n\r\ + \n :local FileName (\$DirName . \"/\" . [ \$CleanName \$0 ] . \"-\" . [ \ + \$GetRandom20CharAlNum ]);\r\ + \n :onerror Err {\r\ + \n /tool/fetch check-certificate=\$CheckCert \$Url dst-path=\$FileName \ + \\\r\ + \n http-header-field=({ [ \$FetchUserAgentStr \$ScriptName ] }) as-va\ + lue;\r\ + \n } do={\r\ + \n :if ([ \$WaitForFile \$FileName 500ms ] = true) do={\r\ + \n \$RmFile \$FileName;\r\ + \n }\r\ + \n \$LogPrint debug \$0 (\"Failed downloading from \" . \$Url . \" - \"\ + \_. \$Err);\r\ + \n \$RmDir \$DirName;\r\ + \n :return false;\r\ + \n }\r\ + \n\r\ + \n :if ([ \$WaitForFile \$FileName 5s ] = false) do={\r\ + \n \$LogPrint debug \$0 (\"The file downloaded from \" . \$Url . \" did\ + \_not show up.\");\r\ + \n :return false;\r\ + \n }\r\ + \n\r\ + \n :local FileSize [ /file/get \$FileName size ];\r\ + \n :local Return \"\";\r\ + \n :local VarSize 0;\r\ + \n :while (\$VarSize != \$FileSize) do={\r\ + \n :set Return (\$Return . ([ /file/read offset=\$VarSize chunk-size=32\ + 768 file=\$FileName as-value ]->\"data\"));\r\ + \n :set FileSize [ /file/get \$FileName size ];\r\ + \n :set VarSize [ :len \$Return ];\r\ + \n :if (\$VarSize > \$FileSize) do={\r\ + \n :delay 100ms;\r\ + \n }\r\ + \n }\r\ + \n \$RmDir \$DirName;\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set FetchUserAgentStr do={\r\ + \n :local Caller [ :tostr \$1 ];\r\ + \n :global GlobalScriptsUrl;\r\ + \n :global CommitBrief;\r\ + \n :global IfThenElse;\r\ + \n :local Resource [ /system/resource/get ];\r\ + \n :return (\"User-Agent: Mikrotik/\" . \$Resource->\"version\" . \" \" .\ + \_\$Resource->\"architecture-name\" . \\\r\ + \n \" \" . \$Caller . \"/Fetch (\" . \$GlobalScriptsUrl . \"; \" . [ \$\ + CommitBrief ] . \")\");\r\ + \n}\r\ + \n\r\ + \n:set ScriptInstallUpdate do={ :onerror Err {\r\ + \n :local Scripts [ :toarray \$1 ];\r\ + \n :local NewComment [ :tostr \$2 ];\r\ + \n :global InitSetup;\r\ + \n\r\ + \n :global CommitId;\r\ + \n :global ScriptUpdatesCRLF;\r\ + \n :global GlobalConfVersion;\r\ + \n :global Identity;\r\ + \n :global CertificateAvailable;\r\ + \n :global CheckSumsVerify;\r\ + \n :global GlobalScriptsUrl;\r\ + \n :global SumsDirAndFileName;\r\ + \n :global GlobalScriptsUrlSuffix;\r\ + \n :global EitherOr;\r\ + \n :global FetchUserAgentStr;\r\ + \n :global Grep;\r\ + \n :global IfThenElse;\r\ + \n :global LogPrint;\r\ + \n :global ParseKeyValueStore;\r\ + \n :global RequiredRouterOS;\r\ + \n :global SendNotification2;\r\ + \n :global SymbolForNotification;\r\ + \n :global ValidateSyntax;\r\ + \n :global CommentsInScripts;\r\ + \n\r\ + \n :if ([ \$CertificateAvailable \"Root YE\" \"fetch\" ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Downloading certificate failed, trying wit\ + hout.\");\r\ + \n }\r\ + \n\r\ + \n :foreach Script in=\$Scripts do={\r\ + \n :if ([ :len [ /system/script/find where name=\$Script ] ] = 0) do={\ + \r\ + \n \$LogPrint info \$0 (\"Adding new script: \" . \$Script);\r\ + \n /system/script/add name=\$Script owner=\$Script source=\"#!rsc by \ + Vados\\n\" comment=\$NewComment;\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :local CommitIdBefore \$CommitId;\r\ + \n :local GlobalConfVersionBefore \$GlobalConfVersion;\r\ + \n :local ReloadGlobal false;\r\ + \n :local DeviceMode [ /system/device-mode/get ];\r\ + \n\r\ + \n :if (\$CheckSumsVerify = true) do={\r\ + \n :local CheckSums ({});\r\ + \n :do {\r\ + \n :local Url (\$GlobalScriptsUrl . \$SumsDirAndFileName . \$GlobalScr\ + iptsUrlSuffix);\r\ + \n \$LogPrint debug \$0 (\"Fetching checksums from url: \" . \$Url);\ + \r\ + \n :set CheckSums [ :deserialize from=json ([ /tool/fetch check-certi\ + ficate=yes-without-crl \\\r\ + \n http-header-field=({ [ \$FetchUserAgentStr \$0 ] }) \$Url output\ + =user as-value ]->\"data\") ];\r\ + \n } on-error={ \$LogPrint warning \$0 (\"Err = \" . \$Err); }\r\ + \n }\r\ + \n\r\ + \n :foreach Script in=[ /system/script/find where source~\"^#!rsc by Vado\ + s\" ] do={\r\ + \n :local ScriptVal [ /system/script/get \$Script ];\r\ + \n :local ScriptInfo [ \$ParseKeyValueStore (\$ScriptVal->\"comment\") \ + ];\r\ + \n :local SourceNew;\r\ + \n\r\ + \n :foreach Scheduler in=[ /system/scheduler/find where on-event~(\"\\\ + \\b\" . \$ScriptVal->\"name\" . \"\\\\b\") ] do={\r\ + \n :local SchedulerVal [ /system/scheduler/get \$Scheduler ];\r\ + \n :if (\$ScriptVal->\"policy\" != \$SchedulerVal->\"policy\") do={\r\ + \n \$LogPrint warning \$0 (\"Policies differ for script '\" . \$Scr\ + iptVal->\"name\" . \"' and its scheduler '\" . \$SchedulerVal->\"name\" . \ + \"'!\");\r\ + \n }\r\ + \n }\r\ + \n :do {\r\ + \n :if (\$ScriptInfo->\"ignore\" = true) do={\r\ + \n \$LogPrint debug \$0 (\"Ignoring script '\" . \$ScriptVal->\"nam\ + e\" . \"', as requested.\");\r\ + \n :error true;\r\ + \n }\r\ + \n :if (\$CheckSumsVerify = true) do={\r\ + \n :local CheckSum (\$CheckSums->(\$ScriptVal->\"name\"));\r\ + \n :if ([ :len (\$ScriptInfo->\"base-url\") ] = 0 && [ :len (\$Scri\ + ptInfo->\"url-suffix\") ] = 0 && \\\r\ + \n [ :convert transform=md5 to=hex [ :tolf (\$ScriptVal->\"sou\ + rce\") ] ] = \$CheckSum) do={\r\ + \n \$LogPrint debug \$0 (\"Checksum for script '\" . \$ScriptVal-\ + >\"name\" . \"' matches, ignoring.\");\r\ + \n :error true;\r\ + \n }\r\ + \n }\r\ + \n :if ([ :len (\$ScriptInfo->\"certificate\") ] > 0) do={\r\ + \n :if ([ \$CertificateAvailable (\$ScriptInfo->\"certificate\") \"\ + fetch\" ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Downloading certificate failed, tryi\ + ng without.\");\r\ + \n }\r\ + \n }\r\ + \n :onerror Err {\r\ + \n :local BaseUrl [ \$EitherOr (\$ScriptInfo->\"base-url\") \$Globa\ + lScriptsUrl ];\r\ + \n :local UrlSuffix [ \$EitherOr (\$ScriptInfo->\"url-suffix\") \$G\ + lobalScriptsUrlSuffix ];\r\ + \n :local Url (\$BaseUrl . \$ScriptVal->\"name\" . \".rsc\" . \$Url\ + Suffix);\r\ + \n \$LogPrint warning \$0 (\"Fetching script '\" . (\$ScriptVal->\"\ + name\") . \"' from url: \" . \$Url);\r\ + \n :local Result [ /tool/fetch check-certificate=yes-without-crl \\\ + \r\ + \n http-header-field=({ [ \$FetchUserAgentStr \$0 ] }) \$Url outp\ + ut=user as-value ];\r\ + \n :if (\$Result->\"status\" = \"finished\") do={\r\ + \n :set SourceNew [ :tolf (\$Result->\"data\") ];\r\ + \n } \r\ + \n } do={\r\ + \n \$LogPrint warning \$0 (\"Failed fetching script '\" . \$ScriptV\ + al->\"name\" . \"': \" . \$Err);\r\ + \n :if (\$Err != \"Fetch failed with status 404\") do={\r\ + \n :error false;\r\ + \n }\r\ + \n :if (\$ScriptVal->\"source\" = \"#!rsc by Vados\") do={\r\ + \n \$LogPrint warning \$0 (\"Removing dummy. Typo on installation\ + \?\");\r\ + \n /system/script/remove \$Script;\r\ + \n :error false;\r\ + \n }\r\ + \n :if (\$CheckSumsVerify = true) do={\r\ + \n :if ([ :len (\$ScriptInfo->\"base-url\") ] = 0 && [ :len (\$Sc\ + riptInfo->\"url-suffix\") ] = 0 && \\\r\ + \n [ :len \$CheckSum ] = 0) do={\r\ + \n \$LogPrint warning \$0 (\"Added the script manually\? Skip u\ + pdates with 'ignore=true' in comment.\");\r\ + \n }\r\ + \n }\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :if ([ :len \$SourceNew ] = 0) do={\r\ + \n \$LogPrint debug \$0 (\"No update for script '\" . (\$ScriptVal-\ + >\"name\") . \"'.\");\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :local SourceCRLF [ :tocrlf \$SourceNew ];\r\ + \n :if (\$InitSetup != true && ((\$ScriptVal->\"name\") != \"AM-Globa\ + lConfig\" || (\$ScriptVal->\"name\") != \"AM-GlobalFunc\")) do={\r\ + \n :if (\$SourceNew = (\$ScriptVal->\"source\") || \$SourceCRLF = (\ + \$ScriptVal->\"source\")) do={\r\ + \n \$LogPrint debug \$0 (\"Script '\" . (\$ScriptVal->\"name\") \ + . \"' source did not change. End of lines set to CRLF.\");\r\ + \n if (\$ScriptUpdatesCRLF = false) do={\r\ + \n :put [ :tolf \$SourceNew ];\r\ + \n \$LogPrint debug \$0 (\"Script '\" . (\$ScriptVal->\"name\"\ + ) . \"' source update end of lines to LF.\");\r\ + \n }\r\ + \n :error false;\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :if ([ :pick \$SourceNew 0 14 ] != \"#!rsc by Vados\") do={\r\ + \n \$LogPrint warning \$0 (\"Looks like new script '\" . \$ScriptVa\ + l->\"name\" . \"' is not valid (missing shebang = '\$shebang') Ignoring!\"\ + );\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :if (\$CommentsInScripts = true) do={\r\ + \n :local CommentLine [ \$Grep \$SourceNew (\"\\23 Script comment:\ + \_\") ];\r\ + \n :if ([ :len \$CommentLine ] = 0) do={\r\ + \n \$LogPrint debug \$0 (\"The search in new script '\" . (\$Scr\ + iptVal->\"name\") . \"' for comment in script body, is not found result Ig\ + noring!\");\r\ + \n :error false;\r\ + \n } else={\r\ + \n :if ([ :len (\$ScriptVal->\"comment\")] = 0 || [ :len (\$Scri\ + ptVal->\"comment\")] != [ :pick \$CommentLine ([ :find \$CommentLine \":\"\ + ] + 2) [ :len \$CommentLine] ]) do={\r\ + \n \$LogPrint debug \$0 (\"Exsiting comment for script '\" . (\ + \$ScriptVal->\"name\") . \"' is '\" . (\$ScriptVal->\"comment\") . \"'.\")\ + ;\r\ + \n :set (\$ScriptVal->\"comment\") [ :pick \$CommentLine ([ :f\ + ind \$CommentLine \":\"] + 2) [ :len \$CommentLine] ];\r\ + \n \$LogPrint debug \$0 (\"New comment (\" . (\$ScriptVal->\"c\ + omment\") . \") for script '\" . (\$ScriptVal->\"name\") . \"' has been ad\ + ded!\");\r\ + \n } else={\r\ + \n \$LogPrint debug \$0 (\"Comment for script '\" . (\$ScriptV\ + al->\"name\") . \"' did not change.\");\r\ + \n :error false;\r\ + \n }\r\ + \n } \r\ + \n }\r\ + \n\r\ + \n :local RequiredROS ([ \$ParseKeyValueStore [ \$Grep \$SourceNew (\ + \"\\23 requires RouterOS, \") ] ]->version);\r\ + \n :if ([ \$RequiredRouterOS \$0 [ \$EitherOr \$RequiredROS \"0.0\" ]\ + \_false ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"The script '\" . (\$ScriptVal->\"name\ + \") . \"' requires RouterOS \" . \\\r\ + \n \$RequiredROS . \", which is not met by your installation. I\ + gnoring!\");\r\ + \n :error false;\r\ + \n }\r\ + \n :local RequiredDM [ \$ParseKeyValueStore [ \$Grep \$SourceNew (\"\ + \\23 requires device-mode, \") ] ];\r\ + \n :local MissingDM ({});\r\ + \n :foreach Feature,Value in=\$RequiredDM do={\r\ + \n :if ([ :typeof (\$DeviceMode->\$Feature) ] = \"bool\" && (\$Devi\ + ceMode->\$Feature) = false) do={\r\ + \n :set MissingDM (\$MissingDM, \$Feature);\r\ + \n }\r\ + \n }\r\ + \n :if ([ :len \$MissingDM ] > 0) do={\r\ + \n \$LogPrint warning \$0 (\"The script '\" . (\$ScriptVal->\"name\ + \") . \"' requires disabled \" . \\\r\ + \n \"device-mode features (\" . [ :tostr \$MissingDM ] . \"). I\ + gnoring!\");\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :if ([ \$ValidateSyntax \$SourceNew ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Syntax validation for script '\" . (\$\ + ScriptVal->\"name\") . \"' failed! Ignoring!\");\r\ + \n :error false;\r\ + \n }\r\ + \n \r\ + \n :log info (\"Updating script: \" . (\$ScriptVal->\"name\") . \" Sc\ + ript comment: \" . (\$ScriptVal->\"comment\"));\r\ + \n\r\ + \n /system/script/set owner=(\$ScriptVal->\"name\") comment=(\$Script\ + Val->\"comment\") \\\r\ + \n source=[ \$IfThenElse (\$ScriptUpdatesCRLF = true) \$SourceCRL\ + F \$SourceNew ] \$Script;\r\ + \n :if (\$ScriptVal->\"name\" = \"AM-GlobalConfig\" || \\\r\ + \n \$ScriptVal->\"name\" = \"AM-GlobalFunc\" || \\\r\ + \n \$ScriptVal->\"name\" ~ (\"^(AM-GlobalFunc\\\\.d|mod)/.\")) d\ + o={\r\ + \n :set ReloadGlobal true;\r\ + \n }\r\ + \n } on-error={ }\r\ + \n }\r\ + \n :if (\$ReloadGlobal = true) do={\r\ + \n \$LogPrint info \$0 (\"Reloading global configuration and functions.\ + \");\r\ + \n :onerror Err {\r\ + \n :global InitSetup (a);\r\ + \n /system/script {run AM-GlobalConfig; run AM-GlobalFunc;};\r\ + \n } do={\$LogPrint error \$0 (\"Reloading global configuration and fun\ + ctions failed! \" . \$Err)}\r\ + \n }\r\ + \n :if (\$GlobalConfVersionBefore > \$GlobalConfVersion) do={\r\ + \n \$LogPrint warning \$0 (\"The configuration version decreased from \ + \" . \\\r\ + \n \$GlobalConfVersionBefore . \" to \" . \$GlobalConfVersion . \\\r\ + \n \". Installed an older version\?\");\r\ + \n }\r\ + \n :if (\$GlobalConfVersionBefore < \$GlobalConfVersion) do={\r\ + \n :global GlobalConfChanges;\r\ + \n :global GlobalConfMigration;\r\ + \n :local ChangeLogCode;\r\ + \n :if ([ :len \$ChangeLogCode ] > 0) do={\r\ + \n :if ([ \$ValidateSyntax \$ChangeLogCode ] = true) do={\r\ + \n :onerror Err {\r\ + \n [ :parse \$ChangeLogCode ];\r\ + \n } do={\$LogPrint warning \$0 (\"The changelog failed to run: \" \ + . \$Err)}\r\ + \n } else={\$LogPrint warning \$0 (\"The changelog failed syntax vali\ + dation!\")}\r\ + \n }\r\ + \n :if ([ :len \$GlobalConfMigration ] > 0) do={\r\ + \n :for I from=(\$GlobalConfVersionBefore + 1) to=\$GlobalConfVersion\ + \_do={\r\ + \n :local Migration (\$GlobalConfMigration->[ :tostr \$I ]);\r\ + \n :do {\r\ + \n :if ([ :typeof \$Migration ] != \"str\") do={\r\ + \n \$LogPrint debug \$0 (\"Migration code for change \" . \$I .\ + \_\" is not available.\");\r\ + \n :error false;\r\ + \n }\r\ + \n :if ([ \$ValidateSyntax \$Migration ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Migration code for change \" . \$I\ + \_. \" failed syntax validation!\");\r\ + \n :error false}\r\ + \n \$LogPrint info \$0 (\"Applying migration for change \" . \$I \ + . \": \" . \$Migration);\r\ + \n :onerror Err {\r\ + \n [ :parse \$Migration ];\r\ + \n } do={\$LogPrint warning \$0 (\"Migration code for change \" .\ + \_\$I . \" failed to run: \" . \$Err)}\r\ + \n } on-error={ }\r\ + \n }\r\ + \n }\r\ + \n :local NotificationMessage (\"The configuration version on \" . \$Id\ + entity . \" increased \" . \\\r\ + \n \"to \" . \$GlobalConfVersion . \", current configuration may nee\ + d modification. \" . \\\r\ + \n \"Please review and update global-config-overlay, then re-run glo\ + bal-config.\");\r\ + \n \$LogPrint info \$0 (\$NotificationMessage);\r\ + \n :if ([ :len \$GlobalConfChanges ] > 0) do={\r\ + \n :set NotificationMessage (\$NotificationMessage . \"\\n\\nChanges:\ + \");\r\ + \n :for I from=(\$GlobalConfVersionBefore + 1) to=\$GlobalConfVersion\ + \_do={\r\ + \n :local Change (\$GlobalConfChanges->[ :tostr \$I ]);\r\ + \n :set NotificationMessage (\$NotificationMessage . \"\\n \" . \\\ + \r\ + \n [ \$SymbolForNotification \"pushpin\" \"*\" ] . \$Change);\r\ + \n \$LogPrint info \$0 (\"Change \" . \$I . \": \" . \$Change);\r\ + \n }\r\ + \n } else={\r\ + \n :set NotificationMessage (\$NotificationMessage . \"\\n\\nNews and\ + \_changes are not available.\");\r\ + \n\r\ + \n }\r\ + \n\r\ + \n :if ([ :len \$GlobalConfChanges ] > 0) do={ :set GlobalConfChanges; \ + } else={ :global GlobalConfChanges (a); }\r\ + \n :if ([ :len \$GlobalConfMigration ] > 0) do={ :set GlobalConfMigrati\ + on; } else={ :global GlobalConfMigration (a); }\r\ + \n }\r\ + \n} do={\r\ + \n :global ExitOnError; \$ExitOnError \$0 \$Err;\r\ + \n} }\r\ + \n\r\ + \n# load modules\r\ + \n:foreach Script in=[ /system/script/find where name ~ \"^(global-functio\ + ns\\\\.d|mod)/.\" ] do={\r\ + \n :local ScriptVal [ /system/script/get \$Script ];\r\ + \n :if ([ \$ValidateSyntax (\$ScriptVal->\"source\") ] = true) do={\r\ + \n :onerror Err {\r\ + \n /system/script/run \$Script;\r\ + \n } do={\r\ + \n \$LogPrint error \$0 (\"Module '\" . \$ScriptVal->\"name\" . \"' f\ + ailed to run: \" . \$Err);\r\ + \n }\r\ + \n } else={\r\ + \n \$LogPrint error \$0 (\"Module '\" . \$ScriptVal->\"name\" . \"' fai\ + led syntax validation, skipping.\");\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n# Add and fix global scheduler\r\ + \n:put \"Add or/and fix Global scheduler...\";\r\ + \n:local OnEvent \"/system/script { run AM-GlobalConfig; run AM-GlobalFunc\ + ; }\";\r\ + \n:local Comment \"Every Day Set Global Environment Variables\";\r\ + \n:if ([ :len [ /system/scheduler/find where name=\"AM-SetGlobalEnv\" ] ] \ + = 0) do={\r\ + \n /system/scheduler/add name=\"AM-SetGlobalEnv\" comment=\$Comment on-ev\ + ent=\$OnEvent start-time=startup;\r\ + \n}\r\ + \n:if ([ /system/scheduler/get \"AM-SetGlobalEnv\" comment ] != \$Comment)\ + \_do={\r\ + \n /system/scheduler/set \"AM-SetGlobalEnv\" comment=\$Comment;\r\ + \n}\r\ + \n:if ([ /system/scheduler/get \"AM-SetGlobalEnv\" on-event ] != \$OnEvent\ + ) do={\r\ + \n /system/scheduler/set \"AM-SetGlobalEnv\" on-event=\$OnEvent;\r\ + \n}\r\ + \n# Add Update Script scheduler\r\ + \n:put \"Add or/and fix Update Script scheduler\";\r\ + \n:set OnEvent \":global ScriptInstallUpdate; \\\$ScriptInstallUpdate;\";\ + \r\ + \n:set Comment \"Every Day Check For Update Scripts\";\r\ + \n:if ([ :len [ /system/scheduler/find where name=\"AM-ScriptInstallUpdate\ + \" ] ] = 0) do={\r\ + \n/system/scheduler/add name=\"AM-ScriptInstallUpdate\" comment=\$Comment \ + start-time=startup interval=1d on-event=\$OnEvent;\r\ + \n}\r\ + \n\r\ + \n:onerror Err {\r\ + \n :global GlobalConfReady;\r\ + \n :retry { :if (\$GlobalConfReady != true) do={ :error (\"Global configs\ + \_not ready.\"); }; } delay=100ms max=5;\r\ + \n\r\ + \n:log warning (\"This script \$ScriptName Loaded \" . \\\r\ + \n [ \$IfThenElse (\$CommitId != \"unknown\") ([ \$CommitBrief ] . \" \ + \") ] . \\\r\ + \n \"on \" . \$devBoardName . \"\\nRouterOS: \" . \$devCurVersion . \"\ + \\nArchitecture: \" . \$devCurArch . \"\\nIdentity: \" . \$Identity);\r\ + \n # signal we are ready\r\ + \n:set GlobalFuncReady true;\r\ + \n:set ExitOK true;\r\ + \n\r\ + \n:log info (\$0 . \"Global configs ready!\");\r\ + \n} do={\r\ + \n :global ExitOnError; \$ExitOnError \$0 \$Err;\r\ + \n}\r\ + \n" +add comment="download, import and update firewall address-lists" \ + dont-require-permissions=no name=AM-FwAddrLists owner=AM-FwAddrLists \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + source="#!rsc by Vados\r\ + \n# RouterOS script: AM-FwAddrLists\r\ + \n# Script comment: download, import and update firewall address-lists\r\ + \n# Copyright (c) 2007-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n# https://ros.vados.ru/doc/fw-addr-lists.md\r\ + \n:local ExitOK false;\r\ + \n:onerror Err {\r\ + \n :global GlobalConfReady; :global GlobalFuncReady;\r\ + \n :retry { :if (\$GlobalConfReady != true || \$GlobalFuncReady != true) \ + \\\r\ + \n do={ :error (\"Global config and/or functions not ready.\"); }; } \ + delay=500ms max=50;\r\ + \n :local ScriptName [ :jobname ];\r\ + \n\r\ + \n :global GlobalScriptsUrl;\r\ + \n :local ListsDirName (\"fw-addr-lists.d/\" . [ /system identity get nam\ + e ] . \"/\");\r\ + \n :local ListsUrl (\$GlobalScriptsUrl . \$ListsDirName);\r\ + \n :local ListsIndex \"index.lst\";\r\ + \n :local AddrListsTimeOut 1d;\r\ + \n :local CheckCerts false;\r\ + \n\r\ + \n :global CertificateAvailable;\r\ + \n :global EitherOr;\r\ + \n :global FetchHugeFiles;\r\ + \n :global HumanReadableNum;\r\ + \n :global IfThenElse;\r\ + \n :global LogPrint;\r\ + \n :global NetMask4;\r\ + \n :global NetMask6;\r\ + \n :global ScriptLock;\r\ + \n \r\ + \n :local FindDelim do={\r\ + \n :local ValidChars \"0123456789.:/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi\ + jklmnopqrstuvwxyz-\";\r\ + \n :for I from=0 to=[ :len \$1 ] do={\r\ + \n :if ([ :typeof [ :find \$ValidChars [ :pick (\$1 . \" \") \$I ] ] \ + ] != \"num\") do={\r\ + \n :return \$I;\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :local GetBranch do={\r\ + \n :global EitherOr;\r\ + \n :return [ :pick [ :convert transform=md5 to=hex [ :pick \$1 0 [ \$Ei\ + therOr [ :find \$1 \"/\" ] [ :len \$1 ] ] ] ] 0 2 ];\r\ + \n }\r\ + \n \r\ + \n :if ([ \$ScriptLock \$ScriptName ] = false) do={\r\ + \n :set ExitOK true;\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :local ListComment (\"managed by \" . \$ScriptName);\r\ + \n :local Url (\$ListsUrl . \$ListsIndex);\r\ + \n :local tmpIndex false;\r\ + \n\r\ + \n :for I from=1 to=5 do={\r\ + \n :if (\$tmpIndex = false) do={\r\ + \n :set tmpIndex [ :tolf [ \$FetchHugeFiles \$ScriptName \$Url \$Chec\ + kCerts ] ];\r\ + \n :if (\$tmpIndex = false && \$I < 5) do={\r\ + \n :log warning (\$ScriptName . \" Failed downloading address-list \ + index, \" . \$I . \". try from: \" . \$Url);\r\ + \n :delay ((\$I * \$I) . \"s\");\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n :if (\$tmpIndex = false) do={\r\ + \n :log warning (\$ScriptName . \" Failed downloading address-list inde\ + x from: \" . \$Url);\r\ + \n :set tmpIndex \"\";\r\ + \n }\r\ + \n\r\ + \n :foreach List in=[ :deserialize \$tmpIndex delimiter=\"\\n\" from=dsv \ + options=dsv.plain ] do={\r\ + \n# :set List (\$List->0);\r\ + \n :local ListName;\r\ + \n :local Delim [ \$FindDelim \$List ];\r\ + \n :if (\$Delim = 0) do={ :set List \"\"; };\r\ + \n :log warning (\$ScriptName . \" Parsing address-list index entry: \"\ + \_. \$List);\r\ + \n :if ([ :len \$List ] = 0) do={\r\ + \n :log error (\$ScriptName . \" Failed parsing address-list index en\ + try: \" . \$List);\r\ + \n } else={\r\ + \n :set ListName [ :pick \$List 0 \$Delim ];\r\ + \n }\r\ + \n :log warning (\$ScriptName . \" Parsing address-list index entry: \"\ + \_. \$ListName . \" - Ok.\");\r\ + \n :local ListUrl (\$ListsUrl . \$ListName);\r\ + \n :local CntAdd 0;\r\ + \n :local CntRenew 0;\r\ + \n :local CntRemove 0;\r\ + \n :local IPv4Addresses ({});\r\ + \n :local IPv6Addresses ({});\r\ + \n :local Failure false;\r\ + \n :local Data false;\r\ + \n :local TimeOut \$AddrListTimeOut;\r\ + \n\r\ + \n :for I from=1 to=5 do={\r\ + \n :if (\$Data = false) do={\r\ + \n :set Data [ :tolf [ \$FetchHugeFiles \$ScriptName \$ListUrl \$Ch\ + eckCerts ] ];\r\ + \n :if (\$Data = false && \$I < 5) do={\r\ + \n :log warning (\$ScriptName . \" Failed downloading for list '\ + \" . \$ListName . \"', \" . \$I . \". try from: \" . \$ListUrl);\r\ + \n :delay ((\$I * \$I) . \"s\");\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :if (\$Data = false) do={\r\ + \n :set Data \"\";\r\ + \n :set Failure true;\r\ + \n :log warning (\$ScriptName . \" Failed downloading for list '\" . \ + \$ListName . \"' from: \" . \$ListUrl);\r\ + \n } else={\r\ + \n :log warning (\$ScriptName . \" Downloaded \" . [ \$HumanReadableN\ + um [ :len \$Data ] 1024 ] . \"B for list '\" . \$ListName . \"' from: \" .\ + \_\$ListUrl);\r\ + \n }\r\ + \n\r\ + \n :foreach Line in=[ :deserialize \$Data delimiter=\"\\n\" from=dsv op\ + tions=dsv.plain ] do={\r\ + \n :set Line (\$Line->0);\r\ + \n :local Address;\r\ + \n :if ([ :pick \$Line 0 1 ] = \"{\" && [ :pick \$Line ([ :len \$Line\ + \_] - 1) ] = \"}\") do={\r\ + \n :do {\r\ + \n :set Address [ :tostr ([ :deserialize from=json \$Line ]->\"ci\ + dr\") ];\r\ + \n } on-error={ }\r\ + \n } else={\r\ + \n :set Address ([ :pick \$Line 0 [ \$FindDelim \$Line ] ] . (\$L\ + ist->\"cidr\"));\r\ + \n }\r\ + \n :do {\r\ + \n :local Branch;\r\ + \n :if (\$Address ~ \"^[0-9]{1,3}\\\\.[0-9]{1,3}\\\\.[0-9]{1,3}\\\\\ + .[0-9]{1,3}(/[0-9]{1,2})\?\\\$\") do={\r\ + \n :local Net \$Address;\r\ + \n :local CIDR 32;\r\ + \n :local Slash [ :find \$Address \"/\" ];\r\ + \n :if ([ :typeof \$Slash ] = \"num\") do={\r\ + \n :set Net [ :toip [ :pick \$Address 0 \$Slash ] ]\r\ + \n :set CIDR [ :pick \$Address (\$Slash + 1) [ :len \$Address ]\ + \_];\r\ + \n :set Address [ :tostr (([ :toip \$Net ] & [ \$NetMask4 \$CID\ + R ]) . [ \$IfThenElse (\$CIDR < 32) (\"/\" . \$CIDR) ]) ];\r\ + \n }\r\ + \n :set Branch [ \$GetBranch \$Address ];\r\ + \n :set (\$IPv4Addresses->\$Branch->\$Address) \$TimeOut;\r\ + \n }\r\ + \n :if (\$Address ~ \"^[0-9a-zA-Z]*:[0-9a-zA-Z:\\\\.]+(/[0-9]{1,3})\ + \?\\\$\") do={\r\ + \n :local Net \$Address;\r\ + \n :local CIDR 128;\r\ + \n :local Slash [ :find \$Address \"/\" ];\r\ + \n :if ([ :typeof \$Slash ] = \"num\") do={\r\ + \n :set Net [ :toip6 [ :pick \$Address 0 \$Slash ] ]\r\ + \n :set CIDR [ :pick \$Address (\$Slash + 1) [ :len \$Address ]\ + \_];\r\ + \n }\r\ + \n :set Address (([ :toip6 \$Net ] & [ \$NetMask6 \$CIDR ]) . \"/\ + \" . \$CIDR);\r\ + \n :set Branch [ \$GetBranch \$Address ];\r\ + \n :set (\$IPv6Addresses->\$Branch->\$Address) \$TimeOut;\r\ + \n }\r\ + \n :if (\$Address ~ \"^[\\\\.a-zA-Z0-9-]+\\\\.[a-zA-Z]{2,}\\\$\") d\ + o={\r\ + \n :set Branch [ \$GetBranch \$Address ];\r\ + \n :set (\$IPv4Addresses->\$Branch->\$Address) \$TimeOut;\r\ + \n :set (\$IPv6Addresses->\$Branch->\$Address) \$TimeOut;\r\ + \n }\r\ + \n } on-error={ }\r\ + \n }\r\ + \n \r\ + \n\r\ + \n :foreach Entry in=[ /ip/firewall/address-list/find where \\\r\ + \n list=\$ListName comment=\$ListComment ] do={\r\ + \n :local Address [ /ip/firewall/address-list/get \$Entry address ];\ + \r\ + \n :local Branch [ \$GetBranch \$Address ];\r\ + \n :local TimeOut (\$IPv4Addresses->\$Branch->\$Address);\r\ + \n :if ([ :typeof \$TimeOut ] = \"time\") do={\r\ + \n :log warning (\$ScriptName . \" Renewing IPv4 address \" . \$Add\ + ress . \\\r\ + \n \" in list '\" . \$ListName . \"' with \" . \$TimeOut . \".\ + \");\r\ + \n /ip/firewall/address-list/set \$Entry timeout=\$TimeOut;\r\ + \n :set (\$IPv4Addresses->\$Branch->\$Address);\r\ + \n :set CntRenew (\$CntRenew + 1);\r\ + \n } else={\r\ + \n :if (\$Failure = false) do={\r\ + \n :log warning (\$ScriptName . \" Removing IPv4 address \" . \$A\ + ddress . \\\r\ + \n \" from list '\" . \$ListName . \".\");\r\ + \n /ip/firewall/address-list/remove \$Entry;\r\ + \n :set CntRemove (\$CntRemove + 1);\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :foreach Entry in=[ /ipv6/firewall/address-list/find where \\\r\ + \n list=\$ListName comment=\$ListComment ] do={\r\ + \n :local Address [ /ipv6/firewall/address-list/get \$Entry address ]\ + ;\r\ + \n :local Branch [ \$GetBranch \$Address ];\r\ + \n :local TimeOut (\$IPv6Addresses->\$Branch->\$Address);\r\ + \n :if ([ :typeof \$TimeOut ] = \"time\") do={\r\ + \n :log warning (\$ScriptName . \" Renewing IPv6 address \" . \$Add\ + ress . \\\r\ + \n \" in list '\" . \$ListName . \"' with \" . \$TimeOut . \".\ + \");\r\ + \n /ipv6/firewall/address-list/set \$Entry timeout=\$TimeOut;\r\ + \n :set (\$IPv6Addresses->\$Branch->\$Address);\r\ + \n :set CntRenew (\$CntRenew + 1);\r\ + \n } else={\r\ + \n :if (\$Failure = false) do={\r\ + \n :log warning (\$ScriptName . \" Removing IPv6 address \" . \$A\ + ddress . \\\r\ + \n \" from list '\" . \$ListName . \".\");\r\ + \n /ipv6/firewall/address-list/remove \$Entry;\r\ + \n :set CntRemove (\$CntRemove + 1);\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :foreach BranchName,Branch in=\$IPv4Addresses do={\r\ + \n :log warning (\$ScriptName . \" Handling branch: \" . \$BranchName\ + );\r\ + \n :foreach Address,Timeout in=\$Branch do={\r\ + \n :log warning (\$ScriptName . \" Adding IPv4 address \" . \$Addre\ + ss . \\\r\ + \n \" to list '\" . \$ListName . \"' with \" . \$Timeout . \".\ + \");\r\ + \n :onerror Err {\r\ + \n /ip/firewall/address-list/add list=\$ListName comment=\$ListCo\ + mment \\\r\ + \n address=\$Address timeout=\$Timeout;\r\ + \n :set CntAdd (\$CntAdd + 1);\r\ + \n } do={\r\ + \n :log warning (\$ScriptName . \" Failed to add IPv4 address \" \ + . \$Address . \\\r\ + \n \" to list '\" . \$ListName . \"': \" . \$Err);\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :foreach BranchName,Branch in=\$IPv6Addresses do={\r\ + \n :log warning (\$ScriptName . \" Handling branch: \" . \$BranchName\ + );\r\ + \n :foreach Address,Timeout in=\$Branch do={\r\ + \n :log warning (\$ScriptName . \" Adding IPv6 address \" . \$Addre\ + ss . \\\r\ + \n \" to list '\" . \$ListName . \"' with \" . \$Timeout . \".\ + \");\r\ + \n :onerror Err {\r\ + \n /ipv6/firewall/address-list/add list=\$ListName comment=\$List\ + Comment \\\r\ + \n address=\$Address timeout=\$Timeout;\r\ + \n :set CntAdd (\$CntAdd + 1);\r\ + \n } do={\r\ + \n :log warning (\$ScriptName . \" Failed to add IPv6 address \" \ + . \$Address . \\\r\ + \n \" to list '\" . \$ListName . \"': \" . \$Err);\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :log info (\$ScriptName . \" list: \" . \$ListName . \\\r\ + \n \" (\" . [ \$HumanReadableNum (\$CntAdd + \$CntRenew) 1000 ] . \ + \")\" . \\\r\ + \n \" -- added: \" . [ \$HumanReadableNum \$CntAdd 1000 ] . \\\r\ + \n \" - renewed: \" . [ \$HumanReadableNum \$CntRenew 1000 ] . \\\r\ + \n \" - removed: \" . [ \$HumanReadableNum \$CntRemove 1000 ]);\r\ + \n }\r\ + \n} do={\r\ + \n :global ExitError; \$ExitError \$ExitOK [ :jobname ] \$Err;\r\ + \n}\r\ + \n" +add comment=\ + "Lookup IP addresses for RKN list and add them to firewall address-list" \ + dont-require-permissions=no name=AM-RKN-dnsLookup owner=AM-RKN-dnsLookup \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + source="#!rsc by Vados\r\ + \n# RouterOS script: AM-RKN-dnsLookup\r\ + \n# Script comment: Lookup IP addresses for RKN list and add them to firew\ + all address-list\r\ + \n# Copyright (c) 2007-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n# requires device-mode, fetch\r\ + \n#\r\ + \n# Script description: This script is intended to be run periodically, e.\ + g. once a day, to update the IP addresses in the firewall address-list bas\ + ed on the RKN list.\r\ + \n# It resolves the domain names in the RKN list and a\ + dds the corresponding IP addresses to the specified firewall address-list.\ + \r\ + \n# The script also handles CNAME records by following\ + \_them until it finds A records.\r\ + \n# Usage:\r\ + \n# /system/script { run AM-RKN-dnsLookup; }\r\ + \n:local ScriptName [ :jobname ];\r\ + \n\r\ + \n:global dnsLookupReady false;\r\ + \n:if ([:typeof \$dnsLookupReady] != \"boolean\") do={ :set dnsLookupReady\ + \_true; }\r\ + \nwhile (!\$dnsLookupReady) do={ :nothing; }\r\ + \n:set dnsLookupReady false;\r\ + \n\r\ + \n:local arrRKN {\r\ + \n \"telegra.ph\"\r\ + \n \"grani.ru\"\r\ + \n \"xhamster.com\"\r\ + \n \"kasparov.ru\"\r\ + \n \"lostfilm.tv\"\r\ + \n \"rutracker.org\"\r\ + \n \"lurkmore.to\"\r\ + \n \"dou.ua\"\r\ + \n \"youporn.com\"\r\ + \n \"pornolab.net\"\r\ + \n \"crimerussia.com\"\r\ + \n \"telegram.org\"\r\ + \n \"api.telegram.org\"\r\ + \n \"telegram.me\"\r\ + \n \"t.me\";}\r\ + \n\r\ + \n:local ListRKN \"FuckRKN\";\r\ + \n:local ListComment (\"ListRKN managed by \" . \$ScriptName);\r\ + \n:foreach aListItem in=[/ip/firewall/address-list find list=\$ListRKN] do\ + ={\r\ + \n /ip firewall address-list remove \$aListItem;\r\ + \n}\r\ + \n:foreach aItem in=\$arrRKN do={\r\ + \n :do {\r\ + \n :resolve \$aItem;\r\ + \n } on-error={\r\ + \n :log error \"dns resolve failure [ ip - resolve ip ]\";\r\ + \n }\r\ + \n :foreach dnsRecord in=[/ip dns cache all find where (name=\$aItem)] \ + do={\r\ + \n :if ([/ip dns cache all get \$dnsRecord type]=\"A\") do={\r\ + \n :local newAddress [/ip dns cache all get \$dnsRecord data];\ + \r\ + \n :do {\r\ + \n /ip firewall address-list add list=\$ListRKN address=\$n\ + ewAddress comment=\$aItem;\r\ + \n } on-error={\r\ + \n :log error \"error when adding ip to list: \$newAddress\ + \";\r\ + \n }\r\ + \n }\r\ + \n :if ([/ip dns cache all get \$dnsRecord type]=\"CNAME\") do={\r\ + \n :local cname;\r\ + \n :local nextCname;\r\ + \n :set cname [/ip dns cache all find where (name=\$aItem && ty\ + pe=\"CNAME\")];\r\ + \n :set nextCname [/ip dns cache all find where (name=[/ip dns \ + cache all get \$cname data] && type=\"CNAME\")];\r\ + \n :while (\$nextCname != \"\") do={\r\ + \n :set cname \$nextCname;\r\ + \n :set nextCname [/ip dns cache all find where (name=[/ip \ + dns cache all get \$cname data] && type=\"CNAME\")];\r\ + \n }\r\ + \n :foreach aRecord in=[/ip dns cache all find where (name=[/ip\ + \_dns cache all get \$cname data] && type=\"A\")] do={\r\ + \n :do {\r\ + \n /ip firewall address-list add list=\$ListRKN address\ + =[/ip dns cache all get \$aRecord data] comment=\$aItem;\r\ + \n } on-error={\r\ + \n :log error \"error when adding ip to list: \$newAddr\ + ess\";\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:if ([ :len [ /system/scheduler/find where name=\$ScriptName ] ] = 0) do\ + ={\r\ + \n :log error (\$ScriptName . \"System Scheduler for script: \" . \$Scri\ + ptName . \" is NOT SET! Fix It Now!\");\r\ + \n /system/scheduler/add name=\$ScriptName on-event=\"/system/script { \ + run \$ScriptName; }\" comment=\"Update RKN DNS Looup\" interval=00:20:00 p\ + olicy=\"ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon\"\ + \_start-time=startup;\r\ + \n }\r\ + \n:set dnsLookupReady true;\r\ + \ndelay 5s; \r\ + \n:global dnsLookupReady (a);\r\ + \n" +add dont-require-permissions=no name=dnsForwarders owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + !rsc by Vados\r\ + \n# RouterOS script: AM-dnsForwarders\r\ + \n# Script comment: DNS Forwarders and DOH Servers | by @xmrdenb43\r\ + \n# Copyright (c) 2005-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n# requires device-mode, fetch, scheduler\r\ + \n# \r\ + \n# tested on hap ac lite tc/hap ax3, RoS 7.18.2+\r\ + \n\r\ + \n\r\ + \n/ip/dns/set allow-remote-requests=yes doh-max-concurrent-queries=100 doh\ + -max-server-connections=20 use-doh-server=https://security.cloudflare-dns.\ + com/dns-query verify-doh-cert=no;\r\ + \n\r\ + \n/ip dns static\r\ + \n:do {\r\ + \nadd address=8.8.8.8 comment=\"DNS Google\" name=dns.google type=A\r\ + \nadd address=8.8.4.4 comment=\"DNS Google\" name=dns.google type=A\r\ + \nadd address=9.9.9.9 comment=\"DNS Quad9\" name=dns.quad9.net type=A\r\ + \nadd address=149.112.112.112 comment=\"DNS Quad9\" name=dns.quad9.net typ\ + e=A\r\ + \nadd address=195.133.25.16 comment=\"DNS Comss\" name=dns.comss.one type=\ + A\r\ + \n\r\ + \n/ip dns forwarders\r\ + \nadd doh-servers=https://cloudflare-dns.com/dns-query name=\"CloudFlare D\ + oH\"\r\ + \nadd doh-servers=https://secure.cloudflare-dns.com/dns-query name=\"Cloud\ + Flare Secure DoH\"\r\ + \nadd disabled=yes doh-servers=https://dns.quad9.net/dns-query name=\"Quad\ + 9 Default\" verify-doh-cert=no\r\ + \nadd doh-servers=https://dns.google/dns-query name=\"Google DoH\"\r\ + \nadd dns-servers=dns.comss.one doh-servers=https://dns.comss.one/mikrotik\ + \_name=\"Comss DoH\" verify-doh-cert=no\r\ + \nadd doh-servers=https://cloudflare-dns.com/dns-query,https://dns.google/\ + dns-query name=\"CF & Google DoH\"\r\ + \nadd dns-servers=1.0.0.1,8.8.4.4,1.1.1.1,8.8.8.8,77.88.8.1,77.88.8.8 name\ + =\"CF & G & Ya IPv4\" verify-doh-cert=no\r\ + \n} on-error={ }\r\ + \n\r\ + \n" +add dont-require-permissions=no name=AM-ADguardHome-container owner=vados \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + source="#!rsc by Vados\r\ + \n# RouterOS script: AM-ADguardHome-container\r\ + \n# Script comment: ADguardHome-container to container | by @xdenb43\r\ + \n# Copyright (c) 2005-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n# requires device-mode, fetch, scheduler\r\ + \n# \r\ + \n# tested on hap ac lite tc/hap ax3, RoS 7.18.2+\r\ + \n# tested on hap ax3/RoS 7.17.2+\r\ + \n\r\ + \n# enable containers, follow https://help.mikrotik.com/docs/spaces/ROS/pa\ + ges/84901929/Container\r\ + \n#/system/device-mode/update container=yes\r\ + \n\r\ + \n# MAIN PART STARTS HERE\r\ + \n/interface veth\r\ + \nadd address=192.168.254.5/24 gateway=192.168.254.1 name=ADGUARD-HOME\r\ + \n\r\ + \n/interface bridge\r\ + \nadd name=Bridge-Docker port-cost-mode=short\r\ + \n/interface bridge port\r\ + \nadd bridge=Bridge-Docker interface=ADGUARD-HOME\r\ + \n/ip address\r\ + \nadd address=192.168.254.1/24 interface=Bridge-Docker network=192.168.254\ + .0\r\ + \n\r\ + \n/ip firewall nat\r\ + \nadd action=masquerade chain=srcnat comment=AdGuardHome src-address=192.1\ + 68.254.5\r\ + \n\r\ + \n# USB flash drive, FS ext4\r\ + \n/container config\r\ + \nset ram-high=200.0MiB registry-url=https://registry-1.docker.io tmpdir=/\ + usb1/docker/pull\r\ + \n\r\ + \n/container mounts\r\ + \nadd dst=/opt/adguardhome/conf name=adguard_home_conf src=/usb1/docker_co\ + nfigs/adguard_home\r\ + \n\r\ + \n/container\r\ + \nadd cmd=\"-c /opt/adguardhome/conf/AdGuardHome.yaml -h 0.0.0.0 -w /opt/a\ + dguardhome/work\" entrypoint=/opt/adguardhome/AdGuardHome interface=ADGUAR\ + D-HOME logging=yes mounts=\\\r\ + \n adguard_home_conf root-dir=/usb1/docker/adguard_home workdir=/opt/ad\ + guardhome/work remote-image=adguard/adguardhome:latest\r\ + \n\r\ + \n/container/start [find where interface=ADGUARD-HOME]\r\ + \n\r\ + \n# ADH available on http://192.168.254.5:300 , configure before use\r\ + \n# Choose one of the options below\r\ + \n# uncomment lines before copying to terminal\r\ + \n\r\ + \n# OPTION 1\r\ + \n# Just set AGH ip as DNS server.\r\ + \n# /!\\ DNS FWD will work.\r\ + \n# /!\\ No device-related stats will be gathered (all dns requests are co\ + ming from mikrotik)\r\ + \n#/ip dns\r\ + \n#set allow-remote-requests=yes servers=192.168.254.5\r\ + \n#/ip firewall nat\r\ + \n#add action=redirect chain=dstnat comment=\"Incoming DNS redirect\" dst-\ + address-type=!local dst-port=53 in-interface-list=LAN protocol=udp\r\ + \n#add action=redirect chain=dstnat comment=\"Incoming DNS redirect\" dst-\ + address-type=!local dst-port=53 in-interface-list=LAN protocol=tcp\r\ + \n\r\ + \n\r\ + \n# OPTION 2\r\ + \n# Forward all DNS requests to ADH\r\ + \n# /!\\ DNS FWD will NOT work\r\ + \n# /!\\ WILL SHOW stats for every LAN device\r\ + \n#/ip firewall nat\r\ + \n#add action=dst-nat chain=dstnat comment=\"local AdGuard udp - NO NAT L\ + oopback / local addresses only!\" dst-port=53 in-interface-list=LAN protoc\ + ol=udp src-address=\\\r\ + \n# 192.168.88.0/24 to-addresses=192.168.254.5 to-ports=53\r\ + \n#add action=dst-nat chain=dstnat comment=\"local AdGuard tcp\" dst-port=\ + 53 in-interface-list=LAN protocol=tcp src-address=192.168.88.0/24 to-addre\ + sses=192.168.254.5 to-ports=53\r\ + \n# cat adguardhome_container.rsc\r\ + \n# adguard home to container | by @xdenb43\r\ + \n# tested on hap ax3/RoS 7.17.2+\r\ + \n\r\ + \n# enable containers, follow https://help.mikrotik.com/docs/spaces/ROS/pa\ + ges/84901929/Container\r\ + \n/system/device-mode/update container=yes\r\ + \n\r\ + \n# MAIN PART STARTS HERE\r\ + \n/interface veth\r\ + \nadd address=192.168.254.5/24 gateway=192.168.254.1 name=ADGUARD-HOME\r\ + \n\r\ + \n/interface bridge\r\ + \nadd name=Bridge-Docker port-cost-mode=short\r\ + \n/interface bridge port\r\ + \nadd bridge=Bridge-Docker interface=ADGUARD-HOME\r\ + \n/ip address\r\ + \nadd address=192.168.254.1/24 interface=Bridge-Docker network=192.168.254\ + .0\r\ + \n\r\ + \n/ip firewall nat\r\ + \nadd action=masquerade chain=srcnat comment=AdGuardHome src-address=192.1\ + 68.254.5\r\ + \n\r\ + \n# USB flash drive, FS ext4\r\ + \n/container config\r\ + \nset ram-high=200.0MiB registry-url=https://registry-1.docker.io tmpdir=/\ + usb1/docker/pull\r\ + \n\r\ + \n/container mounts\r\ + \nadd dst=/opt/adguardhome/conf name=adguard_home_conf src=/usb1/docker_co\ + nfigs/adguard_home\r\ + \n\r\ + \n/container\r\ + \nadd cmd=\"-c /opt/adguardhome/conf/AdGuardHome.yaml -h 0.0.0.0 -w /opt/a\ + dguardhome/work\" entrypoint=/opt/adguardhome/AdGuardHome interface=ADGUAR\ + D-HOME logging=yes mounts=\\\r\ + \n adguard_home_conf root-dir=/usb1/docker/adguard_home workdir=/opt/ad\ + guardhome/work remote-image=adguard/adguardhome:latest\r\ + \n\r\ + \n/container/start [find where interface=ADGUARD-HOME]\r\ + \n\r\ + \n# ADH available on http://192.168.254.5:300 , configure before use\r\ + \n# Choose one of the options below\r\ + \n# uncomment lines before copying to terminal\r\ + \n\r\ + \n# OPTION 1\r\ + \n# Just set AGH ip as DNS server.\r\ + \n# /!\\ DNS FWD will work.\r\ + \n# /!\\ No device-related stats will be gathered (all dns requests are co\ + ming from mikrotik)\r\ + \n#/ip dns\r\ + \n#set allow-remote-requests=yes servers=192.168.254.5\r\ + \n#/ip firewall nat\r\ + \n#add action=redirect chain=dstnat comment=\"Incoming DNS redirect\" dst-\ + address-type=!local dst-port=53 in-interface-list=LAN protocol=udp\r\ + \n#add action=redirect chain=dstnat comment=\"Incoming DNS redirect\" dst-\ + address-type=!local dst-port=53 in-interface-list=LAN protocol=tcp\r\ + \n\r\ + \n\r\ + \n# OPTION 2\r\ + \n# Forward all DNS requests to ADH\r\ + \n# /!\\ DNS FWD will NOT work\r\ + \n# /!\\ WILL SHOW stats for every LAN device\r\ + \n#/ip firewall nat\r\ + \n#add action=dst-nat chain=dstnat comment=\"local AdGuard udp - NO NAT L\ + oopback / local addresses only!\" dst-port=53 in-interface-list=LAN protoc\ + ol=udp src-address=\\\r\ + \n# 192.168.88.0/24 to-addresses=192.168.254.5 to-ports=53\r\ + \n#add action=dst-nat chain=dstnat comment=\"local AdGuard tcp\" dst-port=\ + 53 in-interface-list=LAN protocol=tcp src-address=192.168.88.0/24 to-addre\ + sses=192.168.254.5 to-ports=53" +/user group +add name=backup policy="telnet,ssh,ftp,read,write,policy,test,sniff,sensitive,\ + !local,!reboot,!winbox,!password,!web,!api,!romon,!rest-api" +/interface bridge +add admin-mac=48:8F:5A:8E:1A:BC auto-mac=no mlag-peer-port="ether1 - Unet" \ + name=Bridge-LAN port-cost-mode=short +/interface wireless +# same mac-address as ether1 - Unet +set [ find default-name=wlan1 ] ampdu-priorities=0,1,2,3,4,5,6,7 band=\ + 2ghz-b/g/n basic-rates-a/g=\ + 6Mbps,9Mbps,12Mbps,18Mbps,24Mbps,36Mbps,48Mbps,54Mbps basic-rates-b=\ + 1Mbps,2Mbps,5.5Mbps,11Mbps channel-width=20/40mhz-XX country=belarus \ + disabled=no frequency=auto hw-protection-mode=rts-cts mode=ap-bridge \ + rate-set=configured skip-dfs-channels=10min-cac ssid=vados \ + wds-default-bridge=Bridge-LAN wds-mode=dynamic-mesh wireless-protocol=\ + 802.11 wmm-support=enabled wps-mode=disabled +set [ find default-name=wlan2 ] ampdu-priorities=0,1,2,3,4,5,6,7 band=\ + 5ghz-a/n/ac basic-rates-a/g=\ + 6Mbps,9Mbps,12Mbps,18Mbps,24Mbps,36Mbps,48Mbps,54Mbps channel-width=\ + 20/40/80mhz-XXXX country=belarus disabled=no frequency=auto \ + hw-protection-mode=rts-cts mode=ap-bridge rate-set=configured \ + skip-dfs-channels=10min-cac ssid=vados5g wds-default-bridge=Bridge-LAN \ + wds-mode=dynamic-mesh wireless-protocol=802.11 wmm-support=enabled \ + wps-mode=disabled +/interface wireless nstreme +# same mac-address as ether1 - Unet +set wlan1 enable-nstreme=yes +set wlan2 enable-nstreme=yes +/caps-man provisioning +add action=create-dynamic-enabled hw-supported-modes=gn master-configuration=\ + cfg-2ghz name-format=prefix-identity name-prefix=2ghz +add action=create-dynamic-enabled hw-supported-modes=ac master-configuration=\ + cfg-5ghz-ac name-format=prefix-identity name-prefix=5ghz-ac +add action=create-dynamic-enabled hw-supported-modes=an master-configuration=\ + cfg-5ghz-an name-format=prefix-identity name-prefix=5ghz-an +/certificate settings +set builtin-trust-store="ipsec,wpa-eap,capsman,fetch,sstp,ovpn,radius,containe\ + r,userman,wiliot,openflow,tr069,dot1x,www,api,reverse-proxy,logging" \ + crl-download=yes crl-use=yes +/interface bridge port +add bridge=Bridge-LAN disabled=yes interface="ether1 - Unet" +add bridge=Bridge-LAN interface=ether2 +add bridge=Bridge-LAN interface=ether3 +add bridge=Bridge-LAN interface=ether4 +add bridge=Bridge-LAN interface=ether5 +add bridge=Bridge-LAN interface=wlan2 +add bridge=Bridge-LAN interface=wlan1 +/ip firewall connection tracking +set udp-timeout=10s +/ip neighbor discovery-settings +set discover-interface-list=LAN +/ip settings +set max-neighbor-entries=8192 secure-redirects=no +/ipv6 settings +set allow-fast-path=no disable-ipv6=yes disable-link-local-address=yes \ + forward=no max-neighbor-entries=8192 +/interface detect-internet +set detect-interface-list=WAN internet-interface-list=WAN lan-interface-list=\ + LAN wan-interface-list=WAN +/interface l2tp-server server +set authentication=mschap2 use-ipsec=yes +/interface list member +add interface="ether1 - Unet" list=WAN +add interface=Bridge-LAN list=LAN +/interface ovpn-server server +add auth=sha1,md5 mac-address=FE:82:A5:78:8E:84 name=ovpn-server1 +/interface wifi configuration +add channel=2G-AX datapath=xs-DataPath disabled=no mode=ap name=2G-AX \ + security=sec2g security.ft=yes .ft-over-ds=yes ssid=vados +add channel=2G-N datapath=xs-DataPath disabled=no mode=ap name=2G-N security=\ + sec2g security.ft=yes .ft-over-ds=yes ssid=vados +add channel=5G-AC datapath=xs-DataPath disabled=no mode=ap name=5G-AC \ + security=sec5G security.authentication-types="" .ft=yes .ft-over-ds=yes \ + ssid=vados +add channel=2G-G datapath=xs-DataPath disabled=no mode=ap name=2G-G security=\ + sec2g security.authentication-types="" .ft=yes .ft-over-ds=yes ssid=vados +/interface wifi datapath +add bridge=Bridge-LAN disabled=no interface-list=all name=xs-DataPath +/interface wireguard peers +add allowed-address=0.0.0.0/0,::/0 client-allowed-address=0.0.0.0/0,::/0 \ + endpoint-address=89.110.101.17 endpoint-port=29185 interface=WG name=\ + MikroVados persistent-keepalive=20m public-key=\ + "64Y25EUZQQt8EIeAJYD8qWt+te8qvGEepnswdBgmzlY=" +/interface wireless cap +set bridge=Bridge-LAN caps-man-addresses=10.30.30.10 \ + caps-man-certificate-common-names=CAPsMAN-51B25E507D07 certificate=\ + CAP-488F5A8E1ABC discovery-interfaces=ether2 interfaces=wlan1,wlan2 \ + lock-to-caps-man=yes +/ip address +add address=10.30.30.81/24 interface=Bridge-LAN network=10.30.30.0 +add address=10.8.0.2/24 interface=WG network=10.8.0.0 +/ip dhcp-client +add add-default-route=special-classless default-route-distance=2 \ + default-route-tables=main dhcp-options=clientid,clientid_duid interface=\ + "ether1 - Unet" name=client1 use-peer-dns=no use-peer-ntp=no +/ip dhcp-server +add add-arp=yes address-pool=dhcp always-broadcast=yes bootp-support=none \ + dhcp-option-set=domain-search-set interface=Bridge-LAN lease-time=10m \ + name=masterDHCP server-address=10.30.30.81 +/ip dhcp-server config +set accounting=no +/ip dhcp-server lease +add address=10.30.30.101 client-id=1:48:8f:5a:8e:ee:a8 mac-address=\ + 48:8F:5A:8E:EE:A8 server=masterDHCP +add address=10.30.30.107 client-id=1:f0:de:f1:91:d:1e mac-address=\ + F0:DE:F1:91:0D:1E server=masterDHCP +add address=10.30.30.83 client-id=1:0:80:77:ec:43:86 mac-address=\ + 00:80:77:EC:43:86 server=masterDHCP +add address=10.30.30.70 dhcp-option=domain-search-list,HostName \ + dhcp-option-set=HP1505n mac-address=00:1E:0B:1A:88:8D server=masterDHCP +add address=10.30.30.50 client-id=1:4:7c:16:36:f5:37 mac-address=\ + 04:7C:16:36:F5:37 server=masterDHCP +add address=10.30.30.71 client-id=1:10:2d:41:2c:20:c2 mac-address=\ + 10:2D:41:2C:20:C2 server=masterDHCP +add address=10.30.30.61 client-id=1:10:8:c1:81:59:5f mac-address=\ + 10:08:C1:81:59:5F server=masterDHCP +add address=10.30.30.72 client-id=1:10:38:1f:d2:5f:13 mac-address=\ + 10:38:1F:D2:5F:13 server=masterDHCP +add address=10.30.30.99 client-id=1:10:b1:df:e9:d0:d5 mac-address=\ + 10:B1:DF:E9:D0:D5 server=masterDHCP +add address=10.30.30.111 client-id=1:fe:2:52:be:3f:16 mac-address=\ + FE:02:52:BE:3F:16 server=masterDHCP +add address=10.30.30.92 client-id=1:d4:6d:6d:fd:e5:49 mac-address=\ + D4:6D:6D:FD:E5:49 server=masterDHCP +add address=10.30.30.93 client-id=1:7e:8b:1e:cb:b8:cb mac-address=\ + CC:42:10:12:46:94 server=masterDHCP +add address=10.30.30.94 client-id=1:50:cc:f8:85:96:a mac-address=\ + 50:CC:F8:85:96:0A server=masterDHCP +add address=10.30.30.82 client-id=1:e4:18:6b:58:34:ab mac-address=\ + E4:18:6B:58:34:AB server=masterDHCP +add address=10.30.30.75 client-id=1:0:27:15:41:97:a9 mac-address=\ + 00:27:15:41:97:A9 server=masterDHCP +add address=10.30.30.77 dhcp-option=HostName dhcp-option-set=StartLife1 \ + mac-address=C4:82:E1:03:49:10 server=masterDHCP +add address=10.30.30.73 client-id=1:10:38:1f:82:81:f2 mac-address=\ + 10:38:1F:82:81:F2 server=masterDHCP +add address=10.30.30.95 client-id=1:88:ae:dd:60:39:54 dhcp-option=HostName \ + dhcp-option-set=VADOS-NUC mac-address=88:AE:DD:60:39:54 server=masterDHCP +add address=10.30.30.98 client-id=1:c8:5b:76:d8:cc:bf dhcp-option=HostName \ + dhcp-option-set=VADOS-LEN mac-address=C8:5B:76:D8:CC:BF server=masterDHCP +add address=10.30.30.96 client-id=iPhone mac-address=4A:91:ED:0E:1F:39 \ + server=masterDHCP +add address=10.30.30.74 client-id=MiTV dhcp-option=HostName dhcp-option-set=\ + MiTV mac-address=20:72:A9:D3:34:36 server=masterDHCP +add address=10.30.30.30 dhcp-option=HostName dhcp-option-set=miller \ + mac-address=F0:75:5D:1E:5F:71 server=masterDHCP +add address=10.30.30.100 client-id=iVados dhcp-option=HostName \ + dhcp-option-set="=\"Client ID\"" mac-address=DE:4D:72:F3:1A:9F server=\ + masterDHCP +/ip dhcp-server network +add address=10.30.30.0/24 caps-manager=10.30.30.10 dhcp-option=\ + domain-search-list dhcp-option-set=domain-search-set dns-server=\ + 10.30.30.81 domain=WORKGROUP gateway=10.30.30.81 netmask=24 ntp-server=\ + 10.30.30.81,10.30.30.10 wins-server=10.30.30.95,10.30.30.98 +/ip dns +set allow-remote-requests=yes cache-max-ttl=1d doh-max-concurrent-queries=100 \ + doh-max-server-connections=20 servers=8.8.4.4,8.8.8.8 +/ip dns static +add address=8.8.4.4 comment="Google-dns IPv4 2" name=dns.google type=A +add address=8.8.8.8 comment="Google-dns IPv4 1" name=dns.google type=A +add address=10.30.30.33 comment=AMSTER name=amster.vados.ru type=A +add address=10.30.30.33 name=ros.vados.ru type=A +add address=10.30.30.95 name=vados-nuc type=A +add address=10.30.30.33 name=amster-nuc type=A +add address=10.30.30.33 name=amster type=A +add address=10.30.30.33 name=amster-reg type=A +add address=10.30.30.33 name=mng.vados.ru type=A +add address=10.30.30.33 name=mgr.vados.ru type=A +add address=10.30.30.33 name=prt.vados.ru type=A +add address=10.30.30.33 name=reg.vados.ru type=A +add address=10.30.30.33 match-subdomain=yes name=mikrots.vados.ru type=A +add address=10.30.30.33 name=oxidized.vados.ru type=A +add address=10.30.30.30 comment=MILLER name=miller.vados.ru type=A +add address=10.30.30.30 name=MILLER-LEN type=A +add address=10.30.30.30 name=miller type=A +add address=1.0.0.1 comment="CloudFlare-doh IPv4 2" disabled=yes name=\ + security.cloudflare-dns.com type=A +add address=1.1.1.1 comment="CloudFlare-doh IPv4 1" disabled=yes name=\ + security.cloudflare-dns.com type=A +add address=149.112.112.112 comment="Cuad9-dns IPv4 2" disabled=yes name=\ + dns.quad9.net type=A +add address=9.9.9.9 comment="Cuad9-dns IPv4 1" disabled=yes name=\ + dns.quad9.net type=A +add address=91.192.189.2 comment=Unet-DNS disabled=yes name=ns1.unet.ws type=\ + A +add address=10.30.30.81 comment=LocalNet name=MikroVados type=A +add address=10.30.30.10 name=MikroNUC type=A +add address=10.30.30.86 name=MikroYellow type=A +add address=10.30.30.85 name=MikroMic type=A +add address=10.30.30.95 name=VADOS-NUC type=A +add address=10.30.30.98 name=VADOS-LEN type=A +add address=10.30.30.20 name=garage type=A +add address=91.192.189.2 comment=Unet-DNS disabled=yes name=ns1.unet.ws type=\ + A +/ip firewall address-list +add address=91.215.120.206 list=TRUSTED +add address=185.71.70.78 disabled=yes list=TRUSTED +add address=176.53.203.171 disabled=yes list=TRUSTED +add address=176.53.203.170 disabled=yes list=TRUSTED +add address=176.53.202.194 disabled=yes list=TRUSTED +add address=10.30.30.100-255 list=KIDS +add address=8.8.4.0/24 list=YouTube +add address=8.8.8.0/24 list=YouTube +add address=8.34.208.0/20 list=YouTube +add address=8.35.192.0/20 list=YouTube +add address=23.236.48.0/20 list=YouTube +add address=23.251.128.0/19 list=YouTube +add address=34.0.0.0/15 list=YouTube +add address=34.2.0.0/16 list=YouTube +add address=34.3.0.0/23 list=YouTube +add address=34.3.3.0/24 list=YouTube +add address=34.3.4.0/24 list=YouTube +add address=34.3.8.0/21 list=YouTube +add address=34.3.16.0/20 list=YouTube +add address=34.3.32.0/19 list=YouTube +add address=34.3.64.0/18 list=YouTube +add address=34.4.0.0/14 list=YouTube +add address=34.8.0.0/13 list=YouTube +add address=34.16.0.0/12 list=YouTube +add address=34.32.0.0/11 list=YouTube +add address=34.64.0.0/10 list=YouTube +add address=34.128.0.0/10 list=YouTube +add address=35.184.0.0/13 list=YouTube +add address=35.192.0.0/14 list=YouTube +add address=35.196.0.0/15 list=YouTube +add address=35.198.0.0/16 list=YouTube +add address=35.199.0.0/17 list=YouTube +add address=35.199.128.0/18 list=YouTube +add address=35.200.0.0/13 list=YouTube +add address=35.208.0.0/12 list=YouTube +add address=35.224.0.0/12 list=YouTube +add address=35.240.0.0/13 list=YouTube +add address=57.140.192.0/18 list=YouTube +add address=64.15.112.0/20 list=YouTube +add address=64.233.160.0/19 list=YouTube +add address=66.22.228.0/23 list=YouTube +add address=66.102.0.0/20 list=YouTube +add address=66.249.64.0/19 list=YouTube +add address=70.32.128.0/19 list=YouTube +add address=72.14.192.0/18 list=YouTube +add address=74.125.0.0/16 list=YouTube +add address=104.154.0.0/15 list=YouTube +add address=104.196.0.0/14 list=YouTube +add address=104.237.160.0/19 list=YouTube +add address=107.167.160.0/19 list=YouTube +add address=107.178.192.0/18 list=YouTube +add address=108.59.80.0/20 list=YouTube +add address=108.170.192.0/18 list=YouTube +add address=108.177.0.0/17 list=YouTube +add address=130.211.0.0/16 list=YouTube +add address=136.22.160.0/20 list=YouTube +add address=136.22.176.0/21 list=YouTube +add address=136.22.184.0/23 list=YouTube +add address=136.22.186.0/24 list=YouTube +add address=142.250.0.0/15 list=YouTube +add address=146.148.0.0/17 list=YouTube +add address=152.65.208.0/22 list=YouTube +add address=152.65.214.0/23 list=YouTube +add address=152.65.218.0/23 list=YouTube +add address=152.65.222.0/23 list=YouTube +add address=152.65.224.0/19 list=YouTube +add address=162.120.128.0/17 list=YouTube +add address=162.216.148.0/22 list=YouTube +add address=162.222.176.0/21 list=YouTube +add address=172.110.32.0/21 list=YouTube +add address=172.217.0.0/16 list=YouTube +add address=172.253.0.0/16 list=YouTube +add address=173.194.0.0/16 list=YouTube +add address=173.255.112.0/20 list=YouTube +add address=192.158.28.0/22 list=YouTube +add address=192.178.0.0/15 list=YouTube +add address=193.186.4.0/24 list=YouTube +add address=199.36.154.0/23 list=YouTube +add address=199.36.156.0/24 list=YouTube +add address=199.192.112.0/22 list=YouTube +add address=199.223.232.0/21 list=YouTube +add address=207.223.160.0/20 list=YouTube +add address=208.65.152.0/22 list=YouTube +add address=208.68.108.0/22 list=YouTube +add address=208.81.188.0/22 list=YouTube +add address=208.117.224.0/19 list=YouTube +add address=209.85.128.0/17 list=YouTube +add address=216.58.192.0/19 list=YouTube +add address=216.73.80.0/20 list=YouTube +add address=216.239.32.0/19 list=YouTube +add address=2ip.ru list=Test +add address=157.240.247.174 list=Instagram +add address=46.53.178.107 list=Instagram +add address=179.60.195.174 list=Instagram +add address=157.240.205.174 list=Instagram +add address=31.13.24.0/21 list=Instagram +add address=31.13.64.0/18 list=Instagram +add address=45.64.40.0/22 list=Instagram +add address=66.220.144.0/20 list=Instagram +add address=69.63.176.0/20 list=Instagram +add address=69.171.224.0/19 list=Instagram +add address=74.119.76.0/22 list=Instagram +add address=103.4.96.0/22 list=Instagram +add address=129.134.0.0/16 list=Instagram +add address=157.240.0.0/16 list=Instagram +add address=173.252.64.0/18 list=Instagram +add address=179.60.192.0/22 list=Instagram +add address=185.60.216.0/22 list=Instagram +add address=204.15.20.0/22 list=Instagram +add address=157.240.200.63 list=Instagram +add address=185.60.219.63 list=Instagram +add address=129.134.31.12 list=Instagram +add address=66.81.203.132 list=Instagram +add address=185.89.218.12 list=Instagram +add address=31.13.66.63 list=Instagram +add address=84.15.65.162 list=Instagram +add address=68.66.224.28 list=Instagram +add address=157.240.253.63 list=Instagram +add address=83.174.11.224 list=Instagram +add address=157.240.9.52 list=Instagram +add address=157.240.252.174 list=Instagram +add address=157.240.195.63 list=Instagram +add address=31.13.71.52 list=Instagram +add address=57.144.110.192 list=Instagram +add address=157.240.252.17 list=Instagram +add address=84.15.66.97 list=Instagram +add address=217.168.6.33 list=Instagram +add address=31.13.83.52 list=Instagram +add address=157.240.241.63 list=Instagram +add address=129.134.30.12 list=Instagram +add address=185.89.219.12 list=Instagram +add address=157.240.252.10 list=Instagram +add address=157.240.201.63 list=Instagram +add address=66.81.203.197 list=Instagram +add address=179.60.195.52 list=Instagram +add address=66.81.203.7 list=Instagram +add address=216.40.34.41 list=Instagram +add address=157.240.202.63 list=Instagram +add address=157.240.229.63 list=Instagram +add address=157.240.252.63 list=Instagram +add address=31.13.72.53 list=Instagram +add address=124.108.16.224 list=Instagram +add address=157.240.205.63 list=Instagram +add address=92.46.37.96 list=Instagram +add address=157.240.247.63 list=Instagram +add address=157.240.234.63 list=Instagram +add address=157.240.235.63 list=Instagram +add address=87.245.208.97 list=Instagram +add address=216.58.192.0/19 list=Instagram +add address=209.85.128.0/17 list=Instagram +add address=198.105.240.0/20 list=Instagram +add address=173.194.0.0/16 list=Instagram +add address=172.217.0.0/16 list=Instagram +add address=142.250.0.0/15 list=Instagram +add address=108.177.0.0/17 list=Instagram +add address=87.245.197.140 list=Instagram +add address=74.125.0.0/16 list=Instagram +add address=64.233.160.0/19 list=Instagram +add address=157.240.0.1 list=Instagram +add address=157.240.238.63 list=Instagram +add address=157.240.238.174 list=Instagram +add address=157.240.0.63 list=Instagram +add address=157.240.224.63 list=Instagram +add address=157.240.224.174 list=Instagram +add address=157.240.251.36 list=Instagram +add address=157.240.253.12 list=Instagram +add address=157.240.253.35 list=Instagram +add address=157.240.238.13 list=Instagram +add address=157.240.238.56 list=Instagram +add address=157.240.238.175 list=Instagram +add address=57.144.112.141 list=Instagram +add address=157.240.251.60 list=Instagram +add address=157.240.251.128 list=Instagram +add address=157.240.238.5 list=Instagram +add address=157.240.253.13 list=Instagram +add address=157.240.253.5 list=Instagram +add address=157.240.238.2 list=Instagram +add address=157.240.238.37 list=Instagram +add address=157.240.251.5 list=Instagram +add address=157.240.251.34 list=Instagram +add address=57.144.112.1 list=Instagram +add address=157.240.238.54 list=Instagram +add address=129.134.26.123 list=Instagram +add address=157.240.252.3 list=Instagram +add address=31.13.84.4 list=Instagram +add address=157.240.224.12 list=Instagram +add address=157.240.238.4 list=Instagram +add address=157.240.0.13 list=Instagram +add address=3.33.139.32 list=Instagram +add address=157.240.0.35 list=Instagram +add address=157.240.238.14 list=Instagram +add address=157.240.238.60 list=Instagram +add address=57.144.112.145 list=Instagram +add address=157.240.251.35 list=Instagram +add address=151.101.84.159 list=Twitter +add address=pbs.twimg.com list=Twitter +add address=89.110.101.17 comment=VDSIna list=TRUSTED +add address=10.8.0.0/24 comment="WG VDSIna" list=TRUSTED +add address=ikus.pesc.ru comment=ikus.pesc.ru list=NoVdsina +add address=love.ru comment=love.ru list=NoVdsina +add address=gosuslugi.ru comment=gosuslugi.ru list=NoVdsina +add address=pochta.ru comment=pochta.ru list=NoVdsina +add address=vdsina.com list=NoVdsina +add address=vdsina.ru list=NoVdsina +add address=youla.ru list=NoVdsina +add address=kupiprodai.ru list=NoVdsina +add address=myip.ru list=Test +add address=geoip.co list=NoVdsina +add address=x.com list=Twitter +add address=facebook.com list=facebook +add address=fbcd.net list=facebook +add address=comp-lenta.ru list=NoVdsina +add address=128.85.102.70 comment=update.microsoft.com list=\ + windowsupdateslist +add address=wu-b-net.trafficmanager.net. comment=\ + ctldl.windowsupdate.com.delivery.microsoft.com list=windowsupdateslist +add address=ctldl.windowsupdate.com.delivery.microsoft.com. comment=\ + ctldl.windowsupdate.com list=windowsupdateslist +add address=redir.update.msft.com.trafficmanager.net. comment=\ + update.microsoft.com list=windowsupdateslist +add address=geo.prod.do.dsp.trafficmanager.net. comment=\ + geo.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=13.74.139.29 comment=array605.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=kv801.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + kv801.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=e12437.d.akamaiedge.net. comment=\ + kv801.prod.do.dsp.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=displaycatalog-rp.md.mp.microsoft.com.akadns.net. comment=\ + displaycatalog.mp.microsoft.com list=windowsupdateslist +add address=rp-consumer-prod-displaycatalog-geomap.trafficmanager.net. \ + comment=displaycatalog-rp.md.mp.microsoft.com.akadns.net list=\ + windowsupdateslist +add address=sls.update.microsoft.com. comment=slscr.update.microsoft.com \ + list=windowsupdateslist +add address=glb.sls.prod.dcat.dsp.trafficmanager.net. comment=\ + sls.update.microsoft.com list=windowsupdateslist +add address=fe3.delivery.mp.microsoft.com. comment=\ + fe3cr.delivery.mp.microsoft.com list=windowsupdateslist +add address=glb.cws.prod.dcat.dsp.trafficmanager.net. comment=\ + fe3.delivery.mp.microsoft.com list=windowsupdateslist +add address=fe2cr.update.msft.com.trafficmanager.net. comment=\ + fe2cr.update.microsoft.com list=windowsupdateslist +add address=download.windowsupdate.com.delivery.microsoft.com. comment=\ + download.windowsupdate.com list=windowsupdateslist +add address=wu-f-net.trafficmanager.net. comment=\ + download.windowsupdate.com.delivery.microsoft.com list=windowsupdateslist +add address=tsfe.trafficmanager.net. comment=\ + tsfe.trafficshaping.dsp.mp.microsoft.com list=windowsupdateslist +add address=edge.ds-c7110-microsoft.global.dns.qwilted-cds.cqloud.com. \ + comment=9.au.download.windowsupdate.com list=windowsupdateslist +add address=52.158.227.125 comment=array812.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=au.download.windowsupdate.com.delivery.microsoft.com. comment=\ + au.download.windowsupdate.com list=windowsupdateslist +add address=a767.dspw65.akamai.net. comment=\ + download.windowsupdate.com.edgesuite.net list=windowsupdateslist +add address=52.151.58.88 comment=array810.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=consumer-licensing-aks2aks.md.mp.microsoft.com.akadns.net. \ + comment=licensing.mp.microsoft.com list=windowsupdateslist +add address=licensing-prod-frontdoor-geomap.trafficmanager.net. comment=\ + consumer-licensing-aks2aks.md.mp.microsoft.com.akadns.net list=\ + windowsupdateslist +add address=star.f.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.f.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=cdp-f-nlu-net.trafficmanager.net. comment=\ + star.f.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=star.b.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.b.tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=cdp-f-tlu-net.trafficmanager.net. comment=\ + star.b.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=storeedgefd.xbetservices.akadns.net. comment=\ + storeedgefd.dsx.mp.microsoft.com list=windowsupdateslist +add address=\ + storeedgefd.dsx.mp.microsoft.com.edgekey.net.globalredir.akadns.net. \ + comment=storeedgefd.dsx.mp.microsoft.com.edgekey.net list=\ + windowsupdateslist +add address=e16646.dscg.akamaiedge.net. comment=\ + storeedgefd.dsx.mp.microsoft.com.edgekey.net.globalredir.akadns.net list=\ + windowsupdateslist +add address=40.69.76.189 comment=array621.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=bg.microsoft.map.fastly.net. comment=\ + 3.au.download.windowsupdate.com list=windowsupdateslist +add list=windowsupdateslist +add address=40.69.75.33 comment=array613.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=star.sf.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedgeextensions.sf.tlu.dl.delivery.mp.microsoft.com list=\ + windowsupdateslist +add address=cdp-f-ssl-tlu-net.trafficmanager.net. comment=\ + star.sf.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=a2033.dscd.akamai.net. comment=\ + star.sb.tlu.dl.delivery.mp.microsoft.com.edgesuite.net list=\ + windowsupdateslist +add address=13.74.138.242 comment=array602.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=dl.delivery.mp.microsoft.com.delivery.microsoft.com. comment=\ + dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=dcat-f-nlu-net.trafficmanager.net. comment=\ + dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=1d.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=1D.tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=dcat-b-tlu-net.trafficmanager.net. comment=\ + 1d.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=a122.dscg3.akamai.net. comment=\ + tlu.dl.delivery.mp.microsoft.com.edgesuite.net list=windowsupdateslist +add address=geover.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + geover.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=e10370.d.akamaiedge.net. comment=\ + geover.prod.do.dsp.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=52.232.182.21 comment=array511.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.70.77.95 comment=array519.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=a1683.dscd.akamai.net. comment=\ + dl.delivery.mp.microsoft.com-c.edgesuite.net list=windowsupdateslist +add address=consumer-collections-aks2eap.md.mp.microsoft.com.akadns.net. \ + comment=collections.mp.microsoft.com list=windowsupdateslist +add address=a1847.dscd.akamai.net. comment=\ + wildcard.f.tlu.dl.delivery.mp.microsoft.com.edgesuite.net list=\ + windowsupdateslist +add address=13.74.142.6 comment=array607.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=au.download.windowsupdate.com.edgesuite.net. comment=\ + 2.au.download.windowsupdate.com list=windowsupdateslist +add address=a767.dscg3.akamai.net. comment=\ + au.download.windowsupdate.com.edgesuite.net list=windowsupdateslist +add address=52.156.123.84 comment=array818.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.78.254 comment=array610.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=4.au.download.windowsupdate.com.delivery.microsoft.com. comment=\ + 4.au.download.windowsupdate.com list=windowsupdateslist +add address=cl-glcb907925.gcdn.co. comment=\ + 4.au.download.windowsupdate.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=52.167.167.111 comment=array510.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=40.69.70.43 comment=array623.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=tsfe.trafficshaping.dsp.mp.microsoft.com.delivery.microsoft.com. \ + comment=tsfe.trafficshaping.dsp.mp.microsoft.com list=windowsupdateslist +add address=ts-frontend.trafficmanager.net. comment=\ + tsfe.trafficshaping.dsp.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=40.69.75.248 comment=array616.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.74.84 comment=array615.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=sds.trafficmanager.net. comment=software-download.microsoft.com \ + list=windowsupdateslist +add address=40.69.74.80 comment=array611.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.175.242.182 comment=array804.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=dlc-shim.trafficmanager.net. comment=download.microsoft.com list=\ + windowsupdateslist +add address=e12671.dscd.akamaiedge.net. comment=\ + download.microsoft.com.edgekey.net list=windowsupdateslist +add address=20.187.55.34 comment=array808.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.167.231 comment=array513.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=52.167.222.13 comment=array518.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=kv601.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + kv601.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=e12358.d.akamaiedge.net. comment=\ + kv601.prod.do.dsp.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. comment=\ + tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=dcat-f-tlu-net.trafficmanager.net. comment=\ + tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=a1856.dspw65.akamai.net. comment=\ + tlu.dl.delivery.mp.microsoft.com-c.edgesuite.net list=windowsupdateslist +add address=52.167.164.252 comment=array506.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=13.74.137.54 comment=array601.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=kv501.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + kv501.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=collections-prod-frontdoor-geomap.trafficmanager.net. comment=\ + consumer-collections-aks2eap.md.mp.microsoft.com.akadns.net list=\ + windowsupdateslist +add address=52.167.160.173 comment=array509.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=40.70.77.148 comment=array516.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.200.126 comment=array507.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=52.167.167.59 comment=array508.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.76.172 comment=array620.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=82.202.162.184 comment=comp-lenta.ru list=NoWG +add address=smtp.mail.me.com.akadns.net. comment=smtp.mail.me.com list=NoWG +add address=17.57.155.37 comment=smtp.mail.me.com.akadns.net list=NoWG +add address=smtp.mail.me.com comment=smtp.mail.me.com list=NoVdsina +add address=40.70.76.5 comment=array514.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.186.119 comment=array618.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.177.176.186 comment=array520.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=40.70.76.27 comment=array515.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.160.43 comment=array503.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.110 comment=array817.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.142.8 comment=array614.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.138.254 comment=array603.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.167.96 comment=array501.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.76.215 comment=array622.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.143.200 comment=array606.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.111 comment=array818.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.112 comment=array819.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.137.53 comment=array608.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.98 comment=array805.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.96 comment=array803.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.104 comment=array811.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.101 comment=array808.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.99 comment=array806.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.17 comment=array802.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.97 comment=array804.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.103 comment=array810.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.16 comment=array801.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.70.77.177 comment=array517.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.164.84 comment=array512.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.105 comment=array812.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.107 comment=array814.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.232.161.82 comment=array502.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.108 comment=array815.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.161.91 comment=array505.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.102 comment=array809.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.109 comment=array816.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.106 comment=array813.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.117 comment=array622.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.107 comment=array612.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.108 comment=array613.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.105 comment=array610.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.113 comment=array618.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.116 comment=array621.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.98 comment=array603.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.114 comment=array619.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.111 comment=array616.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.97 comment=array602.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.106 comment=array611.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.110 comment=array615.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.119 comment=array624.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.135 comment=array514.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.97 comment=array503.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.99 comment=array604.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.61 comment=array504.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.131 comment=array510.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.132 comment=array511.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.96 comment=array601.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.104 comment=array609.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.138 comment=array517.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.60 comment=array501.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.139 comment=array518.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.118 comment=array623.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.113 comment=array820.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.103 comment=array608.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.100 comment=array807.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.129 comment=array508.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.134 comment=array513.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.62 comment=array505.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.137 comment=array516.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.101 comment=array606.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.96 comment=array502.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.130 comment=array509.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.112 comment=array617.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.100 comment=array605.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.115 comment=array620.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.136 comment=array515.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=purchase.md.mp.microsoft.com.akadns.net. comment=\ + purchase.mp.microsoft.com list=windowsupdateslist +add address=e110219.a.akamaiedge.net. comment=\ + purchase.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=72.153.5.140 comment=array519.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.141 list=windowsupdateslist +add address=72.153.5.63 comment=array506.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.128 comment=array507.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.102 comment=array607.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=storesdk.xbetservices.akadns.net. comment=\ + storesdk.dsx.mp.microsoft.com list=windowsupdateslist +add address=e16646.g.akamaiedge.net. comment=\ + storesdk.dsx.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=software-download.microsoft.com.delivery.microsoft.com. comment=\ + software-download.microsoft.com list=windowsupdateslist +add address=download.prss.microsoft.com.akamaized.net. comment=\ + software-download.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.109 comment=array614.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.133 comment=array512.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=213.180.192.0/19 comment=YandexDisk list=NoVdsina +add address=87.250.250.50 comment=YandexDisk list=NoVdsina +add address=consumer-prod-bcfd-v7-afd.trafficmanager.net. comment=\ + displaycatalog.mp.microsoft.com list=windowsupdateslist +add address=purchase-europeeap.md.mp.microsoft.com.akadns.net. comment=\ + purchase.md.mp.microsoft.com.akadns.net list=windowsupdateslist +add address=ne-az-conspurchase-mp.trafficmanager.net. comment=\ + purchase-europeeap.md.mp.microsoft.com.akadns.net list=windowsupdateslist +add address=storeedgefd.dsx.mp.microsoft.com.edgekey.net. comment=\ + cdn.storeedgefd.dsx.mp.microsoft.com list=windowsupdateslist +add address=star.f.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.f.tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=a1996.dscd.akamai.net. comment=\ + wildcard.f.dl.delivery.mp.microsoft.com.edgesuite.net list=\ + windowsupdateslist +add address=cp801.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + cp801.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=glb.tas02.sls-prod.dcat.dsp.mp.microsoft.com. comment=\ + tas02.sls.update.microsoft.com list=windowsupdateslist +add address=cp601.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + cp601.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=star.sb.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedgeextensions.sb.tlu.dl.delivery.mp.microsoft.com list=\ + windowsupdateslist +add address=star.sf.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.sf.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=cdp-f-ssl-nlu-net.trafficmanager.net. comment=\ + star.sf.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=tm-pifd-prod-gbl-weight.trafficmanager.net. comment=\ + paymentinstruments.mp.microsoft.com list=windowsupdateslist +add address=10.30.30.33 comment=NUC disabled=yes list=NoWG +add address=10.30.30.10 comment=MikroNUC disabled=yes list=NoWG +add address=89.110.101.17 comment=!!!VDSINA!!!! list=NoWG +add address=wg.vados.ru comment=VDSina-vpn list=Trusted-VPN +add address=80.85.244.9 list=TRUSTED +add address=disc801.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + disc801.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=185.71.70.78 disabled=yes list=TRUSTED +add address=176.53.203.171 disabled=yes list=TRUSTED +add address=176.53.203.170 disabled=yes list=TRUSTED +add address=176.53.202.194 disabled=yes list=TRUSTED +add address=89.110.101.17 comment="!!!VDSina Server!!!" disabled=yes list=\ + NoVdsina +add address=dns.quad9.net comment=Quad9-dns disabled=yes list=Trusted-DNS +add address=dns.google comment=Google-dns list=Trusted-DNS +add address=security.cloudflare-dns.com comment=CloudFlare-dns list=\ + Trusted-DNS +add address=time.google.com comment=Google-time list=Trusted-NTP +add address=0.ru.pool.ntp.org comment=ru.pool.ntp.org disabled=yes list=\ + Trusted-NTP +add address=1.ru.pool.ntp.org disabled=yes list=Trusted-NTP +add address=2.ru.pool.ntp.org comment=2.ru.pool.ntp.org disabled=yes list=\ + Trusted-NTP +add address=3.ru.pool.ntp.org comment=3.ru.pool.ntp.org disabled=yes list=\ + Trusted-NTP +add address=cp.vdsina.com comment=VDSina-vpn list=Trusted-VPN +add address=vdsina.ru comment=VDSina-vpn list=Trusted-VPN +add address=ns.vados.ru comment=VDSina-vpn list=Trusted-VPN +add address=vdsina.com comment=VDSina-vpn list=Trusted-VPN +add address=cp.vdsina.ru comment=VDSina-vpn list=Trusted-VPN +add address=ns1.vdsina.ru comment=VDSina-vpn list=Trusted-VPN +add address=ghcr.io comment=GitHub list=Trusted-VPN +add address=github.com comment=GitHub list=Trusted-VPN +add address=149.154.164.13 comment=telegra.ph list=FuckRKN +add address=194.85.61.76 comment=grani.ru list=FuckRKN +add address=109.70.26.37 comment=grani.ru list=FuckRKN +add address=104.16.3.81 comment=xhamster.com list=FuckRKN +add address=104.16.4.81 comment=xhamster.com list=FuckRKN +add address=188.114.97.1 comment=lostfilm.tv list=FuckRKN +add address=188.114.96.1 comment=lostfilm.tv list=FuckRKN +add address=172.67.182.196 comment=rutracker.org list=FuckRKN +add address=104.21.32.39 comment=rutracker.org list=FuckRKN +add address=104.247.81.99 comment=lurkmore.to list=FuckRKN +add address=8.6.112.6 comment=dou.ua list=FuckRKN +add address=8.47.69.6 comment=dou.ua list=FuckRKN +add address=66.254.114.79 comment=youporn.com list=FuckRKN +add address=185.110.92.40 comment=pornolab.net list=FuckRKN +add address=185.110.92.41 comment=pornolab.net list=FuckRKN +add address=172.67.172.95 comment=crimerussia.com list=FuckRKN +add address=104.21.71.238 comment=crimerussia.com list=FuckRKN +add address=149.154.167.99 comment=telegram.org list=FuckRKN +add address=149.154.166.110 comment=api.telegram.org list=FuckRKN +/ip firewall filter +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=12h chain=input comment="block honeypot DNS" \ + connection-state=new dst-port=53 in-interface-list=WAN protocol=udp \ + src-address=!10.30.30.0/24 src-address-list=!Trusted-DNS +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input connection-state=new dst-port=53 \ + in-interface-list=WAN protocol=tcp src-address=!10.30.30.0/24 \ + src-address-list=!Trusted-DNS +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input comment=\ + "block honeypot ssh rdp winbox" connection-state=new dst-port=\ + 22,8291,2222 in-interface-list=WAN protocol=tcp src-address-list=!TRUSTED +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input comment="block honeypot asterisk" \ + connection-state=new dst-port=5060 in-interface-list=WAN protocol=udp \ + src-address-list=!TRUSTED +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=5d chain=input comment="block honeypot NTP" \ + connection-state=new dst-port=123 in-interface-list=WAN protocol=udp \ + src-address=!10.30.30.0/24 src-address-list=!Trusted-NTP +add action=fasttrack-connection chain=forward comment=\ + "FastTrack for non-VPN connections" connection-mark=!VPN_No_FastTrack \ + connection-state=established,related,new disabled=yes +add action=accept chain=output comment="Accept Rule for Trusted-NTP Servers" \ + dst-address-list=Trusted-NTP dst-port=123 out-interface-list=WAN \ + protocol=udp +add action=accept chain=input comment=\ + "accept NTP clients on local area network" disabled=yes dst-port=123 \ + in-interface-list=LAN protocol=udp src-address=10.30.30.0/24 +add action=accept chain=output comment="accept WireGuard" disabled=yes \ + dst-address-list=VPN-Server dst-port=13231 out-interface="ether1 - Unet" \ + protocol=udp +add action=accept chain=output disabled=yes dst-address-list=VPN-Server \ + dst-port=29185 out-interface="ether1 - Unet" protocol=udp +add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \ + connection-state=established,related,new disabled=yes routing-mark=\ + !To-VPN +add action=accept chain=input disabled=yes dst-port=443 in-interface=\ + "ether1 - Unet" protocol=tcp +add action=accept chain=output disabled=yes protocol=tcp src-port=443 +add action=accept chain=input comment=\ + "defconf: accept established,related,untracked" connection-state=\ + established,related,untracked +add action=drop chain=input comment="defconf: drop invalid" connection-state=\ + invalid +add action=accept chain=input comment="defconf: accept ICMP" disabled=yes \ + protocol=icmp +add action=accept chain=input comment=\ + "defconf: accept to local loopback (for CAPsMAN)" disabled=yes \ + dst-address=127.0.0.1 +add action=accept chain=output disabled=yes src-address=127.0.0.1 +add action=accept chain=forward comment="defconf: accept in ipsec policy" \ + ipsec-policy=in,ipsec +add action=accept chain=forward comment="defconf: accept out ipsec policy" \ + ipsec-policy=out,ipsec +add action=accept chain=forward comment=\ + "defconf: accept established,related, untracked" connection-state=\ + established,related,untracked +add action=drop chain=forward comment="defconf: drop invalid" \ + connection-state=invalid +add action=drop chain=forward comment=\ + "defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat \ + connection-state=new in-interface="ether1 - Unet" +add action=accept chain=input connection-state=established disabled=yes +add action=accept chain=input connection-state=related disabled=yes +add action=drop chain=input disabled=yes in-interface-list=!LAN +add action=drop chain=forward comment=\ + "Filter Rule to block FB address LIST : )" disabled=yes dst-address-list=\ + facebook +add action=drop chain=forward comment=\ + "Filter Rule to block YOUTUBE address LIST : )" disabled=yes \ + dst-address-list=YouTube +/ip firewall mangle +add action=mark-routing chain=prerouting comment="Test sites" disabled=yes \ + dst-address=!10.30.30.0/24 dst-address-list=Test new-routing-mark=To-VPN \ + src-address=10.30.30.0/24 +add action=mark-routing chain=prerouting comment=FuckRKN disabled=yes \ + dst-address-list=FuckRKN new-routing-mark=To-VPN passthrough=no \ + src-address=10.30.30.0/24 src-address-list=!NoWG +add action=mark-routing chain=prerouting comment=Instagram dst-address-list=\ + Instagram new-routing-mark=To-VPN src-address=10.30.30.0/24 \ + src-address-list=!NoWG +add action=mark-routing chain=prerouting comment=Twitter dst-address-list=\ + Twitter new-routing-mark=To-VPN src-address=10.30.30.0/24 \ + src-address-list=!NoWG +add action=mark-routing chain=prerouting comment=YouTube dst-address-list=\ + YouTube new-routing-mark=To-VPN src-address=10.30.30.0/24 \ + src-address-list=!NoWG +add action=mark-routing chain=prerouting comment=facebook dst-address-list=\ + facebook new-routing-mark=To-VPN src-address=10.30.30.0/24 \ + src-address-list=!NoWG +add action=mark-routing chain=prerouting comment="VDSIna for All sites" \ + dst-address=!10.30.30.0/24 log-prefix=VPN-all new-routing-mark=To-VPN \ + src-address=10.30.30.0/24 +add action=change-mss chain=forward comment="MSS on WG" new-mss=1380 \ + out-interface=WG passthrough=no protocol=tcp routing-mark=To-VPN \ + tcp-flags=syn tcp-mss=1381-65535 +add action=mark-connection chain=prerouting comment=\ + "Mark VPN connections to exclude from FastTrack" disabled=yes \ + in-interface=WG log-prefix=Mark-VPN-FT new-connection-mark=\ + VPN_No_FastTrack passthrough=no +add action=mark-routing chain=prerouting comment="VPN Network" dst-address=\ + 10.8.0.0/24 log-prefix=VPN-Net new-routing-mark=To-VPN passthrough=no \ + src-address=10.30.30.0/24 +/ip firewall nat +add action=redirect chain=dstnat comment=\ + "FORCE DNS TO LOCAL MIKROTIK DNS SERVER" dst-port=53 protocol=tcp \ + src-address=10.30.30.0/24 to-ports=53 +add action=redirect chain=dstnat dst-port=53 protocol=udp src-address=\ + 10.30.30.0/24 to-ports=53 +add action=masquerade chain=srcnat comment=WG dst-address-list=!NoVdsina \ + log-prefix=WG-nat out-interface=WG +add action=masquerade chain=srcnat comment="masquerade Default" ipsec-policy=\ + out,none out-interface="ether1 - Unet" +add action=dst-nat chain=dstnat comment=amster.vados.ruhttps dst-port=443 \ + in-interface="ether1 - Unet" log-prefix=2Amster protocol=tcp \ + routing-mark=!To-VPN to-addresses=10.30.30.33 to-ports=443 +add action=dst-nat chain=dstnat comment=npm dst-port=81 in-interface=\ + "ether1 - Unet" protocol=tcp routing-mark=!To-VPN to-addresses=\ + 10.30.30.33 to-ports=81 +add action=dst-nat chain=dstnat comment="amster.vados.ru For Certbot HTTP" \ + dst-port=80 in-interface="ether1 - Unet" protocol=tcp routing-mark=\ + !To-VPN to-addresses=10.30.30.33 to-ports=80 +add action=dst-nat chain=dstnat disabled=yes dst-port=22 in-interface=\ + "ether1 - Unet" protocol=tcp routing-mark=!To-VPN to-addresses=\ + 10.30.30.33 to-ports=22 +add action=dst-nat chain=dstnat comment="Yandex.DNS Family" disabled=yes \ + dst-port=53 in-interface=Bridge-LAN protocol=udp src-address-list=KIDS \ + time=6h-15m,sun,mon,tue,wed,thu,fri,sat to-addresses=77.88.8.3 +add action=dst-nat chain=dstnat disabled=yes dst-port=53 in-interface=\ + Bridge-LAN protocol=tcp src-address-list=KIDS time=\ + 6h-15m,sun,mon,tue,wed,thu,fri,sat to-addresses=77.88.8.3 +/ip firewall raw +add action=drop chain=prerouting comment="Drop Honeypot Hackers" \ + in-interface="ether1 - Unet" src-address-list="Honeypot Hacker" +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + extras.getpagespeed.com content=extras.getpagespeed.com disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=linux.duke.edu \ + content=linux.duke.edu disabled=yes +add action=accept chain=prerouting comment="Trusted DNS" disabled=yes \ + in-interface-list=WAN src-address-list=Trusted-DNS +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=vk.com \ + content=vk.com +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=ok.ru content=\ + ok.ru +add action=add-dst-to-address-list address-list=Instagram \ + address-list-timeout=none-dynamic chain=prerouting comment=Instagram \ + content=instagram.com +add action=add-dst-to-address-list address-list=Twitter address-list-timeout=\ + none-dynamic chain=prerouting comment=Twitter content=twimg.com +add action=add-dst-to-address-list address-list=Twitter address-list-timeout=\ + none-dynamic chain=prerouting content=x.com +add action=add-dst-to-address-list address-list=Twitter address-list-timeout=\ + none-dynamic chain=prerouting content=twitter.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting comment=YouTube content=youtube.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=googleapis.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=ggpht.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=youtu.be +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=ytimg.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=googlevideo.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=gstatic.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=googleusercontent.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=nhacmp3youtube.com +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=rutube.ru \ + content=rutube.ru +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=me.com \ + content=me.com +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=icloud.com \ + content=icloud.com +add action=add-dst-to-address-list address-list=facebook \ + address-list-timeout=none-dynamic chain=prerouting comment=facebook \ + content=fbcd.net +add action=add-dst-to-address-list address-list=facebook \ + address-list-timeout=none-dynamic chain=prerouting content=facebook.com +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=comp-lenta.ru \ + content=comp-lenta.ru +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + smtp.mail.me.com content=smtp.mail.me.com +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=gov.ru \ + content=gov.ru +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + r78.fssp.gov.ru content=r78.fssp.gov.ru +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=api.db-ip.com \ + content=api.db-ip.com +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + api.telegram.org content=api.telegram.org +/ip firewall service-port +set ftp disabled=yes +set tftp disabled=yes +set irc disabled=no +set sip disabled=yes +set pptp disabled=yes +set rtsp disabled=no +/ip hotspot user profile +set [ find default=yes ] address-pool=dhcp +/ip hotspot walled-garden +add server=*1 +add server=*1 +/ip ipsec settings +set accounting=no +/ip ipsec policy +set 0 disabled=yes dst-address=0.0.0.0/0 src-address=0.0.0.0/0 +/ip ipsec profile +set [ find default=yes ] dpd-interval=2m dpd-maximum-failures=5 +/ip proxy +set cache-administrator="" max-cache-size=none port=80,443 src-address=\ + 0.0.0.0 +/ip route +add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=WG routing-table=\ + To-VPN scope=30 target-scope=10 +/ip service +set ftp disabled=yes +set telnet disabled=yes +set reverse-proxy disabled=yes +set ssh address=10.30.30.0/24 port=2222 +set winbox address=10.30.30.0/24 +set api address=10.30.30.0/24 disabled=yes +set api-ssl address=10.30.30.0/24 disabled=yes +set www-ssl port=18443 +set www address=10.30.30.0/24 disabled=yes port=18880 +/ip service webserver +set acme-plain=no crl-plain=no graphs-plain=no graphs-secure=no index-plain=\ + no index-secure=no rest-plain=no rest-secure=no scep-plain=no \ + webfig-plain=no webfig-secure=no +/ip ssh +set forwarding-enabled=both publickey-authentication-options=verify-required \ + strong-crypto=yes +/ip upnp +set enabled=yes +/ip upnp interfaces +add interface=Bridge-LAN type=internal +add interface="ether1 - Unet" type=external +add interface=WG type=external +add interface=wlan2 type=internal +/snmp community +set [ find default=yes ] addresses=10.30.30.0/24 read-access=no security=\ + private +/system clock +set time-zone-autodetect=no time-zone-name=Europe/Moscow +/system clock manual +set time-zone=+03:00 +/system identity +set name=MikroMaster +/system logging +add action=email disabled=yes regex="* added|changed|removed *" topics=\ + system,info +/system note +set show-at-login=no +/system ntp client +set enabled=yes +/system ntp server +set enabled=yes manycast=yes multicast=yes use-local-clock=yes +/system ntp client servers +add address=0.ru.pool.ntp.org +add address=1.ru.pool.ntp.org +add address=2.ru.pool.ntp.org +add address=3.ru.pool.ntp.org +add address=time.google.com disabled=yes +/system package update +set channel=development +/system scheduler +add comment="Scheduler for Update Certificates CloudFlare Quad9" disabled=yes \ + interval=1w name="Update Certificates CloudFlare Quad9" on-event=\ + "/system/script { run Update-Certificates; }" policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + start-date=2025-11-28 start-time=05:45:40 +add comment="Every Day Set Global Environment Variables" name=AM-SetGlobalEnv \ + on-event="/system/script { run AM-GlobalConfig; run AM-GlobalFunc; }" \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + start-time=startup +add comment="Every Day Check For Update Scripts" interval=1d name=\ + AM-ScriptInstallUpdate on-event=\ + ":global ScriptInstallUpdate; \$ScriptInstallUpdate;" policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + start-time=startup +add comment="Update RKN DNS Looup" interval=20m name=AM-RKN-dnsLookup \ + on-event="/system/script { run AM-RKN-dnsLookup; }" policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + start-time=startup +/system watchdog +set watchdog-timer=no +/tool e-mail +set certificate-verification=no from=MikroVados port=587 \ + server=smtp.mail.me.com tls=starttls user=vadossio@icloud.com +/tool mac-server +set allowed-interface-list=LAN +/tool mac-server mac-winbox +set allowed-interface-list=LAN +/tool netwatch +add comment="doh, doh-url=https://security.cloudflare-dns.com/dns-query, notif\ + y, name=CloudFlare-doh IPv4 1" disabled=yes down-script="" host=1.1.1.1 \ + http-codes="" test-script="" type=simple up-script="" +add check-certificate=no comment="doh-fallback, doh-url=https://security.cloud\ + flare-dns.com/dns-query, doh-cert=DigiCert Global Root CA, notify, name=Cl\ + oudFlare-doh IPv4" disabled=yes down-script="" host=1.0.0.1 http-codes="" \ + port=443 test-script="" type=simple up-script="" +add comment="dns-fallback, notify, name=Google-DNS IPv4" disabled=yes \ + down-script="" host=8.8.8.8 http-codes="" test-script="" type=simple \ + up-script="" +add comment="doh-fallback, doh-url=https://dns.google/dns-query, doh-cert=GTS \ + Root R1, notify, name=Google-DOH IPv4" disabled=yes down-script="" host=\ + 8.8.4.4 http-codes="" test-script="" type=simple up-script="" +add comment="dns, notify, name=Cuad9-DOH IPv4" disabled=yes down-script="" \ + host=9.9.9.9 http-codes="" test-script="" type=simple up-script="" +add comment="doh-fallback, doh-url=https://dns.quad9.net/dns-query, name=Cuad9\ + -DOH IPv4" disabled=yes down-script="" host=149.112.112.112 http-codes="" \ + test-script="" type=simple up-script="" +add comment="dns-fallback, notify, name=ns1.unet.ws" disabled=yes \ + down-script="" host=91.192.189.2 http-codes="" test-script="" type=simple \ + up-script="" +/tool sniffer +set filter-interface=Bridge-LAN filter-src-ip-address=10.30.30.50/32 +/user aaa +set accounting=no diff --git a/MikroMaster/history/20260510/20260510024002-Diff-Config.rsc b/MikroMaster/history/20260510/20260510024002-Diff-Config.rsc new file mode 100644 index 0000000..522f537 --- /dev/null +++ b/MikroMaster/history/20260510/20260510024002-Diff-Config.rsc @@ -0,0 +1,22 @@ +17d16 +< # same mac-address as wlan1 +3465d3463 +< # same mac-address as ether1 - Unet +3483d3480 +< # same mac-address as ether1 - Unet +3494,3496c3491,3493 +< set builtin-trust-store="ipsec,wpa-eap,capsman,fetch,sstp,ovpn,radius,containe\ +< r,userman,wiliot,openflow,tr069,dot1x,www,api,reverse-proxy,logging" \ +< crl-download=yes crl-use=yes +--- +> set builtin-trust-store="ipsec,wpa-eap,capsman,fetch,sstp,ovpn,radius,userman,\ +> openflow,tr069,dot1x,www,api,reverse-proxy" crl-download=yes crl-store=\ +> system crl-use=yes +4406c4403 +< src-address=10.30.30.0/24 +--- +> passthrough=no src-address=10.30.30.0/24 +4426c4423 +< out,none out-interface="ether1 - Unet" +--- +> out,none out-interface="ether1 - Unet" routing-mark=!To-VPN -- 2.52.0