<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Piotr Sarna on Medium]]></title>
        <description><![CDATA[Stories by Piotr Sarna on Medium]]></description>
        <link>https://medium.com/@p.sarna?source=rss-624320382cf0------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*t7iZy_WBbpv8MWyWU2_O6A.jpeg</url>
            <title>Stories by Piotr Sarna on Medium</title>
            <link>https://medium.com/@p.sarna?source=rss-624320382cf0------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 05 Jun 2026 21:40:27 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@p.sarna/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Zig helped us move data to the Edge. Here are our impressions]]></title>
            <link>https://medium.com/chiselstrike/zig-helped-us-move-data-to-the-edge-here-are-our-impressions-67d3a9c45af4?source=rss-624320382cf0------2</link>
            <guid isPermaLink="false">https://medium.com/p/67d3a9c45af4</guid>
            <category><![CDATA[database]]></category>
            <category><![CDATA[edge-computing]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[postgres]]></category>
            <category><![CDATA[zig]]></category>
            <dc:creator><![CDATA[Piotr Sarna]]></dc:creator>
            <pubDate>Mon, 24 Jul 2023 18:24:52 GMT</pubDate>
            <atom:updated>2023-07-24T18:35:34.995Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="Midjourney: zig-zag, zig, experience, psychedelics, stylistic — ar 2:1" src="https://cdn-images-1.medium.com/max/1024/0*s0atGSvJUm8C3vKL" /><figcaption>Midjourney: zig-zag, zig, experience, psychedelics, stylistic — ar 2:1</figcaption></figure><h4>Kicking the tires on Zig with a greenfield, open source project.</h4><p>Our company is a Rust shop. We love Rust, and believe Rust will be the main engine of our work for a lifetime. But as a bunch of performance nerds, we’ve been keeping a very close eye on Zig. It evokes a feeling of simplicity that I long for the C days, and comptime, the ability to run arbitrary code at compile time, is a straight out brilliant idea.</p><p>Like any shiny new tool, we’ve been looking for a way to make use of Zig in the shop. Rewriting existing production code wasn’t really an option, so we found a new project to give it a spin. This article details our experience.</p><h3>The problem statement</h3><p>Our product, <a href="https://turso.tech">Turso</a>, is an Edge Database. If you are unfamiliar with the concept, it’s very simple: if you are deploying your code in multiple geographical locations, accessing your data from a central location will make your application slow. You may not like it, but a genius a couple of years ago proved there’s nothing you can really do about it (I’m talking about Einstein, not <a href="https://www.youtube.com/watch?v=QwUPs5N9I6I">Tom</a>).</p><p>Because of the limitations of the physical world, the only way to get super fast database queries in both San Francisco and Sydney is to have the data replicated at both places. Keeping a database running in multiple locations is expensive, which means to make this work you need a database that is extremely cheap to run. That’s why we use <a href="https://github.com/libsql">libSQL</a>, an open contribution fork of SQLite. Add to that a lot of machinery to make replication simple and easy, and automatically route you to the closest replica, and you have an Edge Database.</p><h3>Storage costs</h3><p>Replicating data everywhere does have a cost. Our reliance on a slim and mighty database helps us to keep the compute costs in check. But for the data, there’s not much you can do. Want ten replicas? Pay ten times the storage.</p><p>This works well for a variety of applications, especially in the web, where data volumes are “low”. I’ve helped design a NoSQL database before (ScyllaDB) that operated at the Petabyte scale, so “low” and “high” are always relative. Let’s ground this with numbers: storing a GB of data on fast storage costs less than a dollar per month. Assume 25 cents to leave room for all markups. Storing 10GB of data will cost $2.50 per region. We support 34 regions, so even if you deploy to all of our regions, that’s still $85 a month for storage costs– less than you’ll pay for Hubspot, Google Workspaces, or any other SaaS tool that your company depends on.</p><p>But even before we reach the petabyte level, there are many use cases that will accumulate hundreds, or even thousands of GBs. And while you may have the money to spare, the reality is that <a href="https://blog.turso.tech/replicate-my-entire-production-database-you-must-be-mad-641d3f1ed9d8">you don’t need all that data on the Edge</a>. Some of it is just cold, and you don’t need it all the time. An architecture that takes advantage of the edge while keeping the costs down is one that will keep your database of record in a central location, and then replicate some of that data to the edge.</p><h3>The solution: pg_turso</h3><p>To tackle this issue we built <a href="https://github.com/turso-extended/pg_turso">pg_turso</a>, a Postgres extension that automatically syncs a slice of your data to Turso. It is completely experimental at the moment, and not production ready. We are making progress in productizing it over the near future.</p><p>The way it works is that you choose a table (or a materialized view) in Postgres, that you wish to replicate to the edge. Tables often are already a subset of your data, and materialized views are a standard way of selecting part of your data for certain queries. Our extension then hooks into Postgres’ logical replication and materialized view refresh process, replicating the changes right into the Turso database.</p><h3>We built pg_turso with Zig</h3><p>The first reason why this made sense is that pg_turso is a very self-contained and isolated project, and doesn’t need to share code with the rest of our database. There’s no need to rewrite production code, or even take dependency on Zig.</p><p>The second reason was that there was already code in the wild, written in C, that was similar to what we wanted to do. If we could reuse some of that code, that would be a win. Postgres allows users to provide a <a href="https://www.postgresql.org/docs/current/logicaldecoding-output-plugin.html">logical decoding output plugin</a>, which is a fancy name for your own replication routines. Postgres itself already has an example plugin to get you started, <a href="https://github.com/postgres/postgres/blob/master/contrib/test_decoding/test_decoding.c">test_decoding.c</a></p><h3>Zig delivers for C interoperability</h3><p>Zig is famous for its seamless interoperability with C. It even has a cross-compiler to transform C code right into Zig. I have never touched Zig before (and because what could go wrong), so I just tried:</p><pre>zig translate-c test_decoding.c</pre><p>… which didn’t work at all!</p><p>But that was just due to missing headers, and to my slight surprise,</p><pre>zig translate-c -I /usr/include -I ../../src/include test_decoding.c</pre><p>It compiled just fine, dumping lots of valid Zig code. We still had work to do to make our extension work, but that’s a start!</p><p>The next step was to add some definitions about being a postgres module. In the test code above this was done with macros, which Zig thankfully does not support. (For the Rust people who complain about Rust macros… C macros are straight from hell.) <a href="https://github.com/turso-extended/pgturso/blob/fb8467e876e4e47b78640274bca8c0a6eb6c3f8a/src/main.zig#L19-L46">That required a bit of boilerplate code</a>, but still manageable and ergonomic to write.</p><p>Predictably, we’re also going to need a few definitions from the postgres.h header interface. Forget binding generators and explicit foreign function interfaces: In Zig, <a href="https://github.com/turso-extended/pgturso/blob/fb8467e876e4e47b78640274bca8c0a6eb6c3f8a/src/main.zig#L4-L10">you just slap a @cImport in there</a> and call it a day. All the C code available under an isolated namespace.</p><p>The @cImport directive is based on translate-c, which means that the header is translated to native Zig code during compilation. This is where Zig shines. It just seamlessly wraps a C header into a Zig structure, as if it was yet another Zig module, and you’re free to use all constants and functions as if they were native Zig. Truly amazing.</p><h3>Debugging and cross compiling are smooth</h3><p>The way translate-c works is that all dependencies are cooked right into the final file. This means the relevant parts of the standard C library also get translated and added to the output. That’s very convenient, because it makes the resulting single source file self-contained.</p><p>A bonus of this behavior is that debugging deep issues, the kind that always occur when writing system software, is made much easier: all the C dependencies, the C standard library, and the Zig standard library, gets shipped as code that gets compiled along with your project.</p><p>That gives the compiler more opportunity to optimize, inline and reduce your final binary to only what it needs, but it also means you’re free to edit the code yourself if you run into one of those unexplainable issues that could be coming from anywhere (like we did).</p><p>Another advantage is that it allows Zig to shine in cross-compilation. In our company, for example, one of the reasons that led us to code <a href="https://github.com/chiselstrike/turso-cli">our CLI</a> in Go is how well it cross-compiles to Mac (Apple Silicon and Intel), Linux and even Windows. Rust is nowhere near that.</p><h3>translate-c has issues with obscure C code</h3><p>As great as the experience with translate-c was, Zig had issues with some complicated macro constructs. Now, that says more about C macros than it says about Zig (have I mentioned how monstrous C macros can be?). The main issue is that the Zig compiler is not always capable of guessing the types safely. In all fairness, oftentimes with C macros humans cannot guess them either, but reality is that the world of C is full of those macros, so expect interoperability to fail at times.</p><h3>The good parts of Rust are here</h3><p>Judging modern languages like Rust and Zig needs to go beyond the language definition. The ecosystem matters.</p><p>The Zig building process is elegant, and it won’t be a surprise for Rust folks that have ever written a build.rs script before. Zig is built on similar principles, and if you want to state that your code should be linked to the standard C library and compiled to a shared library, you just express all that <a href="https://github.com/turso-extended/pg_turso/blob/main/build.zig">in Zig</a>.</p><p>Another thing that Rust hackers would admire is zig fmt — an opinionated tool for formatting Zig code, so that you avoid endless bikeshedding over the code style.</p><p>Error handling is another ergonomic aspect of Zig. At first I was really confused when I saw all the catch unreachable idioms over the code samples. But once I understood it, it made perfect sense. It also maps well to Rust concepts.</p><p>Functions can explicitly declare if they may return errors. If they do, you can use the try operator inside them, which is conceptually similar to Rust’s ? operator — it returns from the function early if something fails:</p><pre>_ = try std.fmt.bufPrint(stmt_buf[offset..], &quot;null&quot;, .{});</pre><p>Errors are handled by a catch operator:</p><pre>send(data.*.url, data.*.auth, json_payload) catch |err| {<br>  std.debug.print(&quot;Failed to replicate: {}\n&quot;, .{err});<br>};</pre><p>And catch unreachable is a conceptual twin of Rust’s unwrap — it aborts the execution of your program if an error occurred.</p><pre>const prefix = std.fmt.bufPrint(&amp;stmt_buf, &quot;INSERT INTO {s} &quot;, .{table}) catch unreachable;</pre><h3>I miss RAII</h3><p>Zig is very opinionated on “explicit is better than implicit”. As a consequence, it lacks Rust-style destructors, and all allocations need to happen explicitly. The explicit allocations are definitely nice, but the lack of destructors is a mild footgun. Similarly to Go, Zig does offer a defer keyword to let programmers create shutdown routines. It’s idiomatic to write code like:</p><pre>const something = createSomething(allocator);<br>defer something.deinit();</pre><p>However it’s easy to forget, and easy to leak memory or hold on to resources.</p><p>I obviously do see the flip side of that: sometimes you’re not interested in calling destructors, e.g. if your program uses arena allocators or creates long-lived objects, which in Rust are a bit painful to write. Still, as a person who forgets things, I miss the convenience of the default-destroy nature of RAII in Rust.</p><h3>The ecosystem is still maturing</h3><p>Zig has HTTP and JSON support embedded in the standard library — which came in handy since Turso is accessible over HTTP.</p><p>However, a lot of those cool features are only available in dev builds, with daily releases, and are explicitly described as not mature in their docs. HTTP support was one of them. This forced us to use the newest dev release in our CI, which kept breaking in backwards incompatible ways.</p><p>And when we mentioned that having the whole library output in the final file was handy for debugging… that’s from experience: because of an issue with standard headers, we couldn’t get replication working Turso, until it became clear it was an issue with the standard library. <a href="https://github.com/ziglang/zig/pull/16092">We contributed the fix back.</a></p><p>The experience of contributing to Zig was really great — the PR was promptly reviewed and accepted, and landed in a dev release soon after. But at the end of the day, an issue this central, with HTTP headers, does show that the language has to mature a bit before we can switch our whole company to it.</p><h3>The verdict</h3><p>The overall experience was really great — Zig code looks cleaner, the Postgres C API header is neatly hidden behind a Zig interface, and the standard library support for HTTP and JSON means that we don’t need any external dependencies, which has its own value.</p><p>Despite a couple of rough edges, we remain incredibly bullish about the future of Zig. That future, though, is not yet here.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=67d3a9c45af4" width="1" height="1" alt=""><hr><p><a href="https://medium.com/chiselstrike/zig-helped-us-move-data-to-the-edge-here-are-our-impressions-67d3a9c45af4">Zig helped us move data to the Edge. Here are our impressions</a> was originally published in <a href="https://medium.com/chiselstrike">Turso blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Write your own email server (in Rust!)]]></title>
            <link>https://medium.com/chiselstrike/write-your-own-email-server-in-rust-36f4ff5b1956?source=rss-624320382cf0------2</link>
            <guid isPermaLink="false">https://medium.com/p/36f4ff5b1956</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[edge-computing]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[rust]]></category>
            <category><![CDATA[turso]]></category>
            <dc:creator><![CDATA[Piotr Sarna]]></dc:creator>
            <pubDate>Tue, 09 May 2023 16:22:17 GMT</pubDate>
            <atom:updated>2023-05-09T16:22:17.004Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="Mailbox at the edge" src="https://cdn-images-1.medium.com/max/936/1*R3QqpzJiK93zcmLM8_7vMA.png" /><figcaption>Mailbox at the edge — crayion.com’s interpretation</figcaption></figure><p>A walkthrough on how to implement and deploy your own disposable email server from scratch.</p><h3>Write your own email server (in Rust!)</h3><p>As a loyal user of <a href="https://10minutemail.com">10minutemail</a>, I always wondered how hard it would be to implement and set up your own disposable email server — one used solely for posting your email address to one of those “we’d love to know more about you before we let you download our open-source software” forms, registering to trial periods, and local tests for my other weekend projects. As it turns out, implementing such a server is a surprisingly smooth and gratifying experience!</p><p>The result of this small personal hackathon is <a href="https://github.com/psarna/edgemail">edgemail</a>, an open-source disposable email server. In this post, you’ll see how to write and deploy one yourself. A public instance of edgemail is hosted <a href="https://sorry.idont.date">here</a>.</p><h3>About SMTP</h3><p>Simple Mail Transfer Protocol (SMTP) is <a href="https://datatracker.ietf.org/doc/html/rfc780">old</a>. I was also surprised to discover that for such a battle-tested and reliable protocol, there aren’t that many resources to learn about its details, especially if you would like to implement it yourself. In fact, all “build your own SMTP” tutorials basically start with “install Postfix” — which is a fully-fledged, production-grade SMTP server! Let’s start with the basics instead.</p><p>SMTP is an application layer protocol that runs on top of a transport layer, which is customarily TCP. SMTP is text-based and connection-oriented, which fortunately makes it human-readable. An SMTP transaction is simply a sequence of request-reply messages.</p><p>An example conversation between a client and a server may look like this:</p><pre>Server-&gt;Client: 220 edgemail server reporting for duty 🫡<br>Client-&gt;Server: HELO smtp.example.com<br>Server-&gt;Client: 250-smtp.example.com Hello user<br>Client-&gt;Server: MAIL FROM:&lt;robert@example.com&gt;<br>Server-&gt;Client: 250 Ok<br>Client-&gt;Server: RCPT TO:&lt;rosie@example.com&gt;<br>Server-&gt;Client: 250 Ok<br>Client-&gt;Server: DATA<br>Server-&gt;Client: 354 End data with &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;<br>Client-&gt;Server: From: &quot;Robert &lt;robert@example.com&gt;<br>Client-&gt;Server: To: &quot;Rosie &lt;rosie@example.com&gt;<br>Client-&gt;Server: Date: Wed, 19 Apr 2023, 12:30:34<br>Client-&gt;Server: Subject: Hi Rosie!<br>Client-&gt;Server: Hi Rosie! How are you today?<br>Client-&gt;Server: &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;<br>Server-&gt;Client: 250 Ok<br>Client-&gt;Server: QUIT<br>Server-&gt;Client: 221 Bye</pre><p>This simple example is enough to start sketching an implementation of the server, which would be a quite simple state machine capable of handling a few commands: greeting the user, and receiving mail. Sending mail is more complex, and won’t be covered in this blog post. Fortunately, we do not need to ever send mail from our disposable server — it’s only going to be used as a throwaway address used for registering to unwanted newsletters.</p><h3>Implementation</h3><p>The project’s name is <strong>edgemail</strong>, which is a tribute to the fact that it provides low latency for its users thanks to using an edge-native database. More on that in a few paragraphs!</p><p>The server will be implemented as 3 separate layers:</p><ol><li>SMTP state machine, responsible for handling SMTP communication</li><li>Database for storing mail</li><li>Client for browsing mail</li></ol><h3>SMTP state machine</h3><p>SMTP is a rather complicated standard, but fortunately for disposable email purposes we can ignore all the extensions, authentication, authorization, etc, focusing on just being able to receive mail. The (slightly simplified) figure below shows how our server is going to operate.</p><figure><img alt="Awaiting user -&gt; HELO -&gt; Greeted user -&gt; MAIL -&gt; Awaiting recipients -&gt; DATA -&gt; Receiving mail body -&gt; QUIT -&gt; Done" src="https://cdn-images-1.medium.com/max/173/1*gmRpxrWW93vBSflAejkiIA.png" /><figcaption>Simplified SMTP communication flow for receiving mail</figcaption></figure><p>Once a connection is established, the server introduces itself, and then performs a handshake by accepting a HELO or EHLO (extended-hello) message. After the handshake is done, the server waits for the MAIL command, which contains information about who sent the email, followed by RCPT commands, with information about all recipients. Once the sender and recipients are known, the server accepts a DATA command which allows it to receive the email body. Once done, a goodbye procedure is performed, and the transaction is done.</p><p>Source code for the state machine is <a href="https://github.com/psarna/edgemail/blob/aada9ebcdff32801e6b787986b96f82f2e8d992a/src/smtp.rs#L23">here</a>.</p><h3>TCP Server</h3><p>Once we have an SMTP state machine, it’s time to hook it up with a TCP server. The server’s job is going to be extremely simple:</p><ol><li>Accept a new connection</li><li>Send an SMTP greeting</li><li>Receive an SMTP command</li><li>Process the command with our SMTP state machine</li><li>Return the response back to the user</li><li>If mail was received, save it in the database</li></ol><p>With the <a href="https://crates.io/crates/tokio">Tokio</a> crate, implementing such a TCP server is going to be a breeze.</p><p>Since our server is dedicated for use as a temporary mailbox for one person, we’re not going to bother ourselves with user management. Instead, the server is going to accept all mail and save them in the database. In order to not go out of storage, old mail will be cleaned up periodically.</p><p>Source code of the server is <a href="https://github.com/psarna/edgemail/blob/aada9ebcdff32801e6b787986b96f82f2e8d992a/src/smtp.rs#L140">here</a>.</p><h3>Database</h3><p>For storing all the mail, we’re going to use <a href="https://turso.tech">Turso</a> — an edge-native SQL database. Turso can receive requests over HTTP, which allows executing requests straight from the browser, and that makes responses ridiculously fast, as you’ll see in the <strong>Performance</strong> section later.</p><p>Additionally, Rust client for Turso, <a href="https://crates.io/crates/libsql-client">libsql-client</a>, is also capable of storing everything in a libSQL database — which is kept in a local file, just like SQLite. And that’s just perfect for tests and quick prototyping.</p><p>In order to create a new database, start with installing our <a href="https://docs.turso.tech/reference/turso-cli#installation">turso command-line tool</a>.</p><p>Once you’re done, create a new database — let’s call it edgemaildb — with:</p><pre>$ turso db create edgemaildb</pre><p>The schema for storing mail is going to be straightforward, with all mail kept in a single table. This table will be auto-created on edgemail server startup if it does not exist:</p><pre>CREATE TABLE IF NOT EXISTS mail (date text, sender text, recipients text, data text)</pre><p>In order to speed up queries on the mail table, the following indexes can be created. They will also be auto-created on edgemail startup if not present:</p><pre>CREATE INDEX IF NOT EXISTS mail_date ON mail (date)<br>CREATE INDEX IF NOT EXISTS mail_recipients ON mail (recipients)</pre><h4>Connecting to the database from Rust</h4><p>Turso is compatible with the <a href="https://crates.io/crates/libsql-client">libSQL Rust driver</a>. The driver only needs two pieces of information to be able to operate:</p><ol><li>The database URL.</li><li>An authentication token, which is required only when connecting to a Turso remote instance.</li></ol><p>These can be specified as environment variables. The following configuration will connect to a Turso instance:</p><pre>LIBSQL_CLIENT_URL=https://your-db-name-and-username.turso.io<br>LIBSQL_CLIENT_TOKEN=your-auth-token</pre><p>… but you can also specify a local file to use for development purposes — no need to sign up to anything!</p><pre>LIBSQL_CLIENT_URL=file:///tmp/edgemail-test.db</pre><p>In edgemail, the situation is even simpler. If no URL is specified, the server will automatically start with a local database stored in an edgemail.db file placed in your system’s temporary directory path:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/38307f81b44ffc1d447d2f8a59d1c173/href">https://medium.com/media/38307f81b44ffc1d447d2f8a59d1c173/href</a></iframe><p>Once you go to production and store the emails at the edge, it’s enough to point the LIBSQL_CLIENT_URL variable to your Turso database URL, and LIBSQL_CLIENT_TOKEN to the authentication token.</p><p>You can inspect your database’s URL by running the following command:</p><pre>turso db show --url edgemaildb</pre><p>In order to generate an auth token, run the following command:</p><pre>turso db tokens create edgemaildb</pre><h3>Client</h3><p>Since Turso speaks HTTP, our client is going to be a static webpage, which can be hosted for free in a multitude of places, like GitHub Pages. If you’re worried about your database access tokens leaking after being published inside a webpage — don’t. With Turso, you can <a href="https://docs.turso.tech/reference/turso-cli#read-only-auth-tokens">generate read-only tokens</a> for your database:</p><pre>turso db tokens create edgemaildb --read-only</pre><p>Those grant read-only access to your database. In this specific use case it’s fine to “leak” the tokens to users’ browsers, because the whole database is, by design, readable by everyone. Sending database requests straight from the browser is also great for your latency — your browser is going to fetch the data directly from the database, no middlemen involved. The <em>Performance</em> section at the end of this blog post shows the difference with concrete numbers.</p><p>The client is going to be divided into two pages: landing page for choosing your username and the inbox.</p><p>The landing page is a simple form which lets users pick any username they would like to use. The SMTP server accepts all incoming mail anyway, so any username can be chosen. For the undecided, a simple pseudo-random username generator will suggest a hint.</p><p>Once a username is picked, users are transferred to the inbox page, where all the magic happens.</p><p>The inbox page fetches all mail addressed to a given user directly from the database, essentially by sending the following SQL request:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4403d849b551fad7121fe26098864fb8/href">https://medium.com/media/4403d849b551fad7121fe26098864fb8/href</a></iframe><p>This request is a SELECT operation, so it only requires read-only access to the database. That allows us to use a read-only authentication token that can be safely “leaked” to the webpage HTML source.</p><h3>Source code</h3><p>The whole source code, including the server, client, and tests, is open-source and available <a href="https://github.com/psarna/edgemail">here</a>. Enjoy! In order to run the server, just go with cargo run. Tests can be run with cargo test.</p><h3>Deployment</h3><h3>SMTP Server</h3><p>Now that the server is implemented, it’s time to make it public. For that, you’re going to need any machine with a public, exposed IPv4 address and port 25 open for inbound traffic. Technically, SMTP runs just fine on IPv6 as well, but in practice, email providers often refuse to work with IPv6 servers as spam prevention. The IPv6 address space is simply too broad and too unregulated to be as easy to verify as good ol’ IPv4, so it’s better to stick with that. SMTP servers often listen to connections on other port numbers, including 465, and even 2525, but since 25 is universally supported among all email providers, it’s enough to stick with that.</p><p>The edgemail server weighs less than 5MiB total and runs just fine on my ancient Raspberry Pi 2 — as long as it’s accessible via a public IPv4 address at port 25, you’re good to go.</p><h3>DNS configuration</h3><p>In order to become a mailbox provider, you need a domain. Fortunately, with so many top-level domains available, you can get one at a really affordable price — I registered the idont.date domain a few years back with <a href="https://porkbun.com">Porkbun</a> for less than $2 a year.</p><p>Once you become a proud owner of an Internet domain, two DNS entries need to be set up to make your server functional. Examples below show my setup for the idont.date domain and the IP address of the machine I use, so make sure you replace them with your own domain name and IP address accordingly.</p><ol><li>An A entry, which points to the IP address of your server, e.g.<br>[ A ][ smtp.idont.date ][ 3.143.135.0 ]</li><li>An MX (mail exchange) entry, which points back to the A entry above, e.g.<br>[ MX ][ idont.date ][ smtp.idont.date ]</li></ol><p>With those two in place, servers which are going to send mail to you will be able to find out where to route the information. The email server will simply resolve the DNS entries and find out to which IP address it should send all the information.</p><p>That’s it! With a server and DNS set up, the server is ready to receive mail. You can try it out by sending an email to your new domain, or signing up for that newsletter you always hated so much.</p><h3>Performance</h3><p>The best part of using Turso as our database is the user-observed latency. Turso runs <a href="https://blog.chiselstrike.com/what-the-heck-is-the-edge-anyway-a159a12f2412">on the edge</a>, which more or less means “close to you”.</p><p>With Turso, you can create a database at one of the multiple locations, spanning almost all continents (I would like to personally apologise to all residents of Antarctica, but I’m sure you have bigger things to worry about with your climate). Once the database is up, you can create a number of replicas in order to move data closer to your end users. Let’s see how perceived latency changes once a replica is spawned closer to you.</p><p>I’m currently a resident of the Warsaw metropolitan area in Poland. Right after creating a database in the Newark, NJ region (turso db create — location ewr mail_db), the loading time for my edgy_badger_2023@idont.date mailbox is far from great. Here’s a screenshot of the developer console in my browser, tracking the timeline of executing an SQL command via HTTP:</p><figure><img alt="query latency: 191.35ms" src="https://cdn-images-1.medium.com/max/626/1*1LcZ8lF3YPGwNiZ8ENfYDA.png" /><figcaption>Latency for contacting a database in EWR region from Warsaw</figcaption></figure><p>Not bad, but also not great — you can actually see a short lag before the inbox is rendered.</p><p>And here’s how the timeline looks like once I replicate the database to Equinix’s Warsaw datacenter (turso db replicate mail_db waw):</p><figure><img alt="Query latency: 5.87ms" src="https://cdn-images-1.medium.com/max/626/1*BNYQfwsHEmHq_TK3NktBrw.png" /><figcaption>Latency for contacting a database in WAW region from Warsaw</figcaption></figure><p>This is not a typo, the request was served in 5.87 <strong>milliseconds</strong>. It might have to do with the fact that my PC happens to be located less than 1 kilometer (and so, also less than 1 mile, conveniently for fans of all systems of measurement) from the Equinix’s datacenter where the request was processed. But this is the whole point of pushing data to the edge! The last mile matters, and if you place your data at the edge, replicated to many locations, you improve the experience for more and more users.</p><h3>What’s next?</h3><p>Try <a href="https://turso.tech">Turso</a> yourself, I’m sure you’ll have as much fun with it as I did! Turso has an always-free tier with limits that are perfectly good enough for a disposable email server. And remember to always use <a href="https://sorry.idont.date">https://sorry.idont.date</a> for all throwaway mail from now on!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=36f4ff5b1956" width="1" height="1" alt=""><hr><p><a href="https://medium.com/chiselstrike/write-your-own-email-server-in-rust-36f4ff5b1956">Write your own email server (in Rust!)</a> was originally published in <a href="https://medium.com/chiselstrike">Turso blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why SQLite is so great for the edge]]></title>
            <link>https://medium.com/chiselstrike/why-sqlite-is-so-great-for-the-edge-ee00a3a9a55f?source=rss-624320382cf0------2</link>
            <guid isPermaLink="false">https://medium.com/p/ee00a3a9a55f</guid>
            <category><![CDATA[serverless]]></category>
            <category><![CDATA[sqlite]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[database]]></category>
            <category><![CDATA[edge-computing]]></category>
            <dc:creator><![CDATA[Piotr Sarna]]></dc:creator>
            <pubDate>Tue, 02 May 2023 15:26:57 GMT</pubDate>
            <atom:updated>2023-05-02T15:26:57.002Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qHA2KUtvffdBM5x10NOJsQ.png" /><figcaption><em>Feather at the edge — craiyon.com’s interpretation</em></figcaption></figure><p>Everyone already knows that SQLite is great. This article makes the praise much more specific though — it explains why we, the developers of <a href="https://libsql.org">libSQL</a>, think that SQLite is a great choice for bringing your data to <a href="https://blog.chiselstrike.com/what-the-heck-is-the-edge-anyway-a159a12f2412">the edge</a>.</p><h3>It’s lightweight</h3><p>The software industry has a habit of jumping between over- and under-valuing products with a small memory footprint. It was an important factor back in the days when desktop RAM was counted in kilobytes, then it got neglected as the hardware became less expensive and more powerful. The trend returned when we started writing software for mobile devices with limited RAM — until manufacturers continued to pack themwith gigabytes of RAM and storage as well. Now, serverless functions environments like Fermyon Spin and Cloudflare Workers, which demand your apps to be as compact as possible. The reason they do so is straightforward: if you can pack twice as many instances of your application into a single server, you also cut the hardware costs roughly in half. How does SQLite fit into the picture? It’s simply orders of magnitude lighter than similar products, such as Postgres.</p><p>At the time of writing, Cloudflare Worker binary size limit for deployments is <a href="https://developers.cloudflare.com/workers/platform/limits/#worker-size">5MiB after compression</a>. Let’s see how SQLite and Postgres fit into the limit:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e9856f1d14dd8d4506adb3321f87443c/href">https://medium.com/media/e9856f1d14dd8d4506adb3321f87443c/href</a></iframe><p>Sure, Postgres is much more heavyweight due to all its networking code, extensions, utilities, and so on. But the fact remains — you can squeeze ~10 SQLite instances into a machine in place of a single Postgres installation, and in some environments, that counts!</p><h3>It’s fast</h3><p>Speed is of course a relative term, but SQLite really is a highly optimized database library. It’s borderline impossible to compare it against networked database management systems like MySQL or Postgres, because SQLite is a library that operates on a local file — it bypasses all the costs incurred by the network, layers of serialization and deserialization, authentication, authorization, and more.</p><p>Still, it makes sense to evaluate the performance of a database you want to use. SQLite comes with a useful utility called <em>speedtest1</em>, which is perfect for getting a quick overview of the database performance with your setup:</p><pre>$ ./speedtest1 --size 5<br> 100 - 2500 INSERTs into table with no index.......................    0.006s<br> 110 - 2500 ordered INSERTS with one index/PK......................    0.009s<br> 120 - 2500 unordered INSERTS with one index/PK....................    0.010s<br> 130 - 25 SELECTS, numeric BETWEEN, unindexed......................    0.007s<br> 140 - 10 SELECTS, LIKE, unindexed.................................    0.008s<br> 142 - 10 SELECTS w/ORDER BY, unindexed............................    0.007s<br> 145 - 10 SELECTS w/ORDER BY and LIMIT, unindexed..................    0.004s<br> 150 - CREATE INDEX five times.....................................    0.005s<br> 160 - 500 SELECTS, numeric BETWEEN, indexed.......................    0.001s<br> 161 - 500 SELECTS, numeric BETWEEN, PK............................    0.001s<br> 170 - 500 SELECTS, text BETWEEN, indexed..........................    0.002s<br> 180 - 2500 INSERTS with three indexes.............................    0.003s<br> 190 - DELETE and REFILL one table.................................    0.003s<br> 200 - VACUUM......................................................    0.006s<br> 210 - ALTER TABLE ADD COLUMN, and query...........................    0.000s<br> 230 - 500 UPDATES, numeric BETWEEN, indexed.......................    0.001s<br> 240 - 2500 UPDATES of individual rows.............................    0.002s<br> 250 - One big UPDATE of the whole 2500-row table..................    0.001s<br> 260 - Query added column after filling............................    0.000s<br> 270 - 500 DELETEs, numeric BETWEEN, indexed.......................    0.002s<br> 280 - 2500 DELETEs of individual rows.............................    0.003s<br> 290 - Refill two 2500-row tables using REPLACE....................    0.009s<br> 300 - Refill a 2500-row table using (b&amp;1)==(a&amp;1)..................    0.004s<br> 310 - 500 four-ways joins.........................................    0.005s<br> 320 - subquery in result set......................................    0.003s<br> 400 - 3500 REPLACE ops on an IPK..................................    0.002s<br> 410 - 3500 SELECTS on an IPK......................................    0.003s<br> 500 - 3500 REPLACE on TEXT PK.....................................    0.002s<br> 510 - 3500 SELECTS on a TEXT PK...................................    0.003s<br> 520 - 3500 SELECT DISTINCT........................................    0.002s<br> 980 - PRAGMA integrity_check......................................    0.009s<br> 990 - ANALYZE.....................................................    0.001s<br>       TOTAL.......................................................    0.124s</pre><p>At the time of this writing, the time limit for a Cloudflare Worker is 10ms. This is plenty for 2500 database inserts and a couple of hundred selects on top! Sounds like orders of magnitude more than your typical shopping cart implementation requires.</p><h3>It’s zero-configuration</h3><p>Arguably the main advantage of SQLite is that you don’t need to spend dozens of hours trying to set up a distributed system in order to even start using it. In fact, you don’t really need anything, not even a hard drive, to start prototyping. Your environment doesn’t have persistent storage? No problem: SQLite will gladly run an in-memory database for you. That translates to superior developer experience. The primary focus of libSQL is the ability to start fast and prototype your project 100% locally, and push it to the cloud only when deploying to production.</p><h3>It’s rock-solid</h3><p>SQLite is backed by an extensive set of <a href="https://www.sqlite.org/testing.html">tests</a>, claiming 100% branch coverage, in various aspects and configurations:</p><ul><li>Correctness checks</li><li>I/O error tests</li><li>Fuzzing</li><li>Regression tests</li><li>Crash/power loss tests</li><li>Constrained memory tests</li></ul><p>… and more.</p><p>A fair part of this test suite is unfortunately closed-source (<a href="https://github.com/libsql/libsql/issues/119">we’re working on it</a>). Still, the software is universally considered battle-tested, as it powers everything from smartphones to aircraft and more. It’s important to be able to trust the database with your data — avoid corruption, data loss, bit rot, and all other kinds of unpleasant things that can happen. And while it’s impossible to escape all of such situations unharmed, proper test coverage is the best preventive measure to start with.</p><h3>It’s feature-packed</h3><p>Don’t get misled by its compact size — SQLite is <em>loaded</em> with features. Did you know that you can ask for today’s date with a simple query?</p><pre>SELECT date(&#39;now&#39;);</pre><p>Alright, not particularly impressive. How about the first day of the current month?</p><pre>SELECT date(&#39;now&#39;, &#39;start of month&#39;);</pre><p>Still not impressed? Let’s get the first week of the month instead:</p><pre>SELECT date(&#39;now&#39;, &#39;start of month&#39;, &#39;+7 days&#39;);</pre><p>Oh, you wanted the first <strong>Thursday</strong>? SQLite has you covered:</p><pre>SELECT date(&#39;now&#39;, &#39;start of month&#39;, &#39;+7 days&#39;, &#39;weekday 3&#39;);</pre><p>UTC? There you go:</p><pre>SELECT date(&#39;now&#39;, &#39;start of month&#39;, &#39;+7 days&#39;, &#39;weekday 3&#39;, &#39;utc&#39;);</pre><p>And we’ve barely covered date/time functions here.</p><p>The extension mechanism is also worth noting. While the SQLite base is relatively small and robust, it can be easily extended with endless functionalities. Open-source extensions (e.g. <a href="https://github.com/nalgeon/sqlean">sqlean</a>) range from additional math functions, through complex data structures, supporting different storage formats, AI integration like embeddings or vector search, replication, CRDT, and countless more features.</p><p>libSQL also extends the vanilla SQLite interface with <a href="https://blog.chiselstrike.com/webassembly-functions-for-your-sqlite-compatible-database-7e1ad95a2aa7">WebAssembly user-defined functions</a>, which gives users even more flexibility.</p><h3>It can be Wasm!!</h3><p>SQLite, as well as libSQL, can be compiled into a concise Wasm module — just 390 KiB compressed, less than 900 KiB uncompressed size. It can run a fully-fledged in-memory SQL engine, but that’s not all! It’s also capable of persisting the data in your browser’s localStorage, or OPFS — Origin Private File System — which is a modern approach for providing a private filesystem for web applications.. You can <a href="https://playground.libsql.org">try the demo</a> to get a feel for how it works.</p><p>But WebAssembly goes way beyond browsers, and so does SQLite. Recent releases compile to WASI — a modular system interface for WebAssembly. That opens the whole new world of possibilities, making SQLite feasible for edge environments that run serverless functions in the form of Wasm modules — <a href="https://www.fermyon.com/spin">Fermyon Spin</a>, <a href="https://workers.cloudflare.com/">Cloudflare Workers</a>, <a href="https://scale.sh">scale.sh</a>.</p><h3>What’s next?</h3><p>SQLite has great potential for the edge. Our fork — libSQL — is both open source and open contribution, and we aim to evolve it to suit many more use cases than SQLite was originally designed for, including edge environments — like <a href="https://turso.tech/">Turso</a>, our edge-native database. We are a community effort, so feel encouraged to become a contributor. Oh, and <a href="https://github.com/libsql/libsql">star us</a> on GitHub!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ee00a3a9a55f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/chiselstrike/why-sqlite-is-so-great-for-the-edge-ee00a3a9a55f">Why SQLite is so great for the edge</a> was originally published in <a href="https://medium.com/chiselstrike">Turso blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[WebAssembly triggers in libSQL]]></title>
            <link>https://medium.com/chiselstrike/webassembly-triggers-in-libsql-b5eb62cc1c6?source=rss-624320382cf0------2</link>
            <guid isPermaLink="false">https://medium.com/p/b5eb62cc1c6</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[webassembly]]></category>
            <category><![CDATA[rust]]></category>
            <category><![CDATA[database]]></category>
            <category><![CDATA[sqlite]]></category>
            <dc:creator><![CDATA[Piotr Sarna]]></dc:creator>
            <pubDate>Tue, 10 Jan 2023 14:42:22 GMT</pubDate>
            <atom:updated>2023-02-03T18:58:58.058Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="Sample SQL trigger definition" src="https://cdn-images-1.medium.com/max/1024/0*XeE9J3U-Gk9L4zrn" /></figure><p>User-defined WebAssembly functions in libSQL can be used to create powerful triggers, making it easy to automate your workflows.</p><p>The <a href="https://github.com/libsql/libsql/releases/tag/libsql-0.1.0">first official release</a> of libSQL, our open-contribution fork of SQLite, brought the ability to dynamically create <a href="https://blog.chiselstrike.com/webassembly-functions-for-your-sqlite-compatible-database-7e1ad95a2aa7">WebAssembly-powered user-defined functions</a>. That’s an exciting feature on its own, but combined with database triggers, they become a powerful building block for automating your workflows.</p><h3>Database triggers</h3><p>Database triggers are an ancient feature in the database world, implemented in most products, and libSQL is no exception. A trigger is simply a stored procedure, which fires automatically when a specific event happens in the database. In libSQL (and SQLite), the following actions can activate a trigger:</p><ul><li>INSERT</li><li>UPDATE</li><li>DELETE</li></ul><p>Moreover, the trigger can be set up to execute before, after, or instead of the original action, with a few restrictions.</p><p>The syntax of the CREATE TRIGGER statement is very expressive:</p><pre>CREATE [TEMP|TEMPORARY] TRIGGER [IF NOT EXISTS] trigger<br>    [BEFORE|AFTER|INSTEAD OF]<br>    [INSERT|UPDATE OF [column_name*]|DELETE]<br>  ON table_name<br>    [FOR EACH ROW] [WHEN condition]<br>BEGIN<br>  [statement*];<br>END;</pre><p>But worry not, we’ll go through a few simple examples.</p><h3>WebAssembly user-defined functions</h3><p>libSQL 0.1.0 allows users to create user-defined functions not only programmatically, but also with the CREATE FUNCTION statement, well known in the world of SQL.</p><p>WebAssembly was chosen due to its robustness, portability and security, as well as performance. As was explained in <a href="https://blog.chiselstrike.com/webassembly-functions-for-your-sqlite-compatible-database-7e1ad95a2aa7">our previous article</a>, WebAssembly user-defined functions can be easily implemented in Rust with the help of <a href="https://crates.io/crates/libsql_bindgen">libsql_bindgen</a> library. To make it even more ergonomic, we host an interactive <a href="https://bindgen.libsql.org/">libSQL bindgen</a> app — you can also deploy your own mirror from our <a href="https://github.com/libsql/libsql_generate">repository</a>.</p><h3>Use case: users management</h3><p>In this example, we’ll implement a database flow for creating new user records, making sure that their passwords are not stored in plaintext. We’ll rely on database triggers powered by WebAssembly user-defined functions to automate the work, offloading the complexity to the database layer.</p><p>Later, we’ll also introduce email verification based on sending single-use tokens sent to the users.</p><p>Here’s a diagram of the flow implemented in this post:</p><figure><img alt="Data flow diagram of managing a new user account" src="https://cdn-images-1.medium.com/max/622/0*krrbekZCxLRW4SUC" /></figure><p>The users table is defined with the following schema:</p><pre>CREATE TABLE users(<br>  user TEXT PRIMARY KEY,<br>  email TEXT,<br>  pass TEXT<br>);</pre><h3>Encrypting user passwords</h3><p>The first part of the workflow is to save passwords in an encrypted form instead of plaintext. Let’s create a table with secret values, used to encrypt the passwords of newly created users:</p><pre>CREATE TABLE secrets(secret text);<br>INSERT INTO secrets VALUES (&#39;s3cretk3y&#39;);</pre><p>Next, we need an encryption function. Here’s where WebAssembly user-defined functions become useful. With <a href="https://bindgen.libsql.org/">libSQL bindgen</a>, the following Rust snippet can be compiled to Wasm and registered as a user-defined function called encrypt:</p><pre>pub fn encrypt(data: String, key: String) -&gt; String {<br>  use magic_crypt::MagicCryptTrait;<br>  let mc = magic_crypt::new_magic_crypt!(key, 256);<br>  mc.encrypt_str_to_base64(data)<br>}</pre><p>Save the generated SQL to a local file and load it in libsql shell by calling .read &lt;path-to-your-file&gt; and voilà, the function is registered! You can also try copy-pasting the SQL right into libsql shell.</p><p>With the secrets and the encrypt() function available, our first trigger can be created like this:</p><pre>CREATE TRIGGER encrypt_pass AFTER INSERT ON users<br>  BEGIN<br>    UPDATE users<br>      SET pass = encrypt(<br>        new.pass,<br>        (SELECT secret FROM secrets LIMIT 1)<br>      )<br>  WHERE user = new.user;<br>END;</pre><p>Immediately after a new row is inserted into users, the provided value for pass is replaced with the encrypted value using the result of the function. The encryption function takes two parameters: the password, and the value of today’s secret key, selected from the secrets table we previously created.</p><h3>Verifying the trigger</h3><p>In order to check if encryption works, a corresponding function to perform description would be quite handy. Here’s it source code, which you again send to bindgen to generate the code for a UDF:</p><pre>pub fn decrypt(data: String, key: String) -&gt; String {<br>  use magic_crypt::MagicCryptTrait;<br>  let mc = magic_crypt::new_magic_crypt!(key, 256);<br>  mc.decrypt_base64_to_string(data)<br>    .unwrap_or_else(|_| &quot;[ACCESS DENIED]&quot;.to_string())<br>}</pre><p>Let’s check if the trigger works by adding a few entries to the table and inspecting its contents:</p><pre>INSERT INTO users VALUES (<br>  &#39;peter&#39;,<br>  &#39;peter@chiselstrike.com&#39;,<br>  &#39;roe-deer&#39;<br>); <br><br>INSERT INTO users VALUES (<br>  &#39;iku&#39;,<br>  &#39;iku@chiselstrike.com&#39;,<br>  &#39;turso&#39;<br>);<br><br>SELECT user, pass, decrypt(<br>    pass,<br>    (SELECT secret FROM secrets LIMIT 1)<br>  ) AS decrypted<br>  FROM users;<br><br>user   pass                      decrypted<br>-----  ------------------------  ---------<br>peter  1mXVhOvX0YWGHcfEYCvqgg==  roe-deer <br>iku    GeJmXZujKUJbRai+S/4cBA==  turso <br><br>SELECT user, pass, decrypt(<br>    pass,<br>    &#39;incorrect-pass&#39;<br>  ) AS decrypted<br>  FROM users;<br><br>user   pass                      decrypted      <br>-----  ------------------------  ---------------<br>peter  1mXVhOvX0YWGHcfEYCvqgg==  [ACCESS DENIED]<br>iku    GeJmXZujKUJbRai+S/4cBA==  [ACCESS DENIED]</pre><p>Perfect — the passwords are stored in their encrypted form, but they can still be decoded with the proper key.</p><h3>Email verification</h3><p>But we’re not done exploring the capabilities of Wasm triggers, far from it! In the next step, we’ll harden the user management flow by generating a unique single-use token for each user and putting it in a separate table. Later, entries from this table can be processed by an external program which sends a message to each newly created user, asking them to confirm their email by submitting the token generated just for them.</p><p>The table prepared for storing single-use tokens has the following schema:</p><pre>CREATE TABLE tokens(<br>  user text PRIMARY KEY,<br>  date text,<br>  token text<br>);</pre><p>Here’s a Rust implementation of the single_use_token function, which accepts a username and current time as arguments, and returns the generated token:</p><pre>pub fn single_use_token(user: String, seed: u64) -&gt; String {<br>  use rand::{Rng, SeedableRng};<br>  use std::hash::{Hash, Hasher};<br>  let mut hasher = std::collections::hash_map::DefaultHasher::new();<br>  let hash = user.hash(&amp;mut hasher);<br>  let token = rand::rngs::StdRng::seed_from_u64(seed + hasher.finish())<br>              .gen::&lt;u64&gt;();<br>  format!(&quot;{:x}&quot;, token)<br>}</pre><p>And now, the password-encrypting trigger we created in the previous paragraph can be boosted with another action — notice that multiple operations can be performed by a single trigger, so we can just drop the previous one and replace it with a new one:</p><pre>DROP TRIGGER IF EXISTS encrypt_pass;<br>CREATE TRIGGER encrypt_pass_and_generate_token<br>    AFTER INSERT ON users<br>    BEGIN<br>        UPDATE users<br>            SET pass = encrypt(<br>                new.pass,<br>                (SELECT secret FROM secrets LIMIT 1)<br>            )<br>            WHERE user = new.user;<br>        INSERT INTO tokens VALUES (<br>            new.user,<br>            date(),<br>            single_use_token(new.user, unixepoch())<br>        );<br>    END;</pre><h3>Verification in practice</h3><p>Finally, let’s verify that a single-use token was indeed generated and inserted into the tokens table.</p><pre>INSERT INTO users VALUES (<br>  &#39;wojtek&#39;,<br>  &#39;wojtek@ii_corps.pl&#39;,<br>  &#39;the bear&#39;<br>);<br><br>SELECT * FROM tokens WHERE user = &#39;wojtek&#39;;<br>user    date        token   <br>------  ----------  ----------------<br>wojtek  2022-12-16  48e2873b1c5d861b</pre><h3>Summary</h3><p>WebAssembly integration brought portable and secure user-defined functions to libSQL in its <a href="https://github.com/libsql/libsql/releases/tag/libsql-0.1.0">first official release</a>. They are useful not only for queries, but also as building blocks for database triggers. With the help of both features, more business logic can be pushed to the database layer, with computations performed closer to the data. This improves performance, security, and level of control over your data.</p><p>Read more about WebAssembly user-defined functions in our <a href="https://blog.chiselstrike.com/webassembly-functions-for-your-sqlite-compatible-database-7e1ad95a2aa7">previous blog post</a>. If you want to get started working with libSQL, you can jump into our <a href="https://github.com/libsql/libsql">GitHub repo</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b5eb62cc1c6" width="1" height="1" alt=""><hr><p><a href="https://medium.com/chiselstrike/webassembly-triggers-in-libsql-b5eb62cc1c6">WebAssembly triggers in libSQL</a> was originally published in <a href="https://medium.com/chiselstrike">Turso blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[WebAssembly functions for your SQLite-compatible database]]></title>
            <link>https://medium.com/chiselstrike/webassembly-functions-for-your-sqlite-compatible-database-7e1ad95a2aa7?source=rss-624320382cf0------2</link>
            <guid isPermaLink="false">https://medium.com/p/7e1ad95a2aa7</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[webassembly]]></category>
            <category><![CDATA[sqlite]]></category>
            <category><![CDATA[database]]></category>
            <category><![CDATA[software-engineering]]></category>
            <dc:creator><![CDATA[Piotr Sarna]]></dc:creator>
            <pubDate>Wed, 23 Nov 2022 13:54:33 GMT</pubDate>
            <atom:updated>2023-01-06T02:00:43.072Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="Sample WebAssembly function definition" src="https://cdn-images-1.medium.com/max/1024/1*AHny-voQs8foatVwrpP5Qg.png" /></figure><h4>With the first official release of libSQL, it is possible to execute user defined functions (UDF) written in WebAssembly.</h4><p>A while back, we announced that we were <a href="https://itnext.io/sqlite-qemu-all-over-again-aedad19c9a1c">forking SQLite</a>, into a project called <a href="https://libsql.org/">libSQL</a>. While we love SQLite, we respectfully disagree (even if we understand) with their focus on being fully public domain with no 3rd party code and rarely accepting contributions.</p><p>Our goal was to create a community of database enthusiasts that want to explore other directions that could be taken for an OLTP-oriented embedded database if SQLite would be more open, while standing on the shoulders of giants, as we all should aspire to do.</p><p>We started by just stating our intentions, in order to signal that we’d be willing to look into contributions that expand the scope of the project to support a variety of needs of the SQLite community.</p><p>But intentions are just a start. We finally hit the first major <a href="https://github.com/libsql/libsql/releases/tag/libsql-0.1.0">milestone</a>. In this article we’ll explore the result: WebAssembly user-defined functions.</p><h4>User-defined functions (UDFs)</h4><p>SQLite supports user-defined functions. UDFs in SQLite works by allowing users to provide a piece of C code that will be executed directly into the data, performing some in-statement computation.</p><p>For example, you could define a function to calculate a hash of a particular string, and then obtain hashes for all values in a column col from a table table by writing:</p><pre>SELECT hash(col) from table;</pre><p>In an over-the-network database like Postgres, not using UDFs means that before any computation can be performed, the client needs to first fetch the data. This can be very wasteful.</p><p>For an embedded database, there is no network activity involved in fetching this data (although we are also exploring changing that). Still, using UDFs, as opposed to materializing the data and then transforming, can avoid memory copies and extra passes, resulting in faster code.</p><h4>A more convenient API</h4><p>The first problem is that in the original SQLite, UDFs are available through the C API or its derivatives, which means that they can only be registered programmatically. The SQL layer is what is ultimately exposed, so that’s where we should aim for function registration to live.</p><p>Many projects like <a href="https://github.com/rqlite/rqlite">rqlite</a>, <a href="https://dqlite.io/">dqlite</a>, <a href="https://github.com/losfair/mvsqlite">mvsqlite</a>, do try to push the boundaries, and add network functions around SQLite, which is one more point in favor of function manipulation at the statement level, as opposed to the low-level C API.</p><p>That’s why other SQL databases customarily offer a CREATE FUNCTION statement, and we want one as well. CREATE FUNCTION statements would be a perfect gateway for users to add their specific logic to the database.</p><h4>The choice of language</h4><p>Aside from not being available from the SQL statements, the SQLite function API expects you to register a pointer to a C function. With the help of your driver, that doesn’t mean that you have to write your function in C: your language of choice likely has a C <a href="https://en.wikipedia.org/wiki/Foreign_function_interface">FFI</a>. The driver just has to provide C bindings to your functions.</p><p>That is easy from the programmatic interface from a single-language driver. But if we want this to work from the SQL statements in a consistent way, we need a language that is cross platform enough so that it will work with any driver.</p><p>It <em>could</em> be C. But for a large contingent of our industry, we’re usually talking about higher level languages like go, ruby, or TypeScript. Even in the domain of systems programming, historically a stronghold of C and C++, Zig and Rust are rapidly gaining momentum.</p><h4>WebAssembly</h4><p>Thankfully, there is a language, also gaining rapid momentum across different ecosystems, that is a great fit for user-defined functions: WebAssembly.</p><p>One of its core foundations is isolation, which is essential for running untrusted code on your own machines. It also ticks all the other boxes:</p><ul><li>thriving open-source community</li><li>robustness</li><li>portability</li><li>performance</li><li>sandboxing</li></ul><p>You don’t actually have to <em>write</em> your code directly into WebAssembly. It is a common compile target for many modern languages, such as Rust and Zig.</p><p>There are multiple WebAssembly runtimes to choose from, including Google’s <a href="https://v8.dev/">V8</a>, <a href="https://wasmtime.dev/">Wasmtime</a>, <a href="http://wasmer.io/">Wasmer</a>, <a href="https://wasmedge.org/">WasmEdge</a> and many others.</p><p>The language is publicly specified. So, true to the original SQLite’s approach, it would not be <em>impossible</em> to write an entire new WebAssembly runtime into SQLite. But we believe there are benefits to keeping to the existing runtimes, and for libSQL, we will just integrate.</p><h3>Show me how!</h3><p>We will now go through a full example of how to run an encryption routine as a UDF with libSQL.</p><p>In order to run WebAssembly user-defined functions in libSQL, the first step is to get the latest libSQL release.</p><h4>Get the latest release</h4><p>Release artifacts for x86_64 Linux can be downloaded from the official <a href="https://github.com/libsql/libsql/releases/tag/libsql-0.1.0">release page</a>.</p><p>The release is also available in a <a href="https://github.com/libsql/libsql/blob/main/Dockerfile-wasm-udf">container</a>. To run the shell, use the following command:</p><pre>docker run -it piotrsarna/libsql:libsql-0.1.0-wasm-udf ./libsql</pre><p>The <a href="https://github.com/libsql/libsql/">source code</a> is available on GitHub.</p><h4>Compiling your first function</h4><p>The first step is to compile your code into a WebAssembly binary. You can then load a file containing the WebAssembly binary, or even add the resulting binary blob straight into the SQL statement.</p><p>For this example we will write our code in Rust. Your code can do pretty much any computations, as long as it doesn’t try to access system resources (including time/date and sources for entropy for pseudorandom number generation), use the network, and so on — that’s something that WebAssembly isolation rules will prevent.</p><p>In addition to WebAssembly isolation rules, we require that you limit the function parameters and return type to something that both WebAssembly and libSQL can handle, specifically, for our Rust example:</p><ul><li>Any primitive integer type for libSQL’s INTEGER type</li><li>f32 or f64for libSQL’s REAL type</li><li>String or &amp;str for libSQL’s TEXT type</li><li>Vec&lt;u8&gt; for libSQL’s BLOB type</li></ul><p>To make this process easier, we provide a crate, <a href="https://crates.io/crates/libsql_bindgen">libsql_bindgen</a>. It allows you to add the #[libsql_bindgen] macro to a Rust function, making sure all types in the function signature are transformed the the types libSQL understands.</p><h4>Enjoying our playground</h4><p>If you’re not feeling like doing this all manually, that’s okay: we deliver all the tools to make the experience as smooth as possible, at our playground <a href="https://bindgen.libsql.org/">bindgen</a>.</p><p>Navigate there and click the “Generate” button. Now paste the resulting SQL statement right into the libSQL shell.</p><h4>Calling your first function</h4><p>For this example, let’s compile the following Rust function, using bindgen:</p><pre>pub fn decrypt(data: String, key: String) -&gt; String {<br>  use magic_crypt::MagicCryptTrait;<br>  let mc = magic_crypt::new_magic_crypt!(key, 256);<br>  mc.decrypt_base64_to_string(data)<br>      .unwrap_or(&quot;[ACCESS DENIED]&quot;.to_owned())<br>}</pre><p>Start by launching the libSQL shell:</p><pre>./libsql</pre><p>As a next step, let’s instantiate the functions and create a demo table with some data we want encrypted. Note that we will paste the statements as blobs, by clicking “as binary blob” in the bindgen playground. That is just to allow a more compact representation.</p><pre>.init_wasm_func_table<br>DROP FUNCTION IF EXISTS encrypt;<br>CREATE FUNCTION encrypt LANGUAGE wasm AS X&#39;0061736d0100000001410b60037f7f7f017f60027f7f017f60037f7f7f0060017f0060027f7f0060057f7f7f7f7f017f60057f7f7f7f7f0060017f017f60000060027e7f017f60017f017e033c3b0403070302040203020804010109050201010501010101030a010502000201010102020600010100010100010101020403030103020406060400000405017001181805030100110619037f01418080c0000b7f0041a49ac0000b7f0041b09ac0000b072f04066d656d6f7279020007656e637279707400320a5f5f646174615f656e6403010b5f5f686561705f626173650302091d010041010b171911132b0b10161e1f2c1718242526272829301417152d0ab88b023b940504017f017f017f017f200020016a2102024002400240200028020422034101710d002003410371450d012000280200220320016a2101200020036b220041f499c00028020046044020022802044103714103470d0141ec99c000200136020020022002280204417e7136020420002001410172360204200220013602000f0b20034180024f0440200010010c010b2000410c6a2802002204200041086a28020022054704402005200436020c200420053602080c010b41dc96c00041dc96c000280200417e200341037677713602000b20022802042203410271044020022003417e7136020420002001410172360204200020016a20013602000c020b024041f899c0002802002002470440200241f499c000280200470d0141f499c000200036020041ec99c00041ec99c00028020020016a220136020020002001410172360204200020016a20013602000f0b41f899c000200036020041f099c00041f099c00028020020016a220136020020002001410172360204200041f499c000280200470d0141ec99c000410036020041f499c00041003602000f0b2003417871220420016a2101024020044180024f0440200210010c010b2002410c6a2802002204200241086a28020022024704402002200436020c200420023602080c010b41dc96c00041dc96c000280200417e200341037677713602000b20002001410172360204200020016a2001360200200041f499c000280200470d0141ec99c00020013602000b0f0b20014180024f04402000200110380f0b200141787141e496c0006a2102027f41dc96c00028020022034101200141037674220171044020022802080c010b41dc96c000200120037236020020020b2101200220003602082001200036020c2000200236020c200020013602080bbb0205017f017f017f017f017f20002802182104024002402000200028020c2201460440200041144110200041146a220128020022031b6a28020022020d01410021010c020b20002802082202200136020c200120023602080c010b2001200041106a20031b21030340200321052002220141146a22032802002202450440200141106a2103200128021021020b20020d000b200541003602000b02402004450d0002402000200028021c41027441ec98c0006a220228020047044020044110411420042802102000461b6a200136020020010d010c020b2002200136020020010d0041e096c00041e096c000280200417e200028021c77713602000f0b2001200436021820002802102202044020012002360210200220013602180b200041146a2802002200450d00200141146a2000360200200020013602180b0b9d1f09017f017f017f017f017f017f017f017f017e02400240024002400240200041f5014f0440200041cdff7b4f0d042000410b6a2200417871210341e096c0002802002208450d03410020036b2102027f41002003418002490d001a411f200341ffffff074b0d001a2003410620004108766722006b7641017120004101746b413e6a0b220741027441ec98c0006a2802002200044020034100411920074101766b411f712007411f461b74210503400240200028020441787122062003490d00200620036b220620024f0d0020002104200622020d00410021020c040b200041146a28020022062001200620002005411d764104716a41106a2802002200471b200120061b21012005410174210520000d000b20010440200121000c030b20040d030b41002104200841022007742200410020006b72712200450d032000410020006b716841027441ec98c0006a28020022000d010c030b024002400240027f0240024041dc96c000280200220141102000410b6a4178712000410b491b22034103762202762200410371450440200341ec99c0002802004d0d0920000d0141e096c0002802002200450d092000410020006b716841027441ec98c0006a280200220428020441787120036b210120042802102200450440200441146a28020021000b200004400340200028020441787120036b220620014921052006200120051b21012000200420051b210420002802102202047f200205200041146a2802000b22000d000b0b2004100120014110490d0520042003410372360204200320046a22032001410172360204200120036a200136020041ec99c0002802002205450d04200541787141e496c0006a210041f499c000280200210241dc96c00028020022064101200541037674220571450d0220002802080c030b02402000417f7341017120026a2200410374220341ec96c0006a280200220241086a22052802002204200341e496c0006a22034704402004200336020c200320043602080c010b41dc96c0002001417e200077713602000b200220004103742200410372360204200020026a2200200028020441017236020420050f0b024041022002411f712202742204410020046b722000200274712200410020006b71682202410374220541ec96c0006a280200220041086a22062802002204200541e496c0006a22054704402004200536020c200520043602080c010b41dc96c0002001417e200277713602000b20002003410372360204200020036a22052002410374220120036b2204410172360204200020016a200436020041ec99c00028020022010440200141787141e496c0006a210041f499c0002802002102027f41dc96c00028020022034101200141037674220171044020002802080c010b41dc96c000200120037236020020000b2101200020023602082001200236020c2002200036020c200220013602080b41f499c000200536020041ec99c000200436020020060f0b41dc96c000200520067236020020000b2105200020023602082005200236020c2002200036020c200220053602080b41f499c000200336020041ec99c00020013602000c010b2004200120036a2200410372360204200020046a220020002802044101723602040b0c040b0340200020042000280204417871220120034f200120036b22062002497122051b21042006200220051b210220002802102201047f200105200041146a2802000b22000d000b2004450d010b200341ec99c00028020022004d2002200020036b4f710d00200410010240200241104f044020042003410372360204200320046a22012002410172360204200120026a200236020020024180024f04402001200210380c020b200241787141e496c0006a2100027f41dc96c00028020022034101200241037674220271044020002802080c010b41dc96c000200220037236020020000b2102200020013602082002200136020c2001200036020c200120023602080c010b2004200220036a2200410372360204200020046a220020002802044101723602040b0c020b0240024002400240024002400240024002400240200341ec99c00028020022014b044041f099c000280200220020034b0d0441002102200341af80046a220041107640002201417f4622050d0b20014110742204450d0b41fc99c000410020004180807c7120051b220541fc99c0002802006a220036020041809ac00041809ac0002802002201200020002001491b36020041f899c0002802002202450d0141849ac0002100034020002802002201200028020422066a2004460d03200028020822000d000b0c030b41f499c00028020021000240200120036b2202410f4d044041f499c000410036020041ec99c000410036020020002001410372360204200020016a220120012802044101723602040c010b41ec99c000200236020041f499c000200020036a220436020020042002410172360204200020016a2002360200200020034103723602040b200041086a0f0b41989ac000280200220045200020044b720d030c070b200028020c200120024b720d0020022004490d030b41989ac00041989ac0002802002200200420002004491b360200200420056a210141849ac000210002400240034020012000280200470440200028020822000d010c020b0b200028020c450d010b41849ac0002100034002402002200028020022014f0440200120002802046a220620024b0d010b200028020821000c010b0b41f899c000200436020041f099c000200541286b220036020020042000410172360204200020046a412836020441949ac00041808080013602002002200641206b41787141086b22002000200241106a491b2201411b36020441849ac0002902002109200141106a418c9ac0002902003702002001200937020841889ac000200536020041849ac0002004360200418c9ac000200141086a36020041909ac00041003602002001411c6a2100034020004107360200200041046a22002006490d000b20012002460d0720012001280204417e713602042002200120026b22004101723602042001200036020020004180024f04402002200010380c080b200041787141e496c0006a2101027f41dc96c00028020022044101200041037674220071044020012802080c010b41dc96c000200020047236020020010b2100200120023602082000200236020c2002200136020c200220003602080c070b200020043602002000200028020420056a360204200420034103723602042001200320046a22056b210341f899c0002802002001470440200141f499c000280200460d04200128020422024103714101470d050240200241787122004180024f0440200110010c010b2001410c6a2802002206200141086a28020022074704402007200636020c200620073602080c010b41dc96c00041dc96c000280200417e200241037677713602000b200020036a2103200020016a220128020421020c050b41f899c000200536020041f099c00041f099c00028020020036a2200360200200520004101723602040c080b41f099c000200020036b220136020041f899c00041f899c000280200220020036a22023602002002200141017236020420002003410372360204200041086a21020c060b41989ac00020043602000c030b2000200520066a36020441f899c00041f899c0002802002200410f6a417871220141086b36020041f099c00041f099c00028020020056a2202200020016b6a41086a2204360200200141046b2004410172360200200020026a412836020441949ac00041808080013602000c030b41f499c000200536020041ec99c00041ec99c00028020020036a220036020020052000410172360204200020056a20003602000c040b20012002417e7136020420052003410172360204200320056a200336020020034180024f04402005200310380c040b200341787141e496c0006a2100027f41dc96c00028020022014101200341037674220271044020002802080c010b41dc96c000200120027236020020000b2103200020053602082003200536020c2005200036020c200520033602080c030b419c9ac00041ff1f36020041889ac000200536020041849ac000200436020041f096c00041e496c00036020041f896c00041ec96c00036020041ec96c00041e496c000360200418097c00041f496c00036020041f496c00041ec96c000360200418897c00041fc96c00036020041fc96c00041f496c000360200419097c000418497c000360200418497c00041fc96c000360200419897c000418c97c000360200418c97c000418497c00036020041a097c000419497c000360200419497c000418c97c00036020041a897c000419c97c000360200419c97c000419497c00036020041909ac000410036020041b097c00041a497c00036020041a497c000419c97c00036020041ac97c00041a497c00036020041b897c00041ac97c00036020041b497c00041ac97c00036020041c097c00041b497c00036020041bc97c00041b497c00036020041c897c00041bc97c00036020041c497c00041bc97c00036020041d097c00041c497c00036020041cc97c00041c497c00036020041d897c00041cc97c00036020041d497c00041cc97c00036020041e097c00041d497c00036020041dc97c00041d497c00036020041e897c00041dc97c00036020041e497c00041dc97c00036020041f097c00041e497c00036020041f897c00041ec97c00036020041ec97c00041e497c000360200418098c00041f497c00036020041f497c00041ec97c000360200418898c00041fc97c00036020041fc97c00041f497c000360200419098c000418498c000360200418498c00041fc97c000360200419898c000418c98c000360200418c98c000418498c00036020041a098c000419498c000360200419498c000418c98c00036020041a898c000419c98c000360200419c98c000419498c00036020041b098c00041a498c00036020041a498c000419c98c00036020041b898c00041ac98c00036020041ac98c00041a498c00036020041c098c00041b498c00036020041b498c00041ac98c00036020041c898c00041bc98c00036020041bc98c00041b498c00036020041d098c00041c498c00036020041c498c00041bc98c00036020041d898c00041cc98c00036020041cc98c00041c498c00036020041e098c00041d498c00036020041d498c00041cc98c00036020041e898c00041dc98c00036020041dc98c00041d498c00036020041f899c000200436020041e498c00041dc98c00036020041f099c000200541286b220036020020042000410172360204200020046a412836020441949ac00041808080013602000b4100210241f099c000280200220020034d0d0041f099c000200020036b220136020041f899c00041f899c000280200220020036a22023602002002200141017236020420002003410372360204200041086a0f0b20020f0b200441086a0ba70705017f017f017f017f017f200041086b2201200041046b280200220341787122006a210202400240024020034101710d002003410371450d012001280200220320006a2100200120036b220141f499c00028020046044020022802044103714103470d0141ec99c000200036020020022002280204417e7136020420012000410172360204200020016a20003602000f0b20034180024f0440200110010c010b2001410c6a2802002204200141086a28020022054704402005200436020c200420053602080c010b41dc96c00041dc96c000280200417e200341037677713602000b024020022802042203410271044020022003417e7136020420012000410172360204200020016a20003602000c010b02400240024041f899c0002802002002470440200241f499c000280200470d0141f499c000200136020041ec99c00041ec99c00028020020006a220036020020012000410172360204200020016a20003602000f0b41f899c000200136020041f099c00041f099c00028020020006a220036020020012000410172360204200141f499c000280200460d010c020b2003417871220420006a2100024020044180024f0440200210010c010b2002410c6a2802002204200241086a28020022024704402002200436020c200420023602080c010b41dc96c00041dc96c000280200417e200341037677713602000b20012000410172360204200020016a2000360200200141f499c000280200470d0241ec99c00020003602000c030b41ec99c000410036020041f499c00041003602000b41949ac000280200220320004f0d0141f899c0002802002202450d0141002101024041f099c00028020022044129490d0041849ac000210003402002200028020022054f0440200520002802046a20024b0d020b200028020822000d000b0b418c9ac000280200220004400340200141016a2101200028020822000d000b0b419c9ac000200141ff1f200141ff1f4b1b360200200320044f0d0141949ac000417f3602000f0b2000418002490d0120012000103841002101419c9ac000419c9ac00028020041016b220036020020000d00418c9ac000280200220004400340200141016a2101200028020822000d000b0b419c9ac000200141ff1f200141ff1f4b1b3602000f0b0f0b200041787141e496c0006a2102027f41dc96c00028020022034101200041037674220071044020022802080c010b41dc96c000200020037236020020020b2100200220013602082000200136020c2001200236020c200120003602080bbc030d017f017f017f017f017f017f017f017f017f017f017f017f017f2000200228000c2203200128000c22044101767341d5aad5aa05712208200373220320022800082205200128000822064101767341d5aad5aa0571220920057322054102767341b3e6cc990371220b2003732203200228000422072001280004220a4101767341d5aad5aa0571220c200773220720022800002202200128000022014101767341d5aad5aa0571220d20027322024102767341b3e6cc990371220e200773220741047673418f9ebcf80071220f20037336021c200020042008410174732203200620094101747322044102767341b3e6cc99037122082003732203200a200c4101747322062001200d4101747322014102767341b3e6cc9903712209200673220641047673418f9ebcf80071220a2003733602182000200b4102742005732203200e410274200273220241047673418f9ebcf8007122052003733602142000200f41047420077336020c2000200841027420047322032009410274200173220141047673418f9ebcf8007122042003733602102000200a41047420067336020820002005410474200273360204200020044104742001733602000b7a02017f017f200141076a2102200020014102746a210041202101024002400340200241f7004b0d02200241086a41f8004f0d01200020016a2203411c6a200341046b280200360200200241016b2102200141046b22010d000b0f0b200241086a41f80041bc81c0001006000b200241f80041ac81c0001006000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c200341ac85c000360208200341013602242003200341206a360218200320033602282003200341046a360220200341086a2002100a000bd7041c017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f2000200028021c220120002802042205732209200028021022032000280208220673220f732210200028020c732207200673220b201071220a20072000280218220c73220473200b200028020022077322172005200c200028021473220220077322057322162001200673220c73221371732002200b73220d200420012003732211732206732214200f712006201171220873220473221220042005201671200920022006732204727373220e712202200c200d71200873220820032005732218200771200c73200d73200a7373220a73200e200620077322192001200573221a7120042009417f737120017373200873220373712208200273200371221520022003732201732001200a201273220271200a732201712002732202200e201573220e2003200873220373220a73220820012003732212732215200f712011201271220f732211200a201371732213200e20107173221020042001200273220471221b200220057173221c201420157173221420062012717322057336021c20002008200d7120042009712206200b200e712209200320077173220b7373201473220d2001201a717322042008200c71200f73200573733602142000200a201771200973201c732010732207360210200020132003201871732004733602082000200b200120197173201b7322012011200220167173732209200d7336020420002006200973360200200020052007733602182000200120077336020c0bbf0103017f017f017f410041f80020016b2203200341f8004b1b2105200141027420006a41406a2100024002400340200120046a220341106b41f7004b0d0220042005460d01200041406b2203200028020020032802002002784183868c187173220341027441fcf9f36771200373200341047441f0e1c3877f7173200341067441c08183867c7173360200200041046a2100200441016a22044108470d000b0f0b200341f800419c81c0001006000b200341106b41f800418c81c0001006000b3f01017f230041206b220024002000411c6a4100360200200041fc95c0003602182000420137020c200041fc81c000360208200041086a418482c000100a000bd20101017f230041206b22022400200241013a00182002200136021420022000360210200241c485c00036020c200241fc95c000360208230041106b22002400200241086a2201280208220245044041fc95c000412b41c496c000101d000b2000200128020c3602082000200136020420002002360200230041106b22012400200141086a200041086a280200360200200120002902003703002001280200220041146a28020021020240024020002802040e020000010b20020d0020012802042d00101031000b20012802042d00101031000bc10308017f017f017f017f017f017f017f017f230041406a220224002000280200220041086a280200210620002802002103200141186a2207280200419686c00041012001411c6a220828020028020c110000210020060440410121040340200041ff0171210541012100024020050d000240024002400240200128020022094104714504402004410171450d010c040b20044101710d0120082802002104200728020021050c020b2007280200418986c0004102200828020028020c110000450d020c030b20072802002205419586c00041012008280200220428020c1100000d020b200241013a00172002200436020c2002200536020820022009360218200241e885c000360234200220012d00203a00382002200128020436021c20022001290210370328200220012902083703202002200241176a3602102002200241086a3602302003200241186a100c4504402002280230418786c0004102200228023428020c11000021000c020b0c010b20032001100c21000b200341016a210341002104200641016b22060d000b0b410121032000450440200141186a280200419786c00041012001411c6a28020028020c11000021030b200241406b240020030bbc0203017f017f017f23004180016b2204240002400240027f02402001280200220241107145044020024120710d0120003100002001100d0c020b20002d00002102410021000340200020046a41ff006a413041d7002002410f712203410a491b20036a3a0000200041016b21002002220341047621022003410f4b0d000b20004180016a22024181014f0d02200141c486c0004102200020046a4180016a410020006b100e0c010b20002d00002102410021000340200020046a41ff006a413041372002410f712203410a491b20036a3a0000200041016b21002002220341047621022003410f4b0d000b20004180016a22024181014f0d02200141c486c0004102200020046a4180016a410020006b100e0b210020044180016a240020000f0b200241800141b486c000100f000b200241800141b486c000100f000bce0206017f017f017f017e017f017f230041306b2204240041272102024020004290ce00540440200021050c010b0340200441096a20026a220341046b20004290ce0080220542f0b1037e20007ca7220641ffff037141e4006e220741017441c686c0006a2f00003b0000200341026b2007419c7f6c20066a41ffff037141017441c686c0006a2f00003b0000200241046b2102200042ffc1d72f5621032005210020030d000b0b2005a7220341e3004b0440200241026b2202200441096a6a2005a7220641ffff037141e4006e2203419c7f6c20066a41ffff037141017441c686c0006a2f00003b00000b02402003410a4f0440200241026b2202200441096a6a200341017441c686c0006a2f00003b00000c010b200241016b2202200441096a6a200341306a3a00000b200141fc95c0004100200441096a20026a412720026b100e2101200441306a240020010b820508017f017f017f017f017f017f017f017f20002802002208410171220a20046a210702402008410471450440410021010c010b024020024504400c010b20024103712209450d00200121050340200620052c000041bf7f4a6a2106200541016a2105200941016b22090d000b0b200620076a21070b412b418080c400200a1b210902400240200028020845044041012105200041186a28020022072000411c6a2802002200200920012002101a0d010c020b024002400240024020072000410c6a280200220649044020084108710d04200620076b22062107410120002d0020220520054103461b410371220541016b0e020102030b41012105200041186a28020022072000411c6a2802002200200920012002101a0d040c050b41002107200621050c010b20064101762105200641016a41017621070b200541016a21052000411c6a2802002106200041186a28020021082000280204210002400340200541016b2205450d01200820002006280210110100450d000b41010f0b410121052000418080c400460d0120082006200920012002101a0d01200820032004200628020c1100000d0141002105027f0340200720052007460d011a200541016a2105200820002006280210110100450d000b200541016b0b20074921050c010b2000280204210b2000413036020420002d0020210c41012105200041013a0020200041186a28020022082000411c6a280200220a200920012002101a0d00200620076b41016a210502400340200541016b2205450d0120084130200a280210110100450d000b41010f0b41012105200820032004200a28020c1100000d002000200c3a00202000200b36020441000f0b20050f0b200720032004200028020c1100000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c2003419089c000360208200341013602242003200341206a3602182003200341046a36022820032003360220200341086a2002100a000bf30101017f230041106b220224002002200028020022003602002002200041046a360204200128021841e58cc00041092001411c6a28020028020c1100002100200241003a000d200220003a000c20022001360208200241086a41ee8cc000410b20024102101241f98cc0004109200241046a410310122100027f20022d000c220120022d000d450d001a200141ff01712101410120010d001a200028020022002d00004104714504402000280218418f86c00041022000411c6a28020028020c1100000c010b2000280218418e86c00041012000411c6a28020028020c1100000b2101200241106a2400200141ff01714100470bc70203017f017f017f23004180016b220424002000280200210002400240027f02402001280200220241107145044020024120710d0120003502002001100d0c020b20002802002100410021020340200220046a41ff006a413041d7002000410f712203410a491b20036a3a0000200241016b21022000410f4b21032000410476210020030d000b20024180016a22004181014f0d02200141c486c0004102200220046a4180016a410020026b100e0c010b20002802002100410021020340200220046a41ff006a413041372000410f712203410a491b20036a3a0000200241016b21022000410f4b21032000410476210020030d000b20024180016a22004181014f0d02200141c486c0004102200220046a4180016a410020026b100e0b210020044180016a240020000f0b200041800141b486c000100f000b200041800141b486c000100f000b920307017f017f017f017f017f017e017e230041406a2205240041012107024020002d00040d0020002d000521092000280200220628020022084104714504402006280218418986c000418b86c00020091b4102410320091b2006411c6a28020028020c1100000d01200628021820012002200628021c28020c1100000d01200628021841d485c0004102200628021c28020c1100000d0120032006200411010021070c010b20094504402006280218418486c00041032006411c6a28020028020c1100000d01200628020021080b200541013a0017200541346a41e885c00036020020052008360218200520062902183703082005200541176a3602102006290208210a2006290210210b200520062d00203a00382005200628020436021c2005200b3703282005200a3703202005200541086a220836023020082001200210240d00200541086a41d485c000410210240d002003200541186a20041101000d002005280230418786c0004102200528023428020c11000021070b200041013a0005200020073a0004200541406b240020000b9e0203017f017f017f230041206b22022400027f200028020022032d0000450440200128021841e18cc00041042001411c6a28020028020c1100000c010b410121002002200341016a36020c2002200128021841dd8cc00041042001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a2002410c6a4104102a210320022d00182101024020022802142204450440200121000c010b20010d0020032802002101024020044101470d0020022d0019450d0020012d00004104710d002001280218419486c00041012001411c6a28020028020c1100000d010b200128021841f684c00041012001411c6a28020028020c11000021000b200041ff01714100470b2101200241206a240020010bee0101017f230041106b220224002002200036020020022000410c6a3602042001280218419e82c000410d2001411c6a28020028020c1100002100200241003a000d200220003a000c20022001360208200241086a419482c0004105200241051012419982c0004105200241046a410610122100027f20022d000c220120022d000d450d001a200141ff01712101410120010d001a200028020022002d00004104714504402000280218418f86c00041022000411c6a28020028020c1100000c010b2000280218418e86c00041012000411c6a28020028020c1100000b2101200241106a2400200141ff01714100470b1c00200128021841e884c000410e2001411c6a28020028020c1100000b0e0020002802001a03400c000b000b0300010b0c0042b889cf9789c6d1f84c0b0b0020003502002001100d0b39000240027f2002418080c40047044041012000200220012802101101000d011a0b20030d0141000b0f0b200020032004200128020c1100000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c200341b089c000360208200341013602242003200341206a3602182003200341046a36022820032003360220200341086a2002100a000be50d0b017f017f017f017f017f017f017f017f017f017f017f024002402000280208220a4101472000280210220341014771450440024020034101470d00200120026a2109200041146a28020041016a2107200121040340024020042103200741016b2207450d0020032009460d02027f20032c0000220541004e0440200541ff01712105200341016a0c010b20032d0001413f7121082005411f7121042005415f4d044020044106742008722105200341026a0c010b20032d0002413f7120084106747221082005417049044020082004410c74722105200341036a0c010b2004411274418080f0007120032d0003413f71200841067472722205418080c400460d03200341046a0b2204200620036b6a21062005418080c400470d010c020b0b20032009460d0020032c0000220441004e200441604972200441704972450440200441ff0171411274418080f0007120032d0003413f7120032d0002413f7141067420032d0001413f71410c74727272418080c400460d010b024002402006450d00200220064d04404100210320022006460d010c020b41002103200120066a2c00004140480d010b200121030b2006200220031b21022003200120031b21010b200a450d022000410c6a280200210b024002400240200241104f04402002200141036a417c71220320016b220949200941044b720d02200220096b22084104490d022008410371210a4100210641002104024020012003460d0020094103712105024020032001417f736a4103490440200121030c010b2009417c712107200121030340200420032c000041bf7f4a6a20032c000141bf7f4a6a20032c000241bf7f4a6a20032c000341bf7f4a6a2104200341046a2103200741046b22070d000b0b2005450d000340200420032c000041bf7f4a6a2104200341016a2103200541016b22050d000b0b200120096a21030240200a450d0020032008417c716a22052c000041bf7f4a2106200a4101460d00200620052c000141bf7f4a6a2106200a4102460d00200620052c000241bf7f4a6a21060b20084102762107200420066a21040340200321062007450d04200741c001200741c001491b220941037121082009410274210c0240200941fc0171220a450440410021050c010b2006200a4102746a210d4100210503402003450d01200520032802002205417f734107762005410676724181828408716a200341046a2802002205417f734107762005410676724181828408716a200341086a2802002205417f734107762005410676724181828408716a2003410c6a2802002205417f734107762005410676724181828408716a2105200341106a2203200d470d000b0b200720096b21072006200c6a2103200541087641ff81fc0771200541ff81fc07716a418180046c41107620046a21042008450d000b2006450440410021030c020b2006200a4102746a22062802002203417f73410776200341067672418182840871210320084101460d01200320062802042203417f734107762003410676724181828408716a210320084102460d01200320062802082203417f734107762003410676724181828408716a21030c010b2002450440410021040c030b200241037121050240200241016b410349044041002104200121030c010b2002417c71210741002104200121030340200420032c000041bf7f4a6a20032c000141bf7f4a6a20032c000241bf7f4a6a20032c000341bf7f4a6a2104200341046a2103200741046b22070d000b0b2005450d020340200420032c000041bf7f4a6a2104200341016a2103200541016b22050d000b0c020b200341087641ff811c71200341ff81fc07716a418180046c41107620046a21040c010b2002417c71210541002104200121030340200420032c000041bf7f4a6a20032c000141bf7f4a6a20032c000241bf7f4a6a20032c000341bf7f4a6a2104200341046a2103200541046b22050d000b20024103712206450d004100210503402004200320056a2c000041bf7f4a6a21042006200541016a2205470d000b0b2004200b490440200b20046b22042106024002400240410020002d0020220320034103461b410371220341016b0e020001020b41002106200421030c010b20044101762103200441016a41017621060b200341016a21032000411c6a2802002104200041186a28020021052000280204210002400340200341016b2203450d01200520002004280210110100450d000b41010f0b410121032000418080c400460d02200520012002200428020c1100000d024100210303402003200646044041000f0b200341016a2103200520002004280210110100450d000b200341016b2006490f0b0c020b2000280218200120022000411c6a28020028020c11000021030b20030f0b2000280218200120022000411c6a28020028020c1100000b4701017f230041206b22032400200341146a4100360200200341fc95c000360210200342013702042003200136021c200320003602182003200341186a36020020032002100a000b1000200120002802002000280204101c0b140020002802002001200028020428020c1101000b98050b017f017f017f017f017f017f017f017f017f017f017f230041306b22022400200241246a419088c000360200200241033a0028200242808080808004370308200220003602202002410036021820024100360210027f024002402001280208220a450440200141146a2802002200450d012001280210210320004103742105200041016b41ffffffff017141016a2107200128020021000340200041046a28020022040440200228022020002802002004200228022428020c1100000d040b2003280200200241086a200341046a2802001101000d03200341086a2103200041086a2100200541086b22050d000b0c010b2001410c6a2802002200450d002000410574210b200041016b41ffffff3f7141016a2107200128020021000340200041046a28020022030440200228022020002802002003200228022428020c1100000d030b20022005200a6a2204411c6a2d00003a00282002200441046a290200422089370308200441186a2802002106200128021021084100210941002103024002400240200441146a28020041016b0e020002010b200641037420086a220c41046a2802004107470d01200c28020028020021060b410121030b2002200636021420022003360210200441106a28020021030240024002402004410c6a28020041016b0e020002010b200341037420086a220641046a2802004107470d01200628020028020021030b410121090b2002200336021c20022009360218200820042802004103746a2203280200200241086a20032802041101000d02200041086a2100200b200541206a2205470d000b0b200128020420074b04402002280220200128020020074103746a22002802002000280204200228022428020c1100000d010b41000c010b41010b2100200241306a240020000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c200341e489c000360208200341013602242003200341206a3602182003200341046a36022820032003360220200341086a2002100a000b950608017f017f017f017f017f017f017f017f02402002450d004100200241076b220420022004491b2109200141036a417c7120016b210a410021040340024002400240024002400240024002400240200120046a2d00002207411874411875220841004e0440200a20046b410371200a417f46720d0120042009490d020c080b410121064101210302400240024002400240024002400240200741cc8ac0006a2d000041026b0e030001020e0b200441016a22052002490d06410021030c0d0b41002103200441016a220520024f0d0c200120056a2c00002105200741e0016b2203450d012003410d460d020c030b2002200441016a22034d0440410021030c0c0b200120036a2c00002105024002400240200741f0016b0e050100000002000b2008410f6a41ff017141024b0440410121030c0e0b20054100480d09410121030c0d0b200541f0006a41ff01714130490d090c0b0b2005418f7f4a0d0a0c080b200541607141a07f470d090c020b200541a07f4e0d080c010b02402008411f6a41ff0171410c4f04402008417e71416e470440410121030c0b0b20054100480d01410121030c0a0b200541bf7f4a0d080c010b41012103200541404f0d080b41002103200441026a220520024f0d07200120056a2c000041bf7f4c0d0541012103410221060c070b200120056a2c000041bf7f4a0d050c040b200441016a21040c070b0340200120046a2203280200418081828478710d06200341046a280200418081828478710d062009200441086a22044b0d000b0c050b41012103200541404f0d030b2002200441026a22034d0440410021030c030b200120036a2c000041bf7f4a044041022106410121030c030b41002103200441036a220520024f0d02200120056a2c000041bf7f4c0d0041032106410121030c020b200541016a21040c030b410121030b20002004360204200041096a20063a0000200041086a20033a0000200041013602000f0b200220044d0d000340200120046a2c00004100480d012002200441016a2204470d000b0c020b200220044b0d000b0b20002001360204200041086a2002360200200041003602000b7d01017f230041406a220524002005200136020c2005200036020820052003360214200520023602102005412c6a41023602002005413c6a41093602002005420237021c200541d885c000360218200541083602342005200541306a3602282005200541106a3602382005200541086a360230200541186a2004100a000bd8040b017f017f017f017f017f017f017f017f017f017f017f2000280204210a2000280200210b2000280208210c0240034020050d010240024020022004490d000340200120046a210602400240024002400240200220046b220541084f0440200641036a417c7122002006460d02200020066b2200200520002005491b2200450d02410021030340200320066a2d0000410a460d06200341016a22032000470d000b0c010b20022004460440200221040c070b410021030340200320066a2d0000410a460d052005200341016a2203470d000b200221040c060b2000200541086b22034b0d020c010b200541086b2103410021000b03400240200020066a22072802002209417f732009418a94a8d0007341818284086b71418081828478710d00200741046a2802002207417f732007418a94a8d0007341818284086b71418081828478710d00200041086a220020034d0d010b0b200020054d0d002000200541cc88c000100f000b20002005460440200221040c030b0340200020066a2d0000410a460440200021030c020b2005200041016a2200470d000b200221040c020b0240200320046a220041016a2204452002200449720d00200020016a2d0000410a470d004100210520042103200421000c030b200220044f0d000b0b410121052002220020082203460d020b0240200c2d00000440200b418086c0004104200a28020c1100000d010b200120086a2106200020086b210741002109200c2000200847047f200620076a41016b2d0000410a460520090b3a000020032108200b20062007200a28020c110000450d010b0b4101210d0b200d0be60101017f230041106b220224002002410036020c20002002410c6a027f20014180014f044020014180104f04402001418080044f044020022001413f71418001723a000f20022001410676413f71418001723a000e20022001410c76413f71418001723a000d2002200141127641077141f001723a000c41040c030b20022001413f71418001723a000e20022001410c7641e001723a000c20022001410676413f71418001723a000d41030c020b20022001413f71418001723a000d2002200141067641c001723a000c41020c010b200220013a000c41010b10242100200241106a240020000b5501017f230041206b2202240020022000360204200241186a200141106a290200370300200241106a200141086a29020037030020022001290200370308200241046a200241086a10202100200241206a240020000b0d0020002802002001200210240bed0101017f230041106b22022400200028020021002002410036020c20002002410c6a027f20014180014f044020014180104f04402001418080044f044020022001413f71418001723a000f20022001410676413f71418001723a000e20022001410c76413f71418001723a000d2002200141127641077141f001723a000c41040c030b20022001413f71418001723a000e20022001410c7641e001723a000c20022001410676413f71418001723a000d41030c020b20022001413f71418001723a000d2002200141067641c001723a000c41020c010b200220013a000c41010b10242100200241106a240020000b5801017f230041206b2202240020022000280200360204200241186a200141106a290200370300200241106a200141086a29020037030020022001290200370308200241046a200241086a10202100200241206a240020000bd90206017f017f017f017f017e017e230041406a220324002000027f20002d000804402000280204210541010c010b2000280204210520002802002204280200220641047145044041012004280218418986c000419386c00020051b4102410120051b2004411c6a28020028020c1100000d011a2001200420021101000c010b20054504402004280218419186c00041022004411c6a28020028020c11000004404100210541010c020b200428020021060b200341013a0017200341346a41e885c00036020020032006360218200320042902183703082003200341176a3602102004290208210720042902102108200320042d00203a00382003200428020436021c20032008370328200320073703202003200341086a36023041012001200341186a20021101000d001a2003280230418786c0004102200328023428020c1100000b3a00082000200541016a360204200341406b240020000bc20203017f017f017f23004180016b2204240020002802002d0000210002400240027f02402001280200220241107145044020024120710d012000ad42ff01832001100d0c020b410021020340200220046a41ff006a413041d7002000410f712203410a491b20036a3a0000200241016b2102200041ff0171220341047621002003410f4b0d000b20024180016a22004181014f0d02200141c486c0004102200220046a4180016a410020026b100e0c010b410021020340200220046a41ff006a413041372000410f712203410a491b20036a3a0000200241016b2102200041ff0171220341047621002003410f4b0d000b20024180016a22004181014f0d02200141c486c0004102200220046a4180016a410020026b100e0b210020044180016a240020000f0b200041800141b486c000100f000b200041800141b486c000100f000b0d00200141a888c0004102101c0bec0102017f017f230041206b220224002002200036020c2002200128021841cc8cc00041112001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a2002410c6a410a102a2100027f20022d0018220120022802142203450d001a200141ff01712101410120010d001a20002802002100024020034101470d0020022d0019450d0020002d00004104710d0041012000280218419486c00041012000411c6a28020028020c1100000d011a0b200028021841f684c00041012000411c6a28020028020c1100000b2101200241206a2400200141ff01714100470b5d01017f02402001450440410121030c010b200141004e04402001100221030240200204402003450d01200341046b2d0000410371450d0320034100200110391a0c030b20030d020b000b1009000b20002001360204200020033602000bcc0103017f017f017f230041206b220224004103210341828dc000210420012d00004103460440200241106a200141016a2201027f024020012d0000450440410021010c010b200141016a2103410021010340200120036a2104200141016a210120042d00000d000b0b20010b102241858dc0002002280214200228021022011b21044103200241186a28020020011b21030b200241086a20034100102e200228020821012000200228020c36020420002001360200200120042003103a1a20002003360208200241206a24000b110020002802040440200028020010030b0b5902017f017f41d896c00041d896c000280200220241016a36020041a09ac00041a09ac00028020041016a220136020002402002410048200141024b720d0020004541d496c000280200410048200141014b72720d00000b000ba54822017f017f017f017f017f017f017f017f017f017f017f017f017e017e017e017f017f017f017f017e017f017f017f017e017f017f017f017f017f017f017f017f017f017f230041f0096b22022400200241186a2000102f200241286a2001102f2002280228210d200228022c210720022802302101200241386a1033200241003602a80141c0002100200241a8016a410472410041c00010391a0340200041016b22000d000b200241c0003602a801200241e0056a2203200241a8016a41c400103a1a200241e8006a2200200341047241c000103a1a200241003602f801200241c4026a418095c000290200370200200241cc026a418895c000290200370200200241d4026a419095c000290200370200200241f894c0002902003702bc02200241fc016a200041c000103a210020022001ad4203863703f00102402001413f4d04402000200d2001103a1a0c010b200241bc026a200d200141067610342000200d20014140716a2001413f712201103a1a0b200220013602f801200241b4016a4200370200200241bc016a4200370200200241c4016a4200370200200242003702ac01200241003602a801412021000340200041016b22000d000b200241203602a801200241e0056a2201200241a8016a4124103a1a200241e0006a200241fc056a290200370300200241d8006a200241f4056a290200370300200241d0006a200241ec056a2200290200370300200220022902e4053703482001200241f0016a41f000103a1a200241ac066a210a20022903e005210e024020022802e805220341c000470440200341c000490d01200341c00041c894c0001006000b200a20004101103441002103200241003602e8050b2003200241ec056a22056a4180013a0000200220022802e805220041016a22013602e8050240024002400240200141c100490440200120056a4100413f20006b10391a20022802e80541396b4108490440200a20054101103420022802e805220041c1004f0d0220054100200010391a0b200241a4066a200e42288642808080808080c0ff0083200e42388684200e421886428080808080e03f83200e4208864280808080f01f838484200e42088842808080f80f83200e421888428080fc078384200e4228884280fe0383200e423888848484370200200a200541011034200241003602e805200241e8096a200a41186a290200370300200241e0096a200a41106a290200370300200241d8096a200a41086a2902003703002002200a2902003703d00920024280808080c0003702b401200241203602ac012002200241e8006a220a3602b0012002200241c8006a3602a801200241a8016a2205280210220345044041a092c0004119418492c000101d000b20052802002101200a20052802042200360204200a2001360200200a410036021c200a200241d0096a2201360214200a2003360210200a200020036e2203360224200a41186a200241f0096a2200360200200a2005290208370208200a2003200020016b4102762200200020034b1b3602200240200228028401220120022802880122004f0d00200020016b210c200228026822052001200228027822066c6a2103200228027c20014102746a21012006410446210003402005450d0120022001280200220a411874200a410874418080fc077172200a4108764180fe0371200a41187672723602a8012000450d04200320022802a801360000200320066a2103200141046a2101200c41016b220c0d000b0b200241b0016a200241d0006a290300370300200241b8016a200241d8006a290300370300200241c0016a200241e0006a290300370300200241d0016a200241406b290300370300200220022903483703a801200220022903383703c80120070440200d10030b200228021c211e2002280218211c41002101200241106a200228022022044100102e2002280214211a20022802102216201c2004103a2103200441106a417071221120046b2200201a20046b4d0d04200020046a22052004490d032005417f73411f7621000240201a0440200241013602e8052002201a3602e405200220033602e0050c010b200241003602e8050b200241e0056a2103200241f0016a220c027f02400240027f0240024020000440024002400240200541004e044020032802080d012005450d020c060b0c040b20032802040d0120050d040b410121030c050b027f20032802002100410021030240200541ccff7b4b0d0041102005410b6a4178712005410b491b210b200041046b22082802002206417871210d02400240024002400240024020064103710440200041086b2109200b200d4d0d012009200d6a221441f899c000280200460d02201441f499c000280200460d032014280204220a4102710d06200d200a41787122076a2206200b4f0d040c060b200b41800249200d200b4104724972200d200b6b418180084f720d050c040b200d200b6b220a4110490d0320082006410171200b724102723602002009200b6a2207200a4103723602042007200a6a220320032802044101723602042007200a10000c030b41f099c000280200200d6a220a200b4d0d0320082006410171200b724102723602002009200b6a2207200a200b6b220341017236020441f099c000200336020041f899c00020073602000c020b41ec99c000280200200d6a2207200b490d0202402007200b6b220a410f4d044020082006410171200772410272360200200720096a220720072802044101723602044100210a0c010b20082006410171200b724102723602002009200b6a2203200a4101723602042003200a6a2207200a36020020072007280204417e713602040b41f499c000200336020041ec99c000200a3602000c010b2006200b6b210d024020074180024f0440201410010c010b2014410c6a2802002207201441086a28020022034704402003200736020c200720033602080c010b41dc96c00041dc96c000280200417e200a41037677713602000b200d41104f044020082008280200410171200b724102723602002009200b6a2207200d4103723602042007200d6a220320032802044101723602042007200d10000c010b20082008280200410171200672410272360200200620096a220320032802044101723602040b200021030c010b200510022207450d0020072000417c4178200828020022034103711b20034178716a2203200520032005491b103a21032000100320030c010b20030b0c030b200c20053602040b200c41086a410036020041010c040b200510020b2203450d010b200c2003360204200c41086a200536020041000c010b200c2005360204200c41086a410136020041010b36020020022802f00145044020022802f40121162005211a0c050b200241f8016a2802002200418180808078460d042000450d03000b200141c00041d894c000100f000b200041c00041e894c000101b000b230041306b2200240020004104360204200020063602002000411c6a41023602002000412c6a41013602002000420337020c200041b48ac000360208200041013602242000200041206a360218200020003602282000200041046a360220200041086a41ec95c000100a000b1009000b200241c8016a2105200241f0016a2200410041e00310391a2000200241a8016a22002000100420024190026a200241b8016a22002000100441c0002109410821030340200241f0016a220720031005200120076a220a41406b2200100720002000280200417f73360200200a41c4006a22002000280200417f73360200200a41d4006a22002000280200417f73360200200a41d8006a22002000280200417f73360200200720096a2200200028020041808003733602002007200341086a2207410e10082001418003470440200241f0016a220320071005200a41e0006a2200100720002000280200417f73360200200a41e4006a22002000280200417f73360200200a41f4006a22002000280200417f73360200200a41f8006a22002000280200417f733602002003200741086a220341061008200941c4006a2109200141406b21010c010b0b410021004108210902400240024002400340024002402000410171450440200941e8004f0d010c020b20092009411f6a22094b0d00200941e800490d010b41a00321000340200241f0016a20006a220120012802002203410476200373418098bc1871220120037320014104747322034102762003734180e6809803712201200373200141027473360200200041046a220041c003470d000b410021010340200241f0016a20016a220341206a22002000280200417f73360200200341246a22002000280200417f73360200200341346a22002000280200417f73360200200341386a22002000280200417f73360200200141206a220141c003470d000b200241d0056a20051035200241e0056a200241f0016a41f003103a1a0240200441707122012011490440200141106a21052004416f4d0440200520114d04402004410f712200200120166a6a411020006b2200200010391a200241c0096a21032005450440200321010c040b200520166a211f200241e0066a2114200241c0066a210d200241a0066a210620024180066a210a200241a0096a2120200241e0096a212120024180016a21222016210703402007220141106a2107410021000340200020016a220520052d0000200020036a2d0000733a0000200041016a22004110470d000b200241e8006a1033410021000340200241d0096a20006a22032002290368370000200341086a200241f0006a2203290300370000200041106a22004120470d000b200241d8096a221d200141086a2223290000370300200220012900003703d00920224200370300200241f8006a42003703002003420037030020024200370368200241e8006a200241d0096a20211004410021000340200241e8006a20006a22032003280200200241e0056a20006a28020073360200200041046a22004120470d000b4108211b2014210c200d210920062105200a21030340200241e8006a10072002200228028401220b41167741bffefcf90371200b411e7741c08183867c71722208200228028001220441167741bffefcf903712004411e7741c08183867c717222002004732204732008200b732212410c77418f9ebcf80071201241147741f0e1c3877f7172733602840120022004410c77418f9ebcf80071200441147741f0e1c3877f71722000200228027c220441167741bffefcf903712004411e7741c08183867c71722208200473220473733602800120022004410c77418f9ebcf80071200441147741f0e1c3877f717220082002280278220441167741bffefcf903712004411e7741c08183867c717222002004732204737336027c20022004410c77418f9ebcf80071200441147741f0e1c3877f717220002002280274220841167741bffefcf903712008411e7741c08183867c717222042008732217732012737336027820022002280270221341167741bffefcf903712013411e7741c08183867c71722200200228026c220b41167741bffefcf90371200b411e7741c08183867c71722208200b73220b7320002013732200410c77418f9ebcf80071200041147741f0e1c3877f71727336027020022017410c77418f9ebcf80071201741147741f0e1c3877f71722000200473732012733602742002200b410c77418f9ebcf80071200b41147741f0e1c3877f717220082002280268220441167741bffefcf903712004411e7741c08183867c717222002004732204737320127336026c20022004410c77418f9ebcf80071200441147741f0e1c3877f7172200073201273360268201b41086a2104410021000340200241e8006a20006a22082008280200200020036a28020073360200200041046a22004120470d000b200441f000460440410021000340200241e8006a20006a22032003280200220541047620057341809e80f800712203200573200341047473360200200041046a22004120470d000b200241e8006a1007410021000340200241e8006a20006a22032003280200200020206a28020073360200200041046a22004120470d000b201d20022802840141017441aad5aad57a7120022802800141d5aad5aa057172220b200228027c41017441aad5aad57a71200228027841d5aad5aa05717222004102767341b3e6cc99037122044102742000732205200228027441017441aad5aad57a71200228027041d5aad5aa0571722208200228026c41017441aad5aad57a71200228026841d5aad5aa05717222034102767341b3e6cc9903712200410274200373220941047673418f9ebcf80071220c20057336020020022004200b7322052000200873220341047673418f9ebcf8007122002005733602dc09200220004104742003733602d4092002200c4104742009733602d0092023201d290300370000200120022903d009370000200121032007201f470d020c0605200241e8006a100720022002280284012213411477418f9ebcf800712013411c7741f0e1c3877f717222002002280280012208411477418f9ebcf800712008411c7741f0e1c3877f7172220b2008732204732000201373221841107773360284012002200b200228027c2200411477418f9ebcf800712000411c7741f0e1c3877f71722208200073220073200441107773360280012002200820022802782204411477418f9ebcf800712004411c7741f0e1c3877f7172221220047322177320004110777336027c200220022802702204411477418f9ebcf800712004411c7741f0e1c3877f71722200200228026c2208411477418f9ebcf800712008411c7741f0e1c3877f71722213200873220b7320002004732204411077733602702002201220022802742200411477418f9ebcf800712000411c7741f0e1c3877f71722208200073220073201741107773201873360278200220042008732000411077732018733602742002201320022802682200411477418f9ebcf800712000411c7741f0e1c3877f71722208200073220073200b4110777320187336026c20022000411077200873201873360268410021000340200241e8006a20006a22082008280200200020056a28020073360200200041046a22004120470d000b200241e8006a10072002200228028401220b4112774183868c1871200b411a7741fcf9f3677172220820022802800122044112774183868c18712004411a7741fcf9f367717222002004732204732008200b732212410c77418f9ebcf80071201241147741f0e1c3877f7172733602840120022004410c77418f9ebcf80071200441147741f0e1c3877f71722000200228027c22044112774183868c18712004411a7741fcf9f36771722208200473220473733602800120022004410c77418f9ebcf80071200441147741f0e1c3877f71722008200228027822044112774183868c18712004411a7741fcf9f367717222002004732204737336027c20022004410c77418f9ebcf80071200441147741f0e1c3877f71722000200228027422084112774183868c18712008411a7741fcf9f36771722204200873221773201273733602782002200228027022134112774183868c18712013411a7741fcf9f36771722200200228026c220b4112774183868c1871200b411a7741fcf9f36771722208200b73220b7320002013732200410c77418f9ebcf80071200041147741f0e1c3877f71727336027020022017410c77418f9ebcf80071201741147741f0e1c3877f71722000200473732012733602742002200b410c77418f9ebcf80071200b41147741f0e1c3877f71722008200228026822044112774183868c18712004411a7741fcf9f367717222002004732204737320127336026c20022004410c77418f9ebcf80071200441147741f0e1c3877f7172200073201273360268410021000340200241e8006a20006a22082008280200200020096a28020073360200200041046a22004120470d000b200241e8006a100720022002280284012204411877220820022802800122004118772213200073220b7320042008732218411077733602840120022013200228027c22004118772204200073220873200b41107773360280012002200420022802782200411877221220007322177320084110777336027c2002200228027022044118772208200228026c22004118772213200073220b732004200873220441107773360270200220122002280274220041187722082000732200732017411077732018733602782002200420087320004110777320187336027420022013200228026822004118772208200073220073200b4110777320187336026c20022000411077200873201873360268201b41206a211b410021000340200241e8006a20006a220820082802002000200c6a28020073360200200041046a22004120470d000b200c4180016a210c20094180016a210920054180016a210520034180016a21030c010b000b000b000b2005201141a491c000101b000b2001200541a491c0001021000b41cc92c000412b200241e0056a41bc90c00041ac90c0001023000b200241e8006a20011035201141036e220141ffffffff0371200147210020014102742109024002402011410370220d044020002009200941046a22094b72450d010c020b20000d010b200241086a20094101102e41002101200228020c210a2002280208210c02402011411b490440410021030c010b41002011411a6b2200200020114b1b21054100210002400240034020112001411a6a4f044020004160460d02200041206a220320094b0d032000200c6a2206200120166a22072900002219423886220e423a88a741ab82c0006a2d00003a0000200641086a200741066a290000220f4238862215423a88a741ab82c0006a2d00003a0000200641016a200e201942288642808080808080c0ff0083842210423488a7413f7141ab82c0006a2d00003a0000200641076a201942088842808080f80f832019421888428080fc07838420194228884280fe038320194238888484220ea72200411076413f7141ab82c0006a2d00003a0000200641066a2000411676413f7141ab82c0006a2d00003a0000200641046a20102019421886428080808080e03f8320194208864280808080f01f8384842210422288a7413f7141ab82c0006a2d00003a0000200641036a2010422888a7413f7141ab82c0006a2d00003a0000200641026a2010422e88a7413f7141ab82c0006a2d00003a0000200641056a200e201084421c88a7413f7141ab82c0006a2d00003a0000200641096a2015200f42288642808080808080c0ff0083842210423488a7413f7141ab82c0006a2d00003a00002006410f6a200f42088842808080f80f83200f421888428080fc078384200f4228884280fe0383200f4238888484220ea72200411076413f7141ab82c0006a2d00003a00002006410e6a2000411676413f7141ab82c0006a2d00003a00002006410c6a2010200f421886428080808080e03f83200f4208864280808080f01f8384842210422288a7413f7141ab82c0006a2d00003a00002006410b6a2010422888a7413f7141ab82c0006a2d00003a00002006410a6a2010422e88a7413f7141ab82c0006a2d00003a00002006410d6a200e201084421c88a7413f7141ab82c0006a2d00003a0000200641176a2007410c6a290000220f42088842808080f80f83200f421888428080fc078384200f4228884280fe0383200f42388884842215a72200411076413f7141ab82c0006a2d00003a0000200641166a2000411676413f7141ab82c0006a2d00003a0000200641156a2015200f4238862210200f42288642808080808080c0ff008384220e200f421886428080808080e03f83200f4208864280808080f01f838484220f84421c88a7413f7141ab82c0006a2d00003a0000200641146a200f422288a7413f7141ab82c0006a2d00003a0000200641136a200f422888a7413f7141ab82c0006a2d00003a0000200641126a200f422e88a7413f7141ab82c0006a2d00003a0000200641116a200e423488a7413f7141ab82c0006a2d00003a0000200641106a2010423a88a741ab82c0006a2d00003a0000200641186a200741126a2900002215423886220e423a88a741ab82c0006a2d00003a0000200641196a200e201542288642808080808080c0ff0083842210423488a7413f7141ab82c0006a2d00003a00002006411f6a201542088842808080f80f832015421888428080fc07838420154228884280fe038320154238888484220ea72200411076413f7141ab82c0006a2d00003a00002006411e6a2000411676413f7141ab82c0006a2d00003a00002006411c6a20102015421886428080808080e03f8320154208864280808080f01f8384842210422288a7413f7141ab82c0006a2d00003a00002006411b6a2010422888a7413f7141ab82c0006a2d00003a00002006411a6a2010422e88a7413f7141ab82c0006a2d00003a00002006411d6a200e201084421c88a7413f7141ab82c0006a2d00003a0000200321002005200141186a22014f0d010c040b0b2001411a6a201141b883c000101b000b4160410041c883c0001021000b200041206a200941c883c000101b000b024002400240024002400240024002400240024002402011200d6b221420014d0440200321050c010b0340200141036a220020114b0d022003417b4b0d03200341046a220520094b0d042003200c6a2206200120166a22012d0000220741027641ab82c0006a2d00003a0000200641036a200141026a2d00002203413f7141ab82c0006a2d00003a0000200641026a200141016a2d00002201410274200341067672413f7141ab82c0006a2d00003a0000200641016a2007410474200141047672413f7141ab82c0006a2d00003a000020052103200022012014490d000b0b02400240200d41016b0e0200010b0b200520094f0d04410221012005200c6a201420166a2d0000220341027641ab82c0006a2d00003a0000200541016a220020094f0d05200341047441307121030c090b200520094f0d052005200c6a201420166a2d0000220041027641ab82c0006a2d00003a0000201441016a220320114f0d06200541016a220120094f0d072001200c6a2000410474200320166a2d0000220141047672413f7141ab82c0006a2d00003a00002009200541026a22004b04402001410274413c712103410321010c090b2000200941c884c0001006000b200141036a201141d883c000101b000b2003200341046a41e883c0001021000b200341046a200941e883c000101b000b2005200941f883c0001006000b20002009418884c0001006000b20052009419884c0001006000b2003201141a884c0001006000b2001200941b884c0001006000b2000200c6a200341ab82c0006a2d00003a0000200120056a21050b02400240024002400240200520094d04400240200d4103734103702207450440410021010c010b200920056b21062005200c6a210341002100034020002006460d03200020036a413d3a0000200041016a21014101210020012007490d000b0b200120056a2005490d02200241e0056a200c2009102220022802e005044020022902e405220e4280808080f01f83428080808020520d040b201a0440201610030b201e0440201c10030b2002200941026a22034101102e2003450d042002280200220141033a0000200141016a200c2009103a1a2003200941016a22004d0d05200020016a41003a0000200a0440200c10030b200241f0096a240020010f0b2005200941ec82c000100f000b2006200641d884c0001006000b230041106b220024002000412a36020c200041fc82c000360208230041206b22012400200141146a410136020020014201370204200141bc85c0003602002001410836021c2001200041086a3602182001200141186a360210200141a883c000100a000b2002200e3702ec05200220093602e8052002200a3602e4052002200c3602e00541e98ec000410c200241e0056a41848ec00041f88ec0001023000b4100410041e48dc0001006000b2000200341f48dc0001006000b230041106b22012400200141b88fc0003602082001412d360204200141888fc000360200230041106b22002400200041086a200141086a2802003602002000200129020037030041011031000b200941086a220a41f900490440200241f0016a20094102746a2103410021000340200020036a220120012802002207410476200773418098bc1871220120077320014104747322074102762007734180e6809803712201200773200141027473360200200041046a22004120470d000b200941106a2206200a490d02200641f8004b0d03200241f0016a200a4102746a2103410021000340200020036a22012001280200220741047620077341809e80f800712201200773200141047473360200200041046a22004120470d000b200941186a22002006490d04200041f8004b0d05200941016a2109200241f0016a20064102746a2103410021000340200020036a220120012802002207410476200773418086bce00071220120077320014104747322074102762007734180e6809803712201200773200141027473360200200041046a22004120470d000b410121000c010b0b200a41f80041dc80c000101b000b200a200641ec80c0001021000b200641f80041ec80c000101b000b2006200041fc80c0001021000b200041f80041fc80c000101b000b7e02017f017f230041306b2201410c6a42003702002001420037020420014100360200411021020340200241016b22020d000b20014110360200200141206a200141086a290300370300200141286a200141106a280200360200200120012903003703182000200129021c370000200041086a200141246a2902003700000bfa2e26017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f230041a0016b220324002003410041c00010392103200028021c2123200028021821242000280214211f20002802102120200028020c212520002802082126200028020421212000280200212220020440200120024106746a2127200341406b2128034020034280808080c00037027420032001360268200341c00036026c2003200141406b2201360270200341406b210420282102200341e8006a2205280210220f45044041a092c000411941bc92c000101d000b2005280204210e200420052802003602082004410036021c20042002360204200420033602002004410c6a200e360200200441186a200f360200200441106a20052902083702002004200220036b410276220236022420042002200e200f6e220420022004491b3602200240200328025c2202200328026022044f0d00200420026b210f2002410274220420032802406a2102200328024820046a21042003280258210e0340200e41044604402002200428000022054118742005410874418080fc07717220054108764180fe037120054118767272360200200241046a2102200441046a2104200f41016b220f0d010c020b0b41cc92c000412b200341e8006a41f892c00041e093c0001023000b200328023c21162003280238211d2003280234211e2003280230210e200328022c2117200328022821182003280224211920032802202113200328021c211a2003280218211b2003280214211c20032802102111200328020c210f200328020821122003280204211420032802002115200320263602682003202536026c20032024360270200320233602742003201f36024c20032020360248200320213602442003202236024020034190016a2202200341e8006a2204200341406b22052014419189dd89076a20154198dfa894046a1036200328029001211020032802940121062003280298012107200328029c0121082003201f360274200320203602702003202136026c200320223602682003200836024c200320073602482003200636024420032010360240200220042005200f41dbc8a8b2016b201241b188fcd1046b10362003280290012109200328029401210a200328029801210b200328029c01210c20032008360274200320073602702003200636026c200320103602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201c41f1a3c4cf056a201141db84dbca036a1036200328029001211020032802940121062003280298012107200328029c0121082003200c3602742003200b3602702003200a36026c200320093602682003200836024c200320073602482003200636024420032010360240200220042005201a41abc28ea7056b201b41dcfa81ee066b10362003280290012109200328029401210a200328029801210b200328029c01210c20032008360274200320073602702003200636026c200320103602682003200c36024c2003200b3602482003200a3602442003200936024020022004200520194181b68d94016a201341e8aae1bf026b1036200328029001211020032802940121062003280298012107200328029c0121082003200c3602742003200b3602702003200a36026c200320093602682003200836024c200320073602482003200636024420032010360240200220042005201741c3fbb1a8056a201841be8bc6a1026a10362003280290012109200328029401210a200328029801210b200328029c01210c20032008360274200320073602702003200636026c200320103602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201e41829c85f9076b200e41f4baf995076a1036200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c2003200836024820032007360244200320063602402002200420052016418c9d90f3036b201d41d9f28fa1066b10362003280290012109200328029401210a200328029801210b200328029c01210c2003201536029c01200320143602980120032012360294012003200f3602900120032013360274200320193602702003201836026c200320173602682003200e36024c2003201e3602482003201d3602442003201636024020034180016a220f20022011200420051037200328028001211420032802840121152003280288012110200328028c0121122003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201041faf08682016b201241bfac92db016b1036200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201441ccc3b2a0026a201541c6bb86fe006a10362003280290012109200328029401210a200328029801210b200328029c01210c2003201136029c012003201c360298012003201b360294012003201a360290012003200e3602742003201e3602702003201d36026c200320163602682003201236024c200320103602482003201536024420032014360240200f20022013200420051037200328028001211a200328028401211b200328028801211c200328028c0121112003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201c41aa89d2d3046a201141efd8a4ef026a1036200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201a41da91e6b7076a201b41dcd3c2e5056a10362003280290012109200328029401210a200328029801210b200328029c01210c2003201336029c0120032019360298012003201836029401200320173602900120032012360274200320103602702003201536026c200320143602682003201136024c2003201c3602482003201b3602442003201a360240200f2002200e200420051037200328028001211720032802840121182003280288012119200328028c0121132003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a3602442003200936024020022004200520194193f3b8be056b201341aedd86be066b1036200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201741b9809a85046b201841b8b0f3ff046b10362003280290012109200328029401210a200328029801210b200328029c01210c2003200e36029c012003201e360298012003201d360294012003201636029001200320113602742003201c3602702003201b36026c2003201a3602682003201336024c200320193602482003201836024420032017360240200f200220122004200510372003280280012116200328028401211d200328028801211e200328028c01210e2003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201e41b9dde1d2026b200e418de8ffc8036b1036200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201641e7d2a4a1016a201d41d1c6a9366a10362003280290012109200328029401210a200328029801210b200328029c01210c2003201236029c0120032010360298012003201536029401200320143602900120032013360274200320193602702003201836026c200320173602682003200e36024c2003201e3602482003201d36024420032016360240200f20022011200420051037200328028001211420032802840121152003280288012110200328028c0121122003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201041b8c2ecf0026a2012418595dcbd026a1036200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201441939ae099056a201541fcdbb1e9046a10362003280290012109200328029401210a200328029801210b200328029c01210c2003201136029c012003201c360298012003201b360294012003201a360290012003200e3602742003201e3602702003201d36026c200320163602682003201236024c200320103602482003201536024420032014360240200f20022013200420051037200328028001211a200328028401211b200328028801211c200328028c0121112003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201c41bb95a8b3076a201141d4e6a9a8066a1036200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201a41fba6b7ec066b201b41d2edf4f1076b10362003280290012109200328029401210a200328029801210b200328029c01210c2003201336029c0120032019360298012003201836029401200320173602900120032012360274200320103602702003201536026c200320143602682003201136024c2003201c3602482003201b3602442003201a360240200f2002200e200420051037200328028001211720032802840121182003280288012119200328028c0121132003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201941b5b396bf056b201341dfae80ea056b1036200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201741dddccec4036b20184190e9d1ed036b10362003280290012109200328029401210a200328029801210b200328029c01210c2003200e36029c012003201e360298012003201d360294012003201636029001200320113602742003201c3602702003201b36026c2003201a3602682003201336024c200320193602482003201836024420032017360240200f200220122004200510372003280280012116200328028401211d200328028801211e200328028c01210e2003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201e41dcf39bcb026b200e41e7afb4f3026b1036200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201641f0c0aa83016a201d41fb94c7df006b10362003280290012109200328029401210a200328029801210b200328029c01210c2003201236029c0120032010360298012003201536029401200320143602900120032013360274200320193602702003201836026c200320173602682003200e36024c2003201e3602482003201d36024420032016360240200f20022011200420051037200328028001211420032802840121152003280288012110200328028c0121122003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a3602442003200936024020022004200520104188d8ddf1016a201241968293cd016a1036200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201441b5f9c2a5036a201541cceea1ba026a10362003280290012109200328029401210a200328029801210b200328029c01210c2003201136029c012003201c360298012003201b360294012003201a360290012003200e3602742003201e3602702003201d36026c200320163602682003201236024c200320103602482003201536024420032014360240200f200220132004200510372003280280012111200328028401211a200328028801211b200328028c01211c2003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201b41cad4e2f6046a201c41b399f0c8036a1036200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201141f3dfb9c1066a201a41cf94f3dc056a10362003280290012109200328029401210a200328029801210b200328029c01210c2003201336029c0120032019360298012003201836029401200320173602900120032012360274200320103602702003201536026c200320143602682003201c36024c2003201b3602482003201a36024420032011360240200f2002200e200420051037200328028001211320032802840121142003280288012115200328028c0121102003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201541efc695c5076a201041ee85bea4076a1036200328029001211720032802940121182003280298012119200328029c0121062003200c3602742003200b3602702003200a36026c200320093602682003200636024c200320193602482003201836024420032017360240200220042005201341f8fbe399076b201441ec8fded9076b1036200328029001210720032802940121082003280298012109200328029c01210a2003200e36029c012003201e360298012003201d3602940120032016360290012003201c3602742003201b3602702003201a36026c200320113602682003201036024c200320153602482003201436024420032013360240200f2002201220042005103720032802800121132003280284012116200328028801210f200328028c01210e20032006360274200320193602702003201836026c200320173602682003200a36024c200320093602482003200836024420032007360240200220042005200f4195a6bedd056b200e41868084fa066b1036200328029001210f200328029401210e2003280298012112200328029c0121112003200a360274200320093602702003200836026c200320073602682003201136024c200320123602482003200e3602442003200f3602402002200420052013418e8ebacc036b20164189b89988046b1036201120236a2123201220246a2124200e20256a2125200f20266a2126200328029c01201f6a211f20032802980120206a212020032802940120216a212120032802900120226a212220012027470d000b0b2000202336021c200020243602182000201f360214200020203602102000202536020c200020263602082000202136020420002022360200200341a0016a24000b7f02017f017f230041306b220241003602000340200220036a41046a200120036a2d00003a0000200341016a22034110470d000b20024110360200200241206a200241086a290300370300200241286a200241106a280200360200200220022903003703182000200229021c370000200041086a200241246a2902003700000be20106017f017f017f017f017f017f2000200128020c200420022802082204411a772004411577732004410777736a6a20012802082207200228020c2208732004712007736a220520012802046a220636020c2000200520012802002205200228020022017120022802042209200171220a732005200971732001411e772001411377732001410a77736a6a220236020420002005200320076a20082006200420087371736a2006411a772006411577732006410777736a22036a36020820002002411e772002411377732002410a77732002200120097371200a736a20036a3602000bec0103017f017f017f20002003280208200128020c20012802082205410e772005411977732005410376736a6a20042802042206410f772006410d77732006410a76736a220636020c20002003280204200520012802042207410e772007411977732007410376736a6a20042802002205410f772005410d77732005410a76736a220536020820002003280200200720012802002201410e772001411977732001410376736a6a2006410f772006410d77732006410a76736a3602042000200428020c20012002410e772002411977732002410376736a6a2005410f772005410d77732005410a76736a3602000bb60204017f017f017f017f411f210220004200370210200141ffffff074d04402001410620014108766722036b7641017120034101746b413e6a21020b2000200236021c200241027441ec98c0006a2104024002400240024041e096c000280200220541012002742203710440200428020022032802044178712001470d01200321020c020b41e096c000200320057236020020042000360200200020043602180c030b20014100411920024101766b411f712002411f461b742104034020032004411d764104716a41106a22052802002202450d02200441017421042002210320022802044178712001470d000b0b20022802082201200036020c20022000360208200041003602182000200236020c200020013602080f0b20052000360200200020033602180b2000200036020c200020003602080bb30103017f017f017f2001210502402002410f4d0440200021010c010b2000410020006b41037122036a210420030440200021010340200120053a0000200141016a22012004490d000b0b2004200220036b2202417c7122036a2101200341004a0440200541ff017141818284086c2103034020042003360200200441046a22042001490d000b0b200241037121020b20020440200120026a21020340200120053a0000200141016a22012002490d000b0b20000bbf0207017f017f017f017f017f017f017f024020022204410f4d0440200021020c010b2000410020006b41037122036a21052003044020002102200121060340200220062d00003a0000200641016a2106200241016a22022005490d000b0b2005200420036b2208417c7122076a21020240200120036a220341037122040440200741004c0d012003417c71220641046a21014100200441037422096b4118712104200628020021060340200520062009762001280200220620047472360200200141046a2101200541046a22052002490d000b0c010b200741004c0d0020032101034020052001280200360200200141046a2101200541046a22052002490d000b0b20084103712104200320076a21010b20040440200220046a21030340200220012d00003a0000200141016a2101200241016a22022003490d000b0b20000b0b99160400418080c0000bcc0b2f7573722f6c6f63616c2f636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6165732d302e372e352f7372632f736f66742f666978736c69636533322e72730000000010005a000000e500000023000000000010005a000000e600000023000000000010005a000000e700000023000000000010005a0000009104000012000000000010005a000000910400003d000000000010005a0000001b05000022000000000010005a0000001b050000090000006c6962726172792f616c6c6f632f7372632f7261775f7665632e72736361706163697479206f766572666c6f77000000e800100011000000cc0010001c000000060200000500000062797465736572726f7246726f6d557466384572726f724142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f00140710005500000092000000270000007573697a65206f766572666c6f77207768656e2063616c63756c6174696e6720623634206c656e67746800001407100055000000990000000a0000001407100055000000b6000000200000001407100055000000b7000000250000001407100055000000fc0000001c0000001407100055000000fd00000021000000140710005500000013010000090000001407100055000000140100000900000014071000550000000b0100000900000014071000550000000d0100000f00000014071000550000000c0100000900000014071000550000000f0100000900000014071000550000003b01000009000000426c6f636b4d6f64654572726f7229696e646578206f7574206f6620626f756e64733a20746865206c656e20697320206275742074686520696e6465782069732000000077021000200000009702100012000000fc0a1000000000000b00000000000000010000000c0000003a200000fc0a100000000000d4021000020000000b0000000c000000040000000d0000000e0000000f00000020202020207b0a2c0a2c20207b207d207d280a282c0a5b5d6c6962726172792f636f72652f7372632f666d742f6e756d2e727300180310001b00000065000000140000003078303030313032303330343035303630373038303931303131313231333134313531363137313831393230323132323233323432353236323732383239333033313332333333343335333633373338333934303431343234333434343534363437343834393530353135323533353435353536353735383539363036313632363336343635363636373638363937303731373237333734373537363737373837393830383138323833383438353836383738383839393039313932393339343935393639373938393900000b000000040000000400000010000000110000001200000028296c6962726172792f636f72652f7372632f736c6963652f6d656d6368722e727300002a04100020000000680000002700000072616e676520737461727420696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e677468205c041000120000006e0410002200000072616e676520656e6420696e64657820a0041000100000006e04100022000000736c69636520696e64657820737461727473206174202062757420656e64732061742000c004100016000000d60410000d000000736f7572636520736c696365206c656e67746820282920646f6573206e6f74206d617463682064657374696e6174696f6e20736c696365206c656e6774682028f404100015000000090510002b0000007602100001000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100418e8cc0000b330202020202020202020202020202020202020202020202020202020202020303030303030303030303030303030304040404040041cc8cc0000bc50554727946726f6d536c6963654572726f72536f6d654e6f6e65557466384572726f7276616c69645f75705f746f6572726f725f6c656e3f3f3f2121212f7573722f6c6f63616c2f636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6c696273716c5f62696e6467656e2d302e322e332f7372632f6c69622e72730000008806100059000000260000000900000088061000590000002800000009000000130000001400000004000000140000002f7573722f6c6f63616c2f636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6261736536342d302e31332e312f7372632f656e636f64652e7273496e76616c696420555446380000001407100055000000340000001c000000696e7465676572206f766572666c6f77207768656e2063616c63756c6174696e67206275666665722073697a6500000014071000550000002f000000110000002f7573722f6c6f63616c2f636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6d616769632d63727970742d332e312e31322f7372632f636970686572732f6165733235362e72730000c8071000620000005800000038000000150000000000000001000000160000002f7573722f6c6f63616c2f636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f626c6f636b2d70616464696e672d302e322e312f7372632f6c69622e72734c08100058000000270000001e0000002f72757374632f383937653337353533626261386234323735316336373635383936373838396431316563643132302f6c6962726172792f636f72652f7372632f736c6963652f697465722e72730000b40810004e000000ee070000110041a092c0000bb104617474656d707420746f20646976696465206279207a65726f000000b40810004e0000004e0700001100000063616c6c65642060526573756c743a3a756e77726170282960206f6e20616e2060457272602076616c756500150000000000000001000000170000002f7573722f6c6f63616c2f636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f736861322d302e392e392f7372632f7368613235362f736f66742e7273008809100057000000d5000000360000002f7573722f6c6f63616c2f636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f626c6f636b2d6275666665722d302e392e302f7372632f6c69622e727300f0091000570000008400000009000000f0091000570000008700000017000000f0091000570000008b0000001b00000067e6096a85ae67bb72f36e3c3af54fa57f520e518c68059babd9831f19cde05b2f7573722f6c6f63616c2f636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f736861322d302e392e392f7372632f7368613235362e72730000980a100052000000510000001300000063616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c75656c6962726172792f7374642f7372632f70616e69636b696e672e727300270b10001c000000470200000f&#39;;<br>DROP FUNCTION IF EXISTS decrypt;<br>CREATE FUNCTION decrypt LANGUAGE wasm AS X&#39;0061736d01000000013a0a60027f7f017f60037f7f7f017f60037f7f7f0060017f0060027f7f0060057f7f7f7f7f0060017f017f60000060017f017e60047f7f7f7f017f0331300004030306020402030203020207040001000308000902020200000202010000010000000204000302040505040300010405017001101005030100110619037f01418080c0000b7f0041949cc0000b7f0041a09cc0000b072f04066d656d6f72790200076465637279707400260a5f5f646174615f656e6403010b5f5f686561705f6261736503020915010041010b0f14110f190f12131d1e1f20212212230ac5950230fe0205017f017f017f017f017f02400240200141094f044041cdff7b20014110200141104b1b22016b20004d0d01200141102000410b6a4178712000410b491b22046a410c6a10042202450d01200241086b21000240200141016b2203200271450440200021010c010b200241046b22052802002206417871200220036a410020016b7141086b220241002001200220006b41104b1b6a220120006b22026b21032006410371044020012001280204410171200372410272360204200120036a2203200328020441017236020420052005280200410171200272410272360200200020026a220320032802044101723602042000200210010c010b20002802002100200120033602042001200020026a3602000b20012802042200410371450d0220004178712202200441106a4d0d0220012000410171200472410272360204200120046a2200200220046b2204410372360204200120026a220220022802044101723602042000200410010c020b2000100421030b20030f0b200141086a0b940504017f017f017f017f200020016a2102024002400240200028020422034101710d002003410371450d012000280200220320016a2101200020036b220041e49bc00028020046044020022802044103714103470d0141dc9bc000200136020020022002280204417e7136020420002001410172360204200220013602000f0b20034180024f0440200010020c010b2000410c6a2802002204200041086a28020022054704402005200436020c200420053602080c010b41cc98c00041cc98c000280200417e200341037677713602000b20022802042203410271044020022003417e7136020420002001410172360204200020016a20013602000c020b024041e89bc0002802002002470440200241e49bc000280200470d0141e49bc000200036020041dc9bc00041dc9bc00028020020016a220136020020002001410172360204200020016a20013602000f0b41e89bc000200036020041e09bc00041e09bc00028020020016a220136020020002001410172360204200041e49bc000280200470d0141dc9bc000410036020041e49bc00041003602000f0b2003417871220420016a2101024020044180024f0440200210020c010b2002410c6a2802002204200241086a28020022024704402002200436020c200420023602080c010b41cc98c00041cc98c000280200417e200341037677713602000b20002001410172360204200020016a2001360200200041e49bc000280200470d0141dc9bc00020013602000b0f0b20014180024f044020002001102c0f0b200141787141d498c0006a2102027f41cc98c00028020022034101200141037674220171044020022802080c010b41cc98c000200120037236020020020b2101200220003602082001200036020c2000200236020c200020013602080bbb0205017f017f017f017f017f20002802182104024002402000200028020c2201460440200041144110200041146a220128020022031b6a28020022020d01410021010c020b20002802082202200136020c200120023602080c010b2001200041106a20031b21030340200321052002220141146a22032802002202450440200141106a2103200128021021020b20020d000b200541003602000b02402004450d0002402000200028021c41027441dc9ac0006a220228020047044020044110411420042802102000461b6a200136020020010d010c020b2002200136020020010d0041d098c00041d098c000280200417e200028021c77713602000f0b2001200436021820002802102202044020012002360210200220013602180b200041146a2802002200450d00200141146a2000360200200020013602180b0ba70705017f017f017f017f017f200041086b2201200041046b280200220341787122006a210202400240024020034101710d002003410371450d012001280200220320006a2100200120036b220141e49bc00028020046044020022802044103714103470d0141dc9bc000200036020020022002280204417e7136020420012000410172360204200020016a20003602000f0b20034180024f0440200110020c010b2001410c6a2802002204200141086a28020022054704402005200436020c200420053602080c010b41cc98c00041cc98c000280200417e200341037677713602000b024020022802042203410271044020022003417e7136020420012000410172360204200020016a20003602000c010b02400240024041e89bc0002802002002470440200241e49bc000280200470d0141e49bc000200136020041dc9bc00041dc9bc00028020020006a220036020020012000410172360204200020016a20003602000f0b41e89bc000200136020041e09bc00041e09bc00028020020006a220036020020012000410172360204200141e49bc000280200460d010c020b2003417871220420006a2100024020044180024f0440200210020c010b2002410c6a2802002204200241086a28020022024704402002200436020c200420023602080c010b41cc98c00041cc98c000280200417e200341037677713602000b20012000410172360204200020016a2000360200200141e49bc000280200470d0241dc9bc00020003602000c030b41dc9bc000410036020041e49bc00041003602000b41849cc000280200220320004f0d0141e89bc0002802002202450d0141002101024041e09bc00028020022044129490d0041f49bc000210003402002200028020022054f0440200520002802046a20024b0d020b200028020822000d000b0b41fc9bc000280200220004400340200141016a2101200028020822000d000b0b418c9cc000200141ff1f200141ff1f4b1b360200200320044f0d0141849cc000417f3602000f0b2000418002490d0120012000102c41002101418c9cc000418c9cc00028020041016b220036020020000d0041fc9bc000280200220004400340200141016a2101200028020822000d000b0b418c9cc000200141ff1f200141ff1f4b1b3602000f0b0f0b200041787141d498c0006a2102027f41cc98c00028020022034101200041037674220071044020022802080c010b41cc98c000200020037236020020020b2100200220013602082000200136020c2001200236020c200120003602080b9d1f09017f017f017f017f017f017f017f017f017e02400240024002400240200041f5014f0440200041cdff7b4f0d042000410b6a2200417871210341d098c0002802002208450d03410020036b2102027f41002003418002490d001a411f200341ffffff074b0d001a2003410620004108766722006b7641017120004101746b413e6a0b220741027441dc9ac0006a2802002200044020034100411920074101766b411f712007411f461b74210503400240200028020441787122062003490d00200620036b220620024f0d0020002104200622020d00410021020c040b200041146a28020022062001200620002005411d764104716a41106a2802002200471b200120061b21012005410174210520000d000b20010440200121000c030b20040d030b41002104200841022007742200410020006b72712200450d032000410020006b716841027441dc9ac0006a28020022000d010c030b024002400240027f0240024041cc98c000280200220141102000410b6a4178712000410b491b22034103762202762200410371450440200341dc9bc0002802004d0d0920000d0141d098c0002802002200450d092000410020006b716841027441dc9ac0006a280200220428020441787120036b210120042802102200450440200441146a28020021000b200004400340200028020441787120036b220620014921052006200120051b21012000200420051b210420002802102202047f200205200041146a2802000b22000d000b0b2004100220014110490d0520042003410372360204200320046a22032001410172360204200120036a200136020041dc9bc0002802002205450d04200541787141d498c0006a210041e49bc000280200210241cc98c00028020022064101200541037674220571450d0220002802080c030b02402000417f7341017120026a2200410374220341dc98c0006a280200220241086a22052802002204200341d498c0006a22034704402004200336020c200320043602080c010b41cc98c0002001417e200077713602000b200220004103742200410372360204200020026a2200200028020441017236020420050f0b024041022002411f712202742204410020046b722000200274712200410020006b71682202410374220541dc98c0006a280200220041086a22062802002204200541d498c0006a22054704402004200536020c200520043602080c010b41cc98c0002001417e200277713602000b20002003410372360204200020036a22052002410374220120036b2204410172360204200020016a200436020041dc9bc00028020022010440200141787141d498c0006a210041e49bc0002802002102027f41cc98c00028020022034101200141037674220171044020002802080c010b41cc98c000200120037236020020000b2101200020023602082001200236020c2002200036020c200220013602080b41e49bc000200536020041dc9bc000200436020020060f0b41cc98c000200520067236020020000b2105200020023602082005200236020c2002200036020c200220053602080b41e49bc000200336020041dc9bc00020013602000c010b2004200120036a2200410372360204200020046a220020002802044101723602040b0c040b0340200020042000280204417871220120034f200120036b22062002497122051b21042006200220051b210220002802102201047f200105200041146a2802000b22000d000b2004450d010b200341dc9bc00028020022004d2002200020036b4f710d00200410020240200241104f044020042003410372360204200320046a22012002410172360204200120026a200236020020024180024f044020012002102c0c020b200241787141d498c0006a2100027f41cc98c00028020022034101200241037674220271044020002802080c010b41cc98c000200220037236020020000b2102200020013602082002200136020c2001200036020c200120023602080c010b2004200220036a2200410372360204200020046a220020002802044101723602040b0c020b0240024002400240024002400240024002400240200341dc9bc00028020022014b044041e09bc000280200220020034b0d0441002102200341af80046a220041107640002201417f4622050d0b20014110742204450d0b41ec9bc000410020004180807c7120051b220541ec9bc0002802006a220036020041f09bc00041f09bc0002802002201200020002001491b36020041e89bc0002802002202450d0141f49bc0002100034020002802002201200028020422066a2004460d03200028020822000d000b0c030b41e49bc00028020021000240200120036b2202410f4d044041e49bc000410036020041dc9bc000410036020020002001410372360204200020016a220120012802044101723602040c010b41dc9bc000200236020041e49bc000200020036a220436020020042002410172360204200020016a2002360200200020034103723602040b200041086a0f0b41889cc000280200220045200020044b720d030c070b200028020c200120024b720d0020022004490d030b41889cc00041889cc0002802002200200420002004491b360200200420056a210141f49bc000210002400240034020012000280200470440200028020822000d010c020b0b200028020c450d010b41f49bc0002100034002402002200028020022014f0440200120002802046a220620024b0d010b200028020821000c010b0b41e89bc000200436020041e09bc000200541286b220036020020042000410172360204200020046a412836020441849cc00041808080013602002002200641206b41787141086b22002000200241106a491b2201411b36020441f49bc0002902002109200141106a41fc9bc0002902003702002001200937020841f89bc000200536020041f49bc000200436020041fc9bc000200141086a36020041809cc00041003602002001411c6a2100034020004107360200200041046a22002006490d000b20012002460d0720012001280204417e713602042002200120026b22004101723602042001200036020020004180024f044020022000102c0c080b200041787141d498c0006a2101027f41cc98c00028020022044101200041037674220071044020012802080c010b41cc98c000200020047236020020010b2100200120023602082000200236020c2002200136020c200220003602080c070b200020043602002000200028020420056a360204200420034103723602042001200320046a22056b210341e89bc0002802002001470440200141e49bc000280200460d04200128020422024103714101470d050240200241787122004180024f0440200110020c010b2001410c6a2802002206200141086a28020022074704402007200636020c200620073602080c010b41cc98c00041cc98c000280200417e200241037677713602000b200020036a2103200020016a220128020421020c050b41e89bc000200536020041e09bc00041e09bc00028020020036a2200360200200520004101723602040c080b41e09bc000200020036b220136020041e89bc00041e89bc000280200220020036a22023602002002200141017236020420002003410372360204200041086a21020c060b41889cc00020043602000c030b2000200520066a36020441e89bc00041e89bc0002802002200410f6a417871220141086b36020041e09bc00041e09bc00028020020056a2202200020016b6a41086a2204360200200141046b2004410172360200200020026a412836020441849cc00041808080013602000c030b41e49bc000200536020041dc9bc00041dc9bc00028020020036a220036020020052000410172360204200020056a20003602000c040b20012002417e7136020420052003410172360204200320056a200336020020034180024f044020052003102c0c040b200341787141d498c0006a2100027f41cc98c00028020022014101200341037674220271044020002802080c010b41cc98c000200120027236020020000b2103200020053602082003200536020c2005200036020c200520033602080c030b418c9cc00041ff1f36020041f89bc000200536020041f49bc000200436020041e098c00041d498c00036020041e898c00041dc98c00036020041dc98c00041d498c00036020041f098c00041e498c00036020041e498c00041dc98c00036020041f898c00041ec98c00036020041ec98c00041e498c000360200418099c00041f498c00036020041f498c00041ec98c000360200418899c00041fc98c00036020041fc98c00041f498c000360200419099c000418499c000360200418499c00041fc98c000360200419899c000418c99c000360200418c99c000418499c00036020041809cc000410036020041a099c000419499c000360200419499c000418c99c000360200419c99c000419499c00036020041a899c000419c99c00036020041a499c000419c99c00036020041b099c00041a499c00036020041ac99c00041a499c00036020041b899c00041ac99c00036020041b499c00041ac99c00036020041c099c00041b499c00036020041bc99c00041b499c00036020041c899c00041bc99c00036020041c499c00041bc99c00036020041d099c00041c499c00036020041cc99c00041c499c00036020041d899c00041cc99c00036020041d499c00041cc99c00036020041e099c00041d499c00036020041e899c00041dc99c00036020041dc99c00041d499c00036020041f099c00041e499c00036020041e499c00041dc99c00036020041f899c00041ec99c00036020041ec99c00041e499c00036020041809ac00041f499c00036020041f499c00041ec99c00036020041889ac00041fc99c00036020041fc99c00041f499c00036020041909ac00041849ac00036020041849ac00041fc99c00036020041989ac000418c9ac000360200418c9ac00041849ac00036020041a09ac00041949ac00036020041949ac000418c9ac00036020041a89ac000419c9ac000360200419c9ac00041949ac00036020041b09ac00041a49ac00036020041a49ac000419c9ac00036020041b89ac00041ac9ac00036020041ac9ac00041a49ac00036020041c09ac00041b49ac00036020041b49ac00041ac9ac00036020041c89ac00041bc9ac00036020041bc9ac00041b49ac00036020041d09ac00041c49ac00036020041c49ac00041bc9ac00036020041d89ac00041cc9ac00036020041cc9ac00041c49ac00036020041e89bc000200436020041d49ac00041cc9ac00036020041e09bc000200541286b220036020020042000410172360204200020046a412836020441849cc00041808080013602000b4100210241e09bc000280200220020034d0d0041e09bc000200020036b220136020041e89bc00041e89bc000280200220020036a22023602002002200141017236020420002003410372360204200041086a0f0b20020f0b200441086a0bbc030d017f017f017f017f017f017f017f017f017f017f017f017f017f2000200228000c2203200128000c22044101767341d5aad5aa05712208200373220320022800082205200128000822064101767341d5aad5aa0571220920057322054102767341b3e6cc990371220b2003732203200228000422072001280004220a4101767341d5aad5aa0571220c200773220720022800002202200128000022014101767341d5aad5aa0571220d20027322024102767341b3e6cc990371220e200773220741047673418f9ebcf80071220f20037336021c200020042008410174732203200620094101747322044102767341b3e6cc99037122082003732203200a200c4101747322062001200d4101747322014102767341b3e6cc9903712209200673220641047673418f9ebcf80071220a2003733602182000200b4102742005732203200e410274200273220241047673418f9ebcf8007122052003733602142000200f41047420077336020c2000200841027420047322032009410274200173220141047673418f9ebcf8007122042003733602102000200a41047420067336020820002005410474200273360204200020044104742001733602000b7a02017f017f200141076a2102200020014102746a210041202101024002400340200241f7004b0d02200241086a41f8004f0d01200020016a2203411c6a200341046b280200360200200241016b2102200141046b22010d000b0f0b200241086a41f80041fc81c0001007000b200241f80041ec81c0001007000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c200341b486c000360208200341013602242003200341206a360218200320033602282003200341046a360220200341086a2002100e000bd7041c017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f2000200028021c220120002802042205732209200028021022032000280208220673220f732210200028020c732207200673220b201071220a20072000280218220c73220473200b200028020022077322172005200c200028021473220220077322057322162001200673220c73221371732002200b73220d200420012003732211732206732214200f712006201171220873220473221220042005201671200920022006732204727373220e712202200c200d71200873220820032005732218200771200c73200d73200a7373220a73200e200620077322192001200573221a7120042009417f737120017373200873220373712208200273200371221520022003732201732001200a201273220271200a732201712002732202200e201573220e2003200873220373220a73220820012003732212732215200f712011201271220f732211200a201371732213200e20107173221020042001200273220471221b200220057173221c201420157173221420062012717322057336021c20002008200d7120042009712206200b200e712209200320077173220b7373201473220d2001201a717322042008200c71200f73200573733602142000200a201771200973201c732010732207360210200020132003201871732004733602082000200b200120197173201b7322012011200220167173732209200d7336020420002006200973360200200020052007733602182000200120077336020c0bbf0103017f017f017f410041f80020016b2203200341f8004b1b2105200141027420006a41406a2100024002400340200120046a220341106b41f7004b0d0220042005460d01200041406b2203200028020020032802002002784183868c187173220341027441fcf9f36771200373200341047441f0e1c3877f7173200341067441c08183867c7173360200200041046a2100200441016a22044108470d000b0f0b200341f80041dc81c0001007000b200341106b41f80041cc81c0001007000b94051d017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f2000200028021822022000280204220573220a20002802142203200028020c22077373220b20002802102201200773220420052000280200220873220673220c72200120027322102004200873221871732001200028021c220173221120027322162007732213200420052000280208220573220d7322177120012002732202200720087322087322072017732219200471220e732209732212200920112016712002200673221420102003200573220973221a71220f2007200d73737373220d712205200e20022007717322152006201073220e200373221b2008200a73221c71200b200c712003200473737373220373200d2015200e2001200973221571200873200f7373220173220a71200173220820032012732209200120057371200373220673220f200471221d2006200e71220e7320062001201271200971200520097373220473220120147120022003200d71200a712005200a73732202200473220371221273220d733602002000200b2002200873220b7122052008201b71220a732003200f732209201371221320032007712207732214200f201971201d73220f200b200c71220b200220107122107373220c7322037336021c20002001201a7122012006201571220673200373360210200020022018712202200920177173200c73220c20062004201171732206200e7322112001200a732201201273737336020c20002005201373200c7336020420002003200420167120027322047320017336020820002004200f7320052008201c7173732204200b7320117320147336021420002004201073200773200673200d733602180b9a1913017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f230041206b22032400200341186a4200370300200341106a4200370300200341086a42003703002003420037030002400240024020020e020002010b41004100418c81c0001007000b20032001200141106a1005200041c0036a2109410021020340200220036a220c200c280200200220096a28020073360200200241046a22024120470d000b2003100a410021020340200220036a22092009280200220941047620097341809e80f80071220c200973200c41047473360200200241046a22024120470d000b200041c0026a210c200041e0026a210f20004180036a2112200041a0036a211341e800210902400340410021020340200220036a22042004280200200220136a28020073360200200241046a22024120470d000b2003200328021c220441167741bffefcf903712004411e7741c08183867c717220047322022003280210220641167741bffefcf903712006411e7741c08183867c7172200673220e2003280214220573220b73220720042003280218220441167741bffefcf903712004411e7741c08183867c7172200473220a732208732007410c77418f9ebcf80071200741147741f0e1c3877f71727336021c200320022003280200220773220d20042005200541167741bffefcf903712005411e7741c08183867c7172732210732204200741167741bffefcf903712007411e7741c08183867c71722007732207732205732005410c77418f9ebcf80071200541147741f0e1c3877f7172733602002003200a2006200328020c220541167741bffefcf903712005411e7741c08183867c7172200573220a7320027322117322062004732006410c77418f9ebcf80071200641147741f0e1c3877f7172733602182003200b20052003280208220641167741bffefcf903712006411e7741c08183867c7172200673220b7320027322142008201073732205732005410c77418f9ebcf80071200541147741f0e1c3877f71727336021420032002200720032802042202737322072004200a737322052014732005410c77418f9ebcf80071200541147741f0e1c3877f71727336020c20032008200b73200d73220520062002200241167741bffefcf903712002411e7741c08183867c7172732202732206732005410c77418f9ebcf80071200541147741f0e1c3877f71727336020820032007200420087322042002732202732002410c77418f9ebcf80071200241147741f0e1c3877f717273360204200320112004200673200e732202732002410c77418f9ebcf80071200241147741f0e1c3877f7172733602102003100a200941086b2202450440410021020340200220036a22092009280200200020026a28020073360200200241046a22024120470d000b2001411c6a200328021c2200200328021822024101767341d5aad5aa0571220920007322002003280214220c2003280210220f4101767341d5aad5aa05712212200c73220c4102767341b3e6cc99037122132000732200200328020c2204200328020822064101767341d5aad5aa05712205200473220420032802042208200328020022074101767341d5aad5aa0571220e20087322084102767341b3e6cc990371220b200473220441047673418f9ebcf80071220a200073360000200141186a2013410274200c732200200b410274200873220c41047673418f9ebcf800712213200073360000200141146a200a410474200473360000200120022009410174732200200f20124101747322024102767341b3e6cc990371220920007322002006200541017473220f2007200e4101747322124102767341b3e6cc9903712204200f73220f41047673418f9ebcf80071220620007336000c20012013410474200c733600102001200941027420027322002004410274201273220241047673418f9ebcf80071220920007336000820012006410474200f7336000420012009410474200273360000200341206a24000f0b200020094102746a200020024102746a6b4102762202410820024108491b0440410021020340200220036a22042004280200200220126a28020073360200200241046a22024120470d000b0b2003200328021c2204411877200473220220032802102205411877200573220e2003280214220673220b73220720032802182208411877200873220a20047322047320074110777336021c200320022003280200220773220d20082006200641187773221073220620074118772007732207732208732008411077733602002003200a2005200328020c2208411877200873220a7320027322117322052006732005411077733602182003200b200820032802082205411877200573220b732002732208200420107373221073201041107773360214200320082002200720032802042202737322082006200a737322077320074110777336020c20032004200b73200d732207200520022002411877732202732205732007411077733602082003200820022004200673220273220473200441107773360204200320112002200573200e73220273200241107773360210200941106b210e2003100a410021020340200220036a220420042802002002200f6a28020073360200200241046a22024120470d000b2003200328021c22044112774183868c18712004411a7741fcf9f36771722004732202200328021022064112774183868c18712006411a7741fcf9f3677172200673220b2003280214220573220a7322072004200328021822044112774183868c18712004411a7741fcf9f3677172200473220d732208732007410c77418f9ebcf80071200741147741f0e1c3877f71727336021c20032002200328020022077322102004200520054112774183868c18712005411a7741fcf9f367717273221173220420074112774183868c18712007411a7741fcf9f36771722007732207732205732005410c77418f9ebcf80071200541147741f0e1c3877f7172733602002003200d2006200328020c22054112774183868c18712005411a7741fcf9f3677172200573220d7320027322147322062004732006410c77418f9ebcf80071200641147741f0e1c3877f7172733602182003200a2005200328020822064112774183868c18712006411a7741fcf9f3677172200673220a7320027322152008201173732205732005410c77418f9ebcf80071200541147741f0e1c3877f71727336021420032002200720032802042202737322072004200d737322052015732005410c77418f9ebcf80071200541147741f0e1c3877f71727336020c20032008200a7320107322052006200220024112774183868c18712002411a7741fcf9f3677172732202732206732005410c77418f9ebcf80071200541147741f0e1c3877f71727336020820032007200420087322042002732202732002410c77418f9ebcf80071200241147741f0e1c3877f717273360204200320142004200673200b732202732002410c77418f9ebcf80071200241147741f0e1c3877f7172733602102003100a200e200941186b220b490d01410021020340200220036a220420042802002002200c6a28020073360200200241046a22024120470d000b2003200328021c2204411477418f9ebcf800712004411c7741f0e1c3877f7172200473220220032802102206411477418f9ebcf800712006411c7741f0e1c3877f7172200673220e2003280214220573220a732207200420032802182204411477418f9ebcf800712004411c7741f0e1c3877f7172200473220d7322087320074110777336021c2003200220032802002207732210200420052005411477418f9ebcf800712005411c7741f0e1c3877f71727322117322042007411477418f9ebcf800712007411c7741f0e1c3877f71722007732207732205732005411077733602002003200d2006200328020c2205411477418f9ebcf800712005411c7741f0e1c3877f7172200573220d7320027322147322062004732006411077733602182003200a200520032802082206411477418f9ebcf800712006411c7741f0e1c3877f7172200673220a732002732205200820117373221173201141107773360214200320052002200720032802042202737322052004200d737322077320074110777336020c20032008200a732010732207200620022002411477418f9ebcf800712002411c7741f0e1c3877f7172732202732206732007411077733602082003200520022004200873220273220473200441107773360204200320142002200673200e73220273200241107773360210200c4180016b210c200f4180016b210f20124180016b211220134180016b21132003100a200941206b22094178470d000b4178200b41ac81c000100c000b200b200e41bc81c000100c000b41014101419c81c0001007000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c200341b08ac000360208200341013602242003200341206a3602182003200341046a36022820032003360220200341086a2002100e000b3f01017f230041206b220024002000411c6a4100360200200041ec97c0003602182000420137020c200041bc82c000360208200041086a41c482c000100e000bd20101017f230041206b22022400200241013a00182002200136021420022000360210200241cc86c00036020c200241ec97c000360208230041106b22002400200241086a2201280208220245044041ec97c000412b41b498c0001018000b2000200128020c3602082000200136020420002002360200230041106b22012400200141086a200041086a280200360200200120002902003703002001280200220041146a28020021020240024020002802040e020000010b20020d0020012802042d0010102d000b20012802042d0010102d000b100020012000280200200028020410100be50d0b017f017f017f017f017f017f017f017f017f017f017f024002402000280208220a4101472000280210220341014771450440024020034101470d00200120026a2109200041146a28020041016a2107200121040340024020042103200741016b2207450d0020032009460d02027f20032c0000220541004e0440200541ff01712105200341016a0c010b20032d0001413f7121082005411f7121042005415f4d044020044106742008722105200341026a0c010b20032d0002413f7120084106747221082005417049044020082004410c74722105200341036a0c010b2004411274418080f0007120032d0003413f71200841067472722205418080c400460d03200341046a0b2204200620036b6a21062005418080c400470d010c020b0b20032009460d0020032c0000220441004e200441604972200441704972450440200441ff0171411274418080f0007120032d0003413f7120032d0002413f7141067420032d0001413f71410c74727272418080c400460d010b024002402006450d00200220064d04404100210320022006460d010c020b41002103200120066a2c00004140480d010b200121030b2006200220031b21022003200120031b21010b200a450d022000410c6a280200210b024002400240200241104f04402002200141036a417c71220320016b220949200941044b720d02200220096b22084104490d022008410371210a4100210641002104024020012003460d0020094103712105024020032001417f736a4103490440200121030c010b2009417c712107200121030340200420032c000041bf7f4a6a20032c000141bf7f4a6a20032c000241bf7f4a6a20032c000341bf7f4a6a2104200341046a2103200741046b22070d000b0b2005450d000340200420032c000041bf7f4a6a2104200341016a2103200541016b22050d000b0b200120096a21030240200a450d0020032008417c716a22052c000041bf7f4a2106200a4101460d00200620052c000141bf7f4a6a2106200a4102460d00200620052c000241bf7f4a6a21060b20084102762107200420066a21040340200321062007450d04200741c001200741c001491b220941037121082009410274210c0240200941fc0171220a450440410021050c010b2006200a4102746a210d4100210503402003450d01200520032802002205417f734107762005410676724181828408716a200341046a2802002205417f734107762005410676724181828408716a200341086a2802002205417f734107762005410676724181828408716a2003410c6a2802002205417f734107762005410676724181828408716a2105200341106a2203200d470d000b0b200720096b21072006200c6a2103200541087641ff81fc0771200541ff81fc07716a418180046c41107620046a21042008450d000b2006450440410021030c020b2006200a4102746a22062802002203417f73410776200341067672418182840871210320084101460d01200320062802042203417f734107762003410676724181828408716a210320084102460d01200320062802082203417f734107762003410676724181828408716a21030c010b2002450440410021040c030b200241037121050240200241016b410349044041002104200121030c010b2002417c71210741002104200121030340200420032c000041bf7f4a6a20032c000141bf7f4a6a20032c000241bf7f4a6a20032c000341bf7f4a6a2104200341046a2103200741046b22070d000b0b2005450d020340200420032c000041bf7f4a6a2104200341016a2103200541016b22050d000b0c020b200341087641ff811c71200341ff81fc07716a418180046c41107620046a21040c010b2002417c71210541002104200121030340200420032c000041bf7f4a6a20032c000141bf7f4a6a20032c000241bf7f4a6a20032c000341bf7f4a6a2104200341046a2103200541046b22050d000b20024103712206450d004100210503402004200320056a2c000041bf7f4a6a21042006200541016a2205470d000b0b2004200b490440200b20046b22042106024002400240410020002d0020220320034103461b410371220341016b0e020001020b41002106200421030c010b20044101762103200441016a41017621060b200341016a21032000411c6a2802002104200041186a28020021052000280204210002400340200341016b2203450d01200520002004280210110000450d000b41010f0b410121032000418080c400460d02200520012002200428020c1101000d024100210303402003200646044041000f0b200341016a2103200520002004280210110000450d000b200341016b2006490f0b0c020b2000280218200120022000411c6a28020028020c11010021030b20030f0b2000280218200120022000411c6a28020028020c1101000b0e0020002802001a03400c000b000b0300010b0c0042b889cf9789c6d1f84c0b8d070e017f017f017f017f017f017f017e017e017f017f017f017f017f017f230041306b2207240020002802002203ad210841272100024020034190ce00490440200821090c010b0340200741096a20006a220341046b20084290ce0080220942f0b1037e20087ca7220241ffff037141e4006e2204410174419187c0006a2f00003b0000200341026b2004419c7f6c20026a41ffff0371410174419187c0006a2f00003b0000200041046b2100200842ffc1d72f5621032009210820030d000b0b2009a7220241e3004b0440200041026b2200200741096a6a2009a7220341ffff037141e4006e2202419c7f6c20036a41ffff0371410174419187c0006a2f00003b00000b02402002410a4f0440200041026b2200200741096a6a2002410174419187c0006a2f00003b00000c010b200041016b2200200741096a6a200241306a3a00000b412720006b210441012102412b418080c4002001280200220341017122051b210a2003411d74411f7541ec97c00071210b200741096a20006a210c02402001280208450440200141186a28020022002001411c6a2802002201200a200b10150d012000200c2004200128020c11010021020c010b02400240024002402001410c6a2802002206200420056a22024b044020034108710d04200620026b22022103410120012d0020220020004103461b410371220041016b0e020102030b41012102200141186a28020022002001411c6a2802002201200a200b10150d042000200c2004200128020c11010021020c040b41002103200221000c010b20024101762100200241016a41017621030b200041016a21002001411c6a2802002105200141186a28020021062001280204210102400340200041016b2200450d01200620012005280210110000450d000b410121020c020b410121022001418080c400460d0120062005200a200b10150d012006200c2004200528020c1101000d0141002100027f0340200320002003460d011a200041016a2100200620012005280210110000450d000b200041016b0b20034921020c010b2001280204210e2001413036020420012d0020210f41012102200141013a0020200141186a28020022032001411c6a280200220d200a200b10150d00200020066a20056b41266b21000340200041016b2200044020034130200d280210110000450d010c020b0b2003200c2004200d28020c1101000d002001200f3a00202001200e360204410021020b200741306a240020020b39000240027f2002418080c40047044041012000200220012802101100000d011a0b20030d0141000b0f0b200020034100200128020c1101000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c200341dc89c000360208200341013602242003200341206a3602182003200341046a36022820032003360220200341086a2002100e000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c200341fc89c000360208200341013602242003200341206a3602182003200341046a36022820032003360220200341086a2002100e000b4701017f230041206b22032400200341146a4100360200200341ec97c000360210200342013702042003200136021c200320003602182003200341186a36020020032002100e000b140020002802002001200028020428020c1100000b98050b017f017f017f017f017f017f017f017f017f017f017f230041306b22022400200241246a41dc88c000360200200241033a0028200242808080808004370308200220003602202002410036021820024100360210027f024002402001280208220a450440200141146a2802002200450d012001280210210320004103742105200041016b41ffffffff017141016a2107200128020021000340200041046a28020022040440200228022020002802002004200228022428020c1101000d040b2003280200200241086a200341046a2802001100000d03200341086a2103200041086a2100200541086b22050d000b0c010b2001410c6a2802002200450d002000410574210b200041016b41ffffff3f7141016a2107200128020021000340200041046a28020022030440200228022020002802002003200228022428020c1101000d030b20022005200a6a2204411c6a2d00003a00282002200441046a290200422089370308200441186a2802002106200128021021084100210941002103024002400240200441146a28020041016b0e020002010b200641037420086a220c41046a2802004102470d01200c28020028020021060b410121030b2002200636021420022003360210200441106a28020021030240024002402004410c6a28020041016b0e020002010b200341037420086a220641046a2802004102470d01200628020028020021030b410121090b2002200336021c20022009360218200820042802004103746a2203280200200241086a20032802041100000d02200041086a2100200b200541206a2205470d000b0b200128020420074b04402002280220200128020020074103746a22002802002000280204200228022428020c1101000d010b41000c010b41010b2100200241306a240020000b950608017f017f017f017f017f017f017f017f02402002450d004100200241076b220420022004491b2109200141036a417c7120016b210a410021040340024002400240024002400240024002400240200120046a2d00002207411874411875220841004e0440200a20046b410371200a417f46720d0120042009490d020c080b410121064101210302400240024002400240024002400240200741cc8bc0006a2d000041026b0e030001020e0b200441016a22052002490d06410021030c0d0b41002103200441016a220520024f0d0c200120056a2c00002105200741e0016b2203450d012003410d460d020c030b2002200441016a22034d0440410021030c0c0b200120036a2c00002105024002400240200741f0016b0e050100000002000b2008410f6a41ff017141024b0440410121030c0e0b20054100480d09410121030c0d0b200541f0006a41ff01714130490d090c0b0b2005418f7f4a0d0a0c080b200541607141a07f470d090c020b200541a07f4e0d080c010b02402008411f6a41ff0171410c4f04402008417e71416e470440410121030c0b0b20054100480d01410121030c0a0b200541bf7f4a0d080c010b41012103200541404f0d080b41002103200441026a220520024f0d07200120056a2c000041bf7f4c0d0541012103410221060c070b200120056a2c000041bf7f4a0d050c040b200441016a21040c070b0340200120046a2203280200418081828478710d06200341046a280200418081828478710d062009200441086a22044b0d000b0c050b41012103200541404f0d030b2002200441026a22034d0440410021030c030b200120036a2c000041bf7f4a044041022106410121030c030b41002103200441036a220520024f0d02200120056a2c000041bf7f4c0d0041032106410121030c020b200541016a21040c030b410121030b20002004360204200041096a20063a0000200041086a20033a0000200041013602000f0b200220044d0d000340200120046a2c00004100480d012002200441016a2204470d000b0c020b200220044b0d000b0b20002001360204200041086a2002360200200041003602000b6101017f230041106b220324002003200136020c20032000360208230041206b22002400200041146a410136020020004201370204200041c486c0003602002000410336021c2000200341086a3602182000200041186a36021020002002100e000bd8040b017f017f017f017f017f017f017f017f017f017f017f2000280204210a2000280200210b2000280208210c0240034020050d010240024020022004490d000340200120046a210602400240024002400240200220046b220541084f0440200641036a417c7122002006460d02200020066b2200200520002005491b2200450d02410021030340200320066a2d0000410a460d06200341016a22032000470d000b0c010b20022004460440200221040c070b410021030340200320066a2d0000410a460d052005200341016a2203470d000b200221040c060b2000200541086b22034b0d020c010b200541086b2103410021000b03400240200020066a22072802002209417f732009418a94a8d0007341818284086b71418081828478710d00200741046a2802002207417f732007418a94a8d0007341818284086b71418081828478710d00200041086a220020034d0d010b0b200020054d0d0020002005419889c0001016000b20002005460440200221040c030b0340200020066a2d0000410a460440200021030c020b2005200041016a2200470d000b200221040c020b0240200320046a220041016a2204452002200449720d00200020016a2d0000410a470d004100210520042103200421000c030b200220044f0d000b0b410121052002220020082203460d020b0240200c2d00000440200b418887c0004104200a28020c1101000d010b200120086a2106200020086b210741002109200c2000200847047f200620076a41016b2d0000410a460520090b3a000020032108200b20062007200a28020c110100450d010b0b4101210d0b200d0be60101017f230041106b220224002002410036020c20002002410c6a027f20014180014f044020014180104f04402001418080044f044020022001413f71418001723a000f20022001410676413f71418001723a000e20022001410c76413f71418001723a000d2002200141127641077141f001723a000c41040c030b20022001413f71418001723a000e20022001410c7641e001723a000c20022001410676413f71418001723a000d41030c020b20022001413f71418001723a000d2002200141067641c001723a000c41020c010b200220013a000c41010b101d2100200241106a240020000b5501017f230041206b2202240020022000360204200241186a200141106a290200370300200241106a200141086a29020037030020022001290200370308200241046a200241086a101a2100200241206a240020000b0d00200028020020012002101d0bed0101017f230041106b22022400200028020021002002410036020c20002002410c6a027f20014180014f044020014180104f04402001418080044f044020022001413f71418001723a000f20022001410676413f71418001723a000e20022001410c76413f71418001723a000d2002200141127641077141f001723a000c41040c030b20022001413f71418001723a000e20022001410c7641e001723a000c20022001410676413f71418001723a000d41030c020b20022001413f71418001723a000d2002200141067641c001723a000c41020c010b200220013a000c41010b101d2100200241106a240020000b5801017f230041206b2202240020022000280200360204200241186a200141106a290200370300200241106a200141086a29020037030020022001290200370308200241046a200241086a101a2100200241206a240020000b9d0205017f017f017f017f017f230041406a220024004101210202402001280218220341cc8dc00041112001411c6a280200220528020c22041101000d000240200128020022064104714504402003419087c000410120041101000d02200141f488c00041021010450d010c020b2003418e87c000410220041101000d01200041013a0017200041346a41f086c0003602002000200536020c2000200336020820002006360218200020012d00203a00382000200128020436021c20002001290210370328200020012902083703202000200041176a3602102000200041086a360230200041186a41f488c000410210100d01200041086a418c87c0004102101d0d010b2003418086c0004101200411010021020b200041406b240020020b5b01017f02402001450440410121030c010b200141004e04402001100421030240200204402003450d01200341046b2d0000410371450d0320032001102e1a0c030b20030d020b000b100d000b20002001360204200020033602000bcc0103017f017f017f230041206b220224004103210341dd8dc000210420012d00004103460440200241106a200141016a2201027f024020012d0000450440410021010c010b200141016a2103410021010340200120036a2104200141016a210120042d00000d000b0b20010b101b41e08dc0002002280214200228021022011b21044103200241186a28020020011b21030b200241086a200341001024200228020821012000200228020c36020420002001360200200120042003102f1a20002003360208200241206a24000ba3481d017f017f017f017f017f017f017f017f017e017e017f017f017f017f017f017f017f017e017f017e017e017e017e017e017e017f017f017f017f230041900c6b22022400200241286a20001025200241386a2001102520022802382107200228023c210820022802402101200241f0096a1027200241003602880b41c0002100200241880b6a41047241c000102e1a0340200041016b22000d000b200241c0003602880b20024180056a2204200241880b6a41c400102f1a200241800a6a2200200441047241c000102f1a2002410036029801200241e4016a41f096c000290200370200200241ec016a41f896c000290200370200200241f4016a418097c000290200370200200241e896c0002902003702dc012002419c016a200041c000102f210020022001ad4203863703900102402001413f4d0440200020072001102f1a0c010b200241dc016a2007200141067610282000200720014140716a2001413f712201102f1a0b2002200136029801200241940b6a42003702002002419c0b6a4200370200200241a40b6a42003702002002420037028c0b200241003602880b412021000340200041016b22000d000b200241203602880b20024180056a2201200241880b6a4124102f1a20024188096a2002419c056a29020037030020024180096a20024194056a290200370300200241f8086a2002418c056a220029020037030020022002290284053703f008200120024190016a41f000102f1a200241cc056a2105200229038005210b0240200228028805220441c000470440200441c000490d01200441c00041b896c0001007000b20052000410110284100210420024100360288050b2002418c056a220120046a4180013a00002002200228028805220341016a2200360288050240024002400240024002400240024002400240024002400240024002400240024002400240200041c100490440200020016a413f20036b102e1a20022802880541396b41084904402005200141011028200228028805220041c1004f0d0220012000102e1a0b200241c4056a200b42288642808080808080c0ff0083200b42388684200b421886428080808080e03f83200b4208864280808080f01f838484200b42088842808080f80f83200b421888428080fc078384200b4228884280fe0383200b42388884848437020020052001410110282002410036028805200241980a6a200541186a290200370300200241900a6a200541106a290200370300200241880a6a200541086a290200370300200220052902003703800a20024280808080c000370284012002412036027c200220024190096a360280012002200241f0086a360278200241f8006a22052802102204450440419094c000411941f893c0001018000b20052802002101200241880b6a220620052802042200360204200620013602002006410036021c2006200241800a6a2201360214200620043602102006200020046e2204360224200641186a200241a00a6a22003602002006200529020837020820062004200020016b4102762200200020044b1b360220024020022802a40b220120022802a80b22004f0d00200020016b210320022802880b2205200120022802980b22096c6a2104200228029c0b20014102746a21012009410446210003402005450d012002200128020022064118742006410874418080fc07717220064108764180fe0371200641187672723602782000450d0420042002280278360000200420096a2104200141046a2101200341016b22030d000b0b200241d0006a200241f8086a290300370300200241d8006a20024180096a290300370300200241e0006a20024188096a290300370300200241f0006a200241f8096a290300370300200220022903f008370348200220022903f00937036820080440200710030b2002280230220f41036a2200200f490d03200228022c211e2002280228211c200241206a200041027641036c4100102420024100360288052002200228022422013602840520022002280220220836028005200f41076a2200200f490d042000410376220d41066c210c200041084f0440410021002001200c490440230041206b2204240020024180056a220728020422054101742200200c2000200c4b1b22004108200041084b1b2201417f73411f7621000240200504402004410136021820042005360214200420072802003602100c010b200441003602180b200441106a21082004027f0240027f0240200004400240200141004e044020082802080d010c030b200441086a41003602000c040b20082802042205450d01027f2008280200210e02400240024002400240200041094f044020012000100022140d0141000c060b200141ccff7b4b0d0241102001410b6a4178712001410b491b2110200e41046b221128020022064178712108024002400240024020064103710440200e41086b2112200820104f0d01200820126a221b41e89bc000280200460d02201b41e49bc000280200460d03201b28020422064102710d062008200641787122056a220920104f0d040c060b201041800249200820104104724972200820106b418180084f720d050c080b200820106b22144110490d07201120064101712010724102723602000c060b41e09bc00028020020086a220520104d0d0320112006410171201072410272360200201020126a2208200520106b220541017236020441e09bc000200536020041e89bc00020083602000c060b41dc9bc00028020020086a22052010490d020240200520106b2208410f4d044020112006410171200572410272360200200520126a22052005280204410172360204410021080c010b20112006410171201072410272360200201020126a22142008410172360204200820146a2205200836020020052005280204417e713602040b41e49bc000201436020041dc9bc00020083602000c050b200920106b2114024020054180024f0440201b10020c010b201b410c6a2802002208201b41086a28020022054704402005200836020c200820053602080c010b41cc98c00041cc98c000280200417e200641037677713602000b201441104f0440201120112802004101712010724102723602000c040b20112011280200410171200972410272360200200920126a220520052802044101723602040c040b2014200e20052001200120054b1b102f1a200e10030c010b200110042205450d002005200e417c4178201128020022054103711b20054178716a22052001200120054b1b102f2105200e100320050c030b20140c020b201020126a22082014410372360204200820146a220520052802044101723602042008201410010b200e0b0c020b20042001360204200441086a41003602000c020b2001200010000b2205044020042005360204200441086a200136020041000c020b20042001360204200441086a20003602000b41010b360200024020042802004504402004280204210020072001360204200720003602000c010b200441086a2802002200418180808078460d0020000440000b100d000b200441206a2400200228028005210820022802880521000b200020086a200c41016b2201102e1a2008200020016a22006a41003a0000200041016a210c20022802800521080b2002200c3602880502400240024002400240024002400240200f41077122000e06000102030401050b410821000c040b42012113200f0d040c100b410a21000c020b410b21000c010b410c21000b410021054100200f20006b22002000200f4b1b220941206b220120094d0d01410021060c0a0b201c200f41016b22036a2d00002200413d460d0b2000419883c0006a2d000041ff01470d0b0c0a0b410021064100210302400240034020034160460d08200341206a2205200f4b0d092006411a6a200c4b0d0a2003201c6a22072d00002200419883c0006a310000221542ff01510d0d200741016a2d00002200419883c0006a310000221642ff01510440200341016a21030c0e0b200741026a2d00002200419883c0006a310000221742ff01510440200341026a21030c0e0b200741036a2d00002200419883c0006a310000221842ff01510440200341036a21030c0e0b200741046a2d00002200419883c0006a310000221942ff01510440200341046a21030c0e0b200741056a2d00002200419883c0006a310000221a42ff01510440200341056a21030c0e0b200741066a2d00002200419883c0006a310000220b42ff01510440200341066a21030c0e0b200741076a2d00002200419883c0006a310000220a42ff01510440200341076a21030c0e0b200620086a220420164234862015423a86842017422e8684201842288684201942228684201a421c8684200b42168684220b200a42108684220a421886428080808080e03f83200b4208864280808080f01f8384200a42088842808080f80f83200a421888428080fc078384200a4228884280fe0383200a423888848484370000200741086a2d00002200419883c0006a310000221542ff01510d02200741096a2d00002200419883c0006a310000221642ff01510440200341096a21030c0e0b2007410a6a2d00002200419883c0006a310000221742ff015104402003410a6a21030c0e0b2007410b6a2d00002200419883c0006a310000221842ff015104402003410b6a21030c0e0b2007410c6a2d00002200419883c0006a310000221942ff015104402003410c6a21030c0e0b2007410d6a2d00002200419883c0006a310000221a42ff015104402003410d6a21030c0e0b2007410e6a2d00002200419883c0006a310000220b42ff015104402003410e6a21030c0e0b2007410f6a2d00002200419883c0006a310000220a42ff015104402003410f6a21030c0e0b200441066a20164234862015423a86842017422e8684201842288684201942228684201a421c8684200b42168684220b200a42108684220a421886428080808080e03f83200b4208864280808080f01f8384200a42088842808080f80f83200a421888428080fc078384200a4228884280fe0383200a423888848484370000200741106a2d00002200419883c0006a310000221542ff01520440200741116a2d00002200419883c0006a310000221642ff01510440200341116a21030c0f0b200741126a2d00002200419883c0006a310000221742ff01510440200341126a21030c0f0b200741136a2d00002200419883c0006a310000221842ff01510440200341136a21030c0f0b200741146a2d00002200419883c0006a310000221942ff01510440200341146a21030c0f0b200741156a2d00002200419883c0006a310000221a42ff01510440200341156a21030c0f0b200741166a2d00002200419883c0006a310000220b42ff01510440200341166a21030c0f0b200741176a2d00002200419883c0006a310000220a42ff01510440200341176a21030c0f0b2004410c6a20164234862015423a86842017422e8684201842288684201942228684201a421c8684200b42168684220b200a42108684220a421886428080808080e03f83200b4208864280808080f01f8384200a42088842808080f80f83200a421888428080fc078384200a4228884280fe0383200a423888848484370000200741186a2d00002200419883c0006a310000221542ff01510d02200741196a2d00002200419883c0006a310000221642ff01510440200341196a21030c0f0b2007411a6a2d00002200419883c0006a310000221742ff015104402003411a6a21030c0f0b2007411b6a2d00002200419883c0006a310000221842ff015104402003411b6a21030c0f0b2007411c6a2d00002200419883c0006a310000221942ff015104402003411c6a21030c0f0b2007411d6a2d00002200419883c0006a310000221a42ff015104402003411d6a21030c0f0b2007411e6a2d00002200419883c0006a310000220b42ff015104402003411e6a21030c0f0b2007411f6a2d00002200419883c0006a310000220a42ff015104402003411f6a21030c0f0b200441126a20164234862015423a86842017422e8684201842288684201942228684201a421c8684200b42168684220b200a42108684220a421886428080808080e03f83200b4208864280808080f01f8384200a42088842808080f80f83200a421888428080fc078384200a4228884280fe0383200a423888848484370000200d41046b210d200641186a2106200120052203490d0c0c010b0b200341106a21030c0c0b200341186a21030c0b0b200341086a21030c0a0b200041c00041c896c0001016000b200041c00041d896c0001017000b230041306b2200240020004104360204200020093602002000411c6a41023602002000412c6a41013602002000420337020c200041b48bc000360208200041013602242000200041206a360218200020003602282000200041046a360220200041086a41dc97c000100e000b41f890c0004123419c91c000101c000b41d482c0004133418883c000101c000b4160410041ac91c000100c000b200341206a200f41ac91c0001017000b2006411a6a200c41bc91c0001017000b02402009200941086b220149200120054d724504400240024002400240034020054178460d01200541086a2203200f4b0d02200641774b0d03200641086a200c4b0d042005201c6a22042d00002200419883c0006a310000221542ff01510440200521030c090b200441016a2d00002200419883c0006a310000221642ff01510440200541017221030c090b200441026a2d00002200419883c0006a310000221742ff01510440200541027221030c090b200441036a2d00002200419883c0006a310000221842ff01510440200541037221030c090b200441046a2d00002200419883c0006a310000221942ff01510440200541047221030c090b200441056a2d00002200419883c0006a310000221a42ff01510440200541057221030c090b200441066a2d00002200419883c0006a310000220b42ff01510440200541067221030c090b200441076a2d00002200419883c0006a310000220a42ff01520440200620086a20164234862015423a86842017422e8684201842288684201942228684201a421c8684200b42168684220b200a42108684220a421886428080808080e03f83200b4208864280808080f01f8384200a42088842808080f80f83200a421888428080fc078384200a4228884280fe0383200a423888848484370000200d41016b210d200641066a210620032105200120034d0d070c010b0b200541077221030c070b4178200541086a41cc91c000100c000b200541086a200f41cc91c0001017000b2006200641086a41dc91c000100c000b200641086a200c41dc91c0001017000b200521030b024002400240024002400240024002400240024002400240024002400240024002400240024002400240200d4102490440200621050c010b200d41016b210d410020036b211103402003200f4b0d02200641794b0d03200641066a2205200c4b0d042003200f460d052003201c6a22042d00002200419883c0006a310000221542ff01510d17200f20116a22014102490d06200441016a2d00002200419883c0006a310000221642ff01510d07200141024d0d08200441026a2d00002200419883c0006a310000221742ff01510d09200141034d0d0a200441036a2d00002200419883c0006a310000221842ff01510d0b200141044d0d0c200441046a2d00002200419883c0006a310000221942ff01510d0d200141054d0d0e200441056a2d00002200419883c0006a310000221a42ff01510d0f200141064d0d10200441066a2d00002200419883c0006a310000220b42ff01510d11200141074d0d12200441076a2d00002200419883c0006a310000220a42ff01510d13200620086a220041046a20164234862015423a86842017422e8684201842288684201942228684201a421c8684200b42168684220b200a42108684220a421886428080808080e03f83200b4208864280808080f01f83844220883d00002000200a42088842808080f80f83200a421888428080fc078384200a4228884280fe0383200a42388884843e0000201141086b2111200341086a210320052106200d41016b220d0d000b0b2003200f4d04402003200f460440410021004100210741002101410021040c150b200f201c6a21122003201c6a210641002104410021114100210d410021070240027f0240024003404100210103402001201d6a210e2001200d6a2109200120066a221b2d00002200413d470440200941004a0d042000419883c0006a310000220b42ff01510d06200e41016a211d200b200741016a2207413a6c413e71ad862013842113200021042009210d201b41016a22062012470d020c1a0b200e410271450d022011200e20091b21112006200141016a22016a2012470d000b0b200421000c170b2011200e2001200d6a41004a1b20036a0c010b200320116a0b2103413d21000c160b2003201d6a20016a21030c150b2003200f418c92c0001016000b2003200f41ec91c0001016000b2006200641066a41fc91c000100c000b200641066a200c41fc91c0001017000b4100410041f88fc0001007000b41012001418890c0001007000b200341016a21030c0f0b41024102419890c0001007000b200341026a21030c0d0b4103410341a890c0001007000b200341036a21030c0b0b4104410441b890c0001007000b200341046a21030c090b4105410541c890c0001007000b200341056a21030c070b4106410641d890c0001007000b200341066a21030c050b4107410741e890c0001007000b200341076a21030c030b41002101027f0240024002400240024002400240200722040e09080001020300040506000b230041206b22002400200041146a410136020020004201370204200041988fc0003602002000410536021c200041f092c0003602182000200041186a360210200041f892c000100e000b41080c050b41100c040b41180c030b41200c020b41280c010b41300b2104410121010b20132004ad8650044002400240200104402005200c2005200c4b1b21034100210141382100034020032005460d02200520086a20132000413871ad883c0000200041086b2100200541016a2105200141086a22012004490d000b0b20022002280288052200200520002005491b360288052002290284052113200228028005221d450d05200241e8006a210341002101200241186a2013422088a7220e41001024200228021c210520022802182208201d200e102f210720024190016a220041e003102e1a2000200241c8006a220020001005200241b0016a200241d8006a22002000100541c0002106410821040c010b2003200c418893c0001007000b034020024190016a220920041006200120096a220d41406b2200100820002000280200417f73360200200d41c4006a22002000280200417f73360200200d41d4006a22002000280200417f73360200200d41d8006a22002000280200417f73360200200620096a2200200028020041808003733602002009200441086a2209410e1009200141800347044020024190016a220420091006200d41e0006a2200100820002000280200417f73360200200d41e4006a22002000280200417f73360200200d41f4006a22002000280200417f73360200200d41f8006a22002000280200417f733602002004200941086a220441061009200641c4006a2106200141406b21010c010b0b410021004108210602400240024002400340024002402000410171450440200641e8004f0d010c020b20062006411f6a22064b0d00200641e800490d010b41a0032100034020024190016a20006a220120012802002204410476200473418098bc1871220120047320014104747322044102762004734180e6809803712201200473200141027473360200200041046a220041c003470d000b41002101034020024190016a20016a220441206a22002000280200417f73360200200441246a22002000280200417f73360200200441346a22002000280200417f73360200200441386a22002000280200417f73360200200141206a220141c003470d000b200241f0046a2003102920024180056a20024190016a41f003102f1a0240024002400240200e410f710d00200241003602800a200e4107762101410421002007200e41807f716a210c0340200241800a6a20006a1027200220022802800a41016a3602800a200041106a2200418401470d000b200241880b6a2204200241800a6a418401102f1a200241f0086a22002004410472418001102f1a2000200241e0086a22121029200e4180014f0440200720014107746a211b20024180096a210d200721040340200d200441f000102f1a200241880b6a200441f0006a10294108210020042101034020024180056a20012000410220004102491b2203100b200120034104746a2101200020036b22000d000b20044180016a210941002106200241f0086a21030340200641016a2106410021000340200020046a220120012d0000200020036a2d0000733a0000200041016a22004110470d000b200441106a2104200341106a210320064108470d000b200241f8086a200241900b6a290300370300200220022903880b3703f00820092204201b470d000b0b200241880b6a200241f0086a1029201241086a2206200241900b6a2209290300370000201220022903880b370000200241f0096a20121029200e41047641077122000440200c20004104746a21030340200241f8006a200c1029200241800a6a1027410021000340200241880b6a20006a220120022903800a370000200141086a200241880a6a290300370000200041106a22004120470d000b2009200c41086a22002900003703002002200c2900003703880b20024180056a200241880b6a4102100b20002009290300370000200c20022903880b370000200c41106a21044100210003402000200c6a220120012d0000200241f0096a20006a2d0000733a0000200041016a22004110470d000b200241f8096a20024180016a290300370300200220022903783703f0092004220c2003470d000b0b201220022903f0093702002006200241f8096a290300370200200e450d002007200e41016b22006a2d00002206452006200e4b720d002000200e20066b2201490d01410020066b21002007200e6a210303402000417f460d03200020036a2104200041016a210020042d00002006460d000b0b410521044100210020050440200710030b0c020b2001200041f085c000100c000b41062104410121000b2013a70440201d10030b201e0440201c10030b2000450d0a20024180056a20072001101b0240200228028005044020024188056a2d000022044102470d010b410f10042203450d0c200341076a419f93c0002900003700002003419893c0002900003700000c0f0b410f10042200450d0b200041076a419f93c0002900003700002000419893c0002900003700002000210320044106460d0e0c0d0b200641086a220d41f90049044020024190016a20064102746a2104410021000340200020046a220120012802002209410476200973418098bc1871220120097320014104747322094102762009734180e6809803712201200973200141027473360200200041046a22004120470d000b200641106a220c200d490d02200c41f8004b0d0320024190016a200d4102746a2104410021000340200020046a22012001280200220941047620097341809e80f800712201200973200141047473360200200041046a22004120470d000b200641186a2200200c490d04200041f8004b0d05200641016a210620024190016a200c4102746a2104410021000340200020046a220120012802002209410476200973418086bce00071220120097320014104747322094102762009734180e6809803712201200973200141027473360200200041046a22004120470d000b410121000c010b0b200d41f80041dc80c0001017000b200d200c41ec80c000100c000b200c41f80041ec80c0001017000b200c200041fc80c000100c000b200041f80041fc80c0001017000b200320076a41016b2103420221130c010b420021130b2003ad4220862000ad42ff0183420886842013842113200228028405450d0020022802800510030b201e0440201c10030b2013422088a721052013a72108410321040b410f100422000d010b000b200041076a419f93c0002900003700002000419893c0002900003700000b027f0240024002400240200441026b22014102200141ff01714104491b41ff01710e03000201020b200841ff01714103470d0120052802002005280204280200110300410f21012005280204280204450d02200528020010030c020b410f21012005450d0020080c020b41112103200241086a4111410110242002280208220441033a0000410f2101410f21050c030b20050b2103410f2105200021080b20031003200241106a200141026a2203410110242003450d012002280210220441033a0000200821002001417f470d00230041206b220024002000411c6a4100360200200041ec97c0003602182000420137020c200041ec8ac000360208200041086a41cc8ec000100e000b200441016a20002001102f1a2003200141016a22014d0d01200120046a41003a000020050440200010030b200241900c6a240020040f0b4100410041bc8ec0001007000b2001200341dc8ec0001007000b7e02017f017f230041306b2201410c6a42003702002001420037020420014100360200411021020340200241016b22020d000b20014110360200200141206a200141086a290300370300200141286a200141106a280200360200200120012903003703182000200129021c370000200041086a200141246a2902003700000be42f26017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f017f230041a0016b22032400200341c000102e2103200028021c2123200028021821242000280214211f20002802102120200028020c212520002802082126200028020421212000280200212220020440200120024106746a2127200341406b2128034020034280808080c00037027420032001360268200341c00036026c2003200141406b2201360270200341406b210420282102200341e8006a2205280210220f450440419094c000411941ac94c0001018000b2005280204210e200420052802003602082004410036021c20042002360204200420033602002004410c6a200e360200200441186a200f360200200441106a20052902083702002004200220036b410276220236022420042002200e200f6e220420022004491b3602200240200328025c2202200328026022044f0d00200420026b210f2002410274220420032802406a2102200328024820046a21042003280258210e0340200e41044604402002200428000022054118742005410874418080fc07717220054108764180fe037120054118767272360200200241046a2102200441046a2104200f41016b220f0d010c020b0b230041406a220024002000412b36020c200041bc94c000360208200041e894c0003602142000200341e8006a3602102000412c6a41023602002000413c6a41043602002000420237021c200041e086c000360218200041033602342000200041306a3602282000200041106a3602382000200041086a360230200041186a41d095c000100e000b200328023c21162003280238211d2003280234211e2003280230210e200328022c2117200328022821182003280224211920032802202113200328021c211a2003280218211b2003280214211c20032802102111200328020c210f200328020821122003280204211420032802002115200320263602682003202536026c20032024360270200320233602742003201f36024c20032020360248200320213602442003202236024020034190016a2202200341e8006a2204200341406b22052014419189dd89076a20154198dfa894046a102a200328029001211020032802940121062003280298012107200328029c0121082003201f360274200320203602702003202136026c200320223602682003200836024c200320073602482003200636024420032010360240200220042005200f41dbc8a8b2016b201241b188fcd1046b102a2003280290012109200328029401210a200328029801210b200328029c01210c20032008360274200320073602702003200636026c200320103602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201c41f1a3c4cf056a201141db84dbca036a102a200328029001211020032802940121062003280298012107200328029c0121082003200c3602742003200b3602702003200a36026c200320093602682003200836024c200320073602482003200636024420032010360240200220042005201a41abc28ea7056b201b41dcfa81ee066b102a2003280290012109200328029401210a200328029801210b200328029c01210c20032008360274200320073602702003200636026c200320103602682003200c36024c2003200b3602482003200a3602442003200936024020022004200520194181b68d94016a201341e8aae1bf026b102a200328029001211020032802940121062003280298012107200328029c0121082003200c3602742003200b3602702003200a36026c200320093602682003200836024c200320073602482003200636024420032010360240200220042005201741c3fbb1a8056a201841be8bc6a1026a102a2003280290012109200328029401210a200328029801210b200328029c01210c20032008360274200320073602702003200636026c200320103602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201e41829c85f9076b200e41f4baf995076a102a200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c2003200836024820032007360244200320063602402002200420052016418c9d90f3036b201d41d9f28fa1066b102a2003280290012109200328029401210a200328029801210b200328029c01210c2003201536029c01200320143602980120032012360294012003200f3602900120032013360274200320193602702003201836026c200320173602682003200e36024c2003201e3602482003201d3602442003201636024020034180016a220f2002201120042005102b200328028001211420032802840121152003280288012110200328028c0121122003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201041faf08682016b201241bfac92db016b102a200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201441ccc3b2a0026a201541c6bb86fe006a102a2003280290012109200328029401210a200328029801210b200328029c01210c2003201136029c012003201c360298012003201b360294012003201a360290012003200e3602742003201e3602702003201d36026c200320163602682003201236024c200320103602482003201536024420032014360240200f2002201320042005102b200328028001211a200328028401211b200328028801211c200328028c0121112003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201c41aa89d2d3046a201141efd8a4ef026a102a200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201a41da91e6b7076a201b41dcd3c2e5056a102a2003280290012109200328029401210a200328029801210b200328029c01210c2003201336029c0120032019360298012003201836029401200320173602900120032012360274200320103602702003201536026c200320143602682003201136024c2003201c3602482003201b3602442003201a360240200f2002200e20042005102b200328028001211720032802840121182003280288012119200328028c0121132003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a3602442003200936024020022004200520194193f3b8be056b201341aedd86be066b102a200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201741b9809a85046b201841b8b0f3ff046b102a2003280290012109200328029401210a200328029801210b200328029c01210c2003200e36029c012003201e360298012003201d360294012003201636029001200320113602742003201c3602702003201b36026c2003201a3602682003201336024c200320193602482003201836024420032017360240200f2002201220042005102b2003280280012116200328028401211d200328028801211e200328028c01210e2003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201e41b9dde1d2026b200e418de8ffc8036b102a200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201641e7d2a4a1016a201d41d1c6a9366a102a2003280290012109200328029401210a200328029801210b200328029c01210c2003201236029c0120032010360298012003201536029401200320143602900120032013360274200320193602702003201836026c200320173602682003200e36024c2003201e3602482003201d36024420032016360240200f2002201120042005102b200328028001211420032802840121152003280288012110200328028c0121122003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201041b8c2ecf0026a2012418595dcbd026a102a200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201441939ae099056a201541fcdbb1e9046a102a2003280290012109200328029401210a200328029801210b200328029c01210c2003201136029c012003201c360298012003201b360294012003201a360290012003200e3602742003201e3602702003201d36026c200320163602682003201236024c200320103602482003201536024420032014360240200f2002201320042005102b200328028001211a200328028401211b200328028801211c200328028c0121112003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201c41bb95a8b3076a201141d4e6a9a8066a102a200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201a41fba6b7ec066b201b41d2edf4f1076b102a2003280290012109200328029401210a200328029801210b200328029c01210c2003201336029c0120032019360298012003201836029401200320173602900120032012360274200320103602702003201536026c200320143602682003201136024c2003201c3602482003201b3602442003201a360240200f2002200e20042005102b200328028001211720032802840121182003280288012119200328028c0121132003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201941b5b396bf056b201341dfae80ea056b102a200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201741dddccec4036b20184190e9d1ed036b102a2003280290012109200328029401210a200328029801210b200328029c01210c2003200e36029c012003201e360298012003201d360294012003201636029001200320113602742003201c3602702003201b36026c2003201a3602682003201336024c200320193602482003201836024420032017360240200f2002201220042005102b2003280280012116200328028401211d200328028801211e200328028c01210e2003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201e41dcf39bcb026b200e41e7afb4f3026b102a200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201641f0c0aa83016a201d41fb94c7df006b102a2003280290012109200328029401210a200328029801210b200328029c01210c2003201236029c0120032010360298012003201536029401200320143602900120032013360274200320193602702003201836026c200320173602682003200e36024c2003201e3602482003201d36024420032016360240200f2002201120042005102b200328028001211420032802840121152003280288012110200328028c0121122003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a3602442003200936024020022004200520104188d8ddf1016a201241968293cd016a102a200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201441b5f9c2a5036a201541cceea1ba026a102a2003280290012109200328029401210a200328029801210b200328029c01210c2003201136029c012003201c360298012003201b360294012003201a360290012003200e3602742003201e3602702003201d36026c200320163602682003201236024c200320103602482003201536024420032014360240200f2002201320042005102b2003280280012111200328028401211a200328028801211b200328028c01211c2003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201b41cad4e2f6046a201c41b399f0c8036a102a200328029001210620032802940121072003280298012108200328029c01210d2003200c3602742003200b3602702003200a36026c200320093602682003200d36024c200320083602482003200736024420032006360240200220042005201141f3dfb9c1066a201a41cf94f3dc056a102a2003280290012109200328029401210a200328029801210b200328029c01210c2003201336029c0120032019360298012003201836029401200320173602900120032012360274200320103602702003201536026c200320143602682003201c36024c2003201b3602482003201a36024420032011360240200f2002200e20042005102b200328028001211320032802840121142003280288012115200328028c0121102003200d360274200320083602702003200736026c200320063602682003200c36024c2003200b3602482003200a36024420032009360240200220042005201541efc695c5076a201041ee85bea4076a102a200328029001211720032802940121182003280298012119200328029c0121062003200c3602742003200b3602702003200a36026c200320093602682003200636024c200320193602482003201836024420032017360240200220042005201341f8fbe399076b201441ec8fded9076b102a200328029001210720032802940121082003280298012109200328029c01210a2003200e36029c012003201e360298012003201d3602940120032016360290012003201c3602742003201b3602702003201a36026c200320113602682003201036024c200320153602482003201436024420032013360240200f2002201220042005102b20032802800121132003280284012116200328028801210f200328028c01210e20032006360274200320193602702003201836026c200320173602682003200a36024c200320093602482003200836024420032007360240200220042005200f4195a6bedd056b200e41868084fa066b102a200328029001210f200328029401210e2003280298012112200328029c0121112003200a360274200320093602702003200836026c200320073602682003201136024c200320123602482003200e3602442003200f3602402002200420052013418e8ebacc036b20164189b89988046b102a201120236a2123201220246a2124200e20256a2125200f20266a2126200328029c01201f6a211f20032802980120206a212020032802940120216a212120032802900120226a212220012027470d000b0b2000202336021c200020243602182000201f360214200020203602102000202536020c200020263602082000202136020420002022360200200341a0016a24000b7f02017f017f230041306b220241003602000340200220036a41046a200120036a2d00003a0000200341016a22034110470d000b20024110360200200241206a200241086a290300370300200241286a200241106a280200360200200220022903003703182000200229021c370000200041086a200241246a2902003700000be20106017f017f017f017f017f017f2000200128020c200420022802082204411a772004411577732004410777736a6a20012802082207200228020c2208732004712007736a220520012802046a220636020c2000200520012802002205200228020022017120022802042209200171220a732005200971732001411e772001411377732001410a77736a6a220236020420002005200320076a20082006200420087371736a2006411a772006411577732006410777736a22036a36020820002002411e772002411377732002410a77732002200120097371200a736a20036a3602000bec0103017f017f017f20002003280208200128020c20012802082205410e772005411977732005410376736a6a20042802042206410f772006410d77732006410a76736a220636020c20002003280204200520012802042207410e772007411977732007410376736a6a20042802002205410f772005410d77732005410a76736a220536020820002003280200200720012802002201410e772001411977732001410376736a6a2006410f772006410d77732006410a76736a3602042000200428020c20012002410e772002411977732002410376736a6a2005410f772005410d77732005410a76736a3602000bb60204017f017f017f017f411f210220004200370210200141ffffff074d04402001410620014108766722036b7641017120034101746b413e6a21020b2000200236021c200241027441dc9ac0006a2104024002400240024041d098c000280200220541012002742203710440200428020022032802044178712001470d01200321020c020b41d098c000200320057236020020042000360200200020043602180c030b20014100411920024101766b411f712002411f461b742104034020032004411d764104716a41106a22052802002202450d02200441017421042002210320022802044178712001470d000b0b20022802082201200036020c20022000360208200041003602182000200236020c200020013602080f0b20052000360200200020033602180b2000200036020c200020003602080b5902017f017f41c898c00041c898c000280200220241016a36020041909cc00041909cc00028020041016a220136020002402002410048200141024b720d0020004541c498c000280200410048200141014b72720d00000b000ba30103017f017f017f024020012202410f4d0440200021010c010b2000410020006b41037122046a210320040440200021010340200141003a0000200141016a22012003490d000b0b2003200220046b2202417c7122046a2101200441004a0440034020034100360200200341046a22032001490d000b0b200241037121020b20020440200120026a21020340200141003a0000200141016a22012002490d000b0b20000bbf0207017f017f017f017f017f017f017f024020022204410f4d0440200021020c010b2000410020006b41037122036a21052003044020002102200121060340200220062d00003a0000200641016a2106200241016a22022005490d000b0b2005200420036b2208417c7122076a21020240200120036a220341037122040440200741004c0d012003417c71220641046a21014100200441037422096b4118712104200628020021060340200520062009762001280200220620047472360200200141046a2101200541046a22052002490d000b0c010b200741004c0d0020032101034020052001280200360200200141046a2101200541046a22052002490d000b0b20084103712104200320076a21010b20040440200220046a21030340200220012d00003a0000200141016a2101200241016a22022003490d000b0b20000b0b8d180400418080c0000bcc0c2f7573722f6c6f63616c2f636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6165732d302e372e352f7372632f736f66742f666978736c69636533322e72730000000010005a000000e500000023000000000010005a000000e600000023000000000010005a000000e700000023000000000010005a000000d30100001b000000000010005a000000d301000027000000000010005a000000e401000024000000000010005a000000f901000028000000000010005a0000009104000012000000000010005a000000910400003d000000000010005a0000001b05000022000000000010005a0000001b050000090000006c6962726172792f616c6c6f632f7372632f7261775f7665632e72736361706163697479206f766572666c6f7700000028011000110000000c0110001c00000006020000050000004f766572666c6f77207768656e2063616c63756c6174696e67206e756d626572206f66206368756e6b7320696e20696e70757400a007100055000000c30000000a000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3effffff3f3435363738393a3b3c3dffffffffffffff000102030405060708090a0b0c0d0e0f10111213141516171819ffffffffffff1a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2f7573722f6c6f63616c2f636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f626c6f636b2d70616464696e672d302e322e312f7372632f6c69622e72739802100058000000b00000001300000029696e646578206f7574206f6620626f756e64733a20746865206c656e20697320206275742074686520696e646578206973200001031000200000002103100012000000ec0b100000000000060000000000000001000000070000003a200000ec0b1000000000005c03100002000000060000000c0000000400000008000000090000000a000000202020202c0a280a2830303031303230333034303530363037303830393130313131323133313431353136313731383139323032313232323332343235323632373238323933303331333233333334333533363337333833393430343134323433343434353436343734383439353035313532353335343535353635373538353936303631363236333634363536363637363836393730373137323733373437353736373737383739383038313832383338343835383638373838383939303931393239333934393539363937393839390000000600000004000000040000000b0000000c0000000d00000028296c6962726172792f636f72652f7372632f736c6963652f6d656d6368722e727300007604100020000000680000002700000072616e676520737461727420696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e67746820a804100012000000ba0410002200000072616e676520656e6420696e64657820ec04100010000000ba04100022000000736c69636520696e64657820737461727473206174202062757420656e647320617420000c05100016000000220510000d000000617474656d7074656420746f20696e64657820736c69636520757020746f206d6178696d756d207573697a65400510002c000000736f7572636520736c696365206c656e67746820282920646f6573206e6f74206d617463682064657374696e6174696f6e20736c696365206c656e67746820287405100015000000890510002b0000000003100001000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100418e8dc0000b330202020202020202020202020202020202020202020202020202020202020303030303030303030303030303030304040404040041cc8dc0000bb90654727946726f6d536c6963654572726f723f3f3f2121212f7573722f6c6f63616c2f636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6c696273716c5f62696e6467656e2d302e322e332f7372632f6c69622e7273e3061000590000002600000009000000e3061000590000002700000009000000e3061000590000002800000009000000696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64653a2000006c0710002a0000002f7573722f6c6f63616c2f636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6261736536342d302e31332e312f7372632f6465636f64652e7273000000a007100055000000d90100001f000000a007100055000000df0100001f000000a007100055000000e80100001f000000a007100055000000f10100001f000000a007100055000000fa0100001f000000a007100055000000030200001f000000a0071000550000000c0200001f000000a007100055000000150200001f0000006465636f646564206c656e6774682063616c63756c6174696f6e206f766572666c6f7700a007100055000000720000000a000000a0071000550000000a01000024000000a0071000550000000b01000029000000a0071000550000003101000016000000a007100055000000340100001a000000a007100055000000480100000e000000a0071000550000004b01000012000000a0071000550000005f01000013000000496d706f737369626c653a206d757374206f6e6c792068617665203020746f203820696e70757420627974657320696e206c617374206368756e6b2c2077697468206e6f20696e76616c6964206c656e677468731c09100054000000a007100055000000a40100000e000000a007100055000000b8010000090000005b4143434553532044454e4945445d2f72757374632f383937653337353533626261386234323735316336373635383936373838396431316563643132302f6c6962726172792f636f72652f7372632f736c6963652f697465722e7273000000a70910004e000000ee0700001100419094c0000bb104617474656d707420746f20646976696465206279207a65726f000000a70910004e0000004e0700001100000063616c6c65642060526573756c743a3a756e77726170282960206f6e20616e2060457272602076616c7565000e00000000000000010000000f0000002f7573722f6c6f63616c2f636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f736861322d302e392e392f7372632f7368613235362f736f66742e727300780a100057000000d5000000360000002f7573722f6c6f63616c2f636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f626c6f636b2d6275666665722d302e392e302f7372632f6c69622e727300e00a1000570000008400000009000000e00a1000570000008700000017000000e00a1000570000008b0000001b00000067e6096a85ae67bb72f36e3c3af54fa57f520e518c68059babd9831f19cde05b2f7573722f6c6f63616c2f636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f736861322d302e392e392f7372632f7368613235362e72730000880b100052000000510000001300000063616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c75656c6962726172792f7374642f7372632f70616e69636b696e672e727300170c10001c000000470200000f&#39;;<br><br>CREATE TABLE secrets(secret_id, secret);<br>INSERT INTO secrets VALUES (1, encrypt(&#39;libSQL is great&#39;, &#39;s3cr3tp4ss&#39;));<br>INSERT INTO secrets VALUES (2, encrypt(&#39;libSQL is fantastic&#39;, &#39;s3cr3tp4ss&#39;));<br>INSERT INTO secrets VALUES (3, encrypt(&#39;libSQL is amazing&#39;, &#39;s3cr3tp4ss&#39;));</pre><p>Now, let’s see if we’re able to read the results as key owners, and get refused otherwise:</p><pre>.mode column<br><br>libsql&gt; SELECT secret_id, secret, decrypt(secret, &#39;s3cr3tp4ss&#39;) FROM secrets;<br><br>secret_id  secret                                        decrypt(secret, &#39;s3cr3tp4ss&#39;)<br>---------  --------------------------------------------  -----------------------------<br>1          JioVkXVK9RygHSe9HpDEQQ==                      libSQL is great              <br>2          nx+havLvYCfvesp65gt/zRO0EApl2IdMvQWCWenCWho=  libSQL is fantastic          <br>3          1o2adrb3IO4VMgengEF10VS+IbFheukZtKIApnqOjm4=  libSQL is amazing <br><br>libsql&gt; SELECT secret_id, secret, decrypt(secret, &#39;zaq12wsx&#39;) FROM secrets;<br><br>secret_id  secret                                        decrypt(secret, &#39;zaq12wsx&#39;)<br>---------  --------------------------------------------  ---------------------------<br>1          JioVkXVK9RygHSe9HpDEQQ==                      [ACCESS DENIED]            <br>2          nx+havLvYCfvesp65gt/zRO0EApl2IdMvQWCWenCWho=  [ACCESS DENIED]            <br>3          1o2adrb3IO4VMgengEF10VS+IbFheukZtKIApnqOjm4=  [ACCESS DENIED]</pre><p>Voilà! All the secrets are properly encrypted, and the decryption key works too.</p><h3>What’s next?</h3><p>Now that you can add WebAssembly functions, we’d love to hear what cool things you’d like to do with them! We’re usually on <a href="https://discord.gg/TxwbQTWHSr">Discord</a> and <a href="https://twitter.com/libsqlhq">Twitter</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7e1ad95a2aa7" width="1" height="1" alt=""><hr><p><a href="https://medium.com/chiselstrike/webassembly-functions-for-your-sqlite-compatible-database-7e1ad95a2aa7">WebAssembly functions for your SQLite-compatible database</a> was originally published in <a href="https://medium.com/chiselstrike">Turso blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>