RFC 6716

Definition of the Opus Audio Codec

๐Ÿ“… published September 2012, from ietf

Definition of the Opus Audio Codec ๐ŸŽ€

okay so bestie, this is RFC 6716, and it's the spec for Opus, an audio codec ๐Ÿฆ‹ It's an Internet Standards Track document (category: Standards Track), published in September 2012 with ISSN 2070-1721. The IETF put it out. Three authors wrote it: JM. Valin and T. Terriberry from Mozilla Corporation, and K. Vos from Skype Technologies S.A. The header doesn't list anything it obsoletes or updates, so it stands on its own โœจ


Abstract ๐Ÿ’œ

okay, the big pitch: this doc defines the Opus interactive speech and audio codec. Opus is built for all kinds of interactive audio, like Voice over IP, videoconferencing, in-game chat, and even live, distributed music performances ๐ŸŽถ It scales from low bitrate narrowband speech at 6 kbit/s all the way up to very high quality stereo music at 510 kbit/s. That range is iconic ๐Ÿ”ฅ To get good compression for both speech and music, Opus uses both Linear Prediction (LP) and the Modified Discrete Cosine Transform (MDCT) ๐Ÿ’…


Status of This Memo ๐Ÿ“œ

this is an Internet Standards Track document โœจ

it's a product of the Internet Engineering Task Force (IETF), so it represents the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG) ๐Ÿซถ If you want more on Internet Standards, check Section 2 of RFC 5741 ๐ŸŒธ

for the current status, any errata, and how to send feedback, go to http://www.rfc-editor.org/info/rfc6716 ๐Ÿงš


Copyright (c) 2012 IETF Trust and the persons identified as the document authors. All rights reserved. ๐Ÿ’–

this document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they stand on the date of publication. Please read these carefully, because they spell out your rights and restrictions for this document ๐Ÿ‘€ Code Components pulled out of this document must include Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come with no warranty, as the Simplified BSD License describes ๐Ÿ”ฅ

the IETF Trust's licenses to this RFC under Section 3.c of the Trust Legal Provisions also cover extracting text from Sections 1 through 8, Appendix A, and Appendix B. You can make derivative works from those extracts and copy, publish, display, and distribute them in any medium for any purpose. The one catch: no derivative work can be presented, displayed, or published in a way that states or implies it's part of this RFC or any other IETF Document ๐Ÿ™ˆ

Table of Contents ๐Ÿ“

here's the map of the whole doc, so you can find your way around ๐Ÿ—บ๏ธ

   1. Introduction ....................................................5
      1.1. Notation and Conventions ...................................6
   2. Opus Codec Overview .............................................8
      2.1. Control Parameters ........................................10
           2.1.1. Bitrate ............................................10
           2.1.2. Number of Channels (Mono/Stereo) ...................11
           2.1.3. Audio Bandwidth ....................................11
           2.1.4. Frame Duration .....................................11
           2.1.5. Complexity .........................................11
           2.1.6. Packet Loss Resilience .............................12
           2.1.7. Forward Error Correction (FEC) .....................12
           2.1.8. Constant/Variable Bitrate ..........................12
           2.1.9. Discontinuous Transmission (DTX) ...................13
   3. Internal Framing ...............................................13
      3.1. The TOC Byte ..............................................13
      3.2. Frame Packing .............................................16
           3.2.1. Frame Length Coding ................................16
           3.2.2. Code 0: One Frame in the Packet ....................16
           3.2.3. Code 1: Two Frames in the Packet, Each with
                  Equal Compressed Size ..............................17
           3.2.4. Code 2: Two Frames in the Packet, with
                  Different Compressed Sizes .........................17

           3.2.5. Code 3: A Signaled Number of Frames in the Packet ..18
      3.3. Examples ..................................................21
      3.4. Receiving Malformed Packets ...............................22
   4. Opus Decoder ...................................................23
      4.1. Range Decoder .............................................23
           4.1.1. Range Decoder Initialization .......................25
           4.1.2. Decoding Symbols ...................................25
           4.1.3. Alternate Decoding Methods .........................27
           4.1.4. Decoding Raw Bits ..................................29
           4.1.5. Decoding Uniformly Distributed Integers ............29
           4.1.6. Current Bit Usage ..................................30
      4.2. SILK Decoder ..............................................32
           4.2.1. SILK Decoder Modules ...............................32
           4.2.2. LP Layer Organization ..............................33
           4.2.3. Header Bits ........................................35
           4.2.4. Per-Frame LBRR Flags ...............................36
           4.2.5. LBRR Frames ........................................36
           4.2.6. Regular SILK Frames ................................37
           4.2.7. SILK Frame Contents ................................37
                  4.2.7.1. Stereo Prediction Weights .................40
                  4.2.7.2. Mid-Only Flag .............................42
                  4.2.7.3. Frame Type ................................43
                  4.2.7.4. Subframe Gains ............................44
                  4.2.7.5. Normalized Line Spectral Frequency
                           (LSF) and Linear Predictive Coding (LPC)
                           Coeffieients ..............................46
                  4.2.7.6. Long-Term Prediction (LTP) Parameters .....74
                  4.2.7.7. Linear Congruential Generator (LCG) Seed ..86
                  4.2.7.8. Excitation ................................86
                  4.2.7.9. SILK Frame Reconstruction .................98
           4.2.8. Stereo Unmixing ...................................102
           4.2.9. Resampling ........................................103
      4.3. CELT Decoder .............................................104
           4.3.1. Transient Decoding ................................108
           4.3.2. Energy Envelope Decoding ..........................108
           4.3.3. Bit Allocation ....................................110
           4.3.4. Shape Decoding ....................................116
           4.3.5. Anti-collapse Processing ..........................120
           4.3.6. Denormalization ...................................121
           4.3.7. Inverse MDCT ......................................121
      4.4. Packet Loss Concealment (PLC) ............................122
           4.4.1. Clock Drift Compensation ..........................122
      4.5. Configuration Switching ..................................123
           4.5.1. Transition Side Information (Redundancy) ..........124
           4.5.2. State Reset .......................................127
           4.5.3. Summary of Transitions ............................128
   5. Opus Encoder ..................................................131
      5.1. Range Encoder ............................................132

           5.1.1. Encoding Symbols ..................................133
           5.1.2. Alternate Encoding Methods ........................134
           5.1.3. Encoding Raw Bits .................................135
           5.1.4. Encoding Uniformly Distributed Integers ...........135
           5.1.5. Finalizing the Stream .............................135
           5.1.6. Current Bit Usage .................................136
      5.2. SILK Encoder .............................................136
           5.2.1. Sample Rate Conversion ............................137
           5.2.2. Stereo Mixing .....................................137
           5.2.3. SILK Core Encoder .................................138
      5.3. CELT Encoder .............................................150
           5.3.1. Pitch Pre-filter ..................................150
           5.3.2. Bands and Normalization ...........................151
           5.3.3. Energy Envelope Quantization ......................151
           5.3.4. Bit Allocation ....................................151
           5.3.5. Stereo Decisions ..................................152
           5.3.6. Time-Frequency Decision ...........................153
           5.3.7. Spreading Values Decision .........................153
           5.3.8. Spherical Vector Quantization .....................154
   6. Conformance ...................................................155
      6.1. Testing ..................................................155
      6.2. Opus Custom ..............................................156
   7. Security Considerations .......................................157
   8. Acknowledgements ..............................................158
   9. References ....................................................159
      9.1. Normative References .....................................159
      9.2. Informative References ...................................159
   Appendix A. Reference Implementation .............................163
      A.1. Extracting the Source ....................................164
      A.2. Up-to-Date Implementation ................................164
      A.3. Base64-Encoded Source Code ...............................164
      A.4. Test Vectors .............................................321
   Appendix B. Self-Delimiting Framing ..............................321

Part 1 of 84 done, bestie! More parts coming ๐ŸŒˆ๐Ÿ’–

1. Introduction โœจ

Okay bestie, so Opus is a real-time interactive audio codec ๐ŸŽง๐Ÿ’– built to hit the requirements in [REQUIREMENTS]. Under the hood it has two layers: one based on Linear Prediction (LP) [LPC] and one based on the Modified Discrete Cosine Transform (MDCT) [MDCT]. The whole point of using two layers is this: for speech, linear prediction techniques (like Code-Excited Linear Prediction, or CELP) code low frequencies more efficiently than transform (e.g., MDCT) domain techniques ๐Ÿ—ฃ๏ธ, but it's the opposite for music and the higher speech frequencies ๐ŸŽถ. So a codec with both layers can cover a wider range than either one alone, and combining them gives better quality than using either one by itself. It's giving teamwork ๐Ÿซถโœจ

The primary normative part of this spec is the source code in Appendix A ๐Ÿ‘‘. Only the decoder portion of that software is normative, though a big chunk of code is shared between the encoder and decoder ๐Ÿ’…. Section 6 has a decoder conformance test ๐Ÿงช. The decoder does a ton of integer and fixed-point arithmetic that has to be done exactly, rounding included ๐Ÿคฏ, so any useful spec needs domain-specific symbolic language to define these operations properly. And if the symbolic language and the included reference implementation ever disagree, that conflict has to be resolved ๐Ÿ™ˆ. For compatibility and testability reasons, it's way easier if the reference implementation wins any disagreement. Plus, C is one of the most widely understood, human-readable symbolic representations for machine behavior ๐Ÿ’œ. So this RFC uses the reference implementation as the sole symbolic representation of the codec. Iconic, honestly ๐Ÿ”ฅ.

The symbolic representation is unambiguous and complete, but it's not always the easiest way to understand how the codec actually works ๐Ÿ˜ญ. So this document also describes the significant parts of the codec in prose and explains the reasoning behind many of the more surprising design choices ๐Ÿฆ‹. The descriptions are meant to be accurate and informative, but normal English can be ambiguous, so you should always read them alongside the symbolic representation ๐Ÿ“–. There are tons of references to the implementation for exactly this reason ๐Ÿ”. The prose sometimes differs from the reference in ordering or through mathematical simplification whenever that makes things easier to follow ๐ŸŒธ. For example, right shifts and left shifts in the reference implementation are often described with division and multiplication in the text โœจ. Generally, the text focuses on the "what" and "why", while the symbolic representation is where the "how" really lives ๐Ÿงš.

1.1. Notation and Conventions

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC2119] ๐Ÿ“œ๐Ÿ’….

Lots of operations in the codec need bit-exact fixed-point behavior, even if you're writing a floating point implementation ๐Ÿ”ข๐Ÿฉท. The notation "Q<n>", where n is an integer, means the number of binary digits to the right of the decimal point in a fixed-point number ๐ŸŽ€. For example, a signed Q14 value in a 16-bit word can represent values from -2.0 to 1.99993896484375, inclusive ๐ŸŒˆ. This notation is purely for information. Arithmetic, when it's described, always operates on the underlying integer, so the text will explicitly tell you any shifts needed after a multiplication ๐Ÿ’œ.

Expressions that show up in the text follow C operator rules and precedence, with one exception: the syntax "x**y" means x raised to the power y ๐Ÿงฎ. The text also uses the following functions ๐Ÿ’ซ.

1.1.1. min(x,y)

The smallest of two values x and y ๐ŸŒฑ.

1.1.2. max(x,y)

The largest of two values x and y ๐ŸŒท.

1.1.3. clamp(lo,x,hi)

                 clamp(lo,x,hi) = max(lo,min(x,hi))

With this definition, if lo > hi, then lo is returned ๐Ÿ™ƒ.

1.1.4. sign(x)

The sign of x, i.e.,

                                ( -1,  x < 0
                      sign(x) = <  0,  x == 0
                                (  1,  x > 0

1.1.5. abs(x)

The absolute value of x, i.e.,

                         abs(x) = sign(x)*x

1.1.6. floor(f)

The largest integer z such that z <= f ๐Ÿ“.

1.1.7. ceil(f)

The smallest integer z such that z >= f ๐Ÿ‘.

1.1.8. round(f)

The integer z nearest to f, with ties rounded towards negative infinity, i.e.,

                       round(f) = ceil(f - 0.5)

1.1.9. log2(f)

The base-two logarithm of f ๐Ÿช„.

1.1.10. ilog(n)

The minimum number of bits required to store a positive integer n in binary, or 0 for a non-positive integer n ๐Ÿง .

                          ( 0,                 n <= 0
                ilog(n) = <
                          ( floor(log2(n))+1,  n > 0

Examples:

  • ilog(-1) = 0
  • ilog(0) = 0
  • ilog(1) = 1
  • ilog(2) = 2
  • ilog(3) = 2
  • ilog(4) = 3
  • ilog(7) = 3 ๐Ÿฅฐ

2. Opus Codec Overview โœจ

okay so Opus is literally the most flexible codec ever ๐Ÿ’– it scales from 6 kbit/s narrowband mono speech all the way up to 510 kbit/s fullband stereo music ๐ŸŽถ, and the algorithmic delays range from 5 ms to 65.2 ms. At any given moment, the LP layer, the MDCT layer, or both can be active. It can switch between all of its operating modes seamlessly, so it adapts to different content and network conditions without renegotiating the session ๐Ÿฆ‹. It also lets you input and output a bunch of different audio bandwidths, which are defined in the table below:

+----------------------+-----------------+-------------------------+
| Abbreviation         | Audio Bandwidth | Sample Rate (Effective) |
+----------------------+-----------------+-------------------------+
| NB (narrowband)      |           4 kHz |                   8 kHz |
|                      |                 |                         |
| MB (medium-band)     |           6 kHz |                  12 kHz |
|                      |                 |                         |
| WB (wideband)        |           8 kHz |                  16 kHz |
|                      |                 |                         |
| SWB (super-wideband) |          12 kHz |                  24 kHz |
|                      |                 |                         |
| FB (fullband)        |      20 kHz (*) |                  48 kHz |
+----------------------+-----------------+-------------------------+

                                  Table 1

(*) Okay, so the sampling theorem technically allows a bandwidth as large as half the sampling rate, but Opus never codes audio above 20 kHz, because that's the generally accepted upper limit of human hearing ๐Ÿ‘‚โœจ.

Opus defines super-wideband (SWB) with an effective sample rate of 24 kHz ๐ŸŒธ, which is different from some other audio coding standards that use 32 kHz. There were a few reasons for this. The band layout in the MDCT layer naturally lets you skip coefficients for frequencies over 12 kHz, but it doesn't let you cleanly drop just the frequencies over 16 kHz. A 24 kHz sample rate also makes resampling in the MDCT layer easier, because 24 evenly divides 48 ๐Ÿงฎ. And when 24 kHz is good enough, it saves computation in other processing, like Acoustic Echo Cancellation (AEC). Experimental changes to the band layout to allow a 16 kHz cutoff (32 kHz effective sample rate) showed potential quality degradations at other sample rates, and at typical bitrates, the number of bits you'd save by using that cutoff instead of coding in fullband (FB) mode is super tiny ๐Ÿค. So, if an application wants to process a signal sampled at 32 kHz, it should just use FB ๐Ÿ’….

The LP layer is based on the SILK codec [SILK] ๐ŸŽค. It supports NB, MB, or WB audio and frame sizes from 10 ms to 60 ms, and it requires an additional 5 ms look-ahead for noise shaping estimation. A small extra delay (up to 1.5 ms) may be needed for sampling rate conversion. Like Vorbis [VORBIS-WEBSITE] and a lot of other modern codecs, SILK is inherently designed for variable bitrate (VBR) coding, though the encoder can also produce constant bitrate (CBR) streams ๐ŸŽ€. The version of SILK used in Opus is substantially modified from the stand-alone SILK codec that Skype previously deployed, and it is not compatible with it ๐Ÿ™ˆ. This document doesn't define that format, so if you're curious about the original SILK codec, go check out [SILK] instead.

The MDCT layer is based on the Constrained-Energy Lapped Transform (CELT) codec [CELT] ๐Ÿฆข. It supports NB, WB, SWB, or FB audio and frame sizes from 2.5 ms to 20 ms, and it needs an additional 2.5 ms look-ahead because of the overlapping MDCT windows. The CELT codec is inherently designed for CBR coding, but unlike a lot of CBR codecs, it isn't stuck with a set of predetermined rates ๐Ÿ™Œ. It internally allocates bits to exactly fill any given target budget, and an encoder can make a VBR stream by changing the target on a per-frame basis. The MDCT layer isn't used for speech when the audio bandwidth is WB or less, because it isn't useful there. On the other hand, non-speech signals aren't always coded well using linear prediction, so the MDCT layer should be used for music signals ๐ŸŽต.

A "Hybrid" mode lets you use both layers at the same time, with a frame size of 10 or 20 ms and an SWB or FB audio bandwidth ๐Ÿ“. The LP layer codes the low frequencies by resampling the signal down to WB, and then the MDCT layer follows up and codes the high frequency part of the signal. The cutoff between the two sits at 8 kHz, which is the maximum WB audio bandwidth. In the MDCT layer, all bands below 8 kHz get discarded, so there's no coding redundancy between the two layers ๐Ÿง โœจ.

The sample rate (which is different from the actual audio bandwidth) can be chosen independently on the encoder and decoder sides. For example, a fullband signal can be decoded as wideband, or the other way around ๐Ÿ”„. This means a sender and receiver can always interoperate, no matter what their audio hardware can do ๐Ÿซถ. Internally, the LP layer always operates at a sample rate of twice the audio bandwidth, up to a maximum of 16 kHz, and it keeps using that for SWB and FB too. The decoder just resamples its output to support different sample rates. The MDCT layer always operates internally at a sample rate of 48 kHz. Since all the supported sample rates evenly divide this rate, and since the decoder can easily zero out the high frequency portion of the spectrum in the frequency domain, it can simply decimate the MDCT layer output to get the other supported sample rates super cheaply ๐Ÿ’ฐ.

After converting to the common, desired output sample rate, the decoder simply adds the output from the two layers together ๐Ÿ’œ. To make up for the different look-ahead each layer needs, the CELT encoder input is delayed by an additional 2.7 ms. This makes sure that the low frequencies and high frequencies arrive at the same time ๐Ÿ‘ฏโ€โ™€๏ธ. An encoder can reduce this extra delay by using less look-ahead for noise shaping or by using a simpler resampler in the LP layer, but that will reduce quality ๐Ÿ˜ฌ. The base 2.5 ms look-ahead in the CELT layer can't be reduced in the encoder, though, because it's needed for the MDCT overlap, and that overlap size is fixed by the decoder.

Both layers use the same entropy coder, which avoids any waste from "padding bits" between them ๐ŸŒˆ. The hybrid approach also makes it easy to support both CBR and VBR coding. Even though the LP layer is VBR, the bit allocation of the MDCT layer can produce a final stream that's CBR, by using all the bits the LP layer left unused ๐Ÿช„.


2.1. Control Parameters

The Opus codec has a bunch of control parameters that you can change on the fly while it's running, without interrupting the audio stream from the encoder to the decoder ๐ŸŽ›๏ธ. These parameters only affect the encoder. Any impact they have on the bitstream is signaled in-band, so a decoder can decode any Opus stream without any out-of-band signaling ๐Ÿ’…. Any Opus implementation can add or modify these control parameters without affecting interoperability. The most important encoder control parameters in the reference encoder are listed below ๐Ÿ“.

2.1.1. Bitrate

Opus supports every bitrate from 6 kbit/s to 510 kbit/s. All other parameters being equal, a higher bitrate gives you higher quality ๐Ÿ“ˆ. For a frame size of 20 ms, these are the bitrate "sweet spots" for Opus in various configurations ๐Ÿฌ:

  • 8-12 kbit/s for NB speech,
  • 16-20 kbit/s for WB speech,
  • 28-40 kbit/s for FB speech,
  • 48-64 kbit/s for FB mono music, and
  • 64-128 kbit/s for FB stereo music.

2.1.2. Number of Channels (Mono/Stereo)

Opus can transmit either mono or stereo frames within a single stream ๐ŸŽง. When a stereo decoder decodes a mono frame, the left and right channels are identical. When a mono decoder decodes a stereo frame, the mono output is the average of the left and right channels ๐Ÿค. Sometimes you want to encode a stereo input stream in mono, like when the bitrate is too low to encode stereo with decent quality ๐Ÿฅบ. The number of channels encoded can be selected in real-time, but by default the reference encoder tries to make the best decision it can, given the current bitrate โœจ.

2.1.3. Audio Bandwidth

The audio bandwidths Opus supports are listed in Table 1 ๐ŸŒท. Just like with the number of channels, any decoder can decode audio that's encoded at any bandwidth. For example, any Opus decoder operating at 8 kHz can decode an FB Opus frame, and any Opus decoder operating at 48 kHz can decode an NB frame ๐Ÿ™Œ. Similarly, the reference encoder can take a 48 kHz input signal and encode it as NB. The higher the audio bandwidth, the higher the bitrate you need to reach acceptable quality ๐Ÿ“ถ. The audio bandwidth can be explicitly specified in real-time, but by default the reference encoder tries to make the best bandwidth decision it can, given the current bitrate ๐Ÿ’–.

2.1.4. Frame Duration

Opus can encode frames of 2.5, 5, 10, 20, 40, or 60 ms โฑ๏ธ. It can also combine multiple frames into packets of up to 120 ms ๐Ÿ“ฆ. For real-time apps, sending fewer packets per second reduces the bitrate, because it cuts down on the overhead from IP, UDP, and RTP headers ๐Ÿงพ. However, it increases latency and makes things more sensitive to packet losses, since losing one packet means losing a bigger chunk of audio ๐Ÿ˜ญ. Increasing the frame duration also slightly improves coding efficiency, but the gain gets small for frame sizes above 20 ms. That's why 20 ms frames are a good choice for most applications ๐Ÿ“.

2.1.5. Complexity

There are a bunch of spots in the Opus encoding process where you can trade off between CPU complexity and quality/bitrate ๐Ÿง. In the reference encoder, you pick the complexity with an integer from 0 to 10, where 0 is the lowest complexity and 10 is the highest ๐ŸŽš๏ธ. Examples of computations where these trade-offs can happen are:

  • The order of the pitch analysis whitening filter [WHITENING],
  • The order of the short-term noise shaping filter,
  • The number of states in delayed decision quantization of the residual signal, and
  • The use of certain bitstream features, such as variable time-frequency resolution and the pitch post-filter.

2.1.6. Packet Loss Resilience

Audio codecs often exploit inter-frame correlations to lower the bitrate, but that comes at a cost in error propagation ๐ŸŒ€. After losing one packet, several packets need to be received before the decoder can accurately reconstruct the speech signal, which is kind of a lot ๐Ÿ˜ฉ. The extent to which Opus exploits inter-frame dependencies can be adjusted on the fly, so you can pick a trade-off between bitrate and amount of error propagation ๐Ÿฆ‹.

2.1.7. Forward Error Correction (FEC)

Another way Opus stays robust against packet loss is in-band Forward Error Correction (FEC) ๐Ÿ›ก๏ธ. Packets that are determined to contain perceptually important speech information, like onsets or transients, get encoded again at a lower bitrate, and that re-encoded information is added to a subsequent packet ๐Ÿซถโœจ.

2.1.8. Constant/Variable Bitrate ๐ŸŽ€

okay so Opus is most efficient when it's running in variable bitrate (VBR) mode, which is the default ๐Ÿ’–. If you need low-latency transmission over a kinda slow connection, you can use constrained VBR too. It fakes a "bit reservoir" so it acts like what MP3 (MPEG 1, Layer 3) and AAC (Advanced Audio Coding) call CBR, but it's not true CBR because of that reservoir ๐Ÿงš. Real constant bitrate (CBR) is still needed in some rare apps, and there are two main reasons to go that route:

  • When the transport only supports a fixed size for each compressed frame, or
  • When encryption is used for an audio stream that is either highly constrained (e.g., yes/no, recorded prompts) or highly sensitive [SRTP-VBR].

Bitrate can still change even with sensitive data, as long as the change isn't driven by the input signal (like adjusting to changing network conditions, which is honestly so smart ๐Ÿ‘‘). To do that, an application should still run Opus in CBR mode, but change the target rate before each packet.

2.1.9. Discontinuous Transmission (DTX) ๐ŸŒธ

Discontinuous Transmission (DTX) lowers the bitrate during silence or background noise ๐Ÿ™ˆ. When DTX is enabled, only one frame gets encoded every 400 milliseconds โœจ.


3. Internal Framing ๐Ÿฆ‹

okay this part is giving packet-building energy ๐Ÿซถ. The Opus encoder makes "packets," and each one is a contiguous set of bytes meant to be sent as a single unit. The packets described here don't include stuff like IP, UDP, or RTP headers, since those usually live in the transport-layer packet. A single packet can hold multiple audio frames, as long as they share the same operating mode, audio bandwidth, frame size, and channel count (mono vs. stereo). This section breaks down the possible combos of these parameters and how the frames get packed together.

This framing is not self-delimiting ๐Ÿ’…. Instead, it assumes a lower layer (like UDP or RTP [RFC3550], Ogg [RFC3533], or Matroska [MATROSKA-WEBSITE]) tells it how many bytes long the packet is, and it uses that info to cut down on framing overhead. A decoder implementation MUST support the framing described in this section. There's an alternative, self-delimiting variant described in Appendix B, and support for that variant is OPTIONAL.

All bit diagrams in this document number the bits so that bit 0 is the most significant bit of the first byte, and bit 7 is the least significant. Bit 8 is therefore the most significant bit of the second byte, and so on. Well-formed Opus packets obey certain requirements, marked [R1] through [R7] below. These are summarized in Section 3.4, along with the right way to handle malformed packets ๐Ÿ“.

3.1. The TOC Byte

A well-formed Opus packet MUST contain at least one byte [R1]. This byte forms a table-of-contents (TOC) header that signals which of the various modes and configurations a given packet uses. It's made up of a configuration number, "config," a stereo flag, "s," and a frame count code, "c," laid out like Figure 1. Here's the breakdown of each field ๐ŸŽ€.

                              0
                              0 1 2 3 4 5 6 7
                             +-+-+-+-+-+-+-+-+
                             | config  |s| c |
                             +-+-+-+-+-+-+-+-+

                          Figure 1: The TOC Byte

The top five bits of the TOC byte, labeled "config," pick one of 32 possible configurations of operating mode, audio bandwidth, and frame size. The LP (SILK) layer and the MDCT (CELT) layer can be combined in three possible operating modes:

  1. A SILK-only mode for use in low bitrate connections with an audio bandwidth of WB or less,
  2. A Hybrid (SILK+CELT) mode for SWB or FB speech at medium bitrates, and
  3. A CELT-only mode for very low delay speech transmission as well as music transmission (NB to FB).

The 32 configurations each tell you which of these operating modes the packet uses, plus the audio bandwidth and the frame size. Table 2 lists the parameters for each configuration ๐Ÿ“Š.

   +-----------------------+-----------+-----------+-------------------+
   | Configuration         | Mode      | Bandwidth | Frame Sizes       |
   | Number(s)             |           |           |                   |
   +-----------------------+-----------+-----------+-------------------+
   | 0...3                 | SILK-only | NB        | 10, 20, 40, 60 ms |
   |                       |           |           |                   |
   | 4...7                 | SILK-only | MB        | 10, 20, 40, 60 ms |
   |                       |           |           |                   |
   | 8...11                | SILK-only | WB        | 10, 20, 40, 60 ms |
   |                       |           |           |                   |
   | 12...13               | Hybrid    | SWB       | 10, 20 ms         |
   |                       |           |           |                   |
   | 14...15               | Hybrid    | FB        | 10, 20 ms         |
   |                       |           |           |                   |
   | 16...19               | CELT-only | NB        | 2.5, 5, 10, 20 ms |
   |                       |           |           |                   |
   | 20...23               | CELT-only | WB        | 2.5, 5, 10, 20 ms |
   |                       |           |           |                   |
   | 24...27               | CELT-only | SWB       | 2.5, 5, 10, 20 ms |
   |                       |           |           |                   |
   | 28...31               | CELT-only | FB        | 2.5, 5, 10, 20 ms |
   +-----------------------+-----------+-----------+-------------------+

                Table 2: TOC Byte Configuration Parameters

The configuration numbers in each range (e.g., 0...3 for NB SILK-only) line up with the different frame sizes, in the same order. So, for example, configuration 0 has a 10 ms frame size and configuration 3 has a 60 ms frame size ๐Ÿงš.

One more bit, labeled "s," tells you mono vs. stereo: 0 means mono and 1 means stereo ๐ŸŒˆ.

The last two bits of the TOC byte, labeled "c," code the number of frames per packet (codes 0 to 3) like this:

  • 0: 1 frame in the packet
  • 1: 2 frames in the packet, each with equal compressed size
  • 2: 2 frames in the packet, with different compressed sizes
  • 3: an arbitrary number of frames in the packet

This document refers to a packet as a code 0 packet, code 1 packet, etc., based on the value of "c" ๐Ÿ’œ.

3.2. Frame Packing

This section describes how frames get packed for each possible value of "c" in the TOC byte ๐Ÿ“ฆ.

3.2.1. Frame Length Coding

When a packet has multiple VBR frames (i.e., code 2 or 3), the compressed length of one or more of those frames is indicated with a one- or two-byte sequence. The first byte means the following:

  • 0: No frame (Discontinuous Transmission (DTX) or lost packet)
  • 1...251: Length of the frame in bytes
  • 252...255: A second byte is needed. The total length is (second_byte*4)+first_byte

The special length 0 means no frame is available, either because some intermediary dropped it during transmission or because the encoder chose not to send it ๐Ÿ™ˆ. Any Opus frame in any mode MAY have a length of 0.

The maximum representable length is 255*4+255=1275 bytes. For 20 ms frames, that works out to a bitrate of 510 kbit/s, which is roughly the highest useful rate for lossily compressed fullband stereo music. Past that point, lossless codecs are the better pick. It's also about the maximum useful rate of the MDCT layer, because soon after that, quality stops improving with extra bits due to limits on the codebook sizes ๐Ÿ”ฅ.

No length is sent for the last frame in a VBR packet, or for any of the frames in a CBR packet, since it can be figured out from the total size of the packet and the size of all the other data in it. However, the length of any individual frame MUST NOT exceed 1275 bytes [R2], so gateways, conference bridges, and other software can repacketize things safely ๐Ÿซถ.

3.2.2. Code 0: One Frame in the Packet

For code 0 packets, the TOC byte is immediately followed by N-1 bytes of compressed data for a single frame (where N is the size of the packet), as shown in Figure 2.

      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     | config  |s|0|0|                                               |
     +-+-+-+-+-+-+-+-+                                               |
     |                    Compressed frame 1 (N-1 bytes)...          :
     :                                                               |
     |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                         Figure 2: A Code 0 Packet

3.2.3. Code 1: Two Frames in the Packet, Each with Equal Compressed Size

For code 1 packets, the TOC byte is immediately followed by the (N-1)/2 bytes of compressed data for the first frame, then (N-1)/2 bytes of compressed data for the second frame, as shown in Figure 3. The number of payload bytes available for compressed data, N-1, MUST be even for all code 1 packets [R3] โœจ.

      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     | config  |s|0|1|                                               |
     +-+-+-+-+-+-+-+-+                                               :
     |             Compressed frame 1 ((N-1)/2 bytes)...             |
     :                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                               |                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               :
     |             Compressed frame 2 ((N-1)/2 bytes)...             |
     :                                               +-+-+-+-+-+-+-+-+
     |                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                         Figure 3: A Code 1 Packet

3.2.4. Code 2: Two Frames in the Packet, with Different Compressed Sizes โœจ

okay bestie, code 2 is the one where the two frames are different sizes ๐ŸŽ€ The TOC byte is followed by a one- or two-byte length for the first frame (that's N1 in Figure 4 ๐Ÿ’…), then N1 bytes of compressed data for frame one. Whatever's left, N-N1-2 or N-N1-3 bytes depending on how long the length field is, is frame two ๐Ÿ’–

A code 2 packet MUST contain enough bytes to represent a valid length. So a 1-byte code 2 packet is always invalid ๐Ÿ’€ and a 2-byte code 2 packet whose second byte is in the range 252...255 is also invalid ๐Ÿ™ˆ

The length of the first frame, N1, MUST also be no larger than the size of the payload remaining after decoding that length for all code 2 packets [R4]. That makes a 2-byte code 2 packet with a second byte in the range 1...251 invalid too ๐Ÿ˜ญ The only valid 2-byte code 2 packet is one where the length of both frames is zero ๐Ÿงš

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  | config  |s|1|0| N1 (1-2 bytes):                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               :
  |               Compressed frame 1 (N1 bytes)...                |
  :                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                               |                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
  |                     Compressed frame 2...                     :
  :                                                               |
  |                                                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 4: A Code 2 Packet

3.2.5. Code 3: A Signaled Number of Frames in the Packet ๐Ÿ‘‘

Code 3 is the main character of frame packing ๐Ÿ’œ These packets signal the number of frames, plus extra padding called "Opus padding" ๐ŸŒˆ The name is there to show this padding is added at the Opus layer, not at the transport layer.

Code 3 packets MUST have at least 2 bytes [R6,R7]. The TOC byte is followed by a byte that encodes the number of frames in bits 2 to 7 (that's M in Figure 5 ๐Ÿ“), bit 1 says whether Opus padding is inserted (that's p), and bit 0 says whether it's VBR (that's v). M MUST NOT be zero, and the audio duration in a packet MUST NOT exceed 120 ms [R5]. That caps the frame count at 48 for any frame size, which is 2.5 ms frames, and gets lower for longer frames ๐Ÿฆ‹

                              0
                              0 1 2 3 4 5 6 7
                             +-+-+-+-+-+-+-+-+
                             |v|p|     M     |
                             +-+-+-+-+-+-+-+-+

Figure 5: The frame count byte

When Opus padding is used, the number of padding bytes is encoded in the bytes after the frame count byte ๐Ÿซถ Values from 0...254 mean 0...254 bytes of padding are included, on top of the byte(s) used to indicate the padding size. If the value is 255, then the padding size is 254 bytes plus whatever padding value is in the next byte. There MUST be at least one more byte in the packet in this case [R6,R7]. The additional padding bytes go at the end of the packet and MUST be set to zero by the encoder to avoid creating a covert channel ๐Ÿ•ต๏ธ The decoder MUST accept any value for the padding bytes, though ๐Ÿซถ

This encoding gives you more than one way to say the same padding amount, but each way uses a different number of bytes to say it, so the total packet size goes up by a different amount each time ๐ŸŒธ For example, to add 255 bytes, set p to 1, insert a single byte after the frame count byte with a value of 254, and append 254 zero-valued padding bytes to the end of the packet. To add 256 bytes, set p to 1, insert two bytes after the frame count byte with the values 255 and 0, and append 254 zero-valued padding bytes to the end. By using the value 255 multiple times, you can make a packet of any specific size you want ๐ŸŽ€

Let P be the number of header bytes used to indicate the padding size plus the number of padding bytes themselves (so P is the total number of bytes added to the packet). Then P MUST be no more than N-2 [R6,R7].

In the CBR case, let R=N-2-P be the number of bytes left in the packet after subtracting the (optional) padding ๐ŸŒท Then the compressed length of each frame in bytes is equal to R/M. The value R MUST be a non-negative integer multiple of M [R6]. The compressed data for all M frames follows, each one R/M bytes, as shown in Figure 6 โœจ

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  | config  |s|1|1|0|p|     M     |  Padding length (Optional)    :
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                                                               |
  :               Compressed frame 1 (R/M bytes)...               :
  |                                                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                                                               |
  :               Compressed frame 2 (R/M bytes)...               :
  |                                                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                                                               |
  :                              ...                              :
  |                                                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                                                               |
  :               Compressed frame M (R/M bytes)...               :
  |                                                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  :                  Opus Padding (Optional)...                   |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 6: A CBR Code 3 Packet

In the VBR case, the (optional) padding length is followed by M-1 frame lengths (labelled "N1" to "N[M-1]" in Figure 7 ๐Ÿ’–), each one- or two-byte encoded like we saw above. The packet MUST contain enough data for those M-1 lengths after removing the (optional) padding, and the sum of these lengths MUST be no larger than the number of bytes left in the packet after decoding them [R7]. The compressed data for all M frames follows. Each frame is the indicated number of bytes, and the final frame eats up whatever's left before the final padding, as illustrated in Figure 6 ๐Ÿฆ‹ Last rule: the number of header bytes (TOC byte, frame count byte, padding length bytes and frame length bytes), plus the signaled length of the first M-1 frames, plus the signaled length of the padding, MUST be no larger than N, the total size of the packet ๐Ÿซถ

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  | config  |s|1|1|1|p|     M     | Padding length (Optional)     :
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  : N1 (1-2 bytes): N2 (1-2 bytes):     ...       :     N[M-1]    |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                                                               |
  :               Compressed frame 1 (N1 bytes)...                :
  |                                                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                                                               |
  :               Compressed frame 2 (N2 bytes)...                :
  |                                                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                                                               |
  :                              ...                              :
  |                                                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                                                               |
  :                     Compressed frame M...                     :
  |                                                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  :                  Opus Padding (Optional)...                   |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 7: A VBR Code 3 Packet

3.3. Examples ๐Ÿงš

Let's look at some real packets, bestie ๐Ÿ’… First up, the simplest case: one NB mono 20 ms SILK frame ๐ŸŒธ

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |    1    |0|0|0|               compressed data...              :
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 8

Next, two FB mono 5 ms CELT frames of the same compressed size ๐ŸŽ€

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |   29    |0|0|1|               compressed data...              :
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 9

Then, two FB mono 20 ms Hybrid frames of different compressed size ๐Ÿฆ‹

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |   15    |0|1|1|1|0|     2     |      N1       |               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               |
  |                       compressed data...                      :
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 10

And finally, four FB stereo 20 ms CELT frames of the same compressed size ๐ŸŒˆ

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |   31    |1|1|1|0|0|     4     |      compressed data...       :
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 11

3.4. Receiving Malformed Packets โš ๏ธ

okay bestie, this part is all about what happens when a packet is totally broken ๐Ÿ’€. A receiver MUST NOT process packets that break any of the rules above as normal Opus packets. Those packets are basically reserved for future stuff, like in-band headers that carry metadata and other extras โœจ. If a packet breaks these constraints, implementations of this specification may treat it as malformed and toss it ๐Ÿ—‘๏ธ.

These are the constraints, all in one spot so you can check them fast ๐Ÿซถ:

  • [R1] Packets are at least one byte.
  • [R2] No implicit frame length is larger than 1275 bytes.
  • [R3] Code 1 packets have an odd total length, N, so that (N-1)/2 is an integer.
  • [R4] Code 2 packets have enough bytes after the TOC for a valid frame length, and that length is no larger than the number of bytes remaining in the packet.
  • [R5] Code 3 packets contain at least one frame, but no more than 120 ms of audio total.
  • [R6] The length of a CBR code 3 packet, N, is at least two bytes, the number of bytes added to indicate the padding size plus the trailing padding bytes themselves, P, is no more than N-2, and the frame count, M, satisfies the constraint that (N-2-P) is a non-negative integer multiple of M.
  • [R7] VBR code 3 packets are large enough to contain all the header bytes (TOC byte, frame count byte, any padding length bytes, and any frame length bytes), plus the length of the first M-1 frames, plus any trailing padding bytes.

4. Opus Decoder ๐ŸŽง

the Opus decoder is made of two main blocks: the SILK decoder and the CELT decoder ๐Ÿ‘‘. At any moment, one or both of them can be active. The decoder output is the sum of the SILK and CELT outputs. The SILK side gets proper sample rate conversion and delay compensation, and the CELT side gets optional decimation when you're decoding to rates below 48 kHz ๐Ÿฆ‹. Here's the block diagram:

                            +---------+    +------------+
                            |  SILK   |    |   Sample   |
                         +->| Decoder |--->|    Rate    |----+
   Bit-    +---------+   |  |         |    | Conversion |    v
   stream  |  Range  |---+  +---------+    +------------+  /---\  Audio
   ------->| Decoder |                                     | + |------>
           |         |---+  +---------+    +------------+  \---/
           +---------+   |  |  CELT   |    | Decimation |    ^
                         +->| Decoder |--->| (Optional) |----+
                            |         |    |            |
                            +---------+    +------------+

4.1. Range Decoder ๐ŸŒธ

Opus uses an entropy coder based on range coding [RANGE-CODING] [MARTIN79], which is basically a rediscovery of the FIFO arithmetic code introduced by [CODING-THESIS]. It's super similar to arithmetic encoding, except the digits can be in any base instead of just bits. That makes it faster with bigger bases, like a byte ๐Ÿ’…. All of the range coder math has to use bit-exact integer arithmetic, no fudging it ๐Ÿ™ˆ.

Symbols can also be coded as "raw bits" packed straight into the bitstream, skipping the range coder entirely. These get packed backwards starting from the end of the frame, as shown in Figure 12 โœจ. This cuts down on complexity and makes the stream more resilient to bit errors. If the raw bits get corrupted, the decoding process doesn't fall out of sync, unlike corruption in the input to the range decoder ๐Ÿงš. Raw bits are only used in the CELT layer.

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  | Range coder data (packed MSB to LSB) ->                       :
  +                                                               +
  :                                                               :
  +     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  :     | <- Boundary occurs at an arbitrary bit position         :
  +-+-+-+                                                         +
  :                          <- Raw bits data (packed LSB to MSB) |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   Legend:

   LSB = Least Significant Bit
   MSB = Most Significant Bit

        Figure 12: Illustrative Example of Packing Range Coder
                           and Raw Bits Data

Each symbol the range coder handles comes from a finite alphabet and gets coded in its own "context". The context describes how big the alphabet is and how often each symbol shows up in it ๐ŸŽ€.

Say there's a context with n symbols, indexed from 0 to n-1. The parameters needed to encode or decode symbol k in that context are a three-tuple (fl[k], fh[k], ft). All three are 16-bit unsigned integers, with 0 <= fl[k] < fh[k] <= ft <= 65535. These values come from the probability model for the symbol, which is written as traditional "frequency counts" ๐Ÿ“Š. Opus uses static contexts, so those counts never get updated while symbols are decoded. Let f[i] be the frequency of symbol i. Then the three-tuple for symbol k is:

                 k-1                                   n-1
                 __                                    __
         fl[k] = \  f[i],  fh[k] = fl[k] + f[k],  ft = \  f[i]
                 /_                                    /_
                 i=0                                   i=0

The range decoder pulls out the symbols and integers that the range encoder put in, which is covered in Section 5.1. The decoder keeps an internal state vector made of the two-tuple (val, rng). Here, val is the difference between the high end of the current range and the actual coded value, minus one. rng is the size of the current range. Both val and rng are 32-bit unsigned integer values ๐Ÿ’œ.

4.1.1. Range Decoder Initialization ๐Ÿ“

Let b0 be an 8-bit unsigned integer holding the first input byte, or zero if there are no bytes in this Opus frame. The decoder sets rng to 128 and sets val to (127 - (b0>>1)), where (b0>>1) is the top 7 bits of the first input byte. It saves the leftover bit, (b0&1), for the renormalization procedure in Section 4.1.2.1. The decoder runs that renormalization right after initialization, reading more bits and making sure the invariant rng > 2**23 holds ๐Ÿ”ฅ.

4.1.2. Decoding Symbols ๐Ÿ’–

Decoding a symbol is a two-step process ๐Ÿง . The first step works out a 16-bit unsigned value fs that lands inside the range of some symbol in the current context. The second step updates the range decoder state with the three-tuple (fl[k], fh[k], ft) for that symbol.

The first step is handled by ec_decode() (entdec.c), which computes:

                                   val
                    fs = ft - min(------ + 1, ft)
                                  rng/ft

The divisions here are integer division โœจ.

Next, the decoder finds the symbol in the current context that matches fs. That's the value of k whose three-tuple satisfies fl[k] <= fs < fh[k]. It uses that tuple to update val like this:

                                rng
                    val = val - --- * (ft - fh[k])
                                ft

If fl[k] is greater than zero, the decoder updates rng using:

                           rng
                     rng = --- * (fh[k] - fl[k])
                           ft

Otherwise, it updates rng using:

                                rng
                    rng = rng - --- * (ft - fh[k])
                                ft

Using a special case for the first symbol, instead of the last one like most other arithmetic coders do, means all the truncation error from the finite precision math piles up on symbol 0 ๐ŸŽฏ. That makes coding a 0 a tiny bit cheaper on average than its estimated probability says, and coding any other symbol a tiny bit more expensive. When contexts are designed so 0 is the most probable symbol, which happens a lot, this strategy keeps the inefficiency from finite precision as low as possible. It also makes some of the special-case decoding routines in Section 4.1.3 really simple ๐Ÿ‘‘.

After the updates, which are handled by ec_dec_update() (entdec.c), the decoder normalizes the range using the procedure in the next section. Then it returns the index k ๐Ÿฆ‹.

4.1.2.1. Renormalization ๐ŸŒˆ

To normalize the range, the decoder keeps repeating the following process, handled by ec_dec_normalize() (entdec.c), until rng > 223 ๐ŸŽ€. If rng is already bigger than 223, the whole process gets skipped. First, it sets rng to (rng<<8). Then it reads the next byte of the Opus frame and forms an 8-bit value sym. The leftover bit buffered from the previous byte becomes the high bit, and the top 7 bits of the byte just read become the other 7 bits of sym. The remaining bit in the byte just read gets buffered for the next iteration. If no more input bytes are left, it uses zero bits instead. See Section 4.1.1 for how the first byte gets initialized. Then it sets:

val = ((val<<8) + (255-sym)) & 0x7FFFFFFF

It's normal and totally expected that the range decoder reads several bytes into the raw bits data at the end of the frame by the time the frame is fully decoded, as Figure 13 shows ๐Ÿ˜Œ. This same data MUST also be returned as raw bits when requested. The encoder is expected to end the stream in a way that makes the range decoder produce the intended values no matter what data is in the raw bits. Section 5.1.5 describes a procedure for doing exactly that ๐Ÿซถ. If the range decoder uses up all the bytes belonging to the current frame, it MUST keep using zero whenever it needs more input bytes, even if there's extra data in the current packet from padding or other frames ๐Ÿšซ.

   n              n+1             n+2             n+3
   0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  :     | <----------- Overlap region ------------> |             :
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        ^                                           ^
        |   End of data buffered by the range coder |
  ...-----------------------------------------------+
        |
        | End of data consumed by raw bits
        +-------------------------------------------------------...

       Figure 13: Illustrative Example of Raw Bits Overlapping
                          Range Coder Data

4.1.3. Alternate Decoding Methods ๐Ÿงšโ€โ™€๏ธ

The reference implementation uses three extra decoding methods. They're exactly equivalent to the ones above, but they make some assumptions and simplifications so the implementation can be more efficient ๐Ÿ’….

4.1.3.1. ec_decode_bin() ๐ŸŒธ

The first one is ec_decode_bin() (entdec.c). It's defined using the parameter ftb instead of ft. It's mathematically equivalent to calling ec_decode() with ft = (1<<ftb), but it skips one of the divisions ๐Ÿ™Œ.

4.1.3.2. ec_dec_bit_logp() ๐Ÿ’–

okay so ec_dec_bit_logp() (in entdec.c) decodes a single binary symbol ๐ŸŽ€ It does the job of both ec_decode() AND ec_dec_update() in one move, so you skip the middle steps โœจ The context is described by just one parameter, logp, which is the absolute value of the base-2 logarithm of the probability of a "1" ๐Ÿงš

Mathematically, this is the same as calling ec_decode() with ft = (1<<logp), and then calling ec_dec_update() with the 3-tuple (fl[k] = 0, fh[k] = (1<<logp) - 1, ft = (1<<logp)) if the returned value of fs is less than (1<<logp) - 1 (a "0" was decoded). Otherwise, you use (fl[k] = (1<<logp) - 1, fh[k] = ft = (1<<logp)) (a "1" was decoded) ๐Ÿฆ‹ The implementation needs no multiplications or divisions ๐Ÿ”ฅ

4.1.3.3. ec_dec_icdf() ๐ŸŒˆ

the last one is ec_dec_icdf() (in entdec.c) ๐Ÿ’… It decodes a single symbol using a table-based context of up to 8 bits. It also replaces both the ec_decode() and ec_dec_update() steps, plus the search for the decoded symbol in between, so it's giving efficiency ๐Ÿ˜ญ The context is described by two parameters: an icdf ("inverse" cumulative distribution function) table and ftb. Just like with ec_decode_bin(), (1<<ftb) is equivalent to ft. Then idcf[k] stores (1<<ftb)-fh[k], which is equal to (1<<ftb) - fl[k+1]. fl[0] is assumed to be 0, and the table ends with a value of 0 (where fh[k] == ft) ๐Ÿ“

The function is mathematically the same as calling ec_decode() with ft = (1<<ftb). You use the returned value fs to search the table for the first entry where fs < (1<<ftb)-icdf[k], then call ec_dec_update() with fl[k] = (1<<ftb) - icdf[k-1] (or 0 if k == 0), fh[k] = (1<<ftb) - idcf[k], and ft = (1<<ftb). Combining the search with the update lets the division become a series of multiplications (which are usually much cheaper) ๐Ÿ‘‘ Using an inverse CDF also means an ftb as large as 8 works in an 8-bit table without any special cases ๐Ÿ’œ This is the main interface with the range decoder in the SILK layer, though it shows up in a few places in the CELT layer too ๐Ÿซถ

Icdf[k] is more convenient for the code, but the frequency counts, f[k], are a more natural way to represent the probability distribution function (PDF) for a symbol. So this document lists the frequency counts when it describes a context as a list, e.g., {4, 4, 4, 4}/16 for a uniform context with four possible values and ft = 16. The value of ft after the slash is always the sum of the entries in the PDF. It's included just for convenience ๐Ÿ™ˆ Contexts with identical probabilities, f[k]/ft, but different values of ft (or equivalently, ftb) are not the same, and generally can't be swapped for one another โญ An icdf table also can't represent a PDF where the first symbol has 0 probability. For those contexts, ec_dec_icdf() can still decode the symbol: use a table that drops the entries for any initial zero-probability values, and add the constant offset of the first value with a non-zero probability to the return value ๐ŸŒธ

4.1.4. Decoding Raw Bits ๐Ÿฆ‹

the raw bits used by the CELT layer are packed at the end of the frame. The least significant bit of the first value goes in the least significant bit of the last byte, then it fills up to the most significant bit in that last byte, continues on to the least significant bit of the penultimate byte, and so on ๐Ÿ“ The reference implementation reads them using ec_dec_bits() (in entdec.c). The range decoder has to read several bytes ahead in the stream, as described in Section 4.1.2.1, so the input used by the raw bits might overlap with the input used by the range coder. A decoder MUST allow this ๐Ÿซถ The format should make it impossible to try reading more raw bits than there are actual bits in the frame, though a decoder may wish to check for this and report an error โœจ

4.1.5. Decoding Uniformly Distributed Integers ๐Ÿ’…

the function ec_dec_uint() (in entdec.c) decodes one of ft equiprobable values in the range 0 to (ft - 1), inclusive, where each value has a frequency of 1. ft can be as large as (2**32 - 1) ๐Ÿ”ฅ Since ec_decode() is limited to a total frequency of (2**16 - 1), it splits the value up: a range coded symbol represents up to 8 of the high bits, and, if needed, raw bits represent the remainder of the value ๐Ÿงš Limiting the range coded symbol to 8 bits is a trade-off between implementation complexity, modeling error (since the symbols no longer truly have equal coding cost), and rounding error from the range coder itself (which gets larger as more bits are included) ๐ŸŒˆ Using raw bits reduces the maximum number of divisions needed in the worst case, but it means a decoder might end up decoding a value outside the range 0 to (ft - 1), inclusive ๐Ÿ™ˆ

ec_dec_uint() takes a single, positive parameter, ft, which isn't necessarily a power of two. It returns an integer, t, with a value between 0 and (ft - 1), inclusive. Let ftb = ilog(ft - 1), i.e., the number of bits needed to store (ft - 1) in two's complement notation. If ftb is 8 or less, then t is decoded with t = ec_decode(ft), and the range coder state is updated using the three-tuple (t, t + 1, ft) ๐Ÿ’–

If ftb is greater than 8, the top 8 bits of t are decoded using:

t = ec_decode(((ft - 1) >> (ftb - 8)) + 1)

The decoder state is then updated using the three-tuple (t, t + 1, ((ft - 1) >> (ftb - 8)) + 1). The remaining bits are decoded as raw bits, setting:

t = (t << (ftb - 8)) | ec_dec_bits(ftb - 8)

If, at this point, t >= ft, then the current frame is corrupt ๐Ÿ˜ญ In that case, the decoder should assume there was an error in the coding, decoding, or transmission, and it SHOULD take measures to conceal the error (e.g., saturate to ft-1 or use the Packet Loss Concealment (PLC)) and/or report to the application that the error has occurred ๐Ÿฅบ

4.1.6. Current Bit Usage ๐ŸŽ€

the bit allocation routines in the CELT decoder need a conservative upper bound on the number of bits used from the current frame so far, including both range coder bits and raw bits. This drives allocation decisions that must match the ones the encoder made ๐Ÿง  The reference implementation computes the upper bound to whole-bit precision with the function ec_tell() (in entcode.h), and to fractional 1/8th bit precision with the function ec_tell_frac() (in entcode.c). Like every operation in the range coder, it must be implemented in a bit-exact manner, and it must produce exactly the same value that the same functions return in the encoder after encoding the same symbols ๐Ÿ’…

ec_tell() is guaranteed to return ceil(ec_tell_frac()/8.0). In various places, the codec checks that there's enough room to contain a symbol before it tries to decode it. In practice, even though the number of bits used so far is an upper bound, decoding a symbol whose probability model suggests a worst-case cost of p 1/8th bits can actually advance the return value of ec_tell_frac() by p-1, p, or p+1 1/8th bits. This comes from approximation error in that upper bound, truncation error in the range coder, and, for large values of ft, modeling error in ec_dec_uint() ๐Ÿ™ˆ

BUT this error is bounded, and periodic calls to ec_tell() or ec_tell_frac() at precisely defined points in the decoding process stop it from building up. For a range coder symbol that needs a whole number of bits (i.e., where ft/(fh[k] - fl[k]) is a power of two), and where at least p 1/8th bits are available, decoding the symbol will never make ec_tell() or ec_tell_frac() go over the size of the frame ("bust the budget") โœจ In this case, the return value of ec_tell_frac() only advances by more than p 1/8th bits if there was an extra, fractional number of bits remaining. It never advances past the next whole-bit boundary, which is safe, since frames always contain a whole number of bits ๐Ÿซถ However, when p isn't a whole number of bits, an extra 1/8th bit is required to make sure decoding the symbol won't bust the budget ๐ŸŒธ

The reference implementation tracks the total number of whole bits the decoder has processed so far in the variable nbits_total. That count includes the (possibly fractional) number of bits currently buffered but not consumed inside the range coder. nbits_total is initialized to 9 just before the initial range renormalization process completes (or equivalently, it can be initialized to 33 after the first renormalization). The extra two bits over the actual amount buffered by the range coder guarantee that it's an upper bound and that there's enough room for the encoder to terminate the stream ๐Ÿงš Each iteration through the range coder's renormalization loop increases nbits_total by 8. Reading raw bits increases nbits_total by the number of raw bits read ๐Ÿ’œ

4.1.6.1. ec_tell() ๐Ÿฆ‹

The whole number of bits buffered in rng can be estimated via lg = ilog(rng). Then ec_tell() is just a simple matter of removing these bits from the total. It returns (nbits_total - lg) ๐Ÿ“

In a newly initialized decoder, before any symbols are read, this reports that 1 bit has been used. That's the bit reserved for termination of the encoder ๐Ÿ‘‘

4.1.6.2. ec_tell_frac() ๐ŸŒˆ

ec_tell_frac() estimates the number of bits buffered in rng to fractional precision. Since rng must be greater than 2**23 after renormalization, lg must be at least 24. Let:

r_Q15 = rng >> (lg-16)

so that 32768 <= r_Q15 < 65536, an unsigned Q15 value representing the fractional part of rng ๐Ÿ’– Then the following procedure adds one bit of precision to lg. First, update:

r_Q15 = (r_Q15*r_Q15) >> 15

Then, add the 16th bit of r_Q15 to lg via:

lg = 2*lg + (r_Q15 >> 16)

Finally, if that bit was a 1, reduce r_Q15 by a factor of two via:

r_Q15 = r_Q15 >> 1

so that it once again lies in the range 32768 <= r_Q15 < 65536. This procedure is repeated three times to extend lg to 1/8th bit precision. Then ec_tell_frac() returns (nbits_total*8 - lg) ๐Ÿ”ฅ

4.2. SILK Decoder โœจ

the decoder's LP layer uses a modified version of the SILK codec (called "SILK" from here on) ๐ŸŽ€ It runs a decoded excitation signal through adaptive long-term and short-term prediction synthesis filters. Internally, it runs at NB, MB, and WB sample rates. When it's used in a SWB or FB Hybrid frame, the LP layer itself still only runs in WB ๐Ÿงš

4.2.1. SILK Decoder Modules โœจ

okay bestie, here's the big picture ๐Ÿงš Figure 14 shows how the whole SILK decoder fits together ๐Ÿ’–

     +---------+    +------------+
  -->| Range   |--->| Decode     |---------------------------+
   1 | Decoder | 2  | Parameters |----------+       5        |
     +---------+    +------------+     4    |                |
                         3 |                |                |
                          \/               \/               \/
                    +------------+   +------------+   +------------+
                    | Generate   |-->| LTP        |-->| LPC        |
                    | Excitation |   | Synthesis  |   | Synthesis  |
                    +------------+   +------------+   +------------+
                                            ^                |
                                            |                |
                        +-------------------+----------------+
                        |                                      6
                        |   +------------+   +-------------+
                        +-->| Stereo     |-->| Sample Rate |-->
                            | Unmixing   | 7 | Conversion  | 8
                            +------------+   +-------------+

  1: Range encoded bitstream
  2: Coded parameters
  3: Pulses, LSBs, and signs
  4: Pitch lags, Long-Term Prediction (LTP) coefficients
  5: Linear Predictive Coding (LPC) coefficients and gains
  6: Decoded signal (mono or mid-side stereo)
  7: Unmixed signal (mono or left-right stereo)
  8: Resampled signal

Figure 14: SILK Decoder

so the decoder hands the bitstream (1) to the range decoder from Section 4.1, then pulls out the parameters (2) using the procedures in Sections 4.2.3 through 4.2.7.8.5. โœจ Those parameters (3, 4, 5) are used to build an excitation signal (see Section 4.2.7.8.6) ๐Ÿ”ฅ. That excitation goes through an optional Long-Term Prediction (LTP) filter (voiced frames only, see Section 4.2.7.9.1) and then a short-term prediction filter (see Section 4.2.7.9.2), and boom, you get the decoded signal (6) ๐ŸŽ€

for stereo streams, the mid-side stuff gets converted into separate left and right channels (7) ๐Ÿฆ‹ and then the result is resampled to whatever output sample rate you want (e.g., 48 kHz) so the resampled signal (8) can be mixed with the CELT layer ๐Ÿ’…


4.2.2. LP Layer Organization ๐ŸŒธ

okay so inside the LP layer of one Opus frame, you've got either a single 10 ms regular SILK frame, or anywhere from one to three 20 ms regular SILK frames ๐Ÿ“ a stereo Opus frame can double that count (up to six total) because it carries separate frames for a mid channel and, optionally, a side channel ๐Ÿ‘‘

optional Low Bit-Rate Redundancy (LBRR) frames can show up too. these are reduced-bitrate encodings of earlier SILK frames, and they help with recovering from packet loss ๐Ÿซถ if they're there, they come before the regular SILK frames. honestly they're pretty much identical to regular, active SILK frames, except they're usually encoded at a lower bitrate ๐Ÿฅบ in this document, "SILK frame" means either one, and "regular SILK frame" is used when we need to tell them apart ๐Ÿ’œ

logically, every SILK frame is made of either two or four 5 ms subframes โญ stuff like the quantization gain of the excitation, the pitch lag, and the filter coefficients can change from subframe to subframe ๐ŸŒˆ physically though, the parameters for each subframe are interleaved in the bitstream, as described in the relevant section for each parameter ๐Ÿงš

all these frames and subframes come from the same range coder, with no padding between them ๐Ÿ’– so packing several SILK frames into one Opus frame saves, on average, half a byte per SILK frame ๐Ÿ”ฅ it also lets some parameters be predicted from earlier SILK frames in the same Opus frame, and that doesn't hurt packet loss robustness (beyond whatever penalty comes from just using fewer, bigger packets to hold multiple frames) ๐Ÿฆ‹

stereo in SILK uses a variant of mid-side coding, so a mono decoder can just decode the mid channel ๐ŸŽ€ but the data for the two channels is interleaved, which means a mono decoder still has to unpack the side channel data ๐Ÿ˜ญ it would need to do that anyway for Hybrid Opus frames, or to support decoding individual 20 ms frames ๐Ÿ‘‘

Table 3 sums up how the LP layer is grouped, and Figures 15 and 16 show the ordering of the SILK frames for a 60 ms Opus frame, mono and stereo respectively ๐ŸŒธ

+-----------------------------------+---------------+---------------+
|             Symbol(s)             |     PDF(s)    |   Condition   |
+-----------------------------------+---------------+---------------+
|   Voice Activity Detection (VAD)  |    {1, 1}/2   |               |
|               Flags               |               |               |
|                                   |               |               |
|             LBRR Flag             |    {1, 1}/2   |               |
|                                   |               |               |
|        Per-Frame LBRR Flags       |    Table 4    | Section 4.2.4 |
|                                   |               |               |
|           LBRR Frame(s)           | Section 4.2.7 | Section 4.2.4 |
|                                   |               |               |
|       Regular SILK Frame(s)       | Section 4.2.7 |               |
+-----------------------------------+---------------+---------------+

Table 3: Organization of the SILK layer of an Opus Frame

                  +---------------------------------+
                  |            VAD Flags            |
                  +---------------------------------+
                  |            LBRR Flag            |
                  +---------------------------------+
                  | Per-Frame LBRR Flags (Optional) |
                  +---------------------------------+
                  |     LBRR Frame 1 (Optional)     |
                  +---------------------------------+
                  |     LBRR Frame 2 (Optional)     |
                  +---------------------------------+
                  |     LBRR Frame 3 (Optional)     |
                  +---------------------------------+
                  |      Regular SILK Frame 1       |
                  +---------------------------------+
                  |      Regular SILK Frame 2       |
                  +---------------------------------+
                  |      Regular SILK Frame 3       |
                  +---------------------------------+

Figure 15: A 60 ms Mono Frame

               +---------------------------------------+
               |             Mid VAD Flags             |
               +---------------------------------------+
               |             Mid LBRR Flag             |
               +---------------------------------------+
               |             Side VAD Flags            |
               +---------------------------------------+
               |             Side LBRR Flag            |
               +---------------------------------------+
               |  Mid Per-Frame LBRR Flags (Optional)  |
               +---------------------------------------+
               | Side Per-Frame LBRR Flags (Optional)  |
               +---------------------------------------+
               |     Mid LBRR Frame 1 (Optional)       |
               +---------------------------------------+
               |     Side LBRR Frame 1 (Optional)      |
               +---------------------------------------+
               |     Mid LBRR Frame 2 (Optional)       |
               +---------------------------------------+
               |     Side LBRR Frame 2 (Optional)      |
               +---------------------------------------+
               |     Mid LBRR Frame 3 (Optional)       |
               +---------------------------------------+
               |     Side LBRR Frame 3 (Optional)      |
               +---------------------------------------+
               |      Mid Regular SILK Frame 1         |
               +---------------------------------------+
               | Side Regular SILK Frame 1 (Optional)  |
               +---------------------------------------+
               |      Mid Regular SILK Frame 2         |
               +---------------------------------------+
               | Side Regular SILK Frame 2 (Optional)  |
               +---------------------------------------+
               |      Mid Regular SILK Frame 3         |
               +---------------------------------------+
               | Side Regular SILK Frame 3 (Optional)  |
               +---------------------------------------+

Figure 16: A 60 ms Stereo Frame


4.2.3. Header Bits ๐Ÿ’…

the LP layer starts with two to eight header bits, decoded in silk_Decode() (dec_API.c) ๐Ÿซถ these are one Voice Activity Detection (VAD) bit per frame (up to 3), followed by a single flag that says whether LBRR frames are present ๐ŸŒธ for a stereo packet, those first flags are for the mid channel, and then there's a second set of flags for the side channel ๐Ÿ‘‘

here's the fun part: these are the first symbols the range coder decodes, and they're coded as binary values with uniform probability, so you can pull them straight out of the most significant bits of the first byte of compressed data ๐Ÿงš which means a receiver can check whether an Opus frame has any active SILK frames without paying the overhead of running the range decoder ๐Ÿ”ฅ iconic, honestly ๐Ÿ˜ญ


4.2.4. Per-Frame LBRR Flags ๐Ÿ’œ

for Opus frames longer than 20 ms, a set of LBRR flags gets decoded for each channel that has its LBRR flag set ๐Ÿฆ‹ each set has one flag per 20 ms SILK frame. 40 ms Opus frames use the 2-frame LBRR flag PDF from Table 4, and 60 ms Opus frames use the 3-frame LBRR flag PDF ๐ŸŽ€ for each channel, the resulting 2- or 3-bit integer holds the LBRR flag for each frame, packed in order from the LSB to the MSB โœจ

        +------------+-------------------------------------+
        | Frame Size | PDF                                 |
        +------------+-------------------------------------+
        | 40 ms      | {0, 53, 53, 150}/256                |
        |            |                                     |
        | 60 ms      | {0, 41, 20, 29, 41, 15, 28, 82}/256 |
        +------------+-------------------------------------+

Table 4: LBRR Flag PDFs

a 10 or 20 ms Opus frame doesn't have any per-frame LBRR flags ๐Ÿฅบ that's because there can only be at most one LBRR frame per channel. the global LBRR flag in the header bits (see Section 4.2.3) already tells you that single LBRR frame is there, so no extra flags needed ๐Ÿ’–

4.2.5. LBRR Frames ๐ŸŽ€

okay so LBRR frames (if they're there at all) carry a re-encoded version of the signal right before the current Opus frame, as if it had been encoded with the current mode, frame size, audio bandwidth, and channel count ๐Ÿงš. Even if those settings are different from the previous Opus frame, the LBRR frames still get encoded this way. So when one of these settings changes between frames, the current frame's LBRR frames might not be simple drop-in swaps for what was in the last frame ๐Ÿ’….

For example, when you switch from 20 ms to 60 ms, the 60 ms Opus frame can hold LBRR frames covering up to three earlier 20 ms Opus frames, even if some of those times were already covered by LBRR frames ๐Ÿ˜ญ. Going the other way, from 20 ms to 10 ms, the 10 ms Opus frame can only have an LBRR frame covering at most half of the old 20 ms Opus frame ๐Ÿ’€. That can leave a gap that needs to be concealed if even a single packet gets lost (see Section 4.4) ๐Ÿ™ˆ. And when you switch from mono to stereo, the LBRR frames in the first stereo Opus frame MAY contain a non-trivial side channel โœจ.

To make LBRR frames work perfectly in every single case, an encoder might have to buffer up to 60 ms of audio and re-encode it during these transitions ๐ŸŒธ. The reference implementation, though, just turns off LBRR frames at the transition point to keep things simple ๐Ÿซถ. Transitions don't happen super often in normal use, so this doesn't really hurt packet loss robustness in a big way, which is honestly iconic ๐Ÿ‘‘.

The LBRR frames come right after the LBRR flags and before any regular SILK frames ๐Ÿฆ‹. Section 4.2.7 explains exactly what they contain. LBRR frames don't have their own separate VAD flags. They're only meant for active speech, so every LBRR frame is treated as active ๐ŸŽ€.

In a stereo Opus frame longer than 20 ms, the per-frame LBRR flags for the mid channel are coded together as a unit before the per-frame LBRR flags for the side channel ๐ŸŒˆ. The LBRR frames themselves, though, are interleaved. The decoder reads the mid-channel LBRR frame for a given 20 ms interval (if it's there), then immediately reads the matching side-channel LBRR frame (if that's there too), and only then moves on to the next 20 ms interval ๐Ÿงšโ€โ™€๏ธ.


4.2.6. Regular SILK Frames ๐ŸŒธ

The regular SILK frame(s) come after the LBRR frames (if there are any) ๐Ÿ’–. Section 4.2.7 covers their contents too. Unlike LBRR frames, a regular SILK frame gets coded for every time interval in an Opus frame, even if the matching VAD flags are unset ๐Ÿ˜ญ. For stereo Opus frames longer than 20 ms, the regular mid and side SILK frames for each 20 ms interval are interleaved, just like the LBRR frames ๐Ÿ”ฅ. The side frame can be skipped by coding an appropriate flag, as described in Section 4.2.7.2 โœจ.


4.2.7. SILK Frame Contents ๐Ÿ’…

each SILK frame starts with a bunch of side info, which includes:

  • The frame type and quantization type (Section 4.2.7.3) ๐ŸŽ€
  • Quantization gains (Section 4.2.7.4) ๐Ÿ’œ
  • Short-term prediction filter coefficients (Section 4.2.7.5) ๐Ÿฆ‹
  • A Line Spectral Frequencies (LSFs) interpolation weight (Section 4.2.7.5.5) ๐ŸŒˆ
  • LTP filter lags and gains (Section 4.2.7.6) ๐Ÿ“
  • A Linear Congruential Generator (LCG) seed (Section 4.2.7.7) ๐Ÿงš

the quantized excitation signal (see Section 4.2.7.8) comes right after all of these, at the very end of the frame ๐Ÿ‘‘. Table 5 breaks down the full order of a SILK frame ๐Ÿซถ:

   +---------------------------+-------------------+-------------------+
   |         Symbol(s)         |       PDF(s)      |     Condition     |
   +---------------------------+-------------------+-------------------+
   | Stereo Prediction Weights |      Table 6      |  Section 4.2.7.1  |
   |                           |                   |                   |
   |       Mid-only Flag       |      Table 8      |  Section 4.2.7.2  |
   |                           |                   |                   |
   |         Frame Type        |  Section 4.2.7.3  |                   |
   |                           |                   |                   |
   |       Subframe Gains      |  Section 4.2.7.4  |                   |
   |                           |                   |                   |
   |   Normalized LSF Stage-1  |      Table 14     |                   |
   |           Index           |                   |                   |
   |                           |                   |                   |
   |   Normalized LSF Stage-2  | Section 4.2.7.5.2 |                   |
   |          Residual         |                   |                   |
   |                           |                   |                   |
   |       Normalized LSF      |      Table 26     |    20 ms frame    |
   |    Interpolation Weight   |                   |                   |
   |                           |                   |                   |
   |     Primary Pitch Lag     | Section 4.2.7.6.1 |    Voiced frame   |
   |                           |                   |                   |
   |   Subframe Pitch Contour  |      Table 32     |    Voiced frame   |
   |                           |                   |                   |
   |     Periodicity Index     |      Table 37     |    Voiced frame   |
   |                           |                   |                   |
   |         LTP Filter        |      Table 38     |    Voiced frame   |
   |                           |                   |                   |
   |        LTP Scaling        |      Table 42     | Section 4.2.7.6.3 |
   |                           |                   |                   |
   |          LCG Seed         |      Table 43     |                   |
   |                           |                   |                   |
   |   Excitation Rate Level   |      Table 45     |                   |
   |                           |                   |                   |
   |  Excitation Pulse Counts  |      Table 46     |                   |
   |                           |                   |                   |
   |      Excitation Pulse     | Section 4.2.7.8.3 |   Non-zero pulse  |
   |         Locations         |                   |       count       |
   |                           |                   |                   |
   |      Excitation LSBs      |      Table 51     | Section 4.2.7.8.2 |
   |                           |                   |                   |
   |      Excitation Signs     |      Table 52     |                   |
   +---------------------------+-------------------+-------------------+

Table 5: Order of the Symbols in an Individual SILK Frame โœจ

4.2.7.1. Stereo Prediction Weights โœจ

okay bestie, so a SILK frame for the mid channel of a stereo Opus frame starts with a pair of side channel prediction weights ๐ŸŽ€ and they're designed so that zeros mean normal mid-side coupling ๐Ÿฆ‹. these weights can change on literally every frame, so the first chunk of each frame linearly interpolates between the previous weights and the current ones ๐Ÿ’–. if there are no previous weights, you use zeros for them ๐Ÿงš.

these prediction weights are NEVER in a mono Opus frame ๐Ÿ™ˆ, and the previous weights get reset to zeros on any transition from mono to stereo ๐Ÿ’…. they're also not included in an LBRR frame for the side channel, even if the LBRR flags say the mid channel wasn't coded ๐ŸŒธ. in that case the previous weights get used instead, and again zeros fill in if there are no previous weights since the last decoder reset (see Section 4.5.2) โœจ.

to summarize, these weights are coded if and only if

  • This is a stereo Opus frame (Section 3.1), and
  • The current SILK frame corresponds to the mid channel.

the weights come in three separate pieces, decoded by silk_stereo_decode_pred() (stereo_decode_pred.c) ๐Ÿ’œ. the first piece jointly codes the high-order part of a table index for both weights ๐Ÿ“. the second piece codes the low-order part of each table index ๐Ÿซถ. the third piece codes an offset used to linearly interpolate between table indices ๐Ÿ”ฅ. here's the deal:

Let n be an index decoded with the 25-element stage-1 PDF in Table 6. Then, let i0 and i1 be indices decoded with the stage-2 and stage-3 PDFs in Table 6, respectively, and let i2 and i3 be two more indices decoded with the stage-2 and stage-3 PDFs, all in that order.

+-------+-----------------------------------------------------------+
| Stage | PDF                                                       |
+-------+-----------------------------------------------------------+
| Stage | {7, 2, 1, 1, 1, 10, 24, 8, 1, 1, 3, 23, 92, 23, 3, 1, 1,  |
| 1     | 8, 24, 10, 1, 1, 1, 2, 7}/256                             |
|       |                                                           |
| Stage | {85, 86, 85}/256                                          |
| 2     |                                                           |
|       |                                                           |
| Stage | {51, 51, 52, 51, 51}/256                                  |
| 3     |                                                           |
+-------+-----------------------------------------------------------+

                    Table 6: Stereo Weight PDFs

then use n, i0, and i2 to form two table indices, wi0 and wi1, like this ๐Ÿ‘‘

wi0 = i0 + 3*(n/5)
wi1 = i2 + 3*(n%5)

the division is integer division ๐Ÿค“. the range of these indices is 0 to 14, inclusive. let w_Q13[i] be the i'th weight from Table 7. then the two prediction weights, w0_Q13 and w1_Q13, are

   w1_Q13 = w_Q13[wi1]
            + (((w_Q13[wi1+1] - w_Q13[wi1])*6554) >> 16)*(2*i3 + 1)

   w0_Q13 = w_Q13[wi0]
            + (((w_Q13[wi0+1] - w_Q13[wi0])*6554) >> 16)*(2*i1 + 1)
            - w1_Q13

N.B., w1_Q13 is computed first here, because w0_Q13 depends on it ๐Ÿ˜ญ. the constant 6554 is approximately 0.1 in Q16 ๐ŸŒˆ. although wi0 and wi1 only have 15 possible values, Table 7 has 16 entries so there's room to interpolate between entry wi0 and (wi0 + 1) (and likewise for wi1) ๐Ÿฆ‹.

                     +-------+--------------+
                     | Index | Weight (Q13) |
                     +-------+--------------+
                     | 0     |       -13732 |
                     |       |              |
                     | 1     |       -10050 |
                     |       |              |
                     | 2     |        -8266 |
                     |       |              |
                     | 3     |        -7526 |
                     |       |              |
                     | 4     |        -6500 |
                     |       |              |
                     | 5     |        -5000 |
                     |       |              |
                     | 6     |        -2950 |
                     |       |              |
                     | 7     |         -820 |
                     |       |              |
                     | 8     |          820 |
                     |       |              |
                     | 9     |         2950 |
                     |       |              |
                     | 10    |         5000 |
                     |       |              |
                     | 11    |         6500 |
                     |       |              |
                     | 12    |         7526 |
                     |       |              |
                     | 13    |         8266 |
                     |       |              |
                     | 14    |        10050 |
                     |       |              |
                     | 15    |        13732 |
                     +-------+--------------+

                   Table 7: Stereo Weight Table

4.2.7.2. Mid-Only Flag ๐ŸŽ€

there's a flag right after the stereo prediction weights that tells you if only the mid channel is coded for this time interval ๐Ÿ’…. it only shows up when

  • This is a stereo Opus frame (see Section 3.1),
  • The current SILK frame corresponds to the mid channel, and
  • Either
    • This is a regular SILK frame where the VAD flags (see Section 4.2.3) indicate that the corresponding side channel is not active.
    • This is an LBRR frame where the LBRR flags (see Sections 4.2.3 and 4.2.4) indicate that the corresponding side channel is not coded.

it's omitted when there are no stereo weights, for all of the same reasons ๐Ÿ™ˆ. it's also omitted for a regular SILK frame when the VAD flag of the corresponding side channel frame is set (meaning it's active) ๐Ÿ’€. the side channel MUST be coded in this case, which makes the mid-only flag redundant ๐Ÿซถ. it's also omitted for an LBRR frame when the corresponding LBRR flags say the side channel is coded ๐ŸŒธ.

when the flag is there, the decoder reads a single value using the PDF in Table 8, as implemented in silk_stereo_decode_mid_only() (stereo_decode_pred.c) ๐Ÿงš. if the flag is set, there's no corresponding SILK frame for the side channel, the entire decoding process for the side channel gets skipped, and zeros get fed to the stereo unmixing process (see Section 4.2.8) instead โœจ. as we said above, LBRR frames still include this flag when the LBRR flag says the side channel isn't coded ๐Ÿ‘‘. in that case, if this flag is zero (meaning there should be a side channel), then Packet Loss Concealment (PLC, see Section 4.4) SHOULD be invoked to recover a side channel signal ๐Ÿ”ฅ. otherwise, the stereo image will collapse ๐Ÿ˜ญ.

                         +---------------+
                         | PDF           |
                         +---------------+
                         | {192, 64}/256 |
                         +---------------+

                    Table 8: Mid-only Flag PDF

4.2.7.3. Frame Type ๐ŸŒˆ

each SILK frame has a single "frame type" symbol that jointly codes the signal type and quantization offset type of the frame ๐Ÿฆ‹. if the current frame is a regular SILK frame whose VAD bit was not set (an "inactive" frame), the frame type symbol takes a value of either 0 or 1 and gets decoded using the first PDF in Table 9 ๐Ÿ’œ. if the frame is an LBRR frame or a regular SILK frame whose VAD flag was set (an "active" frame), the symbol's value can range from 2 to 5, inclusive, and gets decoded using the second PDF in Table 9 ๐Ÿ“. Table 10 translates between the frame type symbol and the matching signal type and quantization offset type ๐Ÿ’–.

+----------+-----------------------------+
| VAD Flag | PDF                         |
+----------+-----------------------------+
| Inactive | {26, 230, 0, 0, 0, 0}/256   |
|          |                             |
| Active   | {0, 0, 24, 74, 148, 10}/256 |
+----------+-----------------------------+

                 Table 9: Frame Type PDFs
          +------------+-------------+--------------------------+
          | Frame Type | Signal Type | Quantization Offset Type |
          +------------+-------------+--------------------------+
          | 0          | Inactive    |                      Low |
          |            |             |                          |
          | 1          | Inactive    |                     High |
          |            |             |                          |
          | 2          | Unvoiced    |                      Low |
          |            |             |                          |
          | 3          | Unvoiced    |                     High |
          |            |             |                          |
          | 4          | Voiced      |                      Low |
          |            |             |                          |
          | 5          | Voiced      |                     High |
          +------------+-------------+--------------------------+

            Table 10: Signal Type and Quantization Offset Type from Frame Type

4.2.7.4. Subframe Gains

okay so bestie, every 5 ms subframe gets its own quantization gain ๐Ÿ’– these gains set the step size between quantization levels of the excitation signal, which is basically the whole vibe of how good the reconstruction sounds โœจ they're totally separate from the pitch contours coded for voiced frames, no cap ๐ŸŽ€ the gains get uniformly quantized to 6 bits on a log scale, so the resolution is about 1.369 dB and the range runs from roughly 1.94 dB to 88.21 dB ๐ŸŒˆ

the subframe gains are either coded independently or relative to the gain from the most recent coded subframe in the same channel. independent coding happens if and only if ๐Ÿซถ

o This is the first subframe in the current SILK frame, and

o Either

  • This is the first SILK frame of its type (LBRR or regular) for this channel in the current Opus frame, or
  • The previous SILK frame of the same type (LBRR or regular) for this channel in the same Opus frame was not coded.

for an independently coded subframe gain, the 3 most significant bits of the quantization gain get decoded with a PDF picked from Table 11, based on the decoded signal type (see Section 4.2.7.3) ๐Ÿ’…

+-------------+------------------------------------+
| Signal Type | PDF                                |
+-------------+------------------------------------+
| Inactive    | {32, 112, 68, 29, 12, 1, 1, 1}/256 |
|             |                                    |
| Unvoiced    | {2, 17, 45, 60, 62, 47, 19, 4}/256 |
|             |                                    |
| Voiced      | {1, 3, 26, 71, 94, 50, 9, 2}/256   |
+-------------+------------------------------------+

     Table 11: PDFs for Independent Quantization Gain MSB Coding

the 3 least significant bits use a uniform PDF, no drama ๐Ÿ“

+--------------------------------------+
| PDF                                  |
+--------------------------------------+
| {32, 32, 32, 32, 32, 32, 32, 32}/256 |
+--------------------------------------+

     Table 12: PDF for Independent Quantization Gain LSB Coding

those 6 bits combine into a value, gain_index, between 0 and 63 ๐Ÿฆ‹ when the gain for the previous subframe is available, the current gain gets limited like this:

log_gain = max(gain_index, previous_log_gain - 16)

this may help some implementations limit how much their internal LTP history precision changes ๐Ÿงš the indices this clamp applies to can't just be removed from the codebook, because previous_log_gain won't be available after packet loss ๐Ÿ˜ญ the clamping gets skipped after a decoder reset, and in the side channel if the previous frame in the side channel wasn't coded, since there's no previous_log_gain value to work with ๐Ÿ™ˆ it MAY also be skipped after packet loss.

for subframes without an independent gain (including the first subframe of frames not listed as using independent coding above), the quantization gain is coded relative to the gain from the previous subframe in the same channel. the PDF in Table 13 yields a delta_gain_index between 0 and 40, inclusive ๐Ÿ’œ

+-------------------------------------------------------------------+
| PDF                                                               |
+-------------------------------------------------------------------+
| {6, 5, 11, 31, 132, 21, 8, 4, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, |
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,       |
| 1}/256                                                            |
+-------------------------------------------------------------------+

         Table 13: PDF for Delta Quantization Gain Coding

this formula turns that index into a quantization gain for the current subframe, using the gain from the previous subframe ๐ŸŒธ

log_gain = clamp(0, max(2*delta_gain_index - 16,
                   previous_log_gain + delta_gain_index - 4), 63)

silk_gains_dequant() (gain_quant.c) dequantizes log_gain for the k'th subframe and converts it into a linear Q16 scale factor via ๐Ÿ‘‘

gain_Q16[k] = silk_log2lin((0x1D1C71*log_gain>>16) + 2090)

the function silk_log2lin() (log2lin.c) computes an approximation of 2**(inLog_Q7/128.0), where inLog_Q7 is its Q7 input. let i = inLog_Q7>>7 be the integer part of inLogQ7 and f = inLog_Q7&127 be the fractional part. then

(1<<i) + ((-174*f*(128-f)>>16)+f)*((1<<i)>>7)

yields the approximate exponential โœจ the final Q16 gain values lie between 81920 and 1686110208, inclusive (representing scale factors of 1.25 to 25728, respectively) ๐Ÿ”ฅ


4.2.7.5. Normalized Line Spectral Frequency (LSF) and Linear Predictive Coding (LPC) Coefficients

a set of normalized Line Spectral Frequency (LSF) coefficients follows the quantization gains in the bitstream, and they represent the Linear Predictive Coding (LPC) coefficients for the current SILK frame ๐ŸŽ€

once decoded, the normalized LSFs form an increasing list of Q15 values between 0 and 1. these represent the interleaved zeros on the upper half of the unit circle (between 0 and pi, hence "normalized") in the standard decomposition [SPECTRAL-PAIRS] of the LPC filter into a symmetric part and an anti-symmetric part (P and Q in Section 4.2.7.5.6) ๐Ÿฆ‹ because of non-linear effects in the decoding process, an implementation SHOULD match the fixed-point arithmetic described in this section exactly. an encoder SHOULD also use the same process ๐Ÿซถ

the normalized LSFs are coded using a two-stage vector quantizer (VQ) (Sections 4.2.7.5.1 and 4.2.7.5.2). NB and MB frames use an order-10 predictor, while WB frames use an order-16 predictor, so each of these two cases uses a different set of tables ๐Ÿ’– after reconstructing the normalized LSFs (Section 4.2.7.5.3), the decoder runs them through a stabilization process (Section 4.2.7.5.4), interpolates them between frames (Section 4.2.7.5.5), converts them back into LPC coefficients (Section 4.2.7.5.6), and then runs them through further processes to limit the range of the coefficients (Section 4.2.7.5.7) and the gain of the filter (Section 4.2.7.5.8). all of this is necessary to keep the reconstruction process stable ๐Ÿ˜ญ

4.2.7.5.1. Normalized LSF Stage 1 Decoding

the first VQ stage uses a 32-element codebook, coded with one of the PDFs in Table 14, depending on the audio bandwidth and the signal type of the current SILK frame ๐Ÿงš this yields a single index, I1, for the entire frame, which

  1. Indexes an element in a coarse codebook,
  2. Selects the PDFs for the second stage of the VQ, and
  3. Selects the prediction weights used to remove intra-frame redundancy from the second stage.

the actual codebook elements are listed in Tables 23 and 24, but they aren't needed until the last stages of reconstructing the LSF coefficients ๐Ÿ’…

+-----------+----------+--------------------------------------------+
| Audio     | Signal   | PDF                                        |
| Bandwidth | Type     |                                            |
+-----------+----------+--------------------------------------------+
| NB or MB  | Inactive | {44, 34, 30, 19, 21, 12, 11, 3, 3, 2, 16,  |
|           | or       | 2, 2, 1, 5, 2, 1, 3, 3, 1, 1, 2, 2, 2, 3,  |
|           | unvoiced | 1, 9, 9, 2, 7, 2, 1}/256                   |
|           |          |                                            |
| NB or MB  | Voiced   | {1, 10, 1, 8, 3, 8, 8, 14, 13, 14, 1, 14,  |
|           |          | 12, 13, 11, 11, 12, 11, 10, 10, 11, 8, 9,  |
|           |          | 8, 7, 8, 1, 1, 6, 1, 6, 5}/256             |
|           |          |                                            |
| WB        | Inactive | {31, 21, 3, 17, 1, 8, 17, 4, 1, 18, 16, 4, |
|           | or       | 2, 3, 1, 10, 1, 3, 16, 11, 16, 2, 2, 3, 2, |
|           | unvoiced | 11, 1, 4, 9, 8, 7, 3}/256                  |
|           |          |                                            |
| WB        | Voiced   | {1, 4, 16, 5, 18, 11, 5, 14, 15, 1, 3, 12, |
|           |          | 13, 14, 14, 6, 14, 12, 2, 6, 1, 12, 12,    |
|           |          | 11, 10, 3, 10, 5, 1, 1, 1, 3}/256          |
+-----------+----------+--------------------------------------------+

      Table 14: PDFs for Normalized LSF Stage-1 Index Decoding

4.2.7.5.2. Normalized LSF Stage 2 Decoding

a total of 16 PDFs are available for the LSF residual in the second stage: the 8 (a...h) for NB and MB frames given in Table 15, and the 8 (i...p) for WB frames given in Table 16 ๐ŸŒˆ which PDF is used for which coefficient is driven by the index, I1, decoded in the first stage. Table 17 lists the letter of the corresponding PDF for each normalized LSF coefficient for NB and MB, and Table 18 lists the same information for WB โœจ

+----------+--------------------------------------+
| Codebook | PDF                                  |
+----------+--------------------------------------+
| a        | {1, 1, 1, 15, 224, 11, 1, 1, 1}/256  |
|          |                                      |
| b        | {1, 1, 2, 34, 183, 32, 1, 1, 1}/256  |
|          |                                      |
| c        | {1, 1, 4, 42, 149, 55, 2, 1, 1}/256  |
|          |                                      |
| d        | {1, 1, 8, 52, 123, 61, 8, 1, 1}/256  |
|          |                                      |
| e        | {1, 3, 16, 53, 101, 74, 6, 1, 1}/256 |
|          |                                      |
| f        | {1, 3, 17, 55, 90, 73, 15, 1, 1}/256 |
|          |                                      |
| g        | {1, 7, 24, 53, 74, 67, 26, 3, 1}/256 |
|          |                                      |
| h        | {1, 1, 18, 63, 78, 58, 30, 6, 1}/256 |
+----------+--------------------------------------+

      Table 15: PDFs for NB/MB Normalized LSF Stage-2 Index Decoding
+----------+---------------------------------------+
| Codebook | PDF                                   |
+----------+---------------------------------------+
| i        | {1, 1, 1, 9, 232, 9, 1, 1, 1}/256     |
|          |                                       |
| j        | {1, 1, 2, 28, 186, 35, 1, 1, 1}/256   |
|          |                                       |
| k        | {1, 1, 3, 42, 152, 53, 2, 1, 1}/256   |
|          |                                       |
| l        | {1, 1, 10, 49, 126, 65, 2, 1, 1}/256  |
|          |                                       |
| m        | {1, 4, 19, 48, 100, 77, 5, 1, 1}/256  |
|          |                                       |
| n        | {1, 1, 14, 54, 100, 72, 12, 1, 1}/256 |
|          |                                       |
| o        | {1, 1, 15, 61, 87, 61, 25, 4, 1}/256  |
|          |                                       |
| p        | {1, 7, 21, 50, 77, 81, 17, 1, 1}/256  |
+----------+---------------------------------------+

       Table 16: PDFs for WB Normalized LSF Stage-2 Index Decoding

Okay so after we've got the first-stage index, the second stage residuals are decoded one coefficient at a time ๐Ÿ’… For each coefficient, the decoder reads a symbol using the PDF for I1 from Table 17 (NB/MB) or Table 18 (WB) โœจ Then it subtracts 4 from that result, so the index lands somewhere from -4 to 4, inclusive ๐ŸŒธ

If the index is -4 or 4, it's time for a bonus round ๐Ÿ”ฅ The decoder reads a second symbol with the PDF in Table 19 and adds it to the index using the same sign. That gives I2[k] a total range of -10 to 10, inclusive, which is iconic ๐Ÿ‘‘

                       +----+---------------------+
                       | I1 | Coefficient         |
                       +----+---------------------+
                       |    | 0 1 2 3 4 5 6 7 8 9 |
                       | 0  | a a a a a a a a a a |
                       |    |                     |
                       | 1  | b d b c c b c b b b |
                       |    |                     |
                       | 2  | c b b b b b b b b b |
                       |    |                     |
                       | 3  | b c c c c b c b b b |
                       |    |                     |
                       | 4  | c d d d d c c c c c |
                       |    |                     |
                       | 5  | a f d d c c c c b b |
                       |    |                     |
                       | g  | a c c c c c c c c b |
                       |    |                     |
                       | 7  | c d g e e e f e f f |
                       |    |                     |
                       | 8  | c e f f e f e g e e |
                       |    |                     |
                       | 9  | c e e h e f e f f e |
                       |    |                     |
                       | 10 | e d d d c d c c c c |
                       |    |                     |
                       | 11 | b f f g e f e f f f |
                       |    |                     |
                       | 12 | c h e g f f f f f f |
                       |    |                     |
                       | 13 | c h f f f f f g f e |
                       |    |                     |
                       | 14 | d d f e e f e f e e |
                       |    |                     |
                       | 15 | c d d f f e e e e e |
                       |    |                     |
                       | 16 | c e e g e f e f f f |
                       |    |                     |
                       | 17 | c f e g f f f e f e |
                       |    |                     |
                       | 18 | c h e f e f e f f f |
                       |    |                     |
                       | 19 | c f e g h g f g f e |
                       |    |                     |
                       | 20 | d g h e g f f g e f |
                       |    |                     |
                       | 21 | c h g e e e f e f f |
                       |    |                     |
                       | 22 | e f f e g g f g f e |
                       |    |                     |
                       | 23 | c f f g f g e g e e |
                       |    |                     |
                       | 24 | e f f f d h e f f e |
                       |    |                     |
                       | 25 | c d e f f g e f f e |
                       |    |                     |
                       | 26 | c d c d d e c d d d |
                       |    |                     |
                       | 27 | b b c c c c c d c c |
                       |    |                     |
                       | 28 | e f f g g g f g e f |
                       |    |                     |
                       | 29 | d f f e e e e d d c |
                       |    |                     |
                       | 30 | c f d h f f e e f e |
                       |    |                     |
                       | 31 | e e f e f g f g f e |
                       +----+---------------------+

    Table 17: Codebook Selection for NB/MB Normalized LSF Stage-2 Index
                                 Decoding

Table 17 is the NB/MB cheat sheet, and each I1 row tells you which letter-coded PDF to use for each coefficient ๐Ÿฆ‹

          +----+------------------------------------------------+
          | I1 | Coefficient                                    |
          +----+------------------------------------------------+
          |    | 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 |
          |    |                                                |
          | 0  | i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i |
          |    |                                                |
          | 1  | k  l  l  l  l  l  k  k  k  k  k  j  j  j  i  l |
          |    |                                                |
          | 2  | k  n  n  l  p  m  m  n  k  n  m  n  n  m  l  l |
          |    |                                                |
          | 3  | i  k  j  k  k  j  j  j  j  j  i  i  i  i  i  j |
          |    |                                                |
          | 4  | i  o  n  m  o  m  p  n  m  m  m  n  n  m  m  l |
          |    |                                                |
          | 5  | i  l  n  n  m  l  l  n  l  l  l  l  l  l  k  m |
          |    |                                                |
          | 6  | i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i |
          |    |                                                |
          | 7  | i  k  o  l  p  k  n  l  m  n  n  m  l  l  k  l |
          |    |                                                |
          | 8  | i  o  k  o  o  m  n  m  o  n  m  m  n  l  l  l |
          |    |                                                |
          | 9  | k  j  i  i  i  i  i  i  i  i  i  i  i  i  i  i |
          |    |                                                |
          | 10 | i  j  i  i  i  i  i  i  i  i  i  i  i  i  i  j |
          |    |                                                |
          | 11 | k  k  l  m  n  l  l  l  l  l  l  l  k  k  j  l |
          |    |                                                |
          | 12 | k  k  l  l  m  l  l  l  l  l  l  l  l  k  j  l |
          |    |                                                |
          | 13 | l  m  m  m  o  m  m  n  l  n  m  m  n  m  l  m |
          |    |                                                |
          | 14 | i  o  m  n  m  p  n  k  o  n  p  m  m  l  n  l |
          |    |                                                |
          | 15 | i  j  i  j  j  j  j  j  j  j  i  i  i  i  j  i |
          |    |                                                |
          | 16 | j  o  n  p  n  m  n  l  m  n  m  m  m  l  l  m |
          |    |                                                |
          | 17 | j  l  l  m  m  l  l  n  k  l  l  n  n  n  l  m |
          |    |                                                |
          | 18 | k  l  l  k  k  k  l  k  j  k  j  k  j  j  j  m |
          |    |                                                |
          | 19 | i  k  l  n  l  l  k  k  k  j  j  i  i  i  i  i |
          |    |                                                |
          | 20 | l  m  l  n  l  l  k  k  j  j  j  j  j  k  k  m |
          |    |                                                |
          | 21 | k  o  l  p  p  m  n  m  n  l  n  l  l  k  l  l |
          |    |                                                |
          | 22 | k  l  n  o  o  l  n  l  m  m  l  l  l  l  k  m |
          |    |                                                |
          | 23 | j  l  l  m  m  m  m  l  n  n  n  l  j  j  j  j |
          |    |                                                |
          | 24 | k  n  l  o  o  m  p  m  m  n  l  m  m  l  l  l |
          |    |                                                |
          | 25 | i  o  j  j  i  i  i  i  i  i  i  i  i  i  i  i |
          |    |                                                |
          | 26 | i  o  o  l  n  k  n  n  l  m  m  p  p  m  m  m |
          |    |                                                |
          | 27 | l  l  p  l  n  m  l  l  l  k  k  l  l  l  k  l |
          |    |                                                |
          | 28 | i  i  j  i  i  i  k  j  k  j  j  k  k  k  j  j |
          |    |                                                |
          | 29 | i  l  k  n  l  l  k  l  k  j  i  i  j  i  i  j |
          |    |                                                |
          | 30 | l  n  n  m  p  n  l  l  k  l  k  k  j  i  j  i |
          |    |                                                |
          | 31 | k  l  n  l  m  l  l  l  k  j  k  o  m  i  i  i |
          +----+------------------------------------------------+

     Table 18: Codebook Selection for WB Normalized LSF Stage-2 Index
                                 Decoding

Table 18 is the same vibe for WB, just with a wider grid ๐ŸŒˆ

Next up is the index extension PDF from Table 19 ๐Ÿงš

                     +-------------------------------+
                     | PDF                           |
                     +-------------------------------+
                     | {156, 60, 24, 9, 4, 2, 1}/256 |
                     +-------------------------------+

         Table 19: PDF for Normalized LSF Index Extension Decoding

Now, the decoded indices from both stages get translated back into normalized LSF coefficients in silk_NLSF_decode() (NLSF_decode.c) ๐Ÿ’– Here's the tea: the stage-2 indices are residuals after both the first stage of the VQ and a separate backwards-prediction step ๐Ÿซถ In the encoder, the backwards prediction subtracts a prediction from each residual, formed as a multiple of the coefficient that follows it. The decoder must undo this process ๐Ÿ™ˆ

Table 20 holds the prediction weights for each coefficient. There are two lists for NB and MB, and another two lists for WB, so each coefficient has two possible prediction weights to choose from โœจ

                  +-------------+-----+-----+-----+-----+
                  | Coefficient |   A |   B |   C |   D |
                  +-------------+-----+-----+-----+-----+
                  | 0           | 179 | 116 | 175 |  68 |
                  |             |     |     |     |     |
                  | 1           | 138 |  67 | 148 |  62 |
                  |             |     |     |     |     |
                  | 2           | 140 |  82 | 160 |  66 |
                  |             |     |     |     |     |
                  | 3           | 148 |  59 | 176 |  60 |
                  |             |     |     |     |     |
                  | 4           | 151 |  92 | 178 |  72 |
                  |             |     |     |     |     |
                  | 5           | 149 |  72 | 173 | 117 |
                  |             |     |     |     |     |
                  | 6           | 153 | 100 | 174 |  85 |
                  |             |     |     |     |     |
                  | 7           | 151 |  89 | 164 |  90 |
                  |             |     |     |     |     |
                  | 8           | 163 |  92 | 177 | 118 |
                  |             |     |     |     |     |
                  | 9           |     |     | 174 | 136 |
                  |             |     |     |     |     |
                  | 10          |     |     | 196 | 151 |
                  |             |     |     |     |     |
                  | 11          |     |     | 182 | 142 |
                  |             |     |     |     |     |
                  | 12          |     |     | 198 | 160 |
                  |             |     |     |     |     |
                  | 13          |     |     | 192 | 142 |
                  |             |     |     |     |     |
                  | 14          |     |     | 182 | 155 |
                  +-------------+-----+-----+-----+-----+

         Table 20: Prediction Weights for Normalized LSF Decoding

okay so the prediction gets undone using the procedure in silk_NLSF_residual_dequant() (in NLSF_decode.c) ๐Ÿ’…โœจ each coefficient picks its prediction weight from one of two lists, and which list it uses depends on the stage-1 index, I1. ๐ŸŽ€ Table 21 tells you the picks for each coefficient for NB and MB, and Table 22 has the picks for WB ๐Ÿฆ‹

quick stats so you can keep up ๐Ÿงš d_LPC is the order of the codebook, so it's 10 for NB and MB and 16 for WB. pred_Q8[k] is the weight for the k'th coefficient that got selected by this process, for 0 <= k < d_LPC-1 ๐Ÿ’œ

then the stage-2 residual for each coefficient is computed with this formula, and honestly it's giving math-core main character energy ๐Ÿ”ฅ

res_Q10[k] = (k+1 < d_LPC ? (res_Q10[k+1]*pred_Q8[k])>>8 : 0)
             + ((((I2[k]<<10) - sign(I2[k])*102)*qstep)>>16) ,

where qstep is the Q16 quantization step size ๐ŸŒธ it's 11796 for NB and MB and 9830 for WB. those are step sizes of roughly 0.18 and 0.15, respectively ๐Ÿ“

here are the tables, copied exactly because they're a whole vibe ๐Ÿซถ

                    +----+-------------------+
                    | I1 | Coefficient       |
                    +----+-------------------+
                    |    | 0 1 2 3 4 5 6 7 8 |
                    |    |                   |
                    | 0  | A B A A A A A A A |
                    |    |                   |
                    | 1  | B A A A A A A A A |
                    |    |                   |
                    | 2  | A A A A A A A A A |
                    |    |                   |
                    | 3  | B B B A A A A B A |
                    |    |                   |
                    | 4  | A B A A A A A A A |
                    |    |                   |
                    | 5  | A B A A A A A A A |
                    |    |                   |
                    | 6  | B A B B A A A B A |
                    |    |                   |
                    | 7  | A B B A A B B A A |
                    |    |                   |
                    | 8  | A A B B A B A B B |
                    |    |                   |
                    | 9  | A A B B A A B B B |
                    |    |                   |
                    | 10 | A A A A A A A A A |
                    |    |                   |
                    | 11 | A B A B B B B B A |
                    |    |                   |
                    | 12 | A B A B B B B B A |
                    |    |                   |
                    | 13 | A B B B B B B B A |
                    |    |                   |
                    | 14 | B A B B A B B B B |
                    |    |                   |
                    | 15 | A B B B B B A B A |
                    |    |                   |
                    | 16 | A A B B A B A B A |
                    |    |                   |
                    | 17 | A A B B B A B B B |
                    |    |                   |
                    | 18 | A B B A A B B B A |
                    |    |                   |
                    | 19 | A A A B B B A B A |
                    |    |                   |
                    | 20 | A B B A A B A B A |
                    |    |                   |
                    | 21 | A B B A A A B B A |
                    |    |                   |
                    | 22 | A A A A A B B B B |
                    |    |                   |
                    | 23 | A A B B A A A B B |
                    |    |                   |
                    | 24 | A A A B A B B B B |
                    |    |                   |
                    | 25 | A B B B B B B B A |
                    |    |                   |
                    | 26 | A A A A A A A A A |
                    |    |                   |
                    | 27 | A A A A A A A A A |
                    |    |                   |
                    | 28 | A A B A B B A B A |
                    |    |                   |
                    | 29 | B A A B A A A A A |
                    |    |                   |
                    | 30 | A A A B B A B A B |
                    |    |                   |
                    | 31 | B A B B A B B B B |
                    +----+-------------------+

      Table 21: Prediction Weight Selection for NB/MB Normalized LSF
                                 Decoding
       +----+---------------------------------------------+
       | I1 | Coefficient                                 |
       +----+---------------------------------------------+
       |    | 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 |
       |    |                                             |
       | 0  | C  C  C  C  C  C  C  C  C  C  C  C  C  C  D |
       |    |                                             |
       | 1  | C  C  C  C  C  C  C  C  C  C  C  C  C  C  C |
       |    |                                             |
       | 2  | C  C  D  C  C  D  D  D  C  D  D  D  D  C  C |
       |    |                                             |
       | 3  | C  C  C  C  C  C  C  C  C  C  C  C  D  C  C |
       |    |                                             |
       | 4  | C  D  D  C  D  C  D  D  C  D  D  D  D  D  C |
       |    |                                             |
       | 5  | C  C  D  C  C  C  C  C  C  C  C  C  C  C  C |
       |    |                                             |
       | 6  | D  C  C  C  C  C  C  C  C  C  C  D  C  D  C |
       |    |                                             |
       | 7  | C  D  D  C  C  C  D  C  D  D  D  C  D  C  D |
       |    |                                             |
       | 8  | C  D  C  D  D  C  D  C  D  C  D  D  D  D  D |
       |    |                                             |
       | 9  | C  C  C  C  C  C  C  C  C  C  C  C  C  C  D |
       |    |                                             |
       | 10 | C  D  C  C  C  C  C  C  C  C  C  C  C  C  C |
       |    |                                             |
       | 11 | C  C  D  C  D  D  D  D  D  D  D  C  D  C  C |
       |    |                                             |
       | 12 | C  C  D  C  C  D  C  D  C  D  C  C  D  C  C |
       |    |                                             |
       | 13 | C  C  C  C  D  D  C  D  C  D  D  D  D  C  C |
       |    |                                             |
       | 14 | C  D  C  C  C  D  D  C  D  D  D  C  D  D  D |
       |    |                                             |
       | 15 | C  C  D  D  C  C  C  C  C  C  C  C  D  D  C |
       |    |                                             |
       | 16 | C  D  D  C  D  C  D  D  D  D  D  C  D  C  C |
       |    |                                             |
       | 17 | C  C  D  C  C  C  C  D  C  C  D  D  D  C  C |
       |    |                                             |
       | 18 | C  C  C  C  C  C  C  C  C  C  C  C  C  C  D |
       |    |                                             |
       | 19 | C  C  C  C  C  C  C  C  C  C  C  C  D  C  C |
       |    |                                             |
       | 20 | C  C  C  C  C  C  C  C  C  C  C  C  C  C  C |
       |    |                                             |
       | 21 | C  D  C  D  C  D  D  C  D  C  D  C  D  D  C |
       |    |                                             |
       | 22 | C  C  D  D  D  D  C  D  D  C  C  D  D  C  C |
       |    |                                             |
       | 23 | C  D  D  C  D  C  D  C  D  C  C  C  C  D  C |
       |    |                                             |
       | 24 | C  C  C  D  D  C  D  C  D  D  D  D  D  D  D |
       |    |                                             |
       | 25 | C  C  C  C  C  C  C  C  C  C  C  C  C  C  D |
       |    |                                             |
       | 26 | C  D  D  C  C  C  D  D  C  C  D  D  D  D  D |
       |    |                                             |
       | 27 | C  C  C  C  C  D  C  D  D  D  D  C  D  D  D |
       |    |                                             |
       | 28 | C  C  C  C  C  C  C  C  C  C  C  C  C  C  D |
       |    |                                             |
       | 29 | C  C  C  C  C  C  C  C  C  C  C  C  C  C  D |
       |    |                                             |
       | 30 | D  C  C  C  C  C  C  C  C  C  C  D  C  C  C |
       |    |                                             |
       | 31 | C  C  D  C  C  D  D  D  C  C  D  C  C  D  C |
       +----+---------------------------------------------+

   Table 22: Prediction Weight Selection for WB Normalized LSF Decoding

that's the whole picture for the stage-2 prediction undo, bestie ๐ŸŒˆ๐Ÿ’–

4.2.7.5.3. Reconstructing the Normalized LSF Coefficients โœจ

okay so bestie, now that we've got the stage-1 index I1 and the stage-2 residual res_Q10[] decoded, it's time to put the normalized LSF coefficients back together ๐Ÿ’…๐ŸŽ€

the thing is, quantization doesn't hurt every LSF coefficient equally. some errors wreck the spectrum way more than others ๐Ÿ˜ญ so the stage-2 residual gets weighted to match, using the low-complexity Inverse Harmonic Mean Weighting (IHMW) function proposed in [LAROIA-ICASSP]. the cute part is that the weights come straight out of the stage-1 codebook vector, no extra info needed ๐Ÿฆ‹ we call the k'th entry of that vector cb1_Q8[k] (from Table 23 or Table 24). then, for 0 <= k < d_LPC, this expression gives you the square of the weight as a Q18 value:

            w2_Q18[k] = (1024/(cb1_Q8[k] - cb1_Q8[k-1])
                         + 1024/(cb1_Q8[k+1] - cb1_Q8[k])) << 16

where cb1_Q8[-1] = 0 and cb1_Q8[d_LPC] = 256, and the division is integer division. we don't want the squared version though, so we shrink it down to an unsquared, Q9 value with this square-root approximation:

                 i = ilog(w2_Q18[k])
                 f = (w2_Q18[k]>>(i-8)) & 127
                 y = ((i&1) ? 32768 : 46214) >> ((32-i)>>1)
                 w_Q9[k] = y + ((213*f*y)>>16)

the constant 46214 here is approximately the square root of 2 in Q15, which is a fun little detail ๐ŸŒˆ the whole cb1_Q8[] vector fully decides these weights, so you could just tabulate them and store them as 13-bit unsigned values (anything from 1819 to 5227, inclusive) and skip computing them while decoding โญ the reference implementation already has code that calculates these weights on unquantized coefficients in the encoder, in silk_NLSF_VQ_weights_laroia() (NLSF_VQ_weights_laroia.c) and the functions that call it. so instead of hauling around a pre-computed table, the decoder just reuses that same code to save on ROM ๐Ÿ’œ

here are the two stage-1 codebooks, the NB/MB one first ๐Ÿ“

              +----+----------------------------------------+
              | I1 | Codebook (Q8)                          |
              +----+----------------------------------------+
              |    |  0   1   2   3   4   5   6   7   8   9 |
              |    |                                        |
              | 0  | 12  35  60  83 108 132 157 180 206 228 |
              |    |                                        |
              | 1  | 15  32  55  77 101 125 151 175 201 225 |
              |    |                                        |
              | 2  | 19  42  66  89 114 137 162 184 209 230 |
              |    |                                        |
              | 3  | 12  25  50  72  97 120 147 172 200 223 |
              |    |                                        |
              | 4  | 26  44  69  90 114 135 159 180 205 225 |
              |    |                                        |
              | 5  | 13  22  53  80 106 130 156 180 205 228 |
              |    |                                        |
              | 6  | 15  25  44  64  90 115 142 168 196 222 |
              |    |                                        |
              | 7  | 19  24  62  82 100 120 145 168 190 214 |
              |    |                                        |
              | 8  | 22  31  50  79 103 120 151 170 203 227 |
              |    |                                        |
              | 9  | 21  29  45  65 106 124 150 171 196 224 |
              |    |                                        |
              | 10 | 30  49  75  97 121 142 165 186 209 229 |
              |    |                                        |
              | 11 | 19  25  52  70  93 116 143 166 192 219 |
              |    |                                        |
              | 12 | 26  34  62  75  97 118 145 167 194 217 |
              |    |                                        |
              | 13 | 25  33  56  70  91 113 143 165 196 223 |
              |    |                                        |
              | 14 | 21  34  51  72  97 117 145 171 196 222 |
              |    |                                        |
              | 15 | 20  29  50  67  90 117 144 168 197 221 |
              |    |                                        |
              | 16 | 22  31  48  66  95 117 146 168 196 222 |
              |    |                                        |
              | 17 | 24  33  51  77 116 134 158 180 200 224 |
              |    |                                        |
              | 18 | 21  28  70  87 106 124 149 170 194 217 |
              |    |                                        |
              | 19 | 26  33  53  64  83 117 152 173 204 225 |
              |    |                                        |
              | 20 | 27  34  65  95 108 129 155 174 210 225 |
              |    |                                        |
              | 21 | 20  26  72  99 113 131 154 176 200 219 |
              |    |                                        |
              | 22 | 34  43  61  78  93 114 155 177 205 229 |
              |    |                                        |
              | 23 | 23  29  54  97 124 138 163 179 209 229 |
              |    |                                        |
              | 24 | 30  38  56  89 118 129 158 178 200 231 |
              |    |                                        |
              | 25 | 21  29  49  63  85 111 142 163 193 222 |
              |    |                                        |
              | 26 | 27  48  77 103 133 158 179 196 215 232 |
              |    |                                        |
              | 27 | 29  47  74  99 124 151 176 198 220 237 |
              |    |                                        |
              | 28 | 33  42  61  76  93 121 155 174 207 225 |
              |    |                                        |
              | 29 | 29  53  87 112 136 154 170 188 208 227 |
              |    |                                        |
              | 30 | 24  30  52  84 131 150 166 186 203 229 |
              |    |                                        |
              | 31 | 37  48  64  84 104 118 156 177 201 230 |
              +----+----------------------------------------+

          Table 23: NB/MB Normalized LSF Stage-1 Codebook Vectors

and now the WB one, which is a bit wider ๐ŸŒธ

    +----+------------------------------------------------------------+
    | I1 | Codebook (Q8)                                              |
    +----+------------------------------------------------------------+
    |    |  0  1  2  3  4   5   6   7   8   9  10  11  12  13  14  15 |
    |    |                                                            |
    | 0  |  7 23 38 54 69  85 100 116 131 147 162 178 193 208 223 239 |
    |    |                                                            |
    | 1  | 13 25 41 55 69  83  98 112 127 142 157 171 187 203 220 236 |
    |    |                                                            |
    | 2  | 15 21 34 51 61  78  92 106 126 136 152 167 185 205 225 240 |
    |    |                                                            |
    | 3  | 10 21 36 50 63  79  95 110 126 141 157 173 189 205 221 237 |
    |    |                                                            |
    | 4  | 17 20 37 51 59  78  89 107 123 134 150 164 184 205 224 240 |
    |    |                                                            |
    | 5  | 10 15 32 51 67  81  96 112 129 142 158 173 189 204 220 236 |
    |    |                                                            |
    | 6  |  8 21 37 51 65  79  98 113 126 138 155 168 179 192 209 218 |
    |    |                                                            |
    | 7  | 12 15 34 55 63  78  87 108 118 131 148 167 185 203 219 236 |
    |    |                                                            |
    | 8  | 16 19 32 36 56  79  91 108 118 136 154 171 186 204 220 237 |
    |    |                                                            |
    | 9  | 11 28 43 58 74  89 105 120 135 150 165 180 196 211 226 241 |
    |    |                                                            |
    | 10 |  6 16 33 46 60  75  92 107 123 137 156 169 185 199 214 225 |
    |    |                                                            |
    | 11 | 11 19 30 44 57  74  89 105 121 135 152 169 186 202 218 234 |
    |    |                                                            |
    | 12 | 12 19 29 46 57  71  88 100 120 132 148 165 182 199 216 233 |
    |    |                                                            |
    | 13 | 17 23 35 46 56  77  92 106 123 134 152 167 185 204 222 237 |
    |    |                                                            |
    | 14 | 14 17 45 53 63  75  89 107 115 132 151 171 188 206 221 240 |
    |    |                                                            |
    | 15 |  9 16 29 40 56  71  88 103 119 137 154 171 189 205 222 237 |
    |    |                                                            |
    | 16 | 16 19 36 48 57  76  87 105 118 132 150 167 185 202 218 236 |
    |    |                                                            |
    | 17 | 12 17 29 54 71  81  94 104 126 136 149 164 182 201 221 237 |
    |    |                                                            |
    | 18 | 15 28 47 62 79  97 115 129 142 155 168 180 194 208 223 238 |
    |    |                                                            |
    | 19 |  8 14 30 45 62  78  94 111 127 143 159 175 192 207 223 239 |
    |    |                                                            |
    | 20 | 17 30 49 62 79  92 107 119 132 145 160 174 190 204 220 235 |
    |    |                                                            |
    | 21 | 14 19 36 45 61  76  91 108 121 138 154 172 189 205 222 238 |
    |    |                                                            |
    | 22 | 12 18 31 45 60  76  91 107 123 138 154 171 187 204 221 236 |
    |    |                                                            |
    | 23 | 13 17 31 43 53  70  83 103 114 131 149 167 185 203 220 237 |
    |    |                                                            |
    | 24 | 17 22 35 42 58  78  93 110 125 139 155 170 188 206 224 240 |
    |    |                                                            |
    | 25 |  8 15 34 50 67  83  99 115 131 146 162 178 193 209 224 239 |
    |    |                                                            |
    | 26 | 13 16 41 66 73  86  95 111 128 137 150 163 183 206 225 241 |
    |    |                                                            |
    | 27 | 17 25 37 52 63  75  92 102 119 132 144 160 175 191 212 231 |
    |    |                                                            |
    | 28 | 19 31 49 65 83 100 117 133 147 161 174 187 200 213 227 242 |
    |    |                                                            |
    | 29 | 18 31 52 68 88 103 117 126 138 149 163 177 192 207 223 239 |
    |    |                                                            |
    | 30 | 16 29 47 61 76  90 106 119 133 147 161 176 193 209 224 240 |
    |    |                                                            |
    | 31 | 15 21 35 50 61  73  86  97 110 119 129 141 175 198 218 237 |
    +----+------------------------------------------------------------+

           Table 24: WB Normalized LSF Stage-1 Codebook Vectors

okay, last step ๐ŸŽ‰ given the stage-1 codebook entry cb1_Q8[], the stage-2 residual res_Q10[], and their weights w_Q9[], the reconstructed normalized LSF coefficients are:

   NLSF_Q15[k] = clamp(0,
                  (cb1_Q8[k]<<7) + (res_Q10[k]<<14)/w_Q9[k], 32767)

the division here is integer division too ๐Ÿ”ฅ but hold on, this is where it gets a little messy ngl ๐Ÿ™ˆ nothing in the reconstruction OR the encoder's quantization guarantees that the coefficients are monotonically increasing and spaced far enough apart to keep the filter stable [KABAL86]. like, not me getting an unstable filter ๐Ÿ’€ when the reference encoder is used, roughly 2% of frames break this constraint. so the next section is all about the stabilization procedure that makes those guarantees happen ๐Ÿซถ

4.2.7.5.4. Normalized LSF Stabilization โœจ

okay so this is the bit where we tidy up the normalized LSF coefficients, NLSF_Q15[], so they stay a healthy distance apart ๐Ÿงš. The whole thing lives in silk_NLSF_stabilize() (NLSF_stabilize.c). The minimum spacing is basically the 0.01 percentile of a huge training set, so these gaps are predetermined, not vibes-based ๐Ÿ’…. Table 25 gives the minimum spacings for NB and MB in one column and WB in another. Row k is the smallest allowed value of NLSF_Q15[k]-NLSF_Q15[k-1]. For the first and last coefficient, NLSF_Q15[-1] is taken to be 0 and NLSF_Q15[d_LPC] is taken to be 32768, so the edges are covered too ๐Ÿซถ

                 +-------------+-----------+-----+
                 | Coefficient | NB and MB |  WB |
                 +-------------+-----------+-----+
                 | 0           |       250 | 100 |
                 |             |           |     |
                 | 1           |         3 |   3 |
                 |             |           |     |
                 | 2           |         6 |  40 |
                 |             |           |     |
                 | 3           |         3 |   3 |
                 |             |           |     |
                 | 4           |         3 |   3 |
                 |             |           |     |
                 | 5           |         3 |   3 |
                 |             |           |     |
                 | 6           |         4 |   5 |
                 |             |           |     |
                 | 7           |         3 |  14 |
                 |             |           |     |
                 | 8           |         3 |  14 |
                 |             |           |     |
                 | 9           |         3 |  10 |
                 |             |           |     |
                 | 10          |       461 |  11 |
                 |             |           |     |
                 | 11          |           |   3 |
                 |             |           |     |
                 | 12          |           |   8 |
                 |             |           |     |
                 | 13          |           |   9 |
                 |             |           |     |
                 | 14          |           |   7 |
                 |             |           |     |
                 | 15          |           |   3 |
                 |             |           |     |
                 | 16          |           | 347 |
                 +-------------+-----------+-----+

         Table 25: Minimum Spacing for Normalized LSF Coefficients

The procedure starts out gentle ๐ŸŒธ. It tries small adjustments that aim to minimize the distortion introduced. After 20 of those adjustments, it switches to a more direct method. That method guarantees the constraints are enforced, but it may need large adjustments to get there ๐Ÿ’€

Let NDeltaMin_Q15[k] be the minimum required spacing for the current audio bandwidth, taken from Table 25. First, the procedure finds the index i where NLSF_Q15[i] - NLSF_Q15[i-1] - NDeltaMin_Q15[i] is the smallest. Ties go to the lower value of i โœจ. If this value is non-negative, the stabilization stops, because the coefficients already satisfy all the constraints, bestie ๐ŸŽ€. Otherwise, there are two special cases. If i == 0, it sets NLSF_Q15[0] to NDeltaMin_Q15[0]. If i == d_LPC, it sets NLSF_Q15[d_LPC-1] to (32768 - NDeltaMin_Q15[d_LPC]). For every other value of i, both NLSF_Q15[i-1] and NLSF_Q15[i] get updated like this ๐Ÿฆ‹

                                          i-1
                                          __
 min_center_Q15 = (NDeltaMin_Q15[i]>>1) + \  NDeltaMin_Q15[k]
                                          /_
                                          k=0
                                                 d_LPC
                                                  __
 max_center_Q15 = 32768 - (NDeltaMin_Q15[i]>>1) - \  NDeltaMin_Q15[k]
                                                  /_
                                                 k=i+1
center_freq_Q15 = clamp(min_center_Q15[i],
                        (NLSF_Q15[i-1] + NLSF_Q15[i] + 1)>>1
                        max_center_Q15[i])

 NLSF_Q15[i-1] = center_freq_Q15 - (NDeltaMin_Q15[i]>>1)

   NLSF_Q15[i] = NLSF_Q15[i-1] + NDeltaMin_Q15[i]

Then the whole procedure repeats, until it has either run 20 times or stopped because the coefficients satisfy all the constraints ๐Ÿ”ฅ

After the 20th repetition, the fallback procedure runs exactly once ๐Ÿ˜ญ. First, the values of NLSF_Q15[k] for 0 <= k < d_LPC get sorted in ascending order. Then, for each k from 0 to d_LPC-1, NLSF_Q15[k] is set to:

max(NLSF_Q15[k], NLSF_Q15[k-1] + NDeltaMin_Q15[k])

Next, for each k from d_LPC-1 down to 0, NLSF_Q15[k] is set to:

min(NLSF_Q15[k], NLSF_Q15[k+1] - NDeltaMin_Q15[k+1])

No need to check whether the coefficients already satisfy the constraints before running this fallback. If they do, it won't change their values, so it's totally safe ๐Ÿ’œ


4.2.7.5.5. Normalized LSF Interpolation ๐ŸŒˆ

For 20 ms SILK frames, the first half of the frame (aka the first two subframes) may use normalized LSF coefficients that are interpolated between the decoded LSFs for the most recent coded frame in the same channel and the current frame ๐Ÿ“. A Q2 interpolation factor follows the LSF coefficient indices in the bitstream. It gets decoded using the PDF in Table 26. This all happens in silk_decode_indices() (decode_indices.c). After either of these:

  • An uncoded regular SILK frame in the side channel, or
  • A decoder reset (see Section 4.5.2),

the decoder still decodes this factor, but it ignores the value and always uses 4 instead ๐Ÿ™ˆ. For 10 ms SILK frames, this factor isn't stored at all โœจ

                    +---------------------------+
                    | PDF                       |
                    +---------------------------+
                    | {13, 22, 29, 11, 181}/256 |
                    +---------------------------+

        Table 26: PDF for Normalized LSF Interpolation Index

Now the math ๐Ÿงฎ. Let n2_Q15[k] be the normalized LSF coefficients decoded by the procedure in Section 4.2.7.5, n0_Q15[k] be the LSF coefficients decoded for the prior frame, and w_Q2 be the interpolation factor. Then the normalized LSF coefficients used for the first half of a 20 ms frame, n1_Q15[k], are:

     n1_Q15[k] = n0_Q15[k] + (w_Q2*(n2_Q15[k] - n0_Q15[k]) >> 2)

This interpolation is performed in silk_decode_parameters() (decode_parameters.c) ๐Ÿ‘‘

4.2.7.5.6. Converting Normalized LSFs to LPC Coefficients โœจ

okay bestie, this is where the LSFs turn back into a real LPC filter ๐Ÿฆ‹ Any LPC filter A(z) can be split into a symmetric part P(z) and an anti-symmetric part Q(z), and the math goes like this:

                          d_LPC
                           __         -k   1
                A(z) = 1 - \  a[k] * z   = - * (P(z) + Q(z))
                           /_              2
                           k=1
                                     -d_LPC-1      -1
                      P(z) = A(z) + z         * A(z  )

                                     -d_LPC-1      -1
                      Q(z) = A(z) - z         * A(z  )

the even normalized LSF coefficients line up with a pair of conjugate roots of P(z), and the odd ones line up with a pair of conjugate roots of Q(z). all of those roots sit on the unit circle ๐ŸŒˆ and P(z) also has a root at pi, while Q(z) has a root at 0. so you can rebuild both polynomials straight from the normalized LSF coefficients, n[k], like this:

                          d_LPC/2-1
                      -1     ___                        -1    -2
         P(z) = (1 + z  ) *  | |  (1 - 2*cos(pi*n[2*k])*z  + z  )
                             k=0

                          d_LPC/2-1
                      -1     ___                          -1    -2
         Q(z) = (1 - z  ) *  | |  (1 - 2*cos(pi*n[2*k+1])*z  + z  )
                             k=0

the catch is that SILK does this with a fixed-point approximation, not the exact math ๐Ÿ’… so every decoder gets the same bit-exact answer and nobody's prediction drifts apart. the function silk_NLSF2A() (NLSF2A.c) is the one that does the work โœจ

first up, it approximates cos(pi*n[k]) with a table lookup and linear interpolation. when the encoder derives the normalized LSF coefficients, it SHOULD use the inverse of this piecewise linear approximation, not the true inverse of the cosine function ๐Ÿซถ the values also get re-ordered so the LPC polynomials come out numerically more accurate. the ordering depends on the audio bandwidth:

                     +-------------+-----------+----+
                     | Coefficient | NB and MB | WB |
                     +-------------+-----------+----+
                     | 0           |         0 |  0 |
                     |             |           |    |
                     | 1           |         9 | 15 |
                     |             |           |    |
                     | 2           |         6 |  8 |
                     |             |           |    |
                     | 3           |         3 |  7 |
                     |             |           |    |
                     | 4           |         4 |  4 |
                     |             |           |    |
                     | 5           |         5 | 11 |
                     |             |           |    |
                     | 6           |         8 | 12 |
                     |             |           |    |
                     | 7           |         1 |  3 |
                     |             |           |    |
                     | 8           |         2 |  2 |
                     |             |           |    |
                     | 9           |         7 | 13 |
                     |             |           |    |
                     | 10          |           | 10 |
                     |             |           |    |
                     | 11          |           |  5 |
                     |             |           |    |
                     | 12          |           |  6 |
                     |             |           |    |
                     | 13          |           |  9 |
                     |             |           |    |
                     | 14          |           | 14 |
                     |             |           |    |
                     | 15          |           |  1 |
                     +-------------+-----------+----+

             Table 27: LSF Ordering for Polynomial Evaluation

here's the vibe for the lookup ๐ŸŽ€ the top 7 bits of each normalized LSF coefficient pick a spot in the table, and the next 8 bits interpolate between that spot and the next one. so with i = (n[k] >> 8) as the integer index and f = (n[k] & 255) as the fractional part, the re-ordered, approximated cosine c_Q17[ordering[k]] comes out as:

       c_Q17[ordering[k]] = (cos_Q12[i]*256
                             + (cos_Q12[i+1]-cos_Q12[i])*f + 4) >> 3

in there, ordering[k] is the k'th entry of the Table 27 column for the current audio bandwidth, and cos_Q12[i] is the i'th entry of Table 28 ๐Ÿ“

                  +-----+-------+-------+-------+-------+
                  |   i |    +0 |    +1 |    +2 |    +3 |
                  +-----+-------+-------+-------+-------+
                  |   0 |  4096 |  4095 |  4091 |  4085 |
                  |     |       |       |       |       |
                  |   4 |  4076 |  4065 |  4052 |  4036 |
                  |     |       |       |       |       |
                  |   8 |  4017 |  3997 |  3973 |  3948 |
                  |     |       |       |       |       |
                  |  12 |  3920 |  3889 |  3857 |  3822 |
                  |     |       |       |       |       |
                  |  16 |  3784 |  3745 |  3703 |  3659 |
                  |     |       |       |       |       |
                  |  20 |  3613 |  3564 |  3513 |  3461 |
                  |     |       |       |       |       |
                  |  24 |  3406 |  3349 |  3290 |  3229 |
                  |     |       |       |       |       |
                  |  28 |  3166 |  3102 |  3035 |  2967 |
                  |     |       |       |       |       |
                  |  32 |  2896 |  2824 |  2751 |  2676 |
                  |     |       |       |       |       |
                  |  36 |  2599 |  2520 |  2440 |  2359 |
                  |     |       |       |       |       |
                  |  40 |  2276 |  2191 |  2106 |  2019 |
                  |     |       |       |       |       |
                  |  44 |  1931 |  1842 |  1751 |  1660 |
                  |     |       |       |       |       |
                  |  48 |  1568 |  1474 |  1380 |  1285 |
                  |     |       |       |       |       |
                  |  52 |  1189 |  1093 |   995 |   897 |
                  |     |       |       |       |       |
                  |  56 |   799 |   700 |   601 |   501 |
                  |     |       |       |       |       |
                  |  60 |   401 |   301 |   201 |   101 |
                  |     |       |       |       |       |
                  |  64 |     0 |  -101 |  -201 |  -301 |
                  |     |       |       |       |       |
                  |  68 |  -401 |  -501 |  -601 |  -700 |
                  |     |       |       |       |       |
                  |  72 |  -799 |  -897 |  -995 | -1093 |
                  |     |       |       |       |       |
                  |  76 | -1189 | -1285 | -1380 | -1474 |
                  |     |       |       |       |       |
                  |  80 | -1568 | -1660 | -1751 | -1842 |
                  |     |       |       |       |       |
                  |  84 | -1931 | -2019 | -2106 | -2191 |
                  |     |       |       |       |       |
                  |  88 | -2276 | -2359 | -2440 | -2520 |
                  |     |       |       |       |       |
                  |  92 | -2599 | -2676 | -2751 | -2824 |
                  |     |       |       |       |       |
                  |  96 | -2896 | -2967 | -3035 | -3102 |
                  |     |       |       |       |       |
                  | 100 | -3166 | -3229 | -3290 | -3349 |
                  |     |       |       |       |       |
                  | 104 | -3406 | -3461 | -3513 | -3564 |
                  |     |       |       |       |       |
                  | 108 | -3613 | -3659 | -3703 | -3745 |
                  |     |       |       |       |       |
                  | 112 | -3784 | -3822 | -3857 | -3889 |
                  |     |       |       |       |       |
                  | 116 | -3920 | -3948 | -3973 | -3997 |
                  |     |       |       |       |       |
                  | 120 | -4017 | -4036 | -4052 | -4065 |
                  |     |       |       |       |       |
                  | 124 | -4076 | -4085 | -4091 | -4095 |
                  |     |       |       |       |       |
                  | 128 | -4096 |       |       |       |
                  +-----+-------+-------+-------+-------+

               Table 28: Q12 Cosine Table for LSF Conversion

now silk_NLSF2A_find_poly() (NLSF2A.c) takes those cosine values and works out the coefficients of P and Q with a simple recurrence โœจ let p_Q16[k][j] and q_Q16[k][j] be the coefficients of the products of the first (k+1) root pairs for P and Q, where j is the coefficient number. you only need the first (k+2) coefficients, since the products are symmetric. start with p_Q16[0][0] = q_Q16[0][0] = 1<<16, p_Q16[0][1] = -c_Q17[0], q_Q16[0][1] = -c_Q17[1], and d2 = d_LPC/2. the boundary conditions are that p_Q16[k][j] = q_Q16[k][j] = 0 for all j < 0, and that p_Q16[k][k+2] = p_Q16[k][k] and q_Q16[k][k+2] = q_Q16[k][k] (thanks to the symmetry). then, for 0 < k < d2 and 0 <= j <= k+1:

        p_Q16[k][j] = p_Q16[k-1][j] + p_Q16[k-1][j-2]
                      - ((c_Q17[2*k]*p_Q16[k-1][j-1] + 32768)>>16)

        q_Q16[k][j] = q_Q16[k-1][j] + q_Q16[k-1][j-2]
                      - ((c_Q17[2*k+1]*q_Q16[k-1][j-1] + 32768)>>16)

heads up, the Q17 cosine terms in this otherwise Q16 expression implicitly scale them by a factor of 2 ๐Ÿ”ฅ and the multiplications can need up to 48 bits of precision in the result to avoid overflow. the good news is that each row only depends on the previous row, so an implementation doesn't have to store all of them ๐Ÿ’œ

silk_NLSF2A() then uses the values from the last row of this recurrence to rebuild a 32-bit version of the LPC filter (without the leading 1.0 coefficient), a32_Q17[k], for 0 <= k < d2:

        a32_Q17[k]         = -(q_Q16[d2-1][k+1] - q_Q16[d2-1][k])
                             - (p_Q16[d2-1][k+1] + p_Q16[d2-1][k]))

        a32_Q17[d_LPC-k-1] =  (q_Q16[d2-1][k+1] - q_Q16[d2-1][k])
                             - (p_Q16[d2-1][k+1] + p_Q16[d2-1][k]))

the sums and differences of those two terms from the p_Q16 and q_Q16 lists are where the (1 + z**-1) and (1 - z**-1) factors of P and Q show up ๐ŸŒธ and promoting the result from Q16 to Q17 implicitly scales it by 1/2.

4.2.7.5.7. Limiting the Range of the LPC Coefficients โœจ

okay so the a32_Q17[] coefficients are way too big to fit in a 16-bit value ๐Ÿ˜ญ which makes this filter really expensive to run in fixed-point decoders. Dropping them to Q12 precision doesn't cost much quality, but it still doesn't guarantee they'll fit ๐Ÿ’… So silk_NLSF2A() runs up to 10 rounds of bandwidth expansion to shrink the dynamic range of these coefficients. Even floating-point decoders SHOULD do these steps, to avoid mismatch ๐Ÿซถ

For each round, the process first hunts down the index k where abs(a32_Q17[k]) is largest. If there's a tie, it picks the lowest k ๐Ÿ‘‘ Then it works out the matching Q12 value, maxabs_Q12, with an upper bound so the later math doesn't overflow ๐Ÿ”ฅ

maxabs_Q12 = min((maxabs_Q17 + 16) >> 5, 163838)

If this is larger than 32767, the procedure derives the chirp factor, sc_Q16[0], for the bandwidth expansion:

                                 (maxabs_Q12 - 32767) << 14
             sc_Q16[0] = 65470 - --------------------------
                                 (maxabs_Q12 * (k+1)) >> 2

where the division here is integer division. This is an approximation of the chirp factor needed to pull the target coefficient down to 32767 ๐Ÿฆ‹ It's both less than 0.999 and, for k > 0 when maxabs_Q12 is much greater than 32767, still slightly too large. The upper bound on maxabs_Q12, 163838, was picked because it equals ((2**31 - 1) >> 14) + 32767. In other words, it's the biggest maxabs_Q12 that won't overflow the numerator above when stored in a signed 32-bit integer ๐Ÿงš

silk_bwexpander_32() (bwexpander_32.c) does the bandwidth expansion (again, only when maxabs_Q12 is greater than 32767) with this recurrence:

a32_Q17[k] = (a32_Q17[k]*sc_Q16[k]) >> 16

sc_Q16[k+1] = (sc_Q16[0]*sc_Q16[k] + 32768) >> 16

The first multiply may need up to 48 bits of precision in the result to avoid overflow. The second multiply must be unsigned to avoid overflow with only 32 bits of precision. The reference implementation uses a slightly more complex formulation that avoids the 32-bit overflow using signed multiplication, but is otherwise equivalent ๐ŸŒธ

After 10 rounds of bandwidth expansion, the coefficients are simply saturated to 16 bits:

a32_Q17[k] = clamp(-32768, (a32_Q17[k] + 16) >> 5, 32767) << 5
This is the bit that needs to happen in this exact order ๐Ÿ‘€ The saturation happens in the Q12 domain, but the coefficients get converted back to Q17 for the prediction gain limiting, so this step has to run after the 10th round of bandwidth expansion. That's true whether or not the Q12 version of any coefficient still overflows a 16-bit integer. The only exception is if maxabs_Q12 drops to 32767 or less before the 10th round, because then this saturation is skipped.

4.2.7.5.8. Limiting the Prediction Gain of the LPC Filter โœจ

the prediction gain of an LPC synthesis filter is the square root of the output energy when the filter gets excited by a unit-energy impulse ๐ŸŽ€ Even if the Q12 coefficients would fit, the filter can still have a big gain (especially for voiced sounds), and that can make it unstable ๐Ÿ’€ So silk_NLSF2A() runs up to 16 more rounds of bandwidth expansion to limit the prediction gain.

Here's the vibe: instead of controlling the bandwidth expansion using the prediction gain itself (which can blow up to infinity for an unstable filter ๐Ÿ˜ญ), silk_NLSF2A() uses silk_LPC_inverse_pred_gain_QA() (LPC_inv_pred_gain.c) to compute the reflection coefficients for the filter. The filter is stable if and only if the magnitude of these coefficients is sufficiently less than one ๐Ÿฆ‹ The reflection coefficients, rc[k], can be computed with a simple Levinson recurrence. You start it with the LPC coefficients a[d_LPC-1][n] = a[n], then update it with

rc[k] = -a[k][k] ,

        a[k][n] - a[k][k-n-1]*rc[k]
a[k-1][n] = ---------------------------
                             2
                    1 - rc[k]

silk_LPC_inverse_pred_gain_QA() estimates this with fixed-point arithmetic so every platform and implementation gets reproducible results ๐Ÿงš Small changes in the coefficients can make a stable filter unstable, so it takes the real Q12 coefficients that will be used during reconstruction as its input. So let

a32_Q12[n] = (a32_Q17[n] + 16) >> 5

be the Q12 version of the LPC coefficients that will eventually be used. As a quick first check, the decoder computes the DC response as

                                d_PLC-1
                                  __
                        DC_resp = \   a32_Q12[n]
                                  /_
                                  n=0

and if DC_resp > 4096, the filter is unstable ๐Ÿ™ˆ

Bumping these Q12 coefficients up to Q24 for the intermediate computations gives a more accurate reflection coefficient calculation, so the decoder starts the recurrence with

inv_gain_Q30[d_LPC] = 1 << 30

a32_Q24[d_LPC-1][n] = a32_Q12[n] << 12

Then, for each k from d_LPC-1 down to 0, if abs(a32_Q24[k][k]) > 16773022, the filter is unstable and the recurrence stops. The constant 16773022 is approximately 0.99975 in Q24 โœจ Otherwise, the inverse of the prediction gain, inv_gain_Q30[k], gets updated with

rc_Q31[k] = -a32_Q24[k][k] << 7

div_Q30[k] = (1<<30) - (rc_Q31[k]*rc_Q31[k] >> 32)

inv_gain_Q30[k] = (inv_gain_Q30[k+1]*div_Q30[k] >> 32) << 2

and if inv_gain_Q30[k] < 107374, the filter is unstable and the recurrence stops. The constant 107374 is approximately 1/10000 in Q30 ๐ŸŒˆ If neither of these checks says the filter is unstable and k > 0, row k-1 of a32_Q24 gets computed from row k with

b1[k] = ilog(div_Q30[k])

b2[k] = b1[k] - 16

              (1<<29) - 1
inv_Qb2[k] = -----------------------
             div_Q30[k] >> (b2[k]+1)

err_Q29[k] = (1<<29)
             - ((div_Q30[k]<<(15-b2[k]))*inv_Qb2[k] >> 16)

gain_Qb1[k] = ((inv_Qb2[k] << 16)
               + (err_Q29[k]*inv_Qb2[k] >> 13))

num_Q24[k-1][n] = a32_Q24[k][n]
                  - ((a32_Q24[k][k-n-1]*rc_Q31[k] + (1<<30)) >> 31)

a32_Q24[k-1][n] = (num_Q24[k-1][n]*gain_Qb1[k]
                   + (1<<(b1[k]-1))) >> b1[k]

where 0 <= n < k. Here rc_Q31[k] are the reflection coefficients, and div_Q30[k] is the denominator for each iteration. gain_Qb1[k] is its multiplicative inverse (with b1[k] fractional bits, where b1[k] ranges from 20 to 31). inv_Qb2[k], which ranges from 16384 to 32767, is a low-precision version of that inverse (with b2[k] fractional bits). err_Q29[k] is the residual error, ranging from -32763 to 32392, and it's used to improve the accuracy ๐Ÿ”ฅ The values t_Q24[k-1][n] for each n are the numerators for the next row of coefficients in the recursion, and a32_Q24[k-1][n] is the final version of that row. Every multiply in this procedure except the one used to compute gain_Qb1[k] needs more than 32 bits of precision, but otherwise all intermediate results fit in 32 bits or less. In practice, each row only depends on the next one, so an implementation doesn't need to store them all ๐Ÿ’…

If abs(a32_Q24[k][k]) <= 16773022 and inv_gain_Q30[k] >= 107374 for 0 <= k < d_LPC, then the filter is considered stable. However, determining stability is ill-conditioned when the filter has several reflection coefficients whose magnitude is very close to one. This fixed-point algorithm isn't mathematically guaranteed to classify filters correctly as stable or unstable in that case, though it does very well in practice ๐Ÿ™ˆ

On round i, 0 <= i < 16, if the filter passes these stability checks, the procedure stops, and the final LPC coefficients used for reconstruction in Section 4.2.7.9.2 are

a_Q12[k] = (a32_Q17[k] + 16) >> 5

Otherwise, a round of bandwidth expansion is applied using the same procedure as in Section 4.2.7.5.7, with

sc_Q16[0] = 65536 - (2<<i)

During round 15, sc_Q16[0] becomes 0 in the above equation, so a_Q12[k] is set to 0 for all k, which guarantees a stable filter ๐ŸŽ€


4.2.7.6. Long-Term Prediction (LTP) Parameters โœจ

after the normalized LSF indices and, for 20 ms frames, the LSF interpolation index, voiced frames (see Section 4.2.7.3) include additional LTP parameters ๐Ÿฆ‹ There's one primary lag index for each SILK frame, but it gets refined into a separate lag index per subframe using a vector quantizer. Each subframe also gets its own prediction gain coefficient ๐Ÿ’–

4.2.7.6.1. Pitch Lags โœจ

the primary lag index is coded either relative to the primary lag of the prior frame in the same channel, or as an absolute index. Absolute coding is used if and only if:

  • This is the first SILK frame of its type (LBRR or regular) for this channel in the current Opus frame,
  • The previous SILK frame of the same type (LBRR or regular) for this channel in the same Opus frame was not coded, or
  • That previous SILK frame was coded, but was not voiced (see Section 4.2.7.3).

With absolute coding, the primary pitch lag can range from 2 ms (inclusive) up to 18 ms (exclusive), which corresponds to pitches from 500 Hz down to 55.6 Hz, respectively ๐Ÿงš It's made of a high part and a low part. The decoder reads the high part first, using the 32-entry codebook in Table 29, and then reads the low part using the codebook for the current audio bandwidth from Table 30. The final primary pitch lag is then

lag = lag_high*lag_scale + lag_low + lag_min

where lag_high is the high part, lag_low is the low part, and lag_scale and lag_min are the values from the "Scale" and "Minimum Lag" columns of Table 30, respectively ๐ŸŒธ

+-------------------------------------------------------------------+
| PDF                                                               |
+-------------------------------------------------------------------+
| {3, 3, 6, 11, 21, 30, 32, 19, 11, 10, 12, 13, 13, 12, 11, 9, 8,   |
| 7, 6, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1}/256                  |
+-------------------------------------------------------------------+

             Table 29: PDF for High Part of Primary Pitch Lag
+------------+------------------------+-------+----------+----------+
| Audio      | PDF                    | Scale | Minimum  | Maximum  |
| Bandwidth  |                        |       | Lag      | Lag      |
+------------+------------------------+-------+----------+----------+
| NB         | {64, 64, 64, 64}/256   | 4     | 16       | 144      |
|            |                        |       |          |          |
| MB         | {43, 42, 43, 43, 42,   | 6     | 24       | 216      |
|            | 43}/256                |       |          |          |
|            |                        |       |          |          |
| WB         | {32, 32, 32, 32, 32,   | 8     | 32       | 288      |
|            | 32, 32, 32}/256        |       |          |          |
+------------+------------------------+-------+----------+----------+

              Table 30: PDF for Low Part of Primary Pitch Lag

Okay so, every frame that doesn't use absolute coding for the primary lag index switches to relative coding instead ๐Ÿ’… The decoder reads one delta value using the 21-entry PDF in Table 31 ๐ŸŽ€

+-------------------------------------------------------------------+
| PDF                                                               |
+-------------------------------------------------------------------+
| {46, 2, 2, 3, 4, 6, 10, 15, 26, 38, 30, 22, 15, 10, 7, 6, 4, 4,   |
| 2, 2, 2}/256                                                      |
+-------------------------------------------------------------------+

Table 31: PDF for Primary Pitch Lag Change

If that decoded value is zero, the decoder falls back to the absolute coding procedure from the paragraph before this one ๐Ÿ™ˆ If it's not zero, the final primary pitch lag gets computed like this:

lag = previous_lag + (delta_lag_index - 9)

Here previous_lag is the primary pitch lag from the most recent frame in the same channel, and delta_lag_index is the value that was just decoded ๐Ÿฆ‹ This lets the pitch lag shift by anywhere from -8 to +11 samples per frame, which is giving main character energy โœจ The decoder does no clamping at this stage, so the value can end up outside the 2 ms to 18 ms range, and the decoder must use this unclamped value when relative coding is used in the next SILK frame (if there is one) ๐Ÿซถ Don't panic though, because an Opus frame can use relative coding for at most two consecutive SILK frames, so integer overflow should not be an issue ๐Ÿ’–

After the primary pitch lag, there's a "pitch contour" ๐ŸŒˆ It's stored as a single entry from one of four small VQ codebooks, and it gives lag offsets for each subframe in the current SILK frame. The codebook index is decoded using one of the PDFs in Table 32, depending on the current frame size and audio bandwidth. Tables 33 through 36 list the offsets to apply to the primary pitch lag for each subframe, based on the decoded codebook index ๐Ÿงš

+-----------+--------+----------+-----------------------------------+
| Audio     | SILK   | Codebook | PDF                               |
| Bandwidth | Frame  |     Size |                                   |
|           | Size   |          |                                   |
+-----------+--------+----------+-----------------------------------+
| NB        | 10 ms  |        3 | {143, 50, 63}/256                 |
|           |        |          |                                   |
| NB        | 20 ms  |       11 | {68, 12, 21, 17, 19, 22, 30, 24,  |
|           |        |          | 17, 16, 10}/256                   |
|           |        |          |                                   |
| MB or WB  | 10 ms  |       12 | {91, 46, 39, 19, 14, 12, 8, 7, 6, |
|           |        |          | 5, 5, 4}/256                      |
|           |        |          |                                   |
| MB or WB  | 20 ms  |       34 | {33, 22, 18, 16, 15, 14, 14, 13,  |
|           |        |          | 13, 10, 9, 9, 8, 6, 6, 6, 5, 4,   |
|           |        |          | 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2,  |
|           |        |          | 2, 1, 1, 1, 1}/256                |
+-----------+--------+----------+-----------------------------------+

Table 32: PDFs for Subframe Pitch Contour

                      +-------+------------------+
                      | Index | Subframe Offsets |
                      +-------+------------------+
                      | 0     |             0  0 |
                      |       |                  |
                      | 1     |             1  0 |
                      |       |                  |
                      | 2     |             0  1 |
                      +-------+------------------+

Table 33: Codebook Vectors for Subframe Pitch Contour: NB, 10 ms Frames

                      +-------+------------------+
                      | Index | Subframe Offsets |
                      +-------+------------------+
                      | 0     |       0  0  0  0 |
                      |       |                  |
                      | 1     |       2  1  0 -1 |
                      |       |                  |
                      | 2     |      -1  0  1  2 |
                      |       |                  |
                      | 3     |      -1  0  0  1 |
                      |       |                  |
                      | 4     |      -1  0  0  0 |
                      |       |                  |
                      | 5     |       0  0  0  1 |
                      |       |                  |
                      | 6     |       0  0  1  1 |
                      |       |                  |
                      | 7     |       1  1  0  0 |
                      |       |                  |
                      | 8     |       1  0  0  0 |
                      |       |                  |
                      | 9     |       0  0  0 -1 |
                      |       |                  |
                      | 10    |       1  0  0 -1 |
                      +-------+------------------+

Table 34: Codebook Vectors for Subframe Pitch Contour: NB, 20 ms Frames

                      +-------+------------------+
                      | Index | Subframe Offsets |
                      +-------+------------------+
                      | 0     |             0  0 |
                      |       |                  |
                      | 1     |             0  1 |
                      |       |                  |
                      | 2     |             1  0 |
                      |       |                  |
                      | 3     |            -1  1 |
                      |       |                  |
                      | 4     |             1 -1 |
                      |       |                  |
                      | 5     |            -1  2 |
                      |       |                  |
                      | 6     |             2 -1 |
                      |       |                  |
                      | 7     |            -2  2 |
                      |       |                  |
                      | 8     |             2 -2 |
                      |       |                  |
                      | 9     |            -2  3 |
                      |       |                  |
                      | 10    |             3 -2 |
                      |       |                  |
                      | 11    |            -3  3 |
                      +-------+------------------+

Table 35: Codebook Vectors for Subframe Pitch Contour: MB or WB, 10 ms Frames

                      +-------+------------------+
                      | Index | Subframe Offsets |
                      +-------+------------------+
                      | 0     |       0  0  0  0 |
                      |       |                  |
                      | 1     |       0  0  1  1 |
                      |       |                  |
                      | 2     |       1  1  0  0 |
                      |       |                  |
                      | 3     |      -1  0  0  0 |
                      |       |                  |
                      | 4     |       0  0  0  1 |
                      |       |                  |
                      | 5     |       1  0  0  0 |
                      |       |                  |
                      | 6     |      -1  0  0  1 |
                      |       |                  |
                      | 7     |       0  0  0 -1 |
                      |       |                  |
                      | 8     |      -1  0  1  2 |
                      |       |                  |
                      | 9     |       1  0  0 -1 |
                      |       |                  |
                      | 10    |      -2 -1  1  2 |
                      |       |                  |
                      | 11    |       2  1  0 -1 |
                      |       |                  |
                      | 12    |      -2  0  0  2 |
                      |       |                  |
                      | 13    |      -2  0  1  3 |
                      |       |                  |
                      | 14    |       2  1 -1 -2 |
                      |       |                  |
                      | 15    |      -3 -1  1  3 |
                      |       |                  |
                      | 16    |       2  0  0 -2 |
                      |       |                  |
                      | 17    |       3  1  0 -2 |
                      |       |                  |
                      | 18    |      -3 -1  2  4 |
                      |       |                  |
                      | 19    |      -4 -1  1  4 |
                      |       |                  |
                      | 20    |       3  1 -1 -3 |
                      |       |                  |
                      | 21    |      -4 -1  2  5 |
                      |       |                  |
                      | 22    |       4  2 -1 -3 |
                      |       |                  |
                      | 23    |       4  1 -1 -4 |
                      |       |                  |
                      | 24    |      -5 -1  2  6 |
                      |       |                  |
                      | 25    |       5  2 -1 -4 |
                      |       |                  |
                      | 26    |      -6 -2  2  6 |
                      |       |                  |
                      | 27    |      -5 -2  2  5 |
                      |       |                  |
                      | 28    |       6  2 -1 -5 |
                      |       |                  |
                      | 29    |      -7 -2  3  8 |
                      |       |                  |
                      | 30    |       6  2 -2 -6 |
                      |       |                  |
                      | 31    |       5  2 -2 -5 |
                      |       |                  |
                      | 32    |       8  3 -2 -7 |
                      |       |                  |
                      | 33    |      -9 -3  3  9 |
                      +-------+------------------+

Table 36: Codebook Vectors for Subframe Pitch Contour: MB or WB, 20 ms Frames

The final pitch lag for each subframe gets assembled in silk_decode_pitch() (decode_pitch.c) โœจ Let lag be the primary pitch lag for the current SILK frame, contour_index be the index of the VQ codebook, and lag_cb[contour_index][k] be the matching entry from the right table above for the k'th subframe. Then the final pitch lag for that subframe is:

    pitch_lags[k] = clamp(lag_min, lag + lag_cb[contour_index][k],
                          lag_max)

where lag_min and lag_max are the values from the "Minimum Lag" and "Maximum Lag" columns of Table 30, respectively ๐Ÿ“ Bestie, that's the whole pitch lag pipeline, and it's so clean ๐Ÿ˜ญ๐Ÿ”ฅ

4.2.7.6.2. LTP Filter Coefficients โœจ

okay so SILK gives every subframe its own 5-tap pitch filter ๐ŸŽ€, and each one gets picked from one of three codebooks ๐Ÿ’…. These codebooks are basically three different rate-distortion vibes: they average 1.61 bits/subframe, 3.68 bits/subframe, and 4.85 bits/subframe ๐Ÿฆ‹.

ngl the importance of the filter coefficients depends on two things. First, how periodic the signal is ๐ŸŒˆ. Second, the relative energy between the current subframe and the signal from one period earlier ๐Ÿ“‰. Greater periodicity and decaying energy both make the coefficients more important, so they should be coded with lower distortion and a higher rate ๐Ÿ‘‘. These properties are pretty stable across a single SILK frame, so all of the subframes in that frame choose their filter from the same codebook ๐Ÿซถ. This choice is signaled with an explicitly-coded "periodicity index" ๐Ÿ’œ. It comes right after the subframe pitch lags and is coded using the 3-entry PDF from Table 37 โœจ.

                         +------------------+
                         | PDF              |
                         +------------------+
                         | {77, 80, 99}/256 |
                         +------------------+

                    Table 37: Periodicity Index PDF

Next up are the indices of the filters for each subframe ๐Ÿ“. They're all coded using the PDF from Table 38 that matches the periodicity index. Tables 39 through 41 hold the actual filter taps, written as signed Q7 integers ๐Ÿงš.

+-------------+----------+------------------------------------------+
| Periodicity | Codebook | PDF                                      |
| Index       |     Size |                                          |
+-------------+----------+------------------------------------------+
| 0           |        8 | {185, 15, 13, 13, 9, 9, 6, 6}/256        |
|             |          |                                          |
| 1           |       16 | {57, 34, 21, 20, 15, 13, 12, 13, 10, 10, |
|             |          | 9, 10, 9, 8, 7, 8}/256                   |
|             |          |                                          |
| 2           |       32 | {15, 16, 14, 12, 12, 12, 11, 11, 11, 10, |
|             |          | 9, 9, 9, 9, 8, 8, 8, 8, 7, 7, 6, 6, 5,   |
|             |          | 4, 5, 4, 4, 4, 3, 4, 3, 2}/256           |
+-------------+----------+------------------------------------------+

                       Table 38: LTP Filter PDFs
                    +-------+---------------------+
                    | Index |    Filter Taps (Q7) |
                    +-------+---------------------+
                    | 0     |   4   6  24   7   5 |
                    |       |                     |
                    | 1     |   0   0   2   0   0 |
                    |       |                     |
                    | 2     |  12  28  41  13  -4 |
                    |       |                     |
                    | 3     |  -9  15  42  25  14 |
                    |       |                     |
                    | 4     |   1  -2  62  41  -9 |
                    |       |                     |
                    | 5     | -10  37  65  -4   3 |
                    |       |                     |
                    | 6     |  -6   4  66   7  -8 |
                    |       |                     |
                    | 7     |  16  14  38  -3  33 |
                    +-------+---------------------+

    Table 39: Codebook Vectors for LTP Filter, Periodicity Index 0
                    +-------+---------------------+
                    | Index |    Filter Taps (Q7) |
                    +-------+---------------------+
                    | 0     |  13  22  39  23  12 |
                    |       |                     |
                    | 1     |  -1  36  64  27  -6 |
                    |       |                     |
                    | 2     |  -7  10  55  43  17 |
                    |       |                     |
                    | 3     |   1   1   8   1   1 |
                    |       |                     |
                    | 4     |   6 -11  74  53  -9 |
                    |       |                     |
                    | 5     | -12  55  76 -12   8 |
                    |       |                     |
                    | 6     |  -3   3  93  27  -4 |
                    |       |                     |
                    | 7     |  26  39  59   3  -8 |
                    |       |                     |
                    | 8     |   2   0  77  11   9 |
                    |       |                     |
                    | 9     |  -8  22  44  -6   7 |
                    |       |                     |
                    | 10    |  40   9  26   3   9 |
                    |       |                     |
                    | 11    |  -7  20 101  -7   4 |
                    |       |                     |
                    | 12    |   3  -8  42  26   0 |
                    |       |                     |
                    | 13    | -15  33  68   2  23 |
                    |       |                     |
                    | 14    |  -2  55  46  -2  15 |
                    |       |                     |
                    | 15    |   3  -1  21  16  41 |
                    +-------+---------------------+

    Table 40: Codebook Vectors for LTP Filter, Periodicity Index 1
                    +-------+---------------------+
                    | Index |    Filter Taps (Q7) |
                    +-------+---------------------+
                    | 0     |  -6  27  61  39   5 |
                    |       |                     |
                    | 1     | -11  42  88   4   1 |
                    |       |                     |
                    | 2     |  -2  60  65   6  -4 |
                    |       |                     |
                    | 3     |  -1  -5  73  56   1 |
                    | 4     |  -9  19  94  29  -9 |
                    |       |                     |
                    | 5     |   0  12  99   6   4 |
                    |       |                     |
                    | 6     |   8 -19 102  46 -13 |
                    |       |                     |
                    | 7     |   3   2  13   3   2 |
                    |       |                     |
                    | 8     |   9 -21  84  72 -18 |
                    |       |                     |
                    | 9     | -11  46 104 -22   8 |
                    |       |                     |
                    | 10    |  18  38  48  23   0 |
                    |       |                     |
                    | 11    | -16  70  83 -21  11 |
                    |       |                     |
                    | 12    |   5 -11 117  22  -8 |
                    |       |                     |
                    | 13    |  -6  23 117 -12   3 |
                    |       |                     |
                    | 14    |   3  -8  95  28   4 |
                    |       |                     |
                    | 15    | -10  15  77  60 -15 |
                    |       |                     |
                    | 16    |  -1   4 124   2  -4 |
                    |       |                     |
                    | 17    |   3  38  84  24 -25 |
                    |       |                     |
                    | 18    |   2  13  42  13  31 |
                    |       |                     |
                    | 19    |  21  -4  56  46  -1 |
                    |       |                     |
                    | 20    |  -1  35  79 -13  19 |
                    |       |                     |
                    | 21    |  -7  65  88  -9 -14 |
                    |       |                     |
                    | 22    |  20   4  81  49 -29 |
                    |       |                     |
                    | 23    |  20   0  75   3 -17 |
                    |       |                     |
                    | 24    |   5  -9  44  92  -8 |
                    |       |                     |
                    | 25    |   1  -3  22  69  31 |
                    |       |                     |
                    | 26    |  -6  95  41 -12   5 |
                    |       |                     |
                    | 27    |  39  67  16  -4   1 |
                    |       |                     |
                    | 28    |   0  -6 120  55 -36 |
                    |       |                     |
                    | 29    | -13  44 122   4 -24 |
                    |       |                     |
                    | 30    |  81   5  11   3   7 |
                    |       |                     |
                    | 31    |   2   0   9  10  88 |
                    +-------+---------------------+

    Table 41: Codebook Vectors for LTP Filter, Periodicity Index 2

4.2.7.6.3. LTP Scaling Parameter ๐ŸŒธ

okay this one's giving "only when it matters" energy ๐Ÿ’…. An LTP scaling parameter shows up after the LTP filter coefficients if and only if all of these are true:

  • This is a voiced frame (see Section 4.2.7.3), and
  • Either
    • This SILK frame corresponds to the first time interval of the current Opus frame for its type (LBRR or regular), or
    • This is an LBRR frame where the LBRR flags (see Section 4.2.4) indicate the previous LBRR frame in the same channel is not coded.

this lets the encoder trade off prediction gain between packets against recovery time after packet loss ๐Ÿ”ฅ. Unlike absolute-coding for pitch lags, regular SILK frames that aren't at the start of an Opus frame (so, the ones that don't line up with the first 20 ms time interval in Opus frames of 40 or 60 ms) skip this field ๐Ÿ™ˆ. That's true even if the prior frame wasn't voiced, or, for the side channel, if it wasn't even coded. After an uncoded frame in the side channel, the LTP buffer (see Section 4.2.7.9.1) gets cleared to zero, so it's in a known state ๐Ÿงš. LBRR frames are different though. They DO include this field when the prior frame wasn't coded, because the LTP buffer holds the output of the PLC, which is non-normative ๐Ÿซถ.

if the scaling parameter is present, the decoder reads a value using the 3-entry PDF in Table 42. Those three values are Q14 scale factors of 15565, 12288, and 8192, respectively, which are roughly 0.95, 0.75, and 0.5 ๐Ÿ’œ. Any frame that doesn't code the scaling parameter just uses the default factor of 15565 (about 0.95) โœจ.
                       +-------------------+
                       | PDF               |
                       +-------------------+
                       | {128, 64, 64}/256 |
                       +-------------------+

              Table 42: PDF for LTP Scaling Parameter

4.2.7.7. Linear Congruential Generator (LCG) Seed

Okay bestie, SILK uses a Linear Congruential Generator (LCG) ๐ŸŽฒ to sprinkle pseudorandom noise onto the quantized excitation, as described in Section 4.2.7.8.6. โœจ For the encoder and decoder to stay in sync, each SILK frame stores a 2-bit seed right after the LTP parameters (if there are any) ๐Ÿซถ. The encoder can factor the seed into its quantization choices, and that flexibility helps it reduce distortion, which kinda helps pay for the bits it takes to signal the seed ๐Ÿ’…. The decoder reads the seed with the uniform 4-entry PDF in Table 43, so you get a value from 0 to 3, inclusive ๐ŸŒธ.

                     +----------------------+
                     | PDF                  |
                     +----------------------+
                     | {64, 64, 64, 64}/256 |
                     +----------------------+

                    Table 43: PDF for LCG Seed

4.2.7.8. Excitation

SILK codes the excitation using a modified version of the Pyramid Vector Quantizer (PVQ) codebook [PVQ]. ๐Ÿ”บ The PVQ codebook is built for Laplace-distributed values, and it's made of all the sums of K signed, unit pulses in a vector of dimension N, where two pulses at the same position have to share the same sign ๐Ÿ‘‘. So the codebook holds every integer codevector y of dimension N that satisfies

                          N-1
                          __
                          \  abs(y[j]) = K
                          /_
                          j=0

Here's the twist: unlike regular PVQ, SILK uses a variable-length encoding instead of a fixed-length one ๐Ÿฆ‹. That fits better because the coefficient magnitudes are more Gaussian-like and the signs are non-uniform (thanks to the quantization offset we'll get to). SILK also handles big codebooks by coding the least significant bits (LSBs) of each coefficient directly ๐Ÿงš. Yes, this adds a tiny bit of coding efficiency loss, but it hugely cuts the computation time and ROM size needed for decoding. You can see it in silk_decode_pulses() (decode_pulses.c) ๐Ÿ’œ.

SILK fixes the codebook dimension at N = 16 โœจ. The excitation is made of a bunch of "shell blocks", each 16 samples long ๐Ÿ“. Table 44 lists how many shell blocks a SILK frame needs for each audio bandwidth and frame size. Quick sidebar: 10 ms MB frames nominally contain 120 samples (10 ms at 12 kHz), which is not a multiple of 16 ๐Ÿ™ˆ. So SILK codes 8 shell blocks (128 samples) and throws away the final 8 samples of the last block. The decoder has no special case stopping an encoder from placing pulses in those samples, so they must be correctly parsed from the bitstream if they're there, but otherwise they get ignored ๐Ÿซ .

      +-----------------+------------+------------------------+
      | Audio Bandwidth | Frame Size | Number of Shell Blocks |
      +-----------------+------------+------------------------+
      | NB              | 10 ms      |                      5 |
      |                 |            |                        |
      | MB              | 10 ms      |                      8 |
      |                 |            |                        |
      | WB              | 10 ms      |                     10 |
      |                 |            |                        |
      | NB              | 20 ms      |                     10 |
      |                 |            |                        |
      | MB              | 20 ms      |                     15 |
      |                 |            |                        |
      | WB              | 20 ms      |                     20 |
      +-----------------+------------+------------------------+

           Table 44: Number of Shell Blocks Per SILK Frame

4.2.7.8.1. Rate Level

The first symbol in the excitation is a "rate level" ๐ŸŒˆ, an index from 0 to 8, inclusive. It's coded with the PDF from Table 45 that matches the signal type of the current frame (from Section 4.2.7.3). The rate level picks the PDF used to decode the number of pulses in each shell block. It doesn't directly tell you anything about the bitrate or the number of pulses. It just shifts the probabilities of the symbols in Section 4.2.7.8.2 ๐ŸŽ€. Level 0 is generally more efficient at low rates, and level 8 is generally more efficient at high rates, though the most efficient level for a given frame can depend on the exact distribution of the coded symbols ๐Ÿง. An encoder should, but is not required to, use the most efficient rate level ๐Ÿ’–.

    +----------------------+------------------------------------------+
    | Signal Type          | PDF                                      |
    +----------------------+------------------------------------------+
    | Inactive or Unvoiced | {15, 51, 12, 46, 45, 13, 33, 27, 14}/256 |
    |                      |                                          |
    | Voiced               | {33, 30, 36, 17, 34, 49, 18, 21, 18}/256 |
    +----------------------+------------------------------------------+

                 Table 45: PDFs for the Rate Level

4.2.7.8.2. Pulses per Shell Block

The total number of pulses in each shell block comes right after the rate level ๐Ÿญ. The pulse counts for all the shell blocks are coded back to back, before the content of any of the blocks. Each block can have anywhere from 0 to 16 pulses, inclusive, coded with the 18-entry PDF in Table 46 that matches the rate level from Section 4.2.7.8.1 ๐Ÿง. The special value 17 means this block has one or more extra LSBs to decode for each coefficient ๐Ÿ™€. If the decoder hits that value, it decodes another value for the actual pulse count of the block, but it uses the PDF for the special rate level 9 instead of the normal one. This keeps going until the decoder reads a value less than 17, and then it sets the number of extra LSBs to however many 17's it decoded for that block ๐Ÿ”. If it reads the value 17 ten times, the next iteration uses the special rate level 10 instead of 9. The probability of decoding a 17 with the rate level 10 PDF is zero, so the number of LSBs for a block can't go past 10 ๐Ÿ›‘. The cumulative distribution for rate level 10 is just a shifted version of the one for 9, so it doesn't need any extra storage โœจ.

   +----------+--------------------------------------------------------+
   | Rate     | PDF                                                    |
   | Level    |                                                        |
   +----------+--------------------------------------------------------+
   | 0        | {131, 74, 25, 8, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,   |
   |          | 1, 1}/256                                              |
   |          |                                                        |
   | 1        | {58, 93, 60, 23, 7, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,   |
   |          | 1, 1}/256                                              |
   |          |                                                        |
   | 2        | {43, 51, 46, 33, 24, 16, 11, 8, 6, 3, 3, 3, 2, 1, 1,   |
   |          | 2, 1, 2}/256                                           |
   |          |                                                        |
   | 3        | {17, 52, 71, 57, 31, 12, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
   |          | 1, 1}/256                                              |
   |          |                                                        |
   | 4        | {6, 21, 41, 53, 49, 35, 21, 11, 6, 3, 2, 2, 1, 1, 1,   |
   |          | 1, 1, 1}/256                                           |
   |          |                                                        |
   | 5        | {7, 14, 22, 28, 29, 28, 25, 20, 17, 13, 11, 9, 7, 5,   |
   |          | 4, 4, 3, 10}/256                                       |
   |          |                                                        |
   | 6        | {2, 5, 14, 29, 42, 46, 41, 31, 19, 11, 6, 3, 2, 1, 1,  |
   |          | 1, 1, 1}/256                                           |
   |          |                                                        |
   | 7        | {1, 2, 4, 10, 19, 29, 35, 37, 34, 28, 20, 14, 8, 5, 4, |
   |          | 2, 2, 2}/256                                           |
   |          |                                                        |
   | 8        | {1, 2, 2, 5, 9, 14, 20, 24, 27, 28, 26, 23, 20, 15,    |
   |          | 11, 8, 6, 15}/256                                      |
   |          |                                                        |
   | 9        | {1, 1, 1, 6, 27, 58, 56, 39, 25, 14, 10, 6, 3, 3, 2,   |
   |          | 1, 1, 2}/256                                           |
   |          |                                                        |
   | 10       | {2, 1, 6, 27, 58, 56, 39, 25, 14, 10, 6, 3, 3, 2, 1,   |
   |          | 1, 2, 0}/256                                           |
   +----------+--------------------------------------------------------+

                 Table 46: PDFs for the Pulse Count

4.2.7.8.3. Pulse Location Decoding

Next up are the locations of the pulses in each shell block, which follow the pulse counts as decoded by silk_shell_decoder() (shell_coder.c) ๐Ÿ“. Just like the pulse counts, the locations are coded for all the shell blocks before any of the remaining info for each block. Here's the vibe: unlike a lot of other codecs, SILK puts no restriction on how pulses can be spread across a shell block ๐Ÿ˜ค. All of them can go in one spot, each one can get its own unique spot, or anything in between. Iconic flexibility ๐Ÿ‘‘.

The locations get coded by recursively splitting each block into halves and coding how many pulses land on the left side of the split ๐Ÿช“. All the remaining pulses have to land on the right side of the split. Then the process recurses into the left half, and after that returns, it does the right half (that's a preorder traversal ๐Ÿง ). The PDF gets picked based on the size of the current partition (16, 8, 4, or 2) and the number of pulses in that partition (1 to 16, inclusive) ๐Ÿ’…. Tables 47 through 50 list the PDFs used for each partition size and pulse count. The process skips partitions that don't have any pulses, meaning the ones where the initial pulse count from Section 4.2.7.8.2 was zero, or where the split at the level above put all the pulses on the other side ๐Ÿ™ƒ. Those partitions have nothing to code, so they don't need a PDF at all ๐Ÿ’€.

Okay bestie, here come the PDF tables for the pulse count split ๐Ÿ’…โœจ Four partition sizes, each one a little different, and we're keeping every number exactly where it lives ๐Ÿซถ

+------------+------------------------------------------------------+
| Pulse      | PDF                                                  |
| Count      |                                                      |
+------------+------------------------------------------------------+
| 1          | {126, 130}/256                                       |
|            |                                                      |
| 2          | {56, 142, 58}/256                                    |
|            |                                                      |
| 3          | {25, 101, 104, 26}/256                               |
|            |                                                      |
| 4          | {12, 60, 108, 64, 12}/256                            |
|            |                                                      |
| 5          | {7, 35, 84, 87, 37, 6}/256                           |
|            |                                                      |
| 6          | {4, 20, 59, 86, 63, 21, 3}/256                       |
|            |                                                      |
| 7          | {3, 12, 38, 72, 75, 42, 12, 2}/256                   |
|            |                                                      |
| 8          | {2, 8, 25, 54, 73, 59, 27, 7, 1}/256                 |
|            |                                                      |
| 9          | {2, 5, 17, 39, 63, 65, 42, 18, 4, 1}/256             |
|            |                                                      |
| 10         | {1, 4, 12, 28, 49, 63, 54, 30, 11, 3, 1}/256         |
|            |                                                      |
| 11         | {1, 4, 8, 20, 37, 55, 57, 41, 22, 8, 2, 1}/256       |
|            |                                                      |
| 12         | {1, 3, 7, 15, 28, 44, 53, 48, 33, 16, 6, 1, 1}/256   |
|            |                                                      |
| 13         | {1, 2, 6, 12, 21, 35, 47, 48, 40, 25, 12, 5, 1,      |
|            | 1}/256                                               |
|            |                                                      |
| 14         | {1, 1, 4, 10, 17, 27, 37, 47, 43, 33, 21, 9, 4, 1,   |
|            | 1}/256                                               |
|            |                                                      |
| 15         | {1, 1, 1, 8, 14, 22, 33, 40, 43, 38, 28, 16, 8, 1,   |
|            | 1, 1}/256                                            |
|            |                                                      |
| 16         | {1, 1, 1, 1, 13, 18, 27, 36, 41, 41, 34, 24, 14, 1,  |
|            | 1, 1, 1}/256                                         |
+------------+------------------------------------------------------+

Table 47: PDFs for Pulse Count Split, 16 Sample Partitions ๐ŸŽ€

+------------+------------------------------------------------------+
| Pulse      | PDF                                                  |
| Count      |                                                      |
+------------+------------------------------------------------------+
| 1          | {127, 129}/256                                       |
|            |                                                      |
| 2          | {53, 149, 54}/256                                    |
|            |                                                      |
| 3          | {22, 105, 106, 23}/256                               |
|            |                                                      |
| 4          | {11, 61, 111, 63, 10}/256                            |
|            |                                                      |
| 5          | {6, 35, 86, 88, 36, 5}/256                           |
|            |                                                      |
| 6          | {4, 20, 59, 87, 62, 21, 3}/256                       |
|            |                                                      |
| 7          | {3, 13, 40, 71, 73, 41, 13, 2}/256                   |
|            |                                                      |
| 8          | {3, 9, 27, 53, 70, 56, 28, 9, 1}/256                 |
|            |                                                      |
| 9          | {3, 8, 19, 37, 57, 61, 44, 20, 6, 1}/256             |
|            |                                                      |
| 10         | {3, 7, 15, 28, 44, 54, 49, 33, 17, 5, 1}/256         |
|            |                                                      |
| 11         | {1, 7, 13, 22, 34, 46, 48, 38, 28, 14, 4, 1}/256     |
|            |                                                      |
| 12         | {1, 1, 11, 22, 27, 35, 42, 47, 33, 25, 10, 1, 1}/256 |
|            |                                                      |
| 13         | {1, 1, 6, 14, 26, 37, 43, 43, 37, 26, 14, 6, 1,      |
|            | 1}/256                                               |
|            |                                                      |
| 14         | {1, 1, 4, 10, 20, 31, 40, 42, 40, 31, 20, 10, 4, 1,  |
|            | 1}/256                                               |
|            |                                                      |
| 15         | {1, 1, 3, 8, 16, 26, 35, 38, 38, 35, 26, 16, 8, 3,   |
|            | 1, 1}/256                                            |
|            |                                                      |
| 16         | {1, 1, 2, 6, 12, 21, 30, 36, 38, 36, 30, 21, 12, 6,  |
|            | 2, 1, 1}/256                                         |
+------------+------------------------------------------------------+

Table 48: PDFs for Pulse Count Split, 8 Sample Partitions ๐ŸŒธ

+------------+------------------------------------------------------+
| Pulse      | PDF                                                  |
| Count      |                                                      |
+------------+------------------------------------------------------+
| 1          | {127, 129}/256                                       |
|            |                                                      |
| 2          | {49, 157, 50}/256                                    |
|            |                                                      |
| 3          | {20, 107, 109, 20}/256                               |
|            |                                                      |
| 4          | {11, 60, 113, 62, 10}/256                            |
|            |                                                      |
| 5          | {7, 36, 84, 87, 36, 6}/256                           |
|            |                                                      |
| 6          | {6, 24, 57, 82, 60, 23, 4}/256                       |
|            |                                                      |
| 7          | {5, 18, 39, 64, 68, 42, 16, 4}/256                   |
|            |                                                      |
| 8          | {6, 14, 29, 47, 61, 52, 30, 14, 3}/256               |
|            |                                                      |
| 9          | {1, 15, 23, 35, 51, 50, 40, 30, 10, 1}/256           |
|            |                                                      |
| 10         | {1, 1, 21, 32, 42, 52, 46, 41, 18, 1, 1}/256         |
|            |                                                      |
| 11         | {1, 6, 16, 27, 36, 42, 42, 36, 27, 16, 6, 1}/256     |
|            |                                                      |
| 12         | {1, 5, 12, 21, 31, 38, 40, 38, 31, 21, 12, 5, 1}/256 |
|            |                                                      |
| 13         | {1, 3, 9, 17, 26, 34, 38, 38, 34, 26, 17, 9, 3,      |
|            | 1}/256                                               |
|            |                                                      |
| 14         | {1, 3, 7, 14, 22, 29, 34, 36, 34, 29, 22, 14, 7, 3,  |
|            | 1}/256                                               |
|            |                                                      |
| 15         | {1, 2, 5, 11, 18, 25, 31, 35, 35, 31, 25, 18, 11, 5, |
|            | 2, 1}/256                                            |
|            |                                                      |
| 16         | {1, 1, 4, 9, 15, 21, 28, 32, 34, 32, 28, 21, 15, 9,  |
|            | 4, 1, 1}/256                                         |
+------------+------------------------------------------------------+

Table 49: PDFs for Pulse Count Split, 4 Sample Partitions ๐Ÿฆ‹

+------------+------------------------------------------------------+
| Pulse      | PDF                                                  |
| Count      |                                                      |
+------------+------------------------------------------------------+
| 1          | {128, 128}/256                                       |
|            |                                                      |
| 2          | {42, 172, 42}/256                                    |
|            |                                                      |
| 3          | {21, 107, 107, 21}/256                               |
|            |                                                      |
| 4          | {12, 60, 112, 61, 11}/256                            |
|            |                                                      |
| 5          | {8, 34, 86, 86, 35, 7}/256                           |
|            |                                                      |
| 6          | {8, 23, 55, 90, 55, 20, 5}/256                       |
|            |                                                      |
| 7          | {5, 15, 38, 72, 72, 36, 15, 3}/256                   |
|            |                                                      |
| 8          | {6, 12, 27, 52, 77, 47, 20, 10, 5}/256               |
|            |                                                      |
| 9          | {6, 19, 28, 35, 40, 40, 35, 28, 19, 6}/256           |
|            |                                                      |
| 10         | {4, 14, 22, 31, 37, 40, 37, 31, 22, 14, 4}/256       |
|            |                                                      |
| 11         | {3, 10, 18, 26, 33, 38, 38, 33, 26, 18, 10, 3}/256   |
|            |                                                      |
| 12         | {2, 8, 13, 21, 29, 36, 38, 36, 29, 21, 13, 8, 2}/256 |
|            |                                                      |
| 13         | {1, 5, 10, 17, 25, 32, 38, 38, 32, 25, 17, 10, 5,    |
|            | 1}/256                                               |
|            |                                                      |
| 14         | {1, 4, 7, 13, 21, 29, 35, 36, 35, 29, 21, 13, 7, 4,  |
|            | 1}/256                                               |
|            |                                                      |
| 15         | {1, 2, 5, 10, 17, 25, 32, 36, 36, 32, 25, 17, 10, 5, |
|            | 2, 1}/256                                            |
|            |                                                      |
| 16         | {1, 2, 4, 7, 13, 21, 28, 34, 36, 34, 28, 21, 13, 7,  |
|            | 4, 2, 1}/256                                         |
+------------+------------------------------------------------------+

Table 50: PDFs for Pulse Count Split, 2 Sample Partitions ๐Ÿ’œ

4.2.7.8.4. LSB Decoding โœจ

okay so once the decoder has read the pulse locations for every block, it goes back and reads the LSBs (if there are any) for each block, one block at a time ๐Ÿ’…. Inside a block it reads all the LSBs for one coefficient, then moves to the next. This happens even for coefficients that got zero pulses ๐Ÿ™ˆ. For 10 ms MB frames, it also reads LSBs for the extra 8 samples in the last block. The LSBs are coded from most significant to least significant, and they all use the PDF in Table 51, so no drama there ๐ŸŽ€

                            +----------------+
                            | PDF            |
                            +----------------+
                            | {136, 120}/256 |
                            +----------------+

                     Table 51: PDF for Excitation LSBs

the number of LSBs for each coefficient in a block is set in Section 4.2.7.8.2 ๐Ÿซถ The magnitude starts out equal to the number of pulses placed at that spot in Section 4.2.7.8.3. Then, every time an LSB gets decoded, the magnitude gets doubled and the LSB value gets added on top. That's how you get the updated magnitude, and it's giving clean bit-shifting energy ๐ŸŒธ

4.2.7.8.5. Sign Decoding

once the pulse locations and LSBs are done, the decoder knows the magnitude of every coefficient in the excitation โœจ Next up is the sign. It decodes a sign for every coefficient with a non-zero magnitude, using one of the PDFs from Table 52. If the decoded value is 0, the magnitude gets negated. Otherwise it stays positive ๐Ÿ’–

the PDF it picks depends on the signal type, the quantization offset type (from Section 4.2.7.3), and the number of pulses in the block (from Section 4.2.7.8.2). Pulses are counted without any LSBs in the mix, so LSBs don't affect this choice ๐Ÿ™ˆ Most PDFs lean toward negative signs because of the quantization offset, but the zero-pulse PDFs are super skewed toward positive signs ๐Ÿ‘‘

this is a fun one: if a block has a whole bunch of positive coefficients, it can be worth coding that block only with LSBs (zero pulses, basically). The encoder might save enough bits on the signs to make up for the less efficient magnitude coding. Galaxy brain move ๐Ÿง โœจ

+-------------+-----------------------+-------------+---------------+
| Signal Type | Quantization Offset   | Pulse Count | PDF           |
|             | Type                  |             |               |
+-------------+-----------------------+-------------+---------------+
| Inactive    | Low                   | 0           | {2, 254}/256  |
|             |                       |             |               |
| Inactive    | Low                   | 1           | {207, 49}/256 |
|             |                       |             |               |
| Inactive    | Low                   | 2           | {189, 67}/256 |
| Inactive    | Low                   | 3           | {179, 77}/256 |
|             |                       |             |               |
| Inactive    | Low                   | 4           | {174, 82}/256 |
|             |                       |             |               |
| Inactive    | Low                   | 5           | {163, 93}/256 |
|             |                       |             |               |
| Inactive    | Low                   | 6 or more   | {157, 99}/256 |
|             |                       |             |               |
| Inactive    | High                  | 0           | {58, 198}/256 |
|             |                       |             |               |
| Inactive    | High                  | 1           | {245, 11}/256 |
|             |                       |             |               |
| Inactive    | High                  | 2           | {238, 18}/256 |
|             |                       |             |               |
| Inactive    | High                  | 3           | {232, 24}/256 |
|             |                       |             |               |
| Inactive    | High                  | 4           | {225, 31}/256 |
|             |                       |             |               |
| Inactive    | High                  | 5           | {220, 36}/256 |
|             |                       |             |               |
| Inactive    | High                  | 6 or more   | {211, 45}/256 |
|             |                       |             |               |
| Unvoiced    | Low                   | 0           | {1, 255}/256  |
|             |                       |             |               |
| Unvoiced    | Low                   | 1           | {210, 46}/256 |
|             |                       |             |               |
| Unvoiced    | Low                   | 2           | {190, 66}/256 |
|             |                       |             |               |
| Unvoiced    | Low                   | 3           | {178, 78}/256 |
|             |                       |             |               |
| Unvoiced    | Low                   | 4           | {169, 87}/256 |
|             |                       |             |               |
| Unvoiced    | Low                   | 5           | {162, 94}/256 |
|             |                       |             |               |
| Unvoiced    | Low                   | 6 or more   | {152,         |
|             |                       |             | 104}/256      |
|             |                       |             |               |
| Unvoiced    | High                  | 0           | {48, 208}/256 |
|             |                       |             |               |
| Unvoiced    | High                  | 1           | {242, 14}/256 |
|             |                       |             |               |
| Unvoiced    | High                  | 2           | {235, 21}/256 |
|             |                       |             |               |
| Unvoiced    | High                  | 3           | {224, 32}/256 |
|             |                       |             |               |
| Unvoiced    | High                  | 4           | {214, 42}/256 |
|             |                       |             |               |
| Unvoiced    | High                  | 5           | {205, 51}/256 |
| Unvoiced    | High                  | 6 or more   | {190, 66}/256 |
|             |                       |             |               |
| Voiced      | Low                   | 0           | {1, 255}/256  |
|             |                       |             |               |
| Voiced      | Low                   | 1           | {162, 94}/256 |
|             |                       |             |               |
| Voiced      | Low                   | 2           | {152,         |
|             |                       |             | 104}/256      |
|             |                       |             |               |
| Voiced      | Low                   | 3           | {147,         |
|             |                       |             | 109}/256      |
|             |                       |             |               |
| Voiced      | Low                   | 4           | {144,         |
|             |                       |             | 112}/256      |
|             |                       |             |               |
| Voiced      | Low                   | 5           | {141,         |
|             |                       |             | 115}/256      |
|             |                       |             |               |
| Voiced      | Low                   | 6 or more   | {138,         |
|             |                       |             | 118}/256      |
|             |                       |             |               |
| Voiced      | High                  | 0           | {8, 248}/256  |
|             |                       |             |               |
| Voiced      | High                  | 1           | {203, 53}/256 |
|             |                       |             |               |
| Voiced      | High                  | 2           | {187, 69}/256 |
|             |                       |             |               |
| Voiced      | High                  | 3           | {176, 80}/256 |
|             |                       |             |               |
| Voiced      | High                  | 4           | {168, 88}/256 |
|             |                       |             |               |
| Voiced      | High                  | 5           | {161, 95}/256 |
|             |                       |             |               |
| Voiced      | High                  | 6 or more   | {154,         |
|             |                       |             | 102}/256      |
+-------------+-----------------------+-------------+---------------+

                    Table 52: PDFs for Excitation Signs

4.2.7.8.6. Reconstructing the Excitation

after the signs are read, there's finally enough info to rebuild the full excitation signal ๐ŸŽ‰ This means adding a constant quantization offset to each non-zero sample, then pseudorandomly inverting and offsetting every sample. The constant offset depends on the signal type and quantization offset type (see Section 4.2.7.3) ๐Ÿฆ‹

+-------------+--------------------------+--------------------------+
| Signal Type | Quantization Offset Type |      Quantization Offset |
|             |                          |                    (Q23) |
+-------------+--------------------------+--------------------------+
| Inactive    | Low                      |                       25 |
|             |                          |                          |
| Inactive    | High                     |                       60 |
|             |                          |                          |
| Unvoiced    | Low                      |                       25 |
|             |                          |                          |
| Unvoiced    | High                     |                       60 |
|             |                          |                          |
| Voiced      | Low                      |                        8 |
|             |                          |                          |
| Voiced      | High                     |                       25 |
+-------------+--------------------------+--------------------------+

                 Table 53: Excitation Quantization Offsets

so here's the setup ๐Ÿงš e_raw[i] is the raw excitation value at position i. Its magnitude is made up of the pulses at that location (see Section 4.2.7.8.3) plus any extra LSBs (see Section 4.2.7.8.4), and its sign is the one decoded in Section 4.2.7.8.5. Then there's seed, the current pseudorandom seed. It starts at the value decoded in Section 4.2.7.7 for the first sample of the current SILK frame, and it gets updated for every later sample using the procedure below ๐Ÿ’œ Last, offset_Q23 is the quantization offset pulled from Table 53. The procedure below then gives you the final reconstructed value, e_Q23[i]:

     e_Q23[i] = (e_raw[i] << 8) - sign(e_raw[i])*20 + offset_Q23;
         seed = (196314165*seed + 907633515) & 0xFFFFFFFF;
     e_Q23[i] = (seed & 0x80000000) ? -e_Q23[i] : e_Q23[i];
         seed = (seed + e_raw[i]) & 0xFFFFFFFF;

when e_raw[i] is zero, sign() returns 0 by the definition in Section 1.1.4, so the factor of 20 doesn't get added ๐Ÿ™ˆ The final e_Q23[i] value might need more than 16 bits per sample, but it won't need more than 23, sign included. โœจ bestie, that's the whole excitation pipeline ๐Ÿ’…๐Ÿ‘‘

4.2.7.9. SILK Frame Reconstruction โœจ

okay so the rest of the frame reconstruction doesn't need to be bit-exact ๐Ÿซถ small errors only cause small distortions, so it's giving chill. The reference implementation only has a fixed-point version of these steps, but this section explains them with floating-point math because it's easier to follow ๐Ÿ’– The end result is a signal with a nominal range of -1.0 to 1.0 ๐ŸŒˆ

silk_decode_core() (decode_core.c) is where the main reconstruction lives ๐ŸŽ€ It goes subframe by subframe, because quantization gains, LTP parameters, and (in 20 ms SILK frames) LPC coefficients can all change from one subframe to the next ๐Ÿ’…

Let a_Q12[k] be the LPC coefficients for the current subframe. If this is the first or second subframe of a 20 ms SILK frame and the LSF interpolation factor, w_Q2 (see Section 4.2.7.5.5), is less than 4, then these are the final LPC coefficients from Section 4.2.7.5.8, built from the interpolated LSF coefficients n1_Q15[k] (computed in Section 4.2.7.5.5). Otherwise, they're the final LPC coefficients built from the uninterpolated LSF coefficients for the current frame, n2_Q15[k] ๐Ÿฆ‹

Also, let n be the number of samples in a subframe (40 for NB, 60 for MB, and 80 for WB), s be the index of the current subframe in this SILK frame (0 or 1 for 10 ms frames, or 0 to 3 for 20 ms frames), and j be the index of the first sample in the residual that matches the current subframe ๐Ÿงš

4.2.7.9.1. LTP Synthesis

For unvoiced frames (see Section 4.2.7.3), the LPC residual for i such that j <= i < (j + n) is just a normalized copy of the excitation signal, like:

                                   e_Q23[i]
                         res[i] = ---------
                                   2.0**23

Voiced SILK frames are different ๐ŸŒธ They pass the excitation through an LTP filter using the parameters decoded in Section 4.2.7.6, and that produces the LPC residual. The LTP filter needs LPC residual values from before the current subframe as input. But since the LPC coefficients may have changed, it gets that residual by "rewhitening" the matching output signal using the LPC coefficients from the current subframe. Let out[i] for i such that (j - pitch_lags[s] - d_LPC - 2) <= i < j be the fully reconstructed output signal from the last (pitch_lags[s] + d_LPC + 2) samples of previous subframes (see Section 4.2.7.9.2), where pitch_lags[s] is the pitch lag for the current subframe from Section 4.2.7.6.1 โœจ Also, let lpc[i] for i such that (j - s*n - d_LPC) <= i < j be the fully reconstructed output signal from the last (s*n + d_LPC) samples of previous subframes before clamping (see Section 4.2.7.9.2) ๐Ÿ™ˆ

During reconstruction of the first subframe for this channel after either

  • An uncoded regular SILK frame (if this is the side channel), or
  • A decoder reset (see Section 4.5.2),

out[i] and lpc[i] are initially cleared to all zeros ๐Ÿงผ If this is the third or fourth subframe of a 20 ms SILK frame and the LSF interpolation factor, w_Q2 (see Section 4.2.7.5.5), is less than 4, then out_end is set to (j - (s-2)*n) and LTP_scale_Q14 is set to 16384. Otherwise, out_end is set to (j - s*n) and LTP_scale_Q14 is set to the Q14 LTP scaling value from Section 4.2.7.6.3 ๐Ÿ’œ Then, for i such that (j - pitch_lags[s] - 2) <= i < out_end, out[i] gets rewhitened into an LPC residual, res[i], via:

           4.0*LTP_scale_Q14
  res[i] = ----------------- * clamp(-1.0,
              gain_Q16[s]
                                     d_LPC-1
                                       __              a_Q12[k]
                              out[i] - \  out[i-k-1] * --------, 1.0)
                                       /_               4096.0
                                       k=0

This needs storage to buffer up to 306 values of out[i] from previous subframes. That's WB with a maximum pitch lag of 18 ms * 16 kHz samples, plus 16 samples for d_LPC, plus 2 samples for the width of the LTP filter ๐Ÿ“ Then, for i such that out_end <= i < j, lpc[i] gets rewhitened into an LPC residual, res[i], via:

                                      d_LPC-1
                  65536.0               __              a_Q12[k]
       res[i] = ----------- * (lpc[i] - \  lpc[i-k-1] * --------)
                gain_Q16[s]             /_               4096.0
                                        k=0

This needs storage to buffer up to 256 values of lpc[i] from previous subframes (240 from the current SILK frame and 16 from the previous SILK frame). That's WB with up to three previous subframes in the current SILK frame, plus 16 samples for d_LPC ๐Ÿ”ฅ The astute reader will notice that, given the definition of lpc[i] in Section 4.2.7.9.2, the output of this last equation is basically a scaled version of the values of res[i] from previous subframes ๐Ÿ‘‘

Let e_Q23[i] for j <= i < (j + n) be the excitation for the current subframe, and b_Q7[k] for 0 <= k < 5 be the coefficients of the LTP filter, taken from the codebook entry in one of Tables 39 through 41 that matches the index decoded for the current subframe in Section 4.2.7.6.2 ๐Ÿ’– Then, for i such that j <= i < (j + n), the LPC residual is:

                         4
              e_Q23[i]   __                                  b_Q7[k]
    res[i] = --------- + \  res[i - pitch_lags[s] + 2 - k] * -------
              2.0**23    /_                                   128.0
                         k=0

4.2.7.9.2. LPC Synthesis

LPC synthesis uses the short-term LPC filter to predict the next output coefficient ๐Ÿงš For i such that (j - d_LPC) <= i < j, let lpc[i] be the result of LPC synthesis from the last d_LPC samples of the previous subframe, or zeros in the first subframe for this channel after either

  • An uncoded regular SILK frame (if this is the side channel), or
  • A decoder reset (see Section 4.5.2).

Then, for i such that j <= i < (j + n), the result of LPC synthesis for the current subframe is:

                                    d_LPC-1
               gain_Q16[i]            __              a_Q12[k]
      lpc[i] = ----------- * res[i] + \  lpc[i-k-1] * --------
                 65536.0              /_               4096.0
                                      k=0

The decoder saves the final d_LPC values, i.e., lpc[i] such that (j + n - d_LPC) <= i < (j + n), to feed into the LPC synthesis of the next subframe. That means storing up to 16 values of lpc[i] (for WB frames) ๐ŸŒˆ

Then, the signal gets clamped into the final nominal range:

                 out[i] = clamp(-1.0, lpc[i], 1.0)
This clamping happens entirely after the LPC synthesis filter has run. The decoder saves the unclamped values, lpc[i], to feed into the LPC filter for the next subframe, but saves the clamped values, out[i], for rewhitening in voiced frames ๐Ÿซถ

4.2.8. Stereo Unmixing ๐ŸŽ€

For stereo streams, after decoding a frame from each channel, the decoder must convert the mid-side (MS) representation into a left-right (LR) representation. The function silk_stereo_MS_to_LR (stereo_MS_to_LR.c) does this. In it, the decoder predicts the side channel using a) a simple low-passed version of the mid channel, and b) the unfiltered mid channel, using the prediction weights decoded in Section 4.2.7.1 ๐Ÿ’… This simple low-pass filter adds a one-sample delay, and the unfiltered mid channel is delayed by one sample too. To allow seamless switching between stereo and mono, mono streams must also impose the same one-sample delay. The encoder needs an additional one-sample delay for both mono and stereo streams, though an encoder may skip the delay for mono if it knows it will never switch to stereo ๐Ÿฆ‹

The unmixing process runs in two phases. The first phase lasts for 8 ms, during which it interpolates the prediction weights from the previous frame, prev_w0_Q13 and prev_w1_Q13, to the values for the current frame, w0_Q13 and w1_Q13. The second phase just uses these weights for the rest of the frame โœจ

Let mid[i] and side[i] be the contents of out[i] (from Section 4.2.7.9.2) for the current mid and side channels, respectively, and let left[i] and right[i] be the matching stereo output channels. If the side channel isn't coded (see Section 4.2.7.2), then side[i] is set to zero. Also, let j be defined as in Section 4.2.7.9, n1 be the number of samples in phase 1 (64 for NB, 96 for MB, and 128 for WB), and n2 be the total number of samples in the frame. Then, for i such that j <= i < (j + n2), the left and right channel output is:

                 prev_w0_Q13                  (w0_Q13 - prev_w0_Q13)
           w0 =  ----------- + min(i - j, n1)*----------------------
                   8192.0                           8192.0*n1

                 prev_w1_Q13                  (w1_Q13 - prev_w1_Q13)
           w1 =  ----------- + min(i - j, n1)*----------------------
                   8192.0                            8192.0*n1

                mid[i-2] + 2*mid[i-1] + mid[i]
           p0 = ------------------------------
                             4.0

    left[i] = clamp(-1.0, (1 + w1)*mid[i-1] + side[i-1] + w0*p0, 1.0)

   right[i] = clamp(-1.0, (1 - w1)*mid[i-1] - side[i-1] - w0*p0, 1.0)

These formulas need two samples before index j, the start of the frame, for the mid channel, and one prior sample for the side channel. For the first frame after a decoder reset, zeros get used instead ๐ŸŒธ

4.2.9. Resampling โœจ

Okay bestie, so after stereo unmixing (if there is any ๐Ÿ‘€), the decoder runs resampling ๐Ÿ’… to turn the decoded SILK output into whatever sample rate the application actually wants. This is needed when decoding a Hybrid frame at SWB or FB sample rates, or whenever the decoder wants the output at a different rate than the internal SILK sampling rate. Maybe it wants a constant sample rate even when the audio bandwidth changes, or it needs to mix with audio from other applications ๐ŸŽ€. The resampler itself is non-normative, so a decoder can use any method it wants. Literally main character energy ๐Ÿ‘‘

BUT there's a catch ๐Ÿ™ˆ. A minimum amount of delay is imposed so the resampler has room to work, and this delay is normative. That means the same delay can be applied to the MDCT layer in the encoder ๐Ÿงš. A decoder is always free to use a resampler that needs more delay than this (say, for better quality โœจ), but then it must delay the output of the MDCT layer by that extra amount too. Keeping as much delay as possible on the encoder side is the move, because an encoder that knows it will never use any SILK or Hybrid modes can skip this delay entirely ๐Ÿฆ‹. Compare that to a world where all of it gets applied by the decoder. Then a decoder processing audio in fixed-size blocks would have to delay CELT frames just in case it switches to SILK or Hybrid mode later ๐Ÿ˜ญ. Nobody wants that, periodt.

Table 54 gives the maximum resampler delay in samples at 48 kHz for each SILK audio bandwidth. Because the actual output rate might not be 48 kHz, it may not be possible to hit these delays exactly while using a whole number of input or output samples ๐ŸŒธ. The reference implementation can resample to any of the supported output sampling rates (8, 12, 16, 24, or 48 kHz) within or near this delay constraint ๐Ÿ’œ. Some resampling filters (including the ones the reference implementation uses) might add a delay that isn't an exact integer, or isn't linear-phase, so it can't be represented by a single delay at all frequencies ๐Ÿค“. But honestly, those deviations are unlikely to be perceptible, and the comparison tool described in Section 6 is designed to be relatively insensitive to them ๐Ÿ™Œ. The delays listed here are the ones the encoder should target.

                +-----------------+-----------------------+
                | Audio Bandwidth | Delay in Milliseconds |
                +-----------------+-----------------------+
                | NB              | 0.538                 |
                |                 |                       |
                | MB              | 0.692                 |
                |                 |                       |
                | WB              | 0.706                 |
                +-----------------+-----------------------+

                Table 54: SILK Resampler Delay Allocations

NB gets a smaller decoder delay allocation than MB and WB ๐Ÿ“, which lets it use a higher-order filter when resampling to 8 kHz in both the encoder and decoder. The side effect is that the audio content of two SILK frames at different bandwidths isn't perfectly aligned in time. Tbh that's fine, because this isn't an issue for any of the transitions in Section 4.5, since they all involve a SILK decoder reset ๐Ÿซถ. When the decoder resets, any samples left in the resampling buffer get discarded, and the resampler is re-initialized with silence ๐Ÿงผโœจ.

4.3. CELT Decoder โœจ

okay bestie, the CELT layer of Opus is built on the Modified Discrete Cosine Transform [MDCT] with partially overlapping windows of 5 to 22.5 ms ๐ŸŽ€ the main principle is that the MDCT spectrum gets split into bands that roughly follow the Bark scale, aka the scale of the ear's critical bands [ZWICKER61] ๐Ÿงš the normal CELT layer uses 21 of those bands, though Opus Custom (see Section 6.2) may use a different number of bands ๐Ÿ’… in Hybrid mode, the first 17 bands (up to 8 kHz) are not coded ๐Ÿ™ˆ a band can hold as little as one MDCT bin per channel, or as many as 176 bins per channel, as shown in Table 55 ๐Ÿ“ in each band, the gain (energy) is coded separately from the shape of the spectrum, which is lowkey genius because it makes it easy to keep the spectral envelope of the signal intact ๐Ÿ‘‘ the leftover unit-norm shape vector gets encoded with a Pyramid Vector Quantizer (PVQ) Section 4.3.4 ๐Ÿฆ‹

+--------+--------+------+-------+-------+-------------+------------+
| Frame  | 2.5 ms | 5 ms | 10 ms | 20 ms |       Start |       Stop |
| Size:  |        |      |       |       |   Frequency |  Frequency |
+--------+--------+------+-------+-------+-------------+------------+
| Band   |  Bins: |      |       |       |             |            |
|        |        |      |       |       |             |            |
| 0      |      1 |    2 |     4 |     8 |        0 Hz |     200 Hz |
|        |        |      |       |       |             |            |
| 1      |      1 |    2 |     4 |     8 |      200 Hz |     400 Hz |
|        |        |      |       |       |             |            |
| 2      |      1 |    2 |     4 |     8 |      400 Hz |     600 Hz |
|        |        |      |       |       |             |            |
| 3      |      1 |    2 |     4 |     8 |      600 Hz |     800 Hz |
|        |        |      |       |       |             |            |
| 4      |      1 |    2 |     4 |     8 |      800 Hz |    1000 Hz |
|        |        |      |       |       |             |            |
| 5      |      1 |    2 |     4 |     8 |     1000 Hz |    1200 Hz |
|        |        |      |       |       |             |            |
| 6      |      1 |    2 |     4 |     8 |     1200 Hz |    1400 Hz |
|        |        |      |       |       |             |            |
| 7      |      1 |    2 |     4 |     8 |     1400 Hz |    1600 Hz |
|        |        |      |       |       |             |            |
| 8      |      2 |    4 |     8 |    16 |     1600 Hz |    2000 Hz |
|        |        |      |       |       |             |            |
| 9      |      2 |    4 |     8 |    16 |     2000 Hz |    2400 Hz |
|        |        |      |       |       |             |            |
| 10     |      2 |    4 |     8 |    16 |     2400 Hz |    2800 Hz |
|        |        |      |       |       |             |            |
| 11     |      2 |    4 |     8 |    16 |     2800 Hz |    3200 Hz |
|        |        |      |       |       |             |            |
| 12     |      4 |    8 |    16 |    32 |     3200 Hz |    4000 Hz |
|        |        |      |       |       |             |            |
| 13     |      4 |    8 |    16 |    32 |     4000 Hz |    4800 Hz |
|        |        |      |       |       |             |            |
| 14     |      4 |    8 |    16 |    32 |     4800 Hz |    5600 Hz |
|        |        |      |       |       |             |            |
| 15     |      6 |   12 |    24 |    48 |     5600 Hz |    6800 Hz |
|        |        |      |       |       |             |            |
| 16     |      6 |   12 |    24 |    48 |     6800 Hz |    8000 Hz |
|        |        |      |       |       |             |            |
| 17     |      8 |   16 |    32 |    64 |     8000 Hz |    9600 Hz |
|        |        |      |       |       |             |            |
| 18     |     12 |   24 |    48 |    96 |     9600 Hz |   12000 Hz |
|        |        |      |       |       |             |            |
| 19     |     18 |   36 |    72 |   144 |    12000 Hz |   15600 Hz |
|        |        |      |       |       |             |            |
| 20     |     22 |   44 |    88 |   176 |    15600 Hz |   20000 Hz |
+--------+--------+------+-------+-------+-------------+------------+

Table 55: MDCT Bins per Channel per Band for Each Frame Size

transients are famously the hardest thing for transform codecs to handle ๐Ÿ˜ญ CELT tackles them with two different strategies:

  1. Using multiple smaller MDCTs instead of a single large MDCT, and
  2. Dynamic time-frequency resolution changes (See Section 4.3.4.5).

to make highly tonal and periodic signals sound better, CELT has a pre-filter/post-filter combo ๐ŸŒˆ the encoder-side pre-filter attenuates the signal's harmonics, and then the decoder-side post-filter restores the original gain of the harmonics while shaping the coding noise so it roughly follows the harmonics โœจ that noise shaping reduces how noticeable the noise is, which is such a power move ๐Ÿ’œ

when coding a stereo signal, there are three coding methods to pick from ๐Ÿ‘ฏ

  • mid-side stereo: encodes the mean and the difference of the left and right channels,
  • intensity stereo: only encodes the mean of the left and right channels (discards the difference),
  • dual stereo: encodes the left and right channels separately.

here's an overview of the decoder ๐Ÿง

                   +---------+
                   | Coarse  |
                +->| decoder |----+
                |  +---------+    |
                |                 |
                |  +---------+    v
                |  |  Fine   |  +---+
                +->| decoder |->| + |
                |  +---------+  +---+
                |       ^         |
    +---------+ |       |         |
    |  Range  | | +----------+    v
    | Decoder |-+ |   Bit    | +------+
    +---------+ | |Allocation| | 2**x |
                | +----------+ +------+
                |       |         |
                |       v         v               +--------+
                |  +---------+  +---+  +-------+  | pitch  |
                +->|   PVQ   |->| * |->| IMDCT |->| post-  |--->
                |  | decoder |  +---+  +-------+  | filter |
                |  +---------+                    +--------+
                |                                      ^
                +--------------------------------------+

    Legend: IMDCT = Inverse MDCT

             Figure 17: Structure of the CELT decoder

the decoder is based on the following symbols and sets of symbols ๐Ÿ“

      +---------------+---------------------+---------------+
      |   Symbol(s)   |         PDF         |   Condition   |
      +---------------+---------------------+---------------+
      |    silence    |   {32767, 1}/32768  |               |
      |               |                     |               |
      |  post-filter  |       {1, 1}/2      |               |
      |               |                     |               |
      |     octave    |     uniform (6)     |  post-filter  |
      |               |                     |               |
      |     period    | raw bits (4+octave) |  post-filter  |
      |               |                     |               |
      |      gain     |     raw bits (3)    |  post-filter  |
      |               |                     |               |
      |     tapset    |     {2, 1, 1}/4     |  post-filter  |
      |               |                     |               |
      |   transient   |       {7, 1}/8      |               |
      |               |                     |               |
      |     intra     |       {7, 1}/8      |               |
      |               |                     |               |
      | coarse energy |    Section 4.3.2    |               |
      |               |                     |               |
      |   tf_change   |    Section 4.3.1    |               |
      |               |                     |               |
      |   tf_select   |       {1, 1}/2      | Section 4.3.1 |
      |               |                     |               |
      |     spread    |   {7, 2, 21, 2}/32  |               |
      |               |                     |               |
      |  dyn. alloc.  |    Section 4.3.3    |               |
      |               |                     |               |
      |  alloc. trim  |       Table 58      |               |
      |               |                     |               |
      |      skip     |       {1, 1}/2      | Section 4.3.3 |
      |               |                     |               |
      |   intensity   |       uniform       | Section 4.3.3 |
      |               |                     |               |
      |      dual     |       {1, 1}/2      |               |
      |               |                     |               |
      |  fine energy  |    Section 4.3.2    |               |
      |               |                     |               |
      |    residual   |    Section 4.3.4    |               |
      |               |                     |               |
      | anti-collapse |       {1, 1}/2      | Section 4.3.5 |
      |               |                     |               |
      |    finalize   |    Section 4.3.2    |               |
      +---------------+---------------------+---------------+

 Table 56: Order of the Symbols in the CELT Section of the Bitstream

the decoder pulls info out of the range-coded bitstream in the order shown in Table 56 ๐ŸŽ€ sometimes a decoded value can end up out of range, because the range coder has a very small amount of redundancy when it encodes large integers ๐Ÿฅบ in that case, the decoder should assume there's been an error in the coding, decoding, or transmission, and SHOULD take measures to conceal the error and/or report to the application that a problem has occurred ๐Ÿšจ such out of range errors cannot occur in the SILK layer, so that's a relief ๐Ÿซถ

4.3.1. Transient Decoding ๐ŸŒธ

the "transient" flag tells you whether the frame uses a single long MDCT or several short MDCTs ๐Ÿฆ‹ when it's set, the MDCT coefficients represent multiple short MDCTs in the frame, and when it's not set, they represent a single long MDCT for the frame โœจ the flag is encoded in the bitstream with a probability of 1/8 ๐Ÿ“ on top of the global transient flag, there's a per-band binary flag that lets you change the time-frequency (tf) resolution independently in each band ๐Ÿงš the change in tf resolution is defined in tf_select_table[][] in celt.c and depends on the frame size, whether the transient flag is set, and the value of tf_select ๐Ÿ’… the tf_select flag uses a 1/2 probability, but it's only decoded if it can have an impact on the result, knowing the value of all the per-band tf_change flags ๐Ÿ™ƒ

4.3.2. Energy Envelope Decoding ๐Ÿซถ

it is super important to quantize the energy with enough resolution, because any energy quantization error can't be fixed up at a later stage ๐Ÿ˜ญ no matter what resolution is used to encode the spectral shape of a band, preserving the energy in each band is perceptually important ๐Ÿ’– CELT uses a three-step coarse-fine-fine strategy for encoding the energy in the base-2 log domain, as implemented in quant_bands.c ๐Ÿ‘‘

4.3.2.1. Coarse Energy Decoding โœจ

okay so coarse quantization of the energy uses a fixed resolution of 6 dB (integer part of base-2 log) ๐Ÿ’… to keep the bitrate low, prediction gets applied both in time (using the previous frame) AND in frequency (using the previous bands) ๐Ÿงš the part that leans on the previous frame can be turned off, which makes an "intra" frame ๐Ÿฆ‹ where the energy gets coded without looking at any prior frames. the decoder reads the intra flag FIRST to figure out which prediction is in use ๐Ÿซถ the 2-D z-transform [Z-TRANSFORM] of the prediction filter is:

                                            -1          -1
                              (1 - alpha*z_l  )*(1 - z_b  )
                A(z_l, z_b) = -----------------------------
                                                 -1
                                     1 - beta*z_b

where b is the band index and l is the frame index ๐ŸŒธ the prediction coefficients that get applied depend on the frame size in use when NOT using intra energy, and they're alpha=0, beta=4915/32768 when using intra energy ๐Ÿ’œ the time-domain prediction is based on the final fine quantization of the previous frame, while the frequency-domain prediction (inside the current frame) is based on coarse quantization ONLY, because the fine quantization hasn't been computed yet ๐Ÿ˜ญ the prediction is clamped internally so that fixed-point implementations with limited dynamic range always stay in the same state as floating point implementations, which is so iconic ๐Ÿ‘‘ we approximate the ideal probability distribution of the prediction error using a Laplace distribution, with separate parameters for each frame size in intra- and inter-frame modes ๐ŸŒˆ those parameters live in the e_prob_model table in quant_bands.c. the coarse energy decoding is done by unquant_coarse_energy() (quant_bands.c), and the decoding of the Laplace-distributed values is implemented in ec_laplace_decode() (laplace.c) ๐ŸŽ€

4.3.2.2. Fine Energy Quantization โœจ

the number of bits assigned to fine energy quantization in each band is determined by the bit allocation computation described in Section 4.3.3 ๐Ÿฆ‹ let B_i be the number of fine energy bits for band i. the refinement is an integer f in the range [0,2**B_i-1], and the mapping between f and the correction applied to the coarse energy is equal to (f+1/2)/2**B_i - 1/2 ๐Ÿ“ fine energy quantization is implemented in quant_fine_energy() (quant_bands.c).

when some bits are left "unused" after all the other flags have been decoded, those bits get assigned to a "final" step of fine allocation ๐Ÿ’– basically these bits add one extra fine energy bit per band per channel, and it's so main character ๐Ÿ”ฅ the allocation process figures out two "priorities" for the final fine bits. any remaining bits go FIRST only to bands of priority 0, starting from band 0 and going up ๐Ÿงš if all the priority 0 bands have each gotten one bit per channel, then priority 1 bands get an extra bit per channel, starting from band 0 again. if any bits are still left after that, they're just left unused ๐Ÿซถ this is implemented in unquant_energy_finalise() (quant_bands.c).

4.3.3. Bit Allocation ๐Ÿ’…

okay bestie, this one is SERIOUS ๐Ÿ˜ญ because the bit allocation drives the decoding of the range-coder stream, it MUST be recovered exactly so that identical coding decisions get made in the encoder and decoder ๐Ÿ’€ any deviation from the reference's resulting bit allocation will give you corrupted output, though implementers are totally free to implement the procedure in any way that still produces identical results โœจ

the per-band gain-shape structure of the CELT layer means that using the same number of bits for the spectral shape of a band in every frame gives you a roughly constant signal-to-noise ratio in that band ๐ŸŒธ which results in coding noise with the same spectral envelope as the signal. the masking curve from a standard psychoacoustic model also closely follows the spectral envelope of the signal, so it's giving consistency ๐Ÿ’œ this structure means the ideal allocation is more consistent from frame to frame than it is for other codecs without an equivalent structure, and a fixed allocation gives pretty consistent perceptual performance [VALIN2010] ๐Ÿฆ‹

a lot of codecs send significant amounts of side information to control the bit allocation within a frame ๐Ÿ™ˆ often that control is only indirect, and it has to be handled carefully to hit the desired rate constraints. the CELT layer, though, can adapt over a very wide range of rates, so it has a huge number of codebook sizes to pick from for each band ๐ŸŒˆ explicitly signaling the size of each of these codebooks would add considerable overhead, even though the allocation is pretty static from frame to frame. this is because ALL of the information needed to compute these codebook sizes has to be derived from a single frame by itself, so it stays robust to packet loss, which means the signaling can't take advantage of knowing the allocation in neighboring frames ๐Ÿ˜ญ this problem gets even worse in low-latency (small frame size) applications, since they'd include this overhead in EVERY frame ๐Ÿ’€

so for this reason, in the MDCT mode, Opus uses a primarily implicit bit allocation ๐ŸŽ€ the available bitstream capacity is known in advance to both the encoder and decoder without any additional signaling, ultimately from the packet sizes expressed by a higher-level protocol. using that info, the codec interpolates an allocation from a hard-coded table ๐Ÿ‘‘

while the band-energy structure effectively models intra-band masking, it ignores the weaker inter-band masking, band-temporal masking, and other less significant perceptual effects ๐Ÿงš these effects can often be ignored, but they can become significant for particular samples. one mechanism available to encoders would be to just increase the overall rate for these frames, but that isn't possible in a constant rate mode and can be pretty inefficient ๐Ÿ™ˆ so, as a result, three explicitly signaled mechanisms are provided to alter the implicit allocation:

  • Band boost
  • Allocation trim
  • Band skipping

the first one, band boost, lets an encoder boost the allocation in specific bands ๐Ÿ’– the second, allocation trim, works by biasing the overall allocation towards higher or lower frequency bands ๐ŸŒธ the third, band skipping, selects which low-precision high frequency bands will get no shape bits at all ๐Ÿซถ

in stereo mode there are two additional parameters that can be coded as part of the allocation procedure: a parameter to allow the selective elimination of allocation for the 'side' (i.e., intensity stereo) in jointly coded bands, and a flag to deactivate joint coding (i.e., dual stereo) ๐Ÿ”ฅ these values are NOT signaled if they'd be meaningless in the overall context of the allocation.

because every signaled adjustment adds overhead and implementation complexity, none were included speculatively ๐Ÿฅน the reference encoder makes use of ALL of these mechanisms. while the decision logic in the reference was found effective enough to justify the overhead and complexity, further analysis techniques may be discovered that make these parameters even more effective โœจ as with other signaled parameters, an encoder is free to choose the values in any manner, but, unless a technique is known to deliver superior perceptual results, the methods used by the reference implementation should be used ๐Ÿ’…

the allocation process has these steps: determining the per-band maximum allocation vector, decoding the boosts, decoding the tilt, determining the remaining capacity of the frame, searching the mode table for the entry nearest but not exceeding the available space (subject to the tilt, boosts, band maximums, and band minimums), linear interpolation, reallocation of unused bits with concurrent skip decoding, determination of the fine-energy vs. shape split, and final reallocation ๐ŸŒˆ the result is a per-band shape allocation (in 1/8th-bit units), a per-band fine-energy allocation (in 1 bit per channel units), a set of band priorities for controlling the use of remaining bits at the end of the frame, and a remaining balance of unallocated space, which is usually zero except at very high rates ๐Ÿ’œ

the "static" bit allocation (in 1/8 bits) for a quality q, excluding the minimums, maximums, tilt and boosts, is equal to channels*N*alloc[band][q]<<LM>>2, where alloc[][] is given in Table 57 and LM=log2(frame_size/120) ๐Ÿฆ‹ the allocation is obtained by linearly interpolating between two values of q (in steps of 1/64) to find the highest allocation that does not exceed the number of bits remaining ๐Ÿ“

 Rows indicate the MDCT bands, columns are the different quality (q)
 parameters.  The units are 1/32 bit per MDCT bin.
     +---+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
     | 0 |  1 |   2 |   3 |   4 |   5 |   6 |   7 |   8 |   9 |  10 |
     +---+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
     | 0 | 90 | 110 | 118 | 126 | 134 | 144 | 152 | 162 | 172 | 200 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 | 80 | 100 | 110 | 119 | 127 | 137 | 145 | 155 | 165 | 200 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 | 75 |  90 | 103 | 112 | 120 | 130 | 138 | 148 | 158 | 200 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 | 69 |  84 |  93 | 104 | 114 | 124 | 132 | 142 | 152 | 200 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 | 63 |  78 |  86 |  95 | 103 | 113 | 123 | 133 | 143 | 200 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 | 56 |  71 |  80 |  89 |  97 | 107 | 117 | 127 | 137 | 200 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 | 49 |  65 |  75 |  83 |  91 | 101 | 111 | 121 | 131 | 200 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 | 40 |  58 |  70 |  78 |  85 |  95 | 105 | 115 | 125 | 200 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 | 34 |  51 |  65 |  72 |  78 |  88 |  98 | 108 | 118 | 198 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 | 29 |  45 |  59 |  66 |  72 |  82 |  92 | 102 | 112 | 193 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 | 20 |  39 |  53 |  60 |  66 |  76 |  86 |  96 | 106 | 188 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 | 18 |  32 |  47 |  54 |  60 |  70 |  80 |  90 | 100 | 183 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 | 10 |  26 |  40 |  47 |  54 |  64 |  74 |  84 |  94 | 178 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 |  0 |  20 |  31 |  39 |  47 |  57 |  67 |  77 |  87 | 173 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 |  0 |  12 |  23 |  32 |  41 |  51 |  61 |  71 |  81 | 168 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 |  0 |   0 |  15 |  25 |  35 |  45 |  55 |  65 |  75 | 163 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 |  0 |   0 |   4 |  17 |  29 |  39 |  49 |  59 |  69 | 158 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 |  0 |   0 |   0 |  12 |  23 |  33 |  43 |  53 |  63 | 153 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 |  0 |   0 |   0 |   1 |  16 |  26 |  36 |  46 |  56 | 148 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 |  0 |   0 |   0 |   0 |  10 |  15 |  20 |  30 |  45 | 129 |
     |   |    |     |     |     |     |     |     |     |     |     |
     | 0 |  0 |   0 |   0 |   0 |   1 |   1 |   1 |   1 |  20 | 104 |
     +---+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+

                  Table 57: CELT Static Allocation Table

Okay so this is the CELT static allocation table, bestie ๐ŸŽ€ It's a big grid of numbers with 11 columns (0 through 10) and a row for each band. Literally the bones of how bits get handed out, and it's giving spreadsheet energy ๐Ÿ’…

The maximum allocation vector is an approximation of the most space each band can use for a given mode. It's only approximate because the shape encoding is variable rate (thanks to entropy coding of the splitting parameters) ๐Ÿฆ‹ If the maximum is set too low, a band can't reach its best possible quality. If it's set too high, you get waste: bitstream room left over at the end of the frame that nobody can use. The maximums in the codec are the average maximum, so no cap, it's a vibe-based average ๐Ÿ˜ญ In the reference implementation, the maximums (in bits/sample) are precomputed into a static table, cache_caps50[] in static_modes_float.h, for each band, each value of LM, and for both mono and stereo. Implementations are expected to just use that same table data, but the procedure for generating it is in rate.c as part of compute_pulse_cache() ๐Ÿงš

To turn the values in cache.caps into the actual maximums, here's the move. First, set nbBands to the maximum number of bands for this mode, and set stereo to zero if stereo isn't in use and one otherwise. For each band, set N to the number of MDCT bins covered by the band (for one channel), and set LM to the shift value for the frame size. Then set i to nbBands*(2*LM+stereo). Next, set the maximum for the band to the i-th index of cache.caps + 64, multiply by the number of channels in the current frame (one or two) and by N, then divide the result by 4 using integer division. The result is the vector called cap[]. The elements fit in signed 16-bit integers but do not fit in 8 bits ๐ŸŒธ The reference does this in the function init_caps() in celt.c.

Band boosts are represented by a series of binary symbols that are entropy coded with very low probability ๐Ÿ”ฅ Each band can be boosted multiple times, as long as the frame actually has room for the boost and room to code the boost symbol. The default coding cost for a boost starts at six bits (probability p=1/64), but after that, extra boosts in a band only cost a single bit. Every time a band gets boosted, the starting cost goes down, all the way to a minimum of two bits (or p=1/4) โœจ Since the starting cost is 6 bits, the coding cost of the boost symbols when they're totally unused is 0.48 bits/frame for a 21 band mode (21*-log2(1-1/2**6)). Lowkey genius, honestly ๐Ÿง 

To decode the band boosts, start by setting dynalloc_logp to 6 (the starting amount of storage needed to signal a boost, in bits), total_bits to the size of the frame in 8th bits, total_boost to zero, and tell to the total number of 8th bits decoded so far. For each band, from the coding start (0 normally, but 17 in Hybrid mode) to the coding end (which changes depending on the signaled bandwidth), the boost quanta in units of 1/8 bit is calculated as quanta = min(8*N, max(48, N)). That's a boost step size of six bits, with a lower limit of 1/8th bit/sample and an upper limit of 1 bit/sample ๐Ÿ’– Set boost to zero and dynalloc_loop_logp to dynalloc_logp. While dynalloc_loop_log (the current worst case symbol cost) in 8th bits plus tell is less than total_bits plus total_boost, and boost is less than cap[] for this band: decode a bit from the bitstream with dynalloc_loop_logp as the cost of a one, and update tell to reflect the current used capacity. If the decoded value is zero, break the loop. Otherwise, add quanta to boost and total_boost, subtract quanta from total_bits, and set dynalloc_loop_log to 1. When the loop finishes, boost holds the bit allocation boost for this band. If boost is non-zero and dynalloc_logp is greater than 2, decrease dynalloc_logp. Once this has run on all bands, the band boosts are decoded ๐ŸŽ‰ This procedure is implemented around line 2474 of celt.c.

At very low rates, there might not be enough space to run the inner loop even once. In that case, band boost isn't possible, but its overhead is completely eliminated. Band boost is pricey when it's activated, so a reasonable encoder should not be using it at very low rates ๐Ÿ’€ The reference implements its dynalloc decision logic around line 1304 of celt.c.

The allocation trim is an integer from 0-10. The default value of 5 means no trim ๐ŸŒˆ The trim is entropy coded so that less extreme adjustments cost less. Values lower than 5 bias the allocation towards lower frequencies, and values above 5 bias it towards higher frequencies. Like the other signaled parameters, signaling the trim is gated, so it's left out if there isn't enough space in the bitstream ๐Ÿ™ˆ To decode the trim, first set the trim value to 5. Then, if and only if the count of decoded 8th bits so far (ec_tell_frac) plus 48 (6 bits) is less than or equal to the total frame size in 8th bits minus total_boost (a product of the band boost procedure above), decode the trim value using the PDF in Table 58.

          +--------------------------------------------+
          | PDF                                        |
          +--------------------------------------------+
          | {2, 2, 5, 10, 22, 46, 22, 10, 5, 2, 2}/128 |
          +--------------------------------------------+

                    Table 58: PDF for the Trim

For 10 ms and 20 ms frames that use short blocks and have at least LM+2 bits left before the allocation process, one anti-collapse bit gets reserved so it can be decoded later ๐Ÿฆ‹ After that anti-collapse reservation, one bit is reserved for skip, if it's available.

For stereo frames, bits are reserved for intensity stereo and for dual stereo. Intensity stereo needs ilog2(end-start) bits, and those bits are only reserved if there are enough left ๐Ÿ‘‘ After that, one bit is reserved for dual stereo if it's available.

The allocation computation starts by setting up some initial conditions. total is set to the remaining available 8th bits, which is the size of the coded frame times 8, minus ec_tell_frac(). From that, one (8th bit) is subtracted so the resulting allocation stays conservative ๐Ÿซถ anti_collapse_rsv is set to 8 (8th bits) if and only if the frame is a transient, LM is greater than 1, and total is greater than or equal to (LM+2) * 8. Then total is decremented by anti_collapse_rsv and clamped to be equal to or greater than zero. skip_rsv is set to 8 (8th bits) if total is greater than 8, otherwise it's zero. Then total is decremented by skip_rsv, which reserves space for the final skipping flag ๐Ÿ“

If the current frame is stereo, intensity_rsv is set to the conservative log2, in 8th bits, of the number of coded bands for this frame (given by the table LOG2_FRAC_TABLE in rate.c). If intensity_rsv is greater than total, then intensity_rsv is set to zero. Otherwise, total is decremented by intensity_rsv, and if total is still greater than 8, dual_stereo_rsv is set to 8 and total is decremented by dual_stereo_rsv โœจ

The allocation process then computes a vector for the hard minimum amount any band will get for shape. This minimum is higher than the technical limit of the PVQ process, but at very low rates, allocations make the spectrum excessively sparse, and those bands are better off with no allocation at all ๐Ÿ˜ญ For each coded band, set thresh[band] to 24 times the number of MDCT bins in the band, divided by 16. If 8 times the number of channels is greater, use that instead. This sets the minimum allocation to one bit per channel, or 48 128th bits per MDCT bin, whichever is greater ๐Ÿ’œ The band-size-dependent part of this value isn't scaled by the channel count, because at the very low rates where this limit applies, there will usually be no bits allocated to the side ๐ŸŒธ

Okay bestie, so the previously decoded allocation trim is what gets turned into a per-band adjustment vector called trim_offsets[] โœจ. For each coded band you take alloc_trim, subtract 5 and LM ๐Ÿ’…. Then you multiply that by the number of channels, the number of MDCT bins in the shortest frame size for this mode, the number of remaining bands, 2**LM, and 8 ๐ŸŽ€. Next you divide the whole thing by 64. Finally, if the band only has one MDCT bin per channel, you subtract 8 times the number of channels so the allocation drops by one bit ๐Ÿฆ‹. Width 1 bands get more out of the coarse energy coding anyway, so they're the ones that need the trim ๐Ÿ˜ญ๐Ÿซถ

4.3.4. Shape Decoding ๐Ÿ”ฅ

In each band, the normalized "shape" gets encoded with the Pyramid Vector Quantizer ๐Ÿ”บโœจ

In the simplest version, the number of bits from Section 4.3.3 gets converted into a number of pulses, as described in Section 4.3.4.1 ๐Ÿ’– Once you know the number of pulses and the number of samples in the band, the decoder works out the codebook size like Section 4.3.4.2 explains ๐Ÿงš That size is used to decode an unsigned integer with a uniform probability model, and that integer is the codeword index. The index then becomes its matching vector (also covered in Section 4.3.4.2), and that vector gets scaled to unit norm ๐Ÿ’…

4.3.4.1. Bits to Pulses ๐Ÿ“

Okay so the allocation happens in 1/8th bit units, but quantization needs a whole number of pulses K ๐Ÿ™ˆ The encoder searches for the K that gives a bit count closest to the allocated value (rounding down if it lands exactly halfway between two values), but it can't go over the total bits available ๐Ÿซ  For efficiency, that search uses a precomputed allocation table, which only allows certain K values for each N ๐Ÿ’œ The codebook entry count can be worked out as explained in Section 4.3.4.2.

The gap between bits allocated and bits actually used gets added to a "balance" that starts at zero, and it helps adjust the allocation for the next bands ๐ŸŒˆ One third of the balance is applied to each band's bit allocation so everything lands near the target ๐ŸŽฏ The only exceptions are the band before the last and the last band. Those get half the balance and the whole balance, respectively ๐Ÿ‘‘

4.3.4.2. PVQ Decoding โœจ

Decoding of PVQ vectors is implemented in decode_pulses() (cwrs.c) ๐Ÿฆ‹ The unique codeword index is decoded as a uniformly distributed integer between 0 and V(N,K)-1, where V(N,K) is the number of possible combinations of K pulses in N samples ๐Ÿ’– The index then gets turned into a vector in the same way [PVQ] specifies. The indexing relies on calculating V(N,K), which [PVQ] calls N(L,K) ๐Ÿง 

The count can be computed recursively as V(N,K) = V(N-1,K) + V(N,K-1) + V(N-1,K-1), with V(N,0) = 1 and V(0,K) = 0, K != 0 ๐ŸŒธ There are lots of ways to compute V(N,K): precomputed tables, or using the recursive formula directly. The reference implementation applies the recursion one line (or column) at a time to save memory, uses an alternate univariate recurrence to initialize an arbitrary line, and uses direct polynomial solutions for small N ๐Ÿ”ฅ All of these methods are equivalent, they just trade off speed, memory usage, and code size differently. Implementations MAY use any methods they like, as long as those methods are equivalent to the mathematical definition ๐Ÿซถ

Here's how the decoded vector X gets recovered ๐Ÿ” Let i be the index decoded with the procedure in Section 4.1.5 with ft = V(N,K), so that 0 <= i < V(N,K). Let k = K. Then, for j = 0 to (N - 1), inclusive, do the following:

  1. Let p = (V(N-j-1,k) + V(N-j,k))/2.
  2. If i < p, then let sgn = 1, else let sgn = -1 and set i = i - p.
  3. Let k0 = k and set p = p - V(N-j-1,k).
  4. While p > i, set k = k - 1 and p = p - V(N-j-1,k).
  5. Set X[j] = sgn*(k0 - k) and i = i - p.

After that, the decoded vector X gets normalized so its L2-norm equals one ๐Ÿ’…โœจ

4.3.4.3. Spreading ๐Ÿฆ‹

The normalized vector from Section 4.3.4.2 then gets rotated so it doesn't sound tonal ๐ŸŽถ The rotation gain is equal to:

                       g_r = N / (N + f_r*K)

where N is the number of dimensions, K is the number of pulses, and f_r depends on the "spread" parameter in the bitstream ๐ŸŒˆ

              +--------------+------------------------+
              | Spread value | f_r                    |
              +--------------+------------------------+
              | 0            | infinite (no rotation) |
              |              |                        |
              | 1            | 15                     |
              |              |                        |
              | 2            | 10                     |
              |              |                        |
              | 3            | 5                      |
              +--------------+------------------------+

                     Table 59: Spreading Values

The rotation angle is then calculated as:

                                           2
                                  pi *  g_r
                          theta = ----------
                                      4

A 2-D rotation R(i,j) between points x_i and x_j is defined as:

               x_i' =  cos(theta)*x_i + sin(theta)*x_j
               x_j' = -sin(theta)*x_i + cos(theta)*x_j

An N-D rotation is then done by applying a series of 2-D rotations back and forth, in this order: R(x_1, x_2), R(x_2, x_3), ..., R(x_N-2, X_N-1), R(x_N-1, X_N), R(x_N-2, X_N-1), ..., R(x_1, x_2) ๐Ÿ”„๐Ÿ’œ

If the decoded vector represents more than one time block, this spreading process gets applied separately to each block ๐Ÿซง Also, if each block represents 8 samples or more, another N-D rotation, by (pi/2-theta), gets applied before the rotation above ๐Ÿ™Œ This extra rotation is applied in an interleaved way with a stride equal to round(sqrt(N/nb_blocks)). Basically, it's applied independently to each set of samples S_k = {stride*n + k}, for n=0..N/stride-1 ๐Ÿงš

4.3.4.4. Split Decoding ๐Ÿ“

To avoid needing multi-precision math when decoding PVQ codevectors, the maximum codebook size is 32 bits ๐Ÿ™…โ€โ™€๏ธ When bigger codebooks are needed, the vector gets split into two sub-vectors of size N/2. A quantized gain parameter, with precision derived from the current allocation, is entropy coded to represent the relative gains of each side of the split, and then the whole decoding process runs recursively ๐Ÿ” You can apply multiple levels of splitting, up to a limit of LM+1 splits. The same recursive mechanism is used for joint coding of stereo audio ๐Ÿ’–

4.3.4.5. Time-Frequency Change โฑ๏ธ

The time-frequency (TF) parameters control the time-frequency resolution trade-off in each coded band ๐ŸŒธ Each band has two possible TF choices. For the first band coded, the PDF is {3, 1}/4 for frames marked as transient, and {15, 1}/16 for the other frames. For subsequent bands, the TF choice gets coded relative to the previous TF choice, with probability {15, 1}/16 for transient frames and {31, 1}/32 otherwise. The mapping between the decoded TF choices and the change in TF resolution is shown in the tables below ๐Ÿ“Š

                    +-----------------+---+----+
                    | Frame size (ms) | 0 |  1 |
                    +-----------------+---+----+
                    |       2.5       | 0 | -1 |
                    |                 |   |    |
                    |        5        | 0 | -1 |
                    |                 |   |    |
                    |        10       | 0 | -2 |
                    |                 |   |    |
                    |        20       | 0 | -2 |
                    +-----------------+---+----+

  Table 60: TF Adjustments for Non-transient Frames and tf_select=0
                    +-----------------+---+----+
                    | Frame size (ms) | 0 |  1 |
                    +-----------------+---+----+
                    |       2.5       | 0 | -1 |
                    |                 |   |    |
                    |        5        | 0 | -2 |
                    |                 |   |    |
                    |        10       | 0 | -3 |
                    |                 |   |    |
                    |        20       | 0 | -3 |
                    +-----------------+---+----+

  Table 61: TF Adjustments for Non-transient Frames and tf_select=1
                    +-----------------+---+----+
                    | Frame size (ms) | 0 |  1 |
                    +-----------------+---+----+
                    |       2.5       | 0 | -1 |
                    |                 |   |    |
                    |        5        | 1 |  0 |
                    |                 |   |    |
                    |        10       | 2 |  0 |
                    |                 |   |    |
                    |        20       | 3 |  0 |
                    +-----------------+---+----+

   Table 62: TF Adjustments for Transient Frames and tf_select=0
                    +-----------------+---+----+
                    | Frame size (ms) | 0 |  1 |
                    +-----------------+---+----+
                    |       2.5       | 0 | -1 |
                    |                 |   |    |
                    |        5        | 1 | -1 |
                    |                 |   |    |
                    |        10       | 1 | -1 |
                    |                 |   |    |
                    |        20       | 1 | -1 |
                    +-----------------+---+----+

   Table 63: TF Adjustments for Transient Frames and tf_select=1

A negative TF adjustment means the temporal resolution goes up, while a positive one means the frequency resolution goes up ๐Ÿ•ฐ๏ธ๐ŸŽผ Changes in TF resolution are done with the Hadamard transform [HADAMARD] ๐Ÿงฎ To increase time resolution by N, N "levels" of the Hadamard transform get applied to the decoded vector for each interleaved MDCT vector. To increase frequency resolution (which assumes a transient frame), N levels of the Hadamard transform get applied across the interleaved MDCT vector instead โœจ When time resolution goes up, the decoder uses "sequency order", because the input vector is sorted in time ๐Ÿ‘‘

4.3.5. Anti-collapse Processing ๐Ÿ›ก๏ธ

Anti-collapse exists to stop the situation where using multiple short MDCTs leaves one or more of them with zero energy in some bands, which sounds gross ๐Ÿคข When the frame has the transient bit set, an anti-collapse bit gets decoded. When anti-collapse is set, the energy in each small MDCT is kept from collapsing to zero. For each band of each MDCT where a collapse is detected, a pseudo-random signal gets inserted with an energy matching the minimum energy over the two previous frames ๐ŸŽฒ A renormalization step is then required so the anti-collapse step doesn't mess up the energy preservation property ๐Ÿซถ

4.3.6. Denormalization ๐ŸŒŸ

Just like each band got normalized in the encoder, the last step in the decoder before the inverse MDCT is to denormalize the bands ๐Ÿ”„ Each decoded normalized band gets multiplied by the square root of the decoded energy. This happens in denormalise_bands() (bands.c) ๐Ÿ’–โœจ


4.3.7. Inverse MDCT โœจ

okay so the inverse MDCT implementation has zero special characteristics, bestie ๐ŸŽ€ you put in N frequency-domain samples and get 2*N time-domain samples out, while scaling by 1/2. the low-overlap window is the main character here ๐Ÿ’… it reduces the algorithmic delay, and it's built from a basic (full-overlap) 240-sample version of the window used by the Vorbis codec ๐Ÿฆ‹

                                                     2
                      /   /pi      /pi   n + 1/2\ \ \
               W(n) = |sin|-- * sin|-- * -------| | |
                      \   \2       \2       L   / / /

the low-overlap window gets made by zero-padding the basic window and inserting ones in the middle, so the result still satisfies power complementarity [PRINCEN86] โœจ it's giving math that just works. the IMDCT and windowing both happen in mdct_backward (mdct.c) ๐Ÿงš

4.3.7.1. Post-Filter

the output of the inverse MDCT (after weighted overlap-add) gets sent to the post-filter ๐ŸŒธ even though the post-filter runs at the very end, its parameters are encoded at the very beginning, right after the silence flag. so iconic ๐Ÿ˜ญ the post-filter can be switched on or off with one bit (logp=1). if it's enabled, the octave is decoded as an integer from 0 to 6 with uniform probability, and then the fine pitch within that octave is decoded using 4+octave raw bits ๐Ÿ’– the final pitch period is (16<<octave)+fine_pitch-1, which means it's bounded between 15 and 1022, inclusively ๐ŸŒˆ next up, the gain is decoded as three raw bits and equals G=3*(int_gain+1)/32. the set of post-filter taps is decoded last, using a pdf of {2, 1, 1}/4 ๐Ÿ“

tapset zero uses the filter coefficients g0 = 0.3066406250, g1 = 0.2170410156, g2 = 0.1296386719. tapset one uses g0 = 0.4638671875, g1 = 0.2680664062, g2 = 0. and tapset two uses g0 = 0.7998046875, g1 = 0.1000976562, g2 = 0 ๐Ÿซถ

the post-filter response gets computed like this:

          y(n) = x(n) + G*(g0*y(n-T) + g1*(y(n-T+1)+y(n-T+1))
                                     + g2*(y(n-T+2)+y(n-T+2)))

during a transition between different gains, a smooth transition is calculated using the square of the MDCT window ๐Ÿฆ‹ and this part is important: the values of y(n) have to be interpolated one at a time, so that the past value of y(n) being used is the interpolated one ๐Ÿ‘‘

4.3.7.2. De-emphasis

after the post-filter, the signal gets de-emphasized using the inverse of the pre-emphasis filter the encoder used ๐Ÿง the vibe is basically undoing what the encoder did, just like a good glow-up reversal โœจ

                          1            1
                         ---- = ---------------
                         A(z)                -1
                                1 - alpha_p*z

where alpha_p=0.8500061035 ๐Ÿ’…

4.4. Packet Loss Concealment (PLC)

Packet Loss Concealment (PLC) is an optional decoder-side feature that SHOULD be included when you're receiving from an unreliable channel ๐Ÿซถ bestie, PLC isn't part of the bitstream, so there are tons of valid ways to implement it, each with its own complexity/quality trade-offs ๐ŸŒˆ

the PLC in the reference implementation depends on the mode of the last packet received ๐Ÿงš in CELT mode, the PLC finds a periodicity in the decoded signal and repeats the windowed waveform using the pitch offset. the windowed waveform gets overlapped in a way that preserves the time-domain aliasing cancellation with the previous frame and the next frame, which is giving careful engineering ๐Ÿ˜ญ this happens in celt_decode_lost() (mdct.c). in SILK mode, the PLC uses LPC extrapolation from the previous frame, implemented in silk_PLC() (PLC.c) ๐Ÿ’œ

4.4.1. Clock Drift Compensation

okay so clock drift is the gradual desynchronization of two endpoints whose sample clocks run at different frequencies while they're streaming live audio ๐Ÿ•ฐ๏ธ the differences usually come from manufacturing variation in the endpoints' clock hardware. for long-lived streams, the time difference between sender and receiver can grow without bound ๐Ÿ’€

when the sender's clock runs slower than the receiver's, it's kinda like packet loss, because too few packets get received ๐Ÿ™ˆ the receiver can tell drift and loss apart if the transport provides packet timestamps ๐ŸŽ€ a receiver for live streams SHOULD conceal the effects of drift, and it MAY do that by invoking the PLC โœจ

when the sender's clock runs faster than the receiver's, too many packets arrive ๐Ÿ˜ญ the receiver MAY respond by skipping any packet (i.e., not submitting the packet for decoding). this is likely to produce a less severe artifact than dropping the frame after decoding it, so it's the lesser evil ๐ŸŒธ

a decoder MAY employ a more sophisticated drift compensation method ๐Ÿ‘‘ for example, the NetEQ component [GOOGLE-NETEQ] of the Google WebRTC codebase [GOOGLE-WEBRTC] compensates for drift by adding or removing one period when the signal is highly periodic. the reference implementation of Opus lets a caller learn whether the current frame's signal is highly periodic, and if so, what the period is, using the OPUS_GET_PITCH() request ๐Ÿงš

4.5. Configuration Switching

switching between Opus coding modes, audio bandwidths, and channel counts needs careful thought so you don't get audible glitches ๐Ÿซ  switching between any two configurations of the CELT-only mode, any two configurations of the Hybrid mode, or from WB SILK to Hybrid mode doesn't need any special treatment in the decoder, because the MDCT overlap smooths the transition for you ๐Ÿฆ‹ switching from Hybrid mode to WB SILK means adding the final contents of the CELT overlap buffer to the first SILK-only packet. you can do that by decoding a 2.5 ms silence frame with the CELT decoder, using the channel count of the SILK-only packet (and any choice of audio bandwidth), which correctly handles the cases where the channel count changes too ๐Ÿ’–

when you change the channel count for SILK-only or Hybrid packets, the encoder can avoid glitches by smoothly varying the stereo width of the input signal before or after the transition, and it SHOULD do so โœจ other transitions, though, like between SILK-only packets or between NB or MB SILK and Hybrid packets, may cause glitches, because neither the LSF coefficients nor the LTP, LPC, stereo unmixing, and resampler buffers are available at the new sample rate ๐Ÿ˜ญ these switches SHOULD be delayed by the encoder until quiet periods or transients, where the unavoidable glitches are less audible ๐ŸŒ™ additionally, the bitstream MAY include redundant side information ("redundancy"), in the form of additional CELT frames embedded in each of the Opus frames around the transition ๐Ÿ“

the other transitions that are hard to handle are the ones where the lower frequencies switch between the SILK LP-based model and the CELT MDCT model ๐ŸŒˆ the encoder might not get a chance to delay that kind of switch, though. say the content goes from speech to music and the encoder doesn't have enough latency in its analysis to spot it ahead of time. then there might not be a convenient silence period for quite some time ๐Ÿ’€ to avoid or reduce glitches during these problematic mode transitions, and between audio bandwidth changes in the SILK-only modes, transitions MAY include redundant side information ("redundancy"), in the form of an additional CELT frame embedded in the Opus frame ๐Ÿซถ

a transition between coding the lower frequencies with the LP model and the MDCT model, or a transition that involves changing the SILK bandwidth, is only normatively specified when it includes redundancy ๐Ÿ‘‘ for those without redundancy, it is RECOMMENDED that the decoder use a concealment technique (e.g., make use of a PLC algorithm) to "fill in" the gap or discontinuity caused by the mode transition ๐Ÿงš so, PLC MUST NOT be applied during any normative transition, i.e., when:

  • A packet includes redundancy for this transition (as described below),
  • The transition is between any WB SILK packet and any Hybrid packet, or vice versa,
  • The transition is between any two Hybrid mode packets, or
  • The transition is between any two CELT mode packets,

unless there is actual packet loss ๐Ÿ™ˆ

4.5.1. Transition Side Information (Redundancy)

transitions with side information include an extra 5 ms "redundant" CELT frame within the Opus frame ๐ŸŽ€ this frame is designed to fill in the gap or discontinuity between the different layers without making the decoder conceal it, which is giving efficiency โœจ for transitions from CELT-only to SILK-only or Hybrid, the redundant frame goes in the first Opus frame after the transition (i.e., the first SILK-only or Hybrid frame). for transitions from SILK-only or Hybrid to CELT-only, the redundant frame goes in the last Opus frame before the transition (i.e., the last SILK-only or Hybrid frame) ๐Ÿฆ‹

4.5.1.1. Redundancy Flag

the presence of redundancy is signaled in all SILK-only and Hybrid frames, not just the ones involved in a mode transition ๐Ÿ’… this lets the frames decode correctly even if an adjacent frame gets lost ๐Ÿซถ for SILK-only frames, this signaling is implicit, based on the size of the Opus frame and the number of bits consumed while decoding the SILK portion of it. after decoding the SILK portion, the decoder uses ec_tell() (see Section 4.1.6.1) to check whether there are at least 17 bits remaining. if so, the frame contains redundancy ๐ŸŒธ

for Hybrid frames, the signaling is explicit ๐Ÿ“ after decoding the SILK portion of the Opus frame, the decoder uses ec_tell() (see Section 4.1.6.1) to make sure there are at least 37 bits remaining. if so, it reads a symbol with the PDF in Table 64, and if the value is 1, then the frame contains redundancy. otherwise (if there were fewer than 37 bits left or the value was 0), the frame does not contain redundancy ๐Ÿ’œ

                          +----------------+
                          | PDF            |
                          +----------------+
                          | {4095, 1}/4096 |
                          +----------------+

                     Table 64: Redundancy Flag PDF

4.5.1.2. Redundancy Position Flag

since the current frame is a SILK-only or a Hybrid frame, it must be at least 10 ms ๐Ÿงš so it needs an extra flag to say whether the redundant 5 ms CELT frame should be mixed into the beginning of the current frame, or the end ๐ŸŒˆ after the decoder figures out that a frame contains redundancy, it reads a 1 bit symbol with a uniform PDF (Table 65) โœจ

                             +----------+
                             | PDF      |
                             +----------+
                             | {1, 1}/2 |
                             +----------+

                   Table 65: Redundancy Position PDF

if the value is zero, this is the first frame in the transition, and the redundancy belongs at the end ๐Ÿฆ‹ if the value is one, this is the second frame in the transition, and the redundancy belongs at the beginning ๐Ÿ’– there is no way to specify that an Opus frame contains separate redundant CELT frames at both the beginning and the end ๐Ÿ˜ญ

4.5.1.3. Redundancy Size

Okay so, the redundant CELT frame is not like the CELT part of a Hybrid frame ๐Ÿ™…โ€โ™€๏ธ. It doesn't share the same entropy coder state as the rest of the Opus frame, because that would totally wreck the CELT bit allocation mechanism in Hybrid frames ๐Ÿ’€. So a redundant CELT frame always starts and ends on a byte boundary โœจ, even in SILK-only frames where that isn't strictly necessary.

For SILK-only frames, the size is just the number of whole bytes left in the frame, and it must be at least 2 (thanks to the space check in Section 4.5.1.1) ๐ŸŽ€. For Hybrid frames, the size is 2 plus a decoded unsigned integer less than 256 (see Section 4.1.5) ๐Ÿฆ‹. This can be more than the number of whole bytes left in the Opus frame, and if it is, the frame is invalid ๐Ÿ˜ญ. BUT a decoder is not required to toss the whole frame, since this could just be a bit error that desynchronized the range coder. There may still be useful data before the error, so a decoder MAY keep any audio it has decoded so far instead of invoking the PLC. Still, it is RECOMMENDED that the decoder stop decoding and discard the rest of the current Opus frame ๐Ÿซถ.

It would have been possible to avoid these invalid states by limiting the range of the explicit length decoded from Hybrid frames to the actual number of whole bytes remaining. The catch is that this would force an encoder to figure out the rate allocation for the MDCT layer up front, before it even starts encoding that layer ๐Ÿ™ˆ. By allowing some invalid sizes, the encoder can put that decision off until much later, which is so smart ๐Ÿง โœจ. When encoding Hybrid frames that don't include redundancy, the encoder must still decide up front whether it wants to use the minimum 37 bits required to trigger encoding of the redundancy flag, but that's a much looser restriction ๐ŸŒธ.

After working out the size of the redundant CELT frame, the decoder shrinks the buffer the range coder is currently using by that amount. The MDCT layer reads any raw bits from the end of this smaller buffer, and every calculation of the number of bits remaining has to use this new, reduced size, not the original size of the Opus frame ๐Ÿ’….

4.5.1.4. Decoding the Redundancy

The redundant frame gets decoded just like any other CELT-only frame, with one twist: it doesn't have a TOC byte ๐Ÿงš. Its frame size is fixed at 5 ms, its channel count matches the current frame, and its audio bandwidth matches the current frame too, except that for MB SILK frames it gets set to WB ๐ŸŒˆ.

If the redundancy goes at the beginning (in a CELT-only to SILK-only or Hybrid transition), the final output uses the first 2.5 ms of audio the decoder made for the redundant frame exactly as it is, and throws away the matching output from the SILK-only or Hybrid part of the frame ๐Ÿช„. The remaining 2.5 ms gets cross-lapped with the decoded SILK/Hybrid signal using CELT's power-complementary MDCT window, so the transition is smooth and seamless ๐Ÿฆ‹๐Ÿ’–.

If the redundancy goes at the end (in a SILK-only or Hybrid to CELT-only transition), only the second half (2.5 ms) of the audio the decoder made for the redundant frame gets used ๐Ÿ“. In that case, that second half is cross-lapped with the end of the SILK/Hybrid signal, again using CELT's power-complementary MDCT window to keep things smooth ๐Ÿ’œ.

4.5.2. State Reset

Sometimes, when a transition happens, the SILK decoder, the CELT decoder, or both need a reset before decoding a frame in the new mode ๐Ÿ”„. This stops them from reusing "out of date" memory, which might not have been updated in a while or might not be in a well-defined state because of things like PLC ๐Ÿ™ˆ. The SILK state gets reset before every SILK-only or Hybrid frame where the previous frame was CELT-only. The CELT state gets reset every time the operating mode changes and the new mode is either Hybrid or CELT-only, EXCEPT when the transition uses redundancy as described above ๐Ÿ‘‘.

When switching from SILK-only or Hybrid to CELT-only with redundancy, the CELT state gets reset before the redundant CELT frame embedded in the SILK-only or Hybrid frame is decoded, but it is NOT reset before decoding the following CELT-only frame โœจ. When switching from CELT-only mode to SILK-only or Hybrid mode with redundancy, the CELT decoder is not reset for decoding the redundant CELT frame ๐Ÿ’….

4.5.3. Summary of Transitions

Figure 18 shows all of the normative transitions that involve a mode change, an audio bandwidth change, or both ๐Ÿ“Š. Each one uses an S, H, or C to stand for an Opus frame in the matching mode ๐ŸŽ€. An R shows that there's redundancy in the Opus frame it's cross-lapped with ๐Ÿฆ‹. Where it sits, in the first or last 5 ms, is assumed to match whether it's the frame before or after the transition ๐Ÿซถ. Other uses of redundancy are non-normative ๐Ÿ’€. Last but not least, a c shows what's in the CELT overlap buffer after the previously decoded frame (aka what you get by decoding a silence frame) ๐Ÿงš.

    SILK to SILK with Redundancy:             S -> S -> S
                                                        &
                                                       !R -> R
                                                             &
                                                            ;S -> S -> S

    NB or MB SILK to Hybrid with Redundancy:  S -> S -> S
                                                        &
                                                       !R ->;H -> H -> H

    WB SILK to Hybrid:                        S -> S -> S ->!H -> H -> H

    SILK to CELT with Redundancy:             S -> S -> S
                                                        &
                                                       !R -> C -> C -> C

    Hybrid to NB or MB SILK with Redundancy:  H -> H -> H
                                                        &
                                                       !R -> R
                                                             &
                                                            ;S -> S -> S

    Hybrid to WB SILK:                        H -> H -> H -> c
                                                          \  +
                                                           > S -> S -> S

    Hybrid to CELT with Redundancy:           H -> H -> H
                                                        &
                                                       !R -> C -> C -> C

    CELT to SILK with Redundancy:             C -> C -> C -> R
                                                             &
                                                            ;S -> S -> S

    CELT to Hybrid with Redundancy:           C -> C -> C -> R
                                                             &
                                                            |H -> H -> H

    Key:
    S   SILK-only frame                 ;   SILK decoder reset
    H   Hybrid frame                    |   CELT and SILK decoder resets
    C   CELT-only frame                 !   CELT decoder reset
    c   CELT overlap                    +   Direct mixing
    R   Redundant CELT frame            &   Windowed cross-lap

                     Figure 18: Normative Transitions

The first two and the last two Opus frames in each example are just for illustration ๐ŸŒท. There's no requirement that a stream stay in the same configuration for three consecutive frames before or after a switch ๐Ÿ’–.

The behavior of transitions without redundancy where PLC is allowed is non-normative ๐ŸŒ™. An encoder might still want to use these transitions if, say, it doesn't want to pay the extra bitrate that redundancy costs, or if it decides to switch after it has already sent the frame that would have had to hold the redundancy ๐Ÿคทโ€โ™€๏ธ. Figure 19 shows the recommended cross-lapping and decoder resets for these transitions ๐ŸŒธ.

    SILK to SILK (audio bandwidth change):    S -> S -> S   ;S -> S -> S

    NB or MB SILK to Hybrid:                  S -> S -> S   |H -> H -> H

    SILK to CELT without Redundancy:          S -> S -> S -> P
                                                             &
                                                            !C -> C -> C

    Hybrid to NB or MB SILK:                  H -> H -> H -> c
                                                             +
                                                            ;S -> S -> S

    Hybrid to CELT without Redundancy:        H -> H -> H -> P
                                                             &
                                                            !C -> C -> C

    CELT to SILK without Redundancy:          C -> C -> C -> P
                                                             &
                                                            ;S -> S -> S

    CELT to Hybrid without Redundancy:        C -> C -> C -> P
                                                             &
                                                            |H -> H -> H

    Key:
    S   SILK-only frame                 ;   SILK decoder reset
    H   Hybrid frame                    |   CELT and SILK decoder resets
    C   CELT-only frame                 !   CELT decoder reset
    c   CELT overlap                    +   Direct mixing
    P   Packet Loss Concealment         &   Windowed cross-lap

             Figure 19: Recommended Non-Normative Transitions
Encoders SHOULD NOT use other transitions, e.g., those that involve redundancy in ways not illustrated in Figure 18. ๐Ÿšซ๐Ÿ’…

5. Opus Encoder ๐ŸŽ€

okay so the encoder is literally the other half of the Opus duo ๐Ÿ’– just like the decoder, it normally has two main blocks: the SILK encoder and the CELT encoder. but here's the tea: a valid (though potentially suboptimal) Opus encoder is not required to support all modes, so it can totally just include a SILK encoder module or a CELT encoder module ๐Ÿซถ the output bitstream has bits from both SILK and CELT, but you can't pull them apart because of the range coder. it's giving tightly packed ๐Ÿ“ฆโœจ here's the block diagram:

                    +------------+    +---------+
                    |   Sample   |    |  SILK   |------+
                 +->|    Rate    |--->| Encoder |      V
  +-----------+  |  | Conversion |    |         | +---------+
  | Optional  |  |  +------------+    +---------+ |  Range  |
->| High-pass |--+                                | Encoder |---->
  |  Filter   |  |  +--------------+  +---------+ |         | Bit-
  +-----------+  |  |    Delay     |  |  CELT   | +---------+ stream
                 +->| Compensation |->| Encoder |      ^
                    |              |  |         |------+
                    +--------------+  +---------+

                      Figure 20: Opus Encoder

for a normal encoder with both the SILK and CELT modules, an optimal encoder should pick its coding mode at run-time based on the conditions ๐ŸŒธ in the reference implementation, the application picks the frame size, but the other config stuff (number of channels, bandwidth, mode) gets auto-selected (unless the application explicitly overrides it) depending on:

  • Requested bitrate
  • Input sampling rate
  • Type of signal (speech vs. music)
  • Frame size in use

the type of signal currently has to be provided by the application (though it can change in real-time) โœจ an encoder could do automatic detection, but since Opus is an interactive codec, that would likely mean either delaying the signal (for non-interactive apps) or delaying the mode switching decisions (for interactive apps) ๐Ÿ™ˆ so it's a whole trade-off, bestie.

when the encoder is set up for voice over IP apps, the input gets run through a high-pass filter to cut the lowest part of the spectrum, which has little speech energy and may contain background noise ๐Ÿงš it's a second order Auto Regressive Moving Average (i.e., with poles and zeros) filter with a cut-off frequency around 50 Hz. in the future, a music detector may also be used to lower the cut-off frequency when the input is detected to be music rather than speech ๐ŸŽถ


5.1. Range Encoder

the range coder is the bit-packer for Opus, and it's used in three different ways ๐Ÿ’… to encode:

  • Entropy-coded symbols with a fixed probability model using ec_encode() (entenc.c),
  • Integers from 0 to (2**M - 1) using ec_enc_uint() or ec_enc_bits() (entenc.c),
  • Integers from 0 to (ft - 1) (where ft is not a power of two) using ec_enc_uint() (entenc.c).

the range encoder keeps an internal state vector made of the four-tuple (val, rng, rem, ext) ๐Ÿฆ‹ that's the low end of the current range, the size of the current range, a single buffered output byte, and a count of additional carry-propagating output bytes. both val and rng are 32-bit unsigned integers, rem is a byte value less than 255 or the special value -1, and ext is an unsigned integer with at least 11 bits. this state vector gets initialized at the start of each frame to (0, 2**31, -1, 0). after encoding a sequence of symbols, the value of rng in the encoder should exactly match the value of rng in the decoder after decoding the same symbols. this is a powerful tool for catching errors in either an encoder or decoder implementation ๐Ÿ˜ญ the value of val, on the other hand, means different things in the encoder and decoder, so it isn't expected to match.

the decoder has no analog for rem and ext. they're used for carry propagation in the renormalization loop below ๐ŸŒˆ each iteration of that loop produces 9 bits of output: 8 data bits and a carry flag. the encoder can't figure out the final value of the output bytes until it propagates those carry flags, so the reference implementation buffers a single non-propagating output byte (i.e., one less than 255) in rem, and keeps a count of additional propagating (i.e., 255) output bytes in ext. an implementation may choose any mathematically equivalent scheme for carry propagation ๐Ÿ’œ

5.1.1. Encoding Symbols

the main encoding function is ec_encode() (entenc.c). it encodes symbol k in the current context using the same three-tuple (fl[k], fh[k], ft) as the decoder, which describes the range of the symbol (see Section 4.1) โœจ

ec_encode() updates the encoder state like this. if fl[k] is greater than zero, then

                                   rng
                 val = val + rng - --- * (ft - fl)
                                   ft

                       rng
                 rng = --- * (fh - fl)
                       ft

otherwise, val is unchanged and

                                rng
                    rng = rng - --- * (fh - fl)
                                ft

the divisions here are integer division ๐Ÿงฎ

5.1.1.1. Renormalization

after that update, the range gets normalized using a procedure very similar to the one in Section 4.1.2.1, implemented by ec_enc_normalize() (entenc.c) ๐Ÿ”ฅ the following process repeats until rng > 2**23. first, the top 9 bits of val, (val>>23), get sent to the carry buffer (described in Section 5.1.1.2). then the encoder sets

                    val = (val<<8) & 0x7FFFFFFF

                    rng = rng<<8

5.1.1.2. Carry Propagation and Output Buffering

the function ec_enc_carry_out() (entenc.c) handles carry propagation and output buffering ๐Ÿ’– it takes in a 9-bit unsigned value, c, made of 8 data bits and an extra carry bit. if c equals 255, then ext is just incremented and no other state updates happen. otherwise, let b = (c>>8) be the carry bit. then:

  • If the buffered byte rem contains a value other than -1, the encoder outputs the byte (rem + b). Otherwise, if rem is -1, no byte is output.
  • If ext is non-zero, then the encoder outputs ext bytes (all with a value of 0 if b is set, or 255 if b is unset) and sets ext to 0.
  • rem is set to the 8 data bits:
                           rem = c & 255

5.1.2. Alternate Encoding Methods

the reference implementation uses three more encoding methods that are exactly equivalent to the above, but they make some assumptions and simplifications that allow a more efficient implementation ๐Ÿš€

5.1.2.1. ec_encode_bin()

the first is ec_encode_bin() (entenc.c), defined with the parameter ftb instead of ft. it's mathematically equivalent to calling ec_encode() with ft = (1<<ftb), but it skips the division ๐Ÿ™Œ

5.1.2.2. ec_enc_bit_logp()

next up is ec_enc_bit_logp() (entenc.c), which encodes a single binary symbol. the context is described by one parameter, logp, which is the absolute value of the base-2 logarithm of the probability of a "1". it's mathematically equivalent to calling ec_encode() with the 3-tuple (fl[k] = 0, fh[k] = (1<<logp) - 1, ft = (1<<logp)) if k is 0, and with (fl[k] = (1<<logp) - 1, fh[k] = ft = (1<<logp)) if k is 1. the implementation needs no multiplications or divisions ๐Ÿฆ‹

5.1.2.3. ec_enc_icdf()

the last one is ec_enc_icdf() (entenc.c), which encodes a single binary symbol with a table-based context of up to 8 bits ๐Ÿงš it uses the same icdf table as ec_dec_icdf() from Section 4.1.3.3. the function is mathematically equivalent to calling ec_encode() with fl[k] = (1<<ftb) - icdf[k-1] (or 0 if k == 0), fh[k] = (1<<ftb) - icdf[k], and ft = (1<<ftb). it only saves a few arithmetic operations over ec_encode_bin(), but it lets the encoder use the same icdf tables as the decoder ๐Ÿซถ

5.1.3. Encoding Raw Bits

the raw bits used by the CELT layer get packed at the end of the buffer using ec_enc_bits() (entenc.c) ๐Ÿ“ฆ the raw bits might continue into the last byte the range coder outputs if there's room in the low-order bits, so the encoder has to be ready to merge these values into a single byte. the procedure in Section 5.1.5 does this in a way that makes sure both the range coded data and the raw bits can be decoded successfully ๐ŸŒธ

5.1.4. Encoding Uniformly Distributed Integers

the function ec_enc_uint() (entenc.c) encodes one of ft equiprobable symbols in the range 0 to (ft - 1), inclusive, each with a frequency of 1, where ft may be as large as (2**32 - 1) ๐Ÿ“ like the decoder (see Section 4.1.5), it splits the value up into a range coded symbol for up to 8 of the high bits and, if necessary, raw bits for the remainder.

ec_enc_uint() takes a two-tuple (t, ft), where t is the unsigned integer to be encoded, 0 <= t < ft, and ft isn't necessarily a power of two. let ftb = ilog(ft - 1), i.e., the number of bits needed to store (ft - 1) in two's complement notation. if ftb is 8 or less, then t is encoded directly using ec_encode() with the three-tuple (t, t + 1, ft) โœจ

if ftb is greater than 8, then the top 8 bits of t are encoded using the three-tuple (t>>(ftb - 8), (t>>(ftb - 8)) + 1, ((ft - 1)>>(ftb - 8)) + 1), and the remaining bits, (t & ((1<<(ftb - 8)) - 1)), are encoded as raw bits with ec_enc_bits() ๐Ÿ’…

5.1.5. Finalizing the Stream

once all the symbols are encoded, the stream has to be finalized by outputting a value inside the current range ๐ŸŽ€ let end be the unsigned integer in the interval [val, val + rng) with the largest number of trailing zero bits, b, such that (end + (1<<b) - 1) is also in the interval [val, val + rng). this choice of end lets the maximum number of trailing bits be set to arbitrary values while still making sure the range coded part of the buffer can be decoded correctly ๐Ÿ™ˆ

then, while end is not zero, the top 9 bits of end, i.e., (end>>23), are passed to the carry buffer following the procedure in Section 5.1.1.2, and end gets updated via

                    end = (end<<8) & 0x7FFFFFFF

finally, if the buffered output byte, rem, is neither zero nor the special value -1, or the carry count, ext, is greater than zero, then 9 zero bits are sent to the carry buffer to flush it to the output buffer ๐ŸŒˆ when outputting the final byte from the range coder, if it would overlap any raw bits already packed into the end of the output buffer, they should be ORed into the same byte. the bit allocation routines in the CELT layer should make sure this can be done without corrupting the range coder data, as long as end is chosen as described above ๐Ÿ”ฅ if there's any space between the end of the range coder data and the end of the raw bits, it gets padded with zero bits. this whole process is implemented by ec_enc_done() (entenc.c) ๐Ÿ‘‘

5.1.6. Current Bit Usage ๐Ÿงฎ

okay bestie, the Opus bit allocation routines need to know a conservative upper bound on how many bits have been used for the current frame so far ๐Ÿ“Š. that number drives allocation decisions and makes sure the range coder and raw bits never overflow the output buffer ๐Ÿ™ˆ. in the reference implementation it's computed to whole-bit precision by ec_tell() (in entcode.h) and to fractional 1/8th bit precision by ec_tell_frac() (in entcode.c) โœจ. like every range coder operation, this has to be bit-exact, and it must return exactly the same value as the same functions in the decoder after it decodes the same symbols ๐Ÿซถ.

5.2. SILK Encoder ๐ŸŽ€

ngl the SILK encoder is basically a mirror of the SILK decoder from Section 4.2 ๐Ÿชž. the quantization and range coder tables are over there, so this section is all about the big-picture design choices ๐Ÿง . here's the basic module lineup ๐Ÿ‘‡

            +----------+    +--------+    +---------+
            |  Sample  |    | Stereo |    |  SILK   |
     ------>|   Rate   |--->| Mixing |--->|  Core   |---------->
     Input  |Conversion|    |        |    | Encoder |  Bitstream
            +----------+    +--------+    +---------+

                       Figure 21: SILK Encoder

5.2.1. Sample Rate Conversion ๐Ÿฆ‹

the input signal's sampling rate gets adjusted by a sample rate conversion module so it matches the SILK internal sampling rate ๐ŸŽถ. the input to the sample rate converter is delayed by a number of samples that depends on the sample rate ratio, so the overall delay stays constant for all input and output sample rates ๐Ÿ’œ.

5.2.2. Stereo Mixing ๐ŸŒธ

the stereo mixer only runs for stereo input signals ๐Ÿ‘ฏ. it turns a stereo left-right signal into an adaptive mid-side representation โœจ. first it computes non-adaptive mid-side signals as half the sum and difference between left and right ๐Ÿง. then the side signal gets minimized in energy by subtracting a prediction of it based on the mid signal ๐Ÿ“‰. this prediction works really well when the left and right signals have a linear dependency, like an amplitude-panned input signal ๐ŸŽš๏ธ. same as in the decoder, the prediction coefficients get linearly interpolated during the first 8 ms of the frame ๐Ÿช„. the mid signal is always encoded ๐Ÿ’–, but the residual side signal is only encoded if it has sufficient energy compared to the mid signal's energy ๐Ÿ”ฅ. if it doesn't, the mid_only_flag is set and the side signal is skipped ๐Ÿ™ƒ.

the predictor coefficients are coded regardless of whether the side signal is encoded ๐Ÿ’…. for each frame there are two predictor coefficients: one predicts between low-passed mid and side channels, and one predicts between high-passed mid and side channels ๐Ÿงฉ. the low-pass filter is a simple three-tap filter and creates a delay of one sample ๐Ÿ•ฐ๏ธ. the high-pass filtered signal is the difference between the mid signal delayed by one sample and the low-passed signal ๐Ÿชž. instead of explicitly computing the high-passed signal, it's computationally more efficient to transform the prediction coefficients before applying them to the filtered mid signal, like this ๐Ÿง :

               pred(n) = LP(n) * w0 + HP(n) * w1
                       = LP(n) * w0 + (mid(n-1) - LP(n)) * w1
                       = LP(n) * (w0 - w1) + mid(n-1) * w1

where w0 and w1 are the low-pass and high-pass prediction coefficients, mid(n-1) is the mid signal delayed by one sample, LP(n) and HP(n) are the low-passed and high-passed signals, and pred(n) is the prediction signal that gets subtracted from the side signal ๐ŸŒˆ.

5.2.3. SILK Core Encoder ๐Ÿ‘‘

okay this is the core encoder and all its components ๐Ÿซง. to keep things simple, the core encoder is just called the encoder for the rest of this section ๐Ÿ’ซ. an overview is in Figure 22 ๐Ÿ‘€.

                                                                +---+
                             +--------------------------------->|   |
        +---------+          |      +---------+                 |   |
        |Voice    |          |      |LTP      |12               |   |
    +-->|Activity |--+       +----->|Scaling  |-----------+---->|   |
    |   |Detection|3 |       |      |Control  |<--+       |     |   |
    |   +---------+  |       |      +---------+   |       |     |   |
    |                |       |      +---------+   |       |     |   |
    |                |       |      |Gains    |   |       |     |   |
    |                |       |  +-->|Processor|---|---+---|---->| R |
    |                |       |  |   |         |11 |   |   |     | a |
    |               \/       |  |   +---------+   |   |   |     | n |
    |          +---------+   |  |   +---------+   |   |   |     | g |
    |          |Pitch    |   |  |   |LSF      |   |   |   |     | e |
    |       +->|Analysis |---+  |   |Quantizer|---|---|---|---->|   |
    |       |  |         |4  |  |   |         |8  |   |   |     | E |-->
    |       |  +---------+   |  |   +---------+   |   |   |     | n | 2
    |       |                |  |    9/\  10|     |   |   |     | c |
    |       |                |  |     |    \/     |   |   |     | o |
    |       |  +---------+   |  |   +----------+  |   |   |     | d |
    |       |  |Noise    |   +--|-->|Prediction|--+---|---|---->| e |
    |       +->|Shaping  |---|--+   |Analysis  |7 |   |   |     | r |
    |       |  |Analysis |5  |  |   |          |  |   |   |     |   |
    |       |  +---------+   |  |   +----------+  |   |   |     |   |
    |       |                |  |        /\       |   |   |     |   |
    |       |     +----------|--|--------+        |   |   |     |   |
    |       |     |         \/  \/               \/  \/  \/     |   |
    |       |     |      +----------+          +------------+   |   |
    |       |     |      |          |          |Noise       |   |   |
   -+-------+-----+----->|Pre-filter|--------->|Shaping     |-->|   |
   1                     |          | 6        |Quantization|13 |   |
                         +----------+          +------------+   +---+

   1:  Input speech signal
   2:  Range encoded bitstream
   3:  Voice activity estimate
   4:  Pitch lags (per 5 ms) and voicing decision (per 20 ms)
   5:  Noise shaping quantization coefficients
     - Short-term synthesis and analysis
       noise shaping coefficients (per 5 ms)

     - Long-term synthesis and analysis noise
       shaping coefficients (per 5 ms and for voiced speech only)
     - Noise shaping tilt (per 5 ms)
     - Quantizer gain/step size (per 5 ms)
   6:  Input signal filtered with analysis noise shaping filters
   7:  Short- and Long-Term Prediction coefficients
       LTP (per 5 ms) and LPC (per 20 ms)
   8:  LSF quantization indices
   9:  LSF coefficients
   10: Quantized LSF coefficients
   11: Processed gains, and synthesis noise shape coefficients
   12: LTP state scaling coefficient.  Controlling error
       propagation / prediction gain trade-off
   13: Quantized signal

                       Figure 22: SILK Core Encoder

5.2.3.1. Voice Activity Detection ๐ŸŽ™๏ธ

the input signal goes through a Voice Activity Detection (VAD) algorithm to get a measure of voice activity, spectral tilt, and signal-to-noise estimates for each frame ๐Ÿ“ก. the VAD uses a sequence of half-band filterbanks to split the signal into four subbands: 0...Fs/16, Fs/16...Fs/8, Fs/8...Fs/4, and Fs/4...Fs/2, where Fs is the sampling frequency (8, 12, 16, or 24 kHz) ๐ŸŒŠ. the lowest subband, from 0 to Fs/16, gets high-pass filtered with a first-order moving average (MA) filter (with transfer function H(z) = 1-z**(-1)) to reduce the energy at the lowest frequencies ๐Ÿงน. for each frame, the signal energy per subband is computed ๐Ÿ”ข. in each subband, a noise level estimator tracks the background noise level, and a Signal-to-Noise Ratio (SNR) value is computed as the logarithm of the ratio of energy-to-noise level ๐Ÿ“ˆ. using these intermediate variables, the following parameters get calculated for use in other SILK modules ๐Ÿ“:

  • Average SNR. The average of the subband SNR values.
  • Smoothed subband SNRs. Temporally smoothed subband SNR values.
  • Speech activity level. Based on the average SNR and a weighted average of the subband energies.
  • Spectral tilt. A weighted average of the subband SNRs, with positive weights for the low subbands and negative weights for the high subbands.

5.2.3.2. Pitch Analysis โœจ

okay bestie, pitch analysis is where the encoder hunts for the repeating beat in the sound ๐ŸŽต Here's the open loop pitch estimator, which the text points to as Figure 23 ๐Ÿ’…

                                    +--------+  +----------+
                                    |2 x Down|  |Time-     |
                                 +->|sampling|->|Correlator|     |
                                 |  |        |  |          |     |4
                                 |  +--------+  +----------+    \/
                                 |                    | 2    +-------+
                                 |                    |  +-->|Speech |5
       +---------+    +--------+ |                   \/  |   |Type   |->
       |LPC      |    |Down    | |              +----------+ |       |
    +->|Analysis | +->|sample  |-+------------->|Time-     | +-------+
    |  |         | |  |to 8 kHz|                |Correlator|----------->
    |  +---------+ |  +--------+                |__________|          6
    |       |      |                                  |3
    |      \/      |                                 \/
    |  +---------+ |                            +----------+
    |  |Whitening| |                            |Time-     |
   -+->|Filter   |-+--------------------------->|Correlator|----------->
   1   |         |                              |          |          7
       +---------+                              +----------+

   1: Input signal
   2: Lag candidates from stage 1
   3: Lag candidates from stage 2
   4: Correlation threshold
   5: Voiced/unvoiced flag
   6: Pitch correlation
   7: Pitch lags

              Figure 23: Block Diagram of the Pitch Estimator

So the whole vibe here is: the pitch analysis gives you a yes-or-no voiced/unvoiced call ๐Ÿฆ‹ For frames that count as voiced, you get four pitch lags per frame, one for each 5 ms subframe, plus a pitch correlation that tells you how periodic the signal is. Lowkey iconic ๐ŸŒธ

Before any of that, the input gets whitened with a Linear Prediction (LP) whitening filter. Its coefficients come from standard Linear Predictive Coding (LPC) analysis ๐Ÿงš The filter order is 16 for best results, but it drops to 12 for medium complexity and 8 for low complexity modes. Mode-based downgrades, very budget-friendly ๐Ÿ’–

Once it's whitened, the signal gets searched for pitch lags with high time correlation. This is done in three stages so it doesn't melt the CPU ๐Ÿ”ฅ

  • In the first stage, the whitened signal is downsampled from 8 kHz to 4 kHz. The current frame is then correlated against a delayed copy of the signal across a range of lags. The shortest lag is the one for 500 Hz, and the longest is the one for 56 Hz. Big range, very main character ๐Ÿ‘‘
  • The second stage works on an 8 kHz signal, which is downsampled from 12, 16, or 24 kHz. It only measures correlations near the lags that were strong in stage one, so it's not wasting time on the boring ones ๐Ÿ™ˆ The results get a little bias toward short lags. That stops the encoder from locking onto a multiple of the true pitch lag, which would be a real "not meโ€ฆ" moment ๐Ÿ’€ The highest adjusted correlation then gets compared to a threshold that depends on:
    • Whether the previous frame was classified as voiced.
    • The speech activity level.
    • The spectral tilt.

If the threshold is exceeded, the current frame is classified as voiced. The lag with the highest adjusted correlation is saved for the final, highest-precision pitch analysis in stage three โœจ

  • The last stage runs directly on the whitened input signal. It computes time correlations for each of the four subframes separately, in a narrow range around the lag with the highest correlation from stage two. Precision level: maximum ๐ŸŽ€

Honestly the three-stage funnel is so smart: cheap coarse search first, then a bit more care, then the super precise final pass ๐Ÿ˜ญ๐Ÿซถ

5.2.3.3. Noise Shaping Analysis โœจ

okay so the noise shaping analysis is where the encoder figures out the gains and filter coefficients for the pre-filter and noise shaping quantizer ๐ŸŽ€ and they have to fulfill a few requirements, bestie ๐Ÿ’…

  • Balancing quantization noise and bitrate. The quantization gains set the step size between reconstruction levels of the excitation signal. So increasing the quantization gain amplifies quantization noise, but it also reduces the bitrate by lowering the entropy of the quantization indices ๐Ÿ“‰
  • Spectral shaping of the quantization noise. The noise shaping quantizer can reduce quantization noise in some parts of the spectrum at the cost of more noise in other parts, without substantially changing the bitrate โœจ By shaping the noise so it follows the signal spectrum, it becomes less audible ๐Ÿฆ‹ In practice, the best results come from making the shape of the noise spectrum slightly flatter than the signal spectrum ๐Ÿ’–
  • De-emphasizing spectral valleys. By using different coefficients in the analysis and synthesis part of the pre-filter and noise shaping quantizer, the levels of the spectral valleys can be decreased relative to the levels of the spectral peaks, like speech formants and harmonics ๐ŸŒˆ This reduces the entropy of the signal, which is the difference between the coded signal and the quantization noise, so the bitrate goes down too ๐Ÿ“‰
  • Matching the levels of the decoded speech formants to the levels of the original speech formants. An adjustment gain and a first order tilt coefficient are computed to compensate for the effect the noise shaping quantization has on the level and spectral tilt ๐Ÿงš

Here's the vibe check, Figure 24 ๐ŸŒธ

                 / \   ___
                  |   // \\
                  |  //   \\     ____
                  |_//     \\___//  \\         ____
                  | /  ___  \   /    \\       //  \\
                P |/  /   \  \_/      \\_____//    \\
                o |  /     \     ____  \     /      \\
                w | /       \___/    \  \___/  ____  \\___ 1
                e |/                  \       /    \  \
                r |                    \_____/      \  \__ 2
                  |                                  \
                  |                                   \___ 3
                  |
                  +---------------------------------------->
                                   Frequency

               1: Input signal spectrum
               2: De-emphasized and level matched spectrum
               3: Quantization noise spectrum

      Figure 24: Noise Shaping and Spectral De-emphasis Illustration

so Figure 24 shows an example of an input signal spectrum (1) ๐Ÿ‘‘ after de-emphasis and level matching, the spectrum has deeper valleys (2) ๐Ÿซถ the quantization noise spectrum (3) more or less follows the input signal spectrum, while having slightly less pronounced peaks ๐Ÿ™ˆ the entropy gives a lower bound on the bitrate for encoding the excitation signal, and it is proportional to the area between the de-emphasized spectrum (2) and the quantization noise spectrum (3) ๐Ÿ“Š without de-emphasis, the entropy is proportional to the area between input spectrum (1) and quantization noise (3), which is clearly higher ๐Ÿ˜ญ

the transformation from input signal to de-emphasized signal can be described as a filtering operation with this filter ๐ŸŽ€

                                          -1    Wana(z)
               H(z) = G * ( 1 - c_tilt * z  ) * -------
                                                Wsyn(z)

it has an adjustment gain G, a first order tilt adjustment filter with tilt coefficient c_tilt, and where

                    16                           d
                    __            -k        -L  __            -k
     Wana(z) = (1 - \ a_ana(k) * z  )*(1 - z  * \ b_ana(k) * z  )
                    /_                          /_
                    k=1                         k=-d

is the analysis part of the de-emphasis filter ๐Ÿฆ‹ it's made of the short-term shaping filter with coefficients a_ana(k) and the long-term shaping filter with coefficients b_ana(k) and pitch lag L. the parameter d decides how many long-term shaping filter taps there are ๐Ÿ’œ

similarly, but without the tilt adjustment, the synthesis part can be written as

                    16                           d
                    __            -k        -L  __            -k
     Wsyn(z) = (1 - \ a_syn(k) * z  )*(1 - z  * \ b_syn(k) * z  )
                    /_                          /_
                    k=1                         k=-d

all the noise shaping parameters are computed and applied per subframe of 5 ms โฑ๏ธ first, an LPC analysis is performed on a windowed signal block of 15 ms ๐ŸŒธ the signal block has a look-ahead of 5 ms relative to the current subframe, and the window is an asymmetric sine window ๐Ÿงš the LPC analysis uses the autocorrelation method, with an order between 8, in lowest-complexity mode, and 16, for best quality โœจ

optionally, the LPC analysis and noise shaping filters are warped by replacing the delay elements with first-order allpass filters ๐ŸŒˆ this increases the frequency resolution at low frequencies and reduces it at high ones, which better matches the human auditory system and improves quality ๐Ÿ‘‘ the warped analysis and filtering costs extra complexity, so it's only done in the higher complexity modes ๐Ÿ’…

the quantization gain is found by taking the square root of the residual energy from the LPC analysis and multiplying it by a value that is inversely proportional to the coding quality control parameter and the pitch correlation ๐Ÿ“

next, the two sets of short-term noise shaping coefficients a_ana(k) and a_syn(k) are obtained by applying different amounts of bandwidth expansion to the coefficients found in the LPC analysis ๐Ÿฆ‹ this bandwidth expansion moves the roots of the LPC polynomial towards the origin, using these formulas ๐Ÿซถ

                                           k
                      a_ana(k) = a(k)*g_ana   and

                                           k
                      a_syn(k) = a(k)*g_syn

where a(k) is the k'th LPC coefficient, and the bandwidth expansion factors g_ana and g_syn are calculated as

                      g_ana = 0.95 - 0.01*C  and

                      g_syn = 0.95 + 0.01*C

where C is the coding quality control parameter between 0 and 1 ๐Ÿ’– applying more bandwidth expansion to the analysis part than to the synthesis part gives the desired de-emphasis of spectral valleys in between formants ๐ŸŒธ

the long-term shaping is only applied during voiced frames ๐ŸŽ€ it uses a three-tap filter, described by

              b_ana = F_ana * [0.25, 0.5, 0.25]  and

              b_syn = F_syn * [0.25, 0.5, 0.25].

for unvoiced frames, these coefficients are set to 0 ๐Ÿ™ˆ the multiplication factors F_ana and F_syn are chosen between 0 and 1, depending on the coding quality control parameter, as well as the calculated pitch correlation and smoothed subband SNR of the lowest subband ๐Ÿ“Š by having F_ana less than F_syn, the pitch harmonics are emphasized relative to the valleys in between the harmonics ๐Ÿงš

the tilt coefficient c_tilt is, for unvoiced frames, chosen as

                          c_tilt = 0.25

and, for voiced frames, as

                    c_tilt = 0.25 + 0.2625 * V

where V is the voice activity level between 0 and 1 ๐ŸŒˆ

the adjustment gain G fixes any level mismatch between the original and decoded signals that might come from the noise shaping and de-emphasis ๐Ÿ‘‘ this gain is computed as the ratio of the prediction gain of the short-term analysis and synthesis filter coefficients ๐Ÿ’… the prediction gain of an LPC synthesis filter is the square root of the output energy when the filter is excited by a unit-energy impulse on the input ๐Ÿ“ an efficient way to compute the prediction gain is to first compute the reflection coefficients from the LPC coefficients through the step-down algorithm, then extract the prediction gain from the reflection coefficients as

                               K
                              ___          2  -0.5
                 predGain = ( | | 1 - (r_k)  )
                              k=1

where r_k is the k'th reflection coefficient ๐Ÿฆ‹

initial values for the quantization gains are computed as the square root of the residual energy of the LPC analysis, adjusted by the coding quality control parameter โœจ these quantization gains get adjusted later based on the results of the prediction analysis ๐Ÿ’œ


5.2.3.4. Prediction Analysis ๐Ÿ”ฅ

the prediction analysis is performed in one of two ways, depending on how the pitch estimator classified the frame ๐ŸŽ€ the processing for voiced and unvoiced speech is described in Section 5.2.3.4.1 and Section 5.2.3.4.2, respectively ๐Ÿซถ the inputs to this function include the pre-whitened signal from the pitch estimator (see Section 5.2.3.2) ๐ŸŒธ

5.2.3.4.1. Voiced Speech ๐ŸŒˆ

for a frame of voiced speech, the pitch pulses stay dominant in the pre-whitened input signal ๐Ÿงš further whitening is desirable, since it leads to higher quality at the same available bitrate ๐Ÿ’– to get there, a Long-Term Prediction (LTP) analysis is carried out to estimate the coefficients of a fifth-order LTP filter for each of four subframes ๐Ÿ‘‘ the LTP coefficients are quantized using the method described in Section 5.2.3.6, and the quantized LTP coefficients are used to compute the LTP residual signal ๐Ÿฆ‹ this LTP residual signal is the input to an LPC analysis, where the LPC coefficients are estimated using Burg's method [BURG], so that the residual energy is minimized ๐Ÿ“Š the estimated LPC coefficients are converted to a Line Spectral Frequency (LSF) vector and quantized as described in Section 5.2.3.5 ๐Ÿ“ after quantization, the quantized LSF vector is converted back to LPC coefficients using the full procedure in Section 4.2.7.5 ๐Ÿ’… by using quantized LTP coefficients and LPC coefficients derived from the quantized LSF coefficients, the encoder stays fully synchronized with the decoder ๐Ÿซถ the quantized LPC and LTP coefficients are also used to filter the input signal and measure the residual energy for each of the four subframes ๐ŸŒธ

5.2.3.4.2. Unvoiced Speech ๐ŸŽ€

for a speech signal that has been classified as unvoiced, there's no need for LTP filtering ๐Ÿ™ˆ it has already been determined that the pre-whitened input signal isn't periodic enough within the allowed pitch period range for LTP analysis to be worth the cost in complexity and bitrate โœจ so the pre-whitened input signal is discarded, and the input signal is used for LPC analysis using Burg's method instead ๐Ÿ’œ the resulting LPC coefficients are converted to an LSF vector and quantized as described in the following section ๐Ÿงš they are then transformed back to obtain quantized LPC coefficients, which are used to filter the input signal and measure the residual energy for each of the four subframes ๐ŸŒˆ

5.2.3.4.2.1. Burg's Method โœจ

Okay so the big job of linear prediction in SILK is to shrink the bitrate by squishing down the residual energy ๐Ÿ’…. At least at high bitrates, the perceptual stuff gets handled separately by the noise shaping filter, so the prediction can focus on being efficient ๐Ÿงš. SILK uses Burg's method because it gives a higher prediction gain than the autocorrelation method and, unlike the covariance method, it produces stable filters (as long as numerical errors don't ruin the vibe ๐Ÿ™ˆ). SILK's version of Burg's method is also computationally faster than the autocovariance method, which is lowkey iconic ๐Ÿ”ฅ.

SILK's implementation is different from the traditional ones in two ways. The first difference is that it works on autocorrelations, kind of like the Schur algorithm [SCHUR], but after finding each reflection coefficient it does a simple update to the autocorrelations so the result is identical to Burg's method ๐ŸŒธ. This brings the complexity of Burg's method down to near the autocorrelation method, which is giving efficiency ๐Ÿ‘‘.

The second difference is that the signal in each subframe gets scaled by the inverse of the residual quantization step size ๐ŸŽ€. Subframes with a small step size will, on average, use more bits for a given amount of residual energy than subframes with a large step size, so it's not fair to treat them all the same ๐Ÿ™„. Without scaling, Burg's method minimizes the total residual energy across all subframes, but that doesn't necessarily minimize the total number of bits needed for the quantized residual. The residual energy of the scaled subframes is a much better measure of those bits, so it's the one that matters ๐Ÿ’–.

5.2.3.5. LSF Quantization ๐Ÿฆ‹

Unlike a lot of other speech codecs, SILK uses variable bitrate coding for the LSFs โœจ. This improves the average rate-distortion (R-D) trade-off and cuts down on outliers ๐Ÿซถ. The variable bitrate coding minimizes a linear combination of the weighted quantization errors and the bitrate. The weights for the quantization errors are the Inverse Harmonic Mean Weighting (IHMW) function proposed by Laroia et al. (see [LAROIA-ICASSP]), and these are referred to here as Laroia weights ๐ŸŒˆ.

The LSF quantizer has two stages ๐Ÿ’…. The first stage is an unweighted vector quantizer (VQ) with a codebook of 32 vectors. The quantization errors for the codebook vectors get sorted, and a second stage quantizer runs for the N best vectors ๐Ÿ“. By changing N, you trade off between R-D performance and computational efficiency, which is such a power move ๐Ÿ‘‘. For each of the N codebook vectors, the Laroia weights are calculated based on that codebook vector (not the input vector) ๐Ÿงš. Then the residual between the input LSF vector and the codebook vector gets scaled by the square roots of those Laroia weights. This partially normalizes the error sensitivity for the residual vector, so a uniform quantizer with fixed step sizes can be used in the second stage without losing too much performance ๐ŸŽ€. Plus, since the scaling uses Laroia weights from the first-stage codebook vector, the decoder can reverse the process ๐Ÿ”ฅ.

The second stage uses predictive delayed decision scalar quantization ๐Ÿ’œ. The quantization error is weighted by Laroia weights that come from the LSF input vector. The predictor multiplies the previous quantized residual value by a prediction coefficient, and that coefficient depends on the vector index from the first stage and on the location in the LSF vector ๐Ÿฆ‹. The prediction gets subtracted from the LSF residual value before quantizing and added back afterwards โœจ. You can think of this subtraction as shifting the quantization levels of the scalar quantizer, which means the quantization error of each value depends on the decision made for the previous value ๐Ÿ™ˆ. The delayed decision mechanism exploits that dependency to search for the quantization sequence with the best R-D performance, using a Viterbi-like algorithm [VITERBI] ๐ŸŒธ. The quantizer processes the residual LSF vector in reverse order, starting with the highest residual LSF value, because the prediction works slightly better in the reverse direction ๐Ÿ’….

The quantization index of the first stage gets entropy coded ๐ŸŽ€. The quantization sequence from the second stage is entropy coded too, and for each element, the probability table is chosen based on the vector index from the first stage and the location of that element in the LSF vector ๐Ÿ“.

5.2.3.5.1. LSF Stabilization ๐Ÿซถ

If the input is stable, finding the best candidate usually gives a quantized vector that's also stable ๐ŸŒˆ. But because of the two-stage approach, it's possible for the best quantization candidate to be unstable, which is kind of a plot twist ๐Ÿ˜ญ. To fix that, the encoder applies the same stabilization procedure the decoder uses (see Section 4.2.7.5.4). This makes sure the LSF parameters stay within their valid range, are increasingly sorted, and have minimum distances between each other and the border values โœจ.

5.2.3.6. LTP Quantization ๐Ÿ’–

For voiced frames, the prediction analysis described in Section 5.2.3.4.1 gives four sets of five LTP coefficients (one set per subframe), plus four weighting matrices ๐Ÿงš. The LTP coefficients for each subframe are quantized using entropy constrained vector quantization ๐Ÿ’…. There are three vector codebooks available, and they have different rate-distortion trade-offs ๐Ÿ‘‘. The three codebooks have 10, 20, and 40 vectors, with average rates of about 3, 4, and 5 bits per vector, respectively ๐Ÿ”ฅ. So the first codebook has larger average quantization distortion at a lower rate, and the last codebook has smaller average distortion at a higher rate ๐Ÿฆ‹.

Given the weighting matrix W_ltp and an LTP vector b, the weighted rate-distortion measure for a codebook vector cb_i with rate r_i is given by:

               RD = u * (b - cb_i)' * W_ltp * (b - cb_i) + r_i

Here, u is a fixed, heuristically determined parameter that balances distortion and rate ๐ŸŽ€. Which codebook performs best for a given LTP vector depends on the weighting matrix for that vector ๐ŸŒธ. For example, for a low valued W_ltp, the codebook with 10 vectors is the move because it has a lower average rate ๐Ÿ™„. For a large W_ltp, the codebook with 40 vectors is often better, since it's more likely to contain the best codebook vector ๐Ÿ’œ.

The weighting matrix W_ltp mostly depends on two things about the input signal ๐ŸŒˆ. The first is periodicity: the more periodic the signal, the larger W_ltp gets โœจ. The second is how the signal energy changes in the current subframe compared to the signal one pitch lag earlier. A decaying energy leads to a larger W_ltp than an increasing energy ๐Ÿ“. Both of these fluctuate pretty slowly, so the W_ltp matrices for different subframes of one frame are often similar to each other ๐Ÿซถ. Because of that, one of the three codebooks usually performs well for all subframes. So the codebook search for the subframe LTP vectors is constrained to only pick vectors from the same codebook, which saves some rate ๐Ÿฆ‹.

To find the best codebook, each of the three vector codebooks is used to quantize all the subframe LTP vectors, producing a combined weighted rate-distortion measure for each codebook ๐Ÿ’…. The codebook with the lowest combined rate-distortion over all subframes wins ๐Ÿ‘‘. The quantized LTP vectors then go into the noise shaping quantizer, and the codebook index plus the four indices for the four subframe codebook vectors get passed on to the range encoder ๐Ÿ”ฅ.

5.2.3.7. Pre-filter ๐Ÿงš

In the pre-filter, the input signal is filtered using the spectral valley de-emphasis filter coefficients from the noise shaping analysis (see Section 5.2.3.3) ๐ŸŽ€. Only the noise shaping analysis filter is applied to the input signal, and that filtered signal is what provides the input to the noise shaping quantizer ๐Ÿ’–.

5.2.3.8. Noise Shaping Quantizer ๐ŸŒธ

The noise shaping quantizer independently shapes the signal and coding noise spectra, so you get a higher perceptual quality at the same bitrate ๐Ÿ’œ. It's giving main character energy ๐ŸŒˆ.

The pre-filter output signal gets multiplied by a compensation gain G computed in the noise shaping analysis โœจ. Then the output of a synthesis shaping filter is added, and the output of a prediction filter is subtracted, which creates a residual signal ๐Ÿ“. The residual signal gets multiplied by the inverse quantized quantization gain from the noise shaping analysis, and that goes into a scalar quantizer ๐Ÿซถ. The quantization indices of the scalar quantizer represent a signal of pulses, which is input to the pyramid range encoder ๐Ÿฆ‹. The scalar quantizer also outputs a quantization signal, and that gets multiplied by the quantized quantization gain from the noise shaping analysis to create an excitation signal ๐Ÿ’…. The output of the prediction filter is added to the excitation signal to form the quantized output signal y(n) ๐Ÿ‘‘. Finally, the quantized output signal y(n) is fed into the synthesis shaping and prediction filters ๐Ÿ”ฅ.

Optionally, the noise shaping quantizer can run in a delayed decision mode ๐Ÿงš. In this mode, it uses a Viterbi algorithm to keep track of multiple rounding choices in the quantizer, then picks the best one after a delay of 32 samples ๐ŸŽ€. This improves the rate/distortion performance of the quantizer, which is so satisfying ๐Ÿ’–.

5.2.3.9. Constant Bitrate Mode ๐ŸŒธ

SILK was designed to run in variable bitrate (VBR) mode ๐Ÿ’œ. However, the reference implementation also has a constant bitrate (CBR) mode for SILK ๐ŸŒˆ. In CBR mode, SILK tries to encode each packet with no more than the allowed number of bits โœจ. The Opus wrapper code then pads the bitstream if there are unused bits left in SILK mode, or it encodes the high band with the remaining bits in Hybrid mode ๐Ÿ“. The number of payload bits gets adjusted by changing the quantization gains and the rate/distortion trade-off in the noise shaping quantizer, in an iterative loop around the noise shaping quantizer and entropy coding ๐Ÿซถ. Compared to SILK VBR mode, CBR mode has lower audio quality at a given average bitrate and higher computational complexity, so it's not the glow-up option ๐Ÿ˜ญ.

5.3. CELT Encoder ๐Ÿฆ‹

Most of the aspects of the CELT encoder can be directly derived from the description of the decoder ๐Ÿ’…. For example, the filters and rotations in the encoder are simply the inverse of what the decoder does ๐Ÿ‘‘. Similarly, the quantizers generally optimize for the mean square error, because noise shaping is part of the bitstream itself, so no special search is required ๐Ÿ”ฅ. For this reason, only the less straightforward aspects of the encoder get described here ๐Ÿงš.

5.3.1. Pitch Pre-filter ๐ŸŽ€

The pitch pre-filter is applied after the pre-emphasis ๐Ÿ’–. It's applied so that it's the inverse of the decoder's post-filter ๐ŸŒธ. The main non-obvious aspect of the pre-filter is choosing the pitch period ๐Ÿ’œ. The pitch search should be optimized for the following criteria:

  • continuity: it is important that the pitch period does not change abruptly between frames; and
  • avoidance of pitch multiples: when the period used is a multiple of the real period (lower frequency fundamental), the post-filter loses most of its ability to reduce noise ๐Ÿ˜ญ

5.3.2. Bands and Normalization โœจ

okay so the MDCT output gets sliced into bands ๐ŸŽ€ the slicing is designed to line up with your ear's critical bands at the tiniest (2.5 ms) frame size, and the bigger frame sizes just use whole-number multiples of that same layout ๐Ÿฆ‹ for each band, the encoder works out the energy it's going to encode later. then each band gets divided by the square root of the unquantized energy, so every band ends up as a unit vector X ๐Ÿ’… the energy and the normalization come from compute_band_energies() and normalise_bands() in bands.c, respectively ๐Ÿซถ

5.3.3. Energy Envelope Quantization ๐ŸŒธ

energy quantization (coarse AND fine) is honestly easy to get once you've seen the decoding process ๐Ÿงš at every useful bitrate, the coarse quantizer picks the quantized log energy value that gives the smallest error for each band ๐Ÿ’– only at super low rates does the encoder let the errors get bigger, so it doesn't spend more bits than it has โœจ if the CPU has room, it's best to try coarse energy both with and without inter-frame prediction so you can pick the better prediction mode ๐Ÿ”ฅ the best mode depends on the coding rate, the available bitrate, and how much packet loss is happening right now ๐Ÿ˜ญ

the fine energy quantizer always picks the quantized log energy value with the smallest error for each band ๐Ÿ’… that's because the fine quantization rate depends only on the bit allocation, not on the values being coded ๐ŸŽ€

5.3.4. Bit Allocation ๐Ÿ’œ

the encoder MUST NOT deviate from the bit allocation process the decoder uses, which is described in Section 4.3.3. wait, let me reword that for real: the encoder must use exactly the same bit allocation process as the decoder, described in Section 4.3.3 ๐Ÿ™ˆ the three tools the encoder has for tweaking the bitrate on each frame are band boost, allocation trim, and band skipping ๐Ÿ“

5.3.4.1. Band Boost ๐Ÿ”ฅ

the reference encoder decides to boost a band when its energy is way higher than the energy of its neighbors ๐Ÿ‘‘ if E_j is the log-energy of band j, we define:

   D_j = 2*E_j - E_j-1 - E_j+1

the allocation for band j gets boosted once if D_j > t1 and twice if D_j > t2 โœจ for LM>=1, t1=2 and t2=4, while for LM<1, t1=3 and t2=5 ๐ŸŒˆ

5.3.4.2. Allocation Trim ๐Ÿฆ‹

the allocation trim is a value from 0 to 10 (inclusive) that controls how the bits get balanced between low and high frequencies ๐Ÿ’– the encoder starts at a safe "default" of 5 and can move away from it in two ways ๐Ÿซถ first, the trim can shift by +/- 2 depending on the spectral tilt of the input. signals with more low frequencies get the trim bumped up by up to 2, and signals with more high frequencies get it lowered by up to 2 ๐ŸŽ€ for stereo inputs, the trim can drop by up to 4 when the inter-channel correlation at low frequency (the first 8 bands) is high ๐Ÿ’…

5.3.4.3. Band Skipping ๐Ÿ“

the encoder uses band skipping so that a band's shape only gets coded if there's at least 1/2 bit per sample available for the PVQ ๐Ÿ˜ญ if not, no bits get allocated to it and folding is used instead โœจ to keep the allocation continuous, there's some hysteresis built in: a band that got PVQ bits in the previous frame only needs 7/16 bit/sample to get coded in the current frame, while a band that got no PVQ bits in the previous frames needs at least 9/16 bit/sample ๐Ÿงš

5.3.5. Stereo Decisions ๐ŸŒŠ

because CELT applies mid-side stereo coupling in the normalized domain, it doesn't have big stereo image problems even when the two channels are totally uncorrelated ๐Ÿ’œ so it's always safe to use stereo coupling on any audio frame ๐Ÿ‘‘ that said, some frames are still more efficient with dual (independent) stereo ๐Ÿ™ˆ the call gets made by comparing the estimated entropy with and without coupling over the first 13 bands, and it takes into account that every band with more than two MDCT bins needs one extra degree of freedom when it's coded in mid-side ๐Ÿ”ฅ let L1_ms and L1_lr be the L1-norm of the mid-side vector and the L1-norm of the left-right vector, respectively. mid-side gets chosen if and only if:

                            L1_ms          L1_lr
                           --------    <   -----
                           bins + E        bins

where bins is the number of MDCT bins in the first 13 bands and E is the number of extra degrees of freedom for mid-side coding. for LM>1, E=13, otherwise E=5 โœจ

the reference encoder picks the intensity stereo threshold based on the bitrate alone ๐ŸŒธ after subtracting 80 bits per frame for coarse energy (to account for the frame size), the first band using intensity coding is:

                     +------------------+------------+
                     | bitrate (kbit/s) | start band |
                     +------------------+------------+
                     |        <35       |      8     |
                     |                  |            |
                     |       35-50      |     12     |
                     |                  |            |
                     |       50-68      |     16     |
                     |                  |            |
                     |       84-84      |     18     |
                     |                  |            |
                     |      84-102      |     19     |
                     |                  |            |
                     |      102-130     |     20     |
                     |                  |            |
                     |       >130       |  disabled  |
                     +------------------+------------+

                 Table 66: Thresholds for Intensity Stereo

5.3.6. Time-Frequency Decision โญ

the time-frequency resolution used in Section 4.3.4.5 is picked using R-D optimization ๐Ÿงš the distortion is the L1-norm (sum of absolute values) of each band after each TF resolution being considered ๐Ÿ’– the L1 norm gets used because it stands in for the entropy of a Laplacian source ๐Ÿฆ‹ switching TF resolution between two bands costs more bits than having both bands share the same resolution, and that's exactly why R-D optimization is needed ๐Ÿ˜ญ the optimal decision is computed with the Viterbi algorithm. see tf_analysis() in celt/celt.c ๐Ÿ’…

5.3.7. Spreading Values Decision ๐ŸŽ€

the spreading value you pick from Table 59 changes the kind of coding noise CELT introduces ๐ŸŒˆ the bigger the f_r value, the less the rotation affects things, and the more tonal the coding noise ends up being ๐Ÿ’œ a tonal signal should have tonal noise, so the CELT encoder figures out the best f_r by estimating how tonal the signal is ๐Ÿ”ฅ that tonality estimate uses a discrete pdf (4-bin histogram) for each band. bands with lots of small values count as more tonal, and the decision combines all bands with more than 8 samples ๐Ÿ‘‘ see spreading_decision() in celt/bands.c โœจ

5.3.8. Spherical Vector Quantization ๐Ÿฆ‹

CELT uses a Pyramid Vector Quantizer (PVQ) [PVQ] to quantize the details of the spectrum in each band that the pitch predictor didn't already predict ๐Ÿ’– the PVQ codebook is made of all sums of K signed pulses in a vector of N samples, where two pulses at the same position have to share the same sign ๐Ÿซถ so the codebook has every integer codevector y of N dimensions where sum(abs(y(j))) = K ๐ŸŽ€

in bands with enough bits allocated, PVQ encodes the unit vector from the normalization in Section 5.3.2 directly ๐Ÿ’… given a PVQ codevector y, the unit vector X is X = y/||y||, where ||.|| is the L2 norm ๐ŸŒธ

the search for the best codevector y is done by alg_quant() in vq.c ๐Ÿ™ˆ there are a few ways to search, trading off quality against complexity ๐Ÿงš the reference implementation computes an initial codeword y1 by projecting the normalized spectrum X onto the codebook pyramid of K-1 pulses:

   y0 = truncate_towards_zero( (K-1) * X / sum(abs(X)))

depending on N, K and the input data, the initial codeword y0 can have anywhere from 0 to K-1 non-zero values ๐Ÿ“ every remaining pulse except the last one gets found iteratively with a greedy search that minimizes the normalized correlation between y and X:

                             T
                       J = -X * y / ||y||

the search above is considered a good trade-off between quality and computational cost ๐Ÿ’œ however, there are other ways to search the PVQ codebook, and implementers MAY use any other search methods ๐Ÿ‘‘ see alg_quant() in celt/vq.c ๐ŸŒˆ

5.3.8.2. PVQ Encoding ๐Ÿ’–

the vector to encode, X, gets converted into an index i with 0 <= i < V(N,K), like this ๐Ÿซถ start with i = 0 and k = 0. then, for j = (N - 1) down to 0, inclusive, do:

  1. If k > 0, set i = i + (V(N-j-1,k-1) + V(N-j,k-1))/2.
  2. Set k = k + abs(X[j]).
  3. If X[j] < 0, set i = i + (V(N-j-1,k) + V(N-j,k))/2.

the index i is then encoded using the procedure in Section 5.1.4 with ft = V(N,K) ๐Ÿฆ‹

6. Conformance ๐ŸŽ€

we really want to give implementers as much freedom as possible ๐Ÿ’… so, outside the exceptions noted in this section, conformance is defined by the reference implementation of the decoder in Appendix A ๐ŸŒธ this document does include a prose description of the codec, but if the description ever contradicts the source code of the reference implementation, the source code shall take precedence ๐Ÿ™ˆ

compliance means that, on top of following the normative keywords in this document, a decoder's output MUST also stay within the thresholds set by the opus_compare.c tool (included with the code) when compared against the reference implementation, for each of the test vectors (see Appendix A.4) and for each output sampling rate and channel count supported ๐Ÿ˜ญ a compliant decoder ALSO MUST end up with the same final range decoder state as the reference decoder ๐Ÿ’€

so it's RECOMMENDED that the decoder implements the same functional behavior as the reference ๐Ÿ’œ a decoder implementation doesn't have to support every output sampling rate or every output channel count ๐Ÿงš

6.1. Testing ๐Ÿงช

okay so the reference code in Appendix A lets you decode a test vector with this command:

opus_demo -d <rate> <channels> testvectorX.bit testX.out

where <rate> is the sampling rate, and the options are 8000, 12000, 16000, 24000, or 48000. <channels> is 1 for mono or 2 for stereo ๐ŸŽ€

If the range decoder state is wrong for one of the frames, the decoder will exit with Error: Range coder state mismatch between encoder and decoder. ๐Ÿ˜ญ If the decoder succeeds, you can compare its output against the "reference" output. For stereo, use:

opus_compare -s -r <rate> testvectorX.dec testX.out

and for mono, use:

opus_compare -r <rate> testvectorX.dec testX.out

The opus_compare tool tells you whether the test vector passes, and it also gives you an "Opus quality metric" that shows how closely your decoder matches the reference implementation. A quality of 0 is the passing threshold, and a quality of 100 is the highest possible score, which means your output is identical to the reference ๐Ÿ’ฏ The passing threshold was calibrated so that it lines up with additive white noise at a 48 dB SNR, which is about what you'd get from a cassette deck ๐Ÿ“ผ A decoder can still sound really good with a score that low (for example, if the difference is only inaudible phase distortion). But unless listening tests confirm that, it is RECOMMENDED that implementations get a quality above 90 for 48 kHz decoding. โœจ For other sampling rates, a lower quality metric is normal (typically as low as 50, even for a good implementation). That's because of harmless mismatches in the delay and phase of the internal sampling rate conversion ๐ŸŒธ

On POSIX environments, you can use the run_vectors.sh script to verify all of the test vectors. The command is:

run_vectors.sh <exec path> <vector path> <rate>

where <exec path> is the directory where the opus_demo and opus_compare executables are built, and <vector path> is the directory that holds the test vectors. ๐Ÿฆ‹


6.2. Opus Custom ๐ŸŒˆ

Opus Custom is an OPTIONAL part of the spec. It exists to handle special sample rates and frame rates that the main Opus spec doesn't support ๐Ÿงš Using it is discouraged for almost everyone. The only really good reason is a very special application that needs a frame size other than 2.5, 5, 10, or 20 ms, for either complexity or latency reasons. Because Opus Custom is optional, you can't expect streams encoded with it to be decodable by every Opus implementation ๐Ÿ™ˆ There's also no in-band way to signal the sampling rate and frame size of Opus Custom streams, so out-of-band signaling is required. In Opus Custom operation, only the CELT layer is available, and you use the opus_custom_* function calls from opus_custom.h ๐Ÿ’œ


7. Security Considerations ๐Ÿ”

Okay, this part is serious bestie. Like any other audio codec, Opus should not be used with insecure ciphers or cipher modes that are vulnerable to known plaintext attacks ๐Ÿ’€ Beyond the zeros used in Opus padding, digital silence frames produce predictable compressed results, and the TOC byte may have an easily predictable value. So be careful!

Implementations of the Opus codec need to take appropriate security considerations into account, as outlined in [DOS]. It is extremely important for the decoder to be robust against malicious payloads. Malicious payloads must not make the decoder overrun its allocated memory or use an excessive amount of resources to decode. Encoder problems are usually rarer, but the same applies to the encoder. Malicious audio streams must not make the encoder misbehave, because that would let an attacker go after transcoding gateways ๐Ÿ˜ค

The reference implementation has no known buffer overflows, and no specially crafted packet or audio segment is known to cause a significant increase in CPU load. However, on certain CPU architectures where denormalized floating-point operations are much slower than normal ones, some audio content (like silence or near silence) can cause a CPU load increase. Denormals can be introduced by reordering operations in the compiler, and they depend on the target architecture, so it's hard to guarantee that an implementation avoids them. For architectures where denormals are a problem, it is RECOMMENDED to add very small floating-point offsets to the affected signals, which prevents significant numbers of denormalized operations. Alternatively, it's often possible to configure the hardware to treat denormals as zero (DAZ). There is no such issue for the fixed-point reference implementation ๐Ÿซถ

The reference implementation was validated under the following conditions:

  1. Sending the decoder valid packets generated by the reference encoder, and verifying that the decoder's final range coder state matches that of the encoder.
  2. Sending the decoder packets generated by the reference encoder, which are then subjected to random corruption.
  3. Sending the decoder random packets.
  4. Sending the decoder packets generated by a version of the reference encoder modified to make random coding decisions (internal fuzzing), including mode switching, and verifying that the range coder final states match.

In all of the conditions above, both the encoder and the decoder were run inside the Valgrind [VALGRIND] memory debugger. Valgrind tracks reads and writes to invalid memory regions as well as the use of uninitialized memory. No errors were reported in any of the tested conditions ๐ŸŽ‰


8. Acknowledgements ๐Ÿซถ

Huge thanks to all the other developers, including Henrik Astrom, Jon Bergenheim, Raymond Chen, Soren Skak Jensen, Gregory Maxwell, Christopher Montgomery, and Karsten Vandborg Sorensen ๐Ÿ‘‘ We also want to thank Igor Dyakonov, Hoang Thi Minh Nguyet, Christian Hoene, Gian-Carlo Pascutto, and Jan Skoglund for helping test the Opus codec ๐Ÿงช Thanks to Andrew D'Addesio, Elwyn Davies, Ralph Giles, John Ridges, Ben Schwartz, Kat Walsh, Mark Warner, Keith Yan, and the many others on the Opus and CELT mailing lists for their bug reports and feedback ๐Ÿ’Œ And last but definitely not least, the authors would like to thank Robert Sparks, Cullen Jennings, and Jonathan Rosenberg for their support throughout the standardization process ๐ŸŒŸ


9. References

9.1. Normative References

  • [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. ๐Ÿ“š

9.2. Informative References

okay bestie, here's the extra reading list ๐Ÿ“š these aren't required to implement anything, but they're the receipts behind the design ๐Ÿ’…

[BURG]     Burg, J., "Maximum Entropy Spectral Analysis", Proceedings
           of the 37th Annual International SEG Meeting, Vol.
           6, 1975.

[CELT]     Valin, JM., Terriberry, T., Maxwell, G., and C.
           Montgomery, "Constrained-Energy Lapped Transform (CELT)
           Codec", Work in Progress, July 2010.

[CODING-THESIS]
           Pasco, R., "Source coding algorithms for fast data
           compression", Ph.D. thesis Dept. of Electrical
           Engineering, Stanford University, May 1976.

[DOS]      Handley, M., Rescorla, E., and IAB, "Internet Denial-of-
           Service Considerations", RFC 4732, December 2006.

[FFT]      Wikipedia, "Fast Fourier Transform",
           <http://en.wikipedia.org/w/
           index.php?title=Fast_Fourier_transform&oldid=508004516>.

[GOOGLE-NETEQ]
           "Google NetEQ code", <http://code.google.com/p/webrtc/
           source/browse/trunk/src/modules/audio_coding/NetEQ/main/
           source/?r=583>.

[GOOGLE-WEBRTC]
           "Google WebRTC code", <http://code.google.com/p/webrtc/>.

[HADAMARD] Wikipedia, "Hadamard Transform", <http://en.wikipedia.org/
           w/index.php?title=Hadamard_transform&oldid=508252957>.

[KABAL86]  Kabal, P. and R. Ramachandran, "The Computation of Line
           Spectral Frequencies Using Chebyshev Polynomials", IEEE
           Trans. Acoustics, Speech, Signal Processing, Vol. 34, no.
           6, pp. 1419-1426, December 1986.

[LAROIA-ICASSP]
           Laroia, R., Phamdo, N., and N. Farvardin, "Robust and
           Efficient Quantization of Speech LSP Parameters Using
           Structured Vector Quantization", ICASSP-1991, Proc. IEEE
           Int. Conf. Acoust., Speech, Signal Processing, pp. 641-
           644, October 1991.

[LPC]      Wikipedia, "Linear Prediction", <http://en.wikipedia.org/
           w/index.php?title=Linear_prediction&oldid=497201278>.

[MARTIN79] Martin, G., "Range encoding: An algorithm for removing
           redundancy from a digitised message", Proc. Institution of
           Electronic and Radio Engineers International Conference on
           Video and Data Recording, 1979.

[MATROSKA-WEBSITE]
           "Matroska website", <http://matroska.org/>.

[MDCT]     Wikipedia, "Modified Discrete Cosine Transform", <http://
           en.wikipedia.org/w/
           index.php?title=Modified_discrete_cosine_
           transform&oldid=490295438>.

[OPUS-GIT] "Opus Git Repository", <https://git.xiph.org/opus.git>.

[OPUS-WEBSITE]
           "Opus website", <http://opus-codec.org/>.

[PRINCEN86]
           Princen, J. and A. Bradley, "Analysis/Synthesis Filter
           Bank Design Based on Time Domain Aliasing Cancellation",
           IEEE Trans. Acoustics, Speech, and Siginal Processing,
           ASSP-34 (5), pp. 1153-1161, October, 1986.

[PVQ]      Fischer, T., "A Pyramid Vector Quantizer", IEEE Trans. on
           Information Theory, Vol. 32, pp. 568-583, July 1986.

[RANGE-CODING]
           Wikipedia, "Range Coding", <http://en.wikipedia.org/w/
           index.php?title=Range_encoding&oldid=509582757>.

[REQUIREMENTS]
           Valin, JM. and K. Vos, "Requirements for an Internet Audio
           Codec", RFC 6366, August 2011.

[RFC3533]  Pfeiffer, S., "The Ogg Encapsulation Format Version 0",
           RFC 3533, May 2003.

[RFC3550]  Schulzrinne, H., Casner, S., Frederick, R., and V.
           Jacobson, "RTP: A Transport Protocol for Real-Time
           Applications", STD 64, RFC 3550, July 2003.

[SCHUR]    Le Roux, J. and C. Gueguen, "A fixed point computation of
           partial correlation coefficients", ICASSP-1977, Proc. IEEE
           Int. Conf. Acoustics, Speech, and Signal Processing, pp.
           257-259, June 1977.

[SILK]     Vos, K., Jensen, S., and K. Sorensen, "SILK Speech Codec",
           Work in Progress, September 2010.

[SPECTRAL-PAIRS]
           Wikipedia, "Line Spectral Pairs", <http://
           en.wikipedia.org/w/
           index.php?title=Line_spectral_pairs&oldid=365426016>.

[SRTP-VBR] Perkins, C. and JM. Valin, "Guidelines for the Use of
           Variable Bit Rate Audio with Secure RTP", RFC 6562,
           March 2012.

[VALGRIND] "Valgrind website", <http://valgrind.org/>.

[VALIN2010]
           Valin, JM., Terriberry, T., Montgomery, C., and G.
           Maxwell, "A High-Quality Speech and Audio Codec With Less
           Than 10 ms Delay", IEEE Trans. on Audio, Speech, and
           Language Processing, Vol. 18, No. 1, pp. 58-67 2010.

[VECTORS-PROC]
           "Opus Testvectors (proceedings)", <http://www.ietf.org/
           proceedings/83/slides/slides-83-codec-0.gz>.

[VECTORS-WEBSITE]
           "Opus Testvectors (website)",
           <http://opus-codec.org/testvectors/>.

[VITERBI]  Wikipedia, "Viterbi Algorithm", <http://en.wikipedia.org/
           w/index.php?title=Viterbi_algorithm&oldid=508835871>.

[VORBIS-WEBSITE]
           "Vorbis website", <http://xiph.org/vorbis/>.

[WHITENING]
           Wikipedia, "White Noise", <http://en.wikipedia.org/w/
           index.php?title=White_noise&oldid=497791998>.

[Z-TRANSFORM]
           Wikipedia, "Z-transform", <http://en.wikipedia.org/w/
           index.php?title=Z-transform&oldid=508392884>.

[ZWICKER61]
           Zwicker, E., "Subdivision of the Audible Frequency Range
           into Critical Bands", The Journal of the Acoustical
           Society of America, Vol. 33, No 2 pp. 248, February 1961.

Appendix A. Reference Implementation โœจ

okay bestie, this appendix is the whole reference implementation of Opus, written in C ๐Ÿ’– by default it uses floating-point math, but if you define the FIXED_POINT macro it runs on fixed-point arithmetic instead ๐Ÿ”ฅ the important bit is that the normative behavior is the output of the floating-point configuration ๐Ÿซถ build and usage details live in the README ๐Ÿ“–

it compiles with either a C89 or a C99 compiler, and it's already pretty well optimized for most platforms ๐ŸŒธ so only architecture-specific tweaks are likely to be worth the effort ๐Ÿ’… the FFT [FFT] is a slightly modified version of the KISS-FFT library, but swapping in any other FFT library is totally fine ๐Ÿงš

ngl this part is so cute: the code doesn't lean on any undefined behavior as defined by C89 or C99 ๐Ÿ‘‘ but it does rely on some implementation-defined behavior for two's complement architectures ๐Ÿค“ specifically:

  • Right shifts of negative values are consistent with two's complement arithmetic, so that a>>b is equivalent to floor(a/(2**b)),
  • For conversion to a signed integer of N bits, the value is reduced modulo 2**N to be within range of the type,
  • The result of integer division of a negative value is truncated towards zero, and
  • The compiler provides a 64-bit integer type (a C99 requirement which is supported by most C89 compilers).

and for acceptable performance, the reference implementation also needs these architectural characteristics ๐ŸŽ€

  • Two's complement arithmetic,
  • At least a 16 bit by 16 bit integer multiplier (32-bit result), and
  • At least a 32-bit adder/accumulator.

A.1. Extracting the Source ๐Ÿง

the full source is hidden inside this document, so here's how to pull it out ๐Ÿฆ‹ run the following command line:

  • cat rfc6716.txt | grep '^\ \ \ ###' | sed -e 's/...###//' | base64 --decode > opus-rfc6716.tar.gz
  • tar xzvf opus-rfc6716.tar.gz
  • cd opus-rfc6716
  • make

if the provided Makefile doesn't work on your system, try compiling with this command line instead ๐Ÿ™ˆ

  • cc -O2 -g -o opus_demo src/opus_demo.c cat .mk | grep -v fixed | sed -e 's/.=//' -e 's/\\//' -DOPUS_BUILD -Iinclude -Icelt -Isilk -Isilk/float -DUSE_ALLOCA -Drestrict= -lm

no base64 utility on your machine? no stress, use these commands instead ๐Ÿ’œ

  • cat rfc6716.txt | grep '^\ \ \ ###' | sed -e 's/...###//' > opus.b64
  • openssl base64 -d -in opus.b64 > opus-rfc6716.tar.gz

the SHA1 hash of the opus-rfc6716.tar.gz file is 86a927223e73d2476646a1b933fcd3fffb6ecc8c ๐Ÿ” check it so you know your tarball is the real deal โœจ

A.2. Up-to-Date Implementation ๐ŸŒˆ

as of the time of publication, there's an up-to-date implementation conforming to this RFC in a Git repository [OPUS-GIT] ๐Ÿ’– releases and other resources live at [OPUS-WEBSITE] ๐Ÿ“ the implementation is expected to stay conformant with the RFC, but the code in this document is the one that shall remain normative ๐Ÿซถ

A.3. Base64-Encoded Source Code ๐ŸŽ€

I can't produce this part as written. It's about 1,000 lines of Base64 that have to be copied character for character, and at that length I'd likely introduce transcription errors. Corrupting the encoded source would break the one rule that matters most here, and there's no prose to rewrite in voice.

If you want to continue, I can take this in smaller pieces, such as 100 to 150 lines per response, and tell you which line each piece ends on so the chunks join cleanly. Or, if you only need the decoded source, decoding the Base64 locally (for example with base64 -d on the blob, then gunzip and tar -x) will give you the original files exactly.

This part isn't readable RFC text. It's a block of base64-looking characters, all prefixed with ###, and it's the encoded source code that Appendix A.3 already covered. I can't decode it reliably here, and rewriting it would mean making up RFC content, so I haven't produced a rewritten part 40.

Here's how we can keep going:

  • Paste the readable text for part 40. If the original RFC text follows Appendix A.3 in your copy, send that and I'll rewrite it in the bubbly voice, keeping every requirement, section number, ABNF block, and citation exact.
  • Decode the blob yourself. If you want the encoded source, you can run something like base64 -d in your shell on the data and then extract the archive. I can help you with the extraction or the rest of the document after that.

Send me whichever you'd like and I'll pick it up from there.

okay so this part is just one giant base64 blob, no cap it's the encoded source ๐Ÿซถ๐Ÿ’…

###1eoGvKqvV9eq3jo8razUKhuNmrvRaKzX6hu1dZiWaGlvFMhcv0DCgygoaZY1RC8J
###gTERM/+weisCj2EEO/uIsl61Xl8rOQKV4H9EJVhpflt2q7WNSsZrEG6qeK0pofkL
###MIM+bMR7BHQhKkRlV6wBYC9wiOS8IA4RRCYyUMdnOCYxm18CigzdEUeY8MzE8RPr
###ORSVGLrQsgwZHQYieTomeZIw9ru/AVuMXHkJWo2C3hTN7ilpOkaUZvOBT0EEB+Wt
###HIDCrXuBW/VGreQCyC8lHkUezM8GBsCW06LT3GFjAtiAPYLfDMJEaQ/vjKGKl8fU
###54C7+FeBcQdDhwBaesNueRSh+f8PIIIGmHYWJY6JyITzCsAAVCAq3Bdy94AggC6I
###+HmNrTD++zDod/kwxW0bmft+iuiA+C1dYHFN7koyhbNIpKXw1cJkrOKuVGob9cZB
###uQaYhb4UXCDvnJ0AZwQFvJX1ysbaxkG5Lk5I2dY48G/QRhfPSKNBb8Vr1DfcVQLJ
###im2twnCMSmnA2w/ukxoEXoZkIcf1vPV1BX5CYkEbz9MEMffTe+Z6gPi9X/VErjiL
###AAKVIwJI3FYG6cMD6mZzLhHEY41PYmHlktJG7n2oXwJ+/e5VgVrA2AE33ZJTrlZc
###F2eysQFfGo3aZz4Se07urgmn9Au5gARIYkOcG2gmZxyUd8iB5Mtr9PJOn4mADl7h
###hlEzST+jiSIgex8qlzPpx94Hd95L7zK5ZDOLVrPagee1y7z80SMTM4gmpbXyjX0Y
###8kGotPWuQ0eHfuA55bVG3dUPqs66t2YUqAGcvcaLhDmSsVKsfO6MMEJgyzN1/hln
###4R2cdAR3m7C8hfndle6soTMk3NLJ0Sn8xWE3SvAM5sl4fuyW7pCqJFrxCIZQ6tib
###866afHcMO/vOm6eSe9KPXitchSldsRy76pOnPlXVp9qLFKuBwJ3FaCAG331XuUMt
###cA9+9IbYZq7p4P3FwSlO2iUakJebBCsCJBGeGeXW8nI5qC3uoLIGHVB9yWDTy62s
###Buqqo981VMXSJlAGKqIUC2t6J7AaOXQnQD+3dGUQYaGPmU006sBclO/yRksv0s2Z
###k+rJSWUQD/T8wnpGeTe7PFGLNbNSqogu8TmDO03SYTjwJSEGPJhDh5Ejn0GGw83F
###eFG+P4rjIJoAIdwGDuilajrPJqJMDzibNKcggwOSUtTHLwWi2ALJnTrlh8z41Pm4
###lbw2sK0mu6qocAh8SN7mXc/RhE0e1kh//MgG16sXJqe5Dkxl3duoAaPZqK1VGsAr
###qC91elktDE1Ot2PylZKjFLyYYCQTkoJbr3mVUrWyXqtcpnhMepwk32WuAtyQgotM
###7zi5HTmnwe0E5RHJ8sR6SmXkfHK5qDAE8XkF2XyNWfpVMReJtwqsEe/wbGbCJnWZ
###vBuzbood4TVJcMHxtE0XAZi6he4EHFeCSqg01JTSjOgmahH8fjySg4GVRe9jZImD
###YUyp60k6iaZD1uoLDkouRhArjk7EO8ucuzxKnhUICgrE1w9Ht4KxrGuFCEzYW80N
###i0gQbVYzwWPKccBc1lYq9WqtwZxkNqvp1mruumY1bR5TNmXwrl6t0aiv0sATrKbY
###dIpyR3ncfg1xXLHubenf+fj7X4qj2OL4uNd/wv1vFRbYS/p/1tzq8v73r/L/rH7Z
###/e/CF7/Jm10L84zb3UN8Xhb5v2WGWaFHoNJX4fBqedm7vOxdXvYuL3uXl73Ly97n
###Ny3lq7L9g913rw0TU/tpllOnchw9OL5o7b3oj4BU0S8SNgfhOMYLx29J5IaTCsiJ
###k1FmU98li54Vo3/+LueX2nknZ4jReUORlc/5+UL6HV5G4ss2ejsZber7LGqVNU5C
###c2XeY6HinNhvaB4v0krwLQet8aUaygz82hynXQFLm0oMeAri35x6bVnPz6jHGgm3
###cVf11FWDPF75kOAwWr68LuRbSDpwMEIBisvIM1AaSwfvN/EjOprZAKf7u4YJHA0Q
###nJk11szZYKmMuaNuS3X2E5ID0imVcBzm6uKirdSLuTtYVWvN3fzWVo5K54015ZZI
###N5FsCXFhgZZ0FLSDs6PDX1vnP8BmhUrQ0l1+q0l6oe++Q810U8iXyRpAR3R5z62t
###1darjdra8bGspp6tHx+nar+zqufM+u/wKt0YIeIgrYy8QG7r1t6ql2+NtwnNMOdt
###B9IDoEdm01RHAdeqVIrfJGBhqRV7wiEwB0QABNmS85IafMUaMZa3J9zVK+cf3f8a
###vixhtvtJXiidPovrY6fplO9mdAmvlYpyZn+sdpvTIbaiVWhIaIrFxG00CtM2jMjS
###m9SYmlBJOOknWdDihXwCrKDIEyCF3T0BTqnOMqDU9DLApFDNVAnrLy28pGm1Do+O
###D1ot/HQMp2yrlc9EQaMW4WFJZBFFoUbYtUPh58FO1dcsDEWK+I/4FXUpIQMj4rHQ
###OJKrcbcAVpngYgUOQ4s+LwgsnLmu8mdAirr6iwAFdIuOHj678vy9pR4sjl2iIkJD
###5KQVDTwZdH7e+eMPx37Go3wApDQUAU8O3WRDdHt7Blz1rOeA19/e1jZWj6WiYmgz
###qGjWmKC99HDmL65e2+PE2h4/dW2P/z5rezx3bb9kYbe2vmRhj7/+wmZQKuY79Blp
###rk/qAJ15gn7JVlOkSy+HOO6sE0+h4cL7yTprHxzCogfu5wVO3SwwH/+1YD7+YjDP
###wu6FwXz83GC2+GjDOFNYp2DFcllIPywXsZxjSRskWEgooiELCD4Sporrl+1LSpiT
###NbYreeefTvL1K7He8KQsmzZEAmnteVfyE2PVXJqYEpz/JRi0KT39sHN8yGyck+PT
###967kJt4z4+Lk5BUwSSSrq7ZMouYCo4AjTWGSWe44UW5rS5dTPfJdno9mpvyZzoj2
###4ueDqGScD+1nPhvaD6EnDeEp50J7/plQbD90HDw4phlnQvEf3easUbVLmafD58cw
###dnTXy4tKnx+7qKLSX7moNISvsKjl9tPOeB7OVz7jjV3JJEhqhRZfQFwKUcU6svSX
###+Uv5sMhtLyc+WWSHzj3DsuAnjzT6+/iduuDRJkaWebTNHNUiG3T+qce2ZmqHPnaB
###RZW/zwLTgL7iApfbT1DHiEE9w9o+uKxsrviOsEkt8jtzG7975D7WPlawfLKyemit
###fMbTL0GBd2kceLcQErybt82n+H8W0OXoCRXUl8dv+HcL7vh3c7b8AyP8gn0vEIRQ
###UiOISQbePZIO2AgiKv+dEGS1kAH8eYSi35/yryejCdtzPUA4shFl3mizUAXHWeY/
###zZmj5rVMoY0xzIcQB03qhB+MuEtyG+ouKYt10xZ74s5BMnBfj1Uzu5zLsSmYpDd0
###4Wlsmd31vAuKBe8m0heiYnvqnh51UhvVFuam5+++51io5+erc5oZyfv5wlOOa2N0
###z3pkz1/mnT1e5U6JLvPI1VeL9U1PuFnkOvmSfTOL4DYlaeNC971AkZ/y1lOJOT89
###EnlEZYE/Fg3HZz89MzItdNYbQ/tHNxudivPZv58W5ABxuDu75+iom99uZiiA3Hrx
###p/zDeCWHKiyxye4Prb5GI/YA/7Khyl1gbwPjW5sUNT89fV/I8WfujcJMhUJ67LP3
###DI7rp2ZTG9Ubp1OVShiuHMa72gKEVDgq0yZLbJU2WlwkdqQoLnblAztSFDZ3ZYbM
###tHPx7mzn4iDzUISJ+9ttOW2/qemXv1XWz/FiuJ2UCKrm7P0ZunrTkN6FAWeN4uvT
###fez8iSd0JoHHV9vbTcd1v4Te86hmHN6M2ZkC48zb9OqDev0kr/STW/3LVqT6VVak
###+oX8FI3r4TXhE+1ZV6L2l61E7ausRO2LV6L2NNubTOinGVxBl20mF549VmmcqPw3
###YndxQH8Sy6tWvf70u4PEuB+hc15cO+k+fMWcXNW3fxmNfPv8NLLYdDCyxhcdWzQs
###6b63AF18Ntr89lloc+3RtPntX0ab3z4/bQYMWHc3vC/EgNrTMKD2xRhQ+4swoP6X
###YUD9K2AAhQH5QhSoPw0F6l+MAvVnQIG5t1T7Rz+DaKVUYPLrPMYgQ/TR1Z7xvqot
###I5wkcEdDSnb7yumG6I+F1vqYBAbhs/q0G6lkQITPixr6PIjnerBpzfjqQ5zKYy7S
###Vr/ApkEPchZLsoq/mvOH+aAWQgwP3m2TM4AVXgInYQWXEEW3pK9AoqwROyHJAlXr
###D+K+hfiP0vuKKn8+xn9VdH+m22Ix0D8f1R8m7GJoz3tnvFaZcyf49gxG1To5enuu
###beLUoxy2msc8ar+rsXJHLyejid+n6BD94C6c3MtrKKxGQ1MDyG9+5hCOTq6ig9a/
###+HP9/6+CYRCFz5ME6oH47zWvXk36/69VvaX//1/l/+8tlP9pbgyAZLwADgr/mDAA
###CgGNQACv+RmXSAUEWEYAWEYAWEYAWEYAWEYAWEYA+FoRAGA8wJrupWIA6OfkiH7C
###LuimvzlbdFHQOcsRXRl70SvO5ipMiGA/+zIQr1U/7Zf+LIEA/j4+9LYH/cL+8wuP
###v/7F46+b40fnjTlzcBefhgplUPUenkbVffI05sd5sKM8zI3xkIzUsEh8h3SdBWI7
###7JnJjOHQ/BREeHbhWdrrj4BPojC8GNcazk2BoKnd8uWBFR4/FrGBZ4zli0Iz4FhO
###gytgZPSmTPXD4QwwgkKZXJytSrMGxx7+uhJP+5oCSCZqAQEZJbpnKiZeAxGLY2DC
###iKHpUWIKUbjEnNhtGFsRxKEGidoUstMYk+VXby+cnJcaoQUMMcJZczUd0O01UDPf
###UVk4eLeVWV6C9Z4Nd+muPdP3K6vdftB7sNlju1kasKDiNk33EVuUT9xD85gFnqTD
###3yPnMbvZY7tZOQ8EvJUxIzEPQR6pVT/RL1NBEasVJVUQDMqTURmjrmK8zRC2ZeB3
###cWTyNYgIt0NzYCkPRxW3ppgz4wQnfRlLJkAeGB/G/2fJJ7oi+YSi6QPjP8SNiaE1
###jQE9k0skDuvl2c4vL0HI6ESjGMuPpv0uqcykzAEiQ4zaSApMirlmAFog85AobePE
###HIzI9Gm01zsZl8WA9SMgrTqStmLs5omunNs4qH86+PuVg6FjyvygrJ5ImJzTwtCB
###SkkLEC8UzviANCYGywOWebNZe9T2Op3naYoD2FcKYAymazTzdPdT3JLdLrVnjtFi
###A6QraTtJTBNMY9H63pajPpfBc+d2Il0bU534+XKyXWvYJtCTwxbRexLE2hwpfm9n
###DXRms9K1I6PZcqpZyWi6jQSHZuzs2W4AaYseCSKyZs4lAYVMQHIJaAzOLFbfuQIS
###EjsXR6Rvhr0bAbJeo7aMNErh5PuYh1/e1kzmvci0+MiJzeaTE7OaLZaYE0y+becz
###4X1fxjxOjxpUwnI894CheEqWoC6fS5LIMJrl8XRKc0WiNAudlCTWNOOcz7YeI3tW
###hkFGS22s7CbCwmmry/n1qjPq1R6oV5tRr/5AvXr2HN9aA2WAovlQ1krPGvRba9Dc
###BhqgZLdRm9FGPdUGJ0HKbETJOuJESDBPpuhtH0ZziIxhE5Am9AlCl1+dQWjmjijz
###eJyD+/KmloYzZwSC2OaXwbz/3PjfH6cguLbawAvFf0r870rDbaTjf1cby/u/vyr/
###81r6/u9r5HRe3tQtb+qWN3XLm7rlTd3ypu45b+p+egd41tqFWWsTLfOZkZAZEwtT
###qmadohnIb2w/AqIUDDupZ90g8czM7kypgvzB2DvGdFKcIRBjgJ8gdS8M2IYw6PUO
###hl3xGT6Ynppo6eIUkAs7KJk5r+gRNHrA1fbQQIw6w7xVO4PxrL5iTEM1r6tgFzm+
###UjqbYWHU7x6Il3aXzCl2Rj4QPmrl6n7B7s3py6Gk+pUjmjEWM9lye9q9CiayKasR
###TCVUcoIODLADX4cdMQv+c3wiK+G3YXvnkx/2/XY/2L2fBGLCcBZ2AtRMR3YK5EI3
###6Pv3QfeI3hjNTG5HrbEfi+r9URy3IjjCEnBDvHwk1OZBwp4vVilQD9RZFgASw+GR
###tCgXbRgHf8KQ9AM68UI8lMlLAQTGFl4gzB31dPgF6DcHvcU6Q8+wwXGNkwiTGsHz
###LWTWqiVGker9edftiYuUMUgW2jHHmEF7kfFfytx/b/m/cxvFK53nFo1ny/91EPcb
###Cfnfc93KUv7/t5D/55oBX4QgCV3fO7srzgUcA2Ebft0vpDHIrEmy5FKXsNQlLHUJ
###S13CUpew1CV8TV0CqhJ+2Pn5oAWTODyitF9K1Ift2wuvSPyXibnUu1Hciqfj8Sia
###2OoB4qtmKQzSKgmVOezd+cWbk9bJm/2Dc7yLez31I+DMAyYVMowRic9wkJLxUP+e
###Q2Q5QTzBJNOBzDMsCHJ/dMWGSQgqon49OCr5og5NGPHcpJMQyAfQESYWQCqgOZFE
###24cDfAxybQiSsrwAFO6Bqr1mrWRc0IvcwZTB+1MQiZEheQb6VVmpNLx6zatVaRDo
###EcSS85XXwqZMczC8aBRyObxhF0wqjD57/ebBXuvo+M3rHJQiv76whx+/w19lN59n
###J8fVArEK8D8+397uY97gkgPk2LmywYtsjjMdg5DzCfgSkGeQTUD3UBioH0vWpx0A
###UHiebAlwS4ZVHR9ZBOls7uSClauVEsGvcncIP3fwkxcZuHGg/W0YBgyoyaPK0bDQ
###FoqnkHO3tsQznErR/q7Ksy8oZX6HaltbTbdR7vNDaBmhsLWFoNsUoDiF84V5jls4
###k/u3/n3sDHH+I/SNlQmwS04MKCqMLaTp3HQsDvEB8GQKGrKtAfGUQwFKv/sbsgBY
###H5YruIIzdYyZ0QVqKpyU8OiOfjdUKm3p4dpukgsnQ4iyPfPzfrHZNuflOBKQxTbA
###pp18WsA3lbs1WAY0KmPfYvZHZefLHLZVLm9X8hJQRz2sLZ1MgzvYJbDTKnfrwO4j
###ywIIArO+9gEeBuoI85QBsF9wcMvZiX3bL9JEuA3qCEewWjjAxmGH3QYRbUk0XYqC
###j9OQfG/VAnBrtNSiQWt9PxvUiVWj5ydwyrUO37y5IJ9VM67i+Y+wt3KMmPhDF/9H
###pz+3LvCg+xBeOtejfjfmzWzYBn3C9UQDaKIyOa8QFt08MrqOVyhUvRUd99TQ8Imt
###rJuvVy+buN5sw4JeoaXK3Q7/7MLHPf7Zh4+7jX38f61ExavrB/j/Br7Y8Q7Wd3eq
###WLx2gP/X4eMB/xxy8cMK/Yete+uN3b0dF1uv7h3i/9j6wcbufnVtR7S+560f1vc8
###bL2xXtvd33Gx9drhmrfnVbH13f2Dw7XdfdF69aByuF49wNbXdw7xf2x9w63tubs7
###2PpG4xD/l62764cbey627h3uVHYP1rH1ndoh/o+tN9bW9muNPdG6u+Me1tf3sfXD
###HfoPW1/fc6t1z8XW6+uNw936umh9d92rHhxUsPWdyvrO/vohQcat7G2suTT2g0P8
###X7S+VznE/7H1ytpOrbbXwNZ3qtVD11snyFS9tZ2NNTn2tQN4c7hBk/IO9zYa2Hr1
###0Nutrq/T2N0qyFs7ovW1dXejtr5LcN/1DmrVfWz9cI/+w9Ybh/uVg92GaP1wp3pY
###WzvA1ve9Q/yfW6/Bh0Nsfb924NV3N0Tr9cOKt1PdwdZ3D+s7624NW1/bq3q7bgNb
###36/Wqu5uXbQOoMD/N0ovPm8ilqM5/3QCHHqu5Rda7XKrk18FRG51EZNvcV8j0n+c
###gnCCprpAAG6GaDQMuxy4diIEeD62/JLTwogDHU5u3+pKxt6P4FiL8OiNRyK8QCzM
###f+ULddIKUzakEgkjGj6gOtMoglEA5cEGJqirpiMle0/SITca9u9fMO0L+fxudbea
###dXNvilAI5uaE4zruhp+q3qjbtQ5gmKf1tQ1QtR50SkiyW106bemKwY+BOZnkuFui
###c5JeKYgbtKbVvfyOCZKIqZy1QK3uY5amC+dJwIQbHk2Bf7lXlBoLwunO4DVnDbwM
###8DnwuucD5xNRf6QcQPvJERoDwnLej6bSkHoai4NUmJkzUkhcQPnM8ISAZuMB8lGC
###LcCZdZNLvmkvN3a+8Ionl7uWp/G0eTydJ+LmNNbWXTgcMdAFUQnh/AW4ZLU5/LQp
###WD/9M/Djm/RTlUzJfgz8zWYKQcV5n8LaGj2mlhSP2er+N/xDXowb/9TUOMwvRL6s
###S1W3XMaP0HPTNZI84bCb8LDsJrZGrtUWTeTLuVZHfi6+IJNaLvAd1s4XsToU4W95
###VcvNF2Bg5nbSivkEN4CaNNhsO33UIVxdKz1DHACjBlJE/564HGc8Jd4y6EwAtToj
###4gTjznUwYL0bcCmAeQE5P5G2ynl7H/kDQMWfucpPeLMQ/gs21H91gL/8/TCM1xuf
###ETnPR9CGVsThdgV8BhYTNqY/dAI/QrQWzlb+eAwPHJ9I5fVkMn61ujoORuN+sHKH
###aspRdLX6/yYTVh6uUlOs276eDPq82XE2qCNrj0Y3zijCCQ+vaMxCz0TcUWio1WB8
###0OIgZuIRfBr1CUKCNUa+F3aPULeQguXi2vIQI52Nb4MQmeOhYoqRTbwDojBkyOZZ
###seh3bmjNu4F8DKC+QtFiyKbIzCH2fZLQpkMS4ODE+Dl3WvqR23hHH2lQ4mmTtVrT
###QRv6JUXbACVEUZWdaIJx3+8EqEwrYZFTlAhQuTnxb4D4/kjAgsVx0BWuxBTZJ2dV
###h2TCGJdTaLX8zjXVFnWhWp/8K0YIvFy4EqyQZsMe02m5Cy0PY0aIKSyGBTwhb/7I
###D2MicW+A+oAUg312+OBgLRn8/yn0if1WAPhxu+L80wGinLtpuisrKz+WgGu9KXSu
###R6M4gEI3efn5x7JbusG97rxyXBooC7fiNS2IkLFHgxDGKlcBh7QjyPaoJ10PkCyf
###brkVWpof8UMfkBCVnjfBK1yiD27lEv/BIFkQ+t0tAfMC//iX9TvxJ/XXqXwu6UY8
###fEq/rN+JP6m/jmc2UsOn6/jLpQJug5viLr2aaGud/1ZlI9WG2QjWcalIlX43qBG3
###wi3WuEl3gxvx6qoxqxF8yu2v40e00aaOaCSNClfaqIs2xXd3Y8OcjouF6/jLXcPf
###Nf5coZG4G/TMqdar9Le+vsGz3PA2TMASINbwl0dj2KAHXrWBwKhXqzTbyjr99Spe
###vcGN1iyYuFiYZlxrQHW3QTCpbdTwi9eoUZPr61SsvrFRoUbden1j3WykgYWxkQbC
###xFun1YE2oJa3VqnwmxoOzK2vuevYWBXAum41so4N0UTW4GOttk7jWfPgT73q1rFy
###bb3hQdPVtZq3ho2sN2qwbCjEImvtCKKTojTxFGiBSW54MwHjc1p2nVH7t6AjIk1J
###WsG3J0AtYB9qikNqKbG30ecFr45o/Kpf3toV3NqwgWHf4zbO581LK0kFcvwWyuWd
###IpMI3O+rHuz4yoqg5UBhkRUM7oApivkc6gPjNIBhxk6njycSnQNiAOhC5/d7GdOn
###mFNZEKD7jTBCwkhwIMKSpphEVuRRDVQR2TnhycfDoKNG3F6wkiW2DrSSMUZ1TwGc
###h0G6kITejqIbJrJE3AOYBamE4NDPYgboLI1L4jJHENoVjQlCe3Ib9Ptl6eNLtLBZ
###4TNZ3cYEdxOm+2JBKybFrigqTOCS423D8YhXLfH9YBBMorDzSmPCu9yPpdO8ONfw
###jBqEfVwtJMxIcd9lUtzKE4iu3EPwAOmTS4SHqY7xO/FH/01UrxLJoZdrTHW4EdFW
###VbRSF3/XEtXxORfyqEiN6zX4z3pdNMbNuLV6ojp2yRUbWMT1qHevStWrazyi+ho3
###s16tJqpjaeqRK1Y9qtdY50fr3JjHYwI6uWFXpznSSLlDUa+xjkOpNuo0aCBfNLJq
###ZS3RO02KZkgDFf2Jeusb9A0OF5peDYhiAvIIUgYMzU8Mk7tT1dYb1Q08PtbrSdC5
###2GUNCwFYSjS7Eo+yxL3JatB0o77mbWiq+QvvAb7F5k2gWDkhtgkeky49iSGFLc6o
###/srmcAT+F/lD0SXSJ3X4p9u47X6E30zfprEqRpe1QDKGk3gOm2ho+JlmBX1iFklM
###jvGOICThFPrD6IYlgxN9TAcsdRPxEA7SKxJMvrzrGBIlVHyW6ITZrRJqZjskpCPg
###AudN7jTvSB5bcvxvcoNwmDst9EdXuR/zpdPij8DtSY4bla5A9QKhhqETzBfdsbq/
###La9pr8N2aN3DILhZ2A9gjsQQd4NPYQc1Gj8qQTwWpeEDhcyUC8U1Txl2p1nFvUqF
###GfvdEV6+SPYfDpCA1UQx3lyDFE/KhE7AkgIUSeCKOADN448/imOxZJ+t73Txd7r4
###O7u4RjXCtIogwCCC9oKIdDZ4HlFoRH3NP8HzAJHmR4mZKEngnX/sAI4SZz+MJ9G0
###g5xANLrFFcf7CnGbQMsSi8sJZgzEEQco9ykcQRtUSdzrwy7D72oPILKASMYCMOLK
###jxpZaBVSSMGTepPDDRoMRhFxIdMYi5AuRgq1VDsWHsnyEv4XPli5SULV9jTs0+WB
###uOMPAKoe7RkYNTZBp/JoGpGgAyC+9aNuvCLbksOjtuQFDFkAOsK0RG7BrOZQ2KT2
###hJQTdq7l5QM6vdNdj9im4ykxAu+Sp7zAUSF+SVMFEFEV+IUYpE57wtDTVzaC5XJe
###4RRVGAq9ygLTPHQV1AhHT2xsc3m/sGiumQ/FGZQMHkBuB3HFgY3AYC10yRzvj8Z4
###t1054h/FiHlv0IjLuHgw4lO9RfCJOWJo4EFMHxpKOYH0xmIyLWrf80oLuqYGzOQZ
###10CRRFpZZLJluJpYjSD20YE8QpIK2OutVqkNQhM4cRBTeFckN4LQUQOjHtNuILbd
###8iSnPs4TgI9l/Atl2wJQYbLELcqgs2QigycCbZxDZBy3hQyNpOWdVnf8LIFyA1RB
###cNVoiIRBSYYOrQQwoFdRwGRh1L+Xcvso4gCTzqlk+hl2veAWxyGW3GUUdSVN9Pg7

more base64, still a whole mood ๐Ÿซถ

###Lb98VhVojA+9fAGOVfmmJhE8V4N3DXy3Dr/K1fxqVZapqzLUQI0aqGApLFpURWG2
###goyLMXkl8V2MCbqQT6rqCbSgyonRrBdy9Bhal6P4WY9C1MEBwN+G7F3j7wxKralo
###goi+UUdtximL7WLz4vBzclgDdWOBQX2pK5C+qG3WqFT5IPxPsv45PmDlIs/Fn4K0
###FDVfXlyPBnBonq048LIDyPSS30/CST9ovtyZqa8U5X4D9B/6/ebLo4ODA+ciAnLo
###ywN36Bxpy0HEHTgKRLVPoz6ITlDrolz1xDPmeZo1/jb2r4K4+bLeWC+X6+tVUWYw
###Gk6um/9n2uev9yDbNYH9bCC3aLq9JO921bUJIWfrhuizvuwn9lLSaYCxNIRr3TQp
###BreTG/h3P37wLoEXTGv3VdS6KapUPZ3IFPpJ3frcCKW6UGy3borwDPaffbtD+IrD
###nHuVMOT+6FLg4a5qBSuSUOsm0SVu0adCppoNGXOwBJzqo4ADWz0xZKQcADI3Ba3q
###gtCqLgot6Br+V8laWzfJoRRTa4aU7MFREBhqi47Cunf0YOol+g2kMTWcWqlaykCj
###2oKAWXhIuVwGLGhZgApubVUXuldRl5gmy7naQaow5FPp3mTRCRWRgY+FBQmflMRX
###fggvP/x22YS/ZRc/FfkJfCnKZ/CLrvumYUVpptHuuYO/eorxvTUGkYaYcDSBsVqX
###dgX4UNJI3Q+G9iUe9Jm6rpuGdLelatHPb5svlDFWd1TmoOd06Yo3G9FUGCxHEWxG
###AC0ws93R8PsJX77EQJt9IVxJzRir9TzB4rB5zG9Nd5MistNLGEdTJPoWf2CEAMIS
###/QGo5Us0fjb6kQ+b+Ew9qjTFbFSc9mLxty2EA1VLVPqcWnxTBnkqAvDCNwUqlBUC
###lL8CAuB45yHAv9vyc6wn8efZlv/BxQfKBKACmlFCmR01oPj3HT5E/TSRV16yV84b
###EAjvMEJiC1eWzMX9cChKh8zshMiKf5BVL43VS1G61hRWOWeumHEmlRJLm168gZde
###PMD29EO6fIc3TaSPvLq/BMpyTS6Z0mNXpVglbSCQ7vKymeQYGtxuVgV4P1QumxXx
###EcAMY8PkaLOYIBwBtFr3yP4DkUfKMCQQ+Ki8bgMHB4JQd0rWIGSMCOIJ28KqC31m
###vlAUaUF1amnC9rCkAGsHbOx5gwYutDrD5hpNJOzBkm01G3lpjOf8ru0JW8MmKuBo
###VtKKBLgOV11AU9RC/aIi7QdVbVeiiFmbsAPkSVHYOtoAlJ5p0ghcTZPNF02vCrkb
###+6PRWG9JMmMlSjJF7U1m+zfKYvJGZCvC3QdjvLls5m62tkDs4mR2wsyyWLzZkpST
###pIkc1ruB/bR5Uyzm+fRpTUF0Qiyn4x6tJGcvOJpDMohtHBa9WnvDk09hfN5lE78D
###RrlNXDJjpDyq6iaNlIal09DPVlaUZ6sqBOAcARdEYttGBkdSmtI/j66di2ITClNh
###gNp2E8HWjgL/ZjPRmtu0mCjRmEcN5m7ILoVadLXV6+f5/Itm3qcfWjeXRfoDRIc5
###n1nWpauFM6rFx08r/H5i3frhBoPdJFTGQAWAMNAdH+cRwqv1OJA2EyQMBmQvHIMw
###BljOFzlxPOqEZPYgrQ5Iw9C6f+WYnYsbKqjNlgIzzjoklqEr+EL7WAvJEqnQus9L
###k3NK9hM3y2SR3AqJKN0jfYJdUIzz/x0L+v/1gOB9PSB4CwDBfDXOsLtKP7qnM3/c
###FGIj4tC7vARjK9xujpnMh+Xm+Duqf/9bs0UIDoQKShQJebmR1s0/VTv5VxVVkauV
###ZT1ekvvfxJI4cpFhbjCf1r2War7eQlWfbaH0ClW//gpVH7VCq4XDcChNxNnfAyFG
###VyXEzao281vNVujkJpZHCROxVrjlubW1mrvuutUmCuicKUzwBYAFMIjKP3Nh/DGC
###WaFsGCJ9JLxgJNCYUX0KZnjPhhmuu+YlEAOxgpxgBGLUvgJi1L4iYtjPbvoZzyID
###gWo5oTVYDH9+kbd0MRrWoVvTtI35fmDKN8Roabs9qcxlx80IDSWgEnvnIq/H2IQ6
###Yzgmuw7AM+j3mOtGYzRysJA2dzpMM7khO0ciTDRJHOTrQ35TcYDOWajkYwUuY+RN
###n/nRm0hMA7mFzU3BIiDVuukXbyJJtkz0rGn0pFN9vNUKFWuBjCMc8lDTOuOhO9YG
###aX8VcgDB6ttQnYYhGZeA+VtR/fOjtkE1tQ0e0nA8apOkdoXaEq2hurh48rYQYtQJ
###uhwJ4ckJ0OUWhA0tMnEc8FvokW+M87i25Me2IqB9hCMdYQAgcm1jc/BuwBcyfMXL
###Pt2cxyq1FXknDktzN2SmAIbvfkuZIg8Fd/0b45x0kkrt5sz9nL2jCSEVO0eFrZ1q
###7VVjt6p6lyY7TzhIL8pl9UohnYl2hHi/2YjnCGVDa4rcvlfSPlFSWBCCdooos9ms
###oAd845tAvh/n4J5JkRdgLC8yUA7v00YYWGDKd0xtokaBlHDD2PmRqt9ozP3xAat5
###xCBXBHSRqMJ/WWUJf5vQT442sKVhxwdblccw588HP+9vBT9vDvyswhkHGT1qimVA
###Mlj67oZN/YtNxXpKAn5TTKwF0m9ehzyUl6UlN4Vrd2Nqvb8qTlf/VmtSfZ418Was
###SfVRa1L9q9ak9rdak9rzrEl1xprUHrUmtZxkGrOX5DGMyPMtGHAJD67YU5aMQqMA
###W9G6oVaGHb1yUmO8wALO4TQK0GbJXl7byypL6Zux0L/NWHvm233UiU6H0Qg5bMvg
###RDmRx9rbezSGsv0gjh3SSKaVvlpRaeh8WRHnbt5sMROMqri0atGk2a1hWaEjcC7D
###sicQk6rZCPmbiZC/CYTEcoIzYh7kN3IKF9cJQjtpcit26xntz+nhM6H8sMP1i8Yb
###G/8zQkMQz3kVTFpC295tIV4a2YGgYfIiNfEEpPQb/kTBFCTfKVaVXjebFae5jasW
###Bd+T8fY12X6PgPnMWDWsInhU6k4tHeZ1JoU12gT9LtWqjlpOrEjrKXWZVPsGrbHd
###ra2W9Oz/LB3euYmfd872D/aOzdup0lRA+RyDd5xf7Oz9yN+BUrzZy8FaYVdF7525
###R0QV47IENx6BZ2qppucPtqlDVtAC8vqVGLrczNkBLNqZMbDPL0zdq7mmRM1oXclu
###JmgxOcmg1Hrfy4iJ+Dt7T2do62cr02OgeJ1rAIZAeLo99F4pGVWfxKXvWjcqGgOP
###grrN4adSWBoqTZ0o9dkQa6nZarLZ6qLNVuc1W0s2W1u02dqMZtGLwp/2J2z997u6
###2HEewsjE7YMKVZHEVANXZyCqmgwfEKXvYNQwq+n8Oam3CSScvf5SxWDoEMRsPwvU
###JGMshZozkZIiROJvjtjyKCSchYVaW8cdiNliHEoD2wAu+c00rmkdR3bl6uzKtVdC
###zTazci2z8tPR5ikIwvoHRo/sUWpCh1QubyPQs6DIMr7mv1/8z6CDIXDD4TMl/3g4
###/8daba2SjP+5Vq8v43/+VfE/q+n4n5nhOOeG/lw4Vcgyfucyfucyfucyfucyfucy
###fuezxe9cLVAsmc5oMAAKwglv6ZgYj/AuD/18xn1/gqStrDbbaDwJB+G/+NTAjHU6
###pify15P7cSI1yBZG8Fy53jaesOmg9czIMtJzvhFO7yCUCT6r9UP+xbeOiMNnPHVy
###bl5NRBMEMWr2UCBLWDHsoOtw1RinEklFIQpZg7YIAMZRaGIdD0D7irI3GLphxdM2
###eYOFFCUrHCChpYOOjlQReuCXQA7ZAC60OaBwNkjdHTinofqwM4rGo0hpW7nf4WhY
###3jk9PyIPogDDDrAtA8wX0xZEQ+eq03FytZW7PI1J5DEVZBz9icy5DEI+0Qf+HZ8G
###ncHok8OyFat8fYoXFI2AnlLic1iRcBJ0sF9tUsCGoKSUbIeT8uQ27Hb7eEjJvuTh
###TZEs/ZjigrGbYXdEpgbS0hVNuWnJAM8m6KU7sbpEAB74UT+EgwnnqeaSq9KEebLA
###j4zoDr2rDFPJ69Bc0VD4BnJAB2mFKrSsFATnOrjXntbQZi7Xaue3cy0/nyf7B3Rl
###6t8TussVPdhrnRydHkGZUkvkb6VoUxSKFJ6UqfZ3ZfqyRV84T+QesHpk20veWejw
###rT0KCU2klSr5xMoTk6xVB2PWwWNFkFRDdAzLl1BryH7fYttw1Iu+YAYINEbwNRmY
###K68isNEu7jlq052c77WAGuKOU1tWijvbGPBy6LT2D3bfvUZWT8cNorhxQ2N/te+l
###NM+QG0f+1cDXBXKt3XByDph7FlBUNgCP0N+3WmJjUiqOTqsdR9owm+Kvte5IzWE/
###BAaQdKp2s7nv4HkJKpjOKmiNSMU/W0u6d/x/K7SSbj75PActOLmyGE0L095/G/QN
###uB2c4mnZujhq7Z/Dib5rwu9lNx73wzYRuKzuqrP6a/WBxRqY3bVar0/f7bWA8Tg7
###+ClXLdWoH7TCvmid7LzfbpJl2Hq1UVuDF1md0eTxtmbU045MBeA2zlq7Rxf5VC0x
###khY6XAPutTr9f4kBOTSi4zenr5NdHz+ib1q8Rw6gr0ZAWhQjhqteD6qLSYq125rV
###hkRaGWKFYre07sjU2+8ASe4KJT7dinU6aa47x7y6ryL07p6fmeRGRDqU+zbGfQpP
###79Ybeek2O/B/o4wxyisf2HzpWz9EBHYwSxJWRFKhvNe1z3oJ3wnPYElOUQPXTZIr
###DseHkBQLUtbQJeSKgxdivxFlsexwPqHyMbMxWVy0Yi7H/1z9zw2IF61eb/J8OWDm
###639qa9VaI63/qS71P3+O/mcR9c+JH904uyNgZCKOK5FIwvLiUXogkU5mRh6YFy+e
###UxOUVAT9XfRAthLIKXyhFkhqXnQM9qdogrJH8mhN0HMMxtAGOUuN0CM0Qs+gEHJe
###kjLoJfLaT9UGJVVB0NaTlEGZmiAc2FN0QRmKoBfO01RBth4IWnmSJiihBsLIKI9X
###BGVqgRDej9UDZSuBeG6PUAPN1AHRsi2oBXpQBQSNzVECsSqBzxGinxgUG4hTSNIu
###b7TEofZ97Px4dH5ePjy8II3ANQj47YD32HXgfwoNW28O4E2RIOMp8KhvgItyrGAc
###Px69NRLHoPlLRj4ZNslO55RxUqy/LNSS3FnrajqZkTnm4VQ0mYlnQD7t3LRQddOZ
###1wqDFYQGTPYCcOmSHC7ck31h+2WH/CFCryJgCX0RnY5I4YwokCImJogUdyI0SryC
###Nvgc5QXTrUbChf6m11LaC63EYt2faYQP5dq9/r2Xy+ZQFDQ74zs4+YBFmcy41GKb
###G5TuWhOnh6dKN5hbVDWNwwmcQjyrZZRLBnPenc6rN8h8xzYWWbNjH1JjhKzkCkSR
###yS07jlAi1BK7B2S00moHV06TPm7KGEC5sFnZDLdON0NhFiWtbrCUKEz1ik5YGAw2
###jbeeeA2v1HMYCUZvnZS3xQhj+QbtsND94betweZv2gTr9xfZqzrZ1C+wk/J2BA2f
###/3CWE99Kjpvf5M+h9SakN3Ztz67umfU9uwEv3cJe6+TdsZMDVsIp8MRLTgFmapbB
###iRebEsWsynA25HRF/gQfJo7dx87+/sWbnHqdeF8sajwwn8gHZMyBNmn2PgqX++gJ
###+ygDE/+9txZh8N6/JwrzUVD7X4nCszAVlqoEvzz8VU3jZNyJ/Enn+kPj0sB3MfOB
###1/QKg4zn1WZVPGdcR7vxr4/tMH4MM37r0e85GO4sguK1nJx65bKEPX4YXApMd1IU
###XRd2ZWFPlPbmlfZk6aooXcXSWcfVW+u88vKpMy20C4WJQmLjyY7r1B+huKOHnrkH
###U6VShXSzNA0NN+OLl2zcGk5t0XoStisWTPhJBljoRZgqOgM48n0KMlV7EDOpG662
###flHwrFdV81V1HrGzu03OiOeuFxK+Fg1AroSb6RqhXSN0ymaNKFWjmtFJeX4n1Yxe
###irN6eQTDsaTWS2q9AEPyGGq99yhqvbcwtf4fQmP/3alh+dHUsPh4alh8PDUsP5Ya
###SlXS2c7+0fvWxS9vWm9Oj3/N5Gmr/yupJNErgpsY900W2aOYzIPNRcjqbIpav9Tv
###zKrBOKwuTC6xcILQfZB7YHD55RTVbcIcmll09KapiqlIiGK7HR693z/6WZCgan5T
###PxL7JeuhR09fJEhlmq5eZgiHdlEvRYIT7SLx0zSgZHShm0iTL+M4eLDGIyhYNvmR
###bHrZ+WHn+LD15tAY8EqUn0GCJN+eWStMQ3f31/O9neOds5xNxRGpoL001NS5opvN
###IKCengJPp2g0n0HZPD14nkjZLB9lg6jcnN8oEeHmzIYSBFK44ZbLwoFvFuv4v5go
###lpakcCFS+PuLh3nDmTRsb0nEnouIlf/3UbEHiRhzdvWlwp3Wv1KiPy7/8fhPlf/U
###TOl1OptyudXLh7T2TCuypNHZBDObHN77pfv2Qkp+LHPvkxycTQnv21kvPfl6cpsg
###dM9wbVBpmshKkKcnlaJ9uyAeylNFPK6Kx1X7cU08ruFjU8J3pjBQZwoyPuySqZPP
###5FAlHtRNdtQRWJHx0Mt6WM16WMOHukeDMjVFp/NYXUdiJizEh2lBLM/lPJbXkViM
###VbzCIpWqslKVKlUXqlSTlWpUqWZXmqliWMs8b2qXc7QLbmWhOlY36+ZZZtP3Wd1s
###zK5iU+MKHmUGMV6zD4X1tJxfwWPMrhHaNUKzE0sbYBN9qHVuLQN2Xrr34RRNvVqn
###V237gLXUBvahk9V2OLvtULadbrzBA0/UcSuivTDd3oZoL8waa4PHWk43F4nmyunm
###ItlccsHFjtKAKOl+0hglUHxW6fRgXXfhVWvPXjU/e9Ww8QWXrT172WY1Ljidcva6
###tWevm5+9bq5ghTLXrT173fzUuqmV8EoGKEpGR+mNLSja7PJJ9qmyyX/dTXkHzH+r
###4m9toUuFJVO1ZKr+VzNVi7A4e0/gcfaexOTsPYnL2VuyOUs2Z1E2pzybzSk/gc1x
###ZrM5xSWb83xszhwup/wULqc8m80p/puzOdJUPDM2pGCCOGCbSMqLIQuj4FOLssYa
###DBEe+QnOx4wh2TOeP8AFEfMwbKWem805Pb9DHjMvHmSYXsw0lMCOxs2CaKpY3MRA
###ipQ9ye+Gdw7nrzHKDpJloY8rDG4J/WG2gKvJ9eqYzPk5xc84glo9J/cS3/+jm/j/
###v4YvS864MCgB3+aMS04MR57kJ/T0ndP8Jo8DA2EORBxMdSiraO8Js4fxDLOHQk/w
###GsXfDHTrmape1beNLGb0zMf3m4k8jrir7+mJAxyMuctFjif5hUcrWSooM0ijOywa
###ttqe9jjN/Hjap4C87Xtn7JYGbmnslQawECsrKyI4vcgi74wxWVbBGeCfJv4pu5ec
###Z7UC34dp9lmF3iUP4ptei2dDoQ5F5jsDmWFEAjcFWtY2JRpxPQcnNR7dBhH5jwHP
###or94lIdrKDIBDvxwiE5xgH7obCZyRlkXuCL/3ND5hzO2ODwVNNHJpV4YcQydMd4J
###bTpWholEKY9LVWeWkmENoVhxVmufrW+4BcbbVa9SqTh//OGoILVVLz8uWN+cbWeY
###T/WI4xlu6u+ADcORMxhFgUI1J74Jx8L1zlHptsyBDJ3VJiZLEAQzYWZhDfWbpud8
###9x10+03TqUl/cnsy9bwdz9GxgS5iM1Q2MwZSYLQpFp2mTN6QfDwUQUj1gm8rzwLR
###NOeHtRJQiL0qhZhclqDFr0qErEOgb7ZthYDN4dH7g/3W2zci4KMhB2EVOJRCjWO0
###ep/8PmaiuEb8gWNXXZbA7ukEd2MvJzsugnS5f/Rz1cud/3AMv6lKyV3Ll2gw8nJE
###QXxu10zhu6Mp5kEfh83qiltz6xteo16tr2+sbVS96nqt4TVq1ep61VvT94BcQYw2
###55S9wjh0VrEDkJsKTnL41ui5mh6oDI66Wnjh4P/o5Dzq+Jj7E72jhkEniGPKJiOy
###IcZjv6MzcmKflOoaPfCx+gVlAaQlpnjhlPSaPK7CqykmEW1D8zcUBSeAHXC/4jg7
###MeVcKmH1IxVAoRcF0jUWP+by1DxsjeRRSyuI38kXTKOPRJESYVcB+yuJw7+AxyZ+
###n3V8Y+pRSRfTR3vz9N3xscg9Ii6rgwHGgIABNx0RUoMjTyRq5/ms5yHKzS9PbtyZ
###YmBN6sKSguMJLbbdXiGPPoCtw0MMOEIhVo2hyFDAOsOg7AXKIG2gPoBQFLhTZ7up
###a9tUjDtP9g2Fjf0vGjHaMJP+YLdwnhoTMo8iPp91Y7O3vsF9osYDF7hJW0sZoCV2
###vyoad/w+bhh3ZVVUsAkgjpBSzgrI5LNJo6lngdawRvraXnd6HfYQdhXrjSSLMIyt
###LV3sG9kcbWVYGP1qy4HjJXGwqLfAFr5IHFfq3XYzXfFqBAdNzw/7Bnm3+aysmRof
###U6Q5jYdiFyQL5gtEKK3xpgi/JvPpwiZQZdoo+3zC6X+j+R4iAVhL7Lb8jHXNAorG
###Ndi1jKPm4YytiqdNR30wYtjPBIsukgKIXD1ujwmBvYAZI83kcyslMaiS45bckmMA
###QbO2n81DOYZdgQ2/0lmacLsT/VU1RFmmgQCi+fR4ETIsxSPR8iyCTq1QfUW+CTib
###Kri3PeJs0t7pXUmmASBN3wxU4BawtrWMUEyuiI5oztX1Dq3kE0Ijt5PeK1RLTsuO
###tW5UMQgtjnIzITvPjr4voZCbqctPvCAC2wuHpcQTYP1N4QAFlIFOzGUk7jrWH4WA
###9OFk5/3hzh5GLbjUL0P9kYCmZA1jW4vjv+zKnSZ3uyZpFeefRoVXjtQGG1HaPScH
###E0KK2iNz8JdHw/K4j5wL+stjqCnhIx50X6r0ws5uOClHHKpMJGOBXSXHYfBy8uRR
###WnVNSrC7D3r/gtiGchuMBT7NPaMyKq5ETqGpz67NeUXDRFHjcBNkTK4MadEF5Txu
###VjZTYtpYAFvQig9e4fhS9T1Iv1SJ2IxO8KHT1F8vC1pUOJbnlbSNHHzTlNJBRvNl
###2bxYAHiwGW7jOpTLCeDjlgy/aZobke0I7SbDsjFiSzgSxfW5IqXSRAOXqgfVtxA+
###jaaUMz+hoARFeAlHPiIu0ODSQKkg4DnsLsvRKyGYChk43UHtizuYYbtvdlzN6Lj6
###nDOrZ3RQ//KZWTzeZxOLZYLqz/bxET4v5bQJp6abmmzOo5qaaCZo5lySuRDF/FJ6
###+QC5nEstHyKTL7LJlaRWBrGaR6vmk6oFKJUkVGk6NYdMzaJSv7+YSaMeIFE2hbIJ
###1EP0SekaktRJRUh44g6zdnCKNCl3yC9rfS5dSpElZUj/bFOqp1uvf+mUTIL0+UWK
###HBE1Wub5WDz+IxHtzjSejAbPlAJkfvxHz6uteYn4j9W65y7jP/5V+T/W0gEgKWBj
###KTOY47wkIK+j4GoU3Tsn/h1m3p4R8REK/sLx7PD+JhFakrShiXYcyhlSgIr/SUEi
###EW9XrvFrOwrx8jMZj0qHOcfThLKp4c0KRe4O5JdpNxy9EBkkl/lIlvlIlvlIlvlI
###lvlIlvlIniMfiWS837x9d94SWsYfXnwrgo7bT18kE49wKQrXKG9kWyAX96cx/nsB
###JxMmzHi591InFcw0A8rqDrYVAo0e8ec5xTAZIGwCuzRJU7PrqJEcHF+09hZo3Mpz
###/GDzolYiOjtyB5oLoMwZpHHA7MtDkU01WnHeQJPiiyiAYfPpqk0pyAIfxEGg44E/
###WMHbVEwIMQwxOUqI5HU0xLNa5A8JrsIhmWxwwHvWtoqq+yOnAMdRAQ6tsm7AGBt1
###BrI/RicF+k5skeBnDswxEouCuWgQquJSFOOP7hHLLoumnmwyUM4lHOiACgxAiC9J
###QKSAQLN6HCBSQBD3HgsBYu5094PkdMUTMV1KQ4BcSypEqcGRGZfycFp2YKiYIoaD
###mitc2R2JU10ijGIe4bPIV4CHrgETtjxCbiC4A9axf69zuOCYSsxC3MrZf5xCtck9
###1IAhtinDzT1n1vS7c4GAGXMSX8X092guaDAwDG4ZEFx7hZlb2RXmYeAZ6O3hcDxW
###jSQKliewAekMgXML6MrF2ZtfgRJOh5Owb0KI2CuzCRH0lfhcGfsVhjO6h659GAxK
###CC+c/xz7sOzOYeyc+4Mx5d+JcEFybC8EY9xo4Icf/pVXhQlRWpSl/ZTixhJzhNVh
###8rkxhqi99ofDoJ9nfohDAg8Jr7Pkl7HfuQF+LBdg7iBO077pNGrAv9VdT3cbRBHg
###KidrhznwV2o7F/boLg3ZNvFcwjoSxbEZcUG3g8sD6MGo1yUo47GRRajtVS8Y0noL
###q7W4DcOICiDJ5j0aSPy9QOPKC1TZ56VAXLHw5A2m6unwrkHTkx4GPcavs1d5GlNy
###Ecr6g009sNKMUyLLUdsoOgMEWrVszlvUyiUBhC95joqM4oE8+/xB0Jiti3m2MLc6
###Ak/osrP6YbgKVIvzmZvQOm9WnANNWYmKYDoUYO1v1TYUhwjtgI4//H5CyVCuAaYA
###SoykDOx6iPGW/WGA5kDcVpxPwHdvHv0DyUmkwIKxk5QbgegSdlDGQCMhg4Y7OZK8
###2oGmZck6fqzzOtEpWFC4obeOBJKxX+WjzO0VE2VSG0zvnVNr59jQfXAPKYzIWnCx
###kxZd7uSmejyG4dGRyxgcSn+PRTpjOxskXYBFAhhatFiL1AZ0FtyBcgbpTWhMQg6N
###H+HI+HxHpgx1L7PHpV6MOwPn7d4Jl0cC3uuP4ERhTBYaEh8l5YHfh1NjeEWtF1fL
###7kqFzN3Uz7k4HEQVLtsO7kdwqnN5IlvqkoZCwiMJt1oBYHX64XjMlscpAkhJvoIr
###mMbO2yNiGDhZmdWGlQtN5Tu7GSIN0KobPyJLVjGe2GoBBYAhsmrd++HAB96ZZkMH
###diT0NdC+4EGsmsa5KU9L47DUC4LmMFFAPAJyAcbXrj/xcbxCJeBglysy49s9J07r

okay bestie, this part is just more of the base64 source blob from Appendix A.3, so it stays exactly as-is ๐Ÿงš๐Ÿ’…

   ###h0AScOmQoyikDlvMX4h6slZ8P8TsgGGsOx6291Rfu/dIRU/8OyB3AxEfHpe3Tc8B
   ###dZGx6BGB4CpyEWiWVs85yil4TYtOao/RUBRjHogYM+OAPk10JmcLhV9qYLxccX4R
   ###h7yRrE93/DI1m5fANVG+QYPAAuR+3j0jbCGWgTNlQZt9TCQYGWh81IOXV0DCPwUl
   ###TR4xb8Go05lGeELkUC+pySYcC4J1PzrBnbwD0j7imG4TB8IuEIpRoQNnNAiuR7fO
   ###BFArFgpGkT1MCxGSm0WmR7eoFKxkqA+r0u7PpMzZlLFFu3w+ZWRCUAAsSzM7Khkb
   ###nlROQS8YFx34d4ll+RqUSgzBbZTboaRYTm5Iq0fpHvxhPrFlE5ucRYi/xZb9C7eu
   ###/bPcyH/1RnYes5Pn72HTgPl5N/JPU1Qn0AEMYp3khghPA2Bc44f3M2Z2BebGeSvr
   ###kKqAEQ/W5OOUhHVRmA31344oQwkholP1aN/jMOmtRskDzdQ+BpTAn076WfDEi7VJ
   ###FHYmDkIWK4uxkzeUEIWk3uRxopDAkOcShSyN0zxRyFZNsRj0QvBff6IoZCYkkwbL
   ###T5OJJAp+dXnIBvGszZrWpxWylv1PE4hkhwmBSA3uSwWiFFj07t8PnkMekhNIy0PG
   ###HPTIFuAyrHGpF3SU7yWOdnEnSiKJb+gRRB04FFLHIMwT1lZcAb7EVl4KjoB0fVp6
   ###4HtLqm3tBNWSPmvuTURfcd7Rme6Lw0+QyF+Ojo9Jk/jLm7MfVyzm6Y06yHPzWZ48
   ###ds4A7xLLJRRt1vjUsIi/SgiOK1nEmPTcixFk7jzFpWaga+IAQ0AztsKilObwsEtU
   ###+QtRRbDsWH4G2z4Dfx6DPV+CNw/wTdlMkCSBJhPkzMYi53GMkPMoVsjJYoYeBb4k
   ###N6Rg+DA3lHGj+llfoyrXEOuOFsf2P9X+b9CLhlcAvWcy/nvQ/q9Sr1TdVP7namVp
   ###//dX2f+5afu/i3AAovS9swu0Hhi6EIh6dD/X9C/DVDDb/I9s+Zb2dkt7u6W93dLe
   ###bmlvt7S3eyZ7O+cbkVk415IsTdD6If/iW5Fx2DEfOzkX3yi7OyA+xMRzwuM9ZML9
   ###4UQocZS8ArL9+F7KLatSf8oW5BdK+iGJB1VZQBpgc6NLF6Y+diZA9bCwGtDBXuv8
   ###15PWLqwoqrbX86KZyWji95ONCesVbWGF+ooouAIaiGmTE+3uvdk/EA3nMH4BNzwQ
   ###Cvn4ftAe9ZkbzxrRyc57Urbn3HdbW8Yo82UXm9oVk2NnuDZZUQ3wbPBly8B3s475
   ###Gk6K8igiwWMU06mQOdTzH44OAbXMkZeNjrnfPR+YEISGBILROl/ocveZPVy8eUtT
   ###YkuZKccbct/lt7bsXt08dnU8uhUNP7G7XSABjp4Q9L69bUIyG2P8T37Yx9gDSnHY
   ###9/FsAtkKjcw0eFljiexCLwz63cwhHLyHvQwztqbn5f9hDKPoqjBGS9eo/6X+X58+
   ###rnSeXzSa4/8FXdcS8p9bb9SX8t+/hf/Xk3y6ljLfUuZbynxLmW8p8y1lvueU+VCR
   ###/8POzwfA4J4eHr1GFysl0sH27YVXKNFpHyn5DijM9WhMHlZGhdso8QRYI+s7HGjX
   ###9pNR3BImmvbzNhC0RGPo1EDypRmzM7gbt6IRE0E3R/FE0JrVKbw37nsodIkIrSvD
   ###bboNp2N9i1NZUs3WxhOODI8fnKbzPplyD/opi3i8yUQHupk7t+TcqcS+d5jFGdv7
   ###UFGRNu48+UwE5JcvzGdQhESTvQu3kTv/4azq5U7eHcOXFnzvlO48jM6tn8SlOzdf
   ###ctx6XkWDoPkUi/zlgdZcjB1uteaZrX02oPLd+w8IB6/AA00EJLFfZccm+bvCqlx+
   ###Hlh9no2985C3G0Y2FuPnH8WjMV4vC+QVjevQ3edwQO3stzimz4fqZfN3t15yK6X6
   ###50R4H3tfxMlnV8BZUbDlia+jAdFgPBETh+5QKQAMh8/BMDNe4cdtXHcMWszjbDbF
   ###iE7fnB7IGDF8l8m4wjGfm4mBc2VCKCyFo4EyBLFu+EnoJCiIbl6D/ye33oJeSjCA
   ###fMkskoMnRe6p8KNYG5oatIl5GaGuaqUFreRo9vgrL4LPd2TvHSBguGY5wIuD031A
   ###CGpINBrPLgaHGQ8RRyjqcHBWJw6HohUZUx1hCWPebq6L/WNtGrEOZlSe1QILCvD/
   ###b8iU+mjoNcaQn8HHaQhQAMYx79wCS0a8J8ZuREYz/hhNsKNV0QuzjRHKLvB6RV9f
   ###HU2+jzFUaIiOTveoBowCZEaxkf4IjRFiDAlE4ypWVur5//acLUe3vKKjWIpQpLJ0
   ###QdYSf/PiAWxTUWR7GzYtNWZEMJK1ipoorRaApTh4hdF9fWcQIquK5reD8F9CNLlF
   ###xnza70qHPjKioMnCHK683G6+RMa9uyUiYW12aAyZQ++NpJWGEMJgjft9fxwHrYEf
   ###3+TyKzxDxP7VpmPEarcCU2WeGLjcsOXNiI5GpFCOz8nAsS4U7bPwfTEsEAGhX6IC
   ###fCg5HTMq0LxKQIKRFuR1KuFkjNaHa5djs7cvHntZD94Mbg/o7t8EbE08poBUnwIi
   ###JFKYkkYsIHCH3anfF+9LMnApV8Ut/oKNgX32XnGu0G7ljz/GxavC/R9/NF1qcRDe
   ###iRqqPSVgUfcrOgo+U3p2sQkBO2QNiktqmFuEIGIZR4B+8b70wkxnZQYMP7u/LyWp
   ###9CIBySkwvxkKymhzkiL92uYj0cyNJG8h7RcYTX572zXbxSBwP/NBSWP1Crmb8pqg
   ###jph9StPZt0BnqbEIqRBTy0meqa44UVT0NXnQc04CfSS/TZ7JV3BG3kMp2Mk3RVf0
   ###KyhOsRjCDjvNm3Hgld1Q9qamJcOFEkuBf3YFwLXJkVlFHY2nlWQ8PdgKu1sirYUV
   ###lv5PpV0GAyJJ1ikmdjhd3RUpx4zZqDjSuBRmFDwrLcZviZepVv5oAgGEZSmcVoq/
   ###XWIouq2tMJGvHNfnt63TSt4MgEeLtrXLzwTAEuCGtVQr4fevWh+n/nCSwVudZjBR
   ###YkFLTtBBo3GnAL9UuoOD819PL37AjlNbzkB4gQw/75ztH+wd635Lzj2PWr6BnhA3
   ###7Ye63RL5v9zlzaxyvyV3ZqxDOk6BMMfHQc/evbCd4+kg+ejuPtnQPT+Zg8LnKCSe
   ###X+zs/SgYICNyY+7H7UoJhDsF7bwwR/eRhfVRwTUMeIgidKNV+3TbnV97cjsCDhjY
   ###C9ToxC8FNeBw1rAXTw26yc3zq5DfAXjMpwTWkklH3YZo0doM76kMjAzQAZBEcNkq
   ###9uXrYOJEaMQsbhOhVRn7cjpQ2yS5E3DPv//w2+W2GXyRRgQPm64Zb9FKPydLmPHG
   ###nff0BH9vJqL5wd767dKM+W59tzeYmNLdPby/v+dCpENTGAXPflTz3keDRIBFOQ5Q
   ###mKf8MdHoNzhMKXoFa1/H95E/CGUaEZz0j862Awu97ebTwa4ZBaPOeA79QKAWm441
   ###WSdrHjzKo57zHnnfyWjkxHDu9kvMBkcBhxQNJ9KPlaaJqFbB0WYfc5JvgTFsASzs
   ###fCbQ21sMQTqkK+YeRbMImMye+qcxKzA7vvBwhfEMMFkNQ9fIOk92877IfNFdwdgJ
   ###RKwdfwzwvQuFtwWgm+jkXrihKT6aos7TILedg7fnR8dvTimCP44amssn8q38biIS
   ###hTj9CfV0eIq6K72SWzPZtt8AN/Wxa6CfmVUgsRrW2s1uXeIsrL91lIszvOqBANbI
   ###/Vh2xS6HcjjJvBbQNbrMXD6BFSi0wDYmiWWAOicgN2SfTedmYTK69SMgPP8KolGB
   ###rZmNWPtqV9miIYKhBIPKbybS3KjySOrzvf5oFOWgXAEr5FO5H+QW1SdGnuobcKTd
   ###ebKzx5wNclNYoHTP7alid1axOyj2PqsY9VfA9EP6mbHny03H6v9z1vp+TtFy3cJ2
   ###E6m6zOXSTaK+vIIHabRzQxzMS01cSXRlz2/hBHgN2wBFAXQqp50M1SlAaoj5azBm
   ###SbBytYL0J4ZBDjuBpK+3eMEvgxqGEXodQVXa/DyQlex939o/2H33es78tpqnxSrM
   ###8HSE/nGj6dX13Jnp5ab0RxrQ2w60M4soTgZjlc+BT6rEQZ+JFlCLfuUfKHIP+14n
   ###E8BvSGPTPegnYr9zPPdYKRwMidaonZJqh+jyFYO00N1M5z6iN0MiFeWfD85+bR3v
   ###nL0+cBubaahQ0W4w5MNqNs1G23URsVpGu5pVNpIRq92iIdD8WNbTKYZFN7ltxWzM
   ###k3aVQyjFwMqgl93AvwJajerrSQDM51WANipdFERhK9z6sBLxCHF0QNfJItKL3pBQ
   ###FDF8NJ3EqAIhe5bRaKzJEq3szj4qlHBZXYsoqnRNJrE34HiGxOFM8H56+AGSRkq4
   ###NB1ILz5yPyRg5OK8RRXPiN4ktaI8JGxfKbyI7uVLDOl83u70l+B7cuPuT8Jx/x6P
   ###SqJPaBoFzB/DqDvCYC7X/idyM4NZAWRSRPpMQsQgkVbCSOhsRx2psFCdURS8oiVA
   ###2y4MLQUzWiVFGMqzTu6WhnYF6wmnRSCurq2TEEHALr4hebm0AzzvA80Y4ktgmYSq
   ###oZsFQPtQwZWBfwkgIWIBGvjM2Tid6wAIDO492DaruB+2m2obrcpNwjST9Rn+vTVu
   ###lCGBw2BIyltVJNHd8FOIvLY1TnLpuHjlnPg3GOYjCqQburq69vtkxRZnHJ1A87RQ
   ###roeGcwQKqF+RkkDOwUiUk8jIZ1AAG3/lOyYkZ3dZ72jDmlkgP2dKnhZD+W6MxhvC
   ###x/7hfXGnt2ViD4gRXOoN8GzYn8J81Zc5EwpPNUSHdkKJ4PtPiPqCuABnCYvYuR6R
   ###gcIUJx0496vhve4FmjjJGKg3Z5gUm44SSrJko0eshkiJEAuxcRjJN0qjK3iDt8Lb
   ###eBSFVzRa2mFtH7YCt/tbOkb/+wTjlpMCVem9yRURky/eJLLpSF6urJmizxkMkQi/
   ###waeGFEBBeoTnhueUoUrIUgsix0YVcRWF+itbOi2nxVN5VZuhuZmh0uJBCp0KDO3i
   ###zZmS9OdpWbR7pRCiDI0rULo2WlIKDSngS0I/KgsDjghrmRcyBgPjoAJMlxbY1zab
   ###GN4BOQnoh3g3S9szHT5F3yPF7g46xzkF+PWAVtVmXc4eVp9kan0W1KnIOT1VqzKz
   ###flqvMlN3Ijx2U4gNzwXiSN2BpadVO/DMZkGJzJNiVupnU1o+oZp9aI+cPWWTfP3N
   ###QTp/wFM1dMb3bLx8ZgX+AfJjrADIUOVnKfuNUd3NsG84TbHzB+aCHpS4qvijSOod
   ###2RnIXJ+LXCIczLlCOPjCC4TFJyfhMP9qgedqXi0kp0xnlsQSHBsxlgeU2hrQhG/R
   ###4WActUK68U0giPHtV2kAgKUF6qSIEn3Sl/TGyg/CLqqUxRWkiS305oBfke3WgBgk
   ###epLAJL69wwFYwMqEZCINtprIQBoX6MQjzLMAfOE3XumU3HyJv/3K3yxtEtoG0N35
   ###ghXEfDSq0oQx+7hVSkxXF4vJ0CK27j8zEoJ/6eTfU74ha3q/2o+efQJkpEttGigJ
   ###D4TNArdjvMIn+VmUCFiyykqj2mig/YG3Og6l1lcaVNiSjVIDikq9klvPl/jkmvhD
   ###b5zjYeNwTJWaas7Qpq3Ue0W3UV2vFWRjBWqDm1AtKIZI7EO5QT6/eB77fyD9qFR+
   ###RieA+fb/bsVbayT9v+vV2tL+f2n/v7T/X9r/L+3/l/b/S/v/pf3/17T/lzyPZaBv
   ###OAW8EOrqQTgkh2nY122/HVK6BplTJIiuMAR0H9i6HO5neF4FzmY9z1dywhn3eAcQ
   ###ae+gdfzmdevk6PStk6vkUy/5hbu1lSydTw5E+wsbGn0k2XAQDylruTWyGPlNVLRw
   ###wP4wCigtWvYQT6FHGEUjn2FO1mkJkFEsyF4UfHRz6m0vrgg776Dj3yftycRFHF1P
   ###EYCAYpsTL+S8gjkEtEGHFk0FRW9SyBGnXOYeQMSuaz2FMTgRddSwfxJBCcnV3Qgo
   ###2ovnjbivpFGoB8Pm6jyNvtYTgTgJL1KXhFoNrDN2s2RUxvJbFSXPcOv4sBjn/1vV
   ###oz56+itWzVwBnAXPwNDGn7Nli7Aa9UnNjf7jUuX/dv9wRamwhfjnbmIv204FTS5Q
   ###dwVD2nSyxUEomLh3h/EWccBFvZC4sJtWHZhnLy4YeSry5lraNxmYuwGV7nBwwuBF
   ###lHZiuTBGrrkZzf6SxiS9OMv6mNwRNu0HQB5aA//OeCqe4KgJZ8u9ftHsq+zCwJO7
   ###Nbu++FiOWTOkinRDeAsHximuP+B8WFK1ysZNqIIvbJNuWHQBU+ZCmVo0C5QcOQOz
   ###TUZpEkiL0KyJfp/TaXPt5YfBzBqBwITv/l+qNUO7mwNg9uKtJpPLzawC8XbFsNHg
   ###/YwaXGBXc7Sre338V8QdABL4ptRGGdtExNmztOJz97/Y70L7m6QG+jsbJPYGvCuF
   ###ahkHRl3QaNKEAopvI2QsaoEbv/gFu76YtQyPJQGcmpm2v3UeASUQg+7Dxs7cTLNJ
   ###QWrvQwdlmzzkHyAGD+GaBbxnpRzQ7Zbd7SKEhPYzrDNutO3tXJI4FK0tjVsepmY1
   ###wLDDXZ65wT+bI0SjOEL/vN0mnDFIujMTX1trk7R9gj25ZezH7M2YKN/sDTKeD7aI
   ###BPHm5CbF5QZtlhZfy/JmwV2cKi0IlmUlTZP6vAxS8hXif7CraueZVWMz9X+uW1+r
   ###ryX1f95S/7fM//xA/uel/nCpP1zqD5f6w6X+cKk//Gv1h1uoKly53p4f8ANzUzwQ
   ###UCQdciSe+J2bFnnSLBZpJDOUiYo1YgQ7ZC6937lqRTBWMwwiHpQyAoN04wT+re7V
   ###nQK9c4qOW3GrG5UaMGrCek456PtA6OJcPuHpA1NncZldg9rhpEx5Ahwi1vcOCLUT
   ###PDRWnF00scRXwyCmo0/QamzaahK7U24v0kg5ZMnOH+I70T6lJMaMs+y9ISyBhU7T
   ###CJ4PZahjDG+QM57fCVgYOVUng/Gm+QhLsdwrfBxqlY1GMWdKtLk7kHDv8nkUaqsp
   ###MQmqsQJkjeUcigYie6EvpHhaK3OIj0PYYa2Td8foEuOVnFx5rVF3M56ve2tr9uNy
   ###w2tgKJJ8XvocmcO483gUDUvacos4Oe1WTK4PElho5gRLQM7EYRwOS/QBQGioUfod
   ###pUHts7zZ7zQP9lpHIA3nqCw/jPXDWNrA4eutraZbL8tW4JV4EJujzPVjKAJAdre2
   ###XNcQhIvG9GmETupB2atvrCFg1zaqpit/2SwJA7Gr0gO7KoEpw7SE+Gyyl2c+CDMb
   ###kyNFDo1ShJI+n4zqSlQEkZUU28LgvoVPW1QjDGKRjgfTq4sUODJpBJu8hFfa9Arr
   ###OAWsfsDqLiBk/GGP/5yYJlgU7+BUmBcm83MFuzS0pjMob/NnKniKFjIFeBZfw8Y8
   ###6XYm5+G/WFPeSbhBGpZGMIwZtkaWI7Zt6TXw77R2LvVWua2aXn8nYthokJTwI0FG
   ###nRokm6P3VS/HX8ndrNgpnFreZrNLl7OKW7bVehBF1/blQE2OaHbbMte2x0l3CsK/
   ###x7A05Jr5sluxB/rQtJVLozK1gq8lw1RQWCvKiZWEx8tcwU+ZcT3USgKqcyFlFlRu
   ###BijDkatuwP4DxEuzPwey72yx+i+M2oyCRBijPb9ILANC19CZkvMpGyWu2t4VuE+g
   ###7w7i87B9QGO51DaERWnGKd0htI0ZeXSWyjxHCxGSvtAL9JPh2kEAAD5/OAGUefmP
   ###nvOyNKMZMs20zP0UgDtbe3kRnUE19V/Dl9KYEyB8Ku19mSgRBOMpaZKFuCouF+Eo
   ###hgVYUZRKGwoTBVuERukAIajVnhk7xKz3tyJnYdrLO2WpbNC0kvDkyyp8YBpQmhv9
   ###X7TRZyx0WXAV2pxZ4Gd2+ZKTws4ry0JYuSef/3BMxspVe7c+RFfkTk/ZTIph4TJb
   ###xKDs5ktXC5PNVBE6RlKG94zkeCbTzgOkNk5l1iMtD+bnPZj5NHGDsrfWM68zsFkb
   ###aRKruvmb7ioZJ4HwpCA/GM3OpJ42Nd5cUs6/K+X8InxD2orYttJbzTHKFWct55eh
   ###okHODMpVuNqciyOfzRRiCcrDeVjLasVNtNCOZOyiKdMrSwVgQHxLWZS2qVE3eBwS
   ###ZaHKbOT6uyCR6Ry2t9UEYfdleuJ5ChpFoQJRNywSsG57KjuodDVLoGTm/JVhwmzQ
   ###KZORnkATRBLlSYPuEeaDxRGfaVQLS2WSXNwCcw97d/bJbZNS7IOgbm4G41I7ecoX
   ###esUidX6svYkoyEk9V7grOVf5kpfg3O/0LX3yjJcDSEVTEZBSo4Iyl0kPFT2Yykwm
   ###QKqpxjLEjdhA0uON02xgauyQXpPqSTgyY6phwELnZH/vQm82fzgJlZdd5kYzPKBa
   ###GSmsDVc7YYNyfGLtIkp9bZqTTfxoYmw4gxIWgD88sJ/gTF16nA48QS89rkNWcewP
   ###KRpI6wIprW6JQneVnBvT64zGlEBj0wTutJIR92JyDfvmukRROluuaSTXDcaT6wdC
   ###YdiRMMQLCvWmaAghb9n4emnYxFAflN5zdZ2Trajjnl81nZxbZIigR+dqLjen4fzW
   ###1vFJfmZkQfIFxtlqZlhsEsOBqN4ja6GSc3J0CpuJ1H0l3tVMb+/GXq4MOw1K0xCh
   ###eKW8e3RxdnAO0qabdzR//nsmmTDlDRQqTis47FnSBqsVJgkztYna7YCEuTUh425t
   ###WRSGl1Q2ZDkw6q1txhdS0AEoFIzZrrgePKDZqpoZjed4JvkkPgi6Ps+HrfA+m6ug
   ###jTP7lZdNiA+g8152rSghAip32n8FlhKLOobZqZ37waLlRYtk01BEYe+hwqhf2ms2
   ###3ZmaJdn1yc57wDH6VtLDsNtNUHU5EF3VK+lBza5qaDQIdiyCsj4lcz75snoP+8Qa
   ###pmc7SormeESVEj+Yu0cFjLjmlkMmxjYXiE60XoE7xtfV9AbVEjR3mE84cNpGWKLN
   ###SmKZjk+azWq6a1OQruW8qrtWkeQCvjQ2Sk5k9RUxX4Dxx2jIkuRGeZsjiBT/YIvq
   ###vNWovNQWJKKCASWNhCM+3+yI0zLkPGkeXmh7BdqjXh4pazAU+jo45+StjS3z0Snb
   ###7o86N7EVf+OacjorFtmPOTSzqbWj5VmxKIhc9YfBW0AxoubWPLdab/QS0EnCL/E6
   ###KshTLBkI7T1yfS3gx/AcL5pnyKUgWbZYcgPE4GbLJcJ8Y3E3vycVoPvBJACmUzEv
   ###Cf0lR9CzOYwPYWGv2Ln8Dtq/ydsASGmFUWLBWGPEBA1HYboHLUpVNjG4aVpqymoX
   ###1xgvEZuJG0jiNDYzSr//kPuNYFW8oZhyWPC7yt16pVJx/gngf+WUo3TFz8kHBsE1
   ###Y4unSn9OhHISIccpzFU8UggoY10NA77VNMIjpIIFGV0nsC4dUwHDPNBpVnI4nHqW
   ###sktpIFIx+DHRNvCYk/sWu7Y/xJMmvfLnCXj48Wg/w1sf4Mnv1DVfKrirD2TE95JP
   ###+0EP2AiyBUq+whHNixeRoRnlqxghAl1qxY6lB2BFqd6mfY4JaitLL0uGdpSN41L6
   ###VEvAMooTKJX23imavufi5kCHXSAA4K+88ZA6LNFvQc59PJb3j34GrpFCBRyb9w5U
   ###HYNQlnTMWN+bU4FbTtQwd7LayOlEFlHJUfbEfceOYRqRt7/+/j4dYbKWA0ToW1kq
   ###+KlXiiyvFXTbB0ltSPEIKdg5mlep3dbx+51pH+M58V5L7QMRhyJGde6DYShMZP7t
   ###S6AxIzrAylplza001tY5PoBjxWmKFq/3q1lPQLdfVJzlr/wkKvc358FkAOQrmAuT
   ###ZKSNbBiZMZjHzQoH5BC8rMkT94H3ijIieHhzw8FArZtoVlB3ADun8Ijwj4q0aWry
   ###aTKjnvO++CvZEL4v/4o8wx/v//hvD9Dvj1/p72oZlcw5DNzGiDR34e/GVjDSsQhG
   ###aq9LMnIFR4D4NVHwszFkINgcjk1m+RxoTfC/lMGK6t8SIGl97sZSH01VSduMo0D7
   ###QBBxoRyHT4ed5vTDmwC4Eizzq2gW10JxgNSg4A4PLJzGVx7FsiAbFOqhDNzdHVup
   ###HEQPFS7qwsRnY0oIxnXotxGUayABe+t5TK8CPWe+S0dqSa6VtRUs6qTTsnyemQKg
   ###nwjf01fi702UeBXNC+0D2Ju76ZfXtGTcN7O8pEVis3KElSOzcjSn8qxN1MMRABTX
   ###JFhocmsK/DeR9TLil4YA/QQayOEo+/eEhnEHDbivHNoBZBrWx4hV9/TCihuZJp2E
   ###hSkymXG4zAlpJEgEh9fpw/mCsY36ZnCjXx9sI+I2OKaPbCNSbYh8HRg5Dud4ex2Q
   ###5fBtIOP9cpAujhRnxdOVgd96Eco0AAkdxw1ghp4xFLPyYfaNNHcgIEX+laUnxEzB
   ###qhlR7LrXkiX5wQRFg2Qx9shpXffM5hZQ7uuUEML6BohOm/gjcSikFf9adT7jCkA4
   ###5dHo1AOYBvTQrKTizOVglOScpPI+ZF0fyA1wUsgZ+uSy/lx2L/Po8rWeSGZh5Hr6
   ###wpssisM2GYwtzQ++mXRG0+HkQxXR8vdKCf77vJmptjIuHehewVDp4x2D2S5fo+RM
   ###3aVWXCYk49Ot5rotoqDZejgU7s5ql8uTNqJQ0Xv7h3jU/oGhJv+wpJ85JNoWDE1m
   ###wjulzFE/uVWZMUrfHnin1iljUw0Kgungb9impwmZEKeH1bccQ+nq1YG1quZTUqtY
   ###h8qldVsxq5VK44F23AXbcesPteTZLX22YwFTOFRp9tsbTSMiA+KCMLfu3PzwL/Zj
   ###GedTQmq4bUg05YTii7ccXsZXvUJOz0rBKb9qGioJK1ivoEaNnqOnyAnoh27Ww4p4
   ###uJnKlgBtFrx6w/SqZuqScPtMiclyvyu6lspOxbMzZiymu9p09gq5WtlUQZr3UwZB

xekaX4uiSUN5LtpsmrXMWK1JYtxseukRARxqVl6N7JqVdM2yUVPP2dl2PLObVFNe qjdV0V2fV9HN9jpNlauY7DCbU+Re/qPr0P//NXxZEhMo2cdXsh1prmGeBgI/8ESA th8m9yAfoOVgTNbmOv0JYIFoSTLZZwEc3zEGx+bxhEoPySuMJidFeSgrHChoVJFp bKCtH+5JLMPLfauJaoHW28nlctWydZgDW0gGx40a/vagfU/HM6T8GOsVC8VlRZ2H cOf1a/TUOfr5YNMIAqgbgH32QAunb85Odo6za0u1+ezax+hss5kRfzCrI3Ha6oib 7/7v/xWuI0Zx0iHmv6vcsRlcCs/4/T8s3Y841zWDoQWDk4Od83dnBzTP1sn5wYsX vf7IB77n/OBDtcLHMxzNFC6iDQ8l+1LhZ/Bkj09yXVaYZ0wHYzrDW4M4yOGjVNxL g4/QbacuVrUV0xVaMeHAwstV1XFoCpq2mZIKlTIIfER4PZwMbpOnjZym/FRRH4Vu 0PwmQr+cWGGK9+x8njTTYTjRERGsNGLf4DtrqkC278JJzgKdjnPNLbl6tgb8DMqd eTP9m3nv3NGxF3BCVya55Mmh1t6toICKN2keBkWQLyx94JZrHuBJFqqTthW9EirU tO0G2TW59aLqZwG7JuvOG02b7KvrtJ6ekYfCilwpK7vy+4o0Zi9kP56nmeZWJS4W m3t6fawNY66Qtpciqepo2IV1xzD1FMkIpwegBCLKyhI0hRr6sIP9vvOD3/UHfkS6 wVHUDaJ79Ui5CaOHcIxxkULKmeOTFxJagkTohPk6wvwV6C40GiMzCzPqXIuI8qT8 J7XqEBAFK4jsRRy6HbpTDkgg+t1SHh54s7/nKGu/LhAo4VXqD0WGVqgER8cQc5FS VCeQljHXUsRTPUWjplrJWS85KCopjyWdDZcn2iLofCAyIxfVLTkgfslvVfrmONAe vJFP18RT6IJKNEpcr04lRSnUHFEpGAXWcD0u7bpc062JWhvcglvlftwKtfQCyZ6p guwGeEER9QM4C1vXYoWy4khX0hmCZXFL8vxtc0aCOpUxhppLRSgXctFppWDkMuVo 4ZRNJp2GzeQsROpWEQeDuCI1OFNJopaqIJCyaS2ayApb9jJMwhLJVBORVuZfu8EM PnA/sPU4LSErw8RkDbuAB4IAp0exWO/hnF4/v5gjGAq1DrYhdD2JOOUZ913/luj0 JyHNYstlLBEtWQJ5Nr8OkiR7Dc3evhRJCDuufT9yH8QHW5XFKHBacba3MzJCpec6 c6KZ9kYwZpewybPFZfcxt0c8iIJX+C1hToPtPqGhHLbk5hONJfphgKOXaWL0Gc3I smWr7OeED6n0m/jI3qOCWWzzn1GvB/x7SecDbXX8sRk1PitHvKFbRPMP3jDrH9Zh QHJRyKoHDqi19QaeVxu1dTiyPNerwekmLGq8utfAb2v1OpSsViq1dZ1f/uOw5Hxs a1JAgcILpyKXpY4pj7zhqSHDn3rl8uYLnfpoOh4DN9APB+jvPJRyp0+54HwxRYeu L9kCg+N8N5ti/MCY6NRafv/Wv4/ZTkZkbyOTRrrbHmHGObwyRY4+nW3DiKEhb682 OXDGbcgO1bekyZaGJHjNN+yoVHVon3MVTDA8RzfoyshZH9sy9Fy7rBavnKttbQl7 xRJw1MVTr8CrnF899YSiRtdcl4UR3oYa52N7C118+R3l4FQ77eNQCwI2taI3Jkp8 bIOouHa5vZ1za2Voc3tbWlJumlVyH4dFjO2HPsXZgbKg2FaTBGbTGfnj0DI47k2H Hem0Dgs9BmQNJUtL19uU8HjY5cwk9IWdRmS2Y8kxDkbDEd/vMYJg1sAVjHE2lBcL VAIfl3CJMCMWI5F0W2LEpWwpFFoFrZ0HoeWUgiZT0DqusgqUguWv/X6vzJENnCMK 3oLNtzHvVr9PgUeFWgS463gktI4dio6KKkcoiTPj4cAQ1ikIXWwmF1fm0ZTjhaz4 c3z7gNgrrVMs+VReQMy+zrbzjRskJpEmmcVSYT7DXye9FroKoMLJaLI/usWRUWLl zuTOKQQdy7yaLacLUTDwQ+TuW7gZtXF3uqXWaDqZb3rTBzGlb3Ui7LMLaA2VSrqS 2UncARGkc80NYhpJQUG536Rlut+5DjTRU5/w3ormoy97RA4PWlctzg/CLtoEhIZR AJ+8zVP9pbVrf9PldivNXfVlEg6CFqZxs5oCdOPETMYzkM6UVsG2NkgYKBBQR8Or XTI0TCQ8oruldHor7pSccZjO6HwO1ptvGF2ty1TdFxSAyaF+lPiM1i4qGHmuCAHk Ilu7/JK3SlNu9qbzq/MNvH53fKxMHs4x7A9mOfOF+wIS9hjdGAMjYfGpNPv9PUvd YSbMUQllsvUU7JFwNWwmLVYT2L7dVCR6tiM7VGNIPWCJSDnRms7dh8rlViVl6MfR QKnXHAYRxNIlO2LqLNdr3bYIRqgaSVW3vV7syaJuXU03kaKv3Mx68zlpH0ioY4Ph jvMY0wD/6ZRJEXm+t3OMEXFeOeZXM10uIkmmWsYtCrbJ1GoZ9Mfo3HjKY5C5aSqX JZ3qWAYHMRLakfZOsz9EtJxm06mkcO/GHIWislYicbW9kZmUJQxDA1QZqUKcjhqv viKK9YbOV1NAi3vclqP+VBrRpOeOA83pvlC1l4MN+J2bp5Hja9X7VoWMU3Yr21q/ N8dJcc7lpwFlQZaFNRc/tFMly5E2k3U0Y/0iZUKspmSaEZs5yE2+2Sb+gNMtQ65m /ZLbuGxau6dScuk/r1Sl/xJ/DWRPkIqsPc+CGtq+bm/flByyT05UE3PPqqcO5Oza lDK5mT0tfAec4OHlHzNfb2/XLre2vKRT2i7IhxrIkstv7W5tmY+NLO6MmzLtJp5p CeS0Eo/PQ8IM1HsQrq1dlfntkTBN1SR4/tGkv0DcjDe7Dszesq3G800L0kJK1ce5 dZmtppgO5KvYgYxTUt7JjaIrf4jW3cJVAI5ANrdBSLOWNgRkR3ucUc+gEPzKCvlL O3xxKGdrNRnq29sKGwCMla0t46tmChZamOxuzIV6ZGefrVykRz1lz+6u1EGQiDhu FsVJEdl1hVdyKSFUCIlCin/EPLJunz6u0ClZ1N9D1Ox/yB2fgHCV5bCUOEiOT5Dv Kbt03+Jsc/sf+Hfl8rLo0k3M6bZnnTOnNuL9SnYyykpB8lbqPXRSNr4SGtjeUoKO 5IhmuPk/crwBNK+wi293WWBMHIvUXeoY/Di0kgOwiF8xnw1Ydoj5D2VxMF9/pKBm 5hMlbpsPWcy2nkThVQvHv5mWXCYBPn5hOJqQdZsIpWbQLDhxr0LOjUt7jkAKQp0/ CCYcQHPi642lRsaY0R9dneLN0PFJQcvzCpQ8YoSnqoayvlOW+pXvvkPtCnBGP138 cHCx03pzeHh+cNG6+OXN2x92zg+ARbJe2GK9oXkCkRDEQaltMjRNGeySxshwu6lE RQNDDAVEJrn43bLWYfhg+muMPIJB1PLyUilCs18QmCe3QcBgz+lYRokgGWTpC3sQ hJwV5xcU2MljhZRJajFKcgdHQZnsL5VaQYe0Mk2HjfusG5VfGeAPQ7lnRRNGIGAr a6FVUD+eKIY3WaNocj26whi7K7bFkcyAZyeMBJr5a0mJlKcpT3BETWbX8VOrF/md nEzaKvVDw2+ajyHeRi4++lT4OCyuuxtoV+HWErnWD4aTaDRGh3H2YuPFgiOrH6yg qxBCzEfIUADccbcnTbpt3TceSLRZSqzqG1MxOWtcA9+ZRCG0O+37LNJJ03A0+1tJ 2W4ZKsdtb27ksDEendXN1HMUHIxcm/Y7rPNxuOqlX5HvzLhSyN1VgOwBib+rpAJ1 vSOgJHLmwDimY2LZmeghxGWs3yHB0XX83sQ8mB8pNaosESjQ3W017yr/hIHevcrd ld3yXSVf5DEXxhX9NncHT7CE/d6OkzRHmiSQxCkRtRc3VWoIHE2qPZVpYEt1ms/w hLtr9uLVcYYInPQplcWxsSLmWtDNZsnPRhz+54eVucXuZnvdaSMiZL5QzBIEOO34 +M7YXwtih9YToN6MRHweVMkhDa89rix4qjlIeMl2kvUzcYMRo+mWHCvql0yElAOq hccbwtD4vPk0zKfO+psv0mioNjnqrEU/cISKZ0XYc6/wDMMP5UxyIBOTzG6lkNOt IQl1XqUwE6ZcpilbHcHM6Ymnn2DD6WlYG9vM/LLwNkW1vCavGWikgNhMbzZ6MUiD xUoAw0ObZIxe5euQ66wWXEIsv5APrXFsoT9I1cutF8wovvnegBqk7EF2DIdMhCg6 2UX0aidX9mGX26x9NH8unkACN4v8IWJkzzVHKAUzxslS9blTfgjFVfqdxyFqChwP ktr52JutL1SwMoILiwWiu8FVLVRYRAO5AyPd9SyNrLxnTB9AKdfiAaWt/1U42lJk mNMFKKnlmskNnOZnRbnEQOgHr0C6l47SyHcp97WBf19wroM+MFDhXdAtj0e4O30O 9zxxMPWPcx1eXTsUATtjmY+DyfcYZoD5W8wLBKWDiASEPhod3mvSYNq5po+mTOqc PAQ+6f227SDLk6bwUGgB8v7b5jxP/ExHfO3vVP7V1i+mtu6jVzqhz25ve1KgQ6xL qsu3He/JlwOWwh+DT4/5MB9+KjneIsc4rYFW9+smvPQhnrF61r2H3IqVpJjCYnmG oIIWEYEWutuocpAyvJR8pWTusIbNlG1kj00nUwnIadApcpA5TOGRWkmq8L5rUpbJ 3XzZSkRHOSxR3YLUZDON/HoQVoSU9EAqGYNIDk4NRI4kb2sU5WiyBpPu0QrhLmhz xiCsYpxJMl3YiGkvfXI/xULa1pHkiW5QOk6QzOH1xylIvV0niKJRlEAfLos7yBbg 5BSN0OK5UwLEWikdZp3ciUORDl4dNDNj2jBcsHzCP5kasuO5cNkcBlPklFuFjHrW a9mGGXTJygUQJ68nT5sew2GErkq3o+gmNoRflgD9myDW4PG7n/zhBP0mhLjdw7j+ Au4JZ2etbeBA0Eg/DP0y6qjIT1MpSVC0BhgnMr6dCttu+7hM3PR0Nh+4FjWvVb2S U7g3qT3p9RAVTUcn8ayymXbqIrWsGK1SBtBkUn5cvD2/EfcG+mtGPCPZY9Yd5UBe bcbqul/Ma84hlnEzyuStKFoxrirRcqoDcsOvIHSYUbju5Yv38OLXBC9DzXz5lTI6 3mC48NuAEVHGlRCsks/XrjPhbN9Lex8ql7C66NBWxm8ufatcApP/119XGx9FZbfs FfDjZjLQzZQSEMnTh8Kpp8zaR2TppaACHMF04pgBj/TBaNuqsdKw0w+IPmL9/uiW zdTwNibsJxSEHZSnDDMgaQI0IO4DNxTaQZBlrdSRC3MeNuWRZjyGCY9ht1NyktY5 aJljmeNw82x447CVDZvWpOxpFMzyKZByACtWjCPpI5soCh0E80OHBE415WKcrAoI hpiVjCBclvZ2yUD7QkcWBd/HZkAUoKTA6/ptTAU1CMlrQtlucRosEfPUhjLjKRz2 iBAFwl1rJyJOsw1CgdB88yHDBRtjLbvXzURA3crlLLf/SjK83HseR2bhVG6AX7Na llE4KunS7uzSqbbZsfW9DQk9G441gBbfmT1RGY4lMKOMbN+9zASA2b47YyZm+25m sL00cQFkfckxq18KZCUyaO1HfZoNgztkSGgXeE02R3qoHO4pN1mWvOeoEO6ydC4P vo6Kgrbf94edIKGMf41XT/KWkuLPQV8yJjKHaaWrS7qLYCNWbdfa5fSDqdOTlI9w bBq3j+JERdfCHgb0e1h6FudiPuPUOSPrXDuTUY+yvgXloHM9cjBOW5iIa2fyiXCi 0oft7VytbAeQmyHykLt+xGanHKcPSUx060fdsuwt7o/GxGDhzW93F3PGOW7FGcQz xyGsdCviUhI9VU+1VW6ujmPLz5ARJfNzdLLzHltgS2G0CS5TY/lVO5ajZFPa5UGC F5nJbyQTqxjWPt+ktCDok2bitLa0KXIogu2qV0bGS+wNn2O8pbk0gTQqIOLYjzHA u3mwrDhvJBKiDvr7OGF7MeyiKa3hN5Z91zN79LTTDFsh+Dov/KTef1gH/xZdE3hq 96Hnug3txGHAq7otGMZ5kQuPhhJSAzrTb/GgpAhFPkWP8VXsGHGzjIy+wYrwoWfl d0kiKdbAfYVnKTaEscJSd0nzeYz3j2cxMnQuDzIdqbXLaoUHotdKciQCjP8UsQKB YdYH2Vs4yIhjQWExg21JciyJxRb8Px7y4mE5sf4Z9xO6gW2nauqAmDB+k6FW5M1d bBqdQ6dVwyIgiT6HxCWZLhIlwgbS9JkcJcmEwjniX0E0IsZrOEqrzhhHbrFKm5g2 bdMAnMBKBt78MQdxfjUQJ34y4lgUaTb6UE+PwJgM/MA55uWY2eJtN7+1lcPDcNvN fydITtkOZJspovxNVud//eIk9nL8VfZyhkJBHe7z9vPf9zT4Y3kcpKWFFxn+VAnl aNuPww7Av2wzSEIZzhrX2OMIaDkGJ861rfpTbiVoTkLFPFJu6LIfddSdNM9neKW8 MIx12KtOGD4N0dPfabNpFAx52kW/taTZbbLxLdaifTRT8v0+m/8sNhMeMgIEwvfv 8ZN9cL6Ju0aygDKO2YTS8kfoEqbdEkvxMZ+QqQ7DIQVH6PJO8zuTqd/nPWGHolz4 0ouosd+/alEjZBRbcn609k7QyXC2sX9Y95KKri1/HjyX1Cimw3nj4G4WlpmPeqYq hmDK+0gbxvrDezjgbKAl7u8WUaQYvkkUyTtJRHelKx6GRcf0hvjBbdCRyvnCKVzy gEIZo0doD7VvFM6Cc/AmYeo2SOCReXk3hWkbhVxHs88A4/L1QhxSO7j2P4WjaCVF T2moeGcgh5/Pue+OUzdOxjVQ5vTIGpgd1uYqdRe5AhWu45UF7bkMybHJnlcLGWdQ CrDsiOkLjvP37PSahczQ6YWZsdP1jLUXfN7KS0x1t7e9Smb9zxnPaC9lLtQcSEre sE9h1MdBZxJNB88OHjO9TFLh+CUwxLimpFqtraN2pB30ySQ2cF4OhdZMcRYkSWfO S6n3lEO+u1LprXp19EOvzOpahNLj4emw9/j4lVOePcv3SYei4oyyM5fYvHyeXXpG CPs0Jc2+lrBdEIinINUj/J3GnEQC4cxWVRFpv8UjQTIxclo5GKK3Tldc30SG56NJ WH9/MUuLkrDjOP2mmVDeWaGz2RSC1M+nSccN23wjbQSYMNx4ENdnmGx8Tl/LJ7zt 0mf/TeKsfzcUp7xwF42kBw2f81cjFWXJ8KDBC6BZnjMZzjPanuQLvWMyRg6DKuNY HOa2RfgElB6A2w/8qB8mBoe+SE3tZqx9NqwHhg+d4ag0NxlH2sVJ9Jb0hlJSRmcA Ytzmoq5apiXZQy5+qcE94OhnORXNcPVDb7+7SqUEv6r4aw9/HcKvKj6r4rMqPqse llLV9rDIHhbZwyJ7WO0Qnx3is0N8dnhoU4nNNOs2Y6SdweUsIFYyXQENCpTtqCe8 qslDAgj+eMq37SwwSiKfxPhsN9oHN7+Z7cJ+M7QSmCbSN5xW8iXPS4r7D2diMd16 f0vfeQ1LVrxtG1iwCBnWQp9VRAzhDNwZ6Ng7LEiDNCGSMS4QxyGR2y7tno4p9MzY Dg9n1JsXVEEmvLPSyo2iCROddIyILshCLemlkREtogCSf6TbMz2qRhOoykK+8Vjo R6xAElYOQEp8sct3xqmoD6m4kdadWUpR/4To25nxpjkeVuKBNytulhHxKuNtQgmh I2zp2A8nRrgGgb/amc0IV66dpF31ag+94VsyZgJwTR7wTO5zhnZw7DBg+P2E7WlE Yj08XgykgjGc8BgcGR9MgGKvoEJ423m6E3HDuFJKe6Oj25q1y+lnGO021ajIWdPi pDviAV6D0Yuikzm0TRHYwlwVJVotkBky5XGot2Hb/HKa4aLIChB5LazLBr0e8KDh J4UPTU2tZmW7Nb79aral9Hj6YloRm7tWZ5B6eE8PZYwyTvyVkWoVT4xfW980E9Lk r4SsWRXsOzssZ96jnybztZYzmpjpN/fCuCPmkO7XINoM/OE96+oNwx9h9SiU78Cg 036zDOdC3Gu05nkzr6zQAjetdU5otZoGkSxjubLlRxmir4kmh+UsDz8TKSieKn9a 5fvlasmsH5oHXTt5F825/fizPc6iW1JJQYtmh8Zld1oGbttGwi9Sih/UMRrLVj7F e1T1gCB6SbYICWr3xx+JDYiG+9lxJtQGDdWqKwznEBtRkETTcLuJJ0Kvx1s+A+bv m4pmzMVugbhm4c8G8r0O0Gwfj6gg+uTjBnZgT6KBhDL7tE7272NlnMdhpm6D7yPz YpulF85JKNk2lGUSlp4J4EijyRwf+980U/GyKf4H+6eZERlmiFzYc4tpYMYLO5+z ehxmGCEHWpfNeuwoGAf+RGhS0MB2hLwIx4oLh2wp6iesB1LEUaJ9AtFKGvNs+ABe 2vGG5exMcwPL1Vwq1nUX5bKudulspweV6iGwQp9w+5b+MNFDsSiroQVmqv2iNQck 5ND6Pf+pJPvG1HbGIqYSYFN1lOfsNItct7BXTNiJ3T9QfK9sGX4ZAXy4yJacWcox Gi1QtF0JW1y20aRTxhs53nstrTdJK+xjAeZJ6GY15/cHo3hijJavZvPYzHA0LOMV rVbx2meSDUUtJhg7zWCe6Q6xmXagT4fSsYUywO3ONbrqEycuL7tgUt2RZsVt03qj 0+TqiljZFuZTsGwjdHZSikLyxbLTDzvHhyCLiQdF4pdM8elz9tQzpipgt9C9Y3vV e/ytY3rbczCNf9J0iunXr0SHKI18l3FHmeyAmjHgptyEKvJekq8jMy4dcfLmdrxv LX57/xWA4T0TNLwnguPeBEeajVgAVX5l0PzPw5I/7rNRxeTEP6sQyqmkt2R6m7OU BXmzakYVJMbpSvdGJclhFuU9LgXRT8VPeUc8G/uuCFZkPIL1oCDyaDYocxn7dMCT obyL7Peq0MxyRnpF2FISb3tb214aWR/SQZH/I/mDIlU56nUaa25jFQWkVY1c8Urn P57jpwI/jUaN/sJP4m+t7tWq/+F6FbderXiNtfp/VNxqrVr7D+c//p1+kpP7N/kh uW98zyluc52841Uqa2VYDM85Org4dC6iaTwpOXvnR2dvgL6E4+uVN9GVcziaDrt0 TbDi7ADzQPUptC0aVXfJ0/aXKJwA3cHrmv8T+MPyiR91nJ/RkAcxebXwQiVm6CGP g0zuHbCynQnsNLp1ODvcQ7Rccd72KaYfEAlW8cMLOr/9bpc2kd9nRQ1eVPOgqO2z oBuiXN/mYEWU94rjHcejadThoDntcOhH99jcAMgWuUxAy/h3NCVmaDDqhr2Qvf1K ZLI2DqIBTq2LMU3wbqDLwxL7G7Yl7nBgyHl0ZOCL9QbB5BUNrJwYGlnEiTHR5dcA jVSiYOKLmL5+e4S+M3KhWEEzCVFzSIJ4P0TNXs/oU7qJGAOCHjt9PxwE0cqMUUBv BjjkKETIr68xECP2dHfUmQ5AgPHlWq1iLFNyXEEhMAr9fqzhrVxbzAnIaZ0Kpxoy CcPsijCgI7w5GIKEdz7qhAGehITe0IeJ5kMdrAcr8rqgB2OPL1C4q1EEmDLw75m/ ln5jXXiMl2Q4yMFoEnDaHQQdbIwuTOCTxGu2xxj1JreIFQLVdD/jKEQM5N1DrSC+ xbGa4cUPR+fO+ZvDi192zg4c+Pz27M3PR/sH+87ur/DywNl78/bXM8yw5Pzw5nj/ 4Ozc2Tndh6enF2dHu+/gSDjHZv6//2/nHGp//z293Tn91Tl4/xalXOfNGYiFb4+P oEXo4mzn9OIIo3Afne4dv9s/On0NTMW7C3TMx2aOj06OLqDkBdAH7Dxd03lz6Jwc nO39AF93do+Ojy5+pS4Pjy5OsbvDN2ek2HTe7pxdHO29O945c96+O3v75vzAwRnu H53vHe8cnRzsr8AYoF/n4OeD0wvnHHjw48SE3/xyekCtwRzMCTu7BzDSnd3jA+yO Zrt/dHawd4HT0p/2AIwwSOBqzt8e7B3tsPHmwfsDmNTOGfBW3Oz5wU/voBy8d/Z3 TnZewxxzaeiYoMFmYJn23p0dnODYASTn73bPL44u3l0cOK/fvNknsJ8fnP18tHdw vukcvzknwL07B4Zof+diB/sWrQDgoAQU3313fkQgPDq9ODg7e/f24ujNaR5W/ReA EIx0B2rvE6zfnNKcAVhvzn6FdnnlxGqUnF9+OIBXZwhegtoOguMcoLd3YRaDLgGY F8ZkKWrxwevjo9cHp3sHWOANNvTL0flBHhbv6Byj1R5x57/sQM/vaO64aDA2/nhE 6CgRukSr6xwdOjv7Px/h+EV5wIfzI4E+BL69HwT0V16gM4ZQ6v+A6niYxOHR69YP 8FAkQ3wJ27cXXq1cv1TuyvqdyfNgAfUCWMK+3wmsh1tAj65XrreNYqO4FU/H41E0 savDiXdtP8G6o3GiF5A9OzctUq/aLyhqBTzJcu+Gk/skoNjq5O8ElDTwQTomjlDY 6wUUl/GndPIg88YswFbiD17dTCDkVqoltwKM+QaIWOt1+GfkDVorOWvwGDMlrK3D v7p+VYWvrnhcKzmNDf1K1oDHaw0qJl814LH9D9MG8QXMY2aJz0R+KDQcAZiSwoOT kyUgYFy9ZgKgsVKrrtUrlR4MZ8WrI0sHH+sra/pj1fXq4iPm/8SPonJtZV2+q61Q Bf5ILfLHdf2xsb5mV643VGU1CLuGpz7KQejKmd0ZNdQMdOuiclW/W/wjLxVtKFgr kDm7IWc66IxAZAzhsB1O4ldOZWUDBL2VdfzVqOPvOq5JBl7PWiZsuoWNfqjRQnkb

###tRrm6mi4mJMKE3hQoqzqeg1GNKuRNvBUZiPVikt5PzxvHZNWYSuw4PX6g22ASB2h ###D1xtw61LXH3UyDmEwoqYgP6G81DfOJ4Pf3vsrHSTODndJPagvuFUF2zfnLGosmkk ###a3srA03GUl9/zLSzTAnnzeh/aOXfF+ZdUonfGfnIPvE2R/HhgtzPw5gTlfhhREED ###dSeUOQNJASfQjoEOlEz0m9yPiQXLkc3IKo0+z7EViXgMp4M2csLUE0ggEUyZn2FH ###1DL1KgzcE9ELKyXF18YBMruinMhJCbwhku4Sxdgk6rSOY+MskytJWmRbMAQt7KtF ###QIL1/OBdfqh5ijStFkBSlgZbNPVY6GS1ZT7xukpZYKqr1wjJMfEb7kHXo6RtaH3o ###ratn9KmmPnnJZ0ZzuhgeE0T1xacN+1lFPHPRItmpufgJE8vVKkZzLuWSwz3tVrGq ###17A+1bCCiynoGphvDje9u0Y567AGHkrQgtQDlUxgRH4mMDzKAoQjJcpRxZFivh+3 ###WlefsPc6prur4tjIULOKGe7qdX5rNCcfAVhoflgBDzxnAweJx56zTkn06vLT+pp6 ###IRbCaG4DJ4lZiOgYduoIvQoNEafrVSSoPErIhy1t4K9aVQK9XrGMdEqMPV7t6diz ###rtpep0G79pT0NGlerlp4rLZR5bfmDMUjmNeGnA1BrYpgxpV2EOrGJ5ocoQAjg4mM ###bo1wAcHU8CR+NOoKP3CclMCQYE2pCml0lF6RsMfZeBT2VGWrhCmEzg18VvHEpnI2 ###aNvQVtiwVpphYzn2MJBcBeANCdH1itxK3GZVbkXqh9GCnllbqVLjRwJ6ddrFWKxW ###k6herUtkrroSe+gFAaNWz8Ke2vrTsaehEGKjKgdXISJA6SLXFGEg1K5LYoFDcimr ###ZNVabk5EiS9xH5vEAhe5qpChRokvsbM6IQPOH6GGzhFGc/V1RiiHEoBRGktBU7Aq ###YTRhCq0EYQ8hPaa9FM1VHoU9rsKeDTlnwgreRbSf6mqjKdwgFOAtVzWxh3ecp4hu ###XWIfEXyCMk6QoazxldCCtly9noItETs6IequhC3tUSRADiKOgO2G7IzoJmOPl4U9 ###G42nY0+N2TNJTunQInJYo2SkriIgaxLJCd2rniSWVWu5ETV4DnQaVhWJJzpTxbe0 ###RMgc8lavewqPsFvPAlhdoSCtEK9ulZEMsKcmMYo/KSDSM+rMrT8KezyJPURx+Kgh ###TPFsnPHEM0EiPHUaWScXQ5SOGlfQa8YUwh5XnXfuuiIlGnvEMxO2a+qApO2NCE4H ###VJU2y5pcFqLhjD1yDQT22CeXmUM2i2GKB2hjypxjK+x0ex+ql83fvZJbqhg1JTtb ###9Zz+KI5bqDgEeR34sVyK3xV3VFZWrcKo3z0QjzNMVUWSrqGd75pMOEumdSaPADtX ###99HJLEtzLOdsPDBG11VJejhCjLIG6xRgUJcwEzl69SxfsgIeiiGd7OyRRXAOv5ec ###bilhaZCV6VnY/p4cnVa9nAfsCowEPlELXmF/t3X+w9HhRbmWz28mEkCy3oV5f7WC ###QCByj7MPfuT6pa0J2Re0lLRItDtIGBprLt3uhyL/lUSYL/g67Jj2xXu2fS+JJVb9 ###gX/XIgnCTkraUTatbb87DOI4leUMxgwixqcPLCtUCPltJEEJMfmsTeFvpbMMTrpY ###RUs7hohEulTEzSHbKePYqzqdLQtZdi5bkO4Nw4s2x8vUAmVWrkazEEm1xyeXm3aD ###WqSW75QL0cFQJrr0OSislC1TuXYWMFHtaNPPdB40vOluYYrNhBHXR1ivj2EqmBGv ###0cfNzA18l126V0r4sRlVEKGz3xD+tNp4R5dIDWbQBduSVzcDrRIdeA9EoKw81TZW ###eiW5k/NJcpLIRz8zFiXCnAiV5c5wly+tYVzUt0w2lFNCDte3hD1Bh+tYgvC7c2mb ###x53hNIWt3xCDy3Hy5OAKJHmpQ4gCcmoG0gIkH0jON5aR0MeQkroUebIwhJW6nmxx ###DUNJ54yvVnBSBWhoAmaEinMYOUAPmtHQ89Yt8CUtI4BmQ/GcXvf8bPiWNIFAevqt ###bYeF4L0rI+CI3pW/KsSgTr7XH40iBFixNxswSWRKgGMeNsGqqwlvpty/YTJvYYZo ###92ikL6VLNrb/7I5uMUvNCE6asHMDE8oFK1crnFUVO7Bjr+ElLhlfGKFBh/mUtw/M ###XkQFuIMPxlRn+v5AjaIAmHlKG1VLsAscBZK0+zO0YAQgsBeiku2yAyQIbYUS1qSc ###5InDEqbyBRsBMIUPO4O0xBDx43g6SIQXi0eDAC1Or4C17yVisdhG53hqWEbXknw6 ###8rhhs+9qYa8AZbu2iTadL98wsaY0UKr2llOtzI3JZhb1atkwZKtvpNsZwDcbcBuz ###Gth5nyunWkgGxtbzRANvtz4/V0toj2UcUq5pGmtYSnlsA5zFfZXKj4Dn9HdwHmW4 ###+BpaxnF4ibGG7UdFFx42ZsxFOJ0m5+PN2wEGjGgGeEymgtYITgPZeB69V/gY/ncZ ###Cm9VYIekeP1k2O4Hh+g+NESOaZfCg0wWqMxzmD2AdAeW4TLxiimiB6XEWdjjkxEO ###TKAW0FcWgZD8IBAYvx1DqUrZHvxHlSuAz5bE8QuFzXZfJBzP553K65hqQRwx8Ikb ###/lhae4AH4IatMxIFBzwUHOOcJdYnnyb6s08LPVyMfulYR7UcZjNzwABkPUNkPEui ###oY8wyXxWPlUgBXuGqZ2QgcRiJJ0gLQlnQeFGujMdPF3QsVwGhYzzIsUtZkksWbLK ###sL3zyQ/76He7ez+x3SbhQAWqk5Bm0E8RaIl/H3SP+A15Vd2OWhgWUYjMKIvjXYkp ###7ijBIEsuslwJdQGDi+Bx5GcWpPmahcTMcX/TIuDvSaBHME04qRlimNusJF0vqWEg ###FH6clM+Gwa2hd9jMch6Ut2wGQCkl7TcSbJRPwYTqtifPS/a7wgLJpQLewShR2FN+ ###lmKgiWwiOUE0C1ZHBb1Wq7m9Qt2VLsj2tMhVw1awKCzVmCmQXeC3Y+ziEu2rF3PY ###B0NS3U4IqgpKTQXJymZCMkS25qo/avt9p9f3r2LhI4Ehv0k3mbqqFG3n+JIwvh+0 ###R/1YmK7BRIBVHhCTOCcIv0RepHukJtEhQBo2L5ygzsmV1LS6XLX4/3QX1LKz4nr1 ###XiHVjBW0P4H4GOgTHjHc2N00sbfQW9VaMr29TCdVY6M9WOPN23fnLbTjSvdloI3V ###SN5QXMh1h72S1kLIvapM5zM0TgONkxSdLYmycjA2GdV8bsm+uD0+ufzgXlq0BlsG ###yrrHEb7ckqHqSabQTk8hoXwSW3fa27Q0NLSS/E6TsLSnraF6SZC4IaNBG3Ek873o ###2HxvUEOVCUCSXWvYJUVxJkZEDz2glH/q0HBQTczMwlGkQcbAuZ0IvRz4Qe67BIar ###E92cz4xqRqd5Y8oMfq6DAdXgSy+I0lWAzcgCKm8QDY+SNZSyWSUR4iC/abrsjoWb ###Lsm8DEX4XmaqpIUxvbvMLtU07N6BGTL712uAEMcZJ89Je5t5X7LNHrXBaMxyk9nb ###q2JvLzPZvHGQ5hRl2NKjx+NWU4ymfoEVzGMyhaz5onGkbhuYnc/yDzWgmbFljQVW ###y0oCetbyZq0wruos/EqvcEY7Jh85l/xnV5eLMvMMyNtqU9r/icgitl74S4b26HFp ###aqyJMS6ayRGhP3OapTPkvmTpnf19LUtVPQq7YgdhsRTbJVvPnS9Z7SX0iPZIBM6n ###PYAMqQSj9z1SJpknZ9jSBMVDoR6osyzxInXDYfNpWDl6ktbeiHGCe5PjceixJHzc ###rRd492Fqk9DoPxxO1baceyHw0ZuhqRcu0fOEYkxI48fCYV36BERSU2spX5HA5rJV ###B0XFV5o6bEuDXbbmm1Yhc/NatzurJ+ggX0DwZojopLH0gATi+3IiGBh1wC82k1W2 ###KhllTf2mlT0HMemjV3JSM5oDZxUFgVWwLOUnVSKeoRKZAdKS3WlpBuBT4NV5zT96 ###DEP0ls65tcS64POV3iqHWAZ6DUUfpQopNp2UJ/4MdVM5o+hqYRwBDsCivPxHz3lZ ###knUxwxEXzm8aiRGz9SI2uRFsQA8jzIZx8CeQHP2AfGpUnCalz32YKmFFkzZhLmvM ###W03xB4XLKx/NBnXCSkAn8M+WR38SBCpNwyyV9nZzz5lx558mWNukSmsdHp0etHaP ###Ls6Rf7HmDIW+aeIXe2slKZtN3FL0LYvEZVO51P7NRrstjGJZUbGQ5u9w94FdbW1s ###vmFhnamn92J5kY1MSZe/TaluzV1bnr1rMQi7uW83swIWP3LTmjclVhTp7F1nmM2I ###3SciHj9NCTnHAkYKtZSKDFmdpNpQ7KQHrCcQQbIZ+82U/cMsWwfnMcYOWaYfyafa ###g/vvYdcggpVj6p9OeRuZPP8qKKwrsrQf/FlGD9Z94gN2DQhIy3oB7x8nIhVTG5PL ###TSYcUjS4g5nHMbtGhsNPPmbnxgvHRGDqSUAXs84eTrU3HbKtfwAQv+dMdHSHG8Z4 ###u8kXm3Z1TK90EwjFHZkh+XAa3f8Lb7798fh+JZ3yCkTFIJrkOlvWRVNCN9kNOvZl ###pXnttN183ns+ukcyLvtExnHcgH/CPd9284FbPpGbkK7wiCg8dGmnDAo+hpjRgm77 ###vnMfM6IHLvXKyXS/3VTOxMfd2z31Sm3u1dWXmNwsfGk3o4XlVd5m9qH5fDJylkCc ###ODizTP40cX+6PPznSrkJ5s/IVEozXQprC/B9i6Ln88pUKRRdUIKai8ZLCeoZJKjk ###JlrKQ0+XhzCT+s5gnHt8DGoOIC3vLNLWGImtlOkFIDEkbfBfATwW+GyFnQtmnpAK ###16iFRX0F+lcqSewcM9PspBJkrUqYZFhU5IUHfXhZalj2XMFDZztD9W7s5fpX+VIt ###FTxPzsuo/UjgZCCFxAN/MPaOARdmIYK0TZiNCSJ+mYkC+AgaPXgyBnCviVnKVjPm ###mVwnTmqC0+JzksaYXl4vnzJjLD+wspv2YOVAk0hnDtfqtBhSIgtt+VAzGdzZq/Uf ###y5+v95OO/8YxR547NNrs+G+Vxlq1kYj/5rkVdxn/bRn/bRn/bRn/bRn/bRn/bRn/ ###bRn/bZH4b0PK6rJzcYCR3zg9pfyqvqOo//b84N3+G3Q0l0+P37xuGW8aifLvjs9h ###jV1v3X6uVQbGC3r45vDw/ODC8Vz1+CeYw8WOfFHLft66+OXN2x92ADJuwwxQ17mN ###EjHjUH1Pj1iY6XDyDs7r2ur4nesgl5Jojk/ym4b/dR+7x+dGQlhS2gipRfg0hFvr ###zj+d0Hnl5NadIrD+363l887WlpPLhdvb1XzZTfh1q3bNpL8zhCzOhWy6GZB1aDKz ###EbsKlJzrcHPmlSJNmtVMxyfFIhfEZ5zWiD6ucJJe/T0ElLn7cHxiCSo4KJXdRomS ###13gNQLU+iKj+lKqkbKa7QQnORqW0MnY4oXTUTUw+UbwOi25+e9s1jDrfvL145Zzg ###NRWmfBBXYrFDxul4Qsrjz9enrN8HNuVTYKe24KFCV6ThYrDqPGk4GXiXnWKGZi3f ###fn5huMGVcdSUZBBwouwCUnA3/dFlnjK00Lfr8LJsdigwqT9KGsiJF7ismRhkZkde ###GIO40rzb52dHFT0V7lxCqKIAxM8viy7NdLWg8+1QeDF8KxPsEKMZrgQrOhWPaJUS ###NVyNZBhE6LZA8wd++z8pNpozIJcF9ZW1ZzFweh+nQTyhUImdiLhpQNhuID4LNlPH ###P2Ob4lGU0gKp6IuqC8ra45zqquxXK96KgevX4sE4YA9cTICDcMNsZs5/ChheUJOJ ###0cjsQ10k9pwbjUmehtqi6m8uRrptASDrWccfc2FquQVMn2inkMz3phI7jGblfLNi ###ShRUvjcz+xx/CZRJdqbC3fDFSuaKkykACPWj4BPSeKFmfYr8T+PtADs8GrS6wWD0 ###5UHg58v/bq1R9xLyf63uLeX/pfy/lP+X8v9S/l/K/0v5fyn/f9X47wbP80AA9614 ###0g1HVvR3fNQP2/azVIz4LaRTwyt8ZqsWdvZ+PLjAOIT1F8TWokkEieF+dAUcHgss ###8PnTh0tDLA6iiKUW4Q56CEdoCdjZ6QQ/0avDI0B25CXheQ9esJstzHSPJio4ZPjd ###VNlE9Vv2wYmEk6X1is2RIrL40MJ5MEza0FKMxxYHZsacU0OQ+0oUF1k70aP3WQvo ###W2vsd27ENb8tqwGX4X/QgNJGwcj+94M74JDJFML5JsdQBZHCMIkgd/hvxJvc3rvz ###izcnrZM3+wfneXol34hUwHlb7dAdTdvAmgBr0GU1gDZf4CFMhxM7EBtPPb4Jx9Yz ###vBqmhZDrgPI0LjAm2drAgcgv6+aXNdvmRbpkAMLB+pecl+9i/yp4RVaxLQOHnS2E ###8razJcEOH3WY7G3nZVKse+lssV8gimW8FNvOhy0NYvjGj8m3nxbx8jKjna1wCDIZ ###dMep07f/a/gyv2nL+q5h1hyxJ6/pVOlPRv0cobsrDBvlJKAgvAz5pSdeaiSzXlfF ###a0RveGHKNPiohXLvJMhxkG4TUSlrqVohrs7pdrOWQq9Ez4dtR5wAN+341PcD80/i ###vzWH2qUeSKogBqD64490A9sGUXkAeZIrzvwem2XfBsC4V4h3+0cXJjHbHMTobs5E ###mUDh9HBmiN5lj7cybD8KdzEOkOoxGXsZtV/quX8DRR6Yyh5ZlAMn6mA7DiEhSxX/ ###iHH0VrezxonblcmnNU6RkBMpqBqoKAc937aL1lDhzePGyhtlxmBdPdheB3ZegJZr ###8+DMLsUmurN2IJIYPyBVgSbH38Gg9PjhC6XAnY/rh0lc50Bh1M8rOQkaA/opo/MP ###NpyfNxX5CME3e3nQztCeHZu+f/3ZiX6+6uwy5zXps8Ef+S+/PrhoHb958+PODwc7 ###+7nv8JTJG0EwEGW21xJ+KpKCNzVhqWusysSUCcVaKVGXeCex9wa434P3wHfldHt5 ###y016aFJxt1HID0h3ltOktSBXpYDfRj2jtGiKN9gXtfJCJgPGrYivcRVS2vdI2xMi ###SqAzauB3c3g+i1bj61E0yZsnQ0EjlbmyZExqdSQsoKDFG1kIeKPMTSnDqNonEDI8 ###pRRht3rEBhMW3Gk6k9Ff3uFjagYaQ7N5KyP8hbh6QF1LHA6mfRDO2ViXffpikcLF ###qRjQFW8M60R6GnbNR7Jx0WqALAVI0APdtr7LMK5WYISF9Tl2vdhILv8Pjerrl3lM ###iD4vOmC41UjEBPw9lRqVpiTuCawXNKuE985n6xvxr+Hq+qXz3+SGnlsr58J/rOez ###nE/MnMESjHbEOmoNerXbgwdmi8JFRrbxDy+zFQEr1ZD8vmnIRz3HpcTLwBwAPcQE ###0PgXlWgGyf8+lodYOIwnsJP00hk4BPXkYjsmK2ldWSEFazaJHxbDcSuVypZeTzoV ###gbnLqw4MWGF8DjllXPW86csVEXeVprFMXjmTLcXvhrmYGzKffUM2vznew3ObI3Rl ###Ri69jbN3sejhgV0MjSY9GYwdBG8VKUtYbcJIP5CJZjikCAkCDZ5XtlpsNMYOJNmL ###g6eiQTkPMl9wVyoF+5HlZijmUpaT0a7qtgU6SXB6Y/dQ6xYge1fEw9Ug+omDAaFc ###pvPXPBjM8x1faitkVtwAzFonR2/PxfIKWpt1BndBootG9zrmWRZzIAsp58Mk65Hi ###O1JykGwCv0iBKghyqgH8wrWfWcRG7MeV3U6wY0LUjj9GEyqwmsOVzmIAaOkMtit1 ###AB7gdnglqRTI8gG5hQ4wpbRk6Ez5LN3C2cm5MwhjrgE07B892m84rhl8nO3wmzEm ###MRhqMojlML75Rg3ERFDRdiU7dfNXsv/FX3+m/a9bqdaS939epbG8//v3uP+b4yji ###OK+j4GoU3Tsn/t1t0O8/6a4QdRCJdvj+sAAV/5PkZkZZ/NqOwqAHMxri1VmsolhL ###T3GRNg43IYV8hKZpB9KXaTccvaA4jsu7yeXd5PJucnk3ubybXN5NPq9tMpqmGbbJ ###4mvyJhJzlybMfek518p6k3V3iaaiw07qGRx42Xec8gK11eqM+9MY/72AUw9Ik/Ny ###7yUwtUovYIxeMrSpm0OrlLwyTF0iWqXoRtK+oNSdtcixEZjmzg2LLuNJhP9y8C/v ###5PhPUX4oOwlbwEIhT2/yeTzeRYjBaFXw39I+MuYwzubqoAIUKM8+YBvgb+sMd9f5 ###BSdZrFQ8YckJ1BdjQiNVx2McSDOlneVLN52Vlngdp9I8AmQYAzQxcQmnwqMXbvMc ###5UsHag6yGyCTxNugS8W95vEIs7hg6awiqJybPZXcXX7eDEuAB4xaBHIYDVTIgM3R ###6dt3F62946O3b2E7JeFTe6iCNYrsthYZCWrGgZRA3YOdsxaQmzdnxlBwJGsPVlBD ###mdNYeiyEg5mQwTPl9OD4PAmT9dlFLWgk68+AA6IzcxB+P3PJzy/g6Grt4ozskbiV ###eYWtsaTbWBQ/DqBKVt/e7KJWz8n6i2IDKiCSfdZpt74OmB1WJIf4JJA8KM080wM2 ###jmYzh9Xsxi10MXsrzaZVmRA6P3p9CsxCeve4jXmF7fVJtTELWwzq58STaa9HJI+s ###GdixnXVL6BKC+hayRJE6F1RYJUq2kEVsBZ1chukIinjAlXbQADsrXIIz7gjDavP+ ###I2mqPxpQaLCgK7NQ7KknnIbCjOGYMUIM8htOcuZhVYjtXH+UlBS4/xbbAySnTDCT ###R1gGzKQ+bibM0kXVkJQxzeOGlGgwYxVUw1mrkIAxq6tVBktrjVTtzMUygr+Q2blA ###Vwv8nUl/1j2jXcG49Jx1GZrJpHzWnAn9pcDZxFnhOi19/B+n/xNsY+fP0v95Va9W ###Ter/apX6Uv/3V+n/3LT+7yIcjCbX987uinMRRFHYhl/3c1V/C7sKLH0Blvq2pb5t ###qW9b6tuW+rbn1Lepe2fLISD/4ltntkuAoVWLW/F0jMlvH3AIyFSzDXrR8AqoN6nV ###Vgs7DmUVktIlaoHOA/xKyriOIotR0AsiKBTwPZXy+GY62MUzAAjff3XCSfD7iR+t ###bZROTn/ZWP9MpOA/j04RqQ4OcCnOxXs6bqZAVKLmS3gyQWOz1yun8B+b9E7CST9o ###vjzTwwOi/AolYb9/he6n1wMaShQMgNoCvY6CLh7nw45Is+sD1b0C6h4LnRQQSrRJ ###59bbo9GN6OFnINUj57++c/ZB1oDDpjOK6NZtD5aA58xV7gM/arobcujdLkp6zZfn ###QBWvQSSajIQt8gAI8HXz/0zxtEfriv8kcnF88DtBxJr3Dh5Efhg5J6NeDyNkA7TP ###/C5MqwvHg9+nB0cw5R9WnF+I0Fqw2SEoBOiYvsc3hWfBpzCGNehyud/gsAa2o/ny ###9529k89wfPjD2BfXjbBsR5oVcc7v40kwiK2pitF+GvXhzGu6DfrGvs/NKn0ZA0AB ###Bl69US57G7UEAOjbu7Pj5svryWT8anX19vZ2BSaM3XZXYLlW4YCN49UgqG6sr16j ###md10Eq+OfThK4lWGycY6z5InuDLu9tC0/zPuJOWTP0Fhj+xjKGlQTkrdLTzCSkqi ###RMFxGuTRBCLs5ehleRu9rIviM+y0Fn7fbooHIpp5Xlg7cKBl8a497X0w2yheNu2c ###YnnuD6tY1hKzht3yUTDt/umjF8XKxWIu0VJ+0SmtFt6QmV2MqQopCWFJBYLwgR1H ###20kkLUc9JCacxtt3xsB+DCfAMSFnAjwIIBO7J3AdYOEiYKbhN5QQqQ2RfwvukU3l ###0POY2CzAmLOTsO+EE6g5RHYH6BEyIzjs2+uAuCygFGjYjuSjM5lCi9wJhi0g86NO ###ZxrpIbL1FVTrMaulu5I5FnF0PeAUeUhmwkUYQGck9OZAkFBDgMkNsXESI66AxcLp ###Q41RhJsXBtMPgVVHNs53esEtgKvfx01pJHTEHJDDq76yUBwRz1X1MJgFlKPNy11g ###sAbSuU6gI2HfOImmw460GGeKD23CLuQY95TSUwKeotWzjc/HaQhEDq0jw74fCZCh ###8HODxEZw/UIHAmxpEHT7QBP7904seGgYG+Y5R0lKoD2FhBGJNKi9Fuz5BM7j1mh1 ###FKp3vmke7LXOfz3B2CV5tmBaLZzCsKcRrS2PS2IQAm48Aka0jW4Qvf40vhbLtyJs ###7UhFhXXYUoo+Nlud7W3RDYbN2RTd7FM6cmFF6pPxM5JOEhUo6SZt4BUhb9ICo14Q ###Web4WmYTmPg3gCIdfIgxI2A/wBp0rsvG1QjtC783MUapdjkccdvNSl7uTjQe+6Np ###kzwGnC5fpEkJUzDdEoiu25V8KnMj4JkyDrwfNHMa3KKd7/QTI/r2wwOC1pQ5Glm/ ###58plYyz5bZlAgO2L9fhhORJ9YgkyYdPV0TpSE1QTs4Z4rvVR4WlhFs18tSD2uNgH ###uEFGnAmgJBcaU8eL2B5wAsMegE0KRSe8NjwTOdjh1Rbi5x7q2XffXAjoplCcAULZ ###q2RVIKaEc1RVBfpmvDtBCZZEQ5hoeTIqX4MkW+Ydy2QB0XhERYxXgPgk0Eok0j01 ###jV63tgxMz3+Xk2O4ePO2LHMPGNPbaqY2hng7pHjHFE6kmCykwxrLzOmoWZ5xurG2 ###l1IDmkk92TD5d+vcasrkoonTimPXGg+BAgHxsR4P8TmOmZ+uFpQN+HUgI0cT8whL ###3LlWOTTyHN4mnrZJ8wM0OKJzC1tiSKfhoXEC4FE0z97UYAHGTWMJzDewE6xzGxfS ###mufdxPouDvMmAc4sh3u0WdlMrAm5eszgN3p988u1+WVCS2IuFLn8Rk09oVUotSkI ###eK+viI6eRtEoXD46eYcRgaMSFJ6UoUI+hYVNs8y1LpOkC9hcM9neNZdNUQemChlQ ###ASQZPgEyFFnqQdhsb1PBp4An577b2uJunhVMdrsLgAu3jp2QGk62a/8T56t+ORoG

###L3FfuasYfZ1Sm+Rxp5j0QOU8yTj9AQIGWKl6JljNB3HyQT8JePzeb2og4/e4GcF6 ###YA9UutxU6wIF8sa26xejxJ7FEv+MX0WPQC3OPZMx4biUef/FSWnMrddeCL+gnJxG ###vDB2UWcfWrF27szCK6NUWX6+XADH7LKLwgvnmICXdUDAXrS/M21SEHOYDBnfadUR ###5sISniEFXIHBEI/GE+B5/xU4QJaPjt+8zuVLyMsCQiNHz44GUjQgkcip8Dlg5mWC ###sWzzadqS+QCgs6ZsEocq1ggeIx/wDr0w6Ejm9YLH5ab5fFM8blLb24gMRRGfr9fX ###slqeaAq93jSYEST2DEEAWq9fdEu9iVWAszgIVrLX/y4nAq4zbPOYqRSaLLvv8iXZ ###tlryZBe4MC3qBIZadNMLy1n05i5sBl1FJpOOdYf/2GuJam58Ik7+FC9AmABlmkl2 ###YDO5dPhQMKewPlinyM9gOX45Ot1/80vr/Oj/HoiF6o4kSz2HJZbyvWAE1WLx0Axu ###V3PM9GZ7O81+8TTK6RfMRzODikWsumrFuOE/mjkFzjzAe2tLwo/m21SQSfNUGpwp ###xkq2kcUhihYTmDBGjxPiDoGnysILSwdifBsqtFAoEF+HiQ0/8OOb1PJSza0UbKi2 ###+bTMJfEdttPM0WnG/QKnvLWl+rN1Mork8jHJkiLJjtd+DBIhSIOcGOdffM1ooA5q ###ZiopxUsuZ73+7v/hcPJ/tIiZp0HY2zElPM4YDl7xTJC39W/9kFxoU8J0YnzIkhpt ###Z4xk1kBQUDJFDTimGJLW4KJAngksyvdHozFBbYiqIIZdNH1AwPnu/9mkC8dIQo8p ###av3BW8kqyNPIWSWLNnx5mNIcC0ZGGf0+BdJESyImMkRovuLcB0JutMRXYsjLbmo3 ###xNdROLyZRxmVTGSh9GyF4FZT+3eS5/zJm58PDHwq0utyohYpb81CtrYwWTqpOpwt ###kyTm2wVWMUNK14TeyST1mtibsBnwXjcfYQ6QRM0+H/i/BFLcx2N8AARoMB0kY3vS ###lXkwxHi3sb4/l4o5seKMSJPraez0/IiFxbbUjGEE5CgKOpP+PSD3lR+Rkgw7IMWi ###6oRvnhlTbOmxrFgGtZMIvgOkSLbsvr1Nk4NJm9uhCCXzsFMZOrAlc1DgD3y4bXDD ###RaN53pF96X8KReEYEqzG3MY/K/2Ilmrm6kKgtRlKEOoHfi2ireiX0+oHoeq5RaL7 ###CdWbSolLpI81g+FE61EENpjKwiQd/eMPS5M2Y2bMOFi9q77JesThkKo8BOh6gPlE ###yQ+NFUxP4V9mHfoW7/8cjMlstiSTKeGF2OsHsDMwYHBw10H8j8e+sG3xu116oXOu ###aRg5Ymn6vjix1LJ8Y85ITJKoG9lG59KUSxG1JGEqGwXKWXRM8YCG7lRqEaPgezia ###RkKZKPx5ker7FKS3ROp+ZzpeMaIJ5B66sUmdEdrPX/uf95vlvvYsF8j2PaEahlMu ###AVeKJxNCFxWcA4b9TMBuwlYwraY4FS6Srul4YuhL9RRL4nbYnwAIBiO81hngtbQ/ ###nKwY8Q0ed1v13Xd9YkPzZqgLgYlN5L76eSvfqTMDVmawi9l3XonBgEj7R5Lz0jtP ###N/pZqDeXRpp/qv2nSCzw5+V/qte9taT9p1f3lvafS//vuf7fS5vRpc3o0mZ0aTO6 ###tBld2ow+p482hS4ynLTl9wW8tDkQyXx70UG3M3mMo7YdLfrg7OjNvuNWvJoe8BtY ###q+Odt6qg+M5BnZwc/wXB4FMQ9f1x3ozvRvUPz3ZODlDRrlNYySfJNnDw56jmUo0g ###FLARIKNAqRwVoFpejZt+fyoQcje4m53HSYras1L3jFG57bzF5Cl7Io8PunWSKyeN ###nw4O1Dj6H6cBppXhqDCJAuQfLUadiIr9eyKc82Gsok7raGkMTRF903yjMhWn3mDK ###XP3KcLMjUh8Eg/H1h9plNtQcmXh6k+TQwpazr+dKUW0wM8/LcRxMu6NyB6g/2bxh ###jp2X5K6YGMzAvzs+SQ1x2CYP9BNY5vT4Y/nqnNY2Y+I7GK7z56CDR9wmj1Jn/sGk ###TrG0Z4MzOQrv4ASEM13EAMxabpi1b7XpJFslMVvkQ+KMQhStUlg0RhRb0mzfRMT+ ###6OqU55F2TjUkUkT6Vn80upmO6TM91PjniGxSn9HTc+HEO39f+Q/pU+c//jT5z6ut ###rbnp+F9rS/lvmf9nKb8t5bel/LaU35by21J+e1B+M4JNox8HOs85J/swgYQfHdHq ###aUzuIaerNRkj3zk8JHyGzdwdAdVnQoY05HYU3QDmTQxfgyjok+cHemHAmYW0EEgm ###7GckBrRn+1Py3QC2fjK5B1IK3ClSQujEwfusFX36AYXt+52AzaN/HkVteIbFcuLA ###4hfBHdpEx0jOdt4e5UtsPE0B732cCXqo0A1UEMf36s6IXiJLCmQXuNfudNyno4zO ###py7RqNyAzn5xNaqCe1NPOAzkpO9vccx5OejA8A4MtecKQI7GHA7jcRgJapd3Dn2Q ###v+D82IXmAUDf03mYtTAArsPDk7cHr8k5hsxR4OhVLpF4boNoALSXLAhhDnSwQofo ###OCB8ZThbKsHTlurPfzx6a6aFelyuqHTKqLQYfwM0utXrJZ625OPW1XRiqwvSSaJm ###up1iydE4oW2IJ37nhtOfmvHbzAjMIlJMf9IiIYacA0xxptAnw9hTjuwCMiFb4WSl ###Xz6t0UeazuQ27Hb7QQsBj0I5nItXm5bTrRkfWrXgNU8p1bGOcNwvb2NuhFNq+rSG ###H7e3vU3xSo4Hs/KKj8lky031IpVnGWP728H/ockbWAmOck7CHq4L55jAfre3w5JT ###gf9nBH2fU1+CJLYbKqk6lUsOok3IeHCKJ1Hr4qi1fw6n5W69bmZ3UL00myrxkBVs ###2kpE9VkAC9cAhiX+5DLWqZCnMfN8c6e1opuXaTQySud14hTRujUcPRSO8/+LMMEI ###hqPp1bUzHsGKC5ubmLI5kwXXMECzBOQwReaIWfhiLjFgnhEbHkfCKwDH0+vWu7fn ###ezvHBwUOuQX7Bw3bcvtHP1e93M7+Pvw+/wFNow/eXxyc4tcwX3LX8qVTD/5ZgfIX ###6TITUNBrziu8PSqEq6f5zXT8bsP8TO3EDlpqJLZiatuZIzK2gzk0hYUUql2jjhHv ###nd5k44NYWLYbNoInGRREBEQGiY+PNyLccOTF1+Jg4mRLfhT5tKj2NMWhKIIxJiiP ###o0ijpCPonp56qENQYS4FFbg/W2HDhEwo50T2Z4SZTAQdgfiQTd5KQJ9K86gcojG9 ###/HnnbP9g7ziXGGnJ6THUz/FUOb/Y2fuRyRrgDdI58WV7u6kNaKFPpnluBgUE7vbN ###Xq7HA0t0lpf7DkaFkeD+X9O5I8ZCbCzS6+o9hYVpGyZ2Te4n5GYv3EausrK2Xq9u ###rLvQn1vPF2F/rJ4au0PUztwAhPy5Fder90QlPi15hHuwVGFXyGOMLcAptANivEYo ###PwGf1QPp12kDYbqJXzkfMAFOycFEGpdCeYcURixwfD3t9cjrdNSXuUZ+NxKOBIMx ###k58gIgOcgX+DXoWARkD57h3aedIwB4cQ9mFst8QsBd8DALsj5CWUbQ1j2hysvBu7 ###lDSjmBNot73tqgNkgdoe1z71ym5mE3Mq32OKid7mzD2hS97SIHmPzBnorMpedmVt ###CQQbXVAq/d7Lz8jpAat0hoEX0MOPKMfwCrAA2L1yt9w5Azls4F9lvGwX/TMzpUvh ###flwswsBO3h0DBreqXusnt54rwGhLuCgfTr1LDAmbeu2WCgB1M2HIzJbckgNl3bxD ###ioXsjrwP5VPPyj8CNYpNz3rgla0Ht8kSt1YJaVVlrpryVzAXQ8DaXgdYhNNa+UvW ###wS+3Zy9Dp9w9c7LWAaG6mfnYXRw4n5MT+XPG7pSz1h6xqDwLjTzCjcXwyDPwKBsl ###CZG+Ch59FvTzbRSUo5GQtWyy+UgSky0DQLnvBEMB3G6aMMxcymTvEQa8HJScezhS ###783kWhGeQPdjo3U8vAf80DUf3mNat/J5CwCdg+aAIxJuE7CUsJEdfgOdTD4AI1wO ###8+q12UioG6GiZiNF2Qg1P7sRADzqD9AfpeNL4Ro4RhSch3ASwYk0GgaZOAmTKIpO ###7sMSHsBZuAajLMtSkV3qs87QB8NI6DpKFDSiTE73MSrpa6unYhiSqVT8JE+r5GiW ###pzO+cwr5XvoRpQ6SGDeKJ4xywd/gnO6N6aBd6FhFsitT9T5U1uOyRWYuCzk8yPNP ###3zBfATRP2IOpvUc7itGsh5stjfQKWXu4Q63tktxUdrlkO+VEP+Hz7SuXt1V57rby ###eFcVk7tq08zThjnJTMKLbeOjAqOB9cbDRGTJN5o2nx2AuHWmRIaUrNj2Ozd/lhRl ###MH1/G3lq9nvvzxa4RAnv310mU7xA8DcSoB4vM2WS3AeZGe9P5WayKalgK5CBLDkW ###ZyHJDvKLD7MnyYZm0VLRWvj8LEp5IRalOINFUVxumm4ys5tNNQUaHw2BMMGAE6zN ###Cl+s4KDFlU1hOJoUiOHhIEPkSRqif/Bd0C0Tspu8T7gQ8+NlPFuE+XmIR3kSt/21 ###2O1eFrvdS7DbpP/9ni9i0A8L2UmPSB9f5cjEsCE6MaEvKkaMGzqD8A4pBd2x0WkT ###W0hmsBxJHr78CA4+m4Evfj32vbfQ3ug9uDcs6W0/KAvFl6K70DHq2GWIjAFhiLq0 ###ZL/e0bB/n0C/BRhldwYWziqP5LhHGqzHE2HCWMqU6oTOFjIMTjbeCmpSBsi5WWqG ###nqV96Al+zHrEjFgavmh/AW/wHJFWspJDANCfhJSQGqTm9mhy7aAyk6F+sb+z95i9 ###TWD1ioBsi8DpTkohiwNWVajJeax6j9UOPlohmKmDkiuKC2qMZdbS8lwTKwsPOaCL ###XlL93dITPYA5SZjdWb3Inq2+UFYAtCo2s/VCrrWVaaCIbZkKQqssKmyKCX1NOY2Q ###C6GTJ9FpIWTyFDI9Sqo9LbvlnLmG+X8ThPLSNAEeWsDvmd+/CKGsXmTPVl8oVwKS ###zFAy33kJhILKzizVtvcEhErJmA/4f3b+NPvfatV1Gyn/z1plaf+79P9c+n8u7YeX ###9sNL++Gl/fDSfvjP8P98lE3oXL9PEUXDfIS+aInUvTOsPROGnfrFx6k/xPuAYZfa ###lkG5U55tARapD+IPaLP2O5yVFQcPdqcG/xrwbx3+Oe6N46548K8G/xpQ4Mbx4LO3 ###su5U4blTu3Fq8LkO7xrw11m/cTbgswvlXHxIgm+lBA3BP+BLnSr8q8G/OvxrwL81 ###+Ldeclwo48J7F9658NyD7x589uBdFf7W4HsNPjfg7xqVr5AvHbAmOyLGPhweU4pZ ###lBNBofv3Nklks+m8maxz9+iCtPUUQtJxXWxvN6R4QaOOsATHlAF4hkDjHErOXa16 ###aEq9SvkXAydXWXHX1+pOd9c5Pz3LOzrEfpa3IkK9pdv/c6D/vP9eOBvwYR2XApax ###sQH/YFnrsGy1DV4qXDJvg5fRFcv7UKMuFIJlLXHjNV7nNcCbBnRSh891+FyDz1Vo ###uAq44gk8QbyZ3eh6iRuGEW7Av/WGHvlaRTQODdbhXW1NjB468qp4nSKQNdko9Oy6 ###G/DPg4ahwAYUXIdG1qti1DCiRoOxtV7jhtWooay7JkbtGo0CzFxvDf7BaGEb8Iih ###4AYUWq/PbrgG76t1Ae8qbx+Xt9wLtwYNVaHRKjQK+8l1q9AwfK+4YtTQ6Do0utYQ ###4IBG62sJWFcZ1gQObLQO04aXbhVgC1NyoVcXpuS6LjQMhTag0Q3PgDU02oBGG9Bo ###vS6wBBqtigWkRhvQELx0YZf//+y9aUMbSZYoOp/1K7I8d9ySUELumTJLD8a4itss ###bsBV1ePx6AkhQGUh0ZKwoav9fvs7Wyy5KMEuV3ff+6huA5kZy4kTJ84WJ074EfwN ###vTI6oFHo2ffgvQeNdhOLQlKLQtQkwvdQNQr48uGjD+TDUIeCDmgUJoKpAycxEdKD ###RjNoNPMraDsmaBuwSjt1/3wYvg+k5gNufaAIHybOT+F3Ar+hMQYm5JHCpCEFES/T ###979bkbW9o8P9vzScyo3BnCwAdkPXCM97tF2BnN9Re4DLCo6n/YUUtA4wFIN7CQQn ###l/yg92bPZByAB+BGfuTH3SCJQztzQPmkATmpLzi3XBA7uSPoxkt9cQv2mwcWpvPh ###h785/dvz0ZRKfBqdL+g4yyld40FcXS40GgzALMtfafT//jKdr52dLdZe9mcfeq/x ###EpXhZHDfO8ENiNWrxXXuKuyX28d/okukTwCwpULzDJu6gKbemfIrPvNwNmeR9Bwi ###JmLo+CvkX8Da2RCOaXkCYdGvNKVfXV4JXsaFgPbpOcroV0pfoT36FQZcCMrgc+jH ###9Iufooh+xaF0l/Bzyl+7sUcsk1qCBceF8NFDGpRx2wfgcRfhdjHskb4wb+ZSHpQv ###+8Xn2VA+tFWaA9n9t5sd5vMfjDrOLx08/g8/MKIAb9IAWwmnriP3QeClCeJtRxcB ###ETEbxXSoIFiNnes5JyCQKOH8QSUr7wP74/HYwuu5s7mJU9O2RtYyI8odF9HjgfmW ###QxFKi2qtFV7gYQ4rYaCqZp2ukAoGKa12U/ew4rdalmtThfhb3+2dO90Dn0DQMIz0 ###BpwcM7CwrjaNXo/EeDb5VgvLUvRPvgAdY7DVxdOUOkGQSUDSfG366/R7wywRfqHg ###RbybhcSf/PftwNnaBJrSYzqbDfsf9JQTmHTEjLMljnBnjaM3hwhkc7Q6XLUKYFZL ###Ou8lGRGBUHAzcdIjJmIDDU0BbuHnBoGCfxnM5mHFT/57N/fiPYINJG/NhQU5pq7Y ###LDTxfgWKrwWtNfhFU4HEDqWoe3csQQ42sUErK1iIPnw5LQUt2XLG0XD1/LEhoQ58 ###pRG+zxhWeGxq3LVs5DFZAnw2Odq0ODInhKaftvRJK7niZVOVhY8u0ADm9nWdHLZc ###2UUGkE4EFnbzzIt0WgKLUFY68wXcZtGfXVLv+akd2QF2x+i+RLcL0A2FAvD1AnoX ###Vw1yBUChYz/c6AqPbC3ASW6tNQMcU6utnf/FgXN9GTg3kVueuxO+E8zOjKzmRPyB ###Z+Rond2XEaBJwJ4dQwQ4QxvOaAkXGSm012JCauie3ufJnWj6fRUuLDCsyltOgfcu ###6cKUsk9B+faYXb/yvJ/GOyxkGw36b/0Wb98o7+uYOrgbHLQr67lWL6216ljrY7wv ###c8iZeK9vFvdMxav5Wfylbh7tsWzJ37+8L0/nysov7zetsnn+svkLr/kqHJYwiBSJ ###h305jQ55b8+GfGcXeUP7EyuZLRRZtWK8rCTplUjb2CzNtFt8Y25EYVh0Rh8FymQK ###ncMqUsB8GsniQVpRgQ83s+HH0fSWwn8egDBHJhubQbsadpHWHHVUELaFm9GUQmWc ###AD1yMjR3dvdPKbdUmzJpWRGToBytN+x74jjPVS7tkSp83b/7Uh1FtiCGeEmEnZ4J ###msh5SKiPfr5AWQjls/a2m7km2qofUQzNAVK73SrppAXTztVw8IEzOIG6f44HDq8J ###a1qp4z6qVTv+lktTlSNwi3vWAV7QvmzgmXsW/TxGtnBDBTSWptIat8Uz9i7o8ky+ ###49IaPOnbw9nNdGw0Mtq2I1JD776Lmz4Dl9aK5d4iG4o+iyzlEpJ6qyRQ8uRQZA5U ###EDnWLxsFbP1SuUWO5PrB3mvH+h+g/ocNRcXrH3J4/jW3k4hzXZxfTdsfUJgwGJo1 ###VlDC6/naMpKw/xOVzinntCYoPmwpgF0/XzdPGQUqAr5cRSptvYZXHNOuHUxHF1jk ###kWEZZn2w7fq53NwABwZbfC06QDVZjuc8ZNiV52w6dfPifjUg61+K22bfay/H7woC ###X7c5Xf5vBTBZ2yLIe+h0pZ8L6flcFZp6M4MBA/E8++/Js9b6t19ptDkoXfzHufOs ###8yDCNMhl0Ajy4d1o0fRa65Ir8BGcrP7MuJF4NP8DSq9I7qneABbcYvgYd0ObLx7I ###HTCocj7B17yE3WR7R2opY2xJgr9yTkCpJxkSZbI4dAazFnyn0hb8uH3cw33Kv5y0 ###nOfPzfu3J7s9qrXdUoLrcjw96497tLeTl4GXU7wduD8a386G6+WMI0s9hzmaOj0C ###muLPlWbRL+tl8oqW8W7tPLGcij3cm0fNCIXv8+fFldU0U7ex8UtraeXckm9XFrGT ###UNbKByGOAiRMM0CtdFHF0Z/yfEX0N62QtVsVMCxf3Y/1oxapswRuHsqX26+Ajr5f ###bxQNdvbzisjHzDuX0ym6dNBEVJd8k58MN/lvJfpBNGFQlSkkYs535fRvYQH2SREY ###U+zBaAJLYXSus4PyrG/g/pTn/P3vsChBynYTeCobWgXMLx9NcUAKldiKIRnoNaI+ ###rVdblOY2//I/gu82fw9o0Ak1UxEbdHMQWRj+9Zwib1Av056yVUsbrXYstn3E4IZy ###eH1DUB/oN43Zz4a8yMLuf/hJazOPt/0D6DPkVtUdYsuHE3vV7WaVzQaPbDb0ljQb ###VTbrW80Wv3nruXMhxD/mzng60cZiuBp+yWRa4Gxt7R+0GNjfaUbJxKkytxSTskwp ###Em414kOLbmTglLnYHPlag/eYZLg/H2FI0Q05V4Ff5Hy+q8RmnikT5Bka1LqWGvdc ###Je7BU/Xbzb+1cH5A9/NWs7j9t/9xffRfRRnu8aw6RxRNxal4+TyONNO/uZlN70bX ###tMEPTMxMBjMi2spoIfDUUiHUnoep8iZ7qBE61tG5MMawU98LYz49t15ZjfZ3XKua ###n3a7XQxDzeqqBcXegtTvdpMMj9t1nJO97+WSLUyCLKnb/DVVOXxv3BL5ZsN8s+Fq ###kiaxHybQOEITtvIri7EURApLoL98MZoS7x+JpigKom43S2LvG6IpWA3ibpalSTcO ###l6MJscRoAn3zi9GU4ngz+Bl+GZoehd0SmlJAUpr635aa/NUQ/ksjLwijMpqg5egr ###Vln2+FVmV/O+AB3+ah4JjxurPULLoKG051BUNHtlJRmFExnZxkbuc95ctv3Ta+X6 ###osJhO9pXtVLlhUCXedV722Wnt4MKG7VoLlXU7fD27POCH2497zur2iTKyxALAJWx ###XjsYctnt6Ta8fLvvChWNp6bSCVMojUcXRF4d8RkP7fw9H30czUcYsIW5KoRKuboc ###B0GUNyv6wgw4GxtBS6V6X+KiJcdsAVfLHZdljMmJu02565TMzFzKvRywbXtbj8pa ###Ql6uJqzrUF/ekD9QblmEue5snya3zq7MP/vx0eFuG0+sr8ZtDPjg4+vqoTlaWY1b ###a7m2Ws4jyizJrPcooA72DsOgGQZpknYuxtPpDLpawcds9feAtJVL2scf9WQqNwFv ###+F4e6vklf0HF/KoF0i7v21oZFaGlh+iphLUq/zQ2xEiDv4IesKZBfjnSJkf+zfsO ###uv6Pd/k6ZhmwjM2+EoHXyQ1edNCjOw6a7I62OKm195xPMio8CF90nEpG1y7zztxZ ###ErsX9CZ4yzH1gHGNLgDLsMaG1xvSwItH1Gf3z+vtvf0cd/guN38lJ9c5nm2b3lts ###pWDYK0fCd0XX2efqACvaYFraTfUGk4CK+Kvadal1LokGYNJ6POhvsn00dtcVHhZj ###MOXcOta2iO19eZzzJZ/w0l6kNv2XMmOWC9pcXyi8WF64u80sHtEwrq4lDebK0Wpb ###pXtySq3mtuDyFeie7y8oj3fpcPlCXlJr9ZbBNZTWEtr+/H/ctSdP/y09/8k3Vv3j ###7n/xoyAOS/e/xNHT+c9/1vnPsHz+s3AoUx0Irdte+6Z3xbSx0H/SOU+mT3rme71+ ###7M8o3gM/jBbAtW9ndkAohx4j02o8HRt9Ojb6dGz06djo07HRp2Oj3/za0G2gNOvW ###UHlcemlo498dO5Cg1/v+8O1ODxbC8e6fW/DRsS5HkI+91vPnhVcHe4dHx/ABK0hx ###J9dUs3fd/6XTux5NWs5/N5ymbmtjw09aK/lmtjabVL7FH5tUjdomT85j+vCoNEcw ###OCqEQSqhDO6RIxfzHDrs0LG+U4jmRX/RHzeBu7acXv5FB3p9vbe/2+vhX/tAgTBw ###HQ4iV2psnwAtIzmeWPeszBfno2nuohV8NR6d8Tuqr/DS6PX6C2a4w16v2QTeTDZp ###S195KvGeowmeU+CwTxtSPlfEQZwEtf0CVQ6ObMHKYqVfqIgcAGo4gxrPXmNLYGmT ###9OiPWw77I0Bs/cecTtIMnf84fwEP/z151nG4UXzbwYycbNGByJwtmmyc2fiVEFiU ###lC3nV7TSv+MHeLJG8YzLURhhH9qH3p45/04F1z9XNhlQMx26gKh/Ofy6xh0MStJN ###UE9MesuG8BhITCyNlN07eItXgvQ7Z3i1bb/Vbp7B9Jql+/IE03c28ceG4zl/dJou ###/N1yXjj0SwKU2xvO9tl8OsYgTJwp3Gqm6PlV++wZNOYnDzWXb8xPXLzNSdqyG4N1 ###Co1puKE5gBwb7FNrZ9QaNXYgxwkKbeUa2/4519jW8sb6dw81BsMEjH7RMMOgZpj2 ###9DximIW2CsPMNfbwMGsaA8l6+EWA4VKvbmj75y8CallDb/mSG93UCtGy/grS3v7q ###5in9zTFIcOD+b06ayERajao0tfqKZytMzvjA1kufw0B/DoP1QnV6yYt1jndGFT9C ###2/QRb/FZX1p1OBnO1s0weBODBEpq3uotQ8cPzFsQdAckgFBD8JMwi8y3Vy9VBc+8 ###3H1zsrcPeoyv34CO85ce6GXf7wK0tj+wRRC0bLh6CFhVGQMmCkOkKmEs8Ef+G+gu ###6iN+y0/Rq92Xb7+3lAw6Idw7H57dSqoKCh8rfr9EBI5yt4ZtHx/EKD4PSoX7s+t4 ###KI0ZpcRpQo0IK7SqakQVFV6+3jusrnAGJSoqnO71duKfq6sM4rslNZJlNZK7XPYO

I can't rewrite this part. The text you've provided is base64-encoded data, not RFC prose. It's the Base64-Encoded Source Code from Appendix A.3, which encodes a compressed source archive. Decoding it by hand wouldn't be reliable, and any "rewrite" of it would have to invent content, which would break the rule that every detail stays exact.

If you can share the readable RFC 6716 text for this part, such as the normative sections that follow Appendix A.3, I can rewrite it in the requested voice and keep every requirement, section number, and citation intact. Or, if you'd rather keep the base64 block as-is, I can reproduce it verbatim in a code block, though that would be a copy rather than a rewrite.

###Ii2a5YtrR2Qiz29HCwpFRrl13f8gGxZkMYpwpSsseRgvnLLkt0+jEXjEXfrjT/37 ###OYI2H6PRCtxN6VJ4N6bZaOF7N5vD1cvVDgZD266OGXo0EBSmsZHmNzfT+Qh3hYBv ###gAqANNtiSVkxbSRlH5oxi6O6lTdh/v9jLnnT4ZyydLfbrBf9C83vI68X/pf0sJf9 ###v+M+bZ/9w/y/XpTEQcn/+3T/51P815PP98nn++TzffL5Pvl8n3y+X+TzBTYCamk+ ###kAfegbYpDtm2s0tqq9MXRZD4NwaOzefAhWhFnzHHmw1BYs37ys1H7ldnn3UkV3Mf ###qAJG4jksbljyg+EceL6ciQRAoLOc586haKCGOYOJEPzIcEylkP56MXfezKZn/bPR ###eLS4RxDwiozb8WJ0Mx6xThwGaZLpCjBKYE2FOjgS7mdlzaWLlHIt+EmYRQ0VqgJq ###qyiBPQamyU5cMFsnA0nhI14NbdZezPkD9a4ibF4N/0FIhl41kpVbNI/kfyAanf8U ###I46nVCwtOgcrtp/Crjhf2A3jtOFHDUb/gfl/QKD3KN9V72J0B9rc1e+p/8epF3uk ###/0eJH3phCvp/lKZP+v8/Sv9He5v2ENSReq2SU2Qp6DuoVIMFDsb05XAynPUXTO7n ###t9c3TCerAwpERaUMrG3S4+YvnCgDRDjdxMOPewvljJ874hChfQ7RElGdn09BV7uZ ###wYrn/TmH25aj8CU7xfe/gZ3yZIQ8GSFPRsiTEfJkhDwZId/CCKnKGGpeoehUYSh0 ###KuHV7msJcwAFSB9OyL/NXVNlxXnzDjGUeAf/6K6qBl6SAXptHHcc38vgR5p1GkGS ###dJwwhW9RN+o4SQhf027QaXTxg+/HKfwME6wTd6G2n4U+1PKyLrQWJthmEoOuG3Rj ###bAi05E4jTHx4E3YTvO41DKBulHoh9OxBF4046kLduIv3liZhhD/TDMBJgwhaTkHh ###6ziZn0KZLEmgVtfHlrsJQNLwPT9BgLwkixC6wMMnPw0R1iBIoQE/yHyEMwzjEH9l ###2JsfRRGWhK6xlTimp8TrIhpA+yRs+F18maYRAOlnQYZPWRbgr26IkPjdrIv3eHmR ###j5jzutht4FPTgd+NodsgiCK88CvoEprCCAEMwiwFcIMoDLEI6K/4FAMSoUicBIjK ###xAvpV4QTECSZj08AkgdF0hgBDFLuPYM+8FccIdqzDPprBF2f6nUjn+YioR66XSwZ ###As6gFVCeM3qKu/QLJxl+dVMAMIR5BnBDH/6HT1FCvxIPiwB2cTb9LOpikW6c4Tx7 ###SBghDJ6eAhxDGEAfUCQIU7wULYj4ZZRhdRgulYyTDIskHgIRwPzTr4SKJFlIJOQh ###LDB46iHlVtLI41/UCmCEijAsKZIh/or4lxBiSkWSVD1V/sL9XZUAy153+0ffH0Ze ###ftWpd+U1B6YY3m4+vcTv7wKfFxzfDlf+f2b9H1eB+hf48o8mDyDE8cD7JSC+ebt/ ###stvb2d75YTfOA5r/sgzcQX9wNYS/z4d3MbAJL2ao8WbHun/2SJAE5V8jg0nAf36A ###SwXnIvBoRQRL0MD1G1YbUtf8wFa4KZx+4lUBEglwm3zndiPLGsMf3I75QS0SwQDb ###AeomesIfzFHCR/0oNhrRcou5UflBLdOPCIkcWWZI1GtGt+RHwzwWG6Uf1J75wS3j ###D1qFKY4NpwV4EBF7jhrygQdMELinCvQQdgOmB+w4fez/G+k3LYx9+8jYiPHhBJlV ###ESL2ujLdKL+gDLBuB/kvShXkyvQPpQ2gEXES432MKIkiloP0D8rgTMRQDhilg7wI ###GQryQPoHhJGQlIJ/UC6BcohaEDb0j2YHUR0KLJn0kVJbDZxgqt+VOvAtRSkL71Jk ###Ah6vmwzlHtRBydqFciSEI5R88A85hYc0jXLU90iEp0qOk7zzcen5JBVJJqLUC2QV ###gFDEDwHRdCYgh4w+RAsNOxXQUPCGDAqBAZyWBCMuZh8lgtU9ShsfJ8hH0pb+TFcI ###A04ZCScfemv4OFM+ThFJDj+mCcYxxaxi4HqnlU88ER9RN/FRnvkpyWdkjCjyMp5a ###VE0IjYi2rgaMgPAUJHgJuk9LmhgD94/gcNfUa0w6AP7AchnpOvgOG/ZRWPrYfICD ###D0jKEssOiMUhPCTGsaOAJDmpAbFwdKQNpDEEnpBJsxUQVlKNC1RNaNw0WuKl3Dk2 ###hbNP6k6A8xsEpFfEpFVIRyQvYyLaRpaQlqS4FELkI/HLMEm1IcUGm/FYjRFeHZCS ###gmAFuGwC4l68VJBsu76iAKIznAYfl6KPa86PiWFjkSTTA/FQn8IaXU8JBaTbgFY2 ###dcm4izXXI9zFLBVx2hDqDOeLSJ36xKXOM4dUK+0neRzhY0j8NeDROL7ICwKM1hI1 ###xuijOSY0d3lSnYB0LISkywwGJ5CBgDE3mFQz3StNCuEh4MWF9ERESbMQKWnGc9vN ###GO1AOpnuKuSuItSBsSuqFyh8IhnyTIUKRczhGqSbB6zVqmEErG0C+niZd4neaCXR ###HISCHmaUDSKIQK9F1BYDPxBaSJh5EvESyZKGSdOIU8Z8tMEkR9gkUIlwmLUyr8BF ###ECATIbKNlTVCoxSibJB+GzNXYgQkvqJSXCgR04MfEGMgGor4bco4aBB+aWiPEXiD ###/g0KPMCw2Emkfz38gzFd+MEsQ3400MRy+AfNH4JEum76qB74R14H4B9EbvoHkRL/ ###yBShISOJSgA2KoEuQ64WVJj7kekfsFYatOxJ584eUGGWQ44/wJIiWlI/7A4RMKQU ###PZoqKA26l0Je9SM3GmZiSFcopiqgXPIjqvjhWz8AJpqWTAkWXOZ6NI+AUv1olN5F ###uR+Z/pEqji+jKQDYqAa6BDn/sEiL6UuLjhQRjqNQo6kwU16/Pu2d/rT36tX+7gk5 ###/Hvo8FemSvXX3HrNZUAY3Nw5eM5dnue6zjv4i9fur2LceZ87zq9iC7pgiH7u0CfU ###ydwszuQrUpYLEiCVz7jcXFACYv6e4Ihd4Lchf0+wZTeIU2k9Qfbmgpmd8fcYZ9kN ###o0Dqk4Xuhlns8/eIvkdBmvJ3MpDdCOxd/k62gBv7qj5ZOW4M1j9/D1Cpc+Nu6vN3 ###Ilk3CbsCn4eM100yP6TvIA5hVtwUuDB9B0GF402TmOEHesTvmZfw+EE3CPAZDHb+ ###HiPxuFnWjfl7RP13Qy/h7wESngvgJPydlAsX9NRACnioSsCLOAyohJehPgMvuiGj ###wJMpAMbocYkY5Qa8SCMGwotQ/sMk+RGPwgtSmiXALg/DI40PXnRDghPmg6uEYMlh ###iaBLfgJ4kfoZl4hTqhJBVS4RdgnSKGJcBl3SjOBFlsZcwvOoRAzTTyWylEvEScgl ###spjbSAAgLhGmNFrc9+USfkKDS9KYe0m7kccU53epRJr6TIIRVsESUUZV0iziXlLS ###L1yQcB6PNvU8fhEnhI8g4WkF1dEnjKF/jl50A1UioHWA9EEzF8RdHku3GzE+4hQl ###lQuSOpMSEa0kTL3ncwniOvCiG9PcBlHX59USMPkAnCEtF0AIQxqRRw5edJk+QB4Q ###QYIKGHEbYYqKCbyIYx5tGKVcIku4jZBUdJd+Uwn4QoBBSW4D6lK3YPkyTtElhy+w ###NyoB/VMJgCegEgAhtQEQ82hhDAG96PqMDxgltYGjphKAByoBeGFIAVMZM4eQekFc ###dukF4BZLILapW8B+zCWChMYC65EgxRmjXnAGqQTMKZWAOY64BJkfLlEBlQC6INBT ###WbRIOVwi9RmO1GdIkdaoBFAflUBqpBJAn/wiTDMu4flUBSmaSgCNUy9I81QCVgGN ###Nut2ibXiOqEXuG6oRBQxfXTDTEqQreri2qPZh9UY0GTD6qQVheu1y/w05NFCZcQY ###rXAqgWueXsB4uQTpxi5yCcapn9JkEx+hEsBZuETKXBx5T5deZBljHbgTVUFuxSVI ###j3aRn1EvwOCIryO/wwLAAPl75BO+kEHScxwSmBmvWeKn9N1LuHwaEyqQAdNzltB3 ###YNAhPXd52oGBU3vIz/E7Mnh6Bn6P30EA8HPAXAMERJefGb5Y4Ed5gt/Z+e6SvMHv ###IIAyfs6YC2fE90leEYuN0HBySZ4x7+ty+wkjCGicyycJrw6fcY7yUkiO6wOV8ixl ###DE/Kyzwj/kTSmMAL5TEhklYP9M1lEak/ouy267pW2zS9JL3tzkl829CR/LbBJwEu ###46PxkwS3EUAi3MYQyXBBIZdAIW7jmKS4PQkkxmWWYi7RTX17Gt3iPJMktwmBRLlN ###Ka5FSiTzXUNrUiIj97shRteiVoYU5bmQM8PRlflT9M4SXVZEzGhHkW4vGpbp9rpi ###oW4vPZbq9upksS4LmCe4tMZZsNtsgCW7cIqEy4S8RknUc5mI1QKS9VwGhTuzpK7A ###jNLd5los3ukNiHsuE9OWmOF9LOBt9sgSXjiojB1FvM1kWcbbfJiFvLBqwTNKeeHm ###gp8iw2c5LzJBxo6C3hYbLOlZsvjSV1dEXCLqC8t6Wz6xsBcRxvCQtBcpl0iZbhzY ###gpDlvcjKTBZcwjCjAiBlukEiEpfJlES+LZRZ5rPcZvWahb6IdilTlP4s9kVBSKRM ###mnRFh5BxWWqGwIySXzQRVUYknC8qEct+0Wd4LmyVR9pB6S9akSqTEi8ndUDKGN2K ###aYMUAFG/BD+oAYiGJuOylDjpC3UA0fOkTFEVZC1AtEWZL1QDRKFUZbTOqWC21FIp ###g5qAaK6xlDHKbSBljP4rfWUsJ0g54DKWFi20geqAKNoyLtQHRBdXZdhMIwVBynRJ ###RJOGwAzZUvoZhyW7gJUCMR0CKWOsi0jKGANElTE2ivRlmTEMM2kGYumkUkbbQpkU ###iYghoa4gJWLij8qaci1zK5ASady17DFWECyDzbUsOl4QlsnH81S0CV3LaAylBEOK ###SoOU0GanQGrsUtVGREIW9QYpoS1bQZoxfRMpkYSs3HVVL9p4DlQJZV0LUo35rdpI ###iUco+9zV9nviqQJs3osIsk1/9VGJY6krpr8rtr/dNHn0Uo3HRLyzoQ2+Mv1dsf2V ###6a8QoEx/hSFl+rti+yvTX+FYmf5qEpTp74rtr0x/NY3K9FfzbE0zEYIy/RWlKNPf ###FdvfoiTiLxapETEq098V298iVrL9lemv6F2Z/q7Y/tr0V4tGm/5qXWnTXy09bfqr ###1alNf1dsf236qzVuL3He7VGmvyu2vzb9XbH9tenviu2vTX9XbH9t+iuupU1/V2x/ ###bfor3qdNf8Uetenviu2vTX/FZLXpr/iwNv1dsf216e+K7a9Nf8XwbX5Ptr82/ZXY ###0Ka/K7a/Nv1dsf216a/kkzb9XbH9tenviu2vTX8lCLXp74rtr01/V2x/bfq7Yvtr ###018JZW36u2L7a9PfFdtfm/5K+lvCn21/bfq7Yvtr098V29/SMtj216a/K7a/Nv1d ###sf216e+K7W9pPGz7a9PfFdtfm/6u2P5GtRLbX5v+rtj+2vR3xfa3dDi2/bXpr1RB ###SxNk21+b/q7Y/tr0d8X2t1ROtv0trZRtf236u2L7W7ot2/6W+su2vzb9XbH9LSWa ###bX9t+rti+2vT3xXbX5v+rtj+2vR3xfa3dH62C2yzgGx/bfq7YvtbxgXb/pb9wba/ ###ZaKw7W9bMWQ7a9PfZdvfmEJs+2vTX6wpbfq7bPtb1hbZY9r0F4NNm/4u2/7GoGPb ###31h8bBMak5Btf2Mzsu2vTX+XbX9jdbLtb8xStv216e+y7W8MW7b9jeXLtr82/V22 ###/S3bmWx/Y1yz7W+sb7bPtenvku1vzHey/W3TX1v+EjwmXzIJ9OJqplHl4oqtPtng ###1yCxuW+cFWTsa1ufTX09Xjb0NTrYzNdWPhv5Gpls4mtcs4Gv7Xs27/VMFSaSTXs9 ###z2zYazIwVBIaB5K26dmkN+4lTYJd8U4lTKFdcV4lFgGLKa8teTHkLeeXrDvlHWMj ###3rjP2IQ3/jU24LX9XlymYrwbFx6b7tpyF8Nd2+1itmurXYx2bbOLyW78jGywa3td ###zHXjqWRj3bgy2VTXlroY6sYZyma68Zayka5tdDHRtYVe5MpinmvrXIxz49Jl01xb ###5mKYa7tczHItOsQo1za5mOTaIheD3Dim2RzX1rgY49oWF1NcW+JiiBvnOJvh2goX ###I1zb4EUhLAa4tr/F/NbWtyXnI7UJELAikKpdgoQ1hURtI6SsSgTWPoO2ucXk1ha3 ###GNza3rbUma7a6+DIEKY/MbW1pW1pTJHaTolYpfKt/RZru4UWn7awxcDW9rVR6wQ+ ###o/fFalMoY8XQ3jXSdrWlWnL7bFRrm9pSTsU3Swa1tqfFnNbWtBjT2pYWU1pb0pYG ###nVrba9buGhnR2oa2lPTI2sHT9rOl5netPUBtO4vprC1nY0hkao8xIzsjVVuQqTFD ###jJUSyAYmGsxm/5LMZbO9qUwge3dUWcoFA8rYV6HaeqUIwahr7cwqC9kYb6Ha103J ###tsusbV9lGxvLMFGbxqT5dLvWnrKyio3ZGVk70soiFoPY2q8mkzax97rZFsadeGsH ###nnLi/Bhl+Z1383ZZgDDutZ+NFrPhRyhl9tg9Ca3jkFQS6J6E8gUka5GieVXRN4zz ###xfIU/eVTpKTXaUSxxHb6OpQpRNZOsXm0xlEzjTwJO/NFyOEQY4lAo7i7kOM9YwoZ ###8jloC4tS8EMswUxBSqEQsUQOZSp4lqR/F6P3SIUIqf+Y4zl9DhBGeHEcBC6ZKF0K ###XPY4cpPC2UIsH2GcDsWGUQRdiBWilIgfB+lJBBqF5erAnCCjJ49DSilADpYMYIdX ###jSdRXCSEI6oQS/xiQAPMVAgVS0WKio45ljSgiGY6fUE45ThawgqdyMB3ErNJsWch ###BSb5Er8VkPaCYWQJBbGQkKdIW59jACkGMsTyEcV7JRJhGdA5EGRCxDg5ZJsiRJJO ###g3hTlxQQIlYVpUihenQWhGzNROI2ifeGiQQB0jkQPmCCTVCkZEah2+ToSThUlsIy ###KXw7iiWmnlQUMrhCHAcH+/l0agLx5XOsXcDKHb6iIFHflwA2iqaOKDTUl4DWgAOs ###JZiQ49MyigWWoGAKwAsp2pBQSvE0FAlKIcJs/EnQJMefw0gacSJRQgGOJMKRcHAh ###6dT4inBKgacUAh1TnDM+SjwcSvNGyOchJOQzII0duTZJIrJPMAIvwvIcUIivsHxE ###IaIS4tcgzSpMJYyaDt6Q4k1nWlIVPRpi+YhCAnUMZEhx1wkHeftsceNrUmNTDnV1 ###WLfGJhIVU0TGVYTluyqIM8TyUUxhgRIKGdDwcBwMLr7CcUS+nECgAMMQy0fEMDmI ###Ed9BhQYpLBR/S8G6ZP/Q+SeS02T84hO2wRGhpB9TgHkgEdAYtNog4zKiCqmELwY0 ###QBxJnEqYbYAjiXAkmQoaC7E8n0fycVykcMeEZvxLHypAA4EO4oQSIx2Q7deVuHQK ###XcMTNwB52GmQmkxGBQWiU2Czis0li50Uj0iFIpLLIkKzPFWxXXg8ARhPJmHlFJUa ###UsBlImdVOE6VTi1kHPbHAZ1kU2ITicS6NUKP3J0Zh64HZERj+YjKhxLVF9DwcBwE ###bsqaPuIrpCD0RsDWK0X2hxINyhYzVog40o3UGYmdDfEVFSW1E5uO8FBSqsLm6IRT ###RCil+NdAHZyIuIIEYwc8wIzDtn12cCB6cCTk7fHUUZGIcEpWDB1JwApRynGqPgdw ###RnLOg1QvPLpESlZIB+5U2F6IemeE5UnhRW9QGNJxBgrxk5C+ADUe8i1S+Drp2qhw ###RajVksuR7HWfwpVZEZPw6hAdBRFW6EpofkCugwRPdXUlljqg6HpsgkLvM/KWdMmN ###zoHMpCaFdOyCykcSbRokeCALxxFHKjgYxxHhODIVYBhSoC6FQXMQM77DChEpnRFH ###yALjwfdpxHHQfP4H24iwjVRFPIZYPiKUeipWNqQDIAmfn2r45IXDkZCSzMHi7GZC ###yLp8aICivcn9FEVdOTlBIfxhTFpet/KMmNGgQA2q0Kvw7cN6FZR6B/+0XpUo3Yoj ###X5XuE2oFSNQoVrZQsYiUMoQ6U4OC1pWWEyhVJxBdhTUaUlhiiQYnZQf74eB41GBS ###pcH4SisJlWoSiGrBCggpUEpNYW1Gzpc2+ExIqjQO1iLkfEgm2kKqNAZRCORoQSy6 ###RSPSRxgSpSEoqR8o0R+I7GYJTwJc1ABUFhqkC8RKmCvLleV4qmQ5x8qLqGWBTAqF ###iG2R7thTrIQvy+iQ5W6iZC9H9SvZGGoBied4tDAmQaKEJcvUgM86qeh1FoWBOk0X ###iUBrhCIWWXhiP7ESbiwDQ5FrqZJtHIMvogcFFMc1R0qMsbTDnuJUnedIUwn4V1Im ###MKHSJCs47JsFBh5W0MKJGKsSHixjApYbiZIdFAaNwirTEoAYvIgJFia+nJ/i0P9U ###cXx8ShWvp4DoQFgxM2wSOIqtM/cP5NQNH05KFYdWXDegc77CXVPFYZmBChum8yzE ###iyPFTJnnBsxHkXnyMadMuGGmOSIxPHUoKVa8M1bMj3lkyHyPz6OEirUFwpqYgXly ###IITYHHNDOiGhmBXztPAhPmWfIc+/fZhP5c6Ri8GXaF7EXChVnEgMr0R4TCDGU6bM ###I18MoFSbOGLEZMpMEUMkUTyBjQm2HjzmA6Hwgq5wgVhxAt/Xp3x4jXu8vEm5zrT6 ###zApyIiqwL0puqlamKKoJrznSPWO1In1ZZ5Faa54ss1gtNZ/XT8hrqNGV1RMpbcvj ###dRHK2uiKThSz1iOUz4oMay6e6CaxInmf6TgUWu4KFUeKkj2iTxLsiRLdIpwzTYEi ###YFMtQkVIZkJZ9fSUVJFT8hhqSrx3ieVLELkWMekEIp5ioZRApEws9irLCpIOMvWh ###ZvLMxyNh1TKvoXBcZqrERmOZwUC4YSx6t/C0iKcnENbEeQTkxKGwFMF3KJxB0Buq ###BS7IjHiZLsPjyen26a4+xNDL47P0sXwuwtwdqf+yKvDhXZT7lADdmUAhzJaEZ7jl ###FV30h+9+VcclI56LQKaFj2gR4suHtz93sA1OGT/HVnL+og71wI/qY+ngRrHQ4xDl ###1yHK/1JE+XzoKyohSvBUQlTCeHoYQRpNzlJEcbe/F6KCOkQFX4qogBBFZJJHVLAE ###UY+mpEcgirv9vRAV1iEq/FJEhYSoxNPrTCEqXIKox2LIwtNSRHG3vw1RBYTRdbjq ###oJZ9gKv0YVk2GrrHVIHAB7YkR8ZDGToSTuIR2nk+4q5sBvOvkFOB+LwlrHaG6VfI ###28YhF5Et5YDThEh6EZ/rsbM0kc3hrmflI0nSRDaQqQhvRfMOLZi9nuwm06/AoyLk ###5MatKNlapl+8lRzziGIycWWrQOdG4X3smLR93lWAXykbzjzoiLfb0R7HIryJHLKZ ###EXKiFfY0BOi5wVwsDBknduFtDfjFsKCDD4qwscs7IPCLHdrsuw9QcW3IZgn84vwY ###HhlsYEtEsoWNRTzGrse7z11yafAWTIjpcyh1DDkawQjIZHObfpGxAVYhDhqU9ER2 ###ujnzDLWScsxFklICGtoDgl80jQAfVYh5hxyj1qBITM4ZPyJvhh/xZjoZ/IAHck/5 ###5HCDX4HaHadfCfv6cH8i9MUpRho3/OIdeo99nrir2ZDNrdDrckqdbsz+Es66gxth ###6Acjt5SXkeLipQQSb5rBL6I6LyFnk0eJgGSDDX5xPaQJKELuetmMCz3yf8OvmH9x ###EfYpeewe89gB7ZEFwZt8UMSjPQPPI09xtyu+ELJju1mXPOIZ+TG7GWmcHDwHv8jv ###1kU4oQiHP3EcHfziwJ2I07KgS78hIXXwi8zybsBb+OTN5w1MdL2T1dalFEzwK/Zk ###F58cWujcCjJK3YQZjjLZ0adfEe8oYF4K+BWpaCX6RVFnGYdBZeivbciGK/zirEm0 ###rwG/aJeZNmcbmDCK2vR446NLVgtv5AYpdI/+OsoDBeuGvCO86Qv8iP3YMXoGMSeR ###J+FY9Ctgjy1tZaWUXkY2kwEEsvBT3uNIvSSRiAFMx9XlzZ2M8JlkhGvepAYO1OWM ###XTRj0HkkkQTkf2O3ZUhu04R2pCTYD/gRuzjYE594NGjeKIdfvJ/BoXRxxvZYym44 ###2ZxMPM6CwF5WjgaMQ4Il5pRWMa0ctVnPgTHAx8gHE3VptLKxH/FsRmnKv+j8twQB ###RDE1HUU0AVHEzlNy2gPHo922SFIO+JIsguz8sEtpskLuIcyiQIIAyUlDjYVItFAk ###jlTEILkV2PIKOe0FTk5DBzh4XM8jxy4QtopyQGOQ8pUFLDsCTmKlYg+DiLKqBRHv ###3XHTEoYY8L4mDIFcdR7n3eCIRJ+D+XzaxYWClAhBghP9OGA3RMR+Fho0xSlCEc5K ###4rMDGhhSLNES5BJJPfL5sMOaMqupABIvpo0BD7c70c1Og5ZgE48zNHjcpuchMUhg ###CvBEzoSW8gZQwolREE4oEpPrsstO2W7IFQJJSJFSKx4fh+eoBg6OwSRr5KpMQ8rd ###wOnYOJAG0EImdhby+XZk1A0JugGZ4XOqFqqecugvRUU2/JTjHgCd9JKjIjhAEsRK ###l3Iz0OaJnwbsQpN8EhyvkHQJliTjTcyUk5EkHMsRk3M8we2ahkRQAiNhTwWfkk/E ###JYvBlA2QUeRaizNyl8Pi8iTCgxywtIMY835QTNExEtTkxxw7EmP4FzqzyRXAAVAg ###29jvmYg/lrKjcLCUH5F8gF/kmI04qQIFVuGBfd6O7rK3PeMd+JS3ipA0GrC0AvZG ###cX6akFO8sEs4RPdbAzMxhxJ3Ta49jtMmdctHHoReMWKHfhBJKi7+FfAv9GqiJcFb ###AV3e28n4V8ovE3R++IAYzmvEv0LZz5MN2pBTwoQq4oRcK7ypnMreMqYKkjBP35O9 ###2JC92+Se5IhPKOLR1kuXtrczClcgpHQTdM91Y6SRLu36c4Bdl7DaJQ9xRjGFHIcH

Bestie, I can't do this one as a rewrite ๐Ÿฅบ๐Ÿ’€. This part is just a block of base64 characters, the encoded source archive that Appendix A.3 is already carrying. There's no RFC prose, sections, or BCP 14 key words in it for me to translate into voice, and I can't turn it into readable text without guessing at the contents.

If you paste the next part of the RFC prose, or the part you actually want rewritten, I'll give it the full main-character treatment ๐Ÿ’…โœจ

###JaAjok80EEJA4isqxYUSMT34ATEGoqGI36aMgwbhl4b2GIE36N+gwAMMs8Cj5h7x ###gzFd+MEsQ340/JRWQabmD0FKSDY/qgf+kdcB+AeRm/5BpMQ/MkVoyEiiEoCNSqDL ###kKsFFeZ+ZPoHrJUGLXsk5zB7QIVZDjn+aIBNhn+pH3aHCBhSih5NFZQG3Ushr/qR ###Gw0zMaQrFFMVUC75EVX88K0fABNNS6YECy5zPZpHQKl+NErvotyPTP9IFceX0RQA ###bFQDXYKcf1ikxfSlRUeKCMdRqNFUmCkY8Yqx3K/2d09oM6yHm2HKVKn+mluvFMC8 ###+DQ6Px8P8fSvg8HM8jzXdd7BX7x2f7VMO8f19MPnjvMrm4Do95BvPpjbYPEm8LXB ###X5M4DQP5GiQwYV0wRXVdEFNkKONXUI9jMFVN3SwBo0S1HAdhGIONq+umYLR3VctJ ###HHkhaEe6btL1Uw0VGPTovDB148yLuuprF1Qm4IembhSDwS2j9T14yiJTNfQSfOSP ###MGNhGnm6JrCJKFMfwZYIuFmqmQEqgIbkYxRG3SAJVM0sRaehYMKPE/gMVr6qGccx ###2/n4MelC1Vj3mYVBHJG3Aj9mAYgxwJmqCUOPyZGAH7voXQ11n2kGAiKRccLa6/rQ ###tqoJA4sCNXEg9pJuGkW6ZhAmXYV7mJcoikONIfTtegogEN2gEJp5SWKY5EwwD39l ###PnptVU3QUuJAkBCkgExAvqpJZVNVM4swtDdSNWOYwW5X1YReIlD9dE3QrZJYoAXQ ###YLK7epwRoNPzpdkQFIGwG+maUZCgi1E+hmEGc6/HGQI8vpqyEMaJripVE2hVHH4u ###uU3DJO3qcQZZ5rFbDD+il9DCbQBWpaZ6MDPR0aXnE9hEF0wC+QiQRmGm+wSTIIoV ###aUZekoZJojHkwWSHfiofQcGKYUJVTQ9mQpNJBHQLmoVa4EC2WcpOL/wYgWaVJWo+ ###sy7YMBq3QAXohNc1swjpWtVM4gSsBEV9WQrzmfoylChNQY9JFW6hQ3Riq4/QIWhN ###CtosSQDeSOg2zrOjLO7CyCOpCeMIYHo1tLAegW4EQzGoAt1MMxRgETDMTIYSh2EO ###WkAzzJOgL46iJES+JTVDUNS7ieozRs9zEKqaoIQSF+CPMCNeEuiaYJsApSqAAAlR ###rPlQpiiVP2YpLmVFQ5kHpg5QoHxELhAliiekSH6hIs3EA8T6moagFfQEC4EBZF43 ###7KpVlhIIXQEI2G8IKq1aK8iiIl8tXsAArBVP95l4kRd3BUNJ1AVGqFd2GkO1roIW ###SC+M4kzhFmgYVrpuNiEnvK9qAvGD2aBqAtF4XqqhDZD7hqpPYKCwAJRwScGSAKag ###kNBNU5gxtVZSLwW9OhWK109cU5flj6odrql74Y8KAqmp4OOPCnapqUbGH9WopabC ###CX9U+JKaCpv8UWFaaqp5kI8yR1JTzSB/VLMrNdXc80dFF1JTUQ1/VBTFNTW90UdN ###i1xTU6p8zPFbTeP8UdG/1FSrgz+qlSM11brij2rNSU21IuWjrFapqdYyf1TrXGoq ###LsAfFYeQmop/yEfhLVIzpxVprsQ1Nc/ij4qfcU3N7eSjcEKpqfgkf1Q8VGoqDssf ###FfeVmoo3y0fh21JTcXX6qDm+1FTyQD6KrJCaSpLwRyVluKaWQfJR5BPX1NKLPyrJ ###JjWV3JOPIhOlppKY/FFJU6mpZK18FDksNZWU5o9KgktNJd/lo8h+qZnjt1pr4Jpa ###p5CPom9wTa2NyEfRVKSm0mP4o9JxpKbSgOSjaEdSU+lO8lH0KqmptC7+qDQyqan0 ###NfkoupzUVJqefBQtkGtqHZE/Kv2Ra2rtUj6K5ik1lV4qH0VnlZpKo5WPou1KTaUL ###y0fRk6Wm0qL5o9KwpabSv+Wj6OZSU2nu8lG0eq5plH75KhYBVzUGg3wVa0LqamND ###voolInW1oSJfxYqRutrIka9iAUldbSCpr2w9SV1tXKmvbHlh3WTVB+oI/WzospLn ###5+w0t762W9+1Ww+3Wz9otx5jbj263fq5cmvn2a0lEbeWutxawnRradqtXQ5u7Upy ###axehW7t+3dql79ZyDbeW4bi1vMqtZXNuLYd0a5mrW8uX3VqW7tZKA7dWkLi1Msit ###FV9ureRza4WmWytv3VpR7dZKebdWQXBrdQu3Vi1xazUat1YZcmv1KLdWBXNrtTe3 ###VvFza3VGt1bddGs1VbdWyXVr9WO3VrV2a7Vyt1ahd2ttAbfWjHBrLRC31nhxa+0e ###t9ZkcmutLbfWUHNrbTy31jx0ay1Lt9YodWvtWbfWFHZrrWi31gB3a213t9bsd2s9 ###Bm6ts8Gt9VO4tS4Ot9Y74tY6Vtxan4xb685xaz1Bbq0Tya31P7m1riu31uvl1jrM ###3Fpfm1vrpnNrPXxurXPQrfUrurUuSbfWm+nWOkLdWh+qW+t+dWs9t26t09et9Re7 ###ta5mt9ZL7dY6uN1a37hb61Z3az3ybq0z363dB3BrtxDc2t0Ht3bjwq3d83Brt0vc ###2p0Wt3aTxq3d33Hr94bc+o0lt35Xyq3f0nLr98Pc+s00t34nzs3t4flAA8DAkwiM ###xaSieql2ru/qrhXglXDrUVcOWqOsEmMa35Xo1pNVOVd6oqvmWdNIFYlo8qqgLkOZ ###FYRpiLqKpvV6qFoOeilVrSS9CisWoVnAFevXrP2qpa/ZRgXXMBynguEYZlXFqzSf ###q2BzhkVWcEjDXauYq2bMFXzZ8PQKlm7EQYU0MJKkQpAYIVQhg4z8qhBfRvRVSD4j ###NSuEphG4FfLWyOoKUW3EfFnKWxpCWUGwlIsK3cLoJRVqiVFpKjQaow1VKENGkarQ ###o4wOVqGCGfWtQnszml+F4meUxgqd0eibFeqmUVUrNFWj5VYouUZBrtCPjW5dVq0t ###tbyslVsafYVCb4yBClvA2BEVZoQxQSosEGO9VBgvxvCpsHuMzVRhMhlzq8LaMpZa ###haFmjLyyjWfZh2Xz0DItKyxLY5VWGKXGoK2wZ40tXGEKGzO6woo2FniFAW6M9wrb ###3dj9FWa/cRmUPQaWt6HsbLAcFRV+CuPjqHBxGPdIhXfEeFYqHCvGKVPhkzH+nAp3 ###jnEFVXiCjBepwolkVKOy/8nyXZVdV5bbq8LrZTxmFQ4z42yr8LUZP12Fm864+Co8 ###fMY7WOEcNI7Fsl/R8kmWXZKWO7PCm2k8oRWOUONErfChGv9rhfvVuG4rPLfG61vh ###9LX5bdFfbPmay65my01d4aU2Hu4KB7dxjlf4xo1fvcKtblzyFR55482vcOabjYDy ###PoC1h1DeQrC2Hyp2H8zORcXGhdn0qNjzMPslFdslZqulYqfF7NJUbNKYDZ7y/o69 ###OVTeG7J3lio2lqxtqYpdKWtPq2JLy9oQq9gPs3bTKjbTrK244k6cD1wvAYhjss3s ###c3XlTcBC3dpuayGuHWwtnmpRXDs7dfNaRxB1lFRHgnW0W0f0daulbpnVrc+6hV3H ###EepYSR0PqmNedVyvjl3W8dk6Bl3H2etEQp0sqRNCddKrTuzVycs6QVsnoetEe51O ###UKdM1GkhdepLnd5TpzDVaVp1KlqdblenFNZpk3VqaJ3+Wqf41mnMdap2nY5ep9zX ###WQV15kSdHVJnwNRZPnUmU52tVWek1Vl3dWZhnT1ZZ4jWWbB1pm+dzVxnbNdZ6XXm ###fZ1foM6hUOeJqHNh1Pk+6pwmdd6WOjdNnX+nzjFU51Gqc0XV+bDqnF91XrM6d1ud ###n67OwVfnGaxzKdb5IuucmHXezzq3aZ2/tc5RW+fhrXMN1/mU65zRdV7sOvd3nd+8 ###zuFe56mvc/HX7Q3UbSrU7UbUbWPU7X/U7pzUbrrU7tfUbvXU7hLVbjDV7U3hATnr ###YNzLvdPj3R+B3+cOxJm3y/J24BG4s9FiNvwIpczRN09OvHOmiITSRcgJ+4BSQeAR ###YT7pSd8w/QaWp0PZPiUw8DqNKJaUC74+YRziGVs6Mo8HCgM8Xhl5chqczqaHWD6i ###M/50Oh6Pw4echiGmk7w+n6XGonQmMZYzxkFKJxRjOdCbqZwWEZbv4qF6bDkMqf+Y ###0yz4nLcD4cVxELh0nLlL+UQ8TqhAp8xDLB/h8Vk6sk0H20OsEKWUywAH6cnBcMqW ###oc/LBhk9eZzpgc6thz5ih1DKaU3wHVaIqEIsaQUCGmCmTjbT8WROVhJzioeAEo1g ###+YhwyuktCCv4jpAqqRToSHhI54V9OVYd4InyEE93J3S2FJ88SoDh89F8Sk0QYvmI ###jmEnkvggiBPJBkLn0zmTCh3cTDoNOpiKh+dDLB+FKnkAnaAPKZkGZbCQdAp0xD1M ###5Gy+jy0H0EQjxCYogUFGGVWwHpanY/l0lB/LR7GkuqGjsAEND8fBZ/BhVEGXDun7 ###fASeTqGGWD6i3A2UeiFUSU4iytjgS56JgPOeyBl/PjaeUYoOydVB5+JDSgJAKKVj ###rpSggTJ3UIVEchlwWhgYSSNO5PBugCOJcCR85h8LYPmIcEr5ICgzSUzpR/BRjqlj ###AoJGiFlFKBMFnqQPUsoREHCyETqxHuLB+AjL8zl/fIXlI8rcICfvGwEmFglTyW7i ###46H3IKNcKZjBQyV1CLF8RCf1dWqCkNKhJJx7xedkBfg6SflEOmagALjwCZtI1FHf ###EFuIsHxX5VYIsXwU02l9yVAQ0PBwHAwuvsJxRL4kBqJz/yGWjyijAecWwHdQoRHR ###IexAknUE2EaYBpzaxcemA2wjwjY4UQMW8CnvSyCJSTCXBDAefEcVUskqENAAcSRx ###KtkvAhxJhCPJ1FnuEMtHhFMfxxVSOg1CM/6lc/1g3hTM+xCGkrokSCmViqSLoRPl ###IWY0iDDzCr4OfCqOryjfiEqZEVACIMwOEKkMAUFG6VkyzmlCR64xaxAwnkyyvVCy ###iJDyICSSQorTR1AyoYxP43OehZQy5GSctgaPoDdCbCHC8px8gjId4SsqH8ph+4CG ###h+MgcFNKuETZbULKDdOg1BFhQAl3QknSEISUfQjf8QF0/BdKSosQX1HRJJQUTiCK ###gfGo0+yhTwVCSQYRBCqfUcQVJEdKwAPMOJsKJVYIuogeHEmWSUYKyuAUEU59Glcm ###yZailNNH+JxXIZL0S5QSI8aT8ZjUIsTj9Ik6TR/iwfgIy3cjyb0RhpRliE7ey0n7 ###ADNchJgchLLKYN6aAFO3RJhJhHKGYBaQ0KcsIpSkpitZT0LMYRNhha5kzAnwDeiI ###yE8lxUlASW+wCcqIgy2H2EIUSNKbAFsOKRsSlY8kCQTo0tAMjoPApZwdOI4Ix5Gp ###c/8h5c+g7CScWwTfYYWI0qREnLgCGA++TyNOT8JpubCNCNtIVSKCEMtHhFJPpbAI ###KS9TwmnNGph5ByBDiHEknMMFX3Upm1OXc/lQEpYwoGQoXUloRJl1QqwQQYXGkoQD ###rEGBGlShV+Hbh/UqKPUO/mm9KlG6FSekULpPqBUgUaNY2ULFIlLKEOpMDcolo7Sc ###QKk6gegqrNGQwhJLkhZSdrAfzlmDGkyqNBhfaSWhUk0CUS1YASEFSqkprM1gTzGm ###a/C1ThKynpEoXYNUCZRgqdIYRCGQjD+x6BaNSGcWSpSGoKR+oER/ILKbJTwJcFED ###UFlokC4QK2FOSZdIovtKSodKVAcialkgk0IhYlukO/YUK+HLMjpkuZso2cvJdpRs ###DLWAxPRaWhiTIFHCkmVqwCnIVFIZFoWBSnIXiUBrhCIWWXhiP7ESbiwDQ5FrqZJt ###nBpHRA8KKE43EikxxtIOe4pTlWaJZFbIcijRyecykSZpJtlYWGBgDiEtnIixKuHB ###MiZguZEo2UHZSVBYZVoCEIMXMcHCxJe0ZpyRJ1UcH59SxespT0kgrJgZNgkcxdaZ ###+weSDItzhqWKQyuuCwyjwYlMFO8MNQMVNkxppogXR4qZMs8NmI8i8+TsY5lww0xz ###RGJ4KldYrHhnrJgf88iQ+R6niQoVawuENTED8yRPE7E55oaUuEgxK+Zp4UN8ys57 ###nH/7MJ/K5T4Wgy/RvIi5UKo4kRheifCYQIynTJlHvhhAqTZxxIjJlJkihkiieAIb ###E2w9eMwHQuEFXeECseIEvq+Tb/Ea93h5k3KdafWZFeREVGBflNxUrUxRVBNec6R7 ###xmpF+rLOIrXWPFlmsVpqPq+fkNdQoyurJ1LalsfrIpS10RWdKGatRyifFRnWXDzR ###TWJF8j7TcSi03BUqjhQle0SfJNgTJbpFOGeaAkXAplqEipDMhLLq6SmpIqfkMdSU ###eO8Sy5cgci1i0glEPMVCKYFImVjsVZYVJB1k6kPN5JmPR8KqZV5D4bjMVImNxjKD ###gXDDWPRu4WkRT08grCnm2eBEgMJSBN+hcAZBb6gWuCAz4mW6DI8np9unuzq3UC+P ###z9LHcroium8V3g4d/ZdVgXNqotx3+GJ2KIQXfGCuIuCWYCag54g+4aWtQ/yGaVel ###+PxqxOV/VRkOI56nQKaMs6rRpJTzrX7uYBsX/QHenoCt5HxJHeqBH9XHUq6lYqHH ###IdGvQ6L/pUj0OU9bVIlETKhOyYkLSBQclpCYMA4fRp5GobMUiQzS74XEoA6JwZci ###MSAkEgmVkUh0WEGJwRIkPpoCH4FEBun3QmJYh8TwS5EY8rUDnl6fFhKJDqsoMVyC ###xMdiz8LhUiQySL8NiQVkHrzaMfna7DxupQ/Lbmy4Ph8YEDhvm6TKto98qCTeVq5v ###9OLrh9iXLUrjaecs4FmS+JHOHO6lgX5IQ7UNl3PdUx7yJPRVA5ipXicLD+OgGH4k ###D143DhQEGSaEz1Qm9LQbR4WoJHmI4qCrOs0C3AtUD16SJgoCa7cCHpJQ56PvppHX ###1fnbU9Dj0zgfw8QNJInesIKHMAt0+vXEA8DDfGiTPMQebZhSA4DcKFVfIgBH483a ###n4EH0JNjHfCUgfqrGsB9ojTLh0KpFPQwPFUHzKtUpa3vgtGYqJz89v4RPHhgD6hi ###Xox7VOoBVNIkyYdOcUZ8wEcSq4z4GaBHzRxu0kXqigB7fwsecA83kAaSJApDFUGV ###QHWVEd/eL4MpRVLqqocIJlXy0WchDFqRsr3/RjMfqlz5Gdgivq/T/Ud+ppBo7+fB ###A3xS/aQwJ6lcVgHUkgEa43zIFl8rkEaJr6BOgcBiuSEDHry4qwZn7zd2sQo0Lg2E ###gB+FqjQEMzEphHjJXQYwzlT142UB7SJTAx5utcX50C+5DCEKPBUQl6Qxrid5SBBU ###uRmB91cDFR/mpaG5WiEAc0JgS3CPOEztUDFZCwnQh6/uTIBZA5qXIeC2eKTWgr3/ ###240BpbGvLndIulBKRZrFXQwtsEPLZHBx5AHFSj9x6PGSoQYCLwkU1Lw/rS+R8HSQ ###ApCk54dqmUUp3s4iENj73bD+slTdIUNhIomia7p/QaFK759TA2ApR2rYAGeo77QI ###uyEYx6kduib94EZ+mPAlH8AEYdWp2Q6jNFL3rsj+vvoCik+QqC94cUxXZiEE3pIG ###QT7UjR9g6n3FhIIEMKBu4ghiP0i66o4OK/4AuEYSBIqqAj+Eieiqez1gzagHHc+A ###DQCnAnSpLwl+kwaQ3H3FiDk+Qn3BG2ti4QdgFyInlQg5mLtMhTtyvIV6SPCKGxVk ###FwNVJoIDLwSmpMIg7fgNZGIaggyZfCZfMuAbGDbAF51wPIjEmwHBBequlgwjezJZ ###gNCHYQ4mvoRvSol9xbgymAToU6LJMlhaiYLAjldB5ggTlEkDPqBbRadlXpiGIgpy ###8S8ASYDRB/IQw+oW4Zqh/PLC2IT2xRJLlAHb6ComlOENM4o9Zci3KOSoUYjPyZBW ###olgVCzAwK1VXx3hpLGvbxPtgA3GKd0NJP8DGI434OIKhiqCU+CHBAQwmiFNBYgRE ###Fgj5g5CExalmgeORpLUoBParAgejIADy99WFNxghltkhhTIlIcoi4eRZCBSWKuyE ###IC7CgFdjLl4qC4AR6n6w+1gNLoiRs3tWCGLAiwnEBazSQH1BHiRRqLCsYyDMXGii ###+oKrPmKOlPkYlpGoq328bpio1jjkRgaH9xZ1FRK92I8pyhkb8MIAJiiwQhlVjB4I ###la4K/MG7kQJ1lw4u/8gXHEj8msQK4qpNRLCkGapsghC6ZihTDXA8nC/3FgFGk1QV ###w8tmZE5BIcHrNAM7JFL6AZLKAlmNaQo8Wd+PlAIOPJELuXi9FKRZFEswFiyqJKJi ###2ECCF/MEnh1CqW5bgolULBqWD+g0njSAEWKhsHWOJ1R4i0CIZqpYhJDK+oHuQxBH ###kR1yKTiAxRiTvkMBl7A4VTQ5SFnqKR+KyQ94iZfwgzQAxShSUaAAM8j31A7RVPGa ###ITC4TH3xYB5iGYKPtxgJwUo8pnpAqhR9J0X+qAL9AdWgdnoyBA7plKa9CGZfBax6 ###QZQQ76UHjMCRO6Ik1FNu0AI+CrLSky8hrDmBGkQPMKgkyYeA8kOMa5uHkMAHtAvk ###C1itSlRLaGggDxi5KWSZ4C1KntxflaR+rNV9DhmVYaPZ2FWiDdYi0ItwvgRVmkCk ###s4SSqrjSBLm0eogiWJ3SdAxiNpClKSGmAgHyMHXBUoJ3dqWBikT1SWTYoafSGqh/ ###8C2Sa8jgg1JowZDKEqXZSUiqtAZaEJhg6gGYIgkwbABsrERJMwlVFVT5CepP6gvi ###UI3UR1ktd+txCGuo7ktLMDJM6oC4idXKAjW1G4XCXTi0VbR1jPnqKukco8WSymyD ###6hOBCZfaIa9yY1uGFwqKsh2jkZUmKvoVNXnhbxIKm6lb3qxg1xSXhehIyME07eTi ###x+MElLFEdQqizVNR50A4oEzJapTQWYldpcg5mUZUVH0d8QqGXaaYqoTUMh3EwLW6 ###6uAErH8/VHoIaIIhsEXfDrWVfmDFRHThGjYQYMOy0EGQBJkKl5UQXEEIaNrAkGQI ###wJLBPJQGwMbxAlmnHJrrq1hcED6pTGOMOrSy3mMPRKMy+yK+3ktiX9EwCQVqIHj4 ###U9g6XvUHWAitUF5BIti6sFJlmYEehpeiSZ0Mb4kUNS93fiHCKxc9kUxRCrAojhQB ###qwB6Da3QXznohHMDLUhwL0YVBkLKERCCp2GjkGAFARgPqbqNEbk4DEPdUQgIpiMT ###DR0qrGKDu3jRooAD2jWwA4E6BNpVjgEOIfakAdDJ41gFM8MS0YpzhDfBdQXxHFqs ###4ppB7wC7WJDoB6mXqFnw0FiUmZOQY2naw/sYZaFHwCphJiK5mjFFbSOyQpFFnQzR ###zRELVYUZ6JDKeAjx8sJI7rPLnZ8B0gVykSD5ENYoLA2JEIa2wPBKrNBlISQwM0Ff ###ySSoGZhi6olcQOLXhCQhzXK7ZAwKhpdJAzAjsfJkAcsBSRflQp3VQwjqoBpCiH4c ###0Q9C1Aa7WWiHQEtrIV77KRw2BLELYlMADTCOOJYLMik0WowUYMrQhEIiaGKhUo/R ###ToM2UjtkWiAAQeSp2yVBvUlReZboaXQxBblQaolJBlkEa4shgNWDXEiKZXgVqNAb ###h1gLEmHxZOiQkABrkBFhyhAEoLzg3X9W6LXwEFRgs66s0wD9PrHwN4w0TjNRMCQk ###WzqNgW0kwqJRmMLyCdT9o2GgPAsSqs1yAaQUimoVqN3FYHZpAOg4UMa3hHALOKgK ###Bp4MAZZCqph3AGZspuzT3Hk6sA9iIAQpBhMHE8GLCb0cvjpWISHfgirQdzxlFAd4 ###EW0cqDtYgXOpxcSh4DJZPlnFIml9wC2oGIE8xMhFUjtEnFVdP+3Sdbn8JcWlFKoH ###sItCIUsOHRfbGeQ5cLQgk8tig0y7RP0YaUcIiUPKQ/UAuoIv0+ijXy2R5QwGD6jb ###qhiHmkunoE/rw4XA5zzmo/QAVNSVa0olBF1GCmo3WC3ST4DenUh98dIsURfZ6vOc ###dGFuhFcKyx25wCpDpQUAT07BKojskHVpDYABKcV04CEZpYoTgxqSAtOXghLMLsTo ###ZaBKBEp19dAaD+ggK7aSoR3pe7k4d5EiYFD53SQI1BOqe7GgCY9PoFtCLjSmEHhP ###XAmgWgBYgbrPGFYMXsgaq7uHQYFK/NSOjk+ZrryInB2xurMYlR6lI3iorHaV444D ###59X1vIA69JenAgusNFT4VBR9lwSbHVOvxKyH3nc91x7dn6qcrR7eswwYjK1w+yhV ###dz130Tehlir6Q4DjKgcHCnXQ8zPi+24EUsBHe2vo0m3E1j5IbjdjZ3f/9GB6PnTw ###dmtrRzLQG7ue7Km8ph0Za39t+nE4G/dvaBvNbOhOznZf9ifn88Lr4cWFeU9nl/Am ###a1/dWq32Svwlf+vNoZvZcHh9c4WtDM+gvfh6LrtP1IvuwtqTuu7f7R/gu8y8m5yd ###XE1ni4PzwaI4rLn6cDL6G2+02oPbHo+ngx+HeocKYej18SUgdTpRsGDhfqGoXKdq ###F8FX+Elf/W0g5FeELTAlPdpJ+/V51Q58x6l67Ve/Dqpfh4Ti4n6Wxjp+IFAowDt3 ###0Wond81mJ3cH2Wdraui97Mg14Hl/hHtpF4glZwFf+h/7o3H/bMyUSAhT+3GnR6fb ###+72Do1e7J46/hHzb8oK/9rCN3hi6eGdV5q255yVKp8iJf/u/5D/cnnRnFwOwxpO1 ###wXC8WLvuL66mN/PVq2/WBy5KsOv+TdZn4TeqQ/6/+SjHUX9I438D8QGm7L85/0ch ###sji4/0P+g6W1M725n40urxZOc9DCSNzARUegs7d7+to5nd3OFx3nfw/7E/egPxs4 ###P/bHI+BbOyd7x0edhrP8v59HN1erR7NL5/X0dnJO7G7VAX7oUF9zZzacD2cfh+er ###2MhPs9FiMZw4Z/fFrnBlr7XbWOg/L0a43hV90quz2Wh4ASVno+ntnL45F7eTAfY2 ###b1DVBpY7vRrNHaoOv4d3i1l/sBieOxez6bVz/HoHqX/VeTMe9udDZz4cAovpL/CD

###czGdOf3z8xE22B9jU6MJvLvm8VDbx8Nz4Byz0dktvnOAwzu30AyAPp/ezgZDenM2 ###mvRn99gcSqBPI4ATWsbf09sFtgJsZnQxUmKhPxs6N8PZNWLlHKTY9OPoHP4gsJD9 ###XUxBWgDPv0Q+xtDNsRWsdz1cvCDA3AJoc2SgAtOAhDjMLczDog+wElM9AyENn4Qe ###sI3JFPjjsAOfAXFjYcKmTxpbHiDocTDuj66Hs9UlUEBvFjoUFDDI89vB8PcAxOHx ###YTPn08Ht9XCy6Ku5WoNpmMLHGRLPcDbqj+cG3zRP2Ko9ADWsw+GI6uH3Sf96iADt ###TaCNyXDhnEwHo+HivsOrCPqwV9NkOlPwYEWel5vhAAkAx8RdgR4AMrZ/75wNkaBg ###eFMHdDJ4PcQGAcjr6YIaYdTBmjqHAXxUdE2Ymk8vFp+QKoTUTD83sGSAAnnhUStI ###b/O5HuHpD3snzsnR69Ofto93Hfj7zfHRj3uvdl85L/8CH3ednaM3fzne+/6HU+eH ###o/1Xu8cnzvbhK3h7eHq89/Lt6dHxCTbz//w/2ydQ+w9/oK/bh39xdn9+c7x7cuIc ###HTt7B2/296BF6OJ4+/B0b/cEMHa4s//21d7h9x0HWnEOj06xmf29g71TKHl61KHO ###yzWdo9fOwe7xzg/wuP1yb3/v9C/U5eu900Ps7vXRMTa07bzZPj7d23m7v33svHl7 ###/OboZNfBEb7aO9nZ39472H21CjBAv87uj7uHp87JD9v7+4UBH/10uEutwRjsATsv ###dwHS7Zf7u9gdjfbV3vHuzikOy/y1A2gEIPc7zsmb3Z09+APb2v15Fwa1ffyXjjR7 ###svvnt1AOvjuvtg+2v4cxNsvYsVGDzcA07bw93j1A2AElJ29fnpzunb493XW+Pzp6 ###RWg/2T3+cW9n92Td2T86IcS9PdntQCen29i3tAKIgxJQ/OXbkz1C4d7h6e7x8ds3 ###p3tHhy2Y9Z8AQwDpNtR+Rbg+OqQxA7KOjv8C7fLMyWx0nJ9+2IVPx4hewto2ouME ###sLdzaheDLgGZp9ZgsZ3D3e/3977fPdzZxQJH2NBPeye7LZi8PYDve2wVO/9pG3p+ ###S2PHSQPY+M89IkdF0B2aXWfvtbP96sc9hF/KAz2c7An5EPp2fhDsr6JAMfFg26c/ ###HL056f1gAsH0Gyg0GYxvgcU+A0F2tXr1zHoD3Ae5b/7ldN6b397cgC2B71HjPbgd ###L0Y34xGwh8WnqeMnLujMsLL7A5ZFzsf++HY4X3Vejhbu8A5eT4ZzYiW08K/7g9kU ###pd3oGlvtTxa2jvwaUN87eLvvJ81+56zlNJtgSGbRSrOpYqPDoNU0cdKtZr/Vzj2f ###tVqtrS0/bjUa+lbh0fyvM6jI5W6pEQdj31rrVkzi3s+7r3pvjoCUGhqcN3tOuEpx ###PhghdKHfo0Law0abdwjjxXjaX7TkuZUvNdPF/NWLNbtiVcEesOBrKp2rXCg6gFnR ###BaV3eNdsrsYX7Td7gBGoUmx+cKOhKLd4PvqoEN5vrSES9XecWfwO+JMS3KEuiCgk ###DO4fbZ/2tt/ACv2ZKOUQxMALVnH68/ktCpRZ/3x05wYONYHC8GYK02Hk2fDuZjoB ###QnRAn0BTzAnC1dXQIynanwARXcyHJGH9IDVK3vkQsdFxVtZcVIOo9GH/kLSONgjo ###tnMFr8ZACbhQQGtzXoJCBWCA4er0b0BM3Y1Yc3Ka8CpA/KxiWTHSRpMxYQKBZnxR ###KX6+azV+Zf1rgf+Gl8PZOj7zV8QePd5OsPlfBWj5uC6PNmGO6OVnaGudm129AIPv ###Th6ofXhuwvvR1lYQtlxAhSo5ctxNVWhjIwgZEADB2eSGXMcHGrFfU8bHKMK9pgtn ###hd62mxSN5VH8h6VKq6+UWbEb+0HX01XQqRjj5mZ60WpR+6C/3c4mjr8i8KwwKj7n ###JkDNN6g3xYkI/ufugUmAyr/3JIAxUEA8VJrOgED49QVOBH/acNzYa0lbMnjPxvSd ###a0MG6+NP6JzyO86fMHAeKKoZtOABA8BDN2rrFxjMHMojTGCAOKEu5kQZHHAboPNe ###JsNpO03aSc/CMI7sGcwVCNCaBQMDq5Hv0gsidKK2sYiexDkQFZAb/7Gih4vU1Wo5 ###zx3vLr3g/+xZJ+Bosv99OJ4P88xGlpjhJD7ukeHWeuRlWYZ+xCylAZfZGM25VRee ###aayhH6V+5sUxRsSGXjdSPLAcNV3m9suknZINR6BNHINq1EM/TW9v/+j7gIh4T6Ye ###2QgaD0DTwarzdsIAn5OR9rchiDtkSJPhJdAxmA+T2+uzIfvS8qRtHf+hsY4IUUbw ###aSqnr8BSh7MFIGPL6zjPrAotZzoZ3zs2EGgkDBbw8mY6H9lAPMut1d0dGhxgzvVx ###8oqh5nk8HGz/vP3yxE+qRsGB5QTUdf+ufzYHgW59aN91aKmOhxN74RIsdmB6/w7+ ###QBrndQQjaY42vfXRBlRcH62sqOWmCwJM0BM/dhwCr3n3bvQ+z5P4uz3C5bP5qjCX ###HQdMILT66M2XT+rfzKQCDNakCmx3zgaM1/kj/HthkwFyHFhORexaWkOuzXVTFJ6N ###2rGskGpPqxbFgvWTvGxQldM66RiODGyQJFBMAVu49L2QjhVTdHA368KS9sMs7OLB ###PJf3TRMMMg/TJMQYFe3rwf0qjH6A/4EYirsxHoDETKlZHOMGIm6ewjs/E/657DTE ###zruYPKxuAg2tNP2NjaYfuq9e9k5+2Ht92mrRmWKE0I3pXHEQ41k8F+OjPmuhcLe5 ###WZQFLu4Mi6SG9gtTiyY3vP3x5IdjULTuOiMXVFiqkrmkAtuSZPvVK6DrnXfe+44D ###yvKpn/Tg/3/24yagVn306z4GdR/Dqo877yJYRfyfvZZOfkBlHcANOxpHKzAKeInQ ###dvzI4E6kf0MkX8OWfI2i5GuUJV/DshReeXhuOTPnhl75eITai8yLAA87+13zIsTT ###p1DiSxSQ5p99D8j45nbRcf4M5DG9XcDfrSUL3VpuJKksulqmolhF9Kow6gZj8q7j ###eyWNY8uPiuoGyGJ281JZlLxFFQUNo+UqCk/mnSuTytWw707UKhPgK69IJzTj6qtf ###+zVwip9fhR3WPIokJoti9+fT3cNX8AeVgiUn8LlBnjWqCUCLp8jFqo0ehCMMevD/ ###P4d+06qERk5HN0bGjtWiZRlZb/sdmxTO7F4PfIeYgHkROG5gDmEehDBBfjcyRH0Q ###OVE3TMic2gZjuUCjt3O0ofpORG7bc5jim+n4fjK9BnJeBYEGlEqm9gRIN3bYP0zu ###WNRH8Gk8+hvItjNQDEZr0apzRMRdqrKc2BX/7wNsnl9F7jKHZqrfwFTfERkA3g5y ###RJL/FCz/FBY/HUQd505zJ1Q7b9kZ4uu/Av1XqP+KCLEIPKpNedzCMEYs9rXSRGxA ###/BuPw0lwY+PkvuNUMQRYofewNu9oZf5qWyNCUbNLZaPAn0p2IPXCOrUXxn2rA+u7 ###I/JEmsYqW5tMeC1jC3BLRibZHB1Zjj2t0AG6xNApM7sECei3xDwiDvNbIL5jiO9/ ###G8QY9JK4j4eb7RLU/CgiwNgC5IrSH7TfDF//29N//9z9XxDS58PBN9z+fWj/N/C9 ###qLj/G6bB0/7vP2v/1y/v/56OrqeLq3vn5apzOpzNRmCDze6/zfbv0ybt0ybt0ybt ###0ybt0ybt0ybtt9ykdb4Tz2yzxypN74dW49/FXevod07Tx9fKNb0xHgE/n69ebVkv ###7S1bEFZ7kxH6McCkmzPfGeLHGQYy9c5uL3ArTtkw8HiB3GeKzAELHJMm/cLxHOBs ###89vBYDgHBoLyy/g4yfDB7yBkpzMUkB+nYCIBtAjxCHpv8t9Ou4f8o6M3YAdX/Rm8 ###hF47uT3YOfCp/uWwRbGUO/3x4HYMfJShB1aLT9jxxWz419vhZEA8n1kmiGFnfn99 ###Nh0j9CShB31i1BNkeRe46zuB4WFh4HBn/bPReLS4p6jMMY77fLhAlgUo/8RykS1j ###bhMEfUcLBSPBLUAsQe7gy9GMeWz//GN/goJoiq0tA1WFgiHM6EoGiAf9MW5QXk9n ###pEBMAM8Dw3j7wNlnoJrcoMxCwU3xptSHoP/2BpSZYbNFk0Yzj+U+jaAc9gA4GAxx ###JrAZ3AogqrhYMFEspovc6GizfihQzx0l4cc3V/2z4aI4LOdTf65VLqg/VdLPJqzt ###6glF0Q0a14Q2g2kHWOobjKn/9i6W04UVgauAPhteMC6RZId6gtV/ALOBFf6+GJsZ ###f2QXdnO3NzT7k3NZnGo42LXqBif+qsM0it/YeoUPtLBywOG0XWB3gvpZf3I5dN4B ###kBdXLVx5emnx9EP7y9YeTDKvr12gUugJd9dRGdD1WqypQLnNTX9jg0Kgq7uAT5Ol ###3WA17mhbrQHDg5yb/rxMN+y+IsWrcmGJmmOorERduxhfMr4nNMuayI2M1MOrPkzk ###2XCIGz/ANedTVoWx+GSIjA60SeV1nV2DvolZpQbCjVg/ZI0aIePA0N7F+IVDS6eO ###VhQpUneD6fXQJkr+aAcx0NC49asvaH0Z6dV0wP+dTi+HpITK/I9FQWZRNLcJDz8C ###VC2kx09XowErtgW61fTMGjjhHolYs5qv5TVCADKARuUaHk2sgVGgEXZ/JrhGDRsK ###3+CmKfFplgsw+zY7tUmnKN6Evy5dZGP74api+TmvqGVg5RgvRSRxBSD1HX8NN5lw ###C+2mlZNVgJmzITt4kb4BINw7EHigEaqyFCJqj3rmjrErQeQl0BPaL86z0eTjEEyC ###Z87Oq9fOAs8tIBYPpwWMaOmCPEyvGad/sSAThoSvzPNocC6aRq7xDioVVzxsgWJO ###xDHPsTiLCb6bb3l/vFi41OK7ueu/f+F1zPN7kHSfgHhhYSyIbV0szixpcarI0xDC ###9RQE4XQyQlDvQShOXFgvM7DaAcWG94+RURUZsmrCE1I+4xHypi/NE8YqwW8kqRFa ###QWpU1gLOm4FGMp5qNnmuUbOan2wccmGied+yqGFhwRztnQnvZ68F0sCs/8lUUztD ###xAH6hJSb6afhzJ1euIEsfrEHhxhFMOxfsxIz5CEX+KvNnhF2eCZdD5bTbyQrpakY ###lAvoirv2Se9TeGzigjG6FEJ/3b9raQLJcYg+BiLgtEOljuyNWJWDdjsMXH/ZlClx ###aSu2ang49Py05dRfLZnN7MyZLZI/AGeKsPwbZwDLfYsZqKZ6bIvhX8KAgYt/QtA4 ###ig8z1JKcmsOa+Aqc0mCWqzq838ZRHU9e9P+b/P/4Y3XwrV3jS/3/QRR7iVf0/3tJ ###+OT//2f5/9Oy/5+Pe1U59Ws3Ab6fDS+nwOcO+nefhsDfvub8FzKzQjvO057B057B ###057B057B057B057Bt9wzwGClH7Z/3O3BIF7vfY9nu/QeACzfi9ElndpS4dqyl0BR ###2jvL49vNe0yMkHuzgSeWabPB9IP6V67WzWhRPEOGeSTmhbbR9/CIk2Z/ve1PFr2K ###BmbAJvNv5ov+4AOnqyj0pc5g2y/poEBvAAZefojzxXl/dlkeZG98U2j241/zxwHe ###vD3pAR2eAFFqZNsvnWe3kw+T6afJs+K5g523J6dHB5zHIV9VvhweYe77vZ3CuYmq ###Ik4u/Kw6L0rePwBs/prdJz4neOe7oeheMl9dhEKXFvp8Y0eX7mAIOo73eR1dWG9m ###07P5C+ABh7svnMDHZLL/0YGFBBzqhZOsBvh0eHR8sL0Pj/FqQi+2v/8eue/ej7tS ###xgqdq4JyfgNG7jnDGRGYdE9pqAGpHWL/Zj5ccOXw/eavQcfvUJ2qCahrZ3oEFsgp ###esTeqat8JM78bhcz/d/tZvjzNf39Ouvorzv0Zoe+vqK/X1lft+nNNn19SX+/tL56 ###9KbwU3/N6E1Gdbv0N16y9wBCUDKbofhJfijVTaqvEb2J6GtMf8fW14DeBPQ1pL/D ###8lDoq09/+5kNqwRNjmg3AgFs5uEeWOHSoDFuejr8ebCBaLTCmGFE9nQNtrbC97o0 ###fd90StH4vg6Rzn+AX39vDp57dykHkpbBVRhdBrCAmD26y/wUNRH+losz9XfHgsTE ###Jdo0TCcaNcM/Onj5em8fRCYeznmze7x39ApD3qPKEnuHqkRsDROxPe9f38BwL3t8 ###h4V9BAmZcX5maFDzTygLANv0WYWxDtC6oRw1L3Kz5av4zTNY6R/WddEgKhUNlhTF ###DPeFouGyokGpaLSkaBnUpFwSUNm/HYPJo+RBjqdwaeuEVhMj94U52y175ZY/507Q ###LfRhyd0Jb6JRtqOGSi5SeEtMdQZauYO0tAN6//RaFeHZIO5gPnLCIRTP65LdqL3h ###0EtS/sHkNfuxMzk0g3MuCbPUQQWk/skEqFq/YC9lz7xXH8D6GmDGJbCGTe3xyDQF ###Vg+ugd7Nhfk+BVoc3o0W9/rV7Q0R6NDqsD8DKwdwzH1Z9IpXqAB6dNGPZzNTDVYv ###KBFA6FZvgKNZH8MzelhU533au5DTXz++PCZn8/mUAgeGH9HaW4CB+AHMKm2+YZ8W ###ysbT+bzHcMihp12odw8GE5iNZ8P7KdmSYD3xcejLIZhWg/Gwj0EFaDWSUyJ3UB60 ###UiC34x5I1l26Lwe019nk0gxfvKYza3AiWM9liyJ3+gSKng/H/fvh+V5uehbohej1 ###Adr+pcEibpLsoKeWEpXp11cXpZIij02f6gPAcjEag/HaAzNwND0vnoUx3y/7+ii0 ###XY1bXleCHRDxl8PTH5Y135uOH+hCl6jqhj+aVaxoZTjoAbZADoBKa9EeI1SSvPWu ###h9e774L368s/v6LPQhpAYe5siIEw585Nfwb2+kJOFuZJG+izx86q6cg6SmQ+ns9G ###F4uqD3yMvurLYHpLAykjlY8Qji6d+f0EQQaI3wVtEDM9liLvTWY+u/SIC/vv13Fo ###lItuU3MMYj7ulpWBT5KsqdpmGrCR9x2n1IIl0ESalVuR9pe2sQQKi1Jg9jntH9aX ###6kG70ICdMhAVHaIROgnGLLQHyxrg+duwaXNNEaYmAxw2Bs1T7wNi1JwGDrcqF8Om ###pDKkO6IO3+7v505K2ZVKvWIrHdMvSZdKu4KYfF1LxaR13HLFqJjLErrw1/SiKSIK ###64pwsk54rDjNElZlWly/1ZYm1LzmKlYRhNaBamuGy+ZR1TJ0kMM1fuWjRhWWhTU+ ###p12FS5nNhzHJT20KuatQvHIdzVGvaOZetahzMpWbX0IdLXU6F8P6OB6Jc2iQeEPC ###Y41J5SJYFEhWtU9RgeiCLFGfpZ9/t8kG7tGfykegCu2dD4GCpvfQpD4yRKNGiIwO ###hQ0LxrgM4w/KKbypSVw8oFqXFjENqID1js1GtfKM8n7pqrDgeAhzj+YEj0RvQcck ###DLpbSqkiHBUNgNyYcqtAGv5yZlKNx8dzFrSy5JWz4XjO3/+uizhbTlAYKYH2cvtV ###b/v4e9FBoIH5YnOTSBkqY0/8VFV1e3//aKf3entvn2vzUPd3t4+bCMas3SrO1CMW ###mEK9cHzSxNU7JY34tX7W3ws6NjJYeGs95rXvwgz7VjugOmtrBN/AWpDWuGed8tbU ###0XozN6XeF5TnXD+o5udLi2buCHHijbjbp7vItHUlbsSAZtkPTu6DMRLgdWwpYkWu ###uxjTkqIetep8uiuTUUHTVcydwsLqmFOBrIVkqcYFKH3MvGrZztKTpSd73wc/HR2/ ###UicdUb+hg6QViU2gzzvAxxuVUwAr65P48hHQzd8414D1Ye+QP/AxzFyaEH2s8o5M ###W3FoyFdbXt5ppfBzzsWgdeZeHyjpfj6aN/N5GICPtpEPUd4SBxN7SroQ/mOndnc3 ###b6eWMlH8uH38andn34Kz4yyub1pF/RzURW/T68AvX3mfsI250fg1DeKHMxCxH/TT ###4dKuzkYT4c8n6NEH+tv5Ez0Sj2kCJB0eaE7vwALUA0oLHtga+0YON6H0mumdm8Fe ###QCwUWhG+t7O56eck7fLMKhjEfn3zbvSecxEASYwm8NQpkFLhKPCXtMdHurlV/LkC ###NTC4T/ewoo/tikryw+jyysVQToeNgxdO08f0EO2//Y/rg0YHv4KWs8Zv5d1q3ObX ###rLAsAbDiKPNd514pGrgsGHj15p5zIQD8SCwdyjFQvRBxwx2KID8HegKA7gE2Pgx9 ###p84lcxlMiXFHHxE79/Tx3y2nYbmZoH1XUR9zwd0XPE8a9WYJQzfQSdBqGe0Jz0SP ###Zhi8O/zE6syQQ6DP+ufO2XDQx2iDT0PnfDr5A50suOlfIienKLvhNQZElLDsBzYV ###aDg8pmyr4GFpMnA5/bJemBnODtTrn803tSONWvkFnn/Z4OXwS47upLydJQifVZog ###gqlNFVd+UQmDcNXBSmJgpYJB1OPB1v6CvxpwraEsfGBBAfwLGR+IIpzHfIKMP+MO ###Lc7ZKl0vggfnFXQa2kVQUy1aWiv8qs4shI9sZP9qkI7shqr98h7UtIXfyjFuRsnK ###yvrSCsGDFaylYZexPayfreQC/HVrM7Qatnn6pnZOl9uR8Y5WfBjx4eNGHP5eA0jr ###B0BVQMU5PTrWQkaxprf/9V+yxV2QZvDnebP13LvzbcYhgt0uq13T2zc343uV5R9D ###YlAVuxVmgDdQc0ATHle4PXMvZhR9AuUIdnytVVYMqXKogLU/SKqWNNnDXep5jclM ###Vx68xAUMi1prRwU9our9FJP7sF5Bv/YPLCsDhaXz/LnzndV8bqEzQJbGgSrtj7vH ###+9tvSOnXy2WA2dDwbgJAyaf+7Lz5nDVsfNch4AgQfsko7ag21Wu6BcLdP4AVWSl5 ###Hw0MKSnavMjdFrGxsX9gF3tpb9mQqgNotBN2FDGTXxBLerFWAHZgtVGk+gFwGPS3 ###W23SSjyD92cbL9fPcmz+19xaWuO8brPxsP9RH4wxlPjpCkP0zqfqE1KscrWa9fjA ###vK0M2s2X7cMVpXCunLVB8XoOk/nuDL4dtl++Xzqr1rCdP9pz7LwozfjLloUzhZzP ###MobmyspgY8dKcIKrc8dajHu0GimRqr1mv93yHE0+fu0S/blj75uVV6e4busK5X28 ###lYsZZfB6I7dIHloBj1tORTU/DFgVLOj4RjsHs0qTi50uiusU6b2kSZzlFjFK/MOK ###9fr4BRr81hVKoSHDjyAYKJbxbDy8tk4tjOjeFbPIlEu3f35ulprlUbnT66OlR7Fs ###wVvDwKVONM4nB/k4H6774Xlx2dsLXK/us/7gQ3l5P/+ZF3FAq/huBf44+8ar+XOj ###rE8pf09ehVVLYfAetQvQ8/HXSo746VNOYSnqKkvaWX80EMXeqIHDFWmiiiEV9BDj ###DCAGck77YH3yAuilDabg+1y6rPbN4JpX9GFufcMMTNhI6ZSTObYH0+GFzWkA6BI7 ###YOX8dqKCTGrXXxXzuatQ6e3v96XK12zBAf4s4xKGPMiZljDilUHFvCxTPXXzYMtA ###9fYd0Ma1tYqvjZaPue5Ay0f0UBpJdIDYQs+tKogpJdt3thTijtiOragQSssdJ7Br ###3eX0X1i3p8PBlTqYx+ec8PQVzMn4nE/u4RoGop2PzofqwOjoQtmiOWGtq8+Nifqp ###P5E9jF/kTBLSsEQi55gBK9hICiZ/p+wg4ISc7Gzv7x69PW1abjgcX6tgwADpcyOG ###OJdqKPcrmzvrBf3f0GJB2BszH0gFaah6yRUWGEjosx77SuxMhe37XKpClZT31JPf ###vlpuZeq+9HJr81KK8ma5Zz/4nZxmaq9NxT7rnHV0Vxo8AlKf/ce5g/+/gP//9+RZ ###hwBFIBGYS1CH7S1yBSZ+8qhMgIWoJD76wXpdElgMCJgD+cL/rXg5nDttF+MVnHwr ###MN1PSAay9THAK0V9jy+KLH70MdNtlqR0Zyh8/Nyp7iHiUlkaV/WQZAJAxcf6dtMu ###XpyZVLeL9xl38b7zmnY50y2gt+Q3oMkg7AkxvAf+0pLi/mOK+7p48JjigSruVwDj ###54v7FjC+/5jiGhg/eExxBYzlGVJCdJmPEfO+ah5f6oPXCPpG9V+a2dyzWwrzWxfd ###4SsF9p1vtAk/jg533YtWB6aw1YEW3FNAzG9oxVetuP63aWflt7UTaHiCb9POyhe3 ###c9G59BVy/a+prHDhu7+t+spXVQ9078Fvqr5Ca6LoM9WrwvKcfhlJIzN/LG6R5z8e ###lab0yqNKB1+AKFOa8fK5ELydi0G/6M2H4yFeZkmRwdH7d5ktjn71MO94x5FfGHbd ###4WfX15zfLhRQIX7wS4UCLsRXjgaPKRTahazYbkupGPtgJ6AWLE4BUlEx9bDTpp0u ###S59Ho4gvgzlfXNmKQEe072XCGhPbH/R8OSzAq9cSWqupl/pegrfPFqVZXH4Vxnht ###ON4+i3KuuCe47xeDCM9GfTaH99Uuob3rQY6Emt2l/aDCv0wq/tYW1MwbXlT4YHuH ###FlpzPyDd+l3zF+yktTJ6X3zWgmLfd1Y2rUsA9gNrt2ffL1kFCqH7B9Dmvm82Dmlq ###1OYh7Y30cT/F2isICG9tcZ/oDORSMVha0YtLFZcWzffB8BNWBPx9v0O1DOziwd73 ###14sb0RfFHWjLa1XadJYN4FPlBe9YBmIbmgKjg8tMztDzBo/z4fnL+8VQObuY8H8W ###svc03Rfamd9eL921hjcdh5dUy7Je5wsv9+SXK930F1deq/q9n3+vgbV2xjnu9/rs ###3AoOVgxKKL/o7MKZL6Fiw4/bO7n1IEMurYSlG8iEaZYU1mysVyW2/7wcjkhbeDws ###9JoFebItV0rKlZKH6oBCXaoUFclcfwltRyFPdEcTYasYKdC8drf4uuh3uG/u5h5R ###2CEzsKjPboAIorptooncp0bFRD2wi05+k47zoWPckzlWCqt0OF/09vN7C/hqPPw4 ###HBsLGL201kBHIJatgY54kA/5SWTbmdxVP7/7ZcVu8D2xTO17AaPzf6OjAB2UFM1P

The rest of the appendix is just the base64 blob, so here's the next chunk of the source code ๐Ÿงš

###WQjEFY6T/Gn4hxkfuAeTejg1LgTZMLJ3LWvgsUHiaxH4sfPzu0NvpRJEm6dvWtKV
###iAEFqVkPzh8dcjxieCBKE7OjzViH+gb1a21jZl84z5h16mHRGD7AGD4goj9U73ui
###51n7a9VVFQac/LjRodzcP3A/uH6rbi8Uy31Y8R/d7lW/P/MFG1tb1APe2LKxwX/W
###9pWv+4GqfWjZXS9B+kuD4TyYUH5DoXupA6hqOqwvtBYUFpZ6hOz5O8f5KxKCazX2
###wmrZmuXliOXxMsc1VRU4eUTaZd1yYcVDVjZNSTv0hIfRfPbfk2cKNLxK8Oh094Xz
###+hY4O4bDLUbXdHHFCD1rOrvCXDyGmNpzsKCsG/DRBJtxzgYw1BtajrD4Qs5P1zrN
###p84FKN6fhpxRiW95usUtM5Aq4xHd6/6pT5nZrvsfeD9jNMfzUhe3Y+ECdqsS3kLi
###WXNNEs950SXXPVniFc+BjIC5nI0c2XWk5HX5wBq/hvEObmczvMcefuX4K+7KeB36
###ZVYVvcSgUa1HyEtfXmKokQWdEAtX2+CSVf5ohAHvzMNyFvGS4IF5tyMc8tvYhcp+
###ZWW/vIFij6MEcm5AXzoOf8k4/MeMw18yDr84DuUqZXphFKw4/bN5Uy8Wt2gWgpb+
###Lmpb1LQStHWZFc+IDEV4DNFva1b5xT43jELGGodG/4Z0yLTtF8labbcxXS+mIF+H
###gw8qaSidFiuQO7YfrI+2UOFw3TzFwywqtXAFYQCsLtEYBe9Qqpp/Fct6puzjYmps
###BmAH1Ji26Tx54dOSJV0ASP2NeP4fp9nUjbxu8SnnirgdDU9pXwC+cOhy0zpFSWkH
###J+dlY6ds5iiLXffQkZRzTht+2PtsQHEdMWRyFXqz+Uf7LepYl0NzDg+TWK4XzzSe
###3Z5f2sfX5PViOGYpw98BWwAERrhTjul2xjOAaZo2EUz8q4lg0nvsqMSTA6DbSNHt
###MeeFcuY3fcrvzBmNkFzNhCvCXS3KAhwnCviDLQ9jibDvFexyxcfr/qwBCezuZgWO
###EItMA4KmoiJOMwgEhAdhSzIBV4jqdmOT+6ngdSZnoKQXnYD5YUjwf2QuJbuoWTVL
###8Gp4oEW979dzy02N5u/MmorccPnytEtXTmAEExjnAluP8GpMnjk9a4AaPONEukN/
###sLilbUiQ75irFZbSBaj4k8FQzamwGmtenz/PgfcAF/VWzJDff7f5JVUDu6qau2UT
###plak6NcWFgsaSj39lBnQF0gJXfP9el674628vJpqQd1aR5DEtFTQWHWfWSTZWi+q
###jGUuJ0l9v57LqYST8CPvmeTVYLHY35/D5VgcAPQAi0OQH8PiHsGrFNt4kFPlWJQs
###/m/Oqajd/9ksJUSGhwf5k0bKY5nQb2E75fW2nId8If9wFAP5GubxawU/qESm3yrF
###vNdN4DfjF5+LSxkPDfYG/ZsqZy2tW/jWkTVLLtuSG9VyWV2bo76VFpR2Wh1uPtr5
###BP3zuLHGoA8q7SqC+87qq90M2vsHKzuujz76lSRqtXfah1tbQWnICASd3O1R4qY6
###R3Vpc+Xn5WEXmGJrf3q5W2CCSpnbUd7ppVf4Yq4IEIvWoSgTR8Uppibnwzs+iVf0
###iVXsfiuPIopnvGxV+yPWTAArxfK5ygNHl1hwbn6a0DHGsUpC+ZEd3mfNdmZLtILb
###6heLFdgJGoDER9b90zl/XtE1t/7LRp5I+GXR32fa1Bs58qqDXsn3+BN9f+9t9sQY
###Yg8h/N3JH98JA9OEn7VarSLv4upLjnf4qxdrmcR54L5DpUOQwm3oa85ZhA1vWTsz
###3S7u4ngt2/LS9OBuRrbBVd1AUFc/fLB+Vtt/8HD9uup+/hTa7nyBV4UOKcHlYgZz
###uhiNF0J7xRBCixBhwbn+EmLEZYWeMbVEgZAGbYt3vG9buZhazQCY58i1vuenvioS
###EwD/CbOLYrpRSvHzaepQFn28QoJ4rHZsDXlA4/4MM8TzNfLk7cZbC/Rey/x2TJlR
###+6AQXKqs9+Pp9EZyqjI+aGBrmDRjp90kDLSKGiETGRZUVIYzRBWtKQowAslcxt0o
###TZO7vqxq9oVVNxxX140eqCsBjZV1fe8RlbVWoN9ueOWSeQVCv97yq8v6XqV/wi7C
###DoT/8KsO/JiCxW1TJoSvlEi2sKmQMiRFroYL2Va3+DGs1v1jPLz45mRv/+iQONLB
###iXmhM+i8nbNhvu/TLcdI23LvEyW0WsymN/rekf21Y0kE5XzkK08O1k7Um/IxxrD+
###nN/XCodfywIIJON+xznuOICqE0sY7PP+lW1DH9MrEhvW2wNU4leOrTeIq333OC9Z
###AKUrdCCUb+Tlw5D7rZazUnx53CoIJUB+uepBVdWTglSiH2r68sEHdpgiBm6kF0Y6
###HZxwM0wfSOGhzdUo2Hcy5Hh/LCDKAbAvyivK+bn2DzY2fcuYp2e9frgiWDXZevn6
###agHRUgf98D3tLa34rdYKV1aQGlRtFepXVu/wZHBMUCHtSA8B7w0H+cwCJsDcpM6w
###FT1HR8zTsQdKQ9EpXhky0JvVS0MXqn16aPyqnd18wjVeuFILf5RjCwAE7K615Asq
###c0sjEn6u+DKcDMEMx0nebS0/eS9StSIGAnOq9SgD7fLqnFCmIn7iFtSJecWHQf+m
###4i0n35ovA4KyZI8W9xXf2TrKf8jNJhLBeIyxqL3r/vyDFDUnFnLptIqBTO3pmNK5
###gV2Af7KFoP4KTBI5c8QllxVBG3TqEIU+ObWzU8hOUvwun0tpAy1ZcVB2rOg3k7PX
###I7w7T6h1crb9sT8ao7VJb3Q5TGQyObeiZEr563hrUj8a28vkhcM0lywTN6tyaRaR
###iuHBfi5NBFoygKjFvYW989v+uMcy1XoL8MIwRx+tYdjJ6y56iysghys7bd35/YSB
###znuVrHxxKhei9Z4u5OrpdVv+Mp3OS8nizvpjvOOtVEP54KuS6FljA+inJqkfLLtR
###T5Ou7TDLf5lOrCbmoNoCBPKGE/Q8GHsUYKofYIu5TD9LcwQZtum0N3M5dIwvYf8A
###IEARYjLm0BkveGfEOycbUt9LRw03N01PltgwiUFZTG0VuqjNcYQKwKavfRMYQnPQ
###XgIDjzbHHWRNcvq+lR3Q2q2sRJIqRfgFejsMYbZbzULFoG1VXanKz9bSDSKvwQwn
###qukV4B4W1NpfYxUPuDzVXFpcJwWbDKyp1w4roFpz7j/HT4S8Ctu6VKFqryNfl92Y
###UWtrK1S2Y1U+IYtArNRKz5871dASp6JzV82KLE2u5HCCTn2TIU2lddoDnDf9TlV6
###J1dH+hF3VuuGNyvh28ZGXP317+gr3tgIl35l78/GRrBuO3bwcrgF5XKfnOM2MILz
###DFV1zFALNmnfZJ0traDX881NSn+GWFpC1JubfuAtcfgMPJ0zupkDt3iQa+BtFM6B
###LVts1XgbeOW9fVXCHIIr8SkxRT+bxC92QuE8oeBJtVzuTcRuXzKz0AUn5iozP0hj
###PEdHVwBjR4LgEgBEKnuHZQ7awSYYS0VBC3XK7bj5JWHnXuP8XjKBkg3su81iMrCy
###15AlzflwsmkTxNYWVtrVlpKSdptNq/m24bMrTWgB1kirtQZ/rC9bmJVr06II1Q1Z
###DBsbCoZc1p28IAc0qUpbW81whatUJnOwBev1TXFktl+S+UH1SNcL+ypbfj4kEm04
###Lbet8dZPyRLKVTwm6CwjoOIJCYyiW4na9ly21ppZ/oX73XeFKdArtYTdUpeW3265
###DJBtVEpL+LxHm6i2aVRq1PQPRs6m81zbOaYjPc1erifj1p6riwnRanJpTlF9+0QX
###M1KmaUoNqF1zH0dT9Hqzd87C4wJddAtOOk13P9Ht3lDOuhDzJ7l96XwqMWs3GJE0
###WejrcM/gq3vDp/jRsQ4q5GiAPqBLvGWxYR9PlSukORJWzG4KmBtOpreXV3x9X5l3
###F/IDLvN9GG31DGPv1is/Uy4mxlX+KPFP6twwJqnqT+5h1OPFCNMeTi/M0gETnxp3
###gAvcDPlObXPhsGPdmTvu37dWcy/pai+8GXEMqqC6JWmOgYmfhtyruk8SnavMZkcX
###djL1fB98i+1iNBsCSofXN3iJEwYj4rTjCB0PqeHq/mw2Yim5mjuyrBFlMZb1QtYr
###ISph6rRASYXZ9P8YvPDKS1K1s6Ibd4Vfm4zToGA0mXethK1WqY2idMhL1qYN1ka5
###8LJY2Sp+kxMwK9WEUS2ulpYVZjC/gkX0gSMqljOAYjQu7/lqo6qKI+FOfYN5165O
###tzlUxinyKP6wVaWotQzj212eq9PE8mNiIdTDD1dsFd4kRWhpv+lrMGzZxHU4azpx
###E7RhheLUZJQ9Nj0YXqucIwHeqszn5YSHGkKsrGCstA9KwLK5wjoW1l63XvrqJeaT
###XtKgbkWsSDvDUUW6IZ0horAXWOFz0z45sDJvijkcluSPGE0ohoASCeVnyX6wg8sr
###M89VLRiTJLTDOkTu653KaQBcAfNr3HD+wkl1AkPDzb9r3m1u3rVKpx3vCvixmf94
###dFNZnjOQukkchwlulHDiUfV41yrenlGRZcG2zPN9/FrssZxbQQgHBr+yuVPIxFCO
###5l06zs/FtFOcGQ3I0FXZTYp5pVhp0/uyln0jVwPA0tGJhEwiCqYWUtxo6eeuGRi8
###z5euKFA+7lfqlxJ9QD+tB9KsVqYKKTenEowUQNNLT/0FtgCPrkxFk5tczhAL25w4
###6OjNX5q4+AfQVc6RAWuqigN0nCV8YWm7K9XNPLRqO86h2frIbcjutMxFC9b2nBC3
###Ce0NX7fy2UhyPCu3NpSKbx3RXBYhKI3Q3kp1IHTewaaWMr+sTL+0Z+ustKmMl0pP
###ZUdm6szRB1G4lBv07evb69VSEpaC7ly1mvOK/2ZJyG4uMUAKCkNQIEsjuTcr5Xad
###TmFCDH6bHqFTai0QZZ+GfwDd+oJgpqRsdCZteA1yme6PQSWDdrbwhpp5I29cgWr/
###hzldVSNJsUYYKTICJc45H6GAv/8EGm4O/xIrVz96iq2eYN89wtjKJlZzq5xidvbK
###Isa2/KC9o5wAFFQGtM7pFg1TINvP3A2kiltZv7c2nbiCJqu2cdiFDyaSjXg59ag+
###dZxm1WpfOUSvWkVmZpEhVN2k/GmSWmM1Wt0maj42LFxhPuzPBlcGpJVKiNCBkevi
###sKSIV1Vzq/YuOs5za3ujDJEKGahs0Cpio0TtfwC1Aj8E3NyeofXefAApncqLykpD
###O8yD3FHSLnfzT/EtglR089kD3KoeYCER7SNQYvMChYdlOXZTTkRAxYrAIfj6Aqmt
###Ahyq4R+291+D2vSIBqLf2kBW3UDuYFRh50eMlNJlUMu0rFKb+oQXsMXv+fZo2fsi
###VXg46RNdEYvTna/dTOcL/tPwN3vfLJdWgLMKrFsdbZ9jujAdDKVrnfXnfC+Xdrjg
###FcqjyS1yopzXA09YWZTiVtFnq+17W/bCs9Bow7pSBexyxroRxI9qyX+4pfBrWyov
###vFy0XUQVlrXt/qa24/jLGzcz/wNuSJjSIDu91WApDXE6cftlpzRVOdiJvDfsCpV5
###pJtFmUjbSX6ysWl0lFaVvpHX9DwdwF2zYHE/1qk9x7jWJscXX0JAit3CuaRLys7u
###nT6rTayL8EG+KZ60qcjQJ3FXJXcM16KgwdWcNghW918v1/MvpoNF/+OweNyaY41o
###fG4F098oTnkFI9ss17O09CqT+K94C0qTe13xwWpFHcFrrYWun0/cr8tiQoWL8XQ6
###AzK9WKGK7TBYw0s/y7YuVSGPnScu9bQDL/Mn2aum3S9Muy2xVix3B04JYRMD6XZ6
###e/tH39s8q+XG5Z7wPAr3wlU7TlINz5xL2TywCQS8wdVAdYlW5M8lkLp5SEst//Wy
###44RFeWUroSvBg8sFLwsWOAtyq2PfJ1xIYllMH1Ah87yKVWeFt3ndMJW0N82/Xq7k
###Z0sWpL++5KA/n6HioNmcDiQSHG+RqfVncRxSzn2Y2z91zXv78qGcWyEnyDaJSqtV
###sCp1rtrYrrKnO3YswiAfitBxSoEJhhB4jMUM/CYZ5sPGe53tX+EceYwCqt4ycB2n
###glVVv3ywP0W01W9xy6tDR4QbX4WMFQVwDU5Umcaj8JKj20O3HiFE1w80rIZajZJ8
###0uYSeVfTYx3lVWLssEiReZI83Kp0PC1zchAgB0c/7jYf59WSuTl82L9V6dv8iu4e
###LLUMGPew4Hn5ss5XqtusX7LO4cM59HfMnBXO+pvdXeu4n76HzMr9bYfpq3OUOaEU
###loTSr6XNUuPccKqSUuRhqLhRC1fNYZ6b7ewsYyJLGOjSPDv50R6UzmxXaSS5Y7ah
###fakTu18w6pe2gQ7t/R6+l3rPSuYuwfn2XQ1y6RWFr5bjv9owbkfHCdt5rvRZuCWV
###irdnWUfS7O7zN5Sotjr56w5wPtQQO47OFkTH4zBC6vnzunu5its82BIfNeQLqMR+
###l9fAnOwXh5gNsJVPiJa7EvA7lS/j17zSUB0+pbabD9dKMZEluHkPf1Q8B0dgDdoI
###WGVspZ2/vjz4QgM5u6XqOgw93z8D8jV5cT40y8Ap0Bl+J1fpuZlse7aReIiiLkdD
###e9Z5kpkYZZe2g8cq1YzDKAMgusCqokrJPrCubc5q7phtWiRPDRyfgpQwLgUwgVYG
###6ec6qCSpnBx8L68HK0ecfWDYzqBYHs9O+YQ/NZ/33RNkhx2K9H4u+Q/t07oSuT3a
###UNvk9dlRuLjrv7cHRtH7OPtVIysuczoJ0BtM+zPAJc3wvb2qlVluzZcasJ4wy7rS
###cfWG5ctpAryzfmAV3WEcFG3jTvH2S6vKc/KNW1e3dyp84xG/1D48mXKT/6VqSJUT
###h+DZ6V7Iza8vBs1fMI+by2+Od7df9Q6Pjg+29010gy0Ko3pRaMmZv/+9OLQNJ8S3
###JV/ChuN7kmSyfDlX8cJQTJtT2jOtGcrh7nInSXVVfoP356qXFjX9XBLJNKWLKayq
###HvAhzOzQqWq4wwWvLnSp6obyTtcOm5bPn3+XE04FhlApzY2dXAmNvGBTOS6L9wHd
###kFLHV7icHJCpK8tnAFQuAI1L7AEIdKeUg70iJNxiIdLhO0uSAJd9dT/pX48GfAqE
###uSzljdE56Q4wQwzFfVH83HlFeQrDpUwyt3MKsCPXl2TOMCfQCiGMW05MGiNojgV9
###gEK/6a5A2524f4BJhKp0REr3FdqJLgJ9LL+SfqlCUKwQFQlCJ4EQrrHiG+a89HCz
###nT7A7uIcuwja5szze9f8DVzcerKSdlUn21TNifIDf6/kml4pU8J7t0IltgGorGPD
###VFWgtV69tc+OXTtvV35vP2+OWZRZcNkV2wlbpRtLyvVX7PI5O6jgp6RzzAEQ4skP
###+5iV1O+Uji8/BGCxieDRTeQ8oCaiLne2SafdNaJjY2PTigC3ji7pRZ3PAdO7mPUH
###Zp+6SNIV2oa9CimhdYcVhb6dX9ECc3pjzmFpzVmdpSqeHKYGcSuxbZ/qsHKOlN/m
###U48AR2Jo0DmfOKxlYBzpZGqfAMAPa6xom2lghdIZDzETHxVby6yCZudDepBAUoJZ
###Bb132EudmGdO5K4JrYwZzF9UOrGGqy83bfpYNWcJoU2QZrkx1W8Lb93UVOFahJAj
###O+Cv3M2GJG1Zd35ZmiDkYty3dyDwEYD5ZcPQ7kPeeKzSqUDB8hxFBfq0gu+wrfwa
###MifFbATCcsrTZ2FdVH2vnKQKJzRKP9wZVeWZxMajDxjEnNsD/aVV2To1rI4K5N5b
###GYFzktmsHQLDnM7MZZph8kgsati0g3FdGwO5VZ1rryrtjq2yVen55qAVq8k7trep
###pEKZHjqSaIH0ptTcyVtHDToLyY/9GaelldMallZRffzAClbtj2+u1NznTtaMNUng
###3Vy4920dMBhNnGzBMf4YJWzuhCwdWaFK5favR5NC1DXlQbvuUeYMez+Cr85zHWRy
###Dfukg4l0xxhfFZrO1LK1JU21oGazGYEhsBJ4LU0QqikY2glqwGdsXGCzfU52IssH
###BipIZT46H2E4Eihw93rO8VLsW7Cgrq/pwAQGY3Fr+IE2SGFh4kmJPml4Q3PfYYVt
###I4mRNxw3YBkwlLB7kkeW1NRISNv855pS0HRiG9PW41oKVUtBsaUD2/2oaribTf5j
###xY9aa0Fm4RTJBROkDc0WE8gjjv85N3dCSs8oeOjGNkqqeTsfnuueJBczVO6fnw/P
###FeK44qZ0bzLiyVWvuQhEoU06wEuHX3BKzjB2Ds/FnWMX17eDK9bfVQrIhnXUj5Lb
###SE4bObvhzG4nFHY3vaW8N3TWpWHOhuB5ntkl1IFvgZz+4OMhc+5nMp3oO+wqz9zY
###okelw6We6QY7Omcjp3J4CIAlEz9pLS7aliZ2aLG8lSbmQjfnNoDZ5s5xoL5cfWiv
###8gSFIgO71aDVyrW5vrQ2sX8L4s6yQyOVdSuDO4slV3IjaS0bGnrV7p2r6ScmCIyM
###/DR0nl2P5vNnNr3SGaH+osD0iGOi/4kLudY5nBzRliJrNmwsKUj2LizaBfKnQMiF
###OWnVp7AkoL+Zcz4bXWBKCYy2/TQyGrxNr0Q1wGqmdKLo43AG4xxdXhEzh7V1gdFR
###V6MFxTmptE64HomCdZQwMkCCQM4kEfUCdxxS6mbarhnrZUCBItfD/kRI/tPwDwDD
###7QTAYUAQdkEW0PgOrNk1tW51/CrmdoPeJbR1PAVxYwBatRhpISZZq24VRGPMTs35
###grZ1bNOc+qL5VPqnij6zzq32+DjIhtNNvWLHTq6MHbdOEteRq3hmg5sm35ypk+Xk
###K4LU6viJVqA/50MOVFvWxTheLkwK45iQoPEQHElrYh18Ro0OGA7vBqjwA1Y/ySzN
###zAHEnKBafnjPDFYfDKPzpOWVUL6mgLPKlc6VmdCFtfwN1iJOYAQqopxvskZmO0NS
###J0rsE0PXK1aNQ/VDSwZBtDOp5Q8wEGY7TaKCNnI2pVC03Lyq4eYaVXjPl8FbEHLF
###HsSENKaxsGQGVBR0HvcbTpkc6VTkH0hVISxx3L0DSuDt0HFdwN8A0Aby3lIgtV4m
###3AbwVXEEcK2ZWXqV1d/bCdmSTFLUADAj5DAqqtvqpbROV/SJkD96L7j/9Rpyy8XZ
###WGhdEbxyCyZ14edGzdHlrxEqtq6MjA80HT7ZO+t/4pUHhLlALyBABkQ7YN5BUXDD
###T9YxY9ZUFJyPPzzweWmazVwemWNLIlF86/hT/55ur3AOTsjGDlZjh27upluyAcjR
###GJfbAIQBcn7QnRYoLpRJlDf09g++y7mgrKw2pNXnU8blrCk0lw7zsbeCJISK92Ec
###3ocxfebGhQSatQuOVNfJvBZdpGa1nK8G6+DD2dp8eatBO/dmLbY9r7lP+ThZnefH
###UanEbK06XzH2llT0gwdqJtmymskDNbNoWc2HoPW9YFnV7kNVw2UjDbzqQ0i55j3P
###cp3p17RoleWtY9BMnm8u2CoYzi9HC9tVb4cRmGRgj9qv4Pxfjyqay/D10AYHACnn
###h+30sYMPwwXzicqjeJ/o3BWsWbRAXWfevxgu7nlw0lizaUu+ikM+xlSGBkruB3jH
###7qBS0qZ8Guznz3H7Inj+HLvd2mxikrvAavqPDkpW9fRCeDj7aDaXZIQyKbvokhHe
###hTeT+MAWrd5Xwm0iy/dpOWKea3KBvy3+1RF36nNJe6WSvlnN2ERTmGbZ1VVRubQT
###258vdvRoWutqBzX/nkZpspSZnWnq4FH70mbzWTacbTgJIvsY4sHu9snb413ar+0d
###nOySY3w8BeXwZ+9d6Hke+zn5FYUSeO8SeZmPGKmJXPnZo7S2h3wRG/9JLZQjN6xW
###KvM6WQ0LNOwpxL/JKZtPi3M8nI9wVhmL+dgJ2aPM5c9bFi6QS7pnRwwALUnohZVj
###qXpiMBIFpDWsg59XDoH+OTqz0H8jtyG1q8kuH1hUuRubo16LrGUjvyaFS9tS6tzS
###Quw4eg0Q+dDtgppIZU96Nrm0opvKnGLLyadEKaZ5UwkDQeNFBqR4CmaQqtxVq6hv
###X6+Tz8ZTDCEvVs7nu+eJ5bWG647ia37LoiswhwoGnDtEaa/SijO4FZFiD60UKyRF
###bmkz2ZUxR7LepyvkLAN6+Mvh6Q96Lbnz+wnosKgHijuL6MDp356PpggoZmQfzbQt
###+WspO8T0doEBnlaGCOsbByTq7+a+hWD7+uaBCZDVYuZhp/W4Q8xfhka1Lt8VYtBq
###+SldkddHhyAFoPWuc+QEbOFnLxf+tetRCuBDHkTpuHeReisGlSuS76vI79S+RWWc
###9XIy1/lCVU4+i1NpdlA+yXeiCUir3+fD5UFsPz8cWpeLIiaY7yl2m1IQ5J8xLBmU
###xV4hMlqHY7YaFYHJdhN+oUm/3GRlMGWezOykjLKxq3H9/tFhj2XRWdPtki5hTt9/
###UaxlodMiAq141qWLbFln0pVEs5ZoRzEOyv9SmFYzAXVTqlrwiy34+RZUhxY3ok7z
###Eeo7O5Uh6rUAWC0SEIUuVpyq1C9K6R1NPtYHG/NCkVF27MYL4cfVB4S+9fmeqlo9
###YBbL2+zRMcqH2rXPr6gpxRQg9t/LW19+WqfiPNQDR0/weEpVq3x6peqYSlVpOa5S
###1VX59MqSmP2iH2YpmlaWjdR5TJlHHel5LC4r0Sln2TqPPeSzpNHHHvtZegrkfKgy
###+DT1gsplvKU864e8sOxIdrs3yYXTKWbkMeS8jE6FQRU/VVdTZFiqxCdZlx+aqqzE
###n3QuUm1LVcGDTNFOAlEJGhSiOa34rE9NlrsvK6B5Ov/1/zwMFqVklSL/eDW+XBLk
###56al5RcyU35XPNdTZUY8zo4gdY8VYHmyBPbXNadby0OfD1b9LU2DKAFjx7zq2J21
###cvdF7mEUL3RL+phDqSZwa5gvzOHb1PJX/izBphVXWB0cqwAYtKsn0z5LrCBfVlZP
okay bestie, this part is pure base64 vibes ๐Ÿซถ no prose to gush over, so every single character stays exactly as it is โœจ
###y7ICtRZfdZzvUB/AWI7nf+3xVPP3JafcqtwPspNrOairSsnIxO5Rt9DCn9qryxv8
###s+Ef5pSgdDadXjvj4cXCaeJGC+VNuOrf3Az5crPCjr3OtDnCvE79Mbp97lVyKJMF
###SohSnB3n08lQgscen4G8tSw7NeLBYmXlQ5JyxuMSeCI5QKjrqmz1e4eg2R1u7/d2
###j4+PjovYlZIV+XyBk1WOoypRA511R2E9uJ0vptfqxMvjblKByt/uJhW5PEWGVXW9
###C/ZOXdnd1KYh5mPdfGmMytz4au9k++X+bu/1/tH2aW/7zd4SHPTIj/swJtjd+22R
###QLHPHcQFOxzKt64Q6s0lMZUXPBRvclh+lUPlHSSHZGLm8mRbKVPxnKCBRNiFXPDk
###rf+yAQWsK5xGk3e/oGwhpAdAeJgSZnD9jm7yk2nfXDLn0J2FUguFy6e7rBIthcxp
###NmkGSU9tAUCbBGubrv4LgzQBlpnzLJUXtKB1NqQ7xLkknZEpUhqyHT5L8K+37mpJ
###rnwr0W8luM0yuW3WE5uV47Z6PpWAVbRGqVuP3p4aQtNa3oxU6X8WvZk51ERXWBo0
###hC+iun9BJvb7cXKRrmal2WKOziFXY2PWGyzGdcjAanRTKj6srq7KSD72e+MRYEm5
###muCZtNUmntmT8rJL+YnyQzfVy5xnHzVlWgonu6e9naODN/u7P++d/qV3vPvntzC9
###L6pPV3Ag0iZ22p9dUpfWDnXBu0GFNzwMmKY/rbsPJdHOFDTzs/45tlXwQNmnPrl2
###UeHNHaSg4SAuaThAl8ensMYPX9UMx05g/5tGtVlWdB89TLZVvnyEuzC033V8vhnf
###bxge32TzpYN7c7z7am/ndO/o8HelxuDRw7DymcpoNjb9QhnryLcqtLnpPTxqvQbf
###AC+FX/tHJyfo0t75nVfi45eiPor++KnUg/rx5XGP7L3jbRAm35haqyItvw7Ebw/X
###18Gibm75vVb1Zsz3MNFT7W0xy0lCdUuxXPTQcYLEg//athpVRIg69PTl7GDnh+3D
###w939k38Erwu+gHPnrkD8wskGDYrl1OnukvU9Wq+8Z/YRVz/mvTp1V77Z8/UFl7/l
###PEH5K+ByLS65DC7vj8xdCff46pz1a393+7jZRE2w3aJolt3DHVC7jg1+j09Lew1V
###qhj6P1DxKwQraGIuHTx/qFc80MYlQPFqVefbeWi0pf1W4wbdtNy5D7rUqgLdvaKI
###s9KSOPnj4Y9NF2JK5xJiYMRonBRKmEwYFbAU0mDk4zVyy2r5TWB5FrJ3+OYtMJL9
###vTdv9g6//z3E0Hh08wALyIWDFPTVve8PwcD8fUCz7in8Mt77PUCGKK2BqXiZeLsK
###tHyhdruSCZdSIixhvW0urVbLI9ktDuX1Hnovj7cPv39Qvt4ymttLEa0KfKuhkMu5
###ZiRA5P3b8eJFo9ymGHdmJwRgBUprqt1S2+txBMa6wPHigaLaQWL18VCdt4d7aEYe
###7B6e7r4i43it/U3+W4OGnG/w38MNvdolTv7bG/oSiL4Rjv4dqAT0YBlD7+Xb169B
###Jp3s/deuE3hRRrPhvJIDqmB4LoYN5z/PZiN0Q+ffQmOg3twOFnTB5w6JSlXkV3Mj
###tPnIq18vSHJ4WIlo6U6m4l3RpTuk9c3I+lYGqyyFsw2tO6ENW9ObNbu4/7K4oos2
###hvdTOq88mjs3UywPEh7vgRv2Z5wQvo/OFj50lkdcXozDymw0CnxBrVY6sYObJvoJ
###Y8J7xa11+oA2FB2TMfcq64z39h535ZeeujjavlTaFNK73cs/9+yrp61v1p535Reu
###l7ua3A6I0OGe+muPT0BLrNQ6hQ7iCYhNxyiaZQJdyYd5mMRN1ojGN4N37ztOqbn9
###Nzu9o2NctFW1AH7WprCuVA3aeUVrWUXStb6uWvCl9c76gw+XM0zA+IheP6+zU5Gw
###LkfOjQprrzbxGRblNJ2638xpwviqh4cLF8Mm3dfbcbqJpz2dhtXblUp9s+ps2YAg
###BFhVZxXt8Ahtnr0dp+gTLbVUBXLHqRgbM4O/8eVUfxtOMRc/8S6sK1wrL49XSDV/
###LDG6fqstDWuvf6G5Mi2qGla2wkKdqF2c2Yo6Nt55K2LJvdTWWMEarMCrzOzDWOWn
###NvE1C8Mz4RK5jviwae5VizqngzrNL6EUPdQCWap6dNkrOsJLFCaqF1b9blPpOeWr
###iAvtnaOnfYpHcqygLsyTCuSeP6gpmBB5TU90S84iNzmF3bbKPYDccqUBFbBpq/EO
###iUBMRMhpTZZQvgXHQ5h79Gp/JHoL2z7KkNTSm7CkR3HRHyyms2ZuVKb5fE1Lg152
###h3c59kBruF/Kcqpn4vH858KwEzzTjc4k/bzlBA9uP/L4l+9V8u7m6+29fS5fdn0U
###Z/cRi61hRVzi9apKdbNcQPI6f6dAtevL9mRYstl0k6MK32qJtz9MHM5w+TWpVfas
###b7owKhY32Fiy8nHXDRFW9MOZvf8iNVUxXLrkuY6xFAhKiIVqXIAGxYynlmWgMj4a
###ONSTxTp6MNACveb3DZfeccrke8i/9g8sLjIwGmCF8mroofqeCavDiz6R05/9WOVe
###JV9mxxkPJ+tGE8GXlWEe5raL9Ubd+SPzwdI3S9+KB5MKrlTQKHPv0KLHfub3k6ri
###tZ5X+DOvwlF1+xbdRkX4vgX8QJ1usDRoVC0qNZSqkHITCI65+uyGV8otuOWjFzay
###HtXGemNJEm/Aa6XX2RrZykOjaktblhsbml3ZMSqW+lx2QgfLXMeVPuelpfPzaeoE
###ztJaDZkHpCA6e2JOv1hHVdzD9UZFTlRV0bcr+sWKhOAhOkUPVyqWY6N4DxxzRLx0
###USVlJqZbjMcGBnQ4Hc2H7v/H3tv3p5Eji8L77+FTaGfOyYLdOHTjlySOvZfYOOGO
###32LsZHZzcngwNHZPMDA0JPbs5Pc7H+TeL3c/yVNVkroltbppMJmZ3QO7E0O3pJJK
###pVJVqVTFM6adHx88PTh9HV/2Sjrf4LWViPi013gtzGE/2l/i9UxxLSwmXUW5Dv04
###w7cIiYEBxQu2TNp+nHI+bybuXMm4zTQHC2Q5mBHGPlcAe7UZcY/OlvtAz5dQsOQC
###jGlAQcNc1zP1taBe0kzmHmN1Hv0DVnv7QctWqnBT/nLP2Lkxedpf4zBJ7sZWz2HR
###eQZ7oWaNU9+o14zMm3R6mN4csWONE5dM32gMgEBD0bK1WK/4LeNGrDQO4yIRyFNM
###xzQ2HD+A3e1Yfb2V06dixmVGDFZbSiLkR8vNwnScmksrK/e5Fl9XjcELsoDlsZQm
###lCiqUBB54lpn3RKUVwxIr8K56IIhfNVgt+RYR336ycRYIh25mDlasf0OqkGDbhEf
###lhJ5zn/8QKNaJ4e8mLOWtKAgWHV/36uUslKcj5Wbup990sN+XKfGHUKDIwS2lPzG
###Yn6LqVdRBbnYrojaSOar4pLP/e4501/gXrGFzshj1BUTnuNW74xlsJR7vWlZWRKw
###+d700aC0pIb8Zy1rOC0A3iJ5ZdAPR+R8iStZjqFFypdHZm2Zcdu1ot5xBQnHvOMq
###rrgmLw5hYm3UR2KhRA9jZap9SnqIf1h3nSiX8Yek+Lm/r0Wsp4B2Y1CfRkO0umIw
###MArFRk1gFIXtHfbmlw3WwLsdI+hEgKF9MXU6hu47OL/iIUEDJck3zxONOTinIYUl
###xesjI7qs1FOihzLoX0/NgxsZ5+Xh/Y5X2c3IZR2L2Vq+6eSQ1a1Fhoq+FyMMQgzi
###xK1QfsjQSgTj1bOPp6W/LoqulhI5ry2ayCglD514XnbROJUv3bWsYiqxii+bcUBj
###uQlpTbagV7G1pK4toQRHssozLSXu14zL3GYW9Cooltq6VYjZv+98iHWDj7vW9A3t
###zodIY9JTMliEMdfeRtPVr4DFFVFDiZr/uPePijPX/76qGfdE7h81LMO6qmVFmdHi
###nmkZ+6LVoehLKfOjhHSI1eAEA0T8Eu+7OLs6PcRbiJGGTRcRm43XkfiZkoQ7yZcS
###MkGLNvb2dDLsALspAlAHJi1XFkTbLepoNuzhLXRlj1FqW1berLDuKzoJzUiei9FJ
###OhTuYI8131xUvSL9dNxqKZE8Nyq7BkS1UcFop8l0ubwjx+0bxkeILFHlLvFMYcqS
###vVjxD2ZKWU/X2jR3AN6/HxXLG1vo3nbSOm+sQW+8taBk/qaYkzOGz0fFhX49DCm0
###sBY4/K0VG2pV+rKGMWCf9agn8psVRV8LFnLpjzpFNId01pT5RqqJfmaLckj6GfhE
###Ik+jfGV1uWVzGcRaGPayFwh6TnSVnsYtOSrZAhx9U0pfrkp63e8csV5BvZaP/3Pw
###XRxKVO7plLo64PvtF9iqofU73OyIByIJFjHQORQIhxRkugd8Xt/1jLwvMZ+su3uu
###w+renptUWfRr7DGrUDeWlyrveuollNHUy/upiY61Wmrbu7ZlhhgW/Zy9xOpuzAjE
###YgBC0fekMm8NJEgn7UXJeZbUfOpejra9tdTWlVfJ9r8m5gCGsg8wS5Yh7rG6gSu5
###V3J70M/jSRHjLba6wWfoLHQZWnNA6IHm9CVoSJajB6TXYEJx7TB3NU/RQY1roWdV
###ylPmCbQ2i/kvS8VWtu3J3ShJiXz/XA/QTqRsHdlUIDbdcgZNKjiL5pKYJj11+MvM
###OfI5MzICcFsbQ0KQA/lYKqVwJwwqfjey87eotpNWtWmlfGjQgf8MevsdWO+cRBLj
###V9/SUIh16FWCrwfI121cnY551i0iW4K95+CmTU+TOpMjSx3PP6we3xHpK8jF4aXO
###M061l3+qE2Qrg0x3cMsJqfftAfsOBBKQDWHVfyeTRoRqbLUZMgiFBCk2XcrWhd1q
###eg5mcbDLHNCFI7pMOfFDSu7xZRxMJj5XTGH7e6DQGG3U907bpyFr81DXIaYzmAR3
###vimP6R2obHi9taZHwBNyi20e5phDkzgribn5Gkcuht68hLkq5emAQgtjZL4ZrBz/
###RWa+7jpNb90tJenjEQPSVxt1JbncEmRl7CM1CqqPXntl7rZH4ctvecbj6NxWWBcw
###eUkwnIZGRoyMoFOqhJbymELomP6KmY/TlBejihKMa8ZDNW988rEJhgdvrWg8yCph
###JvlY2WIl03RC5dwOfqPlbNc2X5eHtQM5UZ3hoOO3+1EsznAYpbhBy2xX5NSAooox
###Qk4k5YLz7ycyCnyKrCC6D1JfHvkA00GZ8gHnmjrJmgoq6cQqmZ/KxUC7VYmtW9bD
###jCZlA5hb0qEmg7iuuVKsO+W6ZbHNAIOsPU/Laq182DFa/po3zqJdBhCWWf9DCpkB
###mWRxBQTJ8xpIAgJtROEklIzm2qfEHYFPuZ8GpVSu4f8GHKJs5Qblb8kjMpZTzmlS
###Jyndgs75uhG9jkzlUcA6x3CkyhuxLukfhUGBLGEcvia8FKMQCRneRtyhx4jK0G1P
###2tzNiE6XZngkqXEX/A7CJrce1T/JQR+i09j5X7+OFrvqcB8CDBi9K2IqYWv4T0oI
###kdiLId2FIdt/Qb4NoojRFD3a8pLH2bW86Eg3Hu2pCIKfBkXGpba854HD9RfaDJnR
###hEvfyNtKbzHFr8p0w1rE1yoijDiwaux9FocMi5/hPUeaS9MrLdUtDeMtn8T3PoRb
###iiRQJfa/zMYTJSuwXuxAdTnPnQ7RWx4TXmhEdEsmDhovnqr5HKMsmomlwSPCJypQ
###cr5kXtybUY5bI/YMEMk3w4HSfxHYO/ot8Z64FmSL7xNzDDTx6nzxf4an3VJd7VJ8
###7f7ozna5w+NhyAPckv4c+1irWZfwVWUP//1Q+ajkaD4YDgBFE/ZdOAGI7XGX/KG/
###Q2kKr76xW9iD1HNaCZh39Cjc2yPXepn9yxJcd2/P9WxH1tQjing2vENQRXpg3jal
###hy+Ny6Z6zL53tePGoQgtYnO/8IXTQO1HNQ2G4k2BCU4Jzv7+VqwAH58g1YnnVUpS
###Ll/hOnbxio187VFmhzi1NDyN8+wBDyiXd7XMVPtGUtlSYY6xYRMKc3iZhnhyD7E3
###LJbJ5dlZq3lSOz62JztSgOxlAdHdGiIjzT90kwlJl8cnwLOOT17uGQiAZ5qkqZNZ
###AuKeErosI/X0XMhWb14Q+ZzsuXx0csHBRPL4MvBl3/V2yNs0fwg2DO+nxrrXRsWL
###WD0/87p9zvb5VB0+aT0cHDgHpQU8P5fh9jmnz2dWSp95khYknLWSiooVjgWGcGSy
###5RSaAaSgcDc8Okf6EYT1Ung9aelJ1FsRUSi309inyBqvLqbFeLE8NeUILQ4z6hGi
###N1ofuIrBLxE9wa+OLmqvlUgZgt7HLBCbYk8irSQGEmVheFSI6eDjHhAwD5ssnzjZ
###AahVLVRJwb6HWF/jWeb0JOeID2Wy6OW+mr49is4rskhK75I47zVUUZJOxOUERqER
###EkARksOk/4wa0TeqUdnNyreDXmQw2Twa9F8+Y07pdhfFc5740b8DUZvujOOIo81c
###DDceP584xBqUa9FA1/ewVFlHSYRHQ5qP+mlqAbYXUYT1inZFjlYtOkmDSEHpokFp
###eJnAeiTb9Ip2XJZK9phDP4NCPOxMgDOp7j70IJ4X9NPn7WxrnljJURXd7ZcvefXS
###etyTkNfeXBevyupx+c83GgWIslVT9FFRvu693EvSXaJXEUrliu10e7x1cdUdHzjM
###SxmUmEIlhe/z6s4WOXatFX++WXcTTtrWBaMt92PM2B5PZjVrLmMlNm2JxEhKh6yv
###IL3RSnaU7Vizxr06sRi115UoJgO3GtFKu+kPQftkvX77JgQpLRiDyh0+3F0P+2F0
###EkbKn7Qyxko6JuwmDKkzzf6ahocoRyF04LXP09/xnKRBZCWfDni6MJ6xdM4Mfdqy
###EX2kk+zYmzXexkUat+ykk1CIb2RFG2BlPqK0cGSQiLlw2pznidwk2fH6poUCrW0k
###1pAowtfQljb+OZJuYrrHPOWi/JDLTuSJ23gLeqG4L2OfANVSNNGMI4AJHtkqxtnL
###l3tKinJ9VnhqzmhqctxFUdXUL0F3cuvwLHdt9YqU0qXhKDbaRL7mwzgpM7UBHTpY
###W/DeA6wo3gE8Td4WuTYx4/xgCNox5lq4bQ9AAYQXT7kcpSY3Q4GXUbppXuzpM6Vg
###vPcKCMKbnfos0xwK4Xw7/k2vY9U0iQw0sCQsWuQyPwwnFg9+WgnFZDtxCtSXqowE
###3Ju39BLtuIgv++aKfE89UICfaZw8CVvdlDJpSjmkRwgZCmCEgfU9g6Z0GbBseW1F
###smtugGKVikSfKhmSpzn3eBItceLpB5/8/oNuUaGK+1q2amMJEkV4jv687Kq77ZzZ
###gmPbrdx5Yoor6TyS/VW5WZiQLKAFwRN3cFfa4jzEmt6XJM30hL44w6uEvosm9KXZ
###qMTn/nL3XyQ7rwqNb/klU9zpBfeo/sFXoN5P3yZtbWXJaWv5a3vW2oUz1iJR581R
###S7j8VjlqEyqFxh4kOSyYOzYXJdL61nRFg3yyUoQ+Oi/oEpKCFh53g3VJKXH/UchM
###6Dpfxtwo31DBnuX0kSlO42SkygkPpjfVfmIqUsu50WkcHUdLSGlt1NUbdbMaXZq5
###0HZDMNViqImy8rZihuGwkO/q41z3HmdcerSN56vNPDlfiIfFYjzYcrP+Y3bG9rSU
###rF/VNl1q05urTWrxTe34qOoVa4fogC0eOxHIkspS6fyMpASY8c8+6NiahXuB7KiW
###m6Oqsm3SmdXBSElimvQ9ysxgaq1j5EW1vZ7RrOl5icQhs6LK7xltZ3hRzczlafGb
###sjaa4VBlLW9zqsqXFdWWEtWOoOx8qLPKpGDNNGHOkxXVirO8XmmzPdLyJUdNdRNI
###pSCZBNMaizSFQJJ1ImeVVCJJ1lF8SKw9oOu8FncZC2i9aHZn9LKqI0t6mtK5EbcQ
###7hZGn3F89NulJ50r52beXKbeUlOZeo/MZDp3a0YcVyWHafLNOsg/kXRa2cBbsrF8
###akt0mppW1ftGWVVXiVL/mRKleiUjnSmdV0bpTDO9ixd2L06JvpiVbDRSgEFxf7aG
###J+P58o3y88w4VSk2oSaBlbFZXTUya8b5/mNSk4rDmmU4RssEilmO0ZYsdoaLNoLk
###rVPLiYR2i+QeFSDitH2PGKpM6pdjlLkTjgIZ/3YZR5XTp+nElnNUTRyaPTnUgGVy
###4li7sb1by92IgXb1GFM8neQetGjJE7qEDKFpKUJ/J9JYygL4Y6zlnDlOf1Mat5C4
###kul0CRS+OInrSUlZkVN8TiKX3pZzJOlUwwVnUMa3T9K5ymr5r5HV8l8sjV2UIgrn
###i6KRc0ltRtrKtcyBpSVUUjlc3pxKcWaWpIRYmSNv1PHZ2Q+1N+gx8wcYmWDi8kav
###xWP1W+Ye7I86Tv4MhEu5m5KWUtK4q6Kl0tNvrWRkK/QWSFHoLZSX0JJaKDMvYSKC
###/0J5CW0JjXLkJfS+ZTLCHCvuvHF58OYPtNpSjXz2bITiFknj+PBfNKXeHzdv4T95
###sj/tTtAfKOdfolp21r9CgdMnV5MIhyhmkM0mypkmBGWR5EKtQK+xBkx9+OEZSv5y
###zr4Lp52OH4bfSeb5XTAAxAZdBsOb3vmDSfxGRFGdDIcsvANCUuvAUsZrOwQpfo4B
###GKejCV7rIakofiOQwQZD2Bxxq0VQfjfZDUqgFz+GLW44fmCxmxTrtYM+VKSZ29VS
###DJErOEhw/MdLVt4xdLrvpoNPA9jsRbdT0uDo2CvTz480LYlJwc0FT2ahX6JCEZON
###iJmJwPaDayzOvuPz/a5+0WycnUZGsqu//x0YgLIGviv3pr/8Aq19l4wLhB350+rz
###L/VB4iiPe53tHXf7KdoGnpKrzMbtEmFgevHt7U36Cx/jr1vZqmz/yfUq7la14m3v
###bP2p4nqeV/0T+6dCpDm4f5KPiGc4Dm5uJyBclphXqeyUYTI81qhfHrHL8RSNIwfN
###xsWZw34MRrcbZ+MbdoRHYTz8YSEjQ+rrsX+DPPSkff/F7/c3WK3fZwQrpAye489+
###dwMbeC9Cm10/sP/ttwflk/a4w94BVx6Q47nRDs+8SrYZCtLWw1MU+OvfT8btDu4B
###ePeaXRwdIFlvsPO+T+ecvs/jM8ELHtGt2w1wDO0+t+lhOFEa1AY3TPndAFnr9ZS4
###P3ZkivffBiwcTscdn55cB4M29Ayrhg6P9zQc09/hdIKtgFgW9IKOiBXZHvsY1PMO
###h9tlo/Hwc9Cl+DwieltvCNsNRdMFjs97R0HIsd6dDzs6/igbXQsxSpjoE7mw3sGk
###4RbQFldz2tegk8ErMdHYBuyGATpuUjA5MndBGzFMGpveIYDY6beDO3+8kdILgKag
###Q/YCBtmddvxv0RFx9YgOyIYdkiHacq6ewjQM4eWYwZyC5N/uhzG+ZVwupg5ADuvU
###D6geBVjC0ErQIbr3O/AnrDnsBD66hNLyABjqMhnwsEw0LArqhfMy8jtIADgmDmo4
###Bkq5az9ggKYp3h4GyRD22iG6WUED0Mm74YQa4aibYIDbcfBZ0jVhKhz2Jl+QKgSp
###xXDIa1UGCyzwILJ3QRhGI7x802iy5tnR5fvaRZ3B9/OLs3eNw/ohe/U3eFlnB2fn
###f7tovH5zyd6cHYMO2mS100N4enp50Xh1dXl2QaEa/r//r9aE2n/5C72tnf6N1X88
###B221yc4uGIqVDWgRQIAgf9mgyx+nB8dXhyBvOAxaYadnFB3xuHHSAOGTXQJ/QeDJ
###muzsiJ3UL9AGd1l71ThuXP6NQB41Lk8R3NHZBRm/2TnoyI2Dq+PaBTu/ujg/a9YZ
###jvCw0Tw4rjVO6ocb0AeAy+rvQOBlzTeg/xgDPnt/WqfWYAzqgNmrOvQUj1gQHI32
###sHFRP7jEYcXfDgCN0MljhzXP6wcN+IJt1X+sw6BqF39zRLNN1GpgbLVjdlg7qb2G
###MRaT2FFRg83ANB1cXZCwjihpXr1qXjYury7r7PXZ2SGhvVm/eNc4qDd32fFZkxB3
###1aw7AOSyhrBFK4A4KAHFX101G4RCOrC9uDq/BOGwBLP+HjAEPa1B7UPC9dkpjRmQ
###dXbxN2iXz5yYDYe9f1OHVxeIXsJaDdHRBOwdXKrFACQg81IZLB1k1F8fN17XTw/q
###WOAMG3rfaNZLMHkN6N9rbBWBv68B5CsaO04a9I1/bRA5SoJ2aHZZ44jVDt81sP+i
###PNBDsyHIh9B38EZgf6NAh2XiaBWN2M3WmyiztPwNBQad/hTY63eYM2Hj9jvlCSrf
###of4ItYxBJ/Gs6xvPMJkmPqEU39LtkpglZtucYJkiBrjklyAfSsj0/DbPY4HFSGAr
###gA78v0btcRvYLiPjAx7oKE9/ZE1gEJPx9E55SFVZ8+cpMpLxcBgls+CgaJMkUHQJ
###s8iVCh+UDNyBeW5D4QqKBVrylmYyU620esQxpX5UoiBgSCiySZKCSXcmMagQ/0Mu
###ok/XNGgDDIA/Nzh6pJpEJ7j1k3+/2RUKPU4Tcip9yBVEAJJ+ZKDN3sb7tkCYnBoq
###JtKHgPoJ6irweHeOSYqRrYSZKC06dfF8mS7xOVAXn5lxd94oKob66ketXt5JxTs3
###gzQEA8awebxa1puC0Bcth8XQ2PXLS8Vk8npBNi5tGEvH8by4lMwquh98WpdG5UrJ
###fHtMWx1/65aSdfFuMX/rJd7WXr/GPb7xrs6K1RI/euVXjDAxsLxlZMVFjIUfRaLq
###9md/3L6JHHLpOB5Ts8SXlajYba8lS/IHwrlSLzYdARn4rdue2pwdWdz6cVKvNWE/
###pQG3Tpp1Pq93oCtMxz71tHUX+rahCKeHH+NvleirmCn1V0XA1nK4HsQpIzjg23Z7
###7BaTWDoV1ZFAur5cOG/xnlIQkrj7FPaZYZeyEvVEXIwwwGteJBQaPD9tyVzIOkX7
###MlFuTV7iVzaY3l0DaQJIekissNMeRFKtjFEqwpPy/Q47iQ+HA5CO232kmwfsJfmU
still the base64 blob, bestie, we do NOT touch a single character ๐Ÿ’…๐Ÿซถ
###RrBgPKwO0jJF2h/QaUq88My7dHyaOzxLcnKuOOrojpMkCDUCjViWP+p87W+O6TBi
###3tTKWqFr+iVHfIQBuVvd4R15kpNLCXnfG8EAHT1ioKR27WKeNVKgYwkTSPE4O5N7
###toYX1RQCVK/oaUZykcqOo1m/tTZjPbdm4ktGYVTWYqj44ltmST+95DfclCcYSNml
###x4XkYSe+9HgddUISyUpxtOozPbWfrXTshSLkQqTLfyX7H4mjnT/9Zva/LXfT80z7
###XwWKr+x//wz2v4Vseiv73cp+t7Lfrex3K/vdyn63TPsdanVvau/qLRjEUeM1GvEi
###Mxss315wQ6Y3oXVF714Ch7nduN3Ptud1voyNJ0kz4DBshdPRaDiekEVPM/whZ0+x
###/GmOFLogfXz22msdwYS0LpF6P3ibH/foiL9CNPXMcav4xd123OeO5zoe/fQ2HW/b
###8XYc75njPXeqFafqOlUPX8G/1apT3aT/bznVbfr/Dvy/8DUlLjNs1of+BLkQam0g
###/b4rnjo/lGDfntCm0YZGy6CGxF1HFeYGNxp0U8cd4AfaAYG3gkbd/+zjTgF7KOed
###7hZpkBswiQIRpCBhpMZgUPVIwWsJtan1yeZ7orjv37XvTz+4W6rjCd6p2HGMP+7m
###zrbDvGdV+Fp57jC2DWo226xE55kePgQ8wj/4xn3mEJbhH3zmVr/uzujGD3m6IXvj
###7njQmyoCeb4F/2xVo45UEShMJfzj6R3ZUjqCriitwf6eu2mEkYTHn6LHmrdJxR4d
###WbxtDTBWEqGz9emj7Q6jLPhJFPzhQ2sgr5h+Lej2YVLAWp1255bf1dDUcwxdHF2r
###OIgj50fffopj9U/HYyUQ/eAazQSBHyrPYKmNH4AGKhisg378oP5o0A8lc4B698OX
###QZLuZEwLKniOvT/AzoNiS3/22BMoQt+1cPzYSCdOpGcoxVFQf1NZllcNOjJLMbVH
###rkdFVJOHvSLBKu9TgQ+Vj6W1OyWmMA8SJWJ2KAUx3JPojYySgiYaEp5BbJ8Ogp+n
###/ASBtHEZ4EHxJ92Dlt1ESDvl1ofSDfXuh+HyqUYuI6MWeheLqCE/Yew6+R0j1gX7
###+2pYUT6CD4E64nW6VKJFH8V8aQEaj0n441ZdkstvMQRqlBqNJx4wky19grF8erkX
###7H7KyLJEFGdJa4epEQYqIjCuXPHTn/cC9AkbvPyptDuYmecOV+opRimWaBkoaBkg
###Wj5hRu48adLSESbefNLeDD7acqOZ8eZsWfK+WvMh4Ug0ak12BKcOkXSqx4tIovsH
###I0cqX9vRsscxnepFfkgmnBPXbOMd5dRB9zluFCr+gNnhsDM/8ARizfrV4VkCzz/E
###ce+Vrvygd8XobcY8ABuzNNfQm+Ol9CbhEQb9g07r9aOKWj+/JgIlifB1Sf6iRy1b
###Q0AaPxEVIxYmHoso+tGAnupnmJxbGvwmhdVEQ0iwG4NdjiZj0ZN1gbb4xr/CiCd3
###I57L6eq4WW8qCdRx8tErNBj7XR5VDLNCSuLCG/UKeYh5xmy0TERC29W5oAtccC8q
###Zl6Am4z5BTjsjdLsT6WPMffCQhSPKG7FGowHMQobbXA3vcMEiL5xQAu8Dkgdfn3x
###/4JGGb8ftK/7D2T1aIeyT3ftwQMng3YIJeHfT9jOhgzuw+cV46jivLZHWbsRlqLN
###CDcgt7TmqaSuBUoVe4l9JzkAHB683PN2D6wbyOzdxso7TivJVM6AvTi1Thw+r6Ju
###+XxDUn4a/BEzsO+5YocZDgDBtMO0KaEAYpYkXjo0I7nWTMRJnL4C2xzywSRHl13k
###kV5dCi91BGpeC6ivGQWCnJE7OrEtWG/BjmIBJnGZhZu9FQYzvctXsOsPEgUR9cl0
###9yeVfAVP8xXjcSrzlR10h718JX++zlcuuVfC+KzJT4F+6p/9QRmXUleQ0XVwc0Mm
###K5DOTvc8eZAW4pE3HpaJ+LzBnb9h2atrITe63YFOxTY3vUr1eWWHOC5vfd8l9cv/
###7JMaJQ/i+H0lxnVde7ZYWBn7LF9y1tPK/r6ZPT1CRJwoJkWUEOuqEi0swMBfJjEO
###8KYcKounL70NS2bbKDMBdPilbVX9w96vPYo9FziuNT8srtI9G5na+q5texibVx6A
###9odf/HBS7gP6++z83Vucqzb5NDzwwdlcaBEJtoGOpP5BLGJdyhjAfyvIgHVJYzeD
###t/CGPog/lY8f110bpda6XRngnQZFdEbUM/Zvpn3gIjSE0NZXFPJPk8gDvAh5Oygj
###clHktk1P1NmXL5UAxUb/zngSc7L1RgfSP8PPSZuj6PqBAl8WT0tPvRRf5XX29vJN
###/bLWOjs6atYvSWmF9dIVqTeDMfuu14Z/Q2Ca/ncAIKUdOo99emrBRJxtHSMH32HI
###lZtT2FjWizRxn+L4viUU8staf1JGfpk6ZL79i4srtCziZBl0lG79BCGO99qP8L5h
###L4hwhTuGdJboagTP44tXNp4936m4xLNC4KJpjuLt0Wg8BJGmjdagW4w+BWLJ5tbz
###p1uudaXzrWgPSqypEZiLRW/ttAwrQOSAl4OwrmvYova0+M2i8suXz0tlaNlW5+dr
###GamyCPDXi9AGTlXpaReZ6taOFRCdJ7fD0B9PitDA/p6emDRJ6hjP+9rKilJWwdd8
###axaEE/Iw4KvVQZoY+Hgbqz1+2EjJFK7Gvszko7MXagrxBwbZF08B5F814m9dvj87
###f1Nr1l9oj61YxE0dYNBc8rZKGWtnFg1HZ0yAuRE7PzySDn3JT2Xj+Za7vRnTegpV
###P9vJpmpEEKEASr2A0iWdxCWe13GggtDT6JtwrVTGKkTeOoD5KZ3X3958sZ2SVH1J
###NJ9G2HSWKGVrwepAwbEhVWzK/iCUuhK59eEpMzscHtFJMF8VybqClg7WTikfHgXj
###RoPFvoch2F0MvF6y7ZfW/Sjur7obQcMk13OKtpHWzI0oY8uxLjkci7nolD7YBoTS
###KG4N5LRFCevJnwkNa92hH6KQBlTe4UulMx1/9lPYyamNncQdBSqI4trv73u2rlym
###IHXGfpeybo3NzkYDtCJtqy7RO7HisAjtIzYlbebS0jW9ROVcC0tdVQdrP1/bu6Iv
###LkUqLG6uyV9Pi6B+FjO0YrTUlkql8vamYfZS+hk1bemttdxL5m1tGwXRPr6+jr3T
###jVQWZd4weH0tZIUNkq6tMjpT/bzJtgvxIVQfX0qPvPGIYHnCfpPP05A/+xSMeASh
###yPMwSllMRwKuYz7xtCeT27Ef3mqPOvr9e84HtCdrLekHqLrYYVcocj+1YngaRj+V
###IgnvROWBUoycEBVAaz53S6TvRjB9xQUQPQJNL0Xpy0l5i8f+Z3E2pAxtFE7jvMx9
###6NdtfFQUOMppEXC9OOsz77Ml6/OeMMTFiZ97/aEIP6NA7fs9DPfrjztDv9eLEy6D
###dh79UDM0N/EgWgn5pTSNG4u2MMU2BI/x5EME68c8rccnWrn+MLIo3AaMOKZCvKa9
###TX1lS0p0F2AspGJ/uH4blJQzF8SvarnAIaq/hT0OI3D+VJZhRFMOfiZ3I6GsumL/
###AaiaWEP0Du/295X+mvEasBlMUUgrARv69VfqVqoBUPTZTZjuDoe4ZUWbRZz36ItP
###Vpd2ZwIULqymxp5AiFkXHJxsxpg16KePam+NQ9LEEBQySOyGsn2TCi28TcaQwxr7
###fPkrzRFxAKLtJ7xERfIttabN+NM1WKuDCbTOoy2MYPpCv0OOWTdo6fyP7n8OvnOg
###GbomYxJIOnWotJeki/5wLZsUJBJfKmQAItmfVTr4R2EunPNe2NGdsKnywnH4KaOE
###SXEL0xqHk0pjiKToSEFbsuvxo69KUpsA9id+LiAORYe0Dzjsy3BMeZwwuvGX9hhe
###Cf80vPsSWZ9oPhVuiRO7G/8ulxNzS5fBKLXXrvlU3a55+L3IqvwT5SaKmlXxeOqD
###rkadFuI/ph/E9rjLXpsff4jDXhCyfXQ7xdRTaF99UCZRZplSTBuNgdImBqJxUJ7s
###omwoDF1kVSGs8YTB8Brm8WZIdxmG7Es7nKiEIpOTinNo3ZAioMFyGkKPs8GNY/dM
###P2oV21OAASH9hG6avGsY/eR2OO2L5jp4nEQaKFkDQIo3rIq4RH56uRcLKJZlhGkY
###A3GAjh374kduvsLxkSZmJAlJF6SJMSFhSslDzWCmnjB/jWb7KLgBdRyjULLb4Rd+
###XIV7bxnjikmBH2hXDBOdgPlExCMsxLaqgCzJTPpcSX3hM6r1wz7SCfSZ0/1tcHOL
###qSBpONIyH9vFsQ9MZA8rRyII988kkYAyzvYmTxWZOaZnVXTmCVlKu2rDZdiIc9Zb
###02QQcsS5k5nUCFGq0G6p78SCeLxStQMwO/jYnhwtZRQfMPFaUTKl9Qgba0rb69jF
###Urygz1CRJE/nNl/VUXZKoEi+vLinMRIdZ/YYSJ9r8IlJPsOF9gVvEAJ5ojv5cNzx
###y2IWDVoA+RaISziGABnRyZ0/GE5vbsU1piGLkp5S1zAT34ae1C4a/b7AerQfOepe
###sq4kaiulbFBc2E2VYp6uUa+DXrHErjGpiq6KU9x+ru2qYYqmA75Z4yALSSsvBkJq
###47rqticYVUNtBodF8ZNeMDompg0Dd6tbYKeYGCCR3AJxRAYuche/RvvKqB90ggme
###bgiuZB4uPV074O21ldkle1s4vINJeSB5OOQW6U++PxIdwWWaOE3oT3EXnSATEOFC
###gHUgxNQgRxz1RbrjU3pSuXdLeBKL9yQTe74x31Drp5eolPx158XzkkLimGYzmuz9
###/c1SMnySxXYKqg8QQJxAknKbRenNZnjj6Dq8ramK0dTX+JjMTF0pUksbXTShflW3
###hffC+z3eHvn+LNenOudSPHEt5ogYvWVLgXhfuPDp1kBEpgzUyRtM9taPgnRJS1mi
###CwS/vCdlp3VN01XlS+1FlJsukleUd3sJ19yfyiLTliGTpQLTGIlFRtV24UbP5Ffk
###VcPNYOKqMk4E8F8mQkw6/L7LxDoVdqE3Fi4t75OqDbDyiPlGaEfvGeIytyTOkACs
###dSEGUjEyuRUMs5CSuHKf21ZKsZeR4NIRemnt82uvXJ2my6TouBxZ99KnWHWY1Zmy
###MtzYYCIFdNWEEndWXXRiYVLmdVxlcY2yMBbF9dbdsjJIhfp1vqR1gyqsq/ndEUpa
###m2YWca2pOF+98vilAKFhKRLrDGtQZDHQH8cZ2SQAs8DsaUjhcbqBKmZ3BsaUUpbE
###vVpOSQNBes04OXpNanWxrZlEYFzOnNjsAuOjpMXHiYpCM+ca+U8v45qqK1UkyeHJ
###Acp2kUCXaQsu5YSQtAEQEFpM3MKWBWU32UlFCZbYiZVgmirFfYyMEtATbuAofvcf
###XfadI1sr7crH/zn4jkcAoe2JTHqmeSPnEPHy/qmj+kRRrHrtEIHKHeAJjfrEv8fj
###2cj9U+WKcvSaTT2vD9vpHnq1xEnBFVRG1ktlEZ7GPscKI+Sdk0qHaKLMDRWOZueX
###zcO0GCNa+ICOTu8P1k6NczmyBWnLFR789DJmZfHBXUntBEc9ZdwZrOlnZWiELRkd
###Fgd8srOPOORb7HQvPtfjHaczPOy6do5XWOIRnv3wLj62A+DawZ0+v5hHLIr6EONO
###6ivijTCIcDNOMO7q8q8p45i9i7VPAeElTaYXSeQpPZcY9AyzX1aj1byNVg1MHAaf
###yRKHag6lEsOxqyPxY7mIlhWwjmQngOgJ30XeiTII7SX2VDyUyqYB+aT9CTCMRhVU
###/fDcE1U1E4kHa1EH9iPA+/uyTV3biLsa1dmXaxW+SRle70Zk/iTSA4oE8bSPfOTa
###77SnIb/d/ZcQdf/pBB0meu0x/kGfOTTi3AzT8QXbh/ydPEjVusEFaZoBDAuEfoVA
###j8C7RnSRWwixeMP3E1kU2gi7G3QVFpWgThCGVBodAaPW75ioJ2C8y7K3a9rUIU+X
###SorcJbTeX/h30jASKz0R69mV4V8m5PAJ3eDHpTDniESbEF7Gc2LZmVj7yhD52RFg
###4XTPdbiHKXI8mBkAoaIAmf1ILHUWAqn3/dg/WptFbSupOHIzKR6o9Jy1n9gIQvU6
###tCDfjQXsgnp7KOo+9z6dIAm0u5/bgwl6CkXRdcp8p+QmB4UYzNA0Jc3yC8ujDXTV
###HSZbQQOKamQqCqwoCqhxrkabJCY793dtL4xj8bh0tFgIwP5+kS/adYFqR1s6ZT8S
###jSxYXt+z9yLuAVNLrB1YlH/bwoir78tJLqsHqxrdlPcsI45Cs0ey27zSlFrAT5aI
###co6T4//gwVQAyFTN77+MIlFh7NvIJkkzYnlEB/jMkMyEJ4xmpuZ3PPgZQSCs5AhX
###WZLaeY4iC6sia16+nkRSkoegTc0kH8sCzWCNL90Y2alZohQBXOYHk5dOY5toXncN
###xcOCc98w6XURuwlMxsGd3ZNC00pTAjfp3hpR0CYtXtG3caWI3SZExq+fLF4Rsd9E
###dDqkP5LqfsJzJHaNsBgHZJI0eM8VL6F3J557lufcWGx7ATPRUh0iTecLbrCQ5nqO
###/orUqQdcc9IywsSjljYWaXi64KdfiWNBcWyKu8Rde8DPdfWjJLEAJfakbQD5SmT3
###RB0l+v5CLBNerGycoil9idb73AYxw6aZZrjR/IEVBTfTIArYMEyiCfvbvum5YLZp
###u6T+D/N8sZxiZLVaoqjK/l42xo3WU8xc8bVKnnlPOHP1+TUbNfdfUXh12V5J9y7r
###u5iwtQIWS4SNn2OYMr8//MLl2uisxRGHbKpOEHkp4HaGwqJiyUJURC4XYhEVDyI3
###R9BTqmszPAWN4xHlcP8y6NtOsQw9VEEE78RBNsS1Ysyjy1vl4xN4gvT4U9m4G7SG
###p3R4fTF2it1WevcatDbYr0lNAQwM+zyYFC17FGrLZBsLOpgWW97lirQZ/wFt4TE4
###cgC5hu24F0zEmXObmkfXkc6wjRGEeCYbsuLHLWvnjzMxjZnEFSLWMVc2fc++Ro5l
###buxYRuyQTJzv/A5GPGJl8VrPKC094NSVSruN4UKWcDdDacJdxKEMyfInSzSBfNc3
###qTb368a7Um1lhB/QMQ2W2DqKMMcnulVAGgR+Ms6ElCalzs5/rxt4LyU6AeKzkDH0
###Liqg/lgOb9SpuVzeomEc2I0mCgSbcrCAw1tEpqlObzAzimtR5OlGr/+j6/CWIg83
###/C293KgbIpYAFH+5R++iJdMfikuOFv85f/IFfZL+g1u4rK3n4OaS/N2fhIj0k2ZC
###zrcIeAMpS6A/tK8ADo3hiPf3krzhr7pdkwgEtlIbhNvADkGSi2uusKi/6vpyMxaY
###bMmzteSZLXkzWoKJtvbHunplg7Z32Fj8dF9tUpM1f0rgXDGMeD+VOXxNo3Jjjc3V
###q8cvBK185XFvolPVPZtv+50jFSNSihT/dSYkHCHNRI7poBcZUpMTh6HVnM4VLUn1
###NddO8UwXc+XwWuhFQiUytCHQhLgW5ESaD2k9u/MokP/T8z9R4OpWpx1OlpUEakb+
###J3dr2zXiv1a9ra1V/NffPv7rAcV/dZPxX+vj4BPr+uwAyGI8ZMfD0dAe+HUV2XUV
###2XUV2XUV2XUV2XUV2XVpkV1hk3rHU50yd8NlarKmo+Oz2mXroNa8VDI2aQ9teZug
###xb0lfgpra8ITfUDsqM/Ogd8FoKgCm8BzJ9SRij7xAdK0zxuNBrFPeH9NIbrON0t0
###0vDZH6NPRNQisRWeSwR4EZnaQwaFHlgIPHeDXQ5h8xH3zQ+I04SOCPwAAxYMni7B
###yBbvMMrBAZ2RwOYMHQPB/sYnRwzZ64Hv82tC6Ed6w/eHo/Or2GsBIwZFDV77PW5S
###8PWO8tFwr/4QWR1uPeiQv7YW1dW8QxIgGNnRwujlKBj5dCeXX93u9afhLTTIGpOo
###QbJyouCB75SMKFFVfhGK2DRHodqdo+F4Mh3ApgQzgrUazTN28Px5xMHbfOMTZEYj
###Fr72sEGO6SSC/vScqMk+PaDJ5l97ogu94J53FWmg79+howOelMOw/V4PtGWtZ0BZ
###V4PgvtwP0JUD/ePvoonGuMZoyBXEJq8Akatw15/4JHfh5icbG6G4hgeLHDmhMowN
###dI8gw+UXUL/QcNTDGYlcj+la0qjf5lLDXdQk3QCgvRsjjeDVgnEXqQzVCLGGo7J4
###eIlYhf6Cqvgw8vnRhYIojifuwSDEi/CFio7YqENnqRNZpcgp8L7EdmeUZazYHU4B
###8aIwZzNR/wwUMRkuUJlw7F6E3u50LMk4mhAF33xipMBEJt6QR6o+vgAOT2/in0fU
###Nnr7tDud4RjXQx9zi0UNxmA2bknGjiJgs6LSTEkbU+gLwsVbMG0cuRwLJUFD1Eh2
###EQlh7nOYJ1oFEWw5uxvY5kN064M33VW5AbFdWv90JIYhtvECiWzIH9y0OXO5I6ob
###jibBnchoRDoDdbLrmCQKvUO3kxi9/KI+dOg9yfhqMyGMpAM8Au0xDnsYTiMqhiqf
###pJAasUboI0q612OUlKdo4Gfl/p1Arlj1LUDHwfMfW82zqwvYF13jxfP4RfymBTui
###qKdWiB8/p+LJeOSiJFG1h77dQKyc1OEbxjbokzM1x70y9aXSH63Dlv6y4vvG6fZm
###iUzb8lGLP4utYzGQ+7s7pNFggJCi962WCNQQre8YOOcGtNziBpMRjGQg67u7Vufz
###JAxbYVD1ivgT6ndbYVh8wttQjN5fbYOpesnBwDPbYCTGCoqlnj7vMUJt5JcJmjGm
###3opiGGu8OqqrcNYxX39RonsZxkJsxaGF53Pvo7ixpxnILcTXrgSSJc/t9ScKjpXD
###GfjvxgxjS223w8RlrqhiD6/79SepyaV7oB2OeNOJMl+ZBZqYY6rB1GkUl74485Qr
###qdV6fXp10GpRXOD4YfPyUD6UP5TvIJg3QUqHZ3igD5yz4h6X1PkVqQFIHmM3HQwx
###QhvhHZkqQf+ks9hrus4kNORYTFNOZr4H9ZJ8jb7jZztRgGtDGimW1O20WNr4ztLE
###BW3nYvMy+Kx1O/9OCamSMXKtwwmyj94kGAbSkbh5UKTbR8WNrXV8WIru1BkRWpSQ
###vyT5e8AA3e1IFOA+LxgK/X4NHYBazcbrVvOgdlzflS9Oaj/Cgr93WBnj8T8rxS9w
###/eILitNfUs3GxRhsSWV3u3rQGVUX+QOmCtPsvzQibq0KN+4+/Tb5vyrVTa9C9t/N
###bddzuf3Xdd2V/fe3+HyfSP/lWsy/Rv6ulJxf3xe+X57Z93vD7EuNL8Hu+/1S7L7f
###K3Zf6tmjDb/fP9bwm9KN+S2/3y/H8vv9kiy/YlyPN/1+vwzT7/dLMf1+r5t++cJZ
###gu33++XYfr9fiu33+6XZfr9fku33+6XYfr9/pO23
###cHZ+1RTqaRPdcMcdklE2Ouw/C/IH3uTFBMH6Q5E1WH94N+1PAh7eInoBvLDd+eRP
###gl+w9P+w039D/sN7Yrh1fwPRKOv8f3N7xzj/d7cq1ZX898eR/5qfHkY+O+Yp21bi
###4EocXImDK3FwJQ6uxMHfVhz83vKBoZycN2DGzwgvTfa9/QO12dUAU+T4FPsgkPcj
###7/1umQdEuJ4G/W7h+6PGj/XD1vkZoHsPDzlYgw7d0fGNzuHGPm+ly7nCNGoUHfCl
###dR2qvatdtHB5/K35gl2F/Mjzc3uMKbn8ct8f3KB1dTxuP/CehBMMRBhfgMH+Nust
###ugZU4y3wl8VSWvlGD7jbgLZaYbOmwzMR4BKKUqzDAM+ZoVwZvXfb3bDd89lNf3jd
###7vPuFA6Ojmuvm+zFHisfxl1g/17kL0qF79US8TCVEtAZfuKIp3G0RdCRtvQCQL9g
###KKIcVcYo4kc8YdDhgUpHPqB5OuIG4vJkWNZdC5Co4jPAF+Kyg7h9w/7CH/+FffIf
###vgzHXVZEzNVOmw3VA6LEG8Fb8+OgM0k0Il8YzYzGfhk7rLajIkY9z03BHe/envJa
###fSvh7mmItX5Y/ZSWUPYiKMjm17F5Uq6E5X7vL9+5G5WNynd/KUhTfRj0PynG4Og5
###Xfq1PDeMx4WCiL4Xr6ZCs3H8Q6TOreOw1CctKloq0HHMrKJoVYei/DgAWHfz6giq
###s73CceMV7G/0HU9y8bd8xzbahbNX/zv+OQSEHBD5IIDLs7Nj2L4apy3eQKnTUR/y
###aqUC7FupNdrjAmyHANL+etweYJcOzjNgjgqFzmiEQSfDMkoSZXlmzyuASAx0h74j
###5UPn34tuqWQUF9MRJoo3RPF+Vynd70KHusE4Wfw4Kg4lZGn4Zp6rGdX6oloBuPwp
###bAuotpff43lW+T38nxN0WfH8KL/n4X7K7/FwqQz6xM0AfsCIQf4uwzsQ6bBUeNvu
###Dr9IAiYKPvNY+QbAS1AlSdSvrhrHhxb6U6lf4/LwG+QPFBw4ZbVq5w1JXAd8G+Rk
###KLD7lP1n4d9wgcRfiD8pP3FfoZ/kVE/Pxx10I2DvzmuXb5i/cbMhvpJh48XGxtNb
###YMfARwry8UbcHt3S6KHbjXwCdXDF6L+Pz7XfzeDmfDxMloue8/ITQHaBVgpeIYJv
###h/Ad5KUm9aGgIv3fix2cTCuJwtQfHNYxeASGi5lVSRIq1pIohmrHh9EkiWp2goVq
###UTepGnVfq6YTLlaAIkibQmTY6Gx07rp0hMjp+OAASKgTc1tWHrJ//1/s318Cbk5/
###2BgmKR9rYEdw9fIq+Evwal5JgSEq8edQ9L+YGIQE9e/FiJVBN2sgTTfe1bUGsH7t
###okT/Soj/C1t68gSeceaDjwqF//j3YsTsSi/+Y6NT+DforznykqXgaKQVHY2Uwt+z
###w2CMseA/+2GBqFlINFziEPowdKJ1Wjupi9Shhcvaxev6pRi84M8l+k7F+Ndo3M2L
###g2brgJlMHwfNz2/j36qBEGriOHDv/PfiqD0Jp9egqcJ4HG2EQAccAFIC1j+sn5y1

okay bestie, this part is just the base64 blob for the reference source, so I'm keeping every character exactly as it is ๐Ÿ’พโœจ

###IpiKWfEO5i4ukbNto0UJBLFZw9tHCTgiCpgAJcvNAU1vmjx/2MW0D/MDU9Ke9kGg
###gfVQKMA/L3DLobko4ebIooEytSuFArxTihYK0Vd8ih0oIYUY9AnlovZUQn7BFKxQ
###ZaXpf5PLIW7l3wpqZ2wtqUiyNlHo9P324EXh38Z3rNxj1m6xNCgKjsRgEwMo/Gva
###fy/qtcOT+jcxjWac/29Wq9uG/bey41VW9t/f4lMTaQXQRBtGaQJAPvsJ1TVKGpvf
###aFvQjbbGva3LIdewpW0sMoY6oGvcjdDlGiTCF7AhUei1QoE8kVGXHfo8aDnmq3DQ
###/Bb0yJfzS3swMdzUBcuLnHC5alxEacvhsd1JWYtiJ8faP94NCNCbdzr2S1GX/G7A
###7b5CkS0Ie608KoFx1Qagn6JmShHiIsc7EcViSDhQMxRE/lSoiH9uB33aPjF0eeF1
###QNbYYRhQYHbA6k0wefH0Kfy7cR+MbjeG4xt+AnaDaYHHDO2o7It/DRV8KP6icDuZ
###jKACLWvEbYeqFN4Mv2AKDYzYhpbIm1sRgk/vLJnoR8JffChiWskhAK4LSkpEPgZH
###hNyPbhxICkITPoEAuZ1SkVNTA04OnwFtETVEKUdu9MEHPF4aWlS4J65s1xF2ZmFo
###weyMIVCNW2IH/eFAxuON2in22yjfmmMd9ozZEPZ9TOFYgJej6XVfHAqgjES961D7
###8ZQYWJYTA6U7XS74FLwSRTgFSsFGNp62p5PhjT/YCG/pZ+wrLon+DJ3OI0dlQa7d
###CMEdsuiQSZmcoGH6403cv/c704kgpwKNZjhiXRLYABVAq1dh+8Z/oVT5UPY/spft
###0UgOdp+9DNuAKsrwiwRdfPNLCR6KkOIhK7pPvVLswMdeUpwYjFfCY3jusw9irUDD
###wWA0nUDt4XSCXwpq3nCCX+7mgxc3qkA2Wy+gI+UL9nkYjNivrD3tBkP4K80osNKB
###arp+v/1QEI29KJR9i3PpCx4mdTwdhCKqEx0msyIHJCPQl/lRcqkAg5jdiDimZkUy
###uhlt4D0HGg001rkeWxoTLvsUjKzN40AgunZZJORJ26J8BS19TjaltzRuk6OyWVVp
###Fc2bUcFCGSPc8JweL09f/Xry6tf3r35twn9Hr/ahaY7yuEyRFvegPR4Pv/AUPUPK
###e43frTlBjZyKog8agRRApcNzm+AXn730NrZ+3frVrfzqVX7drPy6XcFe0HtGBYDn
###3IXKaLxKoYxZA0ftB3TtBuJ9AOaAleBpcIc3tsQbWZ0KOHELbsXbBMwOkZvcU3x0
###/L5PmI2fOqyCoSMw73eJbWxsQDVWpPwy8GBXba0AijCio+d3bLOEChDjJdhR/QAG
###j8lN7oaDoVaanjJ6TMQKyHIo3bswFVP0LyIwINbJfTp9EbzDyx8LsFbCkL3E4N/7
###SjHYFqfIUBn3mmBYCoM5UFhzNIIXK2W3UlHHWMGgfLhsRGoO+gocrB9MJn0KmRa0
###B0wEKnW3McAFOz84ESIJbnLALeLEJCHfhWh/9hVOAjLLaBxM6GgTCAAwsPE/zpvj
###kfI/2Ye+jWi8g3K9Xf6n71z+97ZA9Ef/j8rmzp/Y1kr+/x3mH7ZLZLf+GAOrfIal
###3mo0LlpHjYuNzrfx//HcbS/W/0Dxq7jbla2dlf7328T/WM6nYLoRVbZNNyLi/5on
###UYrjUGFZTkO6/rkEb6EluApFfkKPdRGSXjmFxfyDluEatAy/oKU4BS3DH+jxzkBL
###8ARS3YCW4AHE/t9//x/y//l///1/Cws7AJneP4WFvH+srj+FhVx/LH4/hYX8fnSn
###n8JCTj+Gx09hAY8fq7tPYW53H7uvT2E+X59UR59CbkefmV4+hcyAH8v58OvweAJM
###fhiAhKPGa4wREgUDkRfov4uuFcbvlINTKhC9SEhHFE4k9T7iGnlRpIpULZrj87Pj
###YkGNEA4V2RpwCSf59Hra059WPby3fg9fu/596627nXzNX8EQxmT/wkIFcStSLRe3
###gHsxfNnaNeEj+NZoMt4165LRifdB3L3FRBsUWXBI6uJ0xFHQldGycW8IJ3RVeRBr
###hWNgsuLeKGxCxbhPFEtW+flSH7T6io7pEyNmam5Dpbt4FIdz1Dy5On7/SoX4hFXu
###j+DjMBBjFGuFwAFUfAJfPyg1MKTtNvuo3D4WiFSBvAIgzGjrA6uwjw4ziAXU2A5R
###iet9SPb7I1VSO5YAdlxDYOKxEwNzFwHmLgjMWwSYtyCw6iLAqgsC25wFzHVZeVnA
###thYBtigatxcBtiiB7CwCzCB95Jbr6xhdWrmVzeHW8C44b/+i+aZxdNm6OLs6PVR6
###Ap0sycZ4qGFxxRsaxdvcwMquBPsSRxFtNPWhsCyPEtr9Pub8KV+3UTz07iW/o8Jo
###umtciECryA6xEnC5z8Ogy7I3CL4vUMGMz1oT5DY96HPj6RnejxDN4inHRLd0Cy6r
###bi62D6Dgw0dHa/qM4hFxji2YObM1zfNmpAMIBlrL1GueKCe1ZbPXuLvZPsHg2B9Y
###mj6NkrVxiyRHTyiblpuiMSeEPPh3DMI94BqpLLNEqdlMbJCDJgfVGCRe6bu3be9K
###7MO074AQXwPhtX7Rwpw9r2qXB29azcbf6yBUsHXl7dkF6AZiMUWbk4j7iS31fIxr
###JFGBPrcTkRCav5RIpzHf+Xed0UMRX4E8Wd4PoV0nDdgaWdGHvaI6XFpqkYgASwIp
###k6d2xwTXpIKRBb8JdRsDY6ZEX2wb/B72Jxh8vsAFFqONAnYXgTupAkA8HZI/3QWD
###IqcbGtc15sPDHjA1fZjKCWCRKxEuUpbxdOS13rwtEqYaiKknxtTpk4Oz76idU4Fr
###dCK7fUwsreoVlVoOSiHrOOJddQXgE5maQOdQyjhQN91jeaVWLO5wWphNxSq/BpkP
###xDRzUcRLt6y/jN/2xCRhUG5WSmRL5znmAqIqMkEAOXeHu2SzYP028COZ7LwX9Cec
###8EX2FgwpdxMMBiJonE772jRra4BPqDJlL19y+WruNZEZTd/IxP21oCQvk2t51vjE
###wb2SaXPg308YeUva1ni0vJc3xv9x8bX/+ez/6MQZX5/+Dfy/tqrupoz/Uq1U8fyn
###ul1ZxX9Z2f9X9v+V/X9l/1/Z/1f2/5X9/zew/3+fvDEWl0b/1eg4gK4omu+Oz7W2
###5MvJFFWKlpJ6kQcgnz0AMqEDK233UQ9tgnDG6sITkYvxVGZ2O1II59K9Kt8VY6Ff
###PBGmjKN7xUdsbRQCXDbzI81O50MydSGXpE7j7TNf63j+j2KViYYBeyJPLRdpPyAK
###jIWn5iQY+wY0Q7cJ/UmR0ZAcVnEiVSUFC7G5gqqASnRwN9iQDpOtN+et8G5y66qm
###Tq6TixZBwfb6w5siedYhASEpNuHtO1hPdOMQmjhpnLYOgJUdHbXe/J3UdwDLyqyI
###X0HZ2mElhz2TSmJWRzzRkZmdjbF3JXa0rt/Ge12IsePmkW6udNgIAynjnedu0JEG
###TLMzvWAcTlpkvGm1e1AdbQg0Wa56KqST9LvaoWwLJ3ZdIBEet7BokT1RQYRYXM6I
###MNPiX1QtV9rc0vS/KKbWb3H/B5U9Q//b2l7lf1rpfyv9b6X/rfS/lf630v9W+t9v
###6/+FGl22nhapZ+xQXOxqCtUmSyuzKmNC2FKUMfGkZWhLoIgd+p3ZCpjsEa8+EurY
###TAVrpiblwGbc8Ue4kz9MbvnGNgqA0dk1rEPfomHpQ9MOg/MoIrHaAa2X9zM1DqUc
###poFt3aCazs9Ot7e2qtsx5AuqdADEndQY4WmL3oshqT3m9c6PDyz14Km9HtdaipU/
###xHFYUv4XeXePL1qTYeukuQQVIFv+93Z23Kpx/3/T3Vqd/6zk/5X8v5L/V/L/Sv5f
###yf8r+f93k//ZAc/Kyo793uTpBbFecaE+dq1qd9sjjGvCToLu0ybm8ETOiSkkJxZ3
###X0PEEoI/fwgCdytxSLImxO9Zgn9zjtOVHA7A967uoZsGFjEj/TQJJQ46Gg6Rn94F
###Xd2VNw9YLx9YPhd2uJRHVQFsgH1mcxq+J4d5cYnACpZcn99O26Ab/SJC5gDldPww
###J5JtYNcARS0MFdLCMIdOKtgjeCtiiihIRUmhyxZwk0aoiKQW+t+GretRmPDGJrCv
###eEQQHqMYAdPFnRi74XxgJ8NJu08wEaR1tOSpfYnlZDiS+SjZVoT0P4wl3LltgTDZ
###evvMsYJtUhFG+icG9+j7n/0+hbeABoLhNBTBRXKCnQxPhoNh9rrFv8fouclbFvlT
###24IflPcpqAegYRAGqgKcBbYXtj69+WU2WO7QKcLuQI3S45DM1XAR2ToDbOyFr/rf
###5z//ZQyE7yB0K3fhEYLE6CyD4R13PO76/Um7At+r4juedlYTTvfh9A7eB5gVNrwb
###grzZ6gz9Hm8CDzmxkri7hD9Fg/jV3t7xeWss/M43HfZG+0WXWahl+lbl3++CQQsX
###YbwWKGYOr/Kl9dbbFAOg74krALgEP2DiwtbRRe2k3jqun76+fMPWGfn4G4WhdwDq
###A0uW/0idTXtpaygFMG8o7WXyJiGykj32BLYYVjauJfDtFh2y2yFIyFDyqcZw1AuC
###A34xcMBe6uQHeICn6+uajzhMOkZQRZgDVqbbUevxjaGqV4KdR76Jfa2RSoxa5dm1
###OEoHUNhyKUm/iES06Kou4ByNKZXTbzRxenbV20wSq6/InV1x9tc8vaGzDuM2rPJ+
###eEK/bG7c3DFhN9kAdtiJGmjSr/ka0GA/4djTZvTjgi3yzjzhKJ2nRYm643Oenvtc
###+NSr228OUrST4Z5t/uhR7fAw8iAhNAyITMXXdc6Tol/khu+ie4h2R1UueE5CADB+
###9UZ7pTYEJByV/Jo+fFW0+sbjj9fBevR9Xd4olT/TUaAuIxMH2ju1LTsWjkDQA53f
###H98EPjdsCFeYYZyaV9mSoFGN1Pb2MALYmtiZBbXq+w5UURv4a9RZ03GoCWph/ax1
###UQPFsNU8OQMVDV7Vj9hT5gnfoRdzV+bCQnxJJ9k57Za0dpvZJlwln+EEma1GrlXR
###jlsRExJrST3AfCtCdpE90bdaTumOnG5c6XzhRwIuyBittxVxxVqdFWt/9O64s7vz
###xtz5qTtvZnbHy90dPGhACCK5CEXRJEsVKJhBdyou08dcKd4hheBh3sF9Y2JQ+VWV
###UM3KdEEuFmVMwnKl21rMOA/R3fEOIyJIOV4zwF77ky++P9CUCocvrWEYBteUaoVs
###j0Ld5jEFxdh0RQIvjGmrh7lepcJesO1KZTeSPpvTa7Ils/ZoNB7eB2hgjPqG+g2P
###nCfhxS6b0QqHbcIA/NK4WWi8jg6i+I0tU+gzZwY6XXEi+f05DEHd2tphCJJRMdnK
###S56fWiGYQxEH14b5F+wZXRPjOt2JQH9xa726hvNbUl7i5rnBwuELJuGhRAL1n6Jv
###YhU4ZhW5GtQij8U1MXyuUqhUWFVJCfhGkVVjwVj226KTqgzhsPGu6rU+t8dviwk9
###0iTHZ9C1LUGS65rc7W6vVxVENXqEAYmnax8jywKCMRikk0WASAtpHX6ZnCKVRtLH
###aVbbzazDuZO5EtKa31WvsfKh7LFNmLOiEINEDWphwL+WaKLx9qw202tqCeWKZKTB
###2KZM841NGQ6XXstJ5Sh5C1NuRWmMaD1T28LdyN1c1ySGRO/JyltU9bKKnfFtKiK3
###eXtzmROn9jClH6bg0qQ9RbnFLcTiO2hIbS6pZgBLoq3eVkFRVlFeshdJ2+2hV7UJ
###AyXvgeFiu5YWJkzHhcG90aAX8mM0PDIZ+O0x7AV0WXmC1tkRRgaGPTb8Qj7Jk6F4
###UiZTieDhYri6dY27jcecHK0z2spEeTdhi0mxxOCt4n6/PQrt/MGcr0o8jaa4Y33l
###mq9UKeRntEGSGFKMqjgsuDeoEEcpJod3hcQy6g80zZ48iRpHjrlm2duqYq1ra+fX
###X/UlGEsFduoqQUsmuVY2Klty5bAS9UObhgM8Am2H6tTumla4dh9jKT+w23aX/eKP
###LROAC6DTxuwkwy/8yPdnbr31LfJ7qiR6oTr0S6k3hej1BkrqokwVLRdr37W1Pw+R
###RJj+Lak4fe/TiS/Pzqc0m1jnbs6F8OecC8H9hgvBy1oIl7HpFzgdknmZz5CYrhW1
###/0GpPUl6BjXsW2jhecwUNSo4mvb7+rzr+9wi2MgvTZgyDbm+oWTctfVpl4UrKsyJ
###dytEU4bDZCMsnI4xnwP75PsjzPsh47yzKeCWJ3GZtEcU8kOE07uF7fMaNWySWYSb
###kqK9mDxzz1BlZd+CPkZwIRYM3/CGlmbbKkujEg8Lgzb/1knTMHZJmCltvmTHtVbz
###Te28rlZNBHhJk+ZSw6agPIe+ZnRGTwfwX8ag/FNYrvFwOugmArzY+4fmO/gkArCY
###MFOrV7Q5tWMf96HU3c60M6Tvim6ezZabdChmz4RWey5lBAAkFAw1yqOyvsmiI+0t
###yrVB8okiE7LI8BF59MpjNjyiKQtE0hISe3VVUYaig7iMwq4sTAdoMv2ecUXTJhM4
###aKsV44xOFpmu0uIJjEtxcNAWlkX/cUvyYJK6nGL9VmyqCkuLVKwkPpTDT+JM2xo8
###d354bgY8dxY8juoEllUZyaI4mujXIURzYZ4yZLOdxLFDTGDAweLZ0PcJVyvg6gUk
###IcnXysmsca6hjXzRE53nIoAXLLK3KH8+tUGK1HQNx/z4WD/XQPs72rRiPCjxwSJ2
###+fYZmwUJG9FGqR6GGuOggcSIjSAmIclTVHfeU0/qz7PEoWc8TCB/bTmZLER7b+Ea
###JjkrkoGFOGdR5TzHYysy+j3JSNnQk3zXaNxCYKksNLWqa1Q1VFVOi2pVRWJc8Pp7
###8v4Hv6DD79T8Fve/3epm1Uvc/65uru5/rO5/rO5/rO5/rO5/rO5/rO5/rO5//C73
###P+In58cH9gvhdBGc37gWx1K2C+DmxW9Vysp78Xv2/Q8z8lbXT4+6JWRmv4NAU5yv
###R+EFZlZOgy3BYoZb2L5DYGTd9gRd1zEQOtorF7p2Mjozgs6n3IhQRissntzhTPHR
###n+dqwtro1JkR3swES0lCYcsQ4JNwc3jN94fh5Mh680P3mq+8gK1K5Nt0xV9PzDDT
###s4fmAYvb9AE3IGeCvUS7Msps6tbOL56IpNYoRDFrCH1JzbSRDvsMifhgMu7v2nsH
###/PjuM6rFThzizVpwNO2Hfmj3M6caxxQBjUcIUHVt3jXRi43jy/MWnVTEpz2R10S7
###BwID69z6GJFedZmWPljHFIH8yRP48nIv2RPp64CW3niO0cp7dFx73TqsH5wd1lun
###ZxcnsNP8+qty/JhW9vjVxQXCE+PCn2Q5BjyIRwPyfQs5L+qinskt+slDxfkYqUIS
###gs/9bLsChaJTQCnAe0OmH0suBk9llAJIFFZC5UzW4TvKwlJoXY/m/63w4N93gokW
###r2JZeOCkX9THT88iPIh+bHBn0EtYu04i07JRlMZx1uuF/oTK2xbP4qizYU7xrSSP
###TxyC9aLgI6BpeIvgRST0RDKCDAJhV6Mubp0cBRv8xhQW6439n6f+oPNAegHP1X6L
###M6KdKKXyoQVpIg2pF1Mkv88+KiSnzbdzXQBdUi9UZHeGY9+GZtzYJbk+YiWmYUHM
###VRyO5XfCAnQgffQVbeCCOHA3PxhMDLeCOHRNM1rKMUEll7lxIi13Kns7++K80f4W
###tjTPXAo1Id9Ex8pdsdFIndYfj82T/VlReirpDgZvgC/0tTzj7PqBW4PMYED5MO8m
###nCOz5zOmKCHe8ZQgGyx6n13fNgn9yQgvKEmWur+Xxmnp9PazODy2Vy5niDjiItTd
###8LMfwYZRvKKMJdrvD9YefJSiWHw/SjE7W+9bmc2K+h+jZW8BM/Py1aOVQDGR9QG5
###T3CPVGT3A78jc3fFJOVzT/ib4bDLaT1UWcSSehMFh7rpT4UCqIg1hKrjxTHwNL5G
###edcbjtFKGMDKusGrS3zNPGV+OAm4VdRggk8fMaKD09fpS+9YC/PFF1U4BF6iK6gy
###UHFoRPkCIe4c+BOeIEnZncIRH8ei73UrnF73xvzgR5HjgXVoypkkPOEdPDqFRo/1
###cML/o6IJ58j/vnH7bc9/3Mq2cv6zifnfN7dX+d9X5z+r85/V+c/q/Gd1/rM6/1md
###/yx4/jPAAyDybY9TFZ5fNN7VLut4FgRv8XpyagF5hNRqdUb9aYj/FWA/Aq7Cvjv4
###DvTVhTLH8+ORMO01MA0ZeiwtXy1eeQMgfhgKNgp/QMAHLXk4QtlWDiw1RexJUzOC
###uJWUKkfN1g9v/m6zm2w+mw0FKEX9FDP7s2YHXSrw87WwMw5G/Pbym4frcdBljcbF
###U8yrDKrbw+gWZYEAsRNvJvyGvJLkdJVw+Y+WcHn3N5pdvIqymt7faXqjlMnXD6zN
###em28IIChSm5BiMQjlD5GWpsxgTyRcotub8hQ6cuaxuJ0gFJdaY5pXKPEx7Om8QNd
###rCcrWP5pXMMU0LOm8UPU6jzT2Ncm8febxmKu3q41HZZn+j6w7QgTq+lLnb6mj5oZ
###6CtobwMJXERzmjFhtQsv32w1DY8NPSTpZ5+ohaLezM19YLJab5/F7f8xeOaspmvo
###VaC0LpsG1GNEBND9AtjLQLGUrt2PJwR+gMOsERgFIVgE2q9RzkL6Q2bTFIEYW1nl
###TPvXtv+Ki6wnTQxOfHzxzfM/uO7W5mYi/8Pmyv9/Zf9d2X9X9t+V/Xdl/13Zf1f2
###398//8PMHA/AFVJzRNjyP0gRS8v/0PVX+R++Xf4HXWnT9avoHm4KcKllncdBLuZF
###8uOD9Ye5ovX/0YL1Pyo+vz3+fr7A5veu85iw5vfeMoOaYwT5ZYY0x6vuiwQ0z4jY
###AsKzGqyFrrjMCNUyT6SWGYFavlGwld841sq3D7XyuwdCyROigudLwAgV/JsIUCF/
###JONTzBWiwhYzgod+EE0/yw5UsYQQFfpI0iJUpIaoWF9WiAo10MmMOCeWUBO/bdyS
###FVH8RkSRFbdkzlglBtFY8rT0UerlRok5crTMyM/CUbGeNpkp+VlkCoeZtdTiGfiG
###HimR+/JNEnUomo0/tidx0v5Ldx7llc0WSdePtAHPsv/iOz3+y5YHr1f235X9d2X/
###Xdl/V/bflf13Zf9d2X9/3/gvQiDSH/Ibr5GhGCUnHpfZH7Mo6AV5+zI1AoxFxFJi
###wNQHnQP+qsmrSuuaH73IMtgdaHDtQVhYSsAOeVtVgfTnPXZ6dXysBbTA/8VFyvu1
###80aLWwcvDPsz1GbPKpjGSI2xz+apj4mcHlV/+3H1vc3H1a8+sv+bm+7j6gv8l/Qw
###I3oLXT8MQM3jO2a734wbyzeDmfVzzGB2/e0cI7hr31tq56fBzPo5RpBdP9cIgsHj
###RpBVP88IMuvbRpCvhf2cM53dtBW9L5fSdI5e28HrWRo0DlpRzQbiYjF51cHGilcb
###QIhoNa/Oz2HzrR+qhhvkryrkUfuhP2x3m8EvfusupKnQ8pVkl/XmKLs5R9ntyoJD
###P68d/FC/5Jc+5sABxoA4HobhuQ/qESgLNzj3Fcy/MrPcPuP8c5HeNk7f1Y4bhy2U
###2jBnZj2rl6AZHF7+aOuXeLNv5leYux/QSqtZv7wEMWxGTw5eXaT0BN88vifQSs6e
###NAavQKs7qh+k9Cd+//heNU5fgWDcgsbydG5wwI+1Qtg/Kb+C0Tnt/T4DQGegZbVO
###r05aqOic1o+bj+wvNPUKWjw7ihpsgch/dpGr15IhZXY9KvQH7v9+OtZ/++51hsje
###7/Eug4Velbf7FPz9cYvoDP2rfwQtyCTXglnt9Ex2fbn25KT9V1wsbJ0eN4/CpQQA
###n2H/9UDCNfx/q9ve1sr+u7L/ruy/K/vvyv67sv+u7L8r++/v5v9LmxX5AV4HfVCB
###KVwo9whWcxuSvKT7+WqilGLhFSZiS5RvtP3OCkJNvq/1QXpk7wU8fdGn9YDnafbo
###kiYPrnx8ftA6uwDWgt4sUfzr2D9Qvci4KOgRYgfgbn2IHtlA06hPcTvHOegywnaR
###sI8XREusWEG3D++/3K2yWyrluqZJni4I/ucIvgFa8/rlqYcTfTDgpvrBgq7hsO5Q
###8b60hLcmZNxNW2+9ym7yLmjQCn8eY193k2glPFZaE/9uxEdjDCWtyvvW2/f5C0sA
###tiq2qJdI0OV9Hpe9BWJc8Bl0p9bbZxj6ksVaUt5aLy2ZSjcqmv+TtSmyM0R47/K1
###SuGxQcGThWREVXzLS/Ml4WFJ4YHq5QhPGcdgbPc7U3KzvZuyz+3+NI5sOLOuIAT0
###h6psVCpVIDL8626xNd7hBH52ZdsKDZnOa5bkw5Wqg2bCUjKzfZkAwltym8uYlVKc
###U12WigIy7lEkWT2068m0PwlG/QeMJOBubJHYDsr0XSiivWoxZC2jQY9Cmb9Vee3o
###P8x4rxphqK3upxGiWshCeYieLY481b06nnWsz774XL9R3dOp4XdvW+Jdq98eD4N2
###MV6QTswWY8wLx2xYc2d0iT8ZU1MDiFgNFKKPdyjymlMZETqz5VgreHygFExfLy/Z
###pkoUOiyDGGJ08ThGRodl6IAeF9MZxRJmt+1+LxH9V6lbNNmhYzB7FcEFPTL6jMHN
###no/EwJQ+J2bIOugwMbZsiom4smMZd77e2iiItK1IC4qyt9qnINqbrE7AkfN7fvSm
###k1eJu9bGBjZyMw24m2kA1JcyZnhpeJwyfRcM4ty4mmOxZDZ6UeGqnNgY6VWMDqWf
###yf1Jh72/x7RxfU3wL6IDLj+mIZO+2xlISM8OXjkKp7Ex2rgKPTxpAuU1p+PPwWdS
###hU24cQhyjQ8KKVlKyJK0r4HH01258wNdgDQ5pFcrGoIpeVXPwRkfwXwcpd//3GxI
###TMMstM9AfSVC/TzMxRbYHS2FyV4gYhWk8jTRPGSNFcvyTpSllzaaSeln9uWrr//6

###YaCT9v/rAAi/22r3J8vJ/jnT/l/Zqrpm/k9v013Z/1f2/5X9f2X/X9n/V/b/lf1/ ###Zf+f3/4PsuZSPmsFkhNB6FRlowXaWF5vjGCOJzUZznHulg7aAxCwKdVSCEy6/4BZ ###WB4oxRlvcaaNf7mje9y5jRF92xL3MkIV7N99ckCimC5GcGHtGCee9eLMIwUz/Kfq ###ma+FKpkfL7Pil6y9ArXwmWMHDcPWJvJD9eMyQdcyQBsBL9kHb17QmVlbm07qIZkR ###fDQ/3HwnV2YUWTU2aZSRdoHJzoFwSpKaRmahFga0SIIcSC7+Z39Qeny8GpS7un4K ###6LORT/FpKB0mrC6Q0VEQEj0KeuTjOfMuCoYEp10bt/MT1mgw2MBOmygwHLLiFLMH ###eszn61WmjqI5LlkG8ClxjhYMPmOooFqldcXJFr4di29u9MyVz2Amqx4Gc41NW6f+ ###DQIlqpcHOyjshqN+MCHJ9ssQU1zG1hUJgiztZarIr+OX2BNWuUeVsXp0dKQGCABu ###DBwLW1EauRKNaGZJpT2HuZtRnAFoZIrhsvVGXEtP3Hl74mb3xJ3Vkzg6wCdutv3E ###XiLFwhfDRIssXAytSQ2/YG9Br1Qtzzif0Eow+ADNrEkKVS77R1OYYpsWh2MCzCsF ###m7ztkmOkQ2zKWArNDy4GKciK+YJNRx2IiY2s2JuqtTdq1NorvQmO/dyVXynTQkMy ###BuPGVXOOws0YhWvtiGuOwrWOIqOyGIWnTIxu62xiNufI0vm2whdlezIlpqSQDIbh ###12glX8wNBQUYmcJ9+dLdLGHOOY6Ef0K7YVb+N0ya4LWqjzYDzor/4G26Zv63zS1v ###Zf9b2f9W9r+V/W9l/1vZ/1b2v5X97zf1/82RxS3KjvtdIcqERq6QmGfKljCNp7oC ###mcqWRudp1UE1a1YeHSGSFR9lFjFSsmyzj7+ZWcRMsNPrD0EH9NYowdTTaimrKzkc ###erOsb0YCHp7S6uPS7FBmiqy8CXpygDZ9iQH8QEQDbgzQG306IHsmkEnr7XbC3HGN ###2dizcvStK3T7MVF9Deq3RpOx6tgzesBWe/4YbTtxTsJwgto9DJO/tEbkvcYU9E1H ###AZn0wah6RsDaibAqfYZGr/vDzifaqCmYIF5KbwwMxArAX25Bhiwat4pj1Ek18y4Y ###FPn8OZl4MpVNMiyXzYRKRWH5A/nm7bNSwm/FnmKJPQEdV5kFhz2hadMeAXEnPcmi ###bFgt4AvA5upHzdbxW0cdptFv1R2K9zm20Cm9FdMOSIJvsYYuqA0exxDitwLjstC+ ###4fsb9QCTVQpxSYXJb70iFccmAG56MHolzBoZGOCppgzfO7Ntbl7gT524bXdm29WF ###2/Zmtr21cNvVmW1v8rbNCeF2E9xcnNhcQrYT2CJIRRJE3R6P2w/mjCHDX1+fL2qp ###7LsamnpOCnDzjvafbpYWp67NvKvij00Bkves77GqjgfJWcram68FxRiMtWy8ie/Q ###Zf1l/LYn9gBgWhUb0zohPNBORMot7Hfd4S5pw6zfBpFkJDY/k6dCwWv/JhgMUAFO ###bI5Wp0baJPkOoPDxj/l2zQgppu8lYXbstz+lOBjLrX3WaFDH5qcu0ht24N9PGFBQ ###37rlNxcfy9dVurnf2v5b89DJd1m+n7Ptv94m/M/w//Qq26v4Dyv778r+u7L/ruy/ ###K/vvyv67sv8u5v/JLz/heoK1O/nig3ivpDeyeTgiz+L31FCWhSYu/J+nwRgNXLe+ ###8CIkiR5KkksVG3DrXpr1DpqosVHgd/wvAfCLfjDw27BLjYBb3Ad8cwLeMgrpltnL ###8j50JyzC95LWxCUwN7+HKgh2A7oz7U9wdwQWzNqdDtfXqN+oDfL9B52QlCZ600FH ###8GVoJqoUEIY46/PbnVvBfL+pX2b8YtK+BoVA+mrGhlKxE3WDzwHOHu7Ft4jrIRnW ###0FKuhGK7w+0SeijN8K8ap5g5qtW8rJ83W1ygRdB8KFVUdKRT3GBI+etp54AJdbdZ ###GVq/8YqMbkqeNVvAz1rNv1P1kgoE7YPAAy5quD5NKNUKjeeN30enJ4l5kk94weLG ###RimdYC7H7UFIMggbDfsPg+EdbYO0nyB5DNZ6JaRC/N4r/deA6qFKBhtKMEASY/Hp ###gejZBNtsYXPppwdrIycz6ghj51F3FvJiFBlbutmp7jQwfMkV9+Rq5b+fkmUxJdbG ###J9jVdw0XM49czPYAdtLFLMpSgy/RAPAJ/pTLyZvCmP2lTCaU8h7/9dHUpUW5T3E5 ###zeGMXn3UghN8zUEpnCwUrPjodciZh4pxnQbUfHoKJWBdTgiIcRFlEBnGyNa+Q5Zs ###cc6ScRCSRTv6lDpRc3N6v9472XRTj5EyGkIthzwFl0qa/NroQsc2ePaQOF2551kR ###H6qeIFj4xoi2oCcfd2cDouxY23JI1Jzp5Aho20ykjoPmy8wlcufZmQx65/2IrY3v ###i4LgqbOOgMT9O/U+fFWDV9LAvhZmMadgEAjneuvEr7UJTbyAlfjOs16+dWxNywm3 ###8I/kJXZFVCDTH+38KCsMMWOiwqMFEs4/dLsfzYlw1SR+b2eWMN1jbazrnPgJlCkT ###ij7weUXuw/NgxU/XsaBlunhfslpZz9FKbEI8DFBVQ3Mx+8UfD0HaCNkXn922PwtF ###HVkboU9l6LDBx7FvfoGeAGQQb9r9L+0H+MPGQ77zv3UI69m8QzRRtjdxnmfbinBP ###SEebMPwxlsj5hxjRe2ImdnWcCgTuCQzvGriK9vmc27xqXU1u6+zcwSlSI9lYCr2V ###hb4KCfluNEXZUQlrhUu0CQoqVOuzozEIwP4AxOOQFUnCLPEefrkNQGXNvCnEt61G ###j4upaOuBOeDyZ284HXQdblYgVqJL4WN04x10vwRdUPj9+xF8h55NB5OgL8Kv3UCf ###/A3dUULsmLNdFLCYY3dRyIUI2hK3WLGysSEif7EPsJrz3FfhrMwqXp0MB8Ajs/Eq ###NmOElndPixLlZexrR6pwNdeVkfRwZxjvDEQxTOQLM41T3wpgL+r1xu1OciPsD2FT ###uYUq93dBN/H6AV8/4OuHu4DoZpwoA+uHUqYmXsDSpNhNKLLzUwcMP4EipJIUUCn/ ###ds7ya+f8YC35YhTvJE06SCO5BNgdLmvtKA2b4A7857vRA+4L/1Y0AsvWuG7RFYJk ###YsHTfsoEqQFbiBa97M1RAFyUVqNyDw5ITmrJ58Rm30YZf6lfmVLIOR8ZDkyRI+VV ###D5jeeK87OhiGl+1riqUlw3bs8g3FEwAf4vJJqRUkTSIXZUh4fId1XhqHd+SnMVFC ###tlCAI+gj7k00xju0afJcx9FRlhF+TM5MRUmRS/MyPzIi8Sr/+KIjYL6AoJq7a1vG ###wCHvyQA7HY/xYhTtd3J7Ns8C48Yq8zdG/36ydkRr5Xg4HEUntqJyYAWpVTsQNVBQ ###MDaBkNsvRqN+APxZNAm8IJ4cq88PNCp0Az9lPoDzZNDnp5g+tUmMK9knEfmVQqRS ###QvInsKVwCuyAhBQq2cvjFEtEzTAsjLmGgEBMx4FiKhPxdl95CyXL/LWptNLKwI7u ###Wc615XT3uFkJJ7mP+5t/3+5M+g9MnGT4KOjyMpIgtF3HaI5on+7Y9YfDT/opsZTC ###ogeycEpzfHJd3QvAerSdIIWkYi5zxuvGJRMsbVAoP3pb23pLJBXecQq+A16TZmiC ###t5ZAY/koMaJI2Ofsd7KQl65z4nJNPxEiS6WmnS5pCzUIcw4CzSBUBL3PKS1Jp/jy ###JX9pw42AfuHTgVNPiFsPNsjxko2lhQQa6P2D9X0qAUX8rzOm48XZvSBGntELev+Q ###+l4SWyKwJb2AGcYrqHe2af5qEHnSyy728zM6jxPH49Bdh3yOSkDN21tb1e00qq2R ###lI1LpktywgMnDwtWQALDEUOjZZyDZMeB5k29l8S7Z1Ah1XRb0m9ZFhFMCv1T1Dfo ###xJ/TOF6M93XRDwBZ9YqRBJkD3WkEhFbsIRsH4SfkmAl8XfudNp46I+IjFJVwiYgn ###9J3PhAW31l4T8jTcRC3PRGopi1Vy2UeKCtY7knfBoIV9SE2I/okH512X9CxD5Lnb ###KF4nOFAi/qoKnzMW01uQv15fV28sn0ZbjYXyZYPQXDeN3I9QPVVUVstcGK5U1p2m ###JkTrSPBPlwgjMfttPOQnSsr1+XaQbHlbGCYMmdsim0Z2KYxxrXSLx+D0ZrqbSVZK ###N/X7FnFQfj7B/FkGcG/yD8FOzcfRvp+YbLTdWI9yktMemH2I/AKhjfTjnoytDFUP ###fpgI0056PR38T8bTO9I98PgqbWNRFY/EsqOV30LPSopKjaEYu6ScllJ2GWnOcoUp ###MWlJtMP/lHI1WoRz/YRAHaWvKfC/Wp9yG7GN1VrlJky2+oLVRhg5ejQe3ox9kEw+ ###+308AEzai0Lp5DOewt8b9KKxYJoHePkiLExj4mVCbQYRifPhsh7C1q3AoIGzBsQ+ ###sWduRZjdMSJ0xd2SSm8C0CztPBEbf4banU/XzMcTKqn8YEF9VVNALKq5Za0srqan ###rZyKnR6z1Pf5kPpI5MxS7Gdr47nF2iyVf04wiSezjAFCsA/97F3ga8IxeeUA/Fv7 ###/4a3fr/fouwiS3ICnhH/Ycfd2TbiP1Q3V/nfVv6/K//flf/vyv935f+78v9d+f/+ ###jvnfSCAiljzeZaMpCNhlSm2EXEbEWIQVftsed7EMnUrZ3J06wztgr36LWgiL9jiL ###MnaCdEYQlbocbhgFbQC4H1OP/GUUBHm2z+/Gi6r888Fjayyzkb6IZiAbGUSuuTDp ###5zDvahADqxPmbv4YfyIc20cRxA8794kcj+Jfysn71xSHMp4WpUVBGDl+/Q7mSknx ###WhiFF+3BjV8fdBzVCQP9itGyALjqtidtjBAHTH069udzJIw0zVbnNuh3XcdwuKAJ ###ZYjDYIIkR1ctUfOl4iyisLxgHLtfhwWM1O40EHYwU4DzTBsw1w7Ia1sFwx/g5skX ###S7cX5nEXoYxhiQu3fNZaAbSCOW7iWYpx+UTpxweuecd6C3/cGvZ6oG+GHwDCR3Rb ###fKa63Nrop+ub9JMVB3XNmFm5ZBeY2DxgvNlgRLqUJBwBBvAKQ8xeDYe+vhoOlrwa ###/oXIVM6/NDVx9OpkS+h8FLEqkDwJacTKOvRdu5OH2cNKepMVZWmgMY7wI/KUOoBl ###CsASogFuCMsl3hJ5EBZEqbstNynNJY+PVLQ0P1dOu4mwZC69xrteybBeEQEhrBeg ###MgwGGAEYA4cblBtmu8VxMDAhzygrEf3yRNgG/qsqgk/wX5sflBMg6AQpE9Elgbmn ###JXHC1nxTPz4G4eiwftA6uqid1FvH9dPXl28o39+26jA2Gfs+qYOgpkttjQL66gJR ###hGtN2JHjlsOqKARuL+o5cZ3N7KJVJ67jZRfddOI6seOcJjfoG46cEpH+Ss5JHHzG ###XMjV3K16eqvVrFa93K26eqteVqvRadGsRit6o25Wo5V5GvW0Rt3sRnOP39PG7y5n ###/JtaV73ljH9ba7S6hPF7+virWeOfj6o2Nax6y8HqMw0Bm0vBqquT6taSqGpbG391 ###KeN39QWwvZzx66S6k90o7Pfxhs8l4GVs+KKlPGK03BFSd96zBXbeeeXdNDlj2fIv ###30HYLDkj1rYFii1b7Ww5Q5cldDmDyyC/u2Sh6VzsibHhKr9FGsd40qIdPT5eT9+M ###rWA8A4yXDibn7mwF4xpg3HQw+bZrK5SKAaWSDiXf/p0KxTOgVFOh5NnQU1HmGSir ###pqLMfQTKNo3BbKUOxnsEyrYNKDupUKqLoswzUOaloyynUJA6M5vGzGylzoz3iJl5 ###ZuDseSrONhefGddYMm76ktl6DDFvGyjbSUVZdXGUucbKdNNX5vYjUGYsGTd9ycwU ###PVb+F3/k/B/j4d1SPEBm5f/YgXdG/g+osPL/WPl/rPw/Vv4fK/+Plf/Hyv9j5f/x ###G/h/0L34ZMgF3FUajYunGKoYfbpHt7jxCDkJuRpZYTAF7uVw0u5TMOMXzN15zt4P ###x92QFatbz9irh4kfljIOG2cmGcF4IRQtjTrk3VO0blEQG0gkxrDmDqmwPfb82Y63 ###m7O8C+Wrz59VnrMyvw6xa+nJdCQqORRNTc1iMgvKdOS1bn9uVXjU8z32D0Dc5jbm ###03v+DP5Un1eeVSVo9nU3b3tu3N72s61Nh3lbO9vPHba1tbXpqe3hYE7ak377Wpi3 ###5GXl4aRza4vA8UJENXkFjX9wHVbZcDd3oL8YFacWP6vs4J9nz+Hxa7oZ8ry6S7dJ ###fym+Bkp55TBY+t5/YSJEd9uvlnZZ+z4Iix/waAzkR4eV3Qq2KmN/9YAUBpNe8S// ###OfmP7a7DtH/+c/AXDLAxHXSLr4peaQ3a3S7JJ+Va4lHRhYfVkvH0Nf7cKpXmmDbC ###Eg+0j6h+vl1Fg1x5ByQ/NMzteBXAOQOpfmdTIltQDu3ksKpISMCVlVhyeF+QC3Iq ###pcNycr0qX1nUU34f6v3ZxWGrBozrlNm7HsfDr7Y2eTz8DxTQowqzEWf9OIQNphVF ###Jq9Q0A8aW+HfQJ7dfr6JE1N9tr3jFP4NBljefM4NkNvCEOnu4N+yu0V/WXWr6vBi ###POSLu42/XbeCJMM8z6tsiYaqoiEmYsM8d3lDO9wy7j4Tzz3e4DPe4Ha1in/d58+9 ###Z6IhlzdUrgqIFe45AjX4X4/3tMrzNZefbxEgb2sbf7tbz2HGCjhVc+M1yjPA8erl ###xiume9xBvG5WoPM0ColPV/TS9YT/ixhV1SW0lHe2edbprWdU/rm3jXh1d3aqVdEQ ###J0TZECKSN7jJn3vPxG8xcc+2t/Dvpkt4xp4tig4XEKKgIw0VrooKHDjeCYPuVb2q ###nFBxNiIpZIuPpLy5LSZWokpSCv0uV10aSXlrkyYYEEDPt6rPqNzzChDCoiOr5hmZ ###p43M3SZKhJXhbntyZFVB82KEnvwr4yNtCVJ2xYhF+bJYbHyucCyivLb4gNIlpnj5 ###redU3916Rn+9bU4bVW/HXRgTm/NjwvO2OH/fqjyX5M74yMruplikFfFbjJAJ8vfE ###7+qO9rssIkqVdwTXqOyI35JmeHvec97ONuciIAh4gjYIU+7m9uI0sb0AJna2Njkm ###YHeW61WMzJUObzKtvKABsRrKgiGUq+J31dOeS4wyMfduRawOwTA8QUtVAa/6jLe/ ###6XGMbW5tPZYNinQrnBPKQXP69XaeI9jy9hZMlPDJ2tymZzB1sNDFM3eL+Bl75u1s ###8+7IDZTvn3RHcdTnurPcL0mJdZ8in6/Sv1v078bGBgOJAx+xF+JvcXN7/p00FgIQ ###Is5qC++PovVZzTMWzTm8VWf9H8iintPo+Zxs4xRUKzBU9tXh72lSgCyekxiEW6D3 ###fKeyKd+zLZpkz4M5K3tVJGoPURS95wxiC+eyXK0i8XsgmbjyfZkzhh3kpLDxbm0j ###Xp7vVKP3kkXC6ipvelX447neVgS//JyI5PmOR++R5FyA/0y8l8vvOU4eto/i4Raw ###9Pg9ER/t4eXq5jN87z7fqsTtEzHCLobj41vSs53nz6L3fJlvuzR+l0h5a+dZ3D++ ###NWwidwAmu4P1vefPCT9ARNn23/Pjg2Um/5hp/93cqor7f1vVCuzfW3+quMDBV/f/ ###Vvbflf13Zf9d2X9X9t+V/Xdl//197v/FT1AsUlM9n75q1S4vmScvEiVk5Te1ixMs ###0nrrbn3gpY2QvWgxq3qbqAJVXbcK4h8FYKlsoHgJ/24pEf0TzUN/WrD4DrHd+ulV ###7bLeeqeDouaxXZR+QUqMm98i0+ScrV/pzSud955vPnfNzqddgyQVApufjrrA34ux ###56BwGW3x1II2j82Es6bw0jzkNZlWU3VKlE0TRx/27U0fTMb91Ka1muhxuZs9Oijf ###8dv9P9jwnLzDmxVAO45qhEkhP3xMeOxiwGSQ6ILulA5EKHVkjLmCjiwKDDMvqtg8 ###qJIOslSzvB/iah4Fk87tcevtMzPYmShEjq4tfsOXx9GLPLC0Zsb+59fALniIfH6b ###iqJHY2Ql3FHMsP7pld35KpMnsOggZjipJIsMrltUihKgoK+3hvh/deqkGfzw0bE5 ###dsc0mZrmPSucUX8YTqzO28fDEHSXfvsm9TYhRpc6PogGFflcywDJvZgCw9anN79g ###HEt1TsVT9SqisZJ4ce0GYbL+ng5FS02AfaAR6kGUM7dbBQuv/QFP2N40kKwVy9Va ###gqEyQYkK1XCPdDUupBgZDCE8GExkWL/E/cj8I7qizYolV8cjRiQ2wMSAtGvKTxeR ###fMwOg1KDFJcdwn8hSP/CG7xxpaLqsePL85Zg1pug9Pp3o5b6aNdkHoHDflJycSBO ###+PUR7A/8EgRL32E5PlEWaXwvQ0zkqI1ETpkDSAMF7bmD5g+8IdLufKK4amF0E0O0 ###hLsLX4KXaHWJVnwA4m7HDzfC6B3vpjqa+E6wwpCSFfE6x+XfzkH4PAMF59CMuk5p ###Bii1VNx/ecJOaaaj2yxfboPOLc0CdADTtdD2LC75KMuH4kn8xONJ/MTWIs6m7oUv ###48UESKBt/oMsGO2IIgLqT5YwmDjin3BkZh1b+MKZYWAThJIMS0iDEpHxA+g+lib7 ###+S4GJbWCTba6vqcOG14dDP0evvnAitbRl2GQJUBhBI1hxA01h01yMIiaJOh9nXRs ###/TUQkLJ6UjOi0yLRRuVYgxw+SUOBFsIzBRuOgooS+2iHEBdJpi13bcnsozUuaTFN ###5JxNrzhjZnAAM25iwcSfkAgS+MNT1zyDMcagYTWuL0949DlVeQEZfeG9SKJlJDzQ ###6OMle9c6b1wevGm9rjVOW83L2sVl6wS+2ahL4bhhp933oZCxvBQePrkbGdMDT8zZ ###SAfu4I0RA/kRUKaH5YaGxe2Hu/Z90dg93GTs7QWYgG1KAvbRTBNj0L61jqOMo2Qb ###5lcz0nNi1vatiKv9mHfWNpc/axw4epOlzdrmv8isbdKsbWZxBnuMkBmcycY3ucaA ###h54IVONGy2A6JTNNWhNzx6FFATmHdBFTxT9jl0C5B4pjXGNHZa3nY78reiKvDYoR ###YWme+yqbD6oAYBQqEekbT0sham0YJPVgZt4bknNmjELaBhxtY8OnITcZJHcJugTm ###WcZR9ZTNScAwTAgWYUobt2JOMABnJnn8H2QQEyYHNo9BLJk7DTUHR0ZQU4OytW8c ###FnTvYdkjjV1Pey3+6zboTVzx10ukIRu3B91W6PtdB8PU3UmGtuXwN/HPYPC5dUO/ ###qpVEK6jU3zwAFP4FltYaVR9NxvAV02q3oH/4M1EVlxcVeOuK9S9+GX0FzPK+6juC ###8nrtFWcja/59h8ZvA7cW8tW/mXwLTYiaPLAc7hDNq1f6FfWPiTo1zjKwNDbNuVey ###GM4KL5XVHqbjRRwQE5edsFWwq40JVdFoW+EblQ+evOKvPa0kNhsLzxG3xLcl61Mb ###cPM14MoGEpYtjIjW4hbWdm+Clw0pOLiyXdp2Eo2xV5yIxSVfxyz7q5HzDuhreMcG ###Q0zGjlGkhgOMMhZnDm0i7dFog+EU3Q86gTicFqtWRpeICRCDf/Ff9piHXkrKaUVs ###sPBjuwChgJVSQzI7Q+0SU0Oo82PXrnBfp8y+fFawbSFZrDOe3MFk/GXKu71m3T9w ###O1WJhGI4cgFBSxRSsIyFa69JHCgJ51RzQmw2QIeA/vCLD7sq50syUVm00UpHD/LL ###aIc6BdxwU+VwrO0f4fSuFf4MWxPy0yJ7ErG+J5LTiq47qRuBDUFqZlY7CE+CwC8R ###o0pDth1EQcvwJNdnNATePCV8shTw5GZi5Ogi5I+5wabMUX8LuNQxr6h0cmdQmFVE ###XVK6RpIt4jIuWsjMTSWzMqOTyVdXR61m4+911NRT7busyWMifotem32et7exXAiM ###bzpir8nRZziDQ9H+p54hJ4Vs3r6+kcYF8XnTIpzyTrTRDUXkUNckVE1wgNa0420W ###5YIi5Iiz8TIeXemm+Hj4ymZgminTLYqauIK5UdIOwdkCPUrmyJwNTRyKLwItwjxX ###bEg6RkeoDZHh5tX7OmUfkRsRFlN5VJy0JkPvUTQbJ3GwCBDIU5mfL6rB/kBR6g/b ###3YTOFSWtxd1w0u582mCvg89+yMI7TJU18sfkcAdjYWrCHU27qcnuze7yLAtbxJSO ###8axKC0CokJdEfSIBZmKF8FxKhtlKpCPUViUtVbRjg47TIUcvch4zTFpzk/eC9gRj ###HOU9ziQ+zLLlJsYfsTiUHqrezo5jlikJJw/PzNySaCshlFjNGno1J12/Thg30tKN ###2aYLZ2o60OeKBAe6rIhEbksPpYjUoBe9FmqRQ5fRZM+qiZRjccnIkgLkHGDG8tDn ###ag8Cy7dmE7ZkHXY0ZWoSvosoZRsQM/b3+Oy112qcvqOOkHHsTeP1m9blm4t6E/Gq ###dtmwHqWAAwqZB9zx2fsYmtFkLoDSFqW/nTUyM0+gwc3tRPn+VRKMXjNJiSo/j1Rt ###bXOOnvJamneANcWraZVTrGyq5h/bYfqTEXLYSGwuRMuBp5NHPiLsJZJDpleHnQu7 ###WE7SY1m3+O8m475hs/usosm6WL8N/O8hDMIWv1ILEi9XlrH8RycSt4bTySsUecXj ###mrYuEr0k44dt0Wi6XHLoiplD4h/IqH7RrFe91uf2+G2WPrsZOePY2rnDta2+iFNe ###QtuY8nJ/P3Ykirg9jnc9MRSpG9qmOLEdxDYFxZgsadroEUd9nK8vkkZmeTA8XePo ###fBiAjhVyN3300o4TBM9uw1SPTVNiQlmOxVOZRVNh1arhCeX2GA3aSuEkvW6eWO1m ###aORJW6h1C8ZD+sF42O/DoqfkZsY+IpPnoof9hFzEEVttdh2AKiLzwYrJOq7BZJVY ###u/+l/RDya9kkdZWDQc9sVzWjcf+ujLdq+9o7R0OgDCIoBAhLRsdF2y27SrvuEtv1

###lHa9JbZbVdqtLrHdTaXdzWS7aml0XDJJKfKtQrFFMU5Z5THch+T+UsN9JX5sgOW7 ###gbYnKlZjD7Y99iTWZE9qzR+M4zT7qvuob+GR1GDHlFS/I/ZvSp9KgG8NsACn5m/9 ###qgnxr8dtNLyDWjXm8iEyMVPo011LNNHb5iUi5vCnGSd3hsVdqYWSxJbdMmbrsjLZ ###Zs/tknwuiTsp3GxpohPy3v7wC3QjkDnRuWcOslOVDaecI8qZTko0ySf8/PbwAgWh ###o9oBJVVNOiAkQEjxN9lg+kkmmtw5uOPa69ZJ0zF8LpNmSxzvvLLaXNsqrOdHbavq ###oYe+EaaJT4njDNkXvMzHO6SKTZoar0KLkBc9JNOo3vyMA0lNiEyIdPt73CMBO9e5 ###9TufuDV3SvsuYunLcPwpUsBTtnLVoTu5lUPLo/Z4AoQ+lbu57gO69E1cPRVLHqeY ###1hstt7OtasRTtcM2dZ7MAyz09iqLMMG1KAvwN4PjKXDcbwinqsDxviGcTQVO9RvC ###2VLgbH5DONsKnK1vCGdHgbP9DeE8U+DsfEM4zxU4z74dHB6rWMB5rsOJRBdXyC5J ###TdImwiyzez9xj9qohz/pPdTlsVq3S5JuwK8+AHNMF2dngY7Er9rhoSpnzqrmGEPc ###TMg9ZD0gQ+FrU1QkN48856/Js1gpN2gnsDl6q5+tusrZKkv3mErfwK1b9hO9H5aN ###E3sy18b+NO9dAstVizD1tsLcLZuWOGF7MyxztjOyqJTulGIKGYiU01foTHJksdVb ###HHw58YBYqafeet2fwrjFgZBhrx74X9jNcNgFlaAT+J+1kwfd3eoGWuH+FeFSXK66 ###GS5Xj7yKZbuJNddVLE6XyatY4gVe6VdBpLpc8fNgfiKf4v2UfZ1jxm0Oy5mUIYAe ###tPudaR8xLM6m8ZpHRAmR+5h5m8j0JRBUjDVbvCHH9pCXF/enHGZ4ECjLAV0phLMO ###3QqDbSblyFQZIt01M2tabGfxmKPxwag5vXXlzAU97s8hnD7oDD+cmEaPDMcKR36Z ###PWjRr1M8yewDZ+NzEejne3KwaqNsn6UhOcsPWCmc4lSlTaTWbDkDonH0Fztta8Ve ###ztdnez9l31KbKrPMviWQf9Tu+iJCiATZDXo9f+zj2XLqPFhnwDoOZWVTFKu3GCLr ###+O+7WQVvImfcsD8c4Vawbbnqcfx3iZ2D478rZgmtR7v2avBPWa6tfJRynEEp0JoF ###UPYMagd83iYe+PzdoXNz27UWiTrDh97WmdilXj5xUxqVaLZ7or+9uGzVzs8vzn4s ###xuBLSpJAjSHIedI6SMfb4sSS/AnKytTqrloGWZ60P/m8UbZ5D3uh72NeJvSKoN2X ###QrcMbthwgLk8GTk2ssPLH02CtXYtGqZ8IYydSaQbgkfW2YRVXtUOhuKRK2Uso9dm ###Zn1PXQK2orgmo+L7Cq7t/Uu5SGf3W0g++WoxoabuXUqq01X+j1n5P26/efy3ynZ1 ###azuR/8PdXMV/W8V/W8V/W8V/W8V/W8V/W8V/W8V/Wyj+2wADwEV+z3Fw4ouzE4wF ###J2K5pRaQIeRYq9UZ9ach/leADQnYCvvu4LvCPyyh4yawwUEdPXpcLFRxk1GoxZJL ###D5Ovf9xnM6u4RhVvc2YVz6hS3bZU0aI5Jz7PZmcnEVjLmaRkd77y7pxJSXI2ruUm ###2Z2zlitqLSXnxaw+Pya7xW7epudP8JC7aSNZAn5mJEyYo+lq3qa9uZve/HZNb3+r ###plMD1C8YXn5jY0PGlc+/tOYMHb9rZ8VfY/5Lf+noK4WZY+dW+v5s/f+0+bbV9SmD ###+5LiwGfq/6676W17Rvz3qre5yv+50v9X+v9K/1/p/yv9f6X/r/T/3yf+e0Fo80x4 ###evwjGciF+0t9sEeSWWcoTmEZvDaRGg7mAv2N0LPmAzsEymzCjLcO68eA4WTZt9z/ ###Cz8zy/74M+9bnrLn3BEO787PLNu8bdPh32aO/oa1C0/B0JvaeT09hg7GCjpq1S6S ###sX8QauSmZTxsDIKkw87FIQ8E+JUpEq0wv+zOnti3cRhBS6PG4/ufrR1OHwr55oe3 ###I3s1wI4IOyG7z9WmuPdpkbYG4c/xUMlfjfvRcR8wrpRRQX+geoKtjcL6oHPg2AJa ###w6fOC7Om3W0sEX4Le6E4iq3BCNICpchw3FCEhRnNKyCS08nd6/qHfsfwMNNAQIn2 ###A+zKUC8IAx7BwHQxFCB07bVKFq/71tuqrXkVUY3BCPZ2kGzeVmeNQm+cf+5hzmh1 ###20dxFoOguRXikPuUvFMRqltJHwX3zqObnzNGceGX+aVhgBDfncX2K3lGIe6dbGWN ###Im4WhLzOLYqGYkgBjW+GCyBdynRY5iiaMkTQYHp3DcSbYy7UVwMi9lAQzaGgGUcD ###ccpbBpkR6BHpykJS1rmIrxAqN7Gso4gRhSVlsmmWl2iVSIGqfyo68UYg8nwyRiHd ###WRPtK6M4j26MLQSCOwG2kGU7qdPNHQWxzCIgJFOg+U4BIYkAZztRiGmpQZ7OGa79 ###lOJUhLitop16MAl+AcJCdXY4UKJdzRemPT08O4XFaBG4VgROMtXi3Iz8GzPxBRi4 ###lWlEMVic5VJQtD9YOfcCy0w2/Ex1AcRA6GGyfclRF2he9de+/9m+Kzyi+Tx7gpxa ###ZHMi13oqAWU03+WUEd2OkFBk87RB8lV7PUU30rxTy1HUphst6VPbvB2OJww6f6de ###auFhrnM0f03icXrzx0Ng+9mtZzUPIiiXNA3xJdrFIt7DTVVau7OXFcUkzdiH5+D9 ###tql90x7fkbpx1Lg4x0wHXb5bPmJZqa8ugegs2288tSO/MxkjW4CC8/ceNAAh5TvL ###Ygpq83F44KXxHM0nuX133W3z21HfoPlhrxf6k2/WvMzclC2s226P5NtOUmTQJcmf ###Yj2CLnjG7/8meA5fr3jJS3BOflU6X/OCk6Q2fx5zmrTWs5r/0h5j7xK0uaSpTRPO ###k4K5EBH4jRIuNUzGvp/d/FoI2nYcXdlCOV3/Ho3AA58CSXLtnFvQaXsJM5tPkzXn ###RA7KmbFIpwhUM5R9ftHLpu9nauizjAAZBoCoSIYhYFGZUoBtBl2/MegNGzxDjXmt ###TTx2coN9y6VifiphaTRDEIy1+XSDQepmOfb5cos0Yf12XIaAOEtQZBnSnRgtnmJR ###vp3QnrfLJl3Ijx5bX0a1Vgx9zvxyUw6wKdlI1mzqaF55KgdYbtOsGlrvmt3EKfjS ###LDkrQztNCEMyJYVd7U6RHu2gc4CVQlIGtLkFpxwLKBaeZgOOR/uF9cb+z1PgeQ+W ###EecAm2UzSQOrsYtw4o/oTvRcSM6yo8yUrcO5DR6zZLxMAyGw46d4AgvLl++o7a4P ###0tw8YLXonvnAzrKF2S/2xleSHPbJ4eoKtDKe8M39uHnU4n5OQ+7o1OpRkffBYABb ###ZjDoOkxkuEjXgMJJKyQDPc/GoEkP2m6/a+cs/7YmAh1G6Q1ipW03VWdfG93/vDtb ###5c5MMWBrl0cHJO/RHDVnK2u7OTSA9DYvDu+4Vu9IdSejcGRBz5XYIcuEkHYKlmm4 ###IqhQHP47wBREl/VmVj28b39ohOCWYWpRYQYJk3LnyRDQw4HvsOFnf4zuAhjhfiKM ###hKKOWHc8UhUAxNtvN7Axf7bFWKL32HQruqf35z0euFN2CM/VAn4HuptiezMiS0TZ ###R/sUSICipKOkWd63i+xK8AgLgkpamEwtYmRWo8kAkojnBFsRd/T5xH1SQ0Fi8fJ+ ###U0aJkMVlRgQhDooSGBivaquL2FOitMvHZlF+pKiAqZglomNEWYKmLuSPtUNEpQPx ###CS1PSSzqxMeOHyIsJuKCuSoyzKAhh3HMEEe2qvw0D7vTo4NkARBnxhJA9FMhlvhx ###IgBKzFbi+LrqDt06owIhX+jKhCp5LSlK60ftLVnKeVUqIrO0KOyekygsnYBURFBA ###h/2uqiKiX0JSB9wzAsjrrCdeRNZUD3hdPhGKvE/J9shTSj+1AJ6C6Q/Q56nN/coS ###4fx4EAcbUjJil6cu0dSorrPRoL11IgkJ04oYgYjV5NxKTGZbeAoc6L4RCX7urvDw ###yHm6ULCh9BSkDvJOG3HlxUPM6jny7HKJcn3ZHFtqBTcl34SIpUuh6UggInvJ9FoP ###pA8yhkUkA95JS/D+51Q2Eu97Ct9R41bbapl1ZHnJRNPryLxklRk7Rio5kgQWjU5X ###Z4vE+3ngZvYrxQ4opyG8RIlLrJmijPwdAEZTXz/puVijj1I7FguxdqSF4udTmvqp ###B7VSTxqVpLxmSBkpJVg0Tlx++3tMi91uF/xwiKkfLfyEHYwR7jUFyK9GAIVivNGU ###cgFxKezpthZsgUhwzIOnGytvYRYpZuCdJqzp4UUVFpeMSBP5ZShhQdUOIY0+gX+r ###QJwaRtJ0HJ7kp5TMjKG2+glfe6mRG57SJaD6JaOtCkYs966mLeqF3K8wj9MX0rDS ###SkVivwhSz8U0kGU2VB8s8xNrbckky4n4Ga6MDpotTGbF1VBjHvEeBlEPoel4EFkN ###pA83mDFc67CD9LJfC/mfJoOoPh5NAaoYSmdnYcWK1nWUxJMx9TfTopZY+Zq1ZZOr ###5UVfGplTGN1egKbUkdxfiVOE3DVcrABu04BdeDidoMkX3eb7w8FNmax26rF4mLZa ###SMHRFBoFyx/tI9LNFijxqILsus1wMYtG9CozSSLRg6L5iOcBe2IIxJb44xYLONIc ###NKDLdVq8xmclazhn1ECEl63RnY+2xMgaaBSIZkBNz9InujCbipW8fdBX6eWb7Kxi ###yhTxIlVtyfaxqIl2Cc4coozEmVA/zV7tzrOIDKluRg0130kUL7GWzDcetS7NgKmy ###pZIJhb82zk3tCVFSuU4McF+xtCSKZ+VLiZvArCmREB4/XidJ0KoxpmS0j5KspGBA ###sZamocE2lKQUny3BJ+oa4pebN+d9qhM0k8eedA4Zm6nwpM6JbIc8PYoTGVDRbKyn ###aMjcCR3TrzNahFKDdeyio2Eq1nCaw2vPHFQKjHiUnE06yLOUwRo6sWYUjfLxCCt1 ###rI0Iu3qas058gEQCt3qw88mkSoVn8cLKAYXqMWKjcGGqX19XXht+FNaZTHhDyBea ###H8OseX+SYfjXZhPpDf6s71kHoZjyaIZylOM6emY5Iw2uLnznE7ZtwnWkZ7uLWWZ1 ###4flTPuHZ3t1PKcKy1u1PKQaabyqt5ZHOTLPynmFJlpnD5pbZ5OLVIz5imEYtjbxu ###HpGxvLcTiarySXpLkux+Q0lu+ZLb3JIap/VE4pHfSiT7mowRbpj3n+jm/w9pUsb8 ###5wAWqJHN3zwSiJN+q8/1tKB6EPHY59w8NomwY1zVUg/PYpuntM7YV8uuHn3958in ###Jhz5fufWSB8OxQ7rr65et5qXZxf1Fl4FxdConY1R504R7OwC08d4M9Jis6flSzWP ###6e6Gn32BZ9z8408sUCY3STMKfIq8mJ6zNaUHKmnLkdsPqhbugSS1r6ubGaubGaub ###GaubGaubGaubGaubGaubGaubGaubGd/gZobNCzVw2E/kgap6lnJLhvzavudfdf3M ###4rMomuBpiRCPljJKatVNLdUV/BoIZQe/iSyRlhbg3ZFIEspZwVj+7bryi8e/KE6a ###fBx2L82foR4U+VlU/1nUFsEuHDXyhSOCamR6fU7uRq6D/3powUz6w2mF19TUug6Q ###EpSMf42kVhu7a2pBN1AIbtIDEajF5ur5IU4pbRGjhbtnSvPwttm0OWqmeE6qJwjK ###UGLfnHwmA54V+03t4kR4jmDYxcvaeVPNj52SY3vrg8XIn5loOzJzsNgzT7pnxFtm ###7IqRN9cFLNBzf0xxyzpDUC5BChNphSgQGQXtAh7Q7vcVm4Ba+ziy4CmSnHJkhHbK ###ubw8fu+U4JuZKcE3M1JWb9pTgl/nSQk+V7s8Jfh1npTg87XrKe16S2y3qrRbXWK7 ###m0q7m/najVx7tHbRATHzHgU6jpX3GTZkkI6Zdzyykpt+hpYeVdLSPMarSioxxpJK ###c8ZEI9rD3Z0/GQd4lEXaRTJisjGEaC8zc9zI7JCUFjJmlR84YWtPyh4/J0/xNTNm ###xgIRphumJXphNu+mXelZGOLVKyXppU4OSi88gzKIFrwUWlC6PJMU1A7Z6cB0xcx7 ###NCStpFbbUoJ8E0csVhc6voOnNdFskj1Y2+atzbzGHFbYRJdHnbR0JjrG4XtcLT6Q ###4LcGko2ec3/caLMKrbYLPG6yLCYOVogwAhGaqd5ikkerNZ0R7CbQhKCztsOkP5Xh ###ELBHCbt//dX6Ytuk6m+2HypSbyK3nqlnuQm+a6ltyY5LRxQRnjlPaVuzaS/cKGcb ###bWvq7MUb9ZRGvWU1WlUarS6r0U2l0c1lNbqlNLq1rEa3lUa3l9XojtLozrIafaY0 ###+mxZjT5XGn2ebJRO++0MweImuOBSURegW7Fns1uwaW0ZukttWl2MrrfUptUl6VaX ###2rS6MN3NpTatLk/Xsj6/ziTXSEbWgGxmysiRbFRRZKNkatj4TLAHu/k1iGuZu2PR ###NBqyJ+T+wB3vd3mrnVsfmqHo4dyih8HPP/sDi/J4xl1Phj28yzUCKCz0rXs0mkZM ###nCtYrvBTVPUcXTxUzISWzTqGDxr1DPhuEr4FnvnQpTte3LKT0RdLWwAOq5lis7hB ###aQgBCVuumxS49ZpyFLEJjXdSOcuxbfukDA1HdHvXRFpCkSGJ+SdS4OHPS7OX+HA9 ###7U7GPLOTTiE6Vn+S7kDJF+s02LKwxGXMlG22RLt8xixpb3Ph3tVxL9u0J3CdFzXu ###bNSs2wkYX+QkYjtq1lOJeVGy/GkWEzU7YTKt9NlaZKbsrZuKkdmyZOpxy+5Mhq4x ###dpczdi9pPZg1BMNTKHZrTXRAaNczICSH4s03FC9tj5KWe9MQkvAE085TdNdc2ZW0 ###sZgQIsPHUQq2kk3PwJYOIcaWhLAsbFGkA2QLd8FgGqoaLyYZYuSSE+/zmUdiSpNo ###KL/n6ZTLkV0GvwppBBY4Tjz9QUKiL8dH/M/lOcvaSoUtSzvGObJSYgY+NrOEhQhC ###ZEHSJKyZYIStMUscuHqFEDibohd5ZzMvBN0blDOgzTmgCDnQJJex6k0rRsFdjHCy ###5xsL0okfBt1pu8/88Xg4tkJEp+1+MKIDCNb1R5iugNKMp9ifgh7TjE0vU653ypGU ###x0mv6a/pY6bkF5QgXpwHlotVnuC7UnJYtcK/2kxc5Ho++TKUnnQ8XlIfpNw+67Rh ###VF06m0Eb153fDqdjyjsTjBka28pKxCFjwPxA0ZiTsXlnwNz86DTSlAjl2WSyOCqv ###vMp+Cj5FN4x+aNxLnIByR9+3V7XTy9Zx/V39GBbc/75qXtq6aWlZrE7Z1/QhUl0v ###q65b8aw3J8UZr7qDvHoVV4sdUOyVPWtlb1ZlYWKOUZ16NTnGiBlEaM6xl+eYhj8O ###UsquHSteLqxY6VR2ZFlYKT8KLfnx8g+DyXAcvUQUWYR6+0r6l1qjj0N8OQfi9b1h ###bKMmwX0FUowGjI5H2riUJLEfsZOJ5n1Cl1iTDWb2wbP3wcvRBy+7D4kNQo7sZdS+ ###bZniUZN6v8qYdzUwVORtY9casR03bztedjvYn7cSj3ziskDGRT2L+GA7K1xg6N6S ###hu7OM3Qv/9Bdm+SU8AXRbqPg3YFrdE7ThCCLzBdHZfXvO8GkbZN8hLeUriRxBGjj ###cpLxEfJKiTGIcpSVKHu8tW5X0aJC26mc0W8xa7EjmOpgYPSb+4Ux1YVIVNfcxwx9 ###ZcakmNZb/ZZQfAVIE/p/1r3pksZJOQWqK5YpHWqQNE0upTEtHNweS4sDZ1RScA6V ###tBRT9hoqmlGVFSmuZtN26GMKyN+MxN3fhsRXNJ5B4+4yadxdhMbduWncTadxC2fT ###DWV0oVV/lHWfNeUORoqvcppdyXKndi3r+u+s7qhd0CsO+12lN4anZErsJv1OtuZC ###U0HHWFvkprRoTeal8nk8hviFctOFR5M4ZsVlit9a3YGyo1Cl3TZPDVlB09AZUzLj ###i0P2ud2f8jy0/v0oQDthcvUm3L+1e/Dq3fINJbNkeiCWx3hoWS7wp4NUwj8pnU+R ###kLOm0BT2sgo7eYNF2Zpx54Hpzg/TCEqVOWhbeKo0kuKrdDgOKR1hL8AvoH/yHNc+ ###fyo2anysL2Tuv8/mWMlZS6aio2bXgJRY/dGdiOUxBUBILwUhljh6s6ZBQVEK+0hF ###4Ez2oeLkU5bWLYeUPZlZQ3KXyBHd7CFF85mTIV74o34bM7LL3JM9Pk6Kw6GMFENw ###cLf/cMbcIhLiUbzMmEItFIEWTZKtlRT/0nimPkIb6yxw0uN2ZTcjsCObyY6IXWaB ###9YJ7IqqXNo4nxqQpnRcOGJYSsl8f+OG/2i397kpJj3urzuR7ilQuhQk1jsrc8e7y ###xrijqxoUlgHt9L/+CggDzmmKRvqkR4FGfpOIcd8kSNxc4UYS0e4TO3UyDsmjYpEs ###EBouvmRkAa8GBk6HpeS0Tof1NSXSigChesAn4OPLQh6F6zEiljV6ve2THtE+8m/P ###3Yx127I5XxnR6e0NIuxEkBXD7STLVT0OZYPtmHpa3IiS8NxwbUh0Jr0RJcP6rEbe ###Jre8BOWlt2GxZwCSVAXftTu8pXtwJHqYzDRuuaUwix5iwbc1/Nzrf1GNKg6zssQI ###O5wB2sehqApZ40imTlCa0NMnZJGfKaDECz+Z/CNz7vUbqV+NoEN471tnAIsu/pRL ###LdYd3szMkLgA8ojoTF8xcM4q5fwq5fwq5XzmKFYp59kq5XxuEMtMOZ8n7Vl67itK ###ANXu/sRv3wcDmRKq6qq/vGq+TFYazuOgeVwlE9uXCkPKF43Td/WLZh1kjM/t8Vuh ###84CaqgWqFK2IpA2bO1pcOWlH01o3k1odiMAAPg2bwbCn4eTOB6T12p3JcKxmwUkC ###xuYsmbPUXVvFJibAoK4dNt5FA0vWd+xDjDzFE6fpBgzufbedSPSCK12wNzkqZTrt ###fpL69D9LCwBqjTSbiMsQ52Pj8rumpNL2xn0mtW6VEuPAeIpQxB+HYtbUiI76TOxZ ###UBlPfq2HtgURWJryaGAGJGXHCdl0UOb7Agi2Q75F8E0v7iOAUYgkGavaDHAropjv ###2S+6Hw6pA93hl4FkuKYFz7JajnV/Fe7frc+dnmOxZGRT+arrpoGWI0wP5mEGOScC ###SBS2x/vXFybUS+QTLKWp/SbJJAbII6IH+rUGM6xvjRY4nUx3btuDG8SvSkM4Qdpy ###+nO0nswQI3w99RNBDRLXyS0Y1Y0jKXHQDcQqdezItZhjLOtMZ+8pdVIteOagFff4 ###xLjjKCm0c5phUp48sQV2ty2LJZGkaRpKT0mRTnUJBOpF85zHPNr4kyOwAc0SrvZ2 ###Wq4Q01yTOUizcCkVpDVUgBqlwN4bcz9JKqXpk2WqtjOnzFYh06fR7J0lsdbM7kXX ###qPJ2T6swV/f0U/5ZPVNsUzm7ZtRIvb+m2KVytmzUyFhN0hDxp9VniR9UB8rjXmd7 ###x91+irP1lOT1lh9OWpP2dd8PNzqPhVGBz/b2Jv2Fj/l3x93a/pPrVdzNbbdaqe78 ###Cb7B1z+xfypEmoP7J/nMEbQ681PA7Anj4OZ2woqdEvNgxsswpR5r1C+P2OUYRTDc ###FJqfUC44xuykfneD1fp9RrVCvAfljz/Dw0Lh8hbk8F7QJ3ncv5+MQTGj1KbDO3Zx ###dIC0usHO++QyE/o+vzMPL0jIa3e7Ae5B7X4hGODRMDkVQqsXPl4gGgfX02iLwrAy ###eHY+nI7xtBmP04NBe/zA6EjZ4XI/tIl/h9NJ4W7YDXpBh1p0WHvssxFsfMEEezca ###Dz8HXfhCvUG1ojfs94dfeOjeAe9UWMBKd/7kRaHM9A6Rz4/oCdo+2R3ibOxPUFbF ###5trXw8/4SuJ5MJwEHd8pTBBb/SCka80xJBqO3g0A1+m3gzt/vGEBjzEy49FL8CMK ###x+PbelAQPWCL9IDxURW6w84Ute+2nJSnGFqdbrXdYX7rAPNvRLilCaGstkrXcTCn ###Pr8Jh+8GaIKDnlCG1YE/Yc1hJ/AnDw4nRmg/JkoH0Ei1CgPKm4tzMAKBDGYZR8Jh ###DMdAC3cYotrn0ZkmQ+YPukNUR6E29O5uOPELHFVAyl3o9mdJsISccNibfMGpF5QU ###AxmNAySwMRLRoEDkFIY0qMs3jSZrnh1dvq9d1Bl8P784e9c4BDn61d/Y5Zs6Ozg7 ###/9tF4/WbS/bm7BgkkiarnR7C09PLi8arq8szePD//vv/1JpQ9//99/8t4Mva6d9Y ###/cfzi3qzyc4uWOPk/LgBDQKEi9rpZaPeBBydHhxfHTZOXzsMGmGnZ5eMLvxBscsz ###BwEXktXY2RE7qV8cvIGftVeN48bl36gzR43LU4R1BMBq7Lx2cdk4uDquXbDzq4vz ###s2a9gEM7bDQPjmuNk/rhBkAHiKz+rn56yUDgOj42Rnr2/hQkfmhNG+areuG4UXt1 ###XOeAYJCHjYv6wSWOJv52AMiD7h07rHkOAhN+qf9Yh7HULv7mQJsFaLNZf3sFheAl ###O6yd1F7D0IozMALTcnB1UT/BLp8dFZpXr5qXjcuryzp7fXZ2SHhu1i/egQbU3GXH ###Z01C1lWz7jBM+oCAsQnAFLyG76+umg3EWaFxelm/uLg6vwTBrgRT/B6wAuOuQdVD ###Qu7ZKQ0VEHR28TdsFHFAuHfY+zd1eA4zfFogTNUQBU3A2MGlWgzgAQIvlTGy0/rr ###48br+ulBHd+eYSvvG816CaYKZEwo0OBg39cA5hUOmaYIesW/KkTr0ESyxhGrHb5r ###YLd54QJMfbMhyAQeNa8O3gh0bxSWtCE9LRS+D3pdv8fe1N7VW4CEo8br1ht4OOj0 ###p8Bev4Pl3QtuNm6/K3yPF2p7BeUdaq9Ql15GD2PJCF4FAxCN4HVBN+0+4yLvwSsM

###oBfikdSN77XcSusu/MBAfdBM1phQ+CM9hkcHr35oYiDZ13Usf9JE+VmYdf+Bh6gO ###q3x1op/4BKTh3Tzwq1nwmaUD1UQHmADplF35r+eUPflv1SlXZeeY6KxSzlXK4b8Z ###HT9u36Br6I2fs+ue2sty1WE7sh8IaScvirwkBOvE1H+8NOaFhsf/HyFJjl+Zr+ht ###RSkmvhvTai2jFeMIjbAcFaNu5KaKXEOukveqPuRoapUvgi4kRYgvVeonUodT3qQv ###GIAJ/1/ectiWU96mL/DvDv4LT9gzp/w8HSHK/8vKwI3+qESqUmtMsF7Uscw5UkjZ ###WAHip6dRuUru4ktVwOV0b4FlXSqu7J4XtyDwViW8cUxui3/xCUcd4ROR+XyONfaB ###NRvHP7QENRycwY5Y/1GEr7ESibroMLAR0BQlkffb484tCeEg7slDUB7qHcCwzvWn ###yAwU2yb+AT1+9tVRfrvOdubvTcetCHuAk9GHu6Db7fv5u7GNzapwvBn92MrZj/Z9 ###/k48d1xPA1J1doxO6b93HLcaGUfSZnxw3QKALd6pMMe0y9m1sIPGqZP66jD1Ve1H ###7N3K3vLHt/80g5vz8bDTOmr8uHG7NNNIqv3HdSvVzR2y/2xVK972ztafKm7V83ZW ###9p+V/Wdl/1nZf1b2n5X9Z2X/Wdl/FrL/DNAARGJus/EaJwrFGrQCcQuO7ZU0G7FW ###q4Px//C/AmxCwErYdwffgWAszUVP12QzJGSf1A4uzkCOvgI6WHuq38OPmAYeqbH3 ###J2fnTWAv08FEePvoHUJ5nM6Y8bRZPQ9V80JSw6hb8GDBwLjIlQkqtGHvewgD4uhh ###53Y6xnD5wIo/ee1iiUOTNq2X4aTbD643bvfzhKqj7fU65I2obYxhGHO0ceffhf6k ###WHKY8F7n3ygnrN623RAHogLdThkL/8NQf33X7oyH3DhXeLocWoKOWz5AOKfAKJB4 ###YMHi2ji6Oj3A9dq0+2kuqTfQzp8LDO+Nw0bb7ge/+E9ReuJSR4Qc4Z5Dk8ZuAowk ###PWoHRCnkEvhUXL+j4kiHGGQvLED7kRsp0XWM7QDgKTlo1WmAqlGaq2a6Q/yF0bl5 ###Phn+3/JzFLbe/AIvnVRHeW2wrPjml9JSQQNKLVnpziyIzgs7w19c8QapDzop1wN6 ###zH3BxNWLXbxIW3mBPlHDbop/uuFYvBsRWzR1L1Aw+uyPxXVcSoOsjQwYXXtAIlyB ###pVPTH4aQdKbKPzCPibsE8iKBnE3u/c0WAW27JhE7e1pTCas0vAjkPDQcDI6BSdhB ###xxcPgngh+WFe0JKQ0N31y4BXZt498v1uMOyMKbl2P5g8IP+JLxfFlIHusV5x5hCy ###aIbfJfrsk5c3t2Iuk2bW9MWfQTN0GSs39Bw0s6azvHSa+cB6/eFwXAT4T73SzC78 ###MWiGaURz/QDbmXDV955WHbI15yGeVnWp5LP9O5IPn0RvjZD/tJo5kcslHz7dH/+Z ###WA5ebuQhI7ikXLs4qYkoA7v0EgiILAdtNIAAJXVBCAWtH1X9kN0N0cozRh9dX8s+ ###h1U7UAWq4TFDEZvpP5TY5/b4QabrVsqqhMmhtNr9SfFRcyPxsrSdSJ+htVett96z ###lAzQgEMtF9+H6sdlgq5lgK4ZaQA/eB+XuAlmsQCDB3gf2W/GAmSwjEUmOwfCYUNI ###JzMBU9wgLpJl8Nqn5DSl+UZtK4LqY9dPAX024on2hnjbFFZs32+jZU30CMRZ9AOY ###wQLYu/Y4IMWbMwAgXcVVnYdd5/xgQ1+n6OstlekWL1FcIh9fuuiYm49/A9Cv0tO5 ###6/hWl65DaRk+0LR8/Bak29Qod+mrpptxGfgoLTn7PLsXO7gNxiNWvIZN5kvQhTH4 ###9yP4XmLH58gHRbAcfXf5wsvkItb22EljdnHzoNDhcuetdllRGrFhMVIiArc0x7XX ###CHdOOu6O+Xxhmp7xgsSaxeI7iFS665UEzREu5Mvi5GEUdNr9/oM4rmDkN8EqiBLr ###qJcxbZhaYfY2tZq5rJmj0ATbiyy44R0wyvi6KYwEbaoKA8NrLA4ZVDPbg7YmFJuN ###N6BJLHgSFNL1ClbEnOSjIcq1ODnQ7+kgmLBOMO70/ZJoS0FJtDGJDvL4r9inonXP ###ufAn0zGd7vHxGANBRGEy25sH1h3e0cjeVivzMP4apuizSmrnizL9nHRoY61J0PMz ###4JgYjoiSZIANb1PgKPeUgBC7WUyKAY+Zk7zC86ZdeE6Zk5nT8fgpedScxFPSHIGi ###H8l/A8omg3c88bC4y5DhhqC4IW+jOIBlDkpme+NsMdQ5L4h4JN21oPanlltcor58 ###+nHJDDC/gcJ7DOg0wfY4xSZ6PPxCuIcRP50PcG7Qb1JAvwlubheFnWMxnWaIeEsx ###UHzD8ymSgA9qeN6edTD1Lc6nWG00Gg/vA+59gyhyvWdsjfWHN16xxIr+PezT6ibb ###pvLM+y80vvj94ZeS2EQPxGEDRzGeLWAjIjCDfXvsBwMPyhRnTm4wOA7s1qeI62O0 ###K7xSLcHNya4SaGgjb7hD3tObDqLUk/oZCZbA67bFmbozbjFbaWr7Iz4ZA6AZSp0/ ###Mb/kKZQ1gypWbTMIzUCZXDM4vGm93UmbQUwvplLLAjKAnCby6xqLrRt1gbs24GV6 ###h0fiwz7AotDd8iCegxfMWBkhsDcZGtrdbrXH4/YDBrnBY3Ubn0EWd6LD8Tkg9Ei6 ###fwHT4W6V3cfp7tDLlBOnhjoK9gH06I9L5a79hPE3Ah1rEhoqF5XnYw/s62BCLtrc ###iy68DXr84DwEFKP7189TEM9DvlZjoJyUqTeAPmrgrv0J5nkCQgVxijaZqGybtrV/ ###sfwBgFvhz+MWdSWH5sdlQ8dCKXUuNUIv70FDoVg31CgFuhlyBZZGvaCpbo1ac2xE ###eqrjV0UusIZ+IB1gqIOLEOl9qoGpMT99zDXq34BIZUyqULhw9Pq+RUgX/oR4DjEe ###+33OkkP/56k/6PgxkR61w4k80CD/n+1N9LDBI427KQZF80ESbnc6U7SsbsxSYukU ###RCTDhVbGAC5Afx9QYu8+b9VJEb6F2Ubr6YzRmlyeOyfNdBnSdKY4XaadlBaVMMcY ###p2rLtqhSp0PqTFDvUWcdnXTTqTLREt66+3Fp7DdLXRstRV1bLmU3laM64dkm6BpP ###6XKQtEbZV5yyr46PsZn253bQ56cEA6LtzTlGa6Xs7c1iHsoeL4+ybdsFEfa27lMS ###L6pZlL39GPKyxUaNrHWPp+ysUf8GhoiJP2LTUSTGO9ItKkylctgAUw5CdIEAHTVn ###iwF2K89ZHisPmrIeIzDamWUjH0ltfSuO9c8wr7gW/2Bza+xGnF8sOLfbf+y5BWW2 ###/wBzMcCLGIPu8Atd1eS2Oi66beTZON6Lug8jP3yxoHrNLTYu5qRX+0MbIR0vjYKn ###Xt5mPGsz1AK1lKcZH2j8Qdy8Ea5WINaK9uh+D6rsdBIG0uVoiJt61+EZ/0YYRF63 ###qSKmW9ilFm9i9lnk6B6L2jeq8yFBxdHw5mIfgGWcXo/u030uFdBzu9vksJjDcBJR ###hqPTax+XG8jqEbVmhRqeG7TtVFyCFiTOizigN/QngSCJzfzrTSrf7elkqEp2OqmI ###lznYIohI0JHQLsrgK1YUg1KgHeA9i9IjdcA1siDZOXJTRG0Vlh91oDP1wXxeHYDE ###w/ak7aScNnThHdKnhOwvi0IiyM3gFzn45ElvHD+dLY84zQm0291VXE/ao5BjgRNd ###JnHG5Med4VsU3GU2k+q3byhporN8g6sK+pmlCF5HHE7HGvjIO2x5oG1FeOQbjB0S ###80kJepO/lYkLl00HR2Hr05tf7IeZ0bWD3pirig+s+Gm+Kx1ZoAfXLR652QJaCegw ###vWYU9T+cUx7Rbf4cxZG3GRC2X0zXGd8NQfaCgfvhhE4+X4DMACTdwR3ZZdMB/744 ###y6EBOVkuVTBywWrP61o859ZJc41P2mKMliNCc6IzSQ0DAM9LbnlsQJbFHR1wAkie ###LfWbrO01y+KOZB8asygwZyfyIPz48hyVcVWji1Kk4PX5PuVnVjjtLuf4L8SBB5c1 ###x/7nYDgN+VLIy1agEiDWqmsct4E6caKB0PTGdym3HzD6X/zxkEdsN8g9h67BQ6G0 ###JrcgUrhC4Yk99yiBIAZJYVTgFhPiUlgb6E+nPegGXbJoVSjr77xsRQXtCazHoCmj ###xJxAl8JMecKvRVhpzv0cm78PJg+OxRYk3+HU4mmFwyoY8ugLKCM+aDcwyWRiDiff ###jo9vsbuQR+rPy8uTcq6yXo7pNu8I5L8xzOiRwGoALRdPj5tHYUkkQ4wSEQiPPU2x ###VtSzRg8DPqAjCxsPh8KHrAeSUdfhsRnIKy7hZWZ6IELP8NZxXxg1btC+ang91zzs ###YA7fUSyW4pSRCxHko7fFipWNDX6KWWIfuh9zecG0EzaKiGedDAdBZwZehXcgQpuX ###mHK7/M7lJq8Sk5Rfs4dA1DOI0UxZuUKJ5p6CZm1ycc68Wh7HYKtbH03uXV4MY/0P ###rKteF8ojfNjpii/XPAPmdOXkAp1/cnva5AJ7nva7c9yC0JWOYIAJMWAvbYXD8QR+ ###UgJwQGYex9+M+ylXA2wPsPOUNfmX3CeSeUSFoHufej+FCyYCXI8HVWGiN37fv4sZ ###2iI8/DjD55i940AX8fLPAfqHDKIwVdHOBO2LfNCjYSji4CxGFKCYCqLgayTPol2R ###xv8I0oj5RQsEghbXhVQqySKTb0wlWQg7Zt9sqsTmiXsHudYHuEuMHRH+AlEVpcIi ###c1nsmaVvjq2osppiOWOnMk7CVEySh//TqMGuun1hP0UfhBz04fjjPJvkod+ftE8o ###HdWWnvqOwVMKkNXGw3MOxGFaBYQl5ZN9zHf04ZifvuZZb/mInmZi1EZpmlyuxQWa ###dD+ZeBKP2+Nh0KaL3bHawBv84vNoccl5e/e2JV62+lQ/B78cYc33rbets6tLQ+tO ###2v1Fn2UPPhx+fIxRd5SknQiJaaDlZ17QepHDrPnTfKm6AbBmSj9YzCHlJNWhTG8P ###7TBFvwk1Hd+0eKg9v5vvVKA1GN+knArM7VMxz64nQLfeOjNBvxXmkiU5ONSSXh0z ###j4jl4QjJsKWFafc+w61Dvf7gCF7+ItbA11gR6G+dqVkDWSm/2eYuGDQGn3n+5WrF ###MUBHzsgYFsu8VPPYvV7tspMx6siGEN2XxsBUGzBsjCLg+3TvTtwUKM1nwLAdOpyq ###hmhhuwDO3/lEiW3Z/SNHncUszha52mphFqMHciIUZ4wPsdsthfqg3rUHE8NnlvIa ###YijKFi+cSz7GnZ9My7P5MxUNBs7MhRjn8ExiKM6SvL0Ihmaqq+Jkzmo/XeTKc9IZ ###ZnjnRxI7Zqnk54vK5QXuDwpE99bbpuP54fjThmWq+CxVvRaUa/XJMbjlPsvB3XGQ ###rt3U87by9K37bCmnXukz61lnFkf7DQ/csma2v4yZ/ca3jhqnx43TOoZaYSe1yzez ###nE+WduuISXdK9ObHdKGgVLgfgo+w8dB3D7+XbB6bwQC26RaGcAWVChi5lDwSTGKN ###P+HH49h8gjZx/Lrg5i5h6VtAezlAe0vnOinu8AT6s6rDhQvR5uyJ4RxlNT0pckrS ###USUCnbwEw29o/HNRxvamSRl4k0rQxvZmrvu7Ccr4loSRAO05/3rr9pvvKfJDcXab ###7DfbUy6GdK+6DQyJ32oCsfQv4+HkL7SINtipf9OeBJ9B3R1OpFsCd1RD0W+MtUHk ###L9AM9CYbMghQELKqd01XxyYbBTozQz8OPOf370bDMQZiR+tH0EfrCagOw5sBSgQo ###iR3gaR7AIN2cbsuiBF0Qx6wUOJ/axauW0NXxX+AHD6qJFYJefNkBuj9kA3Tf7JEl ###ik5Vas2TPyMSMbRm0JFPTcZ8cXZR9YrqY0CRExMfoqMk8ojQwykvdc/2WFF5UMJ6 ###u4li40QxaDBZ7C5RrByVw3TU2ItEimkhI0RwvzK/j6kARPmX9uLFeKglVizeY5Lw ###uxL7lcHX/X1WhN6U4UGppDWaqxled1yKWxtHzRS+ct/lfn/YoVBYMWNp9znXQ06+ ###Wb5+mGBugbshUE6720X64MGUe6x+8qp+eFg/bIFEVtCiVh++P7uAx8eN16es1WpP ###eMR7v9UqFqUctAlDKnyPg0mtqsTExms1vWmfnVAUZn5rFuPkXcMSolTsvLvc0XgE ###2gTlWqCOqo2LyNBdH2P0h+MO/APUHxktxGt6X3JYEUrQHyxTSrSE0aYzWsLXOVui ###GNUpTcnXKU3R1bzgnsz/uD54mGomuEwR+csau0aiEKHebtuffRHBJ+IUCTydXB0X ###ad1RzcSniC9LaHfB96XcoKYpsGiVpQBM9ofAIbR1go8RE+ce33Etas/h1RMwa4eH ###wIlopE6RBooDxrKlebswTemDPm69Iyn95LgmZGO2um0oz6dB/JwPD3hP7fIydaqL ###YqIFJAR8Hf/WsLC8Hh3XlB6Zk5M2M0oPO1oPE40fv3pVbG9vQutoXelQf43GQdrD ###ItB4LByWiiqHLV4LaOozbMuyGGw4z1hdRQ2oWGdP19Sna0+VdVfrdkOKVxNypl31 ###yohbITLgDXL2pf0Qc0zgJeMe7O3oB4V7Ovr/jP0+RRcdYpwo3lf0QoAJC4bTMW4Y ###ReSxaAIcdNvjLsL7SyiOUfCglQXyG/nylaNEJFEjSTzQLLaGn3v9L8U24KKUhgfE ###rbYZF9slJDnt0TWiHm1L02vK7BP+cyKlefXqEUgp25CCWDkRVtAy3ma9o6uzcqcg ###HLQxlU6EBXmqJpMesWLgY0ob1g5DurKGJ4H+9fSG3Q27fsnK2cQQbMs4Mft8JZt9 ###FwxXe0jcN7mmX71KhVe0Q2OOFZckAHHYpcT61orwfcBkMIeNdwDH3RYdUZmLZfqo ###I08ZMRNzWNRSHi6htxTvTpe3fhhNMk8RAsR563c+kXcV5kNSpptj6bzROsR53bi1 ###LFYcVZIiI4GAluS1OQzOqheqB1w4V73EAprZ0bIFIC28xerN7GjZ2tHa5TN8mfKh ###ivtRVJdnlDH1r8ZvJu8J/mdhHt2a2n6pttU41duG39A2FEsMt3aJ6C3l67W7bXRb ###PHixhF5jU1q3xYO0buPs5uw2LGG92+LBMrqNTWndFg9kt/V+H7ypH/zQOmqkkAo8 ###TClvn6T08nbsYPnEupQ0YCN5lUUq9KLyAp2ntpHvQzvwPyugtLVVLCosgD1hlftn ###Ff1zfFziKvpfs2Zn3rkkqE+yof6ZQ5UTvL0ZT/A6VXyxGNhfcw1WBUs0G4G1sMqF ###55Kzy5xzKQBlz2X5kTO5hMllYnKhJ/9l70Za9+yzXX7EbKd2ADGcsx9y+sty+lE+ ###bk8wnAlKdSgDcJ/Bz5EHFReQzd3//KyZxUJzs09kcVJp4VkXw0W6g7xBdOmZhaQ4 ###AtcVekp22rKTRpVKqdBsSyUJrZKAZ9kAc0CzySM2aBUDog3xs6HZVmcatFkkF0PT ###wR033zSO+JzREVGqdvNMVW6eIWt5+bLIq5RK6jkDP2na38N05/z7S/aMJSiGA+bT ###Z4Gsi/YxZPxlA50CGE/rrID5TGYCtulzuQGjscEKmE9qJuDYtDGVNof8gLc3UwCn ###TXEurBhnSekj1iFfzKKudml/Xw5sNh/OT10Xs6hrKYAt1HUxi7qWAthCXRezqGsp ###gC3UdZGDui6WRV34lu9PsAld+z0MBxZFPrTTfbxLGJCLOh8SdTDhK4kdjkFJhlaD ###9n7eHpScT5ywoMZsv/aj0j4rKT9KaWO0YreoL+7MMUbvIxVouWM0288ao3WQkQ3O ###HGS2CQ6P3TTeaZAYWdrEYZW0v6SQEj8cSNJw0YAz1+pKWVHZwPAcclFgSYEj3iGu ###TXhCqVM3EpAjHJbc+/MMLQYmRCkdnHaWIKkzKp+EmxdYhEsVXnJkvFja8GYDu8iH ###xouloPFiTjRePAaNF/nQePFoNKJiOotAuKa7BAJBYBdzApsHjeRVIv1myaov3qcv ###+ouzq9NDK48TD/bwFs9fIybglvhRH2oDbokkfckeZI0yvMBSrqiQDtciPSwTLt3b ###ijzTyMeG40P4FhMLxiDLFHSbn48EnSiSlNbtU95tPKmGvSShlxVZuVh1y+hvUeZm ###teO/QyEeh+o6RK0X+5/yFvWkUsJmooCELTqheCJIdwtAuttRo1DIBJnyNgJpcOe7 ###YJBuymYC6y+5GeqvZC15YTGJ37XvZ7eyb2mFTqrwwIIHXBLpgPtDcnUqc/8G6bgf ###8um797vihTJnlO4c864fnJ02QfY4cNhbln2SdsDPjhWlyKUt9i3hsbKxJboXoanE ###8F4I3bYkQwYGUetgdBFxdha5smOip3S3p6hB/BGBZ23F4+laujtJT5+0WdgtfE2B ###IsPDIxygA9XXx1ELLQGU9ONCUEDlqh+XoxZaAijpsYmggJkojxVQ8GsuUN9wktv3 ###807y/kKTDHDmn+T9hSYZQM0/yfsLTTKAmn+SU0AZ4jbXUKC9fnAXTFzxVx66Fov8 ###MbUm38i9iUUv/xp/fSEPfdTi8qs46FlQw9E+L/ROJOConUj0sG05viZMpN0eYUoZ ###W7XU20jZ1VJTGyjV9Hp8f8uynxNSGBpF5cyXaUfURd5XPqzbMboVOlHDUdzsL+Mh ###KPlfbv2BsEX7mA2ae7cLtfLHH8nUbwoL0Aqt85Qu8u79V6xYYQIbdOYb9vhZsYvU ###Uc5+b4WYbp7XIVZdDQD+tLaHAlppLgQbE4XON7OPuPFcx0WKZJxe8XcZH1SSunn4 ###83iS1aJ4z/fq82b96vCsfFE7PTw7Ya/rp/WL2uXZxeLrjTuSn2CCjnA6Jl+2cIJG ###IR6Enpyz2zwkfSidn/HHwL+f8C2iCCSE16/ZtT/54gvXed4sv2UJUj75sH7BxNCi ###yS/DwV/oTv24PegO7xj319lg75E4h4P+g0hNFuK1OhEuNGoWvckdNsE+k6A7DPmV ###UnREwvuPdGXj+oELyGVp3crO36CL9IDeIg43hdwNj6DnlZ3tanULb6jzWg5zn29X ###3U13W8pYdDpEgzHEcrnd6v6/GLICcHDXHo24UF+7ONlg8dUt4SUEkvQLCjNIhUZ4 ###pTC+HbqhMGOo/jliZZ7m49556PT90CxcPVnnP6q2wpjqgucDoPuo0AGkmOPmK5je ###mwBzaoQbRf++448m7P6kRLNmODhleuOqcqyq8McOj8XI7fD9q8jXijyFHCZ+JpVC ###KuCQEyX9K3JPotAzRBMWEZzv34WsxxODwIjvn21bvB0X6T2wHsVX0ugzecF+j/ef ###p12ffdcggSHcuP1OeUhqBIV4tTwXPk7fYSs96CxjrVZn1J+G+B+IB9LtnP/FrYI0 ###imbj9fnF2QFpFm9woH9afewfnNTyuNfZ3nG3n+JEPq2dNzZulwoDzx+3tzf/JI4i ###jb/ATaqVP7lexYW/3vbO1p8qrru1Xf0T+6dCpDm4f5LPUu5JwaeA1/j59ahip8Q8 ###mPEyTKnHGvXLI3Y5RvdbZKrNTxjC/BiFW7+7gZdahMEHt1B//BkeFgqXtwGl6vTx ###khTsyOgljJs0hg25ODpAWt1g533YTmj75nsMvODBfoQrbLtfCAZ4t4R2JGj1wseY ###OHS9BZk+9gYZPrpUDqfjjk9ProMBXryiOykOVyUx5gtPm1zgQUn4HudQfMWRP4ah ###UEyn8fBzgPEVqTc6++0MB7xTYQEr3fmTF4Uy0ztEGcdETzAiNY/PA0JuW/r4Yk49 ###1onwPBiCEuY7hcktRefHe389BRINR+8GgOv028GdP96wgEdZJx69BI/XK6cd39aD ###gugBW6QHQjEvdIedaeR4jTWeor8rXQ7CwMbjAEX5CLdct4cm1a7jYE79gOqQENfm ###0lUDg+gM/AlrDjuBj4FHiRih/Zgo0VmaahUGFDoD50A6f+NVPIIxHIeYbe8BZRgg ###GZHJrDukaCNj7N3dcOIXOKqAlLvQ7c+SYAk54bA3+YJTLxNwR0BG4wAJbIxENCgQ ###OdG1vo3C5ZtGkzXPji7f1y7qDL7DlvaucVg/ZK/+xi7f1NnB2fnfLhqv31yyN2fH ###h/WLJgMBD56eXl40Xl2B/Nxk/++//0+tCXX/33//3wK+rJ3+jdV/PL+oN5sM5OvG ###yflxAxoECCAcXjbqTcDR6cHx1WHj9LXDoBF2enbJSLWDYpdnDgIuJKuxsyN2Ur84 ###eAM/a68ax43Lv1FnjhqXpwjrCIDV2Hnt4rJxcIX5SM+vLs7PmvUCDu2w0Tw4rjVO ###6ocbAB0gsvq7+ukla76pgSimj/TsPegG2HVtmK/qheNG7dVxnQOCQR42LuoHlzia ###+NsBIA+6d+yw5nn9oIFf6j/WYSy1i7850GYBjZD1t1dQCF6yw9pJ7TUMrTgDIyhp ###XF3UT7DLZ0eF5tWr5mXj8uqyzl6fnR0Snpv1i3eNg3pzlx2fNQlZV826AxAuawgY ###mwBMwWv4/uqq2UCcFRqnl/WLi6tzTNtagil+D1iBcdeg6iEh9+yUhgoIOrv4GzaK ###OCDcO+z9mzo8hxk+LRCmaoiCJmDs4FItBvAAgZfKGNlp/fVxA1Swgzq+PcNW3jea ###9RJMVaOJBRoc7PsawLzCIdMUQa/4V4VoHZpI1jhitcN3Dew2L1yAqW82BJnAo+bV ###wRuB7o3CkjakpyQy4m0QLhKix/wb3e7MHykiJy34YV+XQ9GSCLX0h/54DKvfeAbs ###ZtBJPOv6HVWAVeVX2NqAQbHvDr4r/CMWZdUuntR+5MHVm63z+kXrvHbwQ/0S1BeR ###qQgVGNr0Ls8OWPGSZy/rYcLVCQZ8ovseov+MqzvsH4nYI+9qh0f99s1ujvNiDDuP ###edYmwWeMyEZ+gBhqaDJnuBMBMvyQNcqPuykg/XbnVsQZh03E1gELyGCAoZCP6gcz

okay bestie, this part is literally one giant wall of base64 ๐Ÿ’… It's the rest of the encoded reference source from Appendix A.3, so I'm keeping every single character exact ๐Ÿซถ

   ###xoqXNDHidgCz0aHjDLwvLYAggcB2jHtlmVJOQ3sxyK9cj4K5aHFkz3MrnpS2+gB3
   ###/rGiPj/ydvvT+e/lU0de+xOyZJFQ8DDhGyPurU0YIex9vJshXYxf4La9mfAYwLXE
   ###2FsY9qaYNT1aOkhaiFxeemzMHSoGQ8MOvKIx6yCVDKf0FlCD1GtgY464CDyu9yCY
   ###oBCB4u8kaisTpyb2sAmBvTmTac6JPYrplFUMsYdYsMTDbE7y5qXRQNIAYXAHnDUL
   ###lpcEOQ2To5SryXy/pEAWT/kxfrvLxL4hWCzaG0nyyzWZ2VP7duqPH3LN7SOnlgcO
   ###SZ/gtKnFv/8SU6vwX7G3kK5B/C57AqkmD94RUK4K0Fz7fA8JMZ+Bo8Q9JaVK7CLM
   ###rWDKAcwzPe0GQ4cFY2ACGNAc3eox9xoqkunWbT9CXXl/1H7oD9tdZF0taJMDRjVl
   ###WZ8EZXJUFXNU/ddkOuKdYy6Gg4gX5KbMWTGDqJiIGNkYJOPFNke+37mVSftmJ6LO
   ###uRcOmukglaiTvBALBlmQBUi/0wLUZSBjFF60Bzc+4N4x5xKDymJIE4xLiwGcY2b7
   ###uB1/QHv9mZFviKe/Se74YqFhUE9KgXPSvucvc4byxI/KIkzE0kOK+0vipy8Loxx6
   ###Pe31MBbQAF1uKIzo/MGXiHMc+v8UYmbX/wZiphj77yxmwtDmFTN1bCwqZl6QmCnb
   ###mlvMFNj7ncVMxJ6BhUdw/BTsKSuFtYVIYMeXiShe6TfaGrPCpUk8OWy5WyMMUNsa
   ###1zSQ5s6ocHC+NTZncO45F1N/GE6QbdrCtFZeILeEEiHmxeN/PUH+rOd3Ft0a/S/n
   ###ZBFQ4MaxoDnnxhMMzCMm1xp5FXA/AxDPYqtFvDV2/RxbI+B+2VtjmjuQlDnUvVFS
   ###LKfxrgwYFHIRJF3qyBFul+/GzQgmS2WMUuboik4sQ52L9qOJtKJ1hBVNpJAQM5Z/
   ###GzLZwg3sPpdnB4nwlFNbTsA1IWjYiPpcyCA014+PC0kETTuRKunZZD0u4F0rm9ai
   ###4I7IhebcH59Hw0yCo21PhDQfYbA4MW47U4rNbsleNUUBC+u9xPPIeLbzbBYWS67p
   ###iVD45z3/Jy/up8s+Gt/Bc33r+T//zs//vS23svOniuu5W5t/Ylur8//fbf6bwc35
   ###eNhpHR2fP9obJNv/w9t0t3YM/4/NatVb+X+s/D9W/h8r/4+V/8fK/2Pl/7Hy/3ik
   ###/0fkEnx8bvqB6K8U741ICGr8qLt1kIzUwvtl2vOXwLFuN2737d7KVm+Pbxo1HwZ2
   ###CoSMgwOCwrk7ujo9QHpqfvOo+Qe3wXjEitdfROLpEjs+Z7DwRRpdPeHbF5Gceoxz
   ###UIx1OsKz0sP22Jp4DG0gcdM8bnGU7rooWS7IC2Q0d0tzaK3djOSiMptaDySBBc7T
   ###YpD6WDuEOTtI/q7XJjNLcfIwCtCs9ECJBtA6RMm03RIrZdlDogzTQZwx7fj8wMyY
   ###5tD+PeOKzQRzsge8fiL5OE+AiVdp+mw0RIsNzkWAUXqDCesE407fL8VN4UZJkg/8
   ###vW7jPjsU4U5xZba9T8VcabQVbPKLaecHLTHSFg6xRXmdkNBiK4C4iigRksCEyOHX
   ###Hd4lU8llTOVazUmlnlFKkr4PlJ3v4zyWUdWaNrQkZbOAHM6bu01Qj4ncsHM7HQtk
   ###plm35UW98QLJGFULj8ENMLtkC1GnpCOMQdozT86dAVEH3AZZsIXZfHWQDfmOEv32
   ###uSgb8oTkvg5z3S3NZ+nOms/h4xPwxUz4k9eewX3txHzGHknNWetn3EnNNJk6x/lB
   ###zrt+HrOA1Jx6/c9cn+LpgOm+KleY+O1AyrXnfw4G4XBQPpyOr5G7+50p3W+3cbi+
   ###KNylsvpqlDOkdJ2fMi1nEdbsuUDPlsThrPujvv60GeIWalyKZWUtSpAYdOTjIqby
   ###b8xUlS3Z5CKanGS8nLFc+Z3U0LFyZLquKjmT0iZdxCstulwJ/YftSdtJmRk6sqCQ
   ###IRziQulw1VcRRDxOd9LkMw58AfnMBtLElgpyoOd8F5M4aY9CPmo+yZnEoB8ajYJJ
   ###57bVHrT7D2EQ4t7jK+tbzic6SSPnAGEsQKsJ3sj+jI7TXTz2nA749/nnkw5f7Cut
   ###yZPdwkgFms/r3Ie7dVw/fX35pnXSXDsKW5/e/DIXctf4gIeGOw5Pa4yvGDrIiGiz
   ###H2Ri3I/zzqd65LkGLTZAVbh3kgvlGIDRu8V2WBWkesSHmQInw+lYBauPUhSYE3gG
   ###o147vjw/AJq0+QKcxmnpFbLdZcLHieetJmMWMDtMhxEKf4jsucTCx/q5fJyeFmOz
   ###4FQOe0aju9J18Rd/PERVIEG+GRQb+u0xkM/kFjica7CDIzqOB53kBndfKHA77POb
   ###/9iPDig7QZfO7SsYuiH3IlFBegmQuEbmBTZzO+Lryr4uhRdgb8zFzwdWhKKlucjH
   ###BpLnSrkP0IqadHmU73Dq8MqEwyplDzO0+KAFejiJt8HNrR9O5gEZJQ3PPJPeQh/a
   ###OPX1IpIvyE7+mDbUcDieoBvGGCMVDG5mWSPsyh2uqKsBNgU0+xTEPfqS5ZCZnzsG
   ###3XsnRdrinEKAkfEsRC98ntwmXGDijzMMIO/UrJGPMYDoIH9g6SBP9Q22M+k/yEHy
   ###iOQp3oy6tHUgNuI0FYJ4XaAmdbdI3dfT8U2Lnwj5XUMF/saq7yJS9yNV33s7SEW2
   ###45hyBDm8iNbvWvFw/Ri/luYEeRcMGoPPr8kAY4KEd8Hd9C7NYrMo6VGHW3wETsYo
   ###I44jib+INuANdogd6fg+GRqFm1IpH5uzud7E4mTM4WAD63wCcodB3i84ysOMBbYE
   ###mwI0JaO1sLbkSNf4XYYEZKkJ4mewXJ4MPvU9GetSuadMqh7rXKMHsnEu0Fusm7/L
   ###JM+mi9lURPb88eOivMhMnEaSR/WXodpsezxuP8jT7TgYUnc4RWstDFZ8M5IsQ2Px
   ###UFPH4c4Yp5d/HCGsbyT9n6ftMT+abSeGkXMUnO3m6H7u3v0rJjuWp2LnDR1Esbrh
   ###brpbz73trep2r5QMRcqRSIH5rpk1C6kljqM9Hmm+pvZnNoWR0WRTLC2+W0wApZ6I
   ###xWqNsxf3SY87yHig4z9q1EH8LCPyIAXavLlDFhjF0UyE0EycDPAaRfXFPTNjPyoz
   ###UHQ3KpgZD/+s4/ldsXxfikN9GtFl6Y7MxL9Bz2qKP0vG0eJ4OB3g5luanb+aGvQw
   ###/l92F5W4V0oVKLe0nsWbCwcAyiLoIcTfinazxVr6hrJmbhWRdZuLKgUtJzd//4mn
   ###mgatocg+sT0p1IBmugu/MWw1/C2XtaTY0IMPnz5CYTXjVAqyggEWLTEjpbVEE8YH
   ###TsQOlojLwBbhyeOH8Qq2EjuoiS0Fnb85tlSKJ7ToKOEnAP3hjVcssVu/P+JBCtXw
   ###yVm4SZwMYENyT0yStlq+VGTVjarnPveeVZ5vPnu2UwXsYE/cClG7oPfF4rChZ8Uq
   ###Dts/kf+vKZNvdL6V/29lc3Nnm/x/N7fdarXq/qnibm16q/hvK//flf/vyv935f+7
   ###8v9d+f+u/H8X8/9FUfVN7V0d84scNV6j568a7a0XUHDhSHpNev7i9afv/hlMmgUz
   ###sFvgRG83dwsFYePdvGfTwRj4MbCn/nA4kmbiqCioKPI7JRI9Ojo6UPSdgJF6E7CX
   ###Suvwc32PbWoKDw3rA75hFfaRre3RSHZt790Z770Z76vm+6/RcNuDB9jD0GmT3CPk
   ###MZgYNI1IHwz8Wl+3DyQB5GvhX13+N6zcCyoBs+T/Hc+U/7c3t1by/0r+X8n/K/l/
   ###Jf+v5P+V/L+S/393+f9fz1vgj6gy4NhjrYHL22yNiTFHb3ZTKrmpldz0Sl5qJS+9
   ###UjW1UpV9/EZqiIRuh/xxEb0kTf4fDIPQb4W37ZEfe58vqAJky/+brlc15f8dd3Nr
   ###Jf+v5P+V/L+S/1fy/0r+X8n/K/n/N5X/70SIACMVzBTlt9aojZ7YlA5S6AbyPgEJ
   ###ZcAc7jCJJ6x3THMpolJovvi37c8YVJZuON357QG62ShXdjAMPPBPH+MftKP4CIPh
   ###oCzbjIqSfrHBis0h33eCKNlmgM7nyFkl22xLp/ny6BZ3zrvhAPgP795Gialx7Gva
   ###S9yFhwM/Zr48sKkyIp5yF0fublRgEQ94AOcvMALYHZU6HIhaM0Cmz315+e4Ro8mh
   ###/VztSbiR0w091SuKI5BCQKR7AuP9PL8XpmtYrN++u+5mOAtzN/pCKZluJ9g1W+VH
   ###CoW4WZDuy/wbL0tUtUeoCT8IB/1yrNBESpZ846Euwd3QAsMNTTQl4Kzx3+uyaUWH
   ###SPPRxAnuoZcm/1I2mirFXpEH5KY2yVoGuFJodkehP+0OJXXrcURAhiCPVFhU93Tl
   ###Iw4+gvcrggkuTaAc3pKtiWuZdhdT9nwJukDFFB2GXOiGXLiajKe+XsvudyjoB4t7
   ###BJEiUITpGr2gpVb4kKGxy0KgaeUkOnsBxNNCROkA4/DHDoadJ23dhDG5G6EEdN++
   ###hlVJQWgcmnAaFv8GfY9tBnLyoxk2UWslXJcI10a3EQ6RSIn2WVkhY+21orJHWM2q
   ###Jl5rpC/Hhg6bCUoXX0rxMli3dgUtGKV4CSOgRdujPirtmYYVwmDSaKDjRZ5f4oMU
   ###HMVlaDp1KwZpbfrk4ZLmncBvL5krvhr9wKRaSFpyCQMZDfu4YfKrxaJJutdFNIYc
   ###EBER9zLngPEDtCq9kqG1YuI6gIGUkpNSIkJJ5LccBR3oFQnKvuyu2QVtJFByN/GW
   ###L7RAf/G1kPyGsERTL/cEJzTB0YIzYi+JSEs8KlSZdXEDV/Ac8/ddBWhBa5Ev4et2
   ###5xOuY+KQNvaqtBrNkjtzliwrej3Hik5Z1eszVrWOU2V1i+0suSyUFauWiZbFnESZ
   ###ZyXmWY3JeaqN0BZt29qUieFxw6CjG8+fI+8pwrdnyGcqG24PcEbLF2RAFhFbOaK1
   ###p/FDfI+Ui+ZUbVXYwrjFY3Y4ZsTOkbMe7oWJejYCjfaYvMQ5e7t5xJaz4LaTSqBL
   ###2X6+xRb0uy6A+F/Ou0O8wQ9ErYqfXCUjQzZDQzY3xBmiJWhEkwBUF5JeRVgR7QAn
   ###zRCuSHwiz1uLMrPgOy1rg5rLKC0JCMUMqGt5BLVmMu+GS/AiC53aAQ7+YDLuO7nB
   ###y2R2WR3IuLRtCeYC6mw2eIozcH4Q35LnsUYoEIrE+SLgcwROibN2KJe7P9BVa3EN
   ###nFYCJ4CP8TVncXYmriEhccSzD1hv4qPmBFbGE5qC8j5/tJsUzj85Uaat3aRo3zy9
   ###aLW7P7W6rxz2pj2+ezUcotESv1KD/Hb8JShXlsqD8Y2DF9Jb9KU/vBH3YNXvGBLx
   ###swxw2PrcHgc8+Euyta7fx8BOr97X70eu+OsJ4R/PRKUe0O06mIFE3KG/dogvw+Kz
   ###NHnf+gLbyfCL3/2A1r7zOgVrfN84xZSwkjVqNeIIfAyzxsaVzi4O6xfqOV/yYtx9
   ###azSBzSSmSvwd6yzn8vYezOSYTNncZoGUGVHhdX/Y+SQJkBqEOb4HViqn+eBusCHp
   ###JWo7YZsSIF/XGqfcknl2zKLH1tIxIQBAFRi+6L5qvd2h3dkFDu56z5CDl+KhcepG
   ###Gw0GaQn4nbI27J4YC0ek3IrecoW4D7MCg8er4+9qhyRfRLtpxFXK+xQUoSXrooCx
   ###1aOOqF3UCrWoqdZbd4tvJ+v5irokiK+xyAJR9Xa2zXEe8LRosjt9/7MPnO/an3zx
   ###/QH0rUI8Hy+YJkfCU6opQ9FvsVY2PDEyZSbKzKtQF6JOoLiujmca+gevLtjeHu5N
   ###ukZ04dPBikjlBq2y7nTMb/99kQl1orzHihxzLUVSneh4jZas0Xr7TMUW87a2BbKi
   ###6MDKOPbYq9ctfHBYP0BygqrpqFkj8XGLi4+ElFSCwBm7xv80XdJEEiW788MNzn4p
   ###Iwsg7PJvsLTfnTUO6ocpqLuhXMyUhdofB9DJjuDgmtynjBPUhDe1ixMaaeNUG2l5
   ###XwTIEj1lfh/kBl2FBUBRMCoJiOxTwy/lePmMMHYZAMTzM3Vhhbik8KypPWB80cpw
   ###Sem9LbJyZWOzF3dyxpKHKeHTHM99OWN2DA0/3ZYuMNA8r10063SiowSVTmNclvo+
   ###caHBJPiFwpr0Qj8yKDyaKDA/HQVDFvHDQCYVZ3ZD4HTjaZ8HTRmNh9BsSCbgsLjB
   ###Ld9RyDJLB6jDZ9RX3gtpHzMYSDhqj0PYR8OQ+KC0XtgoqRkXvfPb4XTsO3HEYx5/
   ###7bPPen3M4tWODodF7CBMheSxO0wKGfp42qpRu5QloA+eQTY9ChsW993c87Vu88xq
   ###mpTAEgW0nRT3JfnbUBE+cRXhE6gI/Lb4ydXxq1fASq9emUEDHa3LUQww1Ew8aMGi
   ###WYBwQzqNepc5wsK68cKMBqIPIRbFTJNPjAq5M/Cr1QjcYh36hHql1SyUQPr6XsL+
   ###pAArJyahlGYzss3YnvJEr6dPHXRCF0L1ptOo3NwiN/kOmRhjmW3p22SSH/CCgiV0
   ###/ZFPwRIoAnhisaj0HrGNRPf2FXbVunxzUW/iMXnr7ell6+zoqFm/TMzP3Ks/sbbz
   ###t+Km2XMaAwo/pwkGuMXxkc3e4PigjS0uDUdlvoPn3QgMdi4TOmYYn3K3dTKEeQWd
   ###go9VDJJOHDF0YCK+l1SAhZ4BCD1qnB62zhuXB29a7980Luut07NGk2KSUsYDXUrB
   ###5lB12tVVwQxJkas9AIfrPfildnr4vnEIXKv+43nttIlAFPNJ1LW1+KvAM2lSyE2P
   ###z963LmrQV0tbIIodX9bUfbyysWNKW4ZkJtoXfQWpjiApDz2kEOUhjFkU/gL7Ce6V
   ###7dGoH8BG1O6hSVAqeaE40w4m8fakI+apxEyKICyUQBDmtxO8ETlBHz2KYPO+QzoQ
   ###hfnhsNC8qIN36ICkcQxu35mOsGx0LC5DTwaTv4Q4qRPyJgoxbJqybiQUPShHWqef
   ###su2treo2n1wgEDdzKlL2/hikIiDkW3VpS9Bm5qpdcDsaETGXknOuRwsUcwe37c/J
   ###nTmyTHMN/wWsaTyJ7w9H0h8MJuP6AYQc2JZHqHCrTztDpbgyZXFw5NugB2I2FUCH
   ###DPiOLdFXRfiQjwydmUtCMH9VxRQdNUXShKZaoTL/Phgcy0AvcbtcLinoBm1cQw8t
   ###HIGwb3BRI7Z2OEzYIlx1CJphHMeHO2z01jCa3/l3ndGD2ijyHI4VbpeIfsa9XaNs
   ###28OeSu9JqMAiLLjMN7LUTnjmSFVKuRp1Kdc5WmD88Qs28O+z7C6x7WVdn1c1fKMC
   ###YR5eJNdVu9+ZUoBycaqAhidmRGZX6xB6hHeALU57bLlyNEIQfXESgmI6ATqJd9AA
   ###YOuMzjVKM8QTbXBj/wa+jPONbp5hLdp7OllKPerqdoGxB5LdORjvj1Jzi/D7kYqk
   ###9F4xGFb4QaHxZE1YHm1Cg/3AScssAHhLibjK8+d0olCzegRYVWUjBSY1k8MTZZOp
   ###XXgfgAmvWY2fHx11NnLSiNI4CkQhNv8xoU+FP+PxilB2HrOuatwuQjIcSnpyQzTo
   ###zd6rtT3Nf2suzMh1lnvtaFP/yiLhkqD6MJjc+iF3V0cpQ+7AynisZ5zzdD2jx9IM
   ###nzwbtYkFNh8ss6NiX9FmQ++sm9XZjHpe7npZUxRtYRp9muNPm69oP3nUdLmPnC7X
   ###7O4FMhMRCl9Vc0L0yDKST6nWKn60I5lHRqKrJZGbukAQMH7mBe4uA7jJH87HvmRc
   ###sbLU04ygAldPE1wsw5UgLZZ27JSoezKFpnphcxWcazIWXXoRu6tuPH/+vJcLsamK
   ###SHxeRf7NX/z2J2XRZJSPbBlcB5l9vhEdJppK2fBLkXkwkw4axN1tnFrF7KF52YGQ
   ###kF6bydonjdPWWzx/ax2+0rzq5tZ0UveqaDCzdtv1vajr2kyo2BBWhcbp+dVl67Jx
   ###fCkPzlKOaN40Xr/htoW4yjJHGa245EAXUWitdiU8V1Fc3QWvxsXH97UJMPGFFFsN
   ###2jEawpAmk6Bwy0BQ4lgntJid0IRzdFF/SwuSTkNiExC+e3tVw2sOLbMcnbTNd1Jq
   ###PfxE/6LItqr1bW1v8fPBZZ3QqWgNgD1aTDe24ztHtwCPosQ/Cnt9utYD9G9WgIoR
   ###wi/FDy4xh+fP8OKuX96E4fWAg8rHO/B4J37s/ZcLKulRWNpl7fsgLH6ogDZeqcC/
   ###ZRe/fiyZrmNzLxl5WFvZ8BDFFgPEOrDnSvROmCZxsMe0tnbTZOLjo9ZJrRXejuSm
   ###VxYUd51VpXahVpEb4zX9FxspbfZ/9C9BKOzNudCQDs7qR6ysASu6ZgE8haTzVr3a
   ###2uJ0mdBo+WF41Y5fK99VcFdJw50db5VMvMHXysZ2z3Ly5c5LNFkznTqS/DOfOrqs
   ###qdemMD+fj7gs0sHZaeOAST45y+0l+8QB3aCIO/TYbXss7ggpjEZUiVymVGO77Err
   ###1dlZ8zLlpNy0rFv8BLSji6gX1DVz5zCPbeJ+rfOO8U1abha5epg4y48491WTDzLa
   ###k548eRw3fyMHp+uTCofUHNLYXjTdsgu6vK1jzFBSAXN05HMdTMaUIstAZSpU9O6I
   ###pJ6zi5a6/Zr9YWs675L4nYcUsqZBlS0yBtrH91nOK/oI1+x2GZ0wU3mlOUdzHEHE
   ###Hhx3wyHeif+MynOUkyanB8iikqfwpizvR8umFd6JjFN44nn16uii1Ty5fCP3l6Ky
   ###wMoZDdg1yqgQZ5hCy01tZTetpxGuObCMnsazUp7RSHqPo4Ki13vZLVl7jcw+Rm0W
   ###fmlbKNvr2vuI7xWEJrEaNfCvFF/xnzX+I/ASGbsIZu9xEeBnxH/cqm5XzPjvWzur
   ###+C+r+C+r+C+r+C+r+C+r+C+r+C+r+C+/X/wX5TJgUipaXQNMiTWhXekcdMXNnJn3
   ###8C4xFgeKCOpO0u5LZ1hgvLhnJ+7hKV2gPGut/jAMFYuI0oW9PeAdh3gsclg/r58i
   ###Szj+m2nwOBv0RWwdqC7ugfF8r3iDABOwanaIGKbhaHZORY/hRQtYe8e47DQ4IvX5
   ###3B/zcruZ9xAi4uOZnvfiZGvPSnGuwqLaGc1QAfXHPmKBmxLo6rdDRgCHDsdS7QaA
   ###j0O/18ZzKNjKZOZd7IphBMrV64pmctD7x0sap3dy5TXxXdiatK9h/b11Nz/kgfcR
   ###L8dsV59tkq1jpVHm1f+ku5JyV2JhBTBb/3Or25ubZvx/t1pZ6X8r/W+l/630v5X+
   ###t9L/VvrfSv/7/fQ/mRAc3e5g1i9qOCPNFiyixuFV7bh1evE60mPcSlT8ov4aSb3x
   ###dyrfOoIpAITqH9cvP+tRvJoL3T/8hfAK/3KPwSXwJu+XH+8xFg9Ga/wL/fyRfmKY
   ###QiPprym7dYaf28KPdZYGeoZ/3/vI3YF/mT7rj4gEM0P5VVXAI4uXch4F2ApYFANs
   ###OTnAowIcjV69DgFb0Ti4d/C+xAbmcp5z9DB3Ts7RW8GLPBMLIh9oyGGPAk9R+rLB
   ###pxsBDnOEbJXgD0E04N7aucK8WtT/wGE/OTJFtxnBkq8prvKKqy/CGS325mi2eyAr
   ###sM6t3/kUagQmo0wdUnDV6Khfbwjaty98PDUFMpRBT+jrITw9FBHCUnxQM5hO8qg8
   ###4hmKFwIPh1jJjKZ4mB5JcX0POY8IxsU6qSHLEHR5jxsS1njMQ9WAIK/BqLwL7++E
   ###0zuUC/EJikkPdyAbj4OONW7b7M6a44yq/4TBFvFy0S58pSZ+sjShjJkv+FYHb5nR
   ###vDmCsg7J/wPw8JPpcvU1EZUA2ulIzBUV1EBH7O0HSvuBHmpNjwiJrdtu2FyP/fan
   ###2RfAjItU5u2bnBjnUS4zxgHjTyyzdIyp/uKxayhdBRxPB8ngldqqW+OkZ48RxyMy
   ###7O1l7uDq6LTlTotKLHh9obmmA42ImAxvozB08qpdaOymAVc2hHdY5EnD7y23QS2O
   ###n1G0cPT054ELZfRjfl2k4/tk1gxF3IpHfrTYdxYjUDHXfgsICHmArtNXLXIfwbsM
   ###dmnDEHwovIkc+4Ib3v2Hj7k3PC3w22zk5Bl9+wMmDuLj1y5zWMBHN7WR1v1251aY
   ###mW/b/d6Co6e7FjMwIMG/Vf2x+SWNfEH/0rd79Q6uMwN8U86zCLWXA/mzwEs/MifH
   ###6AfTu2uKQ6QstkeCV5dpnpCHs8pmCzvixrYlTt4adiSKaiN+fIBdCIlSDbkDe5G2
   ###TtcMsqUL7rjVFeTw4nA/4hfedJDDFl0Rt9djbKwzy91sCgvNMwzQKsQ7yMD/J9za
   ###pEeETC4Pfr9WhoSJWEbEXdXVih2Jonfyu39cIRJDcBgPbuqwe0owthZdW4+/xoMR
   ###GwHnchXLddmiWITi2ob2IxGBSMWpBlvFWHy/g0N1s6C6KlQ3D1Q3C2q0h0bRmMRW
   ###GhFNYu/MhW9X4tvLh+949F7W6D119N5ScB5DrmZBrqqQq4/G+2/hBZma/3k4njzO
   ###6y+3/99O1d0yzn+qO9XN1fnP6vxndf6zOv9Znf+szn9W5z+r85/f4PyHLFBo9EFW
   ###hBIQK/ba4jJfuw+aSfcB/t7hrSJ8i1GhMG9ZWHohbTKvMGZ2B/YleHJWHJS4MY0y
   ###nIn6akVdv4Pq74fjqD5U/y+vJKuL0Br9lAb4cKM8dbDHwsj15HVmSuvYzBPIMbdI
   ###6uv6ZITDK2/ZuarbTuohytVAdPMpMF/6knKEMZ9X4VrQvU+zI3F/LwGmx5m6RFaU
   ###cXl+5f7YSVfg33FgOYwXc4H8IcNmcBqZLOiApjOJKWI0DMW+O9uGoMwnHe7s2o5R
   ###5jkT+YHts9hEqr06zny1B1WVCO7vx2iV5hH4hUsfSgqBOrlm+jBhpf4haaUGcpH5
   ###sgMzmxXSpWwxoo/rB44PDEAgV4Gw0ZhQ3VSo/Lhsj5n5XZSTCEo+gz/4SRJe0C2K

###evtY7ycy/rOfLHlp6C3PdM44EDyJiANpkuklkVcrwsZPUZZ08ZPXjWpyTCs1YyO9 ###AZkTjjptCagmxN2YmnkNDVo8N40evxlLsdKPZWwdlJ94EE8iRFrgcVZ1XsjRVheG ###dAVha0jevBhQgh2cX3HpjYxGkaj+g/DxVSCJ9ZWY9x/4vB/nn3c0nShz+4M88DMm ###NiKPH3gOx8XI43EksjiZJM9z5ieX+UlGPelZOfcu0/7TuZ2Ol2QAmmH/2XY3PcP+ ###swnlV/aflf1nZf9Z2X9W9p+V/Wdl/1nZf35T/1/TWGK62EbiUTHdjZY7A4V5vGjn ###8TQZ+70+RRJVXDxikL2+b4lXWhQmCtJkS3PndIwjZmsgG/Kd6isa8hhcvg5z3S3N ###Z+mx+UVIkHl9JvL7UWAOxoQTxcEH1mwc/4CpCLkvBJ5qc8XkA3eJMCtM7jAxIv7x ###HDbutGIvSM3qQf3f29v+9Vfx7Vn0za3EX73462b8dVvPdzd60MORp0RaEpOQ9Bg9 ###oJA80otB/uK6lxIo/VOcHj29fWsSiNf+JIUstQu0hCyMM0ddEEiu0PVNmclbZkc6 ###oBfCfcD1y897ibRC6DCHkgDstEbEsHj1iGB42jTp6QhsiI0GP+CDH8jBg87+CX5a ###3CSJLDhyBzAydXS7iYKeLMgHaBRItoDFqf11UX0tGlGippjYOPgSr7EuWkjW/GqY ###ZS64e2NKKHvh/KhMDzlBrnTsf0b935roY0FbwCz9f8fbNu//blVW/h8r/X+l/6/0 ###/5X+v9L/V/r/Sv//He//RqnsKCcdF4coTzy/NBJ5NggfDvEe9rnwRYYaCkVBRi7v ###a60Sx6hQUqngqacW9axFqRSVTlzesadqy3WBZUSZvLKvkEiTwznP2YadiHLApd2m ###yXmBZZTj/o60BSjgg1k3eXJe4YBhtHD28twgafqo2GIWsi/xtD/uBkkeb5Loti4H ###Ki/bYAqOYNSnzW8zp+UjYcXAKOoOXs5sVuA/12bAkBjCewAu+/VX7YGnGihExkSS ###Ja59o4M2P5KiHP8TVgVNek+9aIs9A631vEFpVkU5kTCuEOecHA/vgzuZTpguFHSG ###YbEX5fnuMHFNtcxbXKM/cROYRxykjuAXX8RgUxKURwN9ieM0UpiS04pYwWp63kri ###Xqqto7BSlU5SRbQa8L6lJhKPYboJmO5MmDpiIpiUExjQZrrMXIV+KLwuOtNxiElg ###/Z95gvIXNJGD4mAN2tvTsE7Pi4OyW8J3ZfnTo5+qq8ZmdIkRyLDNJiAmptmzxDUi ###NIXsQT0tXDhnXmQl4QYS4CfRrzU5uCLiaB3Hq4arVuq6Wl1+i6apZG0mFHfoIQyq ###WbG34mmteEYP0GzTrKT1oKrV5fdJVDg0V9SDCvbAXeTGSJr+Pxr78bWdR/oAZOv/ ###nruz6Zrn/zubq/hfK/1/pf+v9P+V/r/S/1f6/0r///30f+VexRQ9jTGDOfAK4C2h ###MA8U1ti5lJdoD+oFPHedCK8QXXDnymkBY3Yhw+vA4z6q9LHWLuQuQ1ePpTEtuPTa ###eeoNDE1zydL3wwlFBtAUblIvc9S9//LBHtYjR921KCXNUePCmQ8uZopxbCpxjrpR ###0jRnobo8W1pK3axA2P32jcMy+pxZ12ISkHVR943JR+ScTbt+XzAyutvHSbTzIRmv ###BC/2NImuPsigDu7HbGPHTFgJ2rNFhhE2nQ8cDx8XNCsxw2lGs6QcqO4yfHgfHxHv ###jq/3D/aYL1rImbRBzQGr37677rbt43ov8qv32tnXr3Iap5gtrksUz0Q4/PRmmOLy ###wsryARJxQ3iRov/ZH5TmipsC4ntgCZvS7nQcxt140DciNgrxRMnSjoXwUsxXvEdP ###0CplWK8MrxFpwhgkfWbOuNsKIBLE5hG0DVoOd59RlpVwFuGLVQSV45RASSnpqeZB ###opTcE/SJTiG7dsjtfj8DshtDdnXIRfkcbR1l3stSohPcuMJRHN0X6aBljvvmcFON ###/h7NicPhiOeeM7oXWgPGefyqjnBOCtBW5CXcc/KOOonzIGXkgbAXlTmmSrorjlKZ ###MODqrxEL6xINgbgqtGYpOGe/XbXf66mzFggrVXLmtL6vW2fQ0v/kNH41aYGvmCQ2 ###tJakj5UNGxTZaGCQNZSFBmKTGBfTdGlqg52gcj2KZbfpgPBX0E5SNFvYHyLhh7Il ###WNN+5E34gX8XSPgx6/zIJhfODDabIwRb/vBvuQOONnke+lzx38z7szapfO0cqPCJ ###TEwhtILE7VqMUOqgSJjYgrREjY6QdBWZNRJBEzVfKU6pCQyt1S7cuFby9eg+0R48 ###+5LePRDaKcRRooTQJyg+FKjCtlhjSkw85YqxP2HTERvx87yIn4/u0VFR9A56hD9E ###tzAf+B47L+/DF0D058dkt4+dPt+1xwFmGAm5Ha9z2x7c+DIooYg+pt5wfVSi9HgY ###sxKAf9UcVE+jRLLQtUgbzcrHm50s1J5g2MiDquwFOhlwiaKy4W2ZIQvX9H6kNfD/ ###s/fnbW0kyaI4PH/7U9Sc+/w8EkhGC1sbw3nF1uaOwIBw23O4PvUUUgnKSCVZJbH0 ###jL/7GxGZWZWZlbVIgN09Uz5zGpByjYyMjD3YW4I17TdY1e/1tbXmOkuXmmuAxvwr ###oAKm3A/WWKY0ahpeP62pWptbac/uaLy9VIg7as/vJi3ltdQePseWLCMf1i0+MFyd ###MCoXw9kBC4YWQMRidEkrz5NHQsT7FAghl93lilhgBS5gRS2bLJXpkW/BPZM67LP6 ###unSaFbXuu5InUvmGFUiGJX4Q6d/krZ67pJAuoY5m8FhGHlkp/d2b0cbDqsvucHzj ###wDZlUOyG1dwleCOCIMnWjmdXIGg1qW2smHTyJVrSa1ZbrPL3xVH7QlSHMladXpJq ###W0tdFNPhvdjVbphskFNjJh7simyAeMi4jvenhuwEPEdy0lmZUyfT5F/Nk39VJ48+ ###rqoCSsQZRusjrpW1T1qQGEbFc1mRZp0i6t7z/6iKp+QXtsJ0NonTymiJz9TydjLM ###5EPKbsgAEb1s5vfB9LIJWHwv1JKFWvKnqiUNmfnjSWYwmw8VbLsZ21ezvg0fxBhK ###32Zw9e32If334jTOdEogCEJQxllaaa6I87wYoTUOJBBgP9EgPIUHw7oL2UCg81PX ###6aGUPaN0MJRXaDqZRblBpGE5R4EEjH+6pTfBXapNtL1H/IM8msb4R0yJ2khs3Zgi ###R1DwWJ4c4GKRDzWllFf0W+9b58ecFYH7YV+0TjvI3zZ1RQHbIg65bD7gMKsqnicu ###X2qFaYpxgKpxOkxHDFSubL2mPsetzt/Vd1XwpKaJluecCP5lTFR/nomWM3fUUJ5K ###U2J/NnNYYVETG9g9wvc0wq8lollSjlu4Y4RMSpvo92UZ75YsHd007I2ebo/0MWwF ###W0rTkLGW+lVpHdKY8ctTin1WJY1rBMEtU+/LWLcvfOrYPpCf8bSv2coE/fmuRGEq ###VMO6cjA/0Uh975RrHAbh6TdbucdKK5mqGaiHeonYVct0BUvy/8KRDPLBQp5gmfl/ ###N/T8L+vraxuF/1fh/1X4fxX+X4X/V+H/Vfh/Ff5fPy/+K1KDJHBF+aKqSPqchCkq ###U61iyMhjZRW5ysZSaTxx7QEIcMtcZYTCXDl3EcKH/CUYZQ8V/gomlprKOf0u472Z ###8nrJXBsqdCSB3Sv5a8LqL/HCUDmdSYTSzEqpShXGlGFbFF5zVNPKuXvPv/uVlQXJ ###nv6IpXq2vuWozfQCNZkiL54EiP/pajLRtcmIqgvPPo7micgnqbniFtUHVnkJfgIi ###4e8Gb6Pd6XAsX4svxkJOjGokDAGIZV+Hhi0FBrcVOYvzA6/Z9BDpo6RCTuwvswU1 ###2Woa7g3HpZ9Vy2i9FKskDw1xE25juZElTVUIFHPpQQY5T9gb0EgWgXFZr1GpuBAB ###bREkXDKVpRWcVLT+yxI6mdcmgVYs8SH8I+bD05ldkXxjDUb+dZUMeDBBzzP68YQ2 ###mhqz0UhQSqpnGVtNdZtD7yspmcIzlBGR6dgyKlzGRl7a1tAxhifLy0nHwq3vuvlf ###R9Xl7ZTTkPAS27J/Wo+tIllwvvw/alq3J0UBZuh/1upNPf5vvb5WL/Q/hf6n0P8U ###+p9C/1Pofwr9T6H/+aH6n1wVlKSy9noWXDUTT5yXSqmqBO/gbDANKsaMwvhVmFlX ###GnNvNPOn5QUVFUvkBbTvTKUYIiEPMwch4M0dqs7LZ3TnSWJsEszDGTve766m/Rlo ###YUQLVFUyTalDy6x0kA9x6owDtmt2yPkzCntS0dzYvDvq7hWpLdZ4W20cT8Iryal6 ###57h4ynFLiKWK/yYvBea7E5s/ZMx3TkKO8FcUsSvaNqowaLkQr/5N5L+oZPHTC8Bk ###yX+1xqqe/6XRLOS/Qv4r5L9C/ivkv0L+K+S/Qv77ufVfQFAIZkOiDt9mzoQRCkeW ###o6geL38xuJzmACUYzdAdFFbDf+Mxu4K5KiULZShzVRKlmR5nuw2O9sCZi29XGT/O ###5xb8f+T6vvpgzfwJUGcgVgOMrQ9LOdAGKG0lH0KMCB+K363XVu3h8PBwb8sojkSL ###YKH3qwZRBD/HdiymnIUNldhyy+rny6/iolfUop7Qs57Zs5HQs5HZs5nQs6nVSgE4 ###A08CT9ujVK00fCvkBJcq3JLENxlmphWosyvu+3yAHTpYIa1NwqoehBuF6FbIf9MV ###DBXD+K4eFcsJXtD+V29u1DZI/ltr1hrrG2to/6utF/7fhfxXyH+F/FfIf4X8V8h/ ###hfz3c+t/HAI7ZGH5RyRpMfdkxdpn4Jz+EDmjkrNFydNn54ySp58jZ1SWhzR5+KHv ###aErqKGGuCxND8hoo6K4d+nQunDMq0z1+wZxRWWH0fHm9PUr4kT39BTxxVINCfmxh ###ISxhCL5NyNakpz+0onj8GEw+AX5rfupLiu9+usNyurv7J+Ab9E9V3+X6Oh/kpN05 ###tM/qa5fxpFEpLtcJK8IvJy7zycah4HqPMXuLtk11JpauSslglbTjoecfsU1H2hWW ###2oyyb+ITLxKdId86DfVIsvwvKU/Maat0hYAi3OvZaZh+YIdKj8jx+dHhMCtwneVc ###MnaPerGD83j90G1tlCX1b0UD8bQUWSsySZeuAm+qfGhoGYcQX8VgOraH7jDKISN/ ###yT2wwwxEO8YELCypjuo1reUqUrzN9WXRS4Hdyc4uJ4q6OMV8tBW6ihUlJxR8AGsD ###UsHyw4VUU83LFFssu3h5EzBF8RopENN2KnLK0JbJ19+cmIx2TqEttHWKa0kGgAlv ###4Msjv+c+VKI8e/LXpwfn7GsFIgyScvvhjBZw9ov6MXxGW2mP7vdGGADy4KHkYEy2 ###o4Fgj7+GCIGg6wxM6bcoQh++c+0u7FTaeMWS3l/pOdDnmLj44vP4MPYKmuYw5vaK ###CF/FekhH+YrpOLJwTNCAp+GZfvnKieWPlhJow8eTVOqgteYg5c+5CHYbA0+IWSlF ###EFKFjhQ+uXrEfVKEFgvKkkaLAg+2swCsRCuwlwkDccITSg6Nyfc0hNjAsQ2EdptV ###qmO4IL2HPFRJoeCVmOo7MQ/Wcp7Ti282JQtW+pCxATnIc+Xf+q5eFaBngTs1055a ###wq1XmaEAaN4IXjiJIygrWdkSaLdSEyyyFJBmzELns9EUsFGEApHahegBkVapIpm8 ###xL43CaY24avt9PHao1JtquBFxKhETz9yOafnB/sgHIKsaZ+CqHlu/9o6OrFbhyCD ###2ucHnYOLhFuojKfkAxzdl6xGJRkAK1ThbcVKnn7LNMuKSPS4DD83qJJWYta8GHTD ###60WiC11f1BjBwqqMUMIFZ16HyLKBUNd1e5VQjzXzDY1mPmumZuqipx1mo7smv1OV ###kK+tKPRY2qFUzi56VTuHgTLDeDKC1y6wcbTANI0EFAZ1xOlobu2C3dFA3/A7ef49 ###Z9CdkcOnXvSd5cLiMaouE451oThcrOgsWz7lBYJAdzK5VgFiXL/OpFZeZZGnBV8c ###NbfPSI7J47m/6OyZ/th3H6Y8NSx+SiFs41HkCiyTm+74sZQCfPmIBGlJOypcK+D3 ###C/j/oYTPackTvQDT7T+ra6v1ZmT/acDn8Ntao7D/FPafwv5T2H8K+09h/ynsP4X9 ###5w9c/81qj+6tXQ/eKWCUMT2533P87qNVau+en5ct4qWg4xv4Dl8cBx49STkGBIY1 ###YdQB85kDIbviw6UkZcbRuUWnsDLlNPP0s0uTGMt0/eHMPPQOBSOr77Dc3vTMhOUp ###1KpwHEd6I/u31v68qGK9BKoIo9RK+hUWun4UsK0W6kEwFf4+3BslPUqOUWivuPtf ###3WmnZZ9tGsXlUJUMJ78762vF5RegQZFm+M6d0KuPlkNH7ARQZWTBqohT2r/4bPUp ###61SebaXNqOuF2LS2mBZ2b72zOkftv9uHR5+RNHYuSvgmHuy9t+GhOPoN6LINy7Ev ###3p8jS7CJcqZcYj3DmsOMOScfmD0nHHLLOIA/YvZUCll0lRQx+j60prAJNN2xdZOV ###rmPvHgAHcICLj5coUFaNLdRUyUyzlTXnDqmriFPY+wj7YnMtL7wSffzttJG2MjYU ###/dOyQJu64G0gfNNKCRySvptd6B4rrJKg+0vbh76GtMWmt03CL6Hl33ri7upKkbDY ###hYLry1pH1NXQKqT8MsENtSd/iKdZLLHZSGg29ncfp27wYTatZOUnPAkDpsfOIzy0 ###aBaBrlsp07td3HvKKsfBOdZaSgOB2D1GZE/cIIB3j0LTmUpuNnGf42muPLcHRp7p ###h84DMJCpuSEjxqSPVv232McbzoZS9PqIFQQE3jGYb3pY797ueT6+6BDT+sMegesg ###VQVwXI4/rQqGdQQyLBPmDSXTTJyhYAgNKewwyHyKxkjY6hH90gfy0rNn43H0B/HL ###aAqfRlRETaH3wG5ihZIrMHs5+8TQGDnEfG4fkceS1eCuI1qxs3bLPj26AEIO34kh ###lGsQYjzZ5yra3w1pUj/4xkiGFZx0zkRz8WtjK37DA5dc0LCdz1CLfghwsT84INGo ###dDwbTMWX4d/0vWFwsnwe7VfEL3JH/NPQj/x6woHPNg3fAmxQv912rsmCT6s3YAVv ###1glfBEPDTcoc5wRTNBNEo5kANSZLAtaqSnFMmvExYW5Mro9jXVr1xsaaXMOO9JZe ###wGx3g0dr5vsuGmlQp4ZS3hBjgJB2eQMU/EpMsCSrXrdbJn3idDSyenCf8YJNXGeA ###dd68qNBIfEOA89K5hn/RAcBf6snKH4gWNb5+06PbwbIoqlmV7k3Iq1mvrebi/LGR ###V+aFAJn0dcrzATIbHBwTctHsHfZ8boSD8+gzhmNxvtm4kjAZIRzDtS+0j3ALJ6To ###ZMsgVSCxB7wjJzYSZ8PB90D1YZZTfGq2+MRZU2hUDKYIPyFD+DxTsF5ovZtEXpWc ###z5kLmiHYDvwAX+JgOBoBuK7g4O69HqptJ44feEq13vnGZkqPU1tU2bC7s+mo31cl ###uTdB+zRZmqvEcVn3Z1pZTMAbP1q+ex+dWH8CT1yUxIYj6QIYKu09wCJ/DXp/bIo3 ###LYXYRo8Nqytz3BEmcbHNwL59//sTgWK1ej1r6gEB4xoR2KNDKoYb7/rG2jv9aBEf ###SDrvnuuj4WVAlmFaL8U84n3i3Eqi4+Nm3JWF7/Eyc4uU+XXJKiXvZ2eHnA6+oLNI ###CYT7KhbmASLWIAl3yaq71fV+zHvxr5oFtu8NBsQFlZPckXKcKAcreZaPw4zT6IYD ###dwTgy7zN466Di8wjOaYT2cCZFN+z15FWLnIpDJFL9UHLsyu5QOlcm9DW7OM4No0T ###ubRlLVxwe3Mtf67zQkWsM5GdAhTXhxKeHXmGlhc7uYwzVIMLcp1hik/hIlA4Zd4n ###SWnJFdljwVkULxfdTVTZ7VN3pm/NjaqnombVj3B58qS9xTcn1xU3bAxkkSdisbIz ###k5ViyjQJkUb6GQ5Nt0sk7SzZy7WNuQhGdwDvb2GpSmQAXZQaHyU5W5gGJGuJJFEf ###MYXaeqQhkuQP+EJXgdZJ1Sl7XobypaqgkqRQ9Qsu/2DBLoQEQ9ujfbMDPMkdR+yP ###ZA9jbehwOdV6/DuxIvk7wZ2MOcOHFnJe9nOqgUzxUXqtC6eyfka4JnFpVvF41EaJ ###xFWVTYPPK6r3ZCTjquMJQVaTRGQhJWptkiG1jlqTWF9NsDT3jhrpnrpTjhSYzoEJ ###Sbr+F3mKEFO2tZM1JXEnmU6V9LTM7JHy2jAwQ4vsgSWpPbXQYFiIOZiOJm4ezJJ3 ###7jE1es24IIOrXIR1MZRMQ8PEEQ1oKGNpHpRM1sIrcnOIudk9NZyEzsnKkBzjdGRt ###eZq+RE3vbzjl+d8AIxsoOYuGykHDW/oc89LB4XneTxxE6KQ3yBQ9YiRSCvc/g+sQ ###0AOmPFpPeDMleHFDw2nkHJDOVj3DrLK9ggMhbhqNrmCyLYUc5hOe9GeFzsFD1+Pu ###Yp24cf7loMOOvpQIjrilyvw9XYMP/X7gTqnRKzP3bMK6TDndRNvh+k/dwUBeuLE9 ###0mZuB4C3o2a9fs3fMv4HG+/dtrBVJNLvq4nr3JrISwqxCR+G7e2QczONj+1ktgzW ###lfKW/utffNU70qKTli29aNyOwig/aTRA3Bt46LU4FdYNcvPseT1r6LrM31MwoVez ###3rU7NWHiPK9bY87nTQQ5aqO8GQGm4amRsjrP+xitqbpzNetXZJ13xTz8k5/dxuLv ###LlVIfqNoxjGQKkn1n4yRCahrQNQ4TmUjqnKldrZJ45SIh63eV/S+RaQKBaC/BRZi ###1wp6vo4mDAUnTg9g1ifZCF1rnQn6Ibt33mgWWP9F7Nx/iaTPifjIH0QA4fCq52AV ###n/qbtb4Z6ImCj/wvTRrJ5Cvjs9TNs6h2DvoreTmKxSNmhMraAP87k6RFTDinlSGG ###VK0143mrEqZhpwbbTrxRspHHtENZSPhrHunDJH0mgiRJ5FRIah7SGCeHeQXQRNIo ###U7a5yaJCBWM0MjZ0LpIo078FpWOlIpfRPJhCKHNitFH6++RNbzwf8Jq8DeCU2bP3 ###1uoORtDH9Uez6xvTSeejsdozr9CEMqOmZfPCOPGkQEmn2x1NhLIIDRVVeqF1Qtqd ###Te6MWCkZinE8u+9QBO1Zfd18C6UGQgc0GF03Bp7PT7HdeX90eCEIRDXy+9igWMhE ###Bm85rqxaZ53KuVcyhE+bjZL+dSU2NGAj9DIOnff5S1uG85BvGfU3zeSFfE+mgqTb ###o6k6xx/bn3YNU8lty/k1HjJqURx4GOinhvqbl6SR6WWrxHlX6XWq6q3KZNCK3hH5 ###QSgTzpSUp1BrsWUUy917tochzDMmvpaifa6Ad3Wn967rW421/4+4ig34iY5Fgx5c ###GiBwVskfTXnElbb0d9rSy0kKIBkqO+ygWvv79jldDYEZye4oMRhVuPnun+nPf4QW ###T58tiaHJ3O87jpgfd00r0N1xnmm/T59tTmlu8ZQFluaQw1LUSKTT7rRoF8r9DnlY ###6vnR/xZ21q66puA3LF0Ouo7ld8iWO8KVDOQvToEn34qnZmDmAeLwc1kIQriYdAav ###UxamKGbg7dz7sE8hMftHGFzUarf/kSPDiUiu4XvfZsDl9lwAUt9jjocMUiy/hA6w ###F7CJ6Gv6cOdOMIQOQ/SjkHS2KHLa0T9E0tblTvlXTvcW2YOzGhP18aky1V1dGJ9V ###7BQ4rWP5irW+ttZcD3NCxC/ady2bAa+ZanIwEWzmcHTnlhQHpIjRpD8vk1kOKQdI ###auqkbNcTesSSEmWI3UhKT9910TmbjK9RaD3fmh4N33auI1erENQiR5MRg6qYF3zL ###OJqiOE/X7kVLP3jwpmFkJ9kox6GRMiEkI9mLxDoZhU7VEhpK3tmq5B2m755q2S7m ###9WE69Hzy2AlnT1E+zzl6niQl4aYIF9gKEGfElCoACIvOOTNt1HACXm5U0NuHn5MM ###p+8iaq/6HFF7bqSQdqZa+F4Rv1fE7y0Sv2dK2nhrcF7O8F1WIHnhDsfGtIysbQee ###9CO/P+KvLx41/5UwFS6dyWJG36XH2CS7sWPfp7ldMszC+0mulleUnxVX+ySqlRhJ ###x68sep/2UJubEWW3E5NpaQA91C5HmB31yx3PFHP+8E2G2JAyINAU4yw/W8YPTdzr ###2QCwVBDEFI8RcaaL+3qohggZ/5IMtmJYHX3LulNRx7nDdA3eNb5zcd5emTq8KoaU ###Q0lZwVIZHGM4o3p2pNP6178WOXZiaMxKMXrY4cWNvObHwO/Ce0uJK7ipgH0Hkj27 ###O2zQBLlHLIvxXqr0k6pq1Jd15HcnlMLlV5aHa2Sh1WzqTPAHrWNi0BWrSMHPhH/E ###U3Jux0HIlsHmC7bmHFBSn3lMUsvoUbFO7PbBbwftjn2GeczofMpyPKaMl/sucRF8 ###/wwvMSnNI3AxJLz0XPaO6sjKJKmeywXISDpMXaEqO77OPNZnkR1fWEYj+eyWyWe3 ###IJ8lCGi3BgEtnvb2lo5celhvWZkdkS1PiGmJJ7qQc+bcrjILu50mucZInF2M8kaU ###/VW6j0IOdiDuPCNb3vPR5zhR1il2fvr8H12xNin/W6wQ8BMSwGXWf11d1+q/rq3X ###i/o/Rf63Iv9bkf+tyP9W5H8r8r8V+d9+ev1X4ohE3U7yarofxQrABjkrwMbYq4xC ###sPVK+veN/5hKsfWkUrGN7Fqx9aRisY3sarH1pHKxjex6sfWkgrGNH1sxtm4qGduI ###V2wpKsL+x8t/tw3nqWm/88t/zQ1N/muuNuqF/FfIf4X8V8h/hfxXyH+F/FfIfz9b ###/gum7hgTk/VnfpfRf26cwqerP3ANeWDUujHJJWM5s1Uyl5ZEGa9VSUzFmTjF5QiL ###2XzJ4fZiFCsncScj4dqSuOH8U5qSkVLnpCmlXZraWfnyTUsC8i2Q/piTTGs6HF8y

I can't rewrite this part faithfully yet. The text you pasted isn't readable RFC 6716 prose. It's a block of base64-looking lines, each prefixed with ###. I could try to decode it by hand, but I'd be likely to garble it, and this rewrite has to keep every requirement, grammar, and citation exact. Making up RFC text from memory would be worse.

Could you paste the plain text of part 61 (the RFC as it reads, not base64)? If the base64 is intentional, the decoded text would work too. Once I have the actual text, I'll rewrite it in the voice you want, keeping all the BCP 14 keywords, section numbers, code blocks, and references exactly as they are.

###SxhJj7VS3eCJIaItg61PTJmkeCoJb0UU6stzW/sezFMehaUtOKQq3CD0NjyWpdL+ ###cht/Lc855RCLLdyhsi4eJg7fecPZMIxFHWuKv9w2TdXbU8asSsouo9IUHKolROk3 ###1j4uBIsgUP0nplsvp08pwFQxANZUazyYOt1bloL0YcFd7qdYZwk9njUYnv27Bc4B ###5FRUdDrdG6yp4DxQ8W0lvDf6t4epIMTpAxzgP3Dd+uzHFQzTrVitKQYDw3/q9N9G ###ssGXDJ7meWymg5uM7i9ZeUMkQGRyRTUiBg7v2Vj7I7lF0sitvrE9GY5h1NZV8tcJ ###QyaMKCobKWbMJCLJY5klEqsothlh1MwbcGwgJqBp904qyxIqs/dqQp/PyBsjhg8V ###ueK5spyyahEjxYZ0EKTSMOwzMm1xyJSVwOmA+ScHUql1+EtzUX4QBkoAdKCtS4uW ###9imCFX68gxtD0Zm+IZ5SQSCfezEvc3h4PgDE5owuB4uwTpFJjC6FDJoqjFHeSg5o ###FAbECCkrKuhyw02c+ZEP4gdVUAvPE1GzRlG1hMT8V3xOWXT76Z4c3U5f1N3qL1zX ###zK9tGE3LHkL11kc6ohDUNQ7qOJhhkR/HPbQ20T4pkJwkp8hIx3Pfhb7+rCEPPi+r ###GlgxGAIwz1jUjg8FpwXiDSO/E5fenp54Uo2TIIBa/eTv+gNvPOuVWv2yVco1dH5U ###z4/upHYFMkqGe+iAiPwl9nUj+jqGstWIaiXFI/vJ8cjKHcJQ5Kq8EEw9Iv6owteG ###udggEZnGMaRBzMuNxo19v2yOg8YHBzaEd8L4PcFweduwXMSCqSl0nuC6vJ2+EmPv ###72nQ3k4FN98AQoiWrAHYBFwkCVGXRgbsDEf03ZQ3huGcRkKljhzr5KNVvs+JY2nn ###Js5MniPz5MSpxYh/UqdozwR8nz3zFoP/1isFzMqXDcVIJRne/RHwwGRvQrVRz43+ ###7o+4XgcD5hk/Jwk6JZDFgNqVZelApi/AaxHdjxYSLY94L/FtTf+mL70Xz3pEuCTy ###SOGrqibeCbZA0fKWAzKpZZ+17Ce3/K4aYQRvxTrvoLApP9axNldRG/MhLn5MEwzR ###qjZg8CWCz4ollrXMp05aGPTcsarwNKMxGv54h8+0vkT+QiWJV7K1md1h8ehzQyuc ###EQy9hP+R1kFZVbA90KdIuovhAnpnOQ+xSV1RXs5CE7lZdpfykw4NQ5B+3OlOB4/W ###jTfVk68QTINvCCS2BWmNK+EOtXQVuCc8gB3NYi9t5sDHko3AQmPSS3jUk9QONw6r ###XDGaeNdUZRWFTVOGGHb4k25qBpuQC4t2obY38GT1DMtmNKhKt76bkAe3wl0VdfcX ###E2EoEbkpk53fTCM4qiWR8Qb/LpFLEM+e+Mdfv2WGqpEEKbeXiTp/+qL2dROlYL2w ###NR6QgvsxiBsw/5y1MaGvQHz0rGdmEtXn6Hd3MqLXAM3glD3IMmVZQpj7TKC5ZQx3 ###EqMgAGbIOKMim5bVx4gOnBPG9dGvVynIEC0wGQ32jHiwpx8y0ng6L+nxWI7jhvYt ###k+ESz/l75AqUeqaSrxgmT5d0Esn3IOE8WuIoStEw5ZJVFfstm3AR3Z1nV2QQFKpH ###EHbiOiqm8QRBbmFBA/pWTUoAg9xRAXE6abWtMQjLD8zVWVeaykyKYDdqLMNuRNxi ###ZEtR96oDIiqSzKXeJKDC5pNKZnI4Stbf1LbmPtc0xicXkxIuAFvScKYWZvypYkPj ###YbC5q9tJIr98Mb6HyoRzUngnHR1ThysroGm2/jR+Ikn+HwgfwEMbKTaRgSf4gGTk ###f1pf3YjFfzfWGoX/R+H/Ufh/FP4fhf9H4f9R+H8U/h8/x//j6LPq4KEnhhJeHud7 ###9sV7uFZ4EwXHWXvzC/zrk4dGl7PsQgEFdAYtWZpAXCGSmWaPpvTOQGg91l/l84G+ ###BFMHDWIl9OMfj1ASQooDtHbmgwjd9SbdgVuOhkLaRI8N/AyDXZl2rXFLEk85j5Vc ###dyXh3CPuVOUgS7orSZJGriI47d5oGPd/SMvBb6hzJXwBklxJLklb+WWefOrNRvSV ###ycXAMOXcnghm9wN0PIiZ00PPAnQjmHRtLERTD39rxMO6Qda5tBpYRyXZA0AWGlsj ###DGFYavnuPdcB4a/WNh+J7e21FkIubLvYlMKUWLPQfCuJTVE0kmxslSyqKHiy7lWm ###6NkhOVQrkcEUiTifJn2SZgMVxcpF/de/mMK4qnyqS7QcU2uh8VcVLAW4uX040hRv ###6U0aoslK2ElaoVA4bxu+RCexe2cMV5oS2St6RzwaPAg6mvBD+XRu5ZMx2ahvza4A ###DI6+QUtTolnZd1X++61iiURFOf3gO0/wAZAPLNRALHpYsYMSc6QeUCLgDdJ9qJr5 ###d4kDSc3/hln/n5z9OTP+o7m6VtPk/9XVWr2Q/wv5v5D/C/m/kP8L+b+Q/wv5/4fK ###/0/I9caZpnxVma9YgqyTXRvQ5vAcuFLszhNkVdRACExvg2Jr8LRYC/nfJxgzZQXa ###asRCPrn0/uBji2v6NnP8qfe7XEYvb1lk6A7y8d6opwZFmMJA2O7JxjtfQETyIib2 ###YNzNyDIn5HgUiyc588zlLIk9cDDbmQL82FrC6WH3mD7wGVPcfYIzvMw5PTvxwJp7 ###+uTdmyJTEjPsacEpzzC9KUolaXpT1MoTp8ccaqN+H91fMqc/iabnzg2A/ogQMMho ###8pivfONtXKVzxRz3WQW6JSQFUViJXDv8dM8OEwfhH9hQyUgoNe7FMWpYsaBjzx1M ###HRvInURRYr3v471hkviHE/d6Fut8PrlUyZXIdhj1TIqnmfDkiXDDpFSCVyxxGLpV ###XfFkbhxGmMsNfuVagqjZa0ZR5NP9oqmwhNNo6Huiu1DwNaC3Ff3EBGJEKW6pzl60 ###wxWroTg50obQ7Z8VTmTaVj5aRbtu4SiVaE+6eyUOxWqJakNNMkY8nyjrwmO4NVQ0 ###i7nWGMaVF4WHLjQ4y+Goy4mF0MTGKPimJq0Qy8Dl6BW2r9aT/ogtb2mbvgRW5hQ5 ###pRWrqQEVWw0crEBvy+FIPNVbOPdrvj2G6gkzsoRjWI83KhlvWD4eSIUjc6Lfbrpr ###kjhAvgXWVJxdd3TncBThFCVaBM4cbkXZhF5qlb1Gt5S2rBTNuSR9sYyKvXo/IfYq ###gkjXGbj2nYS50XoYrTMzONI492LDGZiBdzDlT+UWCCqBkVTGmJUrqUU4RvR1eE/l ###r+UN6J5LwklMZ5z40aKOVWG/MMnXycd2W6FGGr3H++dW5Rxc0uvAXVBVNXl+wmca ###DV0WAX10VNiKdZLXCJ1M+GP05lQcyfWBdizFG17lVjH+GknREhtjMLpulJT1r8TG ###K+tH1BmORmicu46Sw1moyg9mw5K1W6E0ieKrK/4qXM37oPRCl1ftVKTyJxESGSs1 ###8iEAsFcsRsYzl02+iiGorIaHzQ3pFbjHup9/g1nwqtNe75EmI2o1pR1zyoCf9ufd ###tCgGKZuB2CqGWqReruGGOFZPoJR50CEvzqlwDwucF14yhF/n+AMI3+wZKWmfLAsS ###Vab4hCFwCb2Y12xCrew5jl3wbF5E/aVskhEuVFjKOlM1XYSbNExKse3rEH4LLjda ###jyUjKgBL2ciSNkse9P13y/qVbf8ZuHeeH4z83mxy9STnzzz+n/WNWP2feq2w/xT2 ###n8L+U9h/CvtPYf8p7D+F/edn1//soKaF0Rd8VAaW+23GtDc8Lzx+1eZsU3Wf+Cag ###n93ZRGQw170k4zxWKS37lTuZAKX4eQm34F+mo2RaFVBMTK/NqqaiwiQ9VVktxudD ###0fDLIhr3H+uY6cEb8d4Z9OFHTDk9hPMlBTr9B16d2yFL91RnP0RWBN6Oib31BqoX ###pCoHclIa1ir8Uv5QE9TkubmI1hI5cFj/OqndQn0+jlLdFo2Wokb5J4lk3iFLOjQE ###+Y3gDL+i7PZKTVg9Ddcy1INZdSlwaJb+pnzJnrRklIu9BM0P4EFCxL2k+7zF1U8F ###bNS+aQpTXAv0BVFTySiRD2yEB4hIpFSg6PFkYGA7M0BaIrpcE7zFdw32HYORKbhc ###+S7cUUsNH+YtPSlAWW7ZMMnZqHockkuqISaY7fyLOlL4sTE+HReKyHw71BVs3IOT ###1fRIi+Ck84V+f/lP+5ck/6cYKuZWBGTI/6sba+ua/L+xUcj/hfxfyP+F/F/I/4X8 ###X8j/hfz/E/0/X/EadVSdDq8+z6fZ85zrEc+lHfmApnl45HOK/Py5kqf0LBbe3dOz ###fHaTXdPy+mQ+PCw0/Z0zmKX4xeX1SuQlAHMV3j2hA+H8PJwLvPxP9cvbzyH9i+n3 ###4Rlj1eng0fj8eW6NgSeLyZJMtx+X52Q/lNefP5NgXkGFg0e5h8jlAYEh26QfHsLa ###iPw7kxUzif9PKM21kBEwnf/fqDfXdf5/fWOjqP9T8P8F/1/w/wX/X/D/Bf9f8P8/ ###gv9/rseQP4lLvJIq46KAOPVnPpkbXj3rPLDVHIWLEjPaME7PDaY2S2UTKHltOnvn ###LayYLNcuajTCr91xnOWvv6n/0qj90tj8Zd2t1jaeCldKVMNIuTMYPDICLCAZ5DDV ###PXH2AJ+mrhVJeKd2y3fsrjPokoRnB9NmTLLrTkZBEH59aZ0e2GooCn0Ef+7t/r1j ###dy4A85vYIvqCf9Zu/doJY++aQNaOldIOzmTiPKbJVhSupJldSYBhDvL4konx3DlN ###oMayOAiGqTOZ2gOsnatOSV9gHMnC1XgSp+zHI8nYlLMrK3fo2FxTJpY5midabL4p ###u2FFYG3KqFQwJlSeGoqPZwqnIIumITqP9TChOn3luUGB6AWi/zkQ/enP0d4HYFtP ###j+BhBFao1f5HB5iew48ne8iqvfBzFMIrvYK64tHz28jrIqx4SXf3rVXDa951exhj ###MvPZ73Pr7Zbo0M0ePazOPSIHx0e47KxEV/vg5NeL9/ZxZ+mQiqDPhRlLbMMgQVVi ###fkuM2cJbx3WRlwJ1v8yLjPV16auwvrwhKB0mY+XDn3zLN+Wv1Dr1hl3yBnNOnqIC ###XuK1zisGNe8J+bt5vwOKSCR5i3ltvWXQZrLueOLeeaNZwElR+lli47ZCPKV4dyxR ###hUfJsrtLg7KaAaI4AIjWMfRNwdjAdSaAPtObiRvUK+qUh1RhC0j3NSo7oMEN5lVD ###jRKuo+uAiIBp/wOrRh4xeS+JPGUjNiXekXkny1Ros3tlvpcshBxA6X6buX730SpB ###0/Jc6GOaMqLY8dKWcaJdsWpVgMX9jTtxrQYe4o13fYNpLeeYMqzFlxoyv2YNg/ne ###p+QQ+ooF9PJrzLePhrY3AY6XluB/NFJnLVmbhnh31nM1o+eq6ClRJz4nSnOXOeaM ###9VzN6Bmbs9lAhezURibRvbTWDbsJ8bgiyJN95TlBrN1ejEsEXrDEPwI2kFzeMB5w ###zTDJ3l6coWzYB58vkqP7gRm7dqc8xP/KwXfSUD4zktgq3MEXCN5EpCEVP+2wDIGE ###Gz07gCtO69q3O+cgLTNQGqDfs/GmZGxXGpo9njaboRL9iaPEYTN04LXYk35gYVH2 ###i+/eK3/EZtrb9Vg/+mlTxk5ibSUu1/V77BfMBWAapHt1a2Nuz9jSsAOGyFYE1ed/ ###scg88a0dfIvnn3hW+WLrhQX1+AHC1rqjGaovYt+xqyj4efkvoibaR0gmYkNI8kD4 ###K+8c/W3siZ6ndJb8F95L/GXuA4jB+rBfRB/+l7EPkGnCCnoGtwzUfBN4D+i8tyul ###3kAW+8bt3tKLCPwFSqT4cCETGz1dMjsjYrg5T7m9DcTvX/+S/qw3tL/XlTqx2mzd ###uKBhmk1qtrPNMukiAh2d2Hsfjk/bB5+VyrCGXu+kXoB2Ui9DAVyZecH5MNIea56p ###X7zjOTJMMyvMSNIQDXmIMFQdmK7ZWBExAyrptIIoQ1yLKNOXfFIyPouKVSW8Rhhw ###e3xwLD1By3KtXWhBt1H6HgOf2WFuxYYmRHza0KuGUTefPOomP5K+rQnp26Ye6gbV ###65zSaVVvv5neni+KX3yJEaL2iMtA2uLrkQlFUvtVtelmSlOxCkZKYqtgT6W8CkoD ###LfeJrUTus6o23UxpuslGjhV03qMsMobM1UvyyZeML3tZuknnbsiDj4aiCDt90rPg ###QeK7AwFn08JfpHQdKvFSS0KFo0JH+La6g91vfpfjEmJMYH2dcYHwwVISK/hFy65C ###e24Amwc8AenkSspg/M1Sn65YihZRIjviKAm2Damws8R3lmP9J3yzE7s3uvcb6kAS ###a1wxrS0xbwzuqUH7U3cmv8Wb8YEYMpWVal3aaTVST6uR87Qa/LQaz3FajSef1vqC ###p2U3s8+r8YPP65/mhDAyM1HOC9rNRMiqM4cEYd/tsvpwDuXnAZRYlW/+U25M3tuy ###KoMpC2bp0F+VoL9qGGmVjyR23x7dV8cAcFoVFgdYUZ3i4p0p/7/H8v97Wv5/WaL2 ###mPOb+pEU6BSewPNafUmHYB0enXcuLJINKnA07sQhJhLOdxVvOmv1zFZgCoMLhV3M ###RyfvnRXm6Lw/OrwoadwEIlI5K1VdQh3TkHkmt6d71xJeLhj96vjX5IlDzkOyBSd2 ###1aR178hnllj1V+qwrDM775QRllMQkNK+CJUAxvpFo1Y1Wei5dxxNm2/DUfsn7ldJ ###/EblvoWNLHRgunL7WEVSr7gaCcsiktHzQTq3eT9meZDVLeGadfFU3mWkbbEMBTdT ###hogDAhi9Wo0lIItKkJMb7KXKsBJlUEpaSHtbYTWTo3WVNfAdIufmj+6xWI60eqql ###Q0nXeiLw+84dPOo1SHushHG0GCoM26Ma0rIkbfWWl2M5jgQ0qlVpSU/DykUw8+Ww ###My+e5UKzchxI6MkfOvZx522slcIZMnRZnLhD5ucotSJmfTTooZKaN9VAKCHC8nas ###8nC4RBFUXWKqx7L2RTWtpwbYhGH0VlpdYH4dernugLyrclKNW1Eem05ElKhRSqpL ###tHpbW5/ODbXGY7gyxF5UURJEFXKMKVDviYd4qhDrGF8gdu2xSGb5zyX47wrQjV/W ###pbIxodoDliFmV3SxsIhVwOWGtSSpcwwalyY0UDu+244rimXOyvOxJ+CcHSBv2XO7 ###E9fBBBOMHr4207OKJXTEijhcjVGairYciRU7CLrOGIUXxfMCqNqdO3mEx+Decgaw ###lt6jRYYbDhbUKFvbCWR2Kw9T0jn+2N7djTMlIecR8iY81gNEKkHmTQEUWZxOPL6C ###j7ssMwCXnny/lM/lMIvIerfNQLFEP6JCRnzsFRCzUae2I/Uo64KHYPMlK3etIqsX ###dGZfFbeEEdcypuIMDdniW+kr2eCsfsUD5NXCyPKmVe2jvHv9XBTEix+CWlucaT88 ###v0cxTaFuEa6EaoZm7537gAXAA2oTLU4iQXgSRhRdJiKQdCqWZN6RsiAK5JK/WlbG ###Zck7I3qpy5kmguJtpdegj/6rkBh1GJ60VKOXsgauaq3x5BGyNmyZPtVzh3JzlScn ###EP2+yOGKkWSIfaHUILG0tf7daMAe3SSyzxfc1Ej/ppH0y3vAbJThnyyvxbLySUMT ###DvUjqm0lA9YI1HocFIiK0ZysBDqdWgLeqWv4EkcUpcHychxl/jCw1T5pJkEbmywC ###7dUsaCdBmn2vzk8pyyM1XLnEd1FOgD52SoH+s//jOgSrc4CF7OO6BiCLREQrKKYg ###KxW43GeaomjQ5UImpC+gklA0EysvBAD0oumJVxaYedeBWyI8PlCk/epS9Bi+cJY3 ###RV+TAITdxwqLFouEox4A4jF4GTAYVHnMnqDZm5cS7AfGmplhycy+pqqUEyvFWa9L ###swFLcheJvVYmBo45vGQONWf248jNwqQMkIW+ZIUCzfaVzfZVfprIa8L6akp1bEXU ###66suMiUqiHpbc4utsqyabzcSf8r4tnlUJOowiCjSIneY+VeHBZeXboWUmCwkLlmK ###xFgSqZXkU1zGGJGythAjOxSfV+VfVbnz+0LSJWNWLRDvmacdu/wo9FN1HYy7vBqN ###bqV87FROwOo7pCALHfR4u4oFwqkTRqNQ+KNL0i+2whgk2hTJBSFDjqNShCtznOyN ###3MD/2xSjHSWxmbvvYHHUuqLSYv45DLlxoJHlkMc+49OR7s98FpzTk31hhQzrXNOQ ###W2xz0LtLSiOQ+fArehiC6WSEzsL+aKa+ENaNg6pB1wc4wCTh/hCtuFtP7HlNtYRJ ###XqA6Zx06h9YpT3wzxkqnGkQNA58bBjbpM2T/JNGXkvvLl4A3SjIiaWPUYloF5kzB ###fE0bEdaFFbhNrvWSITgUCLe3Yw5LMhiEO5awc8e95qRCDqEPDpJ42iv8ibfCpnU2 ###uPBU06sqyy/P69eKS4zZI0Y7J/TZ7HM7OFwKZgjFwGwHUBJu9iSCD6kdrtyuQ3Hb ###1HzghE67uj5OdjzK3r+RJGWOEeP29FGkI7ASjqFeO+4Yz4EXFTKcBfSxh4HpRNQV ###Z8z3/ZXxddZEuVhBCXormWxyG8vUKL27quuX8d3d27v8aqb0unwZsQymZIcckS4m ###j5YzGIQYE+hIwefENx4fiz2SCfC5WVZybESHQCk2vlaicyx/yX6RVjhTeoXaYv1N ###iag7qp0VAh9+Hfpgptdv0ABsAgzpPfaE6BPNa3z096JZeZ+teCN5bV42LORBteSX ###4VcVOv+y+qBNnVt8zYJvM7RkTEajKVPVX8NbdOcKEolGrIkRtPR4Sv6u8unsolJ5 ###Orp3Jr2A6ZrZk63gyyDrFehJD4g8bZV5Wr3/cH6BXkW7R62O6iQkRk5ZVBj0wBkJ ###+TyT3tqoZofsUAvLD3dSVZ6mrayeS9uJDrrJ+z49P/jNvO2S0E+iOGOYDjhIw6dY ###9mmtXzYmcWXYHa1gJ+Sbsv/BWxVeVOjjDWdDMjZo6sWkkIQ4fu8oilrFoVL/O5pe ###TqHkMxXmCNNMkHTOWTD2CY9yMRnujA+1dFG/kG0x5oWH3heARpTo44oSoTB2OEcM ###CP6L03LBskpHYsAWetU0R3TpzvFnT5OtONuLPcN9JahaECmIz0XSqmuYT0bAUnlT ###B73+wzCbiJ/NoY3XGa5QMheqop+jkpdYsR1NB0AcJ/EDHia79q4p7ChgEXqCiZeq ###hrl+wIAygVtKvkmSwjCufmagZpac1kV9nX2kQCFTChjojLp9/uHjyX5JNRCR73nT ###Kico1+k6yyKBdlcGcTFjYJAEXpnaY74PPFzeJfKe5w6rsteGCJiQXzzRFTWIYXe5 ###F4+tiCR8bBP2WqZe8bl4IAb1gt+38gQ4AZSm4pFVZUX5GeX3jWFlvviwXAMruMPo ###gfBDN10bVfnAbNKs14pkH9wSEZKzKYoRvjFgUUH1PW621KTrmH8MGpSUlPSOUDZ6 ###IJMhxYZJMIUUiSDN2E5NySK0oJPQV1CKtJHiOqL4a0m00p2EzKH6SuzMgtMoqMYj ###WVRyNDc1kKPDmIRy2G5dYJqaDx/PGd+wQtj8SiVhJDQDw2tFBbgtB6BItQ0pvj8W ###tIGnpYTFa6xUXknaJAxGBJ92q3zN3+LmpbwojZtWRcNtc5yRVupQEQ6NsmHTJBUu ###JNw2Nck035rjffIsOlmglegxiT9kchYYzN2mOO0kj6nYsS0glcaUuUAh4pJQ6Izg ###joP4t/MVvjQoekE8tbTgN1KNfsX/yJfRIKRpG4Ch9Di33EN9j31i0iInbkgW/3Kq ###kRkMyuZdkfM8JaTruWNM2wSXHN2zgDz7bhDwBHQUG28Q/dUVLfEwp6pKkZZEjG8u ###jbW+ybgmQ8Nio+wiJBcQC0wzlEhDoREc47X/SkUhI1dC02ipZ5XGnetcR4xLj3Pr ###X7Mw6rvOoglkVE2pCxaUDVl3UQRVLD1Z33NbCWNhI6XPVvqoEY9Y0r6UWMWEOCaj ###FjoSDHQbtNhA1cRE6kJD2HWzzPakKqxlfZWkxZUuDr67zp2LAGKsj8ZPvTBXl4el ###ez7E+PFIwWNVng0zJH8/3f6XFzXi/kXRjHikYsyougqQTFU3wT+vUUWVIn1akVXq ###3z+r1LN6uLA7G8qgQVwIpRyIktTJmNk31pEoZkZ4eedO2FDY//5mNHAV4zXzfxkM ###mGMljYDWx34fE+yQMrxERLFqNcqVaCA5q7EsF09cSRwWTjgMe97y5zvo199KZvfL ###6mblzZs3lY0vsN6pM0CVjTym6NRQO61Sp1XR6Rdjn6bap4l93oR9Nnkfpcuq2mWd ###umyGa1tT52G9jnz+9eqm8vUb64KSFE+ATFgeoleU4ziMEQE43Y8w/KbrBC4bb3Wp ###3lhaA/LcWK0pA1asK3gFhxSV491iVIkzIaVlvVF7w/o+l6fSPxfIo6JmyvlKD6bE ###y1W4CYLlFLFRuZ2eKIJnBqlYXk96cmPZO4LuxMGHdegOL9VUpV9SUk3QCfN9xFJP ###/ND8DvOoIJSVh2J09KlJ4WASqBfVIejqgvmVHnMoPNLjctNARj5zW3NCLVn98DTl ###xbwqlnnUK8IV3+TgZ46AEGGe+Oqd8igdLGfi9XoD8oBkT73sGZyLn45pBnOqUvH9 ###Ub01Y9ZXMpDrTLl0f295GLSmEifrWVbHutYxVBTxqUldtB0RLKOqKNE3sCTZAZZh ###pLTgORmA71Q6pneTCZ6iudFlqgWjM2PezZkCORHquU9pAVcGMtYCu4Lp8xGXmvC+ ###DjkLT0Eg6NZr4pYQzzRlEIxFmIe8kE3MEGfoI5wMuW2tK7xIht1KgqIny4joJYoA ###2krVScZklmS9pII4uJZlGiENaVK6yShk6GXUGnpCz7StoqMY9cvCLpuCsH0vkhEX ###YuN/hNj4ZJHxlfq+hpZJpGMstn96P4pgwuSSsBUIba+6YgAlaP3pdRgWEySihIzs ###lsfEhFvhkZeWWS+HLMEG6Hn9fiFVFFJFIVU8Wap4OaGBG0UjkqZxZTl58DwMquqR

###w+27uQJuKB1J3a02Exwj+GjMKqL4b0jURgKKztDL5NDAmCufI1WjTIV5BCCAUz7Q ###LKuOUiEHX+cBwIKcJjHvPK3GGNkR4OEDr+dS5o17z++BoKex2Rxe1W0pAUYE7Krl ###mbNfqE1SZK7YeejLxWqStFaSLYD2uFgiDTi31PUuy+u1ql5Sko5qzLk6H7Y8k+w4 ###B6L9O0mBcffdeQTBDH/Y/zTh0OCbMqdoaEb7hCEN9uSFxcu/FP8y6r/i1TlmaLxo ###2dec9V/r9bVGXav/ulbbqBf1X4v6r0X916L+a1H/taj/WtR/Leq//nnqv76y1Lg+ ###Jg5wvw9JGml3wopsb15Zz7htscMhPB2iEuwrWa0SKOYMLvF8/tsS5TqMbC7Y6Df6 ###kvQeieYORSB6qOQJFKIyTQ9i6sv2MvktVetfQgKLaQ+nrvU5u8SWMv00//QXLGFl ###uIYvi9W+UmIdsmePapwxPQW8OLACeEusp0//AYFYyTf9sfMQlu1IDXi1UgvHKc0+ ###T/PsnurYEbYZsPCSEOFLZkkuig8y2xdA7hMFHPBX1GA+XDLY8PzfSSsjrwgKwWWK ###Rp7plbiawWzoWzX8/fNb6/Pl20rti+IqwQL+QGbHX96x6egPQ5rDUL2J40CTL/zq ###iTafp2Tdz23Vx20CG1ax2rJ4jJ9Wq1t5juQEuGyxR9yhWAzZYpMpB6dscJaf45Qj ###Eh9fknJYIemwEmjHS1/dafrd/bNc3c/zXN3PJjRgVxfORrrCpqvLjHeqvU/WOppv ###dIV+NBa72Idp11nAKFnhz+ZvU6ApjMZuP0BBoQKy1u/zZ1J2wv/Y6sqkjpe2pKhZ ###Q41fnWn8OO34mkU5vvI1fP0iE49IE43LvrSqX0kJLf1R5X+04Tf5S/53REH0LX2l ###/+XZ0vfwmBraMTXmP6a6ckwSta3PT23FuSHVNUAtOXEbwwHckEZmdSCRD0bOk0/A ###Gxoib/9ktLCWLX2bOqqVwnNhoURG1XIyRjXSMKphwKgEgKF2ODdupWBnOFTecb7L ###r2XjGV7LfxP9b9/ze3b7dO/p2t9M/W9jfXWd9L9rzVpjfWPtL7X6ahN+FPrfQv9b ###6H8L/W+h/y30v4X+t9D/vrz+N/qOJS+i74za1OjT6QyT7tpRShqhbAXmCciZM3gM ###vEBVjsi8leTB7vpI9iesMp8mnY+DA7+7V8lSDqyAfH7AhrEMw2S5PdfXzc1O2p1D ###+6y+pnm0G5UD2Dav63VOne5D2ryaauSI1VNluc2eZ/qh5x/5d7/iM5xj+juXXoU+ ###FUceT+CNZamhr2P9TaoR5uBMLpOK04q8OufSomwBgEAfzoHso3glQvI/sgTCA+Yt ###iWdhUZzXeKQmTJDHA8bL9icgcPJf7Ibfi/5g3WOF7GnsGiFFfDWxFWMm8Bzt8EuY ###l7WUa5uCTKfl3DNDQAYciH7s1lR3lI+Xw4/56cAwTH0gVeTsO7PB9C1mCzSCT4zA ###y9O8QWAQtzHeG7l9+wx1HqvReLuzybUFj15IDkQ5m/4M+F8l9I2DXeghrqCnzbhO ###t8f0EE7FeqhISKmiSyVcWxQqkbBfxV9ctAH25ijcsdtjt/n1a+uvogEpxm1WAsDp ###Q0s8MeCxoI0+MzpSJzqeI70Yo/FrAMwRr0nC0qvDZazXrGGwhRsj3h+h4vVm0JRr ###IjARNOVeR177byAjOIFHzJ/jGxzzmDMnld+k0kIIeX1EXhyPqf1p+jCMHSSViSPS ###u0ex8sAMUnyiMpU4vmrK+eFlgDPEhD4qeFbIzXZJO8/kk9Y7Z590mOQxLLPEDljP ###5NJqEMmn9QriXxErzzlJR0q1r14iUdSJzCxcRBj5jDfGMmNuED/xOIyRTIlrwurQ ###KunSQk/0Jnqi7zCPdK18jaDcEcJzeESu5jfOoG/MuRptyS1FxFCBzp2Nn39jn0dg ###vM0HwvhZIUeBK9Nh42KO/1g+nHClOHOjpSCfeb2ZSwm1jPoK6OQSHxtlNUi0BR20 ###Wc1ftjRO/EM0e+DljY3EzbBaeSb18dJTj5l9UGV9P19L8lsR40eUJ6aavE5r+Rlm ###xxqbClhyz2441X3kWoHIYIoQl2To7mwyAYlcOkxgKtjFcCgBP7JLcHedWFgtviQa ###7N+FNDEhZ/uRgjJYYgJJwCSNAujUdtvIrSjJmXI82FJGpFtjuRLD7nYUapSwQ+Ai ###sITjyGdxn/7U82eueFZ8TNqk7hUj8+49SmPP22K/gTe8MgFBKxMXz6mm0sskSMVS ###KOcAGdbA1PMrx6kAlsVlGAVsqefDe+7dwesdxh0KmovKEokhAn6pCxP1va7nolE+ ###5xuVSSO+GyLycu71X/96FWXk+0EcU3nrRY0KSfr/e2cyBo7FmU1HkqV3MWtAuv6/ ###tlHbWJf8vxt/qdU31hrrhf6/0P8X+v9C/1/o/wv9f6H/L/T/P1T/r3tOt1Q+KOC1 ###QxmXBPfc/TZz/e6j5Tzoyv5kRqqUzzEPe1XyOeadu8FsMBV+eMtW/cuTld9LVJit ###MofuvedMnewENzmnR+jBu1HJM/0n1laWGp7qlBlLb5PLJ5TVsnsGd252jvkMH3LA ###AetXcu9cv5yYeiZueQCWxtOzsFjWdDhG3+LhuBH/jmxMTF0PxBprwYYqeVbXetv6 ###p1WrZPyf9T0+8t4l/XiGkYUSngmBotgRwkYxhghRsMSh95oqT25vS+XU0ag3Go2Z ###SpM5KQaKU6LPHMD9sIYe/K650yE0sXAaosgltPyi+PFFwzuDwRiWFNVs1n34pKj5 ###EXN+9NBBr2FScPIc2oCa2rC6PgFPmdVXwGNlVe35FcQ0BtEX7AyqbDt6noGo9zY1 ###0Co5heXCecMa+QvGG8658Lq88GVefzxh8Q2x+Ebi4gWWRYivbIBPEN9Ew+RbyBsx ###zIqDZS/6Khkschn38aOa2wBlmIiGjhjUmOwTK/QuI425QD0OLc5P9Z6UiwIWcfT/ ###zvH/CWr6hVxB0/U/jdW1jaYW/w+ta4X+p9D/FPqfQv9T6H8K/U+h/yn0Pz9S//Mu ###mPYG3tWbm51kndDc69F9QhlXlaokQIPq7l+tDrlyQpdbd8zN8jAI1oDgBFbtwgd2 ###BvfOY8DylwWMcv7uTkaaY6jogs4uTETm4oMQcJFqobkSaB51513mPw6Ypr5O7ynO ###YgBFxeqNsKjmaEr0MPTGWpeFbZ4Y2vMH6LIQ6dkMDGt9PVKzSYZjs7JtgiPEUzaT ###Xg3XGproU3xLcyq1rNOJ20PDsjxdqEaCuRS799P0d1ZgcJ6d11k2p7rKmO05ST2W ###NKtZN+U9xLxF8cDRxJ8UMxxI6XeZ8Iup+errW/hLpKDxHjTpNwhzul5Cw6pV/6L6 ###tVG5+Cr6zMjuvZI+QiwM9REs2SPJ8iDMh+fOPlg21c4T+SHrepd6ZpeG3qWR2aWp ###d2lmdlnVu6xmdlnTu6xldlnXu6xndtnQu2xkdtnUu2xmdvlF7/JL9lEyVY50lPhB ###epe63qWe2aWhd2lkdmnqXZqZXVb1LquZXdb0LmuWdqeki+ROJmq5BkaYvYcv0X1i ###ukeVAIhMFfXGIk9MY9EnplE8McUToz0xjeKJKZ6YP+cT83JkubYIWa4tSpZrBVku ###yLJGlms/iyzPT5XnJ8rz0+T5SfL8FHl+gjw/PZ6fHM9PjTVi/GJUcnMBIrm5II3c ###LEhkQSJVErlZUMj/AAr5YtRrEeXuorrdQrVbUC+Neq0X1OsnU6+XoiyFqW2+7adS ###zvyu5ya6meR6npeOzkHfTKQ00fk6J2mdY/rgR2SdeRnX87SFzJOOOG82ZAB+Hld1 ###7Q1Q3K7ZfFhuOyxDzRrBZerelMJ8npKXKnp/rb/NlWGAcQscoyshZlWsoGLF617z ###iGp1ps18M20+faZ6Ld9UXMn1pKkaOadqPH2qnEfFjfYLTtXjmXuS6+XVDN1V9+oO ###UOAUIi2Isxw8MHSHQLfDRYfJf4Gn8H53R33Vi5rFdL/6g/r/sjRk9ng2CNzgqalf ###8/j/1jY2VkP/31pz4y+1enNjo4j/Lvx/C//fwv+38P8t/H8L/9/C//fHx38v4OdL ###Aj5LwGp9mzn+1PtdTXkH5MV96HrTMD/avONrOtJQgOuOhkC8XeCme3b3xu3eljg3 ###Cw/IbOJbo9v8aWCltLPEBNo4eMUg9C8o6YphMaOhSZ6cL2mtVA7igXOt5mExIStm ###ynOJTQhmQzwN1iFtWBA6UqVffza8QimhLwQFmiNIU3pSitehrMC8ZYGZt0x9Cb/o ###qktY7bYVwu2SUuPdUohr7EMKTY1kHMzlhd13JADFgoQ5ltSNhTEiJKCazKiyw9VL ###UhPvXtviloC5rkCkrVJED6ajcrv4aQIijINzLC8Os1XSMiJj4T3gLgM4dUpOAJwD ###PNOzibuYeoRpVy6Aj62kIkaHaWGmyPA+g1KIgPmh3wdB0zi3mFZrN89V2jQ0YYeR ###rAtTptXPevHdsnRpJquDOu0h5YpLbpfD/kAZOb9WKCFfBVhg5AnbwAgFXWfg2r3R ###PZCpc2BF2+6dOzjye+4DXVZlnGYDmOPA/kbpWjuz4a43DeyzNbrn/PctfWLswKEb ###T3j8JdYcRlKaY4649wfttr3b/rD3946hh38e3Hj9aXDJEylk91Cu+qahwVK0aGaD ###iZ/jZkjfTQ1mrEW310/72ieYRUYeRcmiPEq1CqwzUrOES0UlC6so9YByx2/O4HqC ###uWZBoBlNuLh2NXCH+KQyfEp9djnKnUJ35OLpAblxKUUjJRYOm+QZJcqjGr0dbLSr ###wah7GxjzUtStd++Ae/y1wc9w78P+wZ6KM9vbVuJ3XOmFOC6S5p533h8dXpSUq1bJ ###mEIMA6CmoZaSZ3yn3mHlNZM3prTaRvdZC90F+fkdO7cg4yOtpqzmN8547PL0OyxL ###8/8PO9y+/122LuHSlpe31PkE+rwWl0iZ+AuhUuJmQgyLcoSWdb3hBS6VicmU0drl ###3AbPGs1f3oR0DBnQxCQN22qyTYl8eMs1lqshQn8G4qtAXBeWswKtk5L6Uxminm+I ###esoQjXxDNFKGaOYbohkNIeXFgHtFrA4H9diVbqmr5llX6RjMGX2wlXhA8VQZEYll ###6TJqki76/sYbuCVKIxPLyFJfrlvVHWTYtBTJ4ZsDgxl4eoX2qXuocDQPmTx76gCF ###I5M0EslyLLtKY7mBi1hNWcRy9iqUPxKWUMclrBqWsLq8ikvYfPklNHAJDcMSNpc3 ###cQn19bnX8Fp+kj0cP89CmtiwHsvETGx6NGNCKuFP8Ga4TAGFzagDUReF/eL2P0Oy ###YAVfZRKp5BaSpJFkgnRrKBQYv9LMts+lBvnVMTThYNEH+27KxWyEzv+dDccohSHJ ###ZbevXrYGmFMJNZHXIwSbj7X7lLdboQu5Myt/f2XeLOJKItBUgmXmDpDVBIYWeM0E ###riJsScnzJ1FzUjwPXKfHUuu7lEgf+NmAF4ql3UYyL5JHYjgs1JOHVUxl/jUqhwkc ###bpRfX0eSE/u8dYGb/O2g3UHHmjh2hBydJcYUIHMnNq3C3j266MCchApbsuSrLQZ3 ###bNOOg6hPJJRZOztIb7Rh8pFzcRFVsr6DRkMDxklLg0MPd8jY89OP7c5BRxfGUzE4 ###cTyNzsQGNCAll/rFeO+0c9W3Ezt1TWwR/2Jy0G08g3gkttse8PmYKTsS09UBKvET ###9fb2Dw3HyV+wbC47i/mGbVY/uWi+cHvVU3YTSF2BlyNZVl18Ti7qJKI927AG2C/z ###MCFxjGVp6/QqrklnEnvG+JI1rsGIt4mDqncgaUwTNVG3YqQmc8+eBvoY9TLyS98X ###hOXTZv6e8mKoaE0vWojIyVi7Midi6bTHRAxpj/SmiiJmKlBey6oOL01o/JJ/8+HW ###253d7I2vPOk+mTatSA+v8+1ORSkfDn3bgO6vnpchI8WUWt9CF6oiLq2cwBJiyWhY ###LxaN3sGlfDWU0gn5Jm9q4va+VaBzGRNrbhm7Jd4pUsnRcIPgiq6O4X7G72i0FAYB ###48RPm/T7vLjKFeP4vAUZuCprxKm9uj5h6VC1N7JuOqYwjq5yVFUi7v8zcZmn0+RZ ###fH9y+P80V9cl/5/VGvr/wP8V/j+F/0/h/1P4/xT+P4X/T+H/U/j//AD/n5WlV1ha ###1oFb/4CUgLNCSLiAZN+MegFd/7fYKuvfYWDjPS/dvv+9nNKem9zhoaQfrABzY5V+ ###rG5Cx3jf0Eq/x358PGQ/1L8OYx35HPCvdZjWHzseoqDAFh+uCv7tp/WPz8j3EfUw ###94/1W93U+qk/+Ch7HDo4THWHZUUv+SPp1Ajw++zrFksgX71ykIA3Hpj+nDfEdh8T ###2s3GSqvDrFb8tYOPrx6B/p2r1fBwjBYf47wh4seyuqzIvmkhg27D23EHb6QoUnKB ###BgYeftZzB84jeb64sEt6W7lfEr5dIBoMvN+xruDUGfC2yDvBLei7VPsROB0lJle3 ###8VMfe0hXBaUUiv9jgYbbIBbCarDc9f8jbTxiLCIfM7HAV2TvAXD/07LWKxYaXqHj ###9wpL3xV+hR9vyF+tK1/VK2gBZl81VpWvGvD/6/yr1XCu+ib2qOAU319hYYg8W+u5 ###XdoVi85O2xphO82mbXG1Eq0Kf9bMW/2lwprillfNW27i4nmTDb4J1P14iA7WPRwi ###HO4QzdCXmyCDYGv2Y51+NFbpxyp+9wWbXuJ3FVwYjLz6BZf+f3pU+Z7MCkf7pfOy ###VWL/B7/u7NQbZavKfqcxyyDP7+ywD2h0/AD1WOVX4UjwMNhMyxviLXKQRmpYqpXT ###+nF8t2fjhv3+zL6foDcARp2V6rn6HR2d23i9ovkaufohqVA6lpplgvyRD5wuXaUV ###VtORl5Zm/Xn4JysVdO1hxZGx403COL0VObIIKQcCnS5daP7WFuTBfFLsZvQFzWQz ###xzZrqVNJ9IU71xY3zz/NW6zZML5673/XHDu1IEl5s1aJHphnnHqkFCsSU38wADrv ###3El+oaqG7EB3Ugx33bfqby2uFt2yvL5Vewskhv5cxGENcP8hqkezB0KwOEpTQFqH ###3FqUILQEpCnLZW7YUZGZW1Kqol6Ub1VXl5bCk7esv25bSGGwvqnyIRGj+Kfrpk+J ###mMQ+JcoFc0t1WOk2Rmcfn5x/qE0uPl1nAxoV2saIQcnbtWr0lu1gFVmA3j49qtuG ###h5KT1mhrZXxe1E9xfeWw0opueHkOiD87FPVPtSPkn4oj/FEQp/d7foizmwAjEyNs ###o3+ZUGnvH/3WbNj19ZJM7Oq0qy2pF4xH3RJ6EZ0SvcS1O4ncAXmw6Xgy6roB8phk ###rXem3RtxG2Ea+ruDjNy2utYlCyT8Fki2B+dotbd3Wxd77+3O0f8c2MedaL5D5hEp ###XoRQucL0SzK19EL/AKQ/kf8rYmIEvx0ZwkpZ6I+MPVbcLNS+2xxQxx/bMmQbDFcy ###wtC5sPWWyy1YBustcCGaTweySqh2AZYXQ5KBDHsTt4tVqVEPGDHxbqyuOQA3Ipv9 ###mc+yWmzn51EyrKhUhp0il6XjePoaOL+j3iV+gLGrFBY5VyjBu8Qj3Rfyk+o7s8Ay ###BXulxSxo2EA3ZpXVZDNhStOAKSbUaMLvqwbgHiKwJk43wDZbpm9ZTPe2dLf2P3w6 ###YVXpcP21WC+MXA9CW1i48aa9au99ODjsxNAicePN5I0rVyTpMjQzdtx42R03YM9z ###7rjBdiyjX+7rX4ffGxk7ri+043reHddhz4ud8cI7br7Ijhv5dzz3Ga8+ccerP3vH ###c9/j9SfueP1n73g9YcexB+1kBEK1c+d4A1RLxZxrF+P3YpOFwgramszyNJpdSOP1 ###lkxX8krmeKywq+5wfk6MkVGcjzz9iT29o6b2WX1dwLRNnhHNRkniD0v6VxGRr69a ###y+zpLldkjlXyaVaiJYiNo+V5gTUZzXy0ns3GYlHcN52m6wCOfvpU0heqTAN8QOLS ###2KoU9kAbSjgaJ0QLhuiFB+TfAUowyxkikCqyT0dwzsw4yNRs6WdPR++gMjOYcskD ###GflkBcsfRrcSqdyjf7DDWBieiMQVCo5cGajyROOpC/D8eADgIrmvFlDreH47FoAr ###po7kJc+Xb17OqWO6Fb/DBpAkMnS2Z17VmI8cA47C2SiW1BSqxZa8o8lk0S1lgmrX ###8f82xVBY8ueH6ypGv5qhEl7SuyiDq9Luu/gk1EXsRBcMq2r/LbWmLEYV0LBsCbpG ###qTt+LFmvYQBqtDvrX2qrARxBghBOHo/Lq69LiiaR28tMhWO5vnILW4bsT1ldSFNG ###D7S0vYrxAOcf9zXeXE0tAKB6jSHbIawIdog31dRZtZiELMBwCTAXRHjb5wOFPOBP ###hIEQL3MBQTR+PigoI74gGJJTn4mrm7Gd5NuaOGLe7ZQSNpQx5/f5yZOyPVqHNLNK ###qtQPMmiVzLP8e9d/RnfY1unRs3l/Zvl/btQ21hvk/7nWrDXWN9b+Uqs3VuuNwv+z ###8P8s/D8L/8/C/7Pw/yz8Pwv/z5f3/4y+Yi5B9FX4GfJEygdEHkYD9UPM9gS91Q+Z ###7ijQWs58oIj22MEAHiBU/Gta8uHR54N9+/QDoECsAPXRZ7bkQeAmFKeO3FnnT1s3 ###sYQAHiQmys9/Aqqa7Vd3avNZbLRalzKzyp8T1x3w+gH0Kj7VV4eaAY+LC9h9nIba ###IjFlpFO6om/hmeoctf8uPHhiqj2THgkebVS8QDf75IMNl/jDORcj1Jm3Vc8cMYUm ###c8CPrfQ6CCvCFw1fo3NyRBNjpR6YrgfFIQ5EAGdW6venHBClfEtrhmBCQFfiWtbO ###nLpVWUqEze2xW9th6tz4lLMgvktxNfTv8ya5Dw9jHMBQWlItYCST8YU6YOymOk5Z ###wCdS4MWOPZ43K6DAQd0fLMQ6IXVTvKfPIk59650FT8EHtBOdfDy28YE/OcA4UN8Q ###NIv7WA5TRnjTKBr4NU1e3WG69MOHh0sY+stcfkBKhCUfzt+7cXwfSCEQ58j4pX95 ###xKt4sBYRwJyexWm4lBJQ8nWTt3M2cyeP4d2I0DPCmnJyiquaptDIfbEN1zxh2cRq ###5rr06SRA3ecLkgBmbkgmBEkkgMxLfyoSkP4s6ETCDq+ItRT+upVES7JJQzTctqVf ###Qt4k3LZ2oZR/26Y7t5XYP7xzyf1Fk9ggMLDNtKjn2jlvWxIBqVlf3gR7Q/8Ntu+j ###OTI20tB5ELN01AHNI0ntk0b0/PlGjNonjNhzA2/i9gyjmkfU2ieMOnYeByOnh7yG ###PQyyYXjqdG/dKW8eG+3Km56br5x5tAtncu1SF/tqHBgWh5O1R0Fw6k66KPxfu9mL ###w/aYQqMbGw/DXAbugzd9zLe8vbB9bCgQ74/8XcfvHR7s5RlKbm8abP/is5UbbKy9 ###aZi93fO5hoH2sWE8M95aoWcrOgLs7paMYwKW3b7/vaI4ukpjO6jgQTDce73pTYcM ###e2lLpPb2lehgM1OgYcmfdjES6RPTmvzmTDx0JmmfJgzLVklZJNfR9djUJgAhCcek ###JDlmTjvt9ZRTfLPMYaST6gAAM95dVmNsNHXfopPleAIy5mBwOHCuUcsJHFqFlFfM ###tkzKN3zlUfnHEl2CROLMet6oYnmTiYv6o6l357JUZwkVvNiUbvjixcgCmxjVWc/1 ###L8ZQMFCVcnT995Qp+HcVnYfZC1m43AxFlpcGNeM+EEd+vP5kZ+y6cC250y5DtDtA ###o9HkSdK0MPSZpox7tHt+2sx8yrSs30mZv8VZ7s2R7XsenYFPMvsHOb5ITGnQGfCL ###ZpVos2+tY+eBfVm2ctdgk0lELO81fgj3ljJtI/LyxqhkZ+ZRrLVqhXnNzLmv4cS8 ###Css0V7H6MCT8mA7HtkYmtlFoxM+lh5Y+YxxtLZ55mqPExWiX1oJzUGrjD/16DQ0r ###osEhiC3Mgcg0TEAIazvdqT29mdggmPKHwj7bjOXfVnmOinUMl1p8EuBHPAdol7Gf ###UcP27vm5HTwOr/CWhpntE5ht7XNLYrc1/60r9I/R83rbxx2MMIdPkWk97Nh/f/8/ ###sTTb04njBx6zMXVnE54zrILRuuzXYEuRgk2vnE+J0QNGfXsG3p+Ssia0rUl+QRgD ###JkKHAa/FzlMF5xJHDAogs3lTm25CSXqOQGD+K0tUly0566+0JE3L7xtDD5SRH6V9 ###4JrkVnEpZSdZaaCFPRyP4FpVd+DJcCfuSDoreNVRA8f0g0jwXLSECXQjW1jA+ijh ###enxj+fUmWgLmuIoHWrPFvcFCqlhN9c4+qzcVzU9aQ9XnI238oOP13LRxqYE6ntZi ###6PXsABrZQA/ssxoroBvSgjwd6tShnr9DY94ZmhkzMBaWg281dexgCC1Ze9aUtAGH ###R5/RQNG5KFFUu5Io2Yugqmq7tilC4p8pzjkpV17zbq2YGtcSG+eOJ11obUe+/f7U ###lli1tLXFGuuYmD6BukxFxRjdbKT7KUz0X7fTCLEiWGPQpVVKJDUwUiqZKm+laT+N ###XUMlTYpSNHVO4VAqv99KUGMJZUJ41GQ2UB5R0+ZwcEdvGb2q6vA7lDT9v/VPdygC ###gt/D6GFUoxFlpkkj3R+wgoDT7bLKzsh0DMLCuUzG0qIT1fkx0tVUOEfc4oOTPfvo ###5PTjBfz3t1b7aB+1fB8ObRZy0dmaP/4hfOnUgNdQ23+gavtNyvv0s41p8cMXnO1r ###Pk3+X7eTEiWnbtaUvtjIhCbfwWjAlHsKxycR5hg7K/fsagoifWSVD956TugbwctI ###CWekBi6+T37XtQdOMBVgUheSMZJ8SZJDQXNdnoD5O1GkhTWcDaYeCpf5btRSGqHA ###66YRFqSe0l/vDOj2k+5jFHgD3OFwRAE4jk8RLEzZie7+6D7E3al6OmBIr7YU5Wht ###NsrSTnfS8DoVij8bPvwxVYUzNTssPiHyDriyuZLBslejagFPvHYYazeacB835PxC

Okay bestie, the base64 keeps going, so we're still in Appendix A.3 ๐Ÿงš๐Ÿ’–

###ph0EbPoM1XwsoCigD4BFlA8wlNz6OIwttJBWyd/eruNDFruKNVVh+Va+u7IERWAS
###AlQGDZYBVomJw7yLSVFbQT2AsvREav6Ua+KZuDJfAAILbtssma3Th5OyWUIduPES
###I6YvR8/nnC0Qn7oTxpGZk/9n0E1SFZCeRCr4kvWWpYzn+Wgf2E5rItsEvsfDgdLv
###CCrCEYQpcIlU5ikcs0ALPUNMGKq0IqXKQ0nX1fJxG2vh6Foiy0rlpJV6TdW0lvQ+
###wZhHD1upkzGRxPNLBoVVnZ4e7bnKhmM5PqOs49JygcQWlTpFaOes5FjIkmKqidhG
###pvzFM0KfUwqpVMMpUhUmoeT5+nU26sXl05BQer30s1ZVUoaM6BK1j8HZzFhRyAzq
###5HxWjEY8rqxspp9cVCN64hGhWXQtKXEmcAFGgIuhBBwIj1/+ZDBFz/2N6/NYN1Zu
###BpoMUYtEo5BGSAuOlmX+04l7Z77XcAReb3vbyHL/WEVA/vHLMd4/xp0IRVgUlDvX
###mmJn/joHobjMR01Y7bIKopFJhV3O4r+NQ27HqIBWGSofmaznJpP1NDL5gqSynkwq
###X/BamwrwLIhz9afgXD0PztUXwbkMpKvnRTpDCounvwHG6nd7rJYaSJB9FhXEAlo4
###1x2AnNRHEUriKTQC+QRcYZWU49Qf4JwHdzR0K0UGn7Ik0tjnHz6e7FPxFEwOll5L
###5t+K6JGmgAX9IEfPHjoiSRXLuXMn6OnDk2TOBrwyGf49vR/piTMDa5F3kdByDsNY
###gs7qJajCjyYMpjou0qXJyWonX6VcT1xOLFv2l8ku8yrJ/i6Xk3nuaV9lu18sW893
###cmxSeDfjZ/Q9hU48gZ9IzdWTLU9yil/PS/GTDT+ErJKLSgxvl7Q6u0BX40qGgkeU
###zzRiAELAWnKXaPKlDBuR6s1jVQ1jSOyGlLRQotMpeiatPi5lrh7c6jELiaoiI2h2
###8qsMDIzIgT+aXd8wP6HQMemKs7XBiC8tNXdVvmVuz7HMrTlvZw5tTz3vkupJS4qn
###q4QJyfMRdWJKLpych2h6iIG+/DXJgCfzjxMXBetg7HQpvxOTxbGyKbeFIFfxW2uf
###eEt05CWVnanEq1R0npXkY84B/0Sfhpr1Pc77sVbMSaGxtg4CllLnDD7CbBdz6CGJ
###ySwnXc3IC2WO0mWwdqlemQmA3H/V8R+l4yPFBHoxeKNZIMwWBphF/alvImyfwRgm
###/kkuWnGda35lsD+/Mti0gn8pKdxKcyiM4WBMJxl/6+fRRcOO5dVhrcL/Jkt5Apzw
###XsodjPxyIqi4cT4ZUoloKc9ZDYtyRhCiInusEuE866my93YzP2C/G+/EXojR5FPp
###svQF7kPXm8pVtZNR/bntEM98h5JJcqJ5I20oRZ2Lnm57pPA30Bt9ATn0xoCSfqJo
###ZhYNmCZVFExEhzatXmLc4+3ogW9zK3MKZiKUiCUmm3D/Rj62oiA7kURuHayO0FxO
###t9Prh3bFqrArhoRTeOAbcCrf2dUTTVN5oZcAQfSCw02kQlE0UpAmG5rfXy3+LSYT
###D9woy4gT1nFnQRXs9WKRGYnZR02w9YhyphNDFchV5ouZA8bR/YCrjNG06O63f4SZ
###HVrt9j/SIZZYLzx7lqOT/YPTgxNMe5E5y6tMBOGYwcljkhmaIFVRsMajMjPS8jJw
###RJ6NFSw1Y6HRokqLo2fl0oMPpYKoc3TTa6dmwj7N2YaV2KWhGROQ0jhNFMg+rrxv
###HXMf+2Hsm9GHOPV6GZ2KU3vEHU5N+pS4aPX+1L7jYWV2dzYd9Q0TmgSgCyqdxUIM
###sFgwU2WauWYKsIhbf6ME0ZnuL5rLT7kSs+4KiXp2RemyrBtn0EeRCN8eWp4zmJBb
###PCUwMohqmYIX20V1Gzm8qTsYyHeS1YGqZ5hQ9z3M4oRFzvwwYmbG5T9C/ICZBCh+
###Zg5A8gCWeaSu6hyiaRzKezxNMRrPYeoV7utvgGqaPyI6uBkhbfaWEuGZfLf1+Pkn
###vhS5BlyrpdspZOzq43+RKcaYJzwTDA15wFIlhHPsVuAxquJkjNBoC6um3BGh+MfF
###HlDWXLcnrkHF2j26OD/ANEsfjs7t/YO91j/si6NjLHdiOL4TF05PpN7lSh9vOtGi
###MpIBR9mfSjEXK+MtXpNrvBhQqA0Iv3JO9i/ApmOvt0IxExmolNPfQuft2uf2dAQw
###kd5uxslVcqpASdTKZ8TApqkyrcaJ57+P8hISGNF5BjMuMhY9luhRZ4wxDgPXgOJN
###H+2zTRU7piMMI6rkFPljQdgLqhJ1KeLpsEuXMkJGQ/GpFOpe4AdGLNcgNxVK0dSs
###g+JBlrIRirxhJdXYRmBHvYFrNj8n8iVJWN25ccaunvw8lTuJupmZkrmmP6VXeVqZ
###c3re7RkWQPh80jmrzLcA0W2OFaSMREd80u4cfrPP6muV3CtQ+z0XNNqnGEPUDuOO
###ckJD7Za+mIw9taWQ4CiLAzyGC42I5/QGLj/a1J8+ImH+m7YTTH91MPtJz31QRlx4
###051QlpOXePGP0wP0XIeXf+/Abu1dHP12dPGPxeFAKHON6fTORHj9trW+ttZcX2jM
###JMfmWKmWdMlOFol7I/u31j7OkydANJcaIWUDONUiL4NJ/fzd+B5lSh5PVfLNs+7y
###VtZz85xAylLSPZdi7hkg8D1LuE7CL2ADdvWSFom+qjm40NhmA+CaK+SylSeBfeKU
###ymhP9ghQGLEv+Zf3/dWC177Gju6V2VSX4UC3oHInNAAMnQcmRIrcQyYseO/4vag2
###D2W/mACdnRrVT3xELTCPf2rma+WYUm5FkKNE0+5aNJv4bclqWivWWiIdjU/YTBwd
###2+ZdSdJqGubVaCtSZ6nPPQvueXWx+4//eKYq9cz4h7HTkKBXDRMzzi30Ju9RS/SB
###rIIhLVnuJzI+nCHDiG/yFw2DH0MnB0NPfLV3MvAiBG8KDwX37FfMC4UharMx6hTq
###Kw2hCBxiFhovdLt0hNCVYh4RuFE1XkRAF+UaLEXlyBbSTRMOa4BOg0p+C6QSSdc5
###Oc8wX+iLKCcMy81RHnC5Yxf+Q0sR5ih/NLdFaj6nmSoS7yxqspBZSKIpvmYYSxK3
###09aAEWN96961gltvPMaaWkzGZ1ChUgCeUBJWsF1v5P9tmmZ1Iatr++LUCroOPipb
###hOD0AUlXMNy9OxhUWSrv3ps0HM+AEEoXMLDd2Wu1j05+TQXYPMeQwwb4PRFJlAhR
###ziEwniOJQaAQUSmLlcw+Rour6G95emh/vsDQed6Q5wuAzwy+jHzh5uyqXkNR3jDV
###bTdRSfV8rHuVhSvoHOCRj6di8IcD8n/lXns+5qEXivzpxHWGJu1zlP8s2U6e4ts3
###h23GhGZswcZjekY75Yt6kLEtWJrvGLd21tN0Qaznv1LDhCUB1EviQczEZLF15VlT
###aJx9VkUA9y8bO5gHDnOTeM7ARtRVBWK+gR/ki5lkZqd4+N/dyUhkBuxbzmAQRTrt
###X3yOW2NzeUBj4DhcwmfxCcaxyokAl25+glIniXQqtjp0SZeGWrI2t/L1q7684Txx
###bs3iZ7ZB1tigtSRv24/jHnIkzN+L5WvkDGKYAFeKD/bQVD8Y3ZvxIi0lYmTXbbc+
###7ZZiucU6pwcHe+9DFakNx25fvD/Hoj+bABnj4etjYAx/NXkkQKIVSm+42zrZ/3S0
###f/He7nw6uoC2+wft1j/sY5irvg73DCcU4Jx6Q7eD7zkLE2ix3dNxbc17MeKWNyxd
###nAa0crpKNCGQIUF5m7kj8w3KoZpNDqhYaB3L+dIp5fKjISEhChtJVG9oBSu1fBkm
###GGg9otaRJkGrLZ0eHpgr1ZncJgHqKWeyFRsjLYl1rsQcLJd1GtKrKa3jCzCllpc9
###QHLYnLXE31HGTeJaP0kpDeOGbuu/Yby36bkQszO4pab2iicMy5G5S80B9mdP41VL
###yL2kJTfPqv+JNrDus5fGTK7/uba+ulHT6n/W1+trRf3Pov5nUf+zqP9Z1P8s6n8W
###9T+L+p8vX/9TK6eJ37xCtgtuqecPMGEN1RghztkPvtloeXBZSoGgJFV0iJfz4gUE
###9iqaZhZ/ypXFTDUq5FojNGvUbkl3y5OGproUnbNYvUrD0GodimYDP3uwz5qXXyrG
###oYlRJ69poOFnzbSh1UHZvwcAHHD8NX14Uf+FDU3A5QS/voKeZKmrZq5aQfviNG3V
###E7d6fwOchy9sR8xUBLuoZa0ah0YfwqRVR8MNHa7J4Vtg+0kpMxLMrvqTipW4avoe
###3zQeNZHrGHnYMiyaoSmIWIZKeln/UjAEjyRAHzlW5eJk1wbKd3iORqZco6eseoyC
###dDt53FMSwwcGH8jMoVk8mD1VnAglgDAfQyv2vTQ0avkSycLIC4AkoAekTTFkIItO
###Si99gY1IJQW+LbjRZNqQeIHnQSox6KYs7FKsXPwKi1s259ByfaSHbybKsPDQOWkD
###HWNEG+bAV7Z2B8ZtGBYeHuPNCOOQgG1EvUnPY1E53ZHbD7KGvkKakDJ0ewQ0LHnk
###tKFb53AHxlhMRB0/LAuF18TCa4J0EthBadgMvIZbX0nyMJiDNpiO8b0zGZLz8uHR
###ORmEeoxqLojXShyRN5hqJFg9RiznNsH7iE77c626fchhvfost1Ee+lfuBZ206icA
###pO0Mr3qI3LXKcw89orDdFxmauXMm8xdHclWJOek1uwzt070Pk547qWReGQzvwBBK
###bJ0+NL++Yuj4lYmutzao8uZFrxw8Sxn8rmWZWN60oH4ilE/ghcMmCU+q9fRnFgPz
###jvz+6IjnB1GajAP+cSX3tGeMQWCaD8OgKU9wxEub2fRUCslCg9xJyJsyXiHH85z1
###TFsp7yvfLWrKsLc2aa4Ch4ioe/BS0JtIHtXIIQJe2x/O9w+IRXzOBzKkVRenfNbV
###S+Ko2WxLMf70eR5P8a913qAXVJ2Gzdp53zo9UHdOM6tUQntVrVyVB8NXkFP/1UvT
###PpNYBfPUOaYVL2TKbIu+mmkXKHo9syeOdntv9SfutxnQvEfDjnNMmyI8JU6rkItg
###6o4pnmAuICcJVrkYqmBuYSvrsU+bFs2UK6jlheuLG4Zz7rnwtM8zrSz85pw2YtW5
###X6lB/ovX0Qz/3VYYg0oZ6Wyv91Cx2p1Dmyyw49GAzk5yiTJd/6UWkreKtbTLeLql
###iJneShRulsYP37ay5ZOQZso1KfX6k/K4pFCh3/L0zGamt3JwbVvZmiNGAz/uxlZD
###XeE5r+5MHL9nBy6vfclf1+pOx8VyAqKKRcedWjMfGBusyMMrqqIFIfTaHvkgPo/u
###3AkrljBAiwRZmXgfjoXMAEvz8jBKPofiFkvfq+GFzK+WN45AIOzz8pW3WTqagAFA
###2lIk6bMSaV+Ub7VMNiGQmB9N2AxjZMleMmZPXQN9CVYVs7YZkSPDc8yDI7FDXXHZ
###EOcwtsYjah5E9RXQHDO7UqMUCIyE0ngtrmZ9vGfCl2IPTmA6xtgukb5Y6yPas7jO
###tD5wpQyEYtt6TYM9fLtM6C1uBXkRsOp08ONd2Nq/skmjB59qjgN088NpVG6nhGPt
###sOR7/+JuWAkALpfjnFHkG7AbUUOYROFtbqFfxN9IfSIShH1CxoQoXhJHomZ6jRgT
###rIiFx0kHLXm4KVfFwITcYoDMtupbbiYyuDEr1VFdpOs0T1NRg1gSJtGzQMqlu3JN
###UidvxHXFa5CRLpeU1Nr1Mlxa6eZv80BoioLeN+W6/U2hWJI6Ba8B5wtuTf7j50Jp
###bojfZJEItxY6ojZFMlQBETN60sbp/xIdxWhSNiczAPjuvdXiHJbJKVK8tok3GpaG
###O62GX+sycVVC/BWrsZVewzCacMcyu30yQMBtcOCEHgMvsJnMVbJeszc1GgLTmYQk
###Jfp4ma6WWC9RjCic1Oj0xxmHRAhITEkSGExbMeGkwf0xTmLTyavBBfCVSgxiNjZL
###qBRIxkfZtxLyBBXiVSohr1NBXkwzf4Rcd4VjfCXhNslgSNHrs3UYh5AXxqTlCj4o
###8vr4cTE275Uq+Qlyy9nJJM1kJDQRRZGFGfpAEjNYg4gRf5WkMjNhnPSprqbKg0l4
###UhblJDcNLhVLJkDlaMde5tR2EXPB3a9Ffgvk3nz3YWpgKkSTiCDqb7YSY4OMi3Pn
###Wt9CzQZzNCa/F1+RxLXcsZgL7WD346925+LD+YGNfgDky/5m3B1WcjAYEdiVMPOk
###CHNFbwbjDIGj5ewoomT0L5pZ8z/UZ/qSSGbSo9wNKwg5OcLo17HPLp++gmaDrQBw
###YiWX68DKUsq1JyEw3ziFmbAwExZmwsJMWJgJCzPhf4SZ0KQa9SrWV4NOD4khTsnY
###XBSV+F9wHr4NpIG4Y99mRLNpGAG+O2StJqzbhP/8VrfP+A/6s8G/7sEHDfqlgb8Y
###hnQfuuyK4HrCPx6+RfJDgoZyOhzXK/jfBrL4h3ZI2lYNjZfGAY7P1LvYDOgQFj6A
###vwgG/E+hQ4waROonlUMyq8SYzLtsvW+dH3P9DJAs+6J12kEZVyh45Clx/EhbHBfp
###xJCKsCwGEuDhuiVFCRLRiHW5jDBX/AXR8wQoy10mV3hAFweVtHX2Aa2PZOzdj4dC
###Byzz53o4t6hn5sXrf//q+i5lJeoxN3JJyRDTJrN9tbC+n/ZdWatuhLuq6k9jkspL
###v34sPTCG7hq+WNcK+7aQt0QX/in5oFMZZuvKc7CWYteZkbk1igwtW87g3nkMrMlo
###5vdI3Vr1/L68NPk+6mepLUiLEjf1FBGp6i0fRyeJ8WYVzsWITFZPGrBalwasP8eA
###DWnAxnMM2JQGbD7HgKvSgKvPMeCaNODacwy4Lg24/hwDbkgDbjzHgJvSgJvPMeAv
###0oC/qAPyYEfT5daUogteAflS1Wvx1H4LDqtcrfqzDStfsHrj2YaVr1m9+WzDypet
###vvpsw8pXrq7due/K64JyV9rjgtg1l4Hgo8+iUq3BaDTW1ewv8cZYGheIJdW20r5V
###gajwjzITI54TJrlaJsRfcFz2qvBx6884bkMat/GM4zalcZvPOO6qNK4B+eXWcnYk
###Y5C/tohaEsLLJsQ+sFtXIHsnclMlXVKyXpPdidmcttiI3RsXhqB4TSbKYLjpnatc
###I2TpyZIRXtKabBlFvl+Y/gNmGNWbxL9joecSrgt5R+e0YtKewmnpvcTJRdITk0ck
###NYt+GYhF/koXD3680yfED5dNhQU4VLStfRXsd9wupLdhINDMSLk2VFc3JMbTMNB8
###LrAb9WyMC1w2ntGiEP+qE/GEeXV8NYNpERCZR5aFFX1UZsFtNuRx6+zaZHlRnQFH
###UN2xcDDpFmUvm4t2suQc2be0xTKxX05igWPNIRfXVWuZeqn00WGlFyVJ2WBcqTqY
###mSah6Iz2YpDppIf5r9rDrMqQe6PhFdoOpDc+07ok4T/bwsddPErtZFUmpIHOCOEp
###RSdNJ9rIGJmhXAi5bDwxj4wci4CRgT/pPA6H7nTiYbZrUrtah0dMJdz3up5ryCMc
###Ko90VKE/Wvv7BJZIvXLJ+Ablkyo9x0kmWJ3sGGYM0Yd9oQ9fT/K/XHRG4X0hzRgv
###yR0tAZ9nE2mXz1dlBaIZEw+azrapH4eMOQB8CRcZ1WRolE5nskdmb6d9/uEjamjY
###mM28tKsmj2zkVrKmaiw2VXQGE0ViYAcQOT5S/ThaQ9Y0MMnEDbzezBlY7mQymog5
###ZfJyOPDGRD4slr+WMkH6Bi2Y17di6q538XsqFl+dRHpS9dVTtkdh9DbukGtuq6Vm
###3Xr3DqRVuHLNGvtVp4mHHuaVuB8JwzvziB4A5zawurA6D+39LPvE0HWC2YSyV3gT
###yjtelXyKpf0xXbEGdr4oyS9TukekZNYZNqFyVpsiYWPNTaSNT51MrUtCoV2nUldn
###H1snF3b74LeDNlyj//uxc6EvzTAqJ3ZifeYtUb9GWr96rRGjQFytrueUEl0iE068
###Y8PYsZHWUUpMzE9gOxWmul/xHPus5gT1zwdANZ4FPdpfIgSMeCcmfw4IVBcGQT4Y
###/DNGVBEe7xAc2gNhvg1/+ju2OICrGQCO6PXEhCWSoU3tGFtou4XTRaY3xVSn9Eyd
###qBGfqGGeqJE0kUKORfd34YoTSMg2n9uoleB+KKzgcuQBvFk2sAfq0yC/ZwdRjXEJ
###bbn1UWfrxDCr6gOT63WOhqzyX5N0La1eTxI5At0ypK1NZeYiG6rCNipMKLOoWrKl
###UB1Esb+qospqzM6GHp7W5zOLNELTEaZ0GgLXwziCK7c/Ag4gcO40/2V0c9MOrr7O
###Tq7TugjzzKqnGIkRn0oxuzBSjk3maiavjzsgMidWeQWhUknWkS3JFk82Q/SlKnZK
###d0UCnVhVJFsr7uwG8RXH0WzWr+JuvRlS9RfzanRBOZKjlVWlGZ2/6HdAQY66YXPq
###0mToxkZX5B84rGPnNrQCRzUd4GpKXp7MJy7TRkx03R7d9Qf3+u2sKKSjnOCyCvu0
###gkd/emNdUQEl3Y+TyhcpNvFKzEYeuUsarOWprpJF6iOz906R+khbdZH66D8m9VHc
###v8ujEIWYkxNFODq9r8znx/NFzGOzLv/VaHLiq2wocr9nPvdcXy8PIkjs0clvB+ed
###AyCzd87kjD/PQ+ehJJ8RH4VHXK1uKM7oQjmrjK6EZaIW1hl0Zxj8SfuyYF+zYIpZ
###K62+052OQsKMnGV8YhzOEPspM2cyuDB6TUp4zzYW718xbzH0DIppr7Q5mJ5lPRaK
###ScyUcnHl8zKrvtTz3RRLMNbT0KM1Yu5YirJL0dwiy4XEmWnBlGXFnlCKzPCwxnbA
###T02O9FBPYtsAyujwW1i10+IBUBQEF6s0NPOrjOJVrGDEiB8j39EaYRoJSeIxVTIE
###yHRPyzAqNzB6ZEQL6I3ufRGnrkfmGW6L4J8UXbh6dmrMfFnj0r6rhkMvtLDFfQT1
###gDpCgFhjc9kU9WJCv1jgua7PDrlHHWViG2TRd57JKBchT4suOIUKYamOa4SvjEN4
###QMp1+mt4n3TPQnafBqGzRmizmWrl5g0QVY1WCcF0GmClPmbgGhh6wz1T6XdCn0Tf
###FH3TkvUqtu/IT4U9TZqjyuvXpgBE07V4UZRMx7IYwNSm5RwRjwliWeaZKB2MgnFg
###dENF7biCi4ERGWshlDTZIRW5hPCRF7Hk9unkhq/HEHGetqDQyJ5zQUp7A534/uov
###/yb/4vn/J25AdSIm9nji3WHRAYDGkyoCpOf/r601Gw3K/7+6Xm/WVuHzOnxUK/L/
###F/n/i/z/Rf7/Iv9/kf+/yP9f5P//ofn/O9716WTUxcp31CD8IsYdUZUAimRDwsf9
###iKO4SyJYAZA+eMx67gBoiDtwh8JZLVKqG7muUqJKVv7X0fSyQgXOtOp3LimomFt5
###Hh21EiM7m9pnm9H4QuP7YTaN5w3Nn8eT6SfMMd9HfuLIeYduaRHrYuiW6i1YsaS0
###gDkBAjJ3mu7UGNJr0Juy4W9Nme4A5M2GHMAoZRCD4eNJw6iDlWJK7XC3RjlBFUCf
###ZYTZlMUbftyUamtbrCRlHqFPoq80VRGbVWke1qW8ZA64vFvLGKbBGmn9mUJH7VeX
###DWix+mbFv3nlP8wEiJa2K2/g/e4+Rym4dPmvvrq62ozkv+YGyH/NjbVGIf8V8l8h
###/xXyXyH/FfJfIf8V8t8PkP8wyBS4HyvkfiZvrbz/WNa4hf+x7lXrGChsQKuAF3BG
###JM0ZYyZkr49U6pEeneloZHUHo8BN7e7cA8UiEnRFUmmQPIbo/h7IugUSEmVjGVlO
###98ZzgeI7lvzwMSI89HxvOBtqez+YdQdAqB2fCLTj48Mx4t4EXBJN3juXKnF1AawA
###CCidhhLh9SKQTxb8X1EIno9bmVr7bh82HTrE/p8e/u2yTMsfPpx2xIiNmgmVKow7
###EcoABpOeM3UEYBR9gMqFlySbllnuXaIOlFc0pgiwPuIGrgbuSjhgj/vI0q+4Tr4G
###9Aerr1mX7S/5Re6lk313MHWOycuBzx+6QcGnESqwSSqW0gHnIl4DHtcdNKNftpfr
###X3Jm+E/J8GadMJcxeNHpJKSs05yhSkbLRFeno+0aJZbFFAlBLG1+10WOw8baELiz
###mHgPd6jPYAS3x1b/4n3Z386D9HfkiUJ8MfzPd7tuECCnRowIRTjBlRux+4PXE3Y4
###cfxrYoMceYmyS2WYl14/DjqGsqyEoP0yRQT79V2E9vyjWFKlFNKsB3MFgIoDF445
###RBWlUd6RJjACV6/JA8jARvcAflMua1+A6Kibr0mx4UdqMgL0DfZ6Pbi6sgYvZqCu
###k4F622pX62aLtGklHq6kJP1dhRuwrK3NizkSoOtEONw7dZ8mBwYNEOLXeC5n3LqX
###7LQgZyFxzDCXpilx1xhck7LLtmmX7ViKnLw7zLU73Fk7wW1lESZDyU9xzzNKsHfW
###gNX+yK/67jU8o3d5UTzH3AgkZfM7JvcYkCRnE9+4dRzgKNHXDHkKiZkASQ6o6gAl
###eN3nTL5Z24abZYpho3nb2dPeAGuSOS9hlI5xOn7F1xGbm0WY3rh8s6iCAAynB5x9
###yjmhETvo7mwyQfxnNFuqDaStU6XzKnkx6XuP4trehKGWdXDffkm6vubeShSrOtTR
###l4r0HJigNBuPnxNKyusXeqquJcCqjbDaIVhVq2ZYqQNW54RVrPcisGLYjJx8RTC3
###V4/WnTOYucBQuO5Y+JUGqLzIApHGaJhCmKLQaoO/rmwKCC/PESPH5u+493QGHuqs
###i/5gqXNtx/ZRzQVb84hf5Af1yPS0HH1J9vjsOH2mAAw8NMNZfSDdLJ4MeMabUa9i
###3d943RvkvoCkAxcGQs4AVX2ybk7yDuUM07YkHZTpS8U59MhHDozcIlHkKvUd7nXq
###DCau0wNJbTAcYVgNwxhnMnEeg/LbiDnm4+ziK9N1Ahe++lDyy+x+IE8oBpJHMJjU

###+DifRpNwIBjnfxtlMQ73pB4kjaTnYfLEzmxsD392YR0o+tgAWJvwnqNryXotvRsV ###4Olj4f64KCZN3Yxmgx5KCv6InQOdQHjM+PDIYVnKeyRiA3DakqXMqT9V+hL+DhcU ###zbdTxx7KAs2VO713XYYCTOhOZgmRUBE/aMZfL2WJHi4xB28YY8ziQOPPKIGtLj+O ###yHiZQMefVLYymE1dGX5bsUr1d+/qa6a31gjIsNG8gGxXyWl3h7mBIrXPhGVsxSos ###UdLUV00fShbF/zD739DpTkbBm5vnNY2l2P+aG/U62f/WmrXG+sbaX2r1xmpztbD/ ###Ffa/wv5X2P8K+19h/yvsf4X9byH7n48GwM5R++/2cWvv/EMHDYDcbKN+upCxUOjj ###ST6iLAk3IGyh4I5vFz5G11RXYGCNB84UqeobMjdB15LTxIq6srBdkmX40hV8Ui5T ###xc91odm/wZhWoD1AhpqNKw+TEExlS5TsJeegixwOInPIJfjn4Gc0bDnPApajTq+t ###2gPyNofwr5x78eUybRj3C2NdZWy7u/i2yblQbLtidaO98/WzrVzl3H9X3v/VfPvv ###KvsvKyeOEOBf8G0aT/Ai8QS1A1Q2lHZacsO0s+nmWCAltcyEtQZqAks4dBpg1Zby ###UpNh7jTL5RxYOfdd2k28SylLaeRZigL8jFVnYtvcl2U3+7Jk3e/sK5B5Znxv0aUw ###n8HF4megoP18EO+mrQogePEcEFRwna1vfTW6jvStafZ2CdrFJ7dKwgV8fbWETcoV ###aR3wJ4OHdCr4GTsthVBFYDMTqE/mI6EGsLyS/BgRQCoW23XF4n/GFdPUoBI7KRkU ###KechLUkBib4keijkJVUsBoDwT8PKutrKer2VYHZFoikXE3lMhDOdYZ7RXmyJ6JXf ###aaFLvgNrVIDGqDahzFWZ0cNNrkjgKev/O92J5f+9yuvuwmd6bZrpr2wmrsAFpLWP ###gdl7C+dVXqbmbxeZ6l8pm5Knan2WpwIwqwf8cTcDetUFYbcYFC0ORZj0f+UZ1fnN ###wKyGwJwbmtpcJYRE2pQCqFUBVDWrl+ScQr322v9TX5cIFbQDlI9Hr7BgkNCAiRYP ###bBm3ITOrs5RnhiuCp2ix8L2rq0GUeCAcBTd0eFirxZKiRN/WanFbNX27g84rjYyS ###E2z5y9vW6pZ5hM2YpUgfRlvsYXw54SSbCZOs5l2lsh8DHOGZZ8oWDm0TPPeSgbmp ###6dH5KHx62UiNi0xrWt/KAayD9Oka+adrSmE/mXgNlEP61POBnnO8FmAk2wj8hHWG ###EAW5785l3pBxLyq2LRiN4wBipRH9pbulcAHUmT/9CaBLH4G2gYBfl0AB+zkf3VtX ###TqC+QkNnOvEeMOl76Zj9ik1spzepWJPRPbyZo8Fs6Fesk4i8LulN6T2G1uWl0gmQ ###atYFWQdtFmiafxYr9yzMIRP/kvbH5Xw+cxd3+Or/oBOSsqJujp0fl9M3vVw6hiVJ ###m2bKgP+jz5S9++Ny5t71yfhsZK6WlRekU3hG+4/nP6f1J8v+s9FYq6/p9p96rVnY ###fwr7T2H/Kew/hf2nsP8U9p/C/vNk+8/RSdz6Q5/lyfvBuqmfAQXC665+SIE22men ###7T31A6Iso4E+xdXsWv0I3SP9buyzntuVgpNIPmm7/enKOb0LAVA9dyRSaGAYV88Z ###k8f5sddb6QAdJbIOz60fVR2IIo9Yd7t9bk9H9nGHhR7xD2Exdiyr9hJ9UkkrRCTl ###I8kdlJUc68TTxNYvv1TS6x/RtAgZkVibQFLBeqUjJPZDr6dmGskzbSPftOwszPMG ###eAbSxNq0m4ZhvQfK4EJVPBPynlNmljO5JJIHL3HXDXIC2TTtEoDIHvmDR8q7WUmc ###9hC+fWthQxmoyMb05smPHnkV92wEko2a1MC+GgexZDE07a43pRbE+OHEzIM3hG4w ###37TT0dQZ0Jw4ZXIu9QtshzqCSTZGpyQ/l6ql3tnAELjdGxs4Xftss2JOMkNNLGji ###3XnTR17fAvgoHMAbzQAMlCs957TT0fHIH6XfWwqyI6dkGpnX0nA4PajuDGEEC8Dg ###B55cvyRt2n5g377/PXvaDuVDoppdVgl6lJ8GZNqAbUzQo0wbRQ2yhExB+rTo3yqR ###4UxSC+Q4kVSbyPBxB8lw+1whw0D/CzL8YmTYlPFfuqpUziZp8jBNP0u0CxLC3EB+ ###+p0Jcl2an35nKHwIhfhpNfg2A+EokPMTU7ptJOsjPzwkpvEjMZFJiEjuRV0Wi8WF ###6ZpffmWAe+vZY3EqpVTEoaflnPSu4ZJEbHRzzoofYZMJ3n+tFIVpWmyGkAxrN1IZ ###Q7gh6El07cmwzRGb/ZB+S8IT3HUClFKNWdcWyML2mHPaC2dy7U7zzZuTbQC42YCE ###9lktvoaQBA5HiD8E10oEaQyJDxa4JuyCZN/OOa9J1rQB7cLG9AiUgz6RKFA7poYK ###Mylk3s4zca0ARitEKccRTTO9VHQP6Yplpy3MQ0bxoCQyWhrNpm+jIkzlRbhZmYm2 ###no+J5hA7QJlu/MiUd6iHCiH3zTSeCYascpIERHjo4bOEmcfBOcb4H/jdShoQ90ZD ###ZEECIGGUboKJrZgzwHohIB49LxCrJFdQ4v8UoAlJ5Q8LOEWUEvvdd5muN+cl67lx ###BIHP0vcJc7zUPtMvd/oLOyePFANYBlpwUMXQ4meCyzgtXyihBj70KSI2sy2EYjbW ###JvFBBLxxAmBqXT8UuOX7hJ+xp520265SbDKCGr9F1O7pV+iJ8FJ5C/Uy8cJ5mdx/ ###2HY+tuYpD708NeeaAeJM+Jibo9Iee9rDxePYzSEFZBTymnNqer0+UDHbxPmNRJ8V ###wE1cR55dz4a2KJQoKqK9P2i37d32h72/d+gBCnc9G1K2m6tgNJiB+MP6oYHOuhqM ###urdp5CTH/eC3VL0fC9OSF6Qnee8HTl3cj+J+pN+PPUpowyt6WtxuwVFUFrdZ5hub ###N7DpTEtRqimsXMW+6rCuYiI3/CINbHvKvOarYVTKUS+P7MBw4iR2oSA04TWowtXT ###IsXinVkPRPUrELzvvd70RtqGWtlUvu16iVOzODOipaASsAPDhWA1FSqVE3UlQC8D ###eM8Evc7JOdNH9JiULESwSTIAoctPBVoad8pUDudcx5+pmhg6D6GivwQdyqlA002Q ###6Kl14w6YJWTCMhXGzJQhl2aWE7N5NnaTn0/u6T6VYZuPNP8ksiym1drN8wZuLvD8 ###KtPOZ6hL221eVe0h2XGS25lpAUNifvMqsASXmd3wEUP1bIjj3E4EOFtfFy+MKpxh ###U0ES/rAou8SWXsviJHCut5jVLUzqxjgqemems56mrVWgyRjK54AmH6mULWrybVUy ###dN9zbusnCtZph8g2u5rJDvqhWlZiiejXalh+On6IVJYbK6U6E/Uuk4vazSNpIQIv ###qFgz3yOHOvhuMOKlsdVjvKbqszRKKVv/5vfi5aENh0gGlAzCMse7KarYJs0tDpH2 ###YpVCRS0665ef4IBAxnHYRiWdSxigkRqauQ8JBvH5cCd0YkR7YQru9Ck3FQN1wDJE ###cSWMB5d27mn9K5vV/c2NsgJDgxxUnIocC5ztuTLW5sdS3q/0HAjzQXoIAWQMdeZ+ ###9jfnvR5HT7weBZ6+BJ4qosdwjCIq4OS3mYu59gBD+h4bSTm4KHW2bvdl2Hq0X8rp ###6iDQccLtvolzB38UdPx5hIQcq8ejAQpF0/sRPwWNN/GiRqVsdw6PQSms5pvwqEmD ###9pITyuc3j9cyp5WuT8Z8c0xbzzdtwGrK5Zo3B1J4ffIua2SJJgzIbyxsjuna711y ###ooGXoRFbTY5pe9k3T+fDolTtmbjYvji1ps5YVUtEWMis0liNm+5uNibusqpiypVd ###kgqHfzEk2C/N/HL0jOGKVEKR4/3oXuGNgWchlVqol2EPCPjVaHQL9xHfk8WeLXfi ###jYDqeNNHNn8lk0KeRl2MM+dwo/oEQN5Ud7oUgnhJBbZAj4PJBNDuk8uihcgZZ3NO ###/fRwZp/9Usn9HtC0xzOWpdcqna/so6tjzx31++W51OKje3zRBu6Dh0EouaYlax+6 ###Pw0wq3jY+znfgEXeA5OhHlYwAXRHdxoKZKwyegF//3Y2X9GL387sT8fO1D7YyxaD ###lpJ5Le3FQAyFDV1RjlxxZYw0Nacfl2tj9JHZl0tMS7OFgCDiYLmEwcuAhkBRJNfh ###PDU2iJderViZpFsqacGywESEaf57ukQXNduiwjaKmnWGAk/k4Ze6V/bZRva04Wnm ###+BefdqbPu9Qd2Gdr+aYVKjREb9fp3iRhVo57mkWVxLSC9lCy3DcRcjG0ovD/EKdy ###UKX23CRBsHmenwT5BEV4QoAO1Uzw0AB541D+c0WPUjrpnJVNKvOE0aTaOZ2zkgR1 ###sxEiy/xgEt4OuOkhyYVattn4wTfbYKJYgsXlfIHCaaGL0dqhTYvu5kd+f3RkkCJg ###t/zjSu5pFVulYdAc9OPBPmtmuILG8O104rLaySicGooBP4MOPsXnDwN5jUbxHEQa ###HZr2mDdmA33kllKY/NDocUO1ttzJUHZ+RkfNIO+0wC7xWYFvjXinJRMjGcZ0jLDc ###QOKseaZtnTfIy0tnlfHPzvvW6YG6c5pZve7SfPmp5XtnMuzAAO6vTL+0msIwx3dr ###njrHtBeAkhmzxc92DAQTsz9OoXPel1C9QO1DO7gZ55s42u29VDkivuMc05KmME15 ###l+XaEEzdMVyh3925gDz2pt2bdh4QS+QC+1jALQcLy8VtZ3jVc2C7tUpuKoUG5BVk ###A0esfkP4OM8xLVxVUrPaUh3yjGlRtmRPAfbEc02Si9WrNgso+h4L0AOF67ldL4hZ ###k+GZsaEF2nGK57N4Povns3g+i+ezeD7/I5/PmBcXep791tqPyaMrzB7iTT0qpkoh ###K3Jj1UEOPrSxcV6jlB6OKAqG1dBsF8y6WAY0/R3FGU3v6Djo8K/ncr7D9kHy8y0M ###zS4luDEHq59tmuECnTot+2yz9EPg8kSnxIMUJ8QFDELjIz8pWka9rXvHOdylYyaS ###0X117ASUUgsPkzxU7pyJh6lKrO5sihcvInlhlC2vrDz23K5bvcenB3MrOhPJCod3 ###V9RucgcDb4w5GNk0Ae8O3B480VdASt0pqQijdAE281rzR6xIVnwDEXPaPrXFim22 ###YsnDFL40eoOOg/ZpJZtTa58KyGQfZ47Q9CXaVXYgvnYszFUmzrD9ITwAE7R3WF7s ###TDa8JbWkhG+VqBp2JUysqYRwh6W/ooMfT0Z4m6kgdvB0r+InXuK0c9f51y8GI68W ###+ybYxrTy5nmmHocVzcKPTFMzcUgp/C1ctZibVqmGFXob/1tfq9bL5XykC/1ecPpv ###4fza1IpswtxdYmvQ5o1QT3froI2ysy/N/04E1vk+N+fhS9RYSwM4+5dgocB1pIiE ###kes915OPHaS5zDQAYkYInWWrLsJojdNqZqCxocx7suwJ4D2RirvL834xk5YIxnu7 ###diCCDeBS8c/Smclwt6Orr253+tRXcWn8yT77lCOuHvfInRRSt5qPkNJW0SjTqFWy ###eFgxrah5C+g1gjdwKBj5ecy1ndnkzrujXIOpBmnnAVgc3tRy+lQolvxTgI5du/M+ ###G5F3fjqQJe/8t1Ztpb7SmMeTS7HskMEqEJVF8aBGE6TDooy4YsRk9uPfziKTk6q0 ###wsP67SzbHREmhRNdT9RqGGP/+Uov//5lURzmNSUzwwGOpD0HMcvtZQikL/lMmWO4 ###vmeb2dPuqVZL3OqSMtd8yPT3nN4NUSaMrr6AhSTQEIXyTgs9grzs8z7TmlZDrWnk ###aoTISdRH5BAJTK6IhKNcs8q9vF/qzcpwHMfnar4bIFwSLy0G4C9z34AH1AykKBPV ###G5Awz/wX794+W0tTYYpphUNRnonzXDxMfsBSshivX5Rwp3t770x6Un4hpmIyrCPH ###bgGxvIdcQGbHSQlsw0wbJJVR3kp5+hy7hWlZhr4EWMtPJYz9ZTFHDXNoF+Z5GNuo ###JENNWyW/Ts1anJbf2bGppZkjIFOtbPXRS5g+hzYxhRVRgSz5py0EZHW3aQTVTFT5 ###u021vbOI6kd/jMXVI+zn3VAcFDSHfGuMWBpnAWY0XimTg85xUT4kXJTwhuisZZxx ###N5OFlAdZTItvSQSTRC72D8e4q032duvMmTSbGjHfPM7rYcY34mQRDJqLUYZrUaSP ###4GPxoLg0B6IYErE+pecQwzSjWG4x7CcJnfmQyHpOJMrtKGY86n1+vIczv8uSzWdT ###vAVnU1XVnu9N1YhLKT2ISR21nxQWKQvsYjus+5hr3bOIaMedhniekdsgXJ87tftB ###3oVXnnvhWU6JcyW6xN1GauvEdJf5pm2dHtnvf8+YFhoZpzbNnITiEvrysC8TaprP ###jynMn+/0dPNOz83MrfCTM2gZtZ8fZtMMVp8pXaPdCk07M1IZou/yuIKPT7LUzPq0 ###xP/Be8enj8+bK5ogmB4ak3GruFrDCG5sDW9Fnf9s8BO2+uoR5pgWI5H2GBOWOu3F ###jctSOMilQFgucGLgRlR0JS5j07JCzg8LZ2ANrunEdYbGREy86fPdhQXyIv8Bs8mR ###decoOZBHtQJx3+75bB+mJvxQ2rvn56k6UwproaNzyBaIHdi+PUxhx5zUeBa7PwpS ###StFohJdj53EwcnpGrIza/lTEVKbtqimC2LR708mgkutl76ZkGPrD0I89TEvPN/wG ###I9SogBNK7CSJowsgS7OBojh6gSwjO2w8wi4M9VL80Q85PPz5hMMzhud+y8wn9yGa ###tife1afKkXJqs8Pz1vGB3T44+fXivRBeQrvifGns1OudI+lSKUziBChYNl98NQfT ###H+1ZyJGViA7wINp0JjifN/VTrrRP8+gHXyb10x/MA2Pv5NdEtwuqA+pihkHeKkJa ###+MCmr15Kgs17Bz+Oe6QaxhW6wdQbUgkLVAI6Y5CyUAEH7wF+e3/j+hbq+GA/905A ###bHBsU39quv3ER9dEtwkjM8wCxGLkIp35RZQM1A7dMcMcoGEO/hw4Q247yAug4tCZ ###kEOJxKOZMuTFhYUf7//3kzOS/4GEBX4ozyEssKF+urDAywD/5c/3L17/VzKnvOn+ ###gPq/tbWNtXWq/7u6Xm/Wmht/qdWbjbXVov5vUf+3qP9b1P8t6v8W9X+L+r9F/d+F ###6v9i+d/3rd8ObADC4dGvWABYLsLb91jBXca+Sd8NgeiKEruFq0rhqjK3q8qrf+ry ###iLf1SgM6ntbjltnJbglLfLoDezydgHzB0YF/YG1br0NoVXfYF5fSVpYs6Wvmx7WC ###ASlsrj7WP/RgkNoW/HgXa4ufLm9D+7L1z1eRzAZrhT7SupaXt14puGoBFnj05xdo ###ScfcOf7Y3t0tsT/OO++PDi9KbCw0Spat19ZGhUK9mUPNR3g+bNT2tvCFufi4f0C+ ###KuVoIoGd0kTS+qVvly0+EcyBMy3B3zGoVOmrL8Z9MCeZHPtYe+I+xETJ+zDNukqz ###ZuyMhmaTfn/1/dWrPPKflGLzB8l/jUZDl/9W15uF/FfIf4X8V8h/hfxXyH+F/FfI ###fz9N/iuynT8tkKTIdm6adt5s57pA6XGxkLDPCYB3mpbCPVs7IN0JccPc4t02ihB8 ###EF0k7MGP5WVFAESc9UhOKUXHXKaxW/v7oXSCOObhAStiE6IAdq5G34cLKaPgVI6E ###lL8U/36q/S+hCuITZMF0+a/eWG3UNflvvQYfFfJfIf8V8l8h/xXyXyH/FfJfIf/9 ###DPkv+mQ684GASQEeQjwsqkwvVmU6biFjwZ9beuAdfIyfvoriQ8lYgsut7sh9qKFu ###sRERpXVgyoSY4fVLojHJSZKYExZjnlg3TmB9xUfwCrMbemGOz55sRWXDiEmHnl8K ###l9ZzA2/i9o44XtjUtBJ+jQGnrLdkFgr3R8PtH/3WbNj1db5adRPfLRejHqK97BiG ###/te/Yl8OnQd1SVGjd1Ejz9caaUA6dm5dTEPlRnhP6A5vHXAF1g3wB/QaOz4ycFKD ###Eb7rD95wNrQc5ArcXsViZY5Ee5hb/toI7dhOt9JORIN8HALlxO7OQ7x7HDZPOUAF ###rCzWa+h0bzzfDbOKJZCW4B6T9+KfEogQH8RKg/bpG1O2zZ1tC16Ek84RPi0ssqaj ###HHC4mtFYStdpjW+Q41Z8CCxlsiHyrahFCFt8Ny6MjjaifTbbCSJiRGyqO0gD9hy/ ###w740rG/vxu3eYsrXe8yKPZoNehwmVm907+sLxQUopEGlIeJwpKtivMFWWRlVXZQA ###XPIqTGfEwKaTIm3ME/dePgvDsPppmBOtxk6ek1bDlCx6RJpUSZOasAJ2b9whRpco ###yznyMVErYXjFqlUoGHrUT2wDsJDuVRyfZGDmx5p5sTsdyxOHZpPDC+xwykY315Vy ###BiTMk/DAIXbU163/tkCifmttGuCiE5MUdDPhxbs07GM++yGE2R07d53eIyXuNfVJ ###Ww8H0j7cLcrd8ZZdlBKIzb3RDHMSY/xgr5wEI/NxVBvmhWSgkPoXLjo/lZmNF6Ux ###756NxsTX8LRLIWEuf8SfAXU3BebW15MvzXMRuNofmqC9yr4N5iNNQPv602hB9tPz ###4pc/ebu5dzzXPf/OTQ30g5V7DkWP/zjzQ1z/H2Au8pHd9/yeHfp3PskTLEP/X1vb ###2Ij0/6vweX1trV7E/xT6/0L/X+j/C/1/of8v9P+F/v/n+X8dAidk4WMzrQbfZnCJ ###A7nq2zWSZ3x3Rn6YgiasoOP4jJIpRU68qSlJuJHtKmWn3BFJwqNQHMwSXm/miM1P ###qm/ujZJrjYfTYjMlcwPucej1gDC6k2tPzgCcx0cso9pglDY7QGqaN9NP1rSPOae9 ###cCbX7jTfvDmADGCyAW42CNb2mSE3epiWYzhC/CG4ViJI+5TbatG0HDnqaYSuaUz0 ###D56W7iGgXfCk6AZ3yDAJELUTxfZ4SZy5DEhUDq7CftT5z0bMnuRPrh8q+N9HrEI0 ###mVR4ME69yX7DuoxChyCuv3S9ZJNZMBvawbeJHdx4/WnJes2Gfi0WAL/zVCiyK56h ###06Po1KhYj7FO+IVkkMBtlLRNxtrST4odot8oUmhLgfkQLTjunRtqWnAdYhrmztds ###lDic2ChVbTbcrrHHg9ajbuoRboV1CNvgmYg2ng/UBGtA9WxnALcPzokGLCFsxbp0 ###gInjVK0wd87krMQPnM/YTOpBz3tJwotqqW69e2fVV8u4UPpN7ksoI1seP+2WNKyi ###4csSWjlI8a0ZJUCiB4RRl4DxuAOkOPI7o2a4Md0ryTOzrOGK2pI7ZzpXQUlafVle ###nUx5iLJrxEe+BMK1VF/PO6vZ2FjfNKKxcBfl5xeevUYZrZocgtduIVgNTfiG2mJQ ###an52fmG3ToGz+swwDB1N2RrKgJamUV4lUSy+OKZAZGCgVw6vC92aKsX+ISzhB+Hv ###Mv31v/gxTW64Y8Ao8iVL90xGIJU44fqbchihPBa64KaOxTBeOu2KtZ4E9Ho20Ov5 ###gP6YDvR6BtBDqAtmIxBoGeM6FLSMmBgTCUjeC1l7jfhVx41Edz4+AacYMvtUq9AF ###2Ah3wnWN4kD/ENrGuP5Pza/7HCGgGfq/9cb6hub/u1rbKPx/C/1fof8r9H+F/q/Q ###/xX6v0L/9/P0fzxPNDCcblV6UebKC19UKyiqFbxYAlJDrqGKdQsU72FL/4LvHET/ ###0WA2dW3YIAd/zx1MnfDvLT2GmSWj0uN4YymNwsQ1sYZclpvnAgtXEXH/wgK0ij4d ###FZWYwdsKe8w7B/rESCiBbqh0C6s7v7X27T7AJLiUUBWkY9lX5ggVWuxu2V63R/41 ###0V2iu45rttkqbRzS29s/rFiblKCnkeAMPOew/kgdWcTTMh8a2oyQ6PSKv5LeaLOs ###aGeOZLWcNoqeO10ZBbtynWPCweuni2aUIPEIVyJlLBU6nl2FlZPEAUqXa3sbuIN9 ###ovn75OgKbMQ/dAf2vfjFkryQtM3+iqvjedaEUkrabvoxsZuFG4wdj8EDHFFsDO8R ###6r7ZuirEKt+PWH3n4K113Nml4jicrwbqc/VoNa12ZzeYaw+GkxfanPQdhXu5TMGt ###L7RR1FnJaa+y1rQ8B2Bnvoev8WYc6yN1HT7keLYCZUIIhSHvdZEFjVbmX9nUNB4A ###n7p079lQIpVQ6rcGk8+J9H/p5G/FdIeleoLzYPVrPoyUdIxyzxFClFJQYmeHJyyL ###D+D/xrNqfJGAEcuZyJ4hoRPdrMQGqmRu0ZQUIb4clkRte1t8FVWYLicl0TMOEUej ###dLpuAC22I8jyJxhRTQaSIIA4sMmPEz6vZr0kNNnB5wsdG7U4IzZFapo7w+zLT5o9 ###6f4pB+st13XspdVWUxaq0wrpSkV5V8hH2JHtfsyBVqEVCBQc/GQXdfqH52lkgy0b ###h98jRXdjHrJBm1EWZ7PFZT4sOVaxqgBE2qbhIsOGL/5xemD/9gGk2n3urS4/Y8kk ###SIX2mLzNkcOylO8z+/8KDB/nzt0HuW8Sh6s6DufiGF6/FiCAIwGSc9dJhkA8OInv ###cB9JfXyZbKkyy61lVknHBIIbf0YMtybiapUZdhLcvGML0T6oWr/Efa417EjYRkkD ###YVs0W9YnMQT7pJxlbSvVu1tj6+MjGA6sxRuxThpDmLbjBU4O+kpSwJJqFOXzhCEj ###OmiS1rGccx3ijQlXQsF4wFDmIsD6QW4nrUeKdeAXtjua+dPRbBK/DtoQqHmFdjGE ###2sy5Kd5f3k86cTHRJiwTp4glc/U+PThny6ds0Sl7DRvO8RDA0uyxO2Hpfo27JP7k ###lvEntyb29lbjSwwrg1loZZcwwpd5lxcyt5gqOLhM3PWXGL5lPAOJZ4V2Zu3WZo6Q ###8A4cnewfnB6coLpYkxzNYGJOKYscI3VMYbvmmzkWeKsoAAyvWPIbnyC4x7QybhSh

okay bestie, this is just the base64 soup for the source code, so no reading it like a novel ๐Ÿงš๐Ÿ’œ
###vZJH5uhgh/mFvFUZRkWSsBfN/wUPJuJB8Ezpn7Ps/81asxmv/1PY/wv7f2H/L+z/
###hf2/sP8X9v/C/v/T7P//B8bwKLaHpeayh8645JR1XUUJP0MFy3+DwP7WqpWpLK/S
###GbncXJ2rddbbohABpJsOehQAie5XyV8ACSZy3TnXZuk1RKBNxaqv8Qoh5Vc5lxmO
###05bHIZ0+1RuJyrO6LEhHL6Rtqs1K7UpPLpH6RC8FNUpoc67i2bLtfjxfKfKnhuzI
###Uw/CarqeP549uTJSVu1urX53aJv/AfW75anP5PLt3BMgaR15dj0b2nLZedTpvz9o
###t+3d9oe9v3eotlW469kQoS2UixxPkCW0rgaj7m12wBJXQlSsrxVrHHOm4N+CXHwZ
###VW+KIerSN1YkylxGCntLRaTYYMxYwpUF33hJKbZ6niBPz6K3UdHjDErxU5Ixph6l
###bxJLwLJVLAAK2nGblie2xZFXCw/hny5b7AxQN7PHslbZ7YOTXy/erzQq8KT+2rCT
###GiTZ69jIBisvLkHCAU+uDkVGEaMWncGVmVDFfi/lnIDWa6v2UD+kqAt5yHBtX9na
###vsLakvYC3xqUdmJh39icX2ENf03L58KIrKpuIaKqPCLScEDisbHBxJCdZSVCsOXt
###5H1FBapCxVKO94Pr9tX3Y2EPtxf0csv7fuDUxftRvB8v+n7EehfvR/F+aO/HTnom
###Smc6dbo3dFwkhHh9q5bUVvZf9TCYPNL1JCT9otR1SSaB8CHKzFkm72fbqkZ/GbOH
###wevzf2K5/6RtaEsnNRQJZxX0LCMFJakEh7PB1BsPuIowaYvS0pa2VaErz9YBJbnE
###+qKPcWEc+Y+0/1zduw9jx8fYhGbjWUxAWfU/a6sx+896rbD/FPafwv5T2H8K+09h
###/ynsP4X958fafzre9elk1LUPjz6HdV5uvMnYKoVFCyzGJpWt9qkFCM0zSSsaKoWV
###KmXnXnMmlSS9UDQD0B4gQ3zgnlUSFAWeQ/Jhq5cXUFv0KskaknaoF3Iygy8XSIbW
###RbhqicHCmjIEc+6AT3nt1ueZ2hQZGUsHxuYHKRs+GfkuT6UUrapqra+tNdeTKmWi
###5SuuBnAmLFDDspSsUJ9K0cCVsJGkVY2mXVZUGfb5h48n+9z6BiMp45h2gPa9dTUM
###EKej5crpfYyLEq3I1a6QA/+z5D9mCn5z87yiUbL812iC2Efy31qz1ljfWPsLlgSt
###Ffm/C/mvkP8K+a+Q/wr5r5D/CvlvMfnPRwGwc9T+u71/cAhgRQGQ+7qpn0qynzuZ
###jFh5T6n6J7xa0I9kQS5W2nZ3PJgF+P+vWIlD67/2/gskDiFNUpXEB5G1Bh0ZeGHJ
###7o3j+y6QtVJ9pVGW/fgA6h/gItsnH49tvEsnB+2OSbZp4OBRmmaeSyhl4P2DvAOH
###XdB6zQrE2afQ87S19/eDC0OXJu2UXvQAc55feVNR+DQc6ujEvmid/3oAckzr4sDe
###PTVObq0B46TMn6fTZk3uJfcASmR3/scsHW6yVWO6l+kNsB43o0EvkNeMX6H1Htee
###Nj8wrtL01Os4R6/VWK9POXqtYy9ykrn4DJzPFH1DlVWju8HpwcHee3F0uwdAEQ9s
###bK+MVAsFbfcbcmvWUBkHgU/UcO/jxdFv8f4hvijjrIbjcOSnOp5h0UqlgpiCZh37
###7+//J12cr68rXbDwZ1a3VXbIknOJskeK3z75wEK4bSCQR78hPYr9q6k9Pp7wmO+U
###tao9MtvTvTPnpImt2hCfaPxXS+mBu8bYwc5eq40UXV+1IRY+ZdUdgYeUxJrKGCBL
###1HWBj2HhmCHJhQft4ANPx0C38+h/DtLPWumCGZPhA9PlWNN70Ot5ikZt+9h4mTal
###VOisym+YDV0bCq7k0Qe7c/wBHkMAy8FhDNZvanU+VKAksZfyevMMxcgScxgxLSK/
###LGTnR1oeZkSw3GDqIQusHP/p0QVc7oPOBRGLduvXhN01ot018E5Wd5C6Wu9/TxgM
###03UlDlbfDAeDX/lo63ww+apHb52Sb0e+uGGSjJR/q6/U902UIUDPqDDxU0g8AZGP
###D465+0LCDohURecKeCT7PCR1WlNWrvcy9SgZx16SqVw5/sJmLCNt0CjnSOKwSVAu
###GRegrZVO1xuAcOeiYEcC0mA0unVuXKdH6M0Q1gEUf8TaHPLJtGyGYYlnIshIvEfr
###c1qPkjK2YckfKFcPrLV9usdENqzSgpUc2HL1BwjIIx8vSloXJ0rEMoTacBwahNre
###6D5jBm30T0cJJKmEz+myVZL3hqUGytLhGseyG3bnUB+rvtBYJriXEnYwN6r4Iw81
###NjcOpfAzIgzIfPBiZiDMmqFHDoQJxzYtnFOwQdrxZq2fTZAKS3E4a6ZF9HZh/jt3
###wCB3Dw8AKy/0TfZRZS007vrs1xb8d383/ZppU1B915xzwFLzzLG5qVLuhKFVnhWo
###z28gj7AJksdeXxUiFYhlE1L+eb5hhjC5iLz4/YP2RcumHRAvYZqguS4mAIFqrgkQ
###LjkmqLKHzeByDCIbdx1kOqhVRXr7cHjYAaHmtzaVbkj+12zEurzP6FKXxBDe52PW
###PMY+GRM1VmuRaMm4OTp1u7X/fz8CA2LsvFkzcBcEHw9YKIcpGYVCLpg6V94AC2w5
###Pl3eO1fk7ZIRAW9nh+mo/gfYYuDwkLs76aTIGqfnB/tHe1Qx/fTDJ5CFDXhad1f7
###2Z3s1iFMaJ8fdEiUrruN/qvY6oyvT8LqkAfM06UWVTI7xSolmPbLYoMEOjOVNRij
###wPQWXpyqNyNBJMVR93b/nk7UmR6BUu7yDLc3zmQ48r2uRHc1geJj58B+3zo/JtIe
###STIGgUzcbESMkWAO1HGZfT3GsEZEPRkwyBuIPuF6DoCtOAcxJ0Fv0UzgnHvuwHmE
###IwIa5AUE1KkuBHCCZqPvLuDyxUEnkY+WD3b342EGSwgHW2+onHWr8/csS3tJH50H
###g0rKp6MOXgRYc+sfuciX2iV5FSV98CgO9cQgiyATIoUTuVjTevwo5X+NXvKEcIDk
###u5geRiAfii4OyfEh+Rh1ayV5hfruSRnHXt0KA4C661iEVfQuky6KPc7ZxCVU97Co
###FimYJbhxB6FCIya/EbH82O4cdDIVQEqf49bF+dHnJBUC+6eSVE4COG/HRASUx5GM
###MZrAtcYlreOOjmXAQ1sCSp0zaplxuZQBeazBvGOoi5D0zEkacNjwe+DxrLETBJy8
###cTxP7hOSsaNf39unrU7HPjo5/XhhpZLWNDU8LOK3kYfm1e7Uu/Omj7Drafg0p/cV
###i8HU1if2butkPx1JJIKHXUgHdNJqMxGZ9KF4SxOET3MPI/eOolTaBGV1HScfjjr8
###IslqJMXpqV5rrHIdyzFXR72DDdV+Wbd0QESjdezdo1bHqEkXqs8heaMZ3mUa6uDX
###Ful3ORt3tmZScG8K5U/AhwOpp2Y5U6uK32lDdk7O7cPW3sWHczvRW2t1TeixI3UZ
###Uiboaw2B755NYhkOxNAq+DbjQwPA+NZ/J30aGoTHntt17/GtH8BYzgRoUYCDOuPx
###ZPTg8XoOwD8OWCU+7NPuHKqcEabj/dDhRgV0DEy4D41N442gi4B5V6XE9Wb8lygw
###TvrJPst6gBtqj9/OSJ/328EeGUcznlq5S+fj+W9Hv5k76V1MSXVj1zGrB6b91d4S
###Q5dQUjAqut/UTX1U/ki7943sHuZLnzEBe3svJo4feCx3cEh0Ea+GlDHvHvVDGr9x
###cd466ZC23b44Ok5WgAB7VuOXkX7dBqnYAq45psQryUMCmULLH2OOqM9SqVFbWi2b
###V3CSJuI3I8Xye2fSY9UvPH57goQ9nbTSsHeREcWWzFBaZMQkcs+P33BCK0YFajlp
###uQmWC21wsYyVtCNkeLb76YD7xgYoMgE1GzxaTh+dhDFbOmZIHgXKdqEHF0HRDyGZ
###QK831za4oZHLiIi+eyfWNda9jHGKeye/Eu+CbHqaJq6xthYaJf63PxiNJqXB6LpR
###0sFYLlfr3IVXnoIk6M7xxfvkhVur603xjNbeNNb+t1RfWS2newnLU9D9zpiiDlNs
###RlPkcUQ2+Qx8j9zO2c8/iP/ndIYFE+youtGTXUEz8j+urTVXo/i/1RrWf1zfaBT+
###n4X/Z+H/Wfh/Fv6fhf9n4f9Z+H8+0f/z4uMJLN4GFAQ+EwDb0V1BTQ3m8fXcd7tA
###IaZA2+gZQjdIetFGnmKD2j26QPPP+W8fjs5Rfmz9I0PiY5qSBIXCKfkacE+hZI3a
###Cndd4IZfZvcgBpzWen8Dr7Ef2UBIPxoauIFQJ/t4SJ4Bn97DleDaqUNEOMDbOPPs
###VpsMXrtqICWZOoyLyTs/qgc/HQHrDgQO5aYPJ0ZtwS+/JOpMV5gnK6mIsMSU1xWS
###TlJ76iADi9vU3sLLeT0bOBNhGSPewrBjfSuoBkbPO9ShZcgVAMq1fmiH01cQHxmN
###cPOMLJuB4HKm2dd0bzitN1Pa5etfe1Pv5zcuHn+kfTGNTKreIlxbs2/ufZyrd2Mt
###ofunfN2fXV9Pus5QiyrXpIW7BFwXMiqRX2Hkgjshh0NOOTRM/A1IPb6m9vtTJgyj
###urWecWapnRupUKmvmbtHjhuH5wdnSd1Xua+9x27Z0HmwurNpddTvS9ulKiyBVao2
###0QVmPPL8aVBO2jOa1feAszg8tBP9i9driUvO6lrXSTozkgCxGM0C/bTZCf/W2o/8
###1BVDJfP2Ft7L6KhtX7w/T1RksctJSDN2XcCIlrDKkC+865MS3DgVeanr86XMVXvT
###7KcZh9gD5oK8M57OnIGMu6mGIQYRIM+zLnfHEbZFtB/0ZnRnEPMDtsPQ7iS/wr+S
###NQHe33O7l31zrcabGoMaj0XHy0UrwLkUKsXeVr6KOzR89cRCZOsaOQnACoDvyrOC
###eefH72d+OL0zCZNKqg5rwO3Aa517IeEyIgQhD2eaAB6dQJhvuKgIbznsm7tzoEfb
###RF0sz7fIoRUuOLZC5IcZqqGkY58BvWUWKwPSbXD8BnFrzGXv6WSkeLMBb4qvGQbS
###XxyhKHOeSbjrfNQ+T/WGagYmCPapJK0DUmJ3NJm4vGhgWPVJ9Q3MxSMxvi983U1e
###KixiXypNGCI2MUH7GVyQwg/xaYCP7bsTIJYuiLnTe9f1lUnYgxJyGeTH/uiD4Ix/
###mR1pnCldQx4QpFrTPnzikS7x9TKSHz8BtkxSB0WuQVejUUAZ0kvczZ4vopxrdryG
###H06O9uzdDx86F9k8Se7JhbfrI8+larh7uAgyrSMDgZJQxmrCRWS7RYUDZbhF6ZRa
###3592rLAndBmNQKptUvceIBB/QFvDp/ge1aXV3jDOKHoEGGHhU7OFTEdwp3sB81ud
###hI+7px4uPMLsfpkiNYybb6xlz02hIcPRJHUVuaj+HOuDczEujSw9VBaAVlElfnEK
###tw7pEWrAZKSTF8Dw7eKofWHNwcrHF8DxJHtuuISEMrErGCFIvjWF2K8uJHwD2Slx
###xeudO3mky5+AIoiQyFHmvR+r4tkb4BMXcR6hKJ02bxQCFDD1JTZAToUTqJQ1ikuj
###r5f4lhiA+EmFxdHVUKS+BzP4U1rOe7jgu0i7KvRrBx3asZ51xbrAgyyxl7q6wxA+
###HEfhl8njJWLwc6DSqnaAXFSlKDcA3vkKsLgTp+ci485V3sBkeD3kDRWficj5/3h3
###v5XECRj4biQyWueIn83oXK0ZepMj1sG+LTyzOim9FaGYdVfIf8bk9VjvvQ+or8vR
###3bh0JrXmgF3tzWafRycOx64fCB/4MNC36wy6swH3xkb0qlMU6JCyuEvHdX6w/3EP
###XvyjC7r39RpGriRF9SKz2aipnoWkW7ty+4iUjrAoOJJaZRo5XmgOhhGb0flEyiLu
###V9pJikLOY7FFC3CS6hAX8GfN/0PB5DYw5nb/WWoAZth/6xuNupb/Z7VeL+y/hf23
###sP8W9t/C/lvYfwv7b2H//Wn1/zC/RZhhJ8xlIlLchKlFpZJEgndiGV/VLzCWSylK
###lFaPKMz+ui+mp+5kvXAni1cF6gf27fvfc5TliWduKUHH8uLTYtqW979nTAuNjFOb
###ZjZleSXx1xalj+AFZcVqotNwAmA1piUOBywlsmn961/Sn8C3qH+HqVSV/ry0uX9l
###k9CNLZWcDDBGRpOVBg4saqqfuPdWCdqVmQDPY9HVOuo0jK2WuxFVdgxpIipiF6KO
###jQQbvbu21opxSmm5Rz688w6F3ALzRjk60Hzv+pKPO2EqaoKY1oj9bs4IFFbIYbPy
###df91W+wggiZHpBvxLccqOQGvujyuS+BLRC4Ra6xAtzf4ALtjh/R2vAVbGLzcfF54
###7HEC+IslPBFTIGKJLL3h4ICAHmDGa77S6HO6uhUV4OIe1kFgwIy94VYqWNuGA1o6
###+2jf0rZFit888FNOH74RTeWPZSjicPIliZUt6mdfAlONHt6HbNI2slnA9lJFJ4GS
###6jcwFn6pVu75bmEQ3dMHr9fsYZAwxavUyX7Q7l9666n7fmXYbAyz9E3ydoPp2B66
###wwRqE8vbo5OqJCTUKXUKiNGbhkV2bqux8luJoAsoBGBvN6w2xv+mXHC7852DMr0c
###ALrA9J92k84oDiN8rrKwY+Bc2yCU2VfeNFBQZOZ7KP9tJuOdNlnj6ZOt551s8+lz
###rc5zoeAZmfnBbDweTVDGj7F/enuFPajpmPzddEvIfmwzEkzBO/iYEM9S3zLeKuf6
###dOLexTihbXxGjD3aTjBF9f4R5S1Rexg7wJN41wmL8ckdzDnz1EFY1Tp3CJsISQaI
###vLuzPjxr+AL+7o76JeWLcjl7iABvz1l91b4yDiR/XZYB/930jN6GTKggYluxViqn
###JP+pPLlUGsLt3jK9T+ikhsL+HXAfPYEmJs5RmQOr7r1+bfzq3XY8BYDgD4ANmU18
###/LFItv64/rd9at8BP4R+QHZ3Nh31+0/VAWfof1c3mhu6/nejVuh/C/1vof8t9L+F
###/rfQ/xb630L/+yP0vytLxFEdDAbeGCjbyp4zQ3URd2fsuejGI4hQ7U2dPMmBo0MH
###BHjFxuMBUGOWtw6/Gno+S4g0HY2piYNXfCYeD79HbS/RA9N6i+OxH821L5QrmDRX
###PXRlt2RXds8NAEYrScrq9+6AsuTOfF6RmBRw49GAHLCIGPMyYs6YvDNQLwVkyPMx
###NYoV1S4DNlDqarNeNvZKKWS2a581Ni+1XBJfKskdWvEOLdHBWK/M83umb/mgfaeL
###gftxlbB/BYTe2YqUZJgJ711yggVNBcaGNVfulr5/ZzUbG+sko1rMV5s+ZjFUE5Hh
###2QH5vArSKR6NSYaksC6361bljDXRWXDHs116XVumAahGmX/FipTBz3fqgeBnCXXA
###pTOEflKZsHbr024psdQ2NYqyniDu8FEQzPjvCxuwsuAQy1iOjK+p+pLLEEdW3sqo
###rR3B2eFwdjQ4t/CzFDhz1Id+T4FzK75BZ044t+JwduaF87zLyA1noZnBWxFdtKrI
###x0OarvK8N0w1AhnH3BZH0rqorydPbFj/v9v1le7en+b6asf0J7zM0k3801zmOaGe
###YV0ROsDu+LHEsLqSgSJfKhrnsSR0hDKfEFuZMlErcaJW4kStHBOxzcY2Ot8mE9iV
###BfY9357zzZsFhu+onsTA3tF9VYpwZey0UDlaTOUoWYavHJS4gWqyqECWzC+FuIrg
###JZdz8XJeX/TmmDqTqXX1KDS11jg48Lt71R1KzvZuB69/kl8FRflTOCGq/5PG2DYO
###oRQGjutYJV8R+FJzExG+Iu3TZJ+N0FekfSoAaxol1WnDlPJqiRTR2S4q2qnikc2m
###UiSIYdq0gsSK+jvFV+RQ9pTITsSlCwYkNyRILUnCSUjvyKsk5vSCBCLB3wRPsLoT
###ealzq48/sna2hfI/qcW7bUOWOMkZ43zmhwkT+pbvuj23p3pV4MiEoH/d1uQYNGFw
###J36XZ7dH7kS9V1LkqfoFutrjDMZ0d9uUobD8Sn8r+CPZpurGpgR41WRYUGnjqkXc
###I8ukmzD6/tFvzYaN/NsTJytXzMDnigMrEk6FUUmq3Rxyj3JJZuXd1ICBMi5v+srI
###suI8hDE6RZcbGKVbeUhykQkl/DCwNIoVCmTuNEspIF4v/pjQHiQuX57147iHE0rR
###GszfiedAp9hJ92EapYqOLHNJt0NAENVyafdsWboHZERMvlN8sa3z4xbGaVXjSRmM
###oFepCKB/E++1SkPg00bs7K68bzOnZzsDlEkYzVVBylZ+RA9zh3kT8Xaqw1tdem8X
###sP/1vQe3t/LcprENtOsZ7X/sd2b/a6zVaxtY/7m+uv4Xa62w//2E+B92/iLyzsaE
###n9eP9XXMeLygITgr/metvh7mf2w263D+640i/2Nh/y3sv4X9t7D/Fvbfwv5b2H9/
###QvwPcTzcrHouEhEwduit5U+uQei4f3gA2bFhLVn3nx/gv10QMLp/oz8/059ShFCz
###EYYKaJxVd3TnTHC2kkEtEtfJLKUEDJlUJKdRJkNeEm3xf0bNTTOW3W0J9l+ZY4l7
###UuYkoPoT7+FHLPFh0SU+FYya2q2ZkB0PsKsyz0HzQtcMr6yn/csRzkUlifKhYrjE
###fXj6WeLLp//LucTu2XxLPOO5u5CX7IqjrqHCe22RJcZcESzLq1hfK9YguPH6U2As
###zpDB3dIxomsPHTj+e/ZjOhzTfxoVpDwxrWPXv4zVxPqyZb4HS+Pz0X2kN+w4fWCN
###rC66MAdGX+V91DVFyibtu3eJ0XEA+J2kfvDdO1nFxYFhbTPVXveM9SHQwIf8a96Y
###QBNpX8ly5zG1uwfD7sMPzVQnejCzh/NgNxslAWG2rqugZJUiKJW7lzDWF9l4Ia+H
###jQNPBDQusU/5QHvt/wnHht6ANRvhJu9NqwBKeQlA+lJhv+3Ds7HPrCti6tyT0u/H
###H9slvJaKAjIMvPm0WxIoxZdYsVaZJRsmXTNPCSuVpwxPNA/gfQZHTcMZGYgsDml+
###DRI1muEpwYjelzKiHf+Q3kiqOrLMaqNs6S75kTXW6jp+yMRzXP+uIGB1W9zH0Ll/
###NBzPpq7hrecDwLWcCxlZe9lGzK43DMtBIaCm4B7jOJRjpQeiDvsWq8dDhLG20ojc
###2VurGu4WeiOnJHSdvZ7CvoCIGwSzIQpu+AnKMY9DEF4nnrz5xgK7l+JOkBxhtBOh
###v0fo/0XSkeOIX+F7D493C36lUb8abPFJcMUJLqEjB+zXCLCqFRr7GwdQgc6Go3Oq
###4/XRDksCij5Sg9PxpIcq49Rb+/v8AuFlhy/EixCe/tZCp/531x1bI9/FhE5od8Xk
###SvfOI7xMV27XQRXJvYtaFZSSh/QsYhWzmA1IGJpwxe80Jzq2Cx7PJAV24ec7BlJF
###NBjvdLS5ZYtMybFB1fbWzo42jbG9oEMExGiGejIIBRhrKtngwTf0JudRt/+J9L88
###fblrS2lNg4W0wOn639paY62p6X83NuDrQv9b6H8L/W+h/y30v4X+t9D/Fvrfn6n/
###RclIJKEWGsqe51yPeILlyLUvhXEq5dL6LeVTnYaOdzHdaRfI2MsqJpfmUEzqS+SF
###OF5ad0qHVcmv9TsRh4uCzg/SnVqL6k7hkfr8+alLjCkmvdwyPLsA9ngKLV+H+iuP
###/rdPFYaFwIqSakbrCr9Yitj78EDNML8Sfbv1pxSu/sTy323DQde9J3j95Jf/6uu6
###/88qCIWF/FfIf4X8V8h/hfxXyH+F/FfIfz9U/ut416eTUVcWATtTd2zNxlJqBRjg
###zp3Q09UfuMzDRgmfADIhlRHVIysimZEzW9ny4RKGAqxWdPHgg+bmo8x0SRkIv1jQ
###8Sk+M0sTHsNikEzOE/YfTm0KLMs/NUuhmOncZGq2gHfGLTwJMW+M1nQ4vmTFPtDP
###gpI4YjpHNFVGUtMtk5puQWqixcCvmuTEoox5kDE0u4UfBlMmm84nwzkdOf1hMlrm
###HTAcRLFLfipJ31T4tLdWFf7kAZ7s1PHDBKsp739LI1cV65rUt4KZG+cISyn+/WT5
###j0qM2YHnuzYwbr3R/UvGf6zWtPx/62uF/a+Q/wr5r5D/CvmvkP8K+a+Q/36+/NdC
###jshCjshiHBFSAZ7cgnmJv8ktdsBwn/gY8BwGb59oyoHhsLwlVuyU10fkp0ZSqLfS
###mHe4hnE4GolGnGe4A6qMyqg6K4hh0YuB6VsGj3KOQswaQBXFXWQP0mHHs37QQ3UV
###Va0GYRMfHuAorRIeaJn+dKDdYOrh1EDjV9+I4ViByenAuWKvLs4+xcQsb18x8cq6
###3a6vv/1lafVtfX25sQS/wBKBavvTfulv1v+38aZX+VvFqk5GM79XWl9ba64vAXDe
###rFil27erb2+XN5dWy+XyVtTn//l/gz8B5V5F6RelaB/MfGPTCpj01Ngg0YrkuXqj
###Xq+TCP7LZo3pATYbzTX6ZaNeq9Ev643mL/TL2to6+2qt1mjQL6trG+yT1UatwRI6
###NTc32UfN9Tpr1GzyRs36+gb90vhlk03W2GywOYBP55+srbJejdUGH7HRrDfZR406
###b1Rv8E9qzU36pf7LOttHfXPzF/4LX2N9Y73Gf8E1fgcBO9KUxMSSUmYCm/EDNr38
###UjHpTHglJUBoNhzm+I/nq8mvuFAXMH5Qp1UUF9HUSsXkhUOctNghz7eRtlRMcUIu
###amuAPQsJmZLl/6lTm5LxiKmVm1tRr+TC6po+U0yRtiGmuenU2LedOvs6HosiQEXF
###LLC6iPyBUp+prRIc4GAdnnSQaCMcPpwm0h0DwTGG1ojM/xT28vq1FaX7x1FMgTNh
###n9dWk6UprMkrPNQLKqFKKppnh5yoq9aqYeTbMAnRLS6gEQb19HlKnTA8pqyTqNtQ
###DYZLYHmCiE+mGKoRPSJwcyejB2+o+Isr2XpEfAo/zmpfzhCpRg+xbKzbVpXnW41m

###96KiTyz9leSZrh60lgApoLxg/MmUkrsw/FFDFqC5uh2UGjy/1C8rPeu8J9vIsurn ###Lq5AM9SL6f7q6qLqxkVJCffSlwenkLQ8OWmftkiRtij+jVj+aqTWE0fwMeCZhidu ###dzYJQBKyAClpJW/pJP2Sv9RHLxEMphELo89LfrVexu+q4s8G/RkRHhh/lbMQAVZQ ###d1hVaP6troXl5Trg9+VtinOKoMufBVJcspRNpYiIlxWEVDbOQb/M4ceDQIDS6yrS ###aAJKxJg2gRiKjQLNlYHCwzb24RmWxPkI3au0OgBmuOh60rBDAHdIK7U0jsYtNdK3 ###lBtmMFIi2JoZYKupYGuqBxAiuLFTEtxqCtzq0ZsSH5LBrG6E2Z9F053m//Mcvj+5 ###4j8aNc3/p7la1P8u9L+F/rfQ/xb630L/W+h/C/3vv7v/zx/M90fVYzHfn7UFfX/W ###Ct+fP6Lvz67q+6NIQQZHIBLZGB4s5g0kZ1eRxqlYvxSeQX88+S8KgHtp+W8NpAQ9 ###/qO5vtEs5L9C/ivkv0L+K+S/Qv4r5L9C/ltI/vNRAOSs+9EJMjQoAsKHaJLUP0+W ###/6IvgOrgFY9/QcRiNFA/FJU5o09O23vqBz33anatfgTU0PW7JHeKLQBa74EQe3pq ###7348au8L0da2u+PBLMD/fwXvJFA767/2/gvkGi7RhoIt3zEx5DA2PC8TVmTIPnx4 ###kNLtad8dfTZ1tXsj+7fWvrFr+F1CV1aqIuxp+g56vlpJOFP0JWJLtA65HM4LOyXg ###AJZEhbcqXnAqVmfK6Tlj/gqFJafG3rR7Yw2cazImw5PjdTXR/X1aJacESNP34qPL ###L7lSKIhdU7/Asp7oMYZWPQmWiKehYkPdYOxYk/d39FmpVgWD508RIbnDdGBoCwdz ###5T0/7/5Cmd+If/NssfKztpgrUcfY330EfPkwm1Yylqj7Q/FiPMAPjZ3HwcgB1hhH ###2pp3iW4XYZjSbBycowtNFigFFLuj4RhEhQCYpp4zdSxGkGcTd7GLkCuDMHC0e8D5 ###+9eVXIk6LoAHJT8TmRt2BsjVIw8MwEW541mXOHQedj1MJpwzl8hRH4sZv8V+VKM6 ###Om1ete0KRnveJcKe93bP86c7OUSyC7ACYYQkIh/uiD/Fsq4TvCsjYJUZtZ6LIhyF ###/kHMR4VuonoLY+QBfYoEIchH3f8Y1G+PsSTxfcZ2yJmXRTa5OP1bdIMSztESsfQi ###W3+HaIHczA2/q+TBOQGxpxCVOfPQXziTa3d6jtC9GgeVbOJC7fHiWuIqlKBj+dmW ###GG/moPRuX93bwT3yQ5W8N5f6WawTEj5n1vNGwFz5vXuvl12ucZ4ldm8c33cHJ1eV ###nNn8WXtB954j3VPWEomO2f3Avn3/O7+hJvb2dOIqReYMrSLmbCwavxzXcvCEW5oK ###KWWhggDRUtkS96aTQb73ViyRD/KcubuSGKuHe/usXot7dycxVp9cVJjN4V3+NMdz ###WmKGZBHzCh+7Lgg7z7BA6Q1KEc9hXpZ0LbhxxkQeYN7HwEuR56KeIim7r4ygGCBZ ###BVN67a1r5P955jnlAlF/G/u7tpj/R90lZahFsSD5FslLzHeX5CWKu/SUReZE1CWS ###srEuTr7rjqZXUURHBCWhmB7izwssMWc9mpC9liM6LtVixsvWwGEYZ32Z6y5Zrdl0 ###JOeUZOYO696ZjEnZHGoyHjwNzVkT21EHiBCd29qTi+Vgr3zZFD8wp4BgNphyHwDm ###0PxULFKXaGgWdJ2BW8m9xA40R5oBIg/yx92nlPfJi0UU6FOZE4tIygVuSqzQfb67 ###GG+GiAJQiWV6SVriJ9ZeprwvzUeJyIO8UORBO3DOLM7qB7B6eb1RTLWlWN+Se+f6 ###5Sc9vWFJbx4B0r445Q9PwFFfLUl/cWrTFbK78Fi83BvoPj8/+dxvoPty/GS2iikf ###xjyziimDWUtkwyQPrFbG65vO1CXOcIilzEM1vPas9eFLm3EP+GWBtC+DtEnZu4AJ ###y5aApCc3ZNqe4d+fSQhiSIxsK8okSIeTXUEZSsO1srFNgdLPjNJZ+AIoyghKBmJH ###3q/PI4fMh9KVn4jSf5rXjF+4SKegXTL4Ou12xaxUiLqVvLfrBbRmWdT4pN05JK/a ###L5Vc1BjbB9bz/Hsh1D2aNzHC09XxQ88/8u9+Re/Xs2YtzxLvXHID65NKXnL3J53T ###gg8GvhFpqAu8eqyeRBJeXAFSrLLyoCe7dufj7uG5RTMwT3ZLHInAC/E+Bc+HF1na ###1E8wZ8oKtdWqOlVWkA7W/G3m+FPv99w2wflI2hJMAWcLVI3hxkYl/XYxKBL5mh8R ###Fny77MG4m+OGCdQN2TF+wZw+WueQavIPljn5Qgj3vQlMXq9Zw+ApsrtzrZ2zebmh ###7A5QJLb/pWhUHCM/AU6x4IT0dYol3rvMffnFlhhvFsyu+hM7Ww8ilkjt0SfWlJnl ###ZZboX9k0ayUnLkb+B2KxwUsvcegO7VG/H7jTyrxL5Okn4FojgsJAo8njU+hiMh81 ###mdgTVp5Sx0ejgEUEkZezxFRJHvNVVpTG8z1GqoIoNJHoVsesRwjJZ7aGXyWfOn0C ###yHME1l6KEj67kXpdvh5WeQ4df75a5lkJnMi70JlaGJ5AdvoSkwvasBZYZ9d16VUQ ###SDQPhQeo7MHLzB50+X3USJVEPnmTmNCJNN11uhosQ0qx8K1iW80m8iEUhWqnQiVo ###w2WlrOSpFN5j/F3AchclL1Rn8RQGAx/1YP41vxCFj3TcCwPvpSn8yY+n8BJVmNNS ###gBYhw12ldExkqp5arx8ua1+Szz6uhneDiKK5vju59li4CSceIVDub9wJlmAeSJ/d ###OHcucma2sCww5Sg6ZyZQlCe98HI1O7Zim1b8mN9i6E+ugzysnmQxlEDziHFVC6Nx ###ToshLvEsxxrFEs+YB8GTlvbnE5hVKMaXiJUrGpeYDoqBErFUFSzVJbbOuXQZXh0G ###yBtn0H8hlp5odb6DpiWexQj9H46l7/zxWfqfQPBlCpmL4IOsO3fmgEzljUbK3vLC ###8/cPD1aVUt7df37AxHfAqnb/Rn9+pj8lr1zAYRP5ra/b3dGdI/HdmUxtd06mNtJf ###ze0FseDtXLrPV/DUZCznlVh/wBIfFl3iU8GYU4V2P0dJViIg7I3gr+0PsQrs50NF ###Q73TZ1dEJgrcZ/MtUbAElOdUHHUNU2asPYGAYOShGwTcO4k9QJrbLzWw6as/levv ###S7sr/qcYt8zOEm1KqG61Btfu1cRJcLlY0YSSbpyefv7b0mcV47DRMavjm//tmVOh ###8iAu0GUbnkb2LlfRdVCE3FNaAnKHE+t8MsMwJ0mKJES21MB65rcn3ozgMEch62Pn ###gQJWWerl6GhfcIk3rtOzJ6PRMGfwxT5wNcBnUD/s9gMsTHMUVdcDIekyGC7JJUfR ###B/7zy1MtTFzRm5c6n8vKXqIt8yt5U7UVBpdYgMU0Thh+oy//xITBsMTpfEvkUVnh ###Or+8PGEoaNfzEIbpEwjD1HRJROa754JiTroQ+SS9CGFo9Xo82ga2zq9Zz3OuiZfR ###dIbXQEEm3u+uLU8dNxY9A7EmShiTCLuLqxryos0c4pa+RB6H9NJPHh3WHJfvRByu ###Ayf9gyRCaz4SFkmEgNafPz91iRyzO6PBHZxH68Hatq4qlhMEsyFy5i3MPhY8Docu ###opSK4wH2sdv77TmwurWwfREWwdYQfJtR/jB2/VrPfR7Hcz4pHSyzQZ5PT1PDzKOK ###uVoYildP1cXkpg12WsHjtCflwQLEmj1Bb8Sxeo60Qd95kiBcjvQ5jhR9oY2jfqml ###UcIvi7yaf/r6vzxU8DmKQGTUf9horta1/J+r67V6kf+zyP9Z5P8s8n8W+T+L/J9F ###/s8i/+fPrv8gUo5oSRRUuVB8maOcw4RyJAQVszMUpk8ocecOaba90cyflp8o6plS ###JTxHWoQ8lSTI223fmTqVBOelxdId5FClhTOj1FpJ0o3OnyMgx9T6AZrdZGRYT51x ###wKDAkC5Z2osXsfAq1uB3eNdID9ghNWCFBqe51fIW66v0zfoqL2URNpNq3GG7kg6+ ###2JakGpxi0dy5oPS7OxlVUa8rdSpHcMPpxXSeD33Qvt2rr9uAide+27PXV6XpK8Zf ###SRMhLaHnhp7Yg0EVF8BPltBLnXp5G8siip6Rmz/wl2Shxd6B6DP4XSx1r/0/uDA+ ###iDQ3T6/wVhoql2M+n0E+N5iruWZVYVZ2bOzmwqdyIz4zVjhV+r6j2rBSMRBOcS7h ###47AUiKk6B9ve+4O9vwP9u2g2ok1WrKoyhVwcUjr4iYsJVxnjK20wTKvLSCKdtcWZ ###JtXdkCqbeBYeDPx4J2Gv5RkqnIQb8+Ib09BKIJUZo6xlvD0qVlVhVNPGxeTfzdVb ###NWCnw1eqlhnhlHqFtVKc80Ebzu7FoD3f1ua/5SlnEoePdihFQZlF9T9JidEW0QVl ###1H9ZbzaapP9Za9Ya6xtrf6nVN+pr64X+p9D/FPqfQv9T6H8K/U+h/yn0Pz9U/xOV ###v5MLs0xnyGbbYwejWYC2BLpuiFI9kH/MrRvm5WRFR5ToW4rnc0iyhMfA8a3B6FpK ###4AlP4Rjop4vcu2OJaD9/5FdjuT5JIHxjlToj9u54U6sL4wGh8jAaECmrIJsOJjfB ###bP/V8Q2+nMORD/SHLe9N2RIpeafuW7iq8pf4CmOga0h8WTIIOecjLAcEbth5/U0N ###LrHPMrzfww7gdZT6sEnknh4SfXhKJ0Be6fWIwFSh91xeSfAmp0aGyrV0YfABFqCR ###9HA8EyoeVAmFKDox+N9ZfT3NA2GJZePCAqzJ6rWBM7zqOZQ7M7kROYe9EjKVrLaJ ###FR69pkwjDaGbiYbH2prRX6yfaAzfhWu9jJwlRQXRUNYT3zRQ5tuhGqJetaoIe9KQ ###StlQaXwPA+lEu4q8xLCmpzKSPhT5DqDbAJJekNYBfSpWgzQN0ajV+LDAFs0mPhvr ###6AToYueg2cBKPGf/f/b+fLltJFkYR8/fegqc88X1UBZpE+AiqWX5C2prK0bWRtnu ###Pg4fBERCElsUySZIS+oZR/we5N6X+z3JzcxaUBtAUKLdPWfoWUQShaqsrKyszKxc ###SsqL9Sq2/yaKIWCx3rxdiRuXiG2UxNPuUGw2K6t0H6VXWTrDkxsU4297E+QU6BND ###Pbm6uHwEIQKFoTQTfvwwirhjE5P1JuNpbGWJ04majM4EikjvS+uSY3nmRJw8DmxC ###djUEve+JFK/1xmDM7yh7V4DqP0EnUkyhh1RqjjO5G6Fs9hBdsu3pdW564xFLYEuU ###QNOV32hOYs8o3QyGd6xVN1b3nEI4kjrMZZm9N61NR4aWt649py0R7i/au+4daLYq ###279/ce3JdBy+wjPGMVuV7d+/ZO/9fNRwvBdjDNi1xg7KNiGKwfk6zsNxDOxV3bNS ###iUp0vnf4UbIfk5JY788ESqI6DyhO2/MCJamzysx/vHy1afqzaSudxYejT59KxnZz ###tM+jP3dvfEouikupTJkF8nQ2Efz0xvP5R2MuIien4OHAPNDvLubhfIp1NOUsSL3+ ###1oplNM3HGv4DFiWvUzAdDLspvOSsp+TEVDmjlY4BFaPiDgBHe6vCbYJjTQve2LJa ###MH7b0x98c5T8xjGV7t5spwzfGprYqXqaco0YBLAxFgED/tJFSVMzT4vTXrXurmg9 ###MgZ9GXVukUvT2ek6eJVeTZN3zur9KI78o7iyvnoubuYUqOS+hsNS6cnFeJzvy52s ###vz/HNlosA1osE7KpsjUa9R+dIp5ChlJWgXHNM6D6anOTHXmwviZD16aRQryjbcWK ###InqlFLTjOG+qrzbKmNwP2I79yBePiKcCzynbo8PgJU0KQ/axBmQJrwXaglPzy3tC ###BwYBWwywLMKGUuQUel1Iq87XXfxCCnQzeEW+ADOnfPe/n6PMRtd3k/m+q9z3XNnv ###u8p/z5UB/9ex4vT/mRyVJLDlS15qEHimcfHZNaieDcGyiFXhrBDLIlYsLmm+6K5F ###F7Hinmosfo6INaVGWOE2/tRGx7MXtNyVt+ynLdtqdFtGu9CgzRLelb2zwfi6zBJd ###l/USRsJfyrYbeV77+DyMur+F3R1K5/wuGt/tDIfJhL2JX2l8lu8Zf7ro9flD0Jhq ###gaNLggPTDsIHzB9eRsO+yJ2HgyhfodlX+o1/pzLiVJbrbN3RdTfuTzjv2/m0/zDy ###lc+BYuC6mwogGcPsdjkmJmNaOvYNcLXhGATdVylo9zOLB2z9ErbftU73laxua6kt ###WXt1HF/1yQKZptU0X3W91jr3GQf3Mkd0vxbM+Rrth4fwHgTT4X3cpTfTVz4dHofQ ###iXjJ2kovH8LRBITKdJvj99RISDF8FKqJKSLR/svuO7QaBJf9IWiofLdSh0CZmBRM ###0Pvu3eCV2Feyb4vx8yF/bh0es1vQkyNP/uxsrVE6jKmOh8/o93QybOPjjU5v8oiX ###P3T3DzJzdB0Lx2D5lNmr+4BTmO7kfuh9bO2R2iNlaMm8K2/Jiyvk7+J2Rc+4dG+v ###Ks5iukuiCrHeCQ3FEnaDbCQlgDWv0Csk5Qaq9yZP7SPm14+/xnDqXMaT+zgegDZU ###Dc+qdK779BEeTSfsAqnumDBL8mPMWJslY4e9a5TNGpq7XHh+8uF4r2SsXkVO0RQa ###gypKjesoNNZJTUP1K53YeUx+HDztEHTqdadUZJaK9LIiIVFn0vuK0+YzQduOikde ###w3vb9CxFduJQYUmM3SAFVu2FDRaKwSQrUnrSVFrNnxMbUKeMialSn0nmuoitcXu3 ###/uxSjSs7P4f47t7+Lm4UQrD39i2QbV0ouAyOgrHTuBRnvm9YuLT5uvUgXNO13M1U ###nkF5aC5MQQg4CN9WnEsNfBLzKLxi5/8Fem3Bsl/8Cgzz48nh7v6eaVDl9MXSleHF ###7Sge9wCIDhchNJ16jqWy0PGudf6eluTwmC8JYZ8DTzmyx2PcTdJCbPrmovkXAJwO ###QIbuyKK8/HJveF9JmRvVawRY0BdKZXsJMjz0G4oGHuOgXhJPJryq3oII0q0bNpEa ###Nkkptm01QAO+ig2dxZumm2xCq+Rzbd30/jpHS+Hobp+2ztv75AqE7jLwFz1Jsk4t ###x/vxROTfJo96TNufxaTmptxD0NCifv8RlxDPcNB/ubPXEA698bQfoxbnaVn3Sq9e ###rapL7QKAAD4hWBkUQgw1DolkFI0TkAKhb2J+1Wyybcum6DeSTMdxOXX0Zr7fX2Pv ###qo/V6yPpVajkVA68u16/D/oiuulpW1KI06YDvTozVr2cHyziRYf8qk/VFno9Axeq ###UIXyifhuGCdumXHi1ntj8OwPO+HBees9yHL7xz9fvAvft/UdIHLXwsq/Ro+HW4dN ###gx3E07sw+R30ZPQpL3kvSKB/weOlNDBT/cM0ZWC61zXjlE91FaaRcEacngilCj1Y ###Rb8l7YZd1R/E0vR7gwAelGgoxxXQLdoenfc+rrUSsEaXSckYr+Jau9WsO6GMtd7W ###O9Xf1pceQBGYctrVczbNTKFKnK4uFFRy2WJDylVu4zia6EneWjdNzQrbEnVYiXN1 ###4xG6nGGc3cBLrD2tbkvJ3VzTfmtBlDLa8OLd+X4bPUPDs+OL8OTgoL1/wcQxkzLm ###Zl4Wayrei591YXI46IzJo1uRUFGMYDNetBDB8KSLESgxlLORXXEsf4MjtOB5aJxq ###u9w+lXNLVLiv90Ogm51P+wxnHFnksXfTu76xCpMJy5tiFTDFbgUR+HZqBzHRcHB4 ###vBeeHl7svgs/vTu82A+PTw4BtwfodHp4cix2CMNRaryA8VLrhctgbY6z0zre+3S4 ###B/x9/5fT1nFb9l1esSWnT7n3Cbo1RMPCKmsjHDa41cUzsZPZubitE4dTbaZYXs5U ###6Y5OPoXnLcCoY+qgkRyh+3AmchkUH3bwikw1GaVzUt/SVqG1tyffCjLeAppjvQKV ###9fsoLYnARlZIjL0MyOXusL1JKqBw6rPBZcvvNw2lTwWfMKazexXOQAmUMyVDxTRo ###nZDIrfsY1QBy4B3uJd6YOahyCw7N9A6DIDSuzm4ApiNsK11zy7ySR2/ytwTtBxOK ###aEhuAUEKD1NBMjhYBuQzyMl1SFV9phZkKkQ6FNW5uFkWa3NdjsjiD6hpycTWTxzF ###FAldAp8t6smreWYJ/AlwPohRnxuJOBVYoMtHkKGjiTdCY576a2eoNFeWUZqwSHAs ###swboKA6fsSf6qEiz4ifDGMfka++lV1NuvGVXppSj2VTQZvipN+CR7JV0CNUMlN6H ###IQpCnAu3iJYU22jZ49ZOX52IdguPs0Rw5FPjhv4uvuuMHtVOsTAXww2zfMqvKS5e ###wrt/xMOrUmp4XbVHBRnRgdHZs8oEIDBnqdLKh1EXr7lGLEfbT94gfsiz6qaW3TV9 ###ZdUCH8oI83AosbNEhl7ht4BGe8/ISGEpNtxF2EheQbeEqdU/VXVUYrB5j5Pm7Gfw ###EmDqhHwiVmcIj9rEeAbRYjOTKTdmzeOpoK/p6q7h5tPtAp/vCU6H6SO9CO/KOlze ###F8q3Anp6y1L9Ypy46qOydBkMZSC1ZhIVfEC5tSH3gPosOw+793DLakFV2o4txxm5 ###QGgKwwufmM1Su/Nmvu1J52Y61swLVASFKWb4DMO9tTujsrp+BUlJu9vHEd5usyt+ ###l79PFsBAY4p0nOUFREPdBiQClcT9U9mcwgy4ZW9nDB1M6d/StgE5Qv7kVfzg1atX ###taoJgpjtGZ8utMvECLV5s+15NQsp71EkI12TwoaoZQ/PZS/+Gg9E6gpDD6VWL4g0 ###9N1LDyqacifW/O3bLJ2PLlGl0HN2fhG2Tk/PT36xzBpnaT+mJV0gqwm48huq8UQR ###kpRqf7dmgoiw3aI0BQQMCdMVNt7q87h0i9mMSddCjUxIkwYH065ssUiQGp4kiSyX ###A2dsDYsYshEiNo2lzOehT7jlZDY07qNddqrsQd5k2K9mgkXXhXiVm+24rG6DHYfm ###TQr04wB4XMLC0FFyFxKsuR0NV0S5ZDmrpF7a27zKJTa7gpVMQITExS/Uy4VASUUu ###9XrdYvxZWJIy0AwkCRJU9L032zka9Ax/TznF2Uj2XUg+R2GCF09UjSIJuq2K87o7 ###vFPsJER7qV+H5CGnu4AzKg+K5k62cRG2YpSgThR5jvhXpHe/UO/KtM2tczqOxc4B ###zF8B36u+Wr+icrr8O5+w95oxZNS0XtWuQB7iDbXnWzMwRdzWkmM0XxlbcV1nRjl5 ###l53FBmAurCgum4/qUuDotSZvUy2TkwYPGf/9elH/4SwhIg0Z1MNMdCdjO5AvJSG5 ###2tpBYE6s9moTPcaZ22hxupDzIS809E6FiZ35NYI7maAphEJkyQ3mdaa3aM6Abh9S ###ZQ1pfn4Nl+9lhtNRT8+iBJoho6PWhTQW6V4T0rGInJZ93w6W0QAIvgMAQQ4A3/JN ###LKmXD0WU38fRrcJYc9pLKzqzruS4eODyop8Pu8lmBCrrXfIOTfGE3T4Nr4M+yicV ###zVxl3Ub7zfTeJN8YX31Fhj1+j6JGtDHvNc8aWreUeXlDG4/eHx6HZ+g7Fe7tZN/q ###WOBo55iOlrep9PQ0k9R3lbWeKAPOhAkU1vD0pC3k51mgiZXUb0pM+soWCdZcW4yF ###nhy1bGv84fHph4vw4vDoAhiidkMwp/H03eHP75gJXu3SD/ihtOCVN84x7ag0vDtz ###X119ugXXeUGFTjFKzgku5iEH4SVhQP57kiVXG+0Ir0CRVdlDobSJQ3GfnCTv/opi ###kVw3KQfn+2fE2SmVS3qNkB9/Esy6oDn70MJEJqE5BLmMQQc18zzOc2B03DIyMBoa ###N3JMW7v7Jhzol1z5HngIo3SmW5QvmLqWWO3ccWnichQr6/fjzDEe84cq4sfrl1cw ###8XoVthuO8Efps1/2KtVXmxvAKoK4UoeD/AqYj/h5HX5eT38O/scHbf8gWd3yoode ###UvqMKK5W4f8rPn78suoy7jPzPMrk9n2VfYgE4q7KYeFfzfZsKcY5uK8k+ZMqYK3N ###AqsmXLw0DkIoPtJ4h7KapxRYez/UxdregJLCMJXRMGsoXR8dhMnNKGVNpntRng8a ###m2DFMH2ajuxsNraFIQeIfwpJbspEuZIcKhscZ7Cbdro6HRXfnXIT6+7J/gGTzmGR ###nZ4EAXfRRLFvGo1hr8RxwuxzzF/Li8bXlCwNRXSOj1Wvl+gx1KDYRgPFeV1ZGxHB ###gKZHG1wdUnaXPa+XKrsAL9B12bLt5PaehcvZfC3z0vNSdcdOd0zgB6hGOTctLo3/ ###qoYu4NusIfahsaU5d0sGkVaftlOyV8tweMhDdfVVU7hJXAq/YXN/5YD9zL0l2aE/ ###LzvM2e/bOQC7trW6TwrQcnFpS8o6SM8nx4e7HhcWZkZy5DsQYdwST9t+E415yizl ###5OWvaDFOTjf7/N29nrq3aO6h2fJ0zZK9DRftcrbTi8BRuHNy0r5IbYOay5OcLuHA ###FBRNt7EMBDD5T48AW8n3km7mosLhmx9kzZUpFkKKzJ00CmYf2gwzQsz0Xrx4nrCm ###o9GwPAM6yX/ssjcZU1VYA78KK7Mi5mZFOcupSpncfTAUcrXKJtqNuYm27oIi3yE+ ###T3M8OQ9VPcE9bdMqR8pQzqr08XleiEXOcjjCahzhjr4z04N2UedyFFd2t6m2WEew ###C8bq3LEFd8Mhpun9ijcQeDxQIteCsQWm9I3Gv+MddJs7OHfp6zxKtfI2ZRbJnVDE ###soM4cl8sezZrwn+VIq9Zd/sIOYx78U6V47SjW+szRf8T5mG/7Aictefheu0586Dj ###ek7wtXeU2C159Mt/lSKvFQbfJUKpSy/UJLoGyoiNFPavAuQRZEht5io5705mD+la ###yawhOWaVCc49yyzsB6kMtsz4v5D8/+Sjs4jijzPz//vVar1m1n+sNqvL/P/L/P/L

Okay bestie, we're deep in the base64 zone now, so this part is just the raw encoded source for the reference implementation ๐Ÿ’พโœจ Every character matters, no cap ๐Ÿ’–

   ###/P/L/P/L/P/L/P/L/P/L/P9/dv3HgyiZiJB/4cG8ytJ/3E3xggoV8qjTmaKd5FV2
   ###HiToCnhI4nGdZBV9iH+f9shPAyTqr4194ptodQE+nZtSSfHZSx2rS8Wqzp9TTtUk
   ###TULF/d7mSDiVnWoKy1t2mAXAMXSWI/Znyjj3xUO74Fy5rvT6mi8dycxETiutQhob
   ###b80vlMGq0NAs/6N7aMU9zNWsaPosM336LZxgZVkgUAdr9zPTS9GoQX5M6NHEMjh9
   ###Bp3pi/Odyd3IL9OfAEizE8IHXEmuuWoXXjSP7e3mP//JP23IT341/RikH+vpx6Zq
   ###yv0ZTul5Ki9S2k9236Dl7hk96kuMO4mn76BMPuTbVquqqSOg3zcUNagZReFXEoDg
   ###xPcphpEFH+EdDqYYxvgHEsJMjzjFlDQU0SPu64pd0oNFfUDxTUnOKS70O9yPxs+s
   ###Osin8daeBtXGExD34ysNYHilsu0FW99tBkfGDPp/FCicSEVIvEHMxCyG9u+DZQZW
   ###hk+ec5x0DBVcJF43T1MBT7cSBX7ol44EGN+YFMNjh/4IctilFjx1FbtBccXq9Hsj
   ###r5SArNnvDv428W6i0ShmXtsgpoKY2X9MJXXKb4JuNauZAKvOjsoDM98BuYvqfZBn
   ###y63lPWlxFj3gzlUZVS7LgC3LQC5/xbuFr67lR27GFn4A+FVxvGU1DERDht0tk5DM
   ###Hsz7Dc46NdLnfJTyROl4szrndGk4gaudB47O/dzODTdTUTfFPPQ5gvlThcK2lva0
   ###f0/731Vv0GVBByzT7nMsgTPsf816rWHU/2xWm+tL+9/S/re0/y3tf0v739L+t7T/
   ###Le1/f1r9TyXTvkMq+j5J9mMtyf7z/n2nJPuxkWR/ASDOymBPaQLRVf3zl3KRDPbn
   ###C0qwPweIDzNAM0Fss6g8nmV/IQvtLLColdoYdHmW60IgXmA9SpTa1MMdgOV5+uAs
   ###RDHq2YZMRwFU9u/T0cXpZ80xy3vpwW88NFP9/CWji97gqxKVpnWFZqlhJ+qztK72
   ###w08g6DAbhv5ky20CPz5qH6TNrWz0GYnlMzrDh+OY5WJiweD43cKFPtIafVfToWai
   ###hdXOhF6vpdMffDtkyMIY6C33SiHC0UCThGOyz9m4EfaG+xgFReGzyL6BYISiO8hA
   ###v09BJJLmHRUQK50DptxuuusVuj3EzZBjV+93GEqqz98dx6iVG3w6DICQvR4KsizE
   ###upmZKCEbird6mCZF/FL0NgvGA22n3/sjFukM8Md4kKZ5EfUO1f3gjB9Bd7XLHia2
   ###12yY+j5SivSoMfQFEcqTrQSmDXGfwSv2XVq2mhdn9AsBRIUWradlr9asWUZLIkPS
   ###HCjbAhKoFgVtLY9jVN1CajfQXBeVgpDCGdcBqqOTtIuULfXsGwPa1745T04o2jw1
   ###qnFMW2ON5nqXMFWE9+YNDxbJhHdBGeYNz10+K95U+9HR0t5eot7GZIS5U0RhG71S
   ###Ab+zk5kT3m67oubQFLymnEKvbaKGh6nkYYJFUiW+TtnY1EgVdKWm1FL1Mh2DZV4b
   ###Rz4G+OAoZ+zaSCIvhSVHpF96rJUzs9SVM5P7CgZXzkFk2TokTJSc8XTuhBvKkzSK
   ###0HUby7xbKKLIUcIRy76eiSUXgUGDw0E3fiinlYXUx6f75+yxNmGGbrX93ZQAODOC
   ###w+A3msrR8B6z9/Tjhx6aGlwIsxNvkOSMCMBEYK7UOTgiJQkLOzBZhUKUVS2rIp05
   ###xjhGDQKHkEZ/1xiybhhL5cMGSmWOslWnxtga5awVyQrREoSoco0cYixAgOZmFZhw
   ###3DC+zGAmH45z2YnRmuOWy+5kmgIYMHIZa0qISASe8p3Sh/JsPjafZTkj2bXPDExv
   ###qS8x6RBeSpdqq1CKlmwhJc2Fz8huOHoMv8adyXCMJ5sikfIkofbJ5Q6dcayqUaXH
   ###sYCaaiWnm5NbM79Lq0OO9NxknY7MYSLjVhJPsllRNaMGga68mPm37DCHTH7vCJZh
   ###lnWMmp8MJ0CUwunkq0yrrmb/Nk9kqlkVskJvlMQZE/PHE1OOVhQEd86OKzgCUSM4
   ###Pd/fO6S8kuHpyaf985DyrrQOLuDj+T6lo69VM4ODrJH0FDDa7ShmFHvjrZfz0FV2
   ###gQqQ1pRcL0qJHk06d8NiSL1Ki4wCQ66s5JmIKqOonxkm7Q6pq74KGqIEjCOdVkMr
   ###D5NXKEgkvjKoS3IZMvsQF0N5ElBdYQeHcCUgfY+V1ynLe4DpwNFIVuFR7VRMJILR
   ###6BxSj+2yVLHL2vlkrJDiFZQKGu2DRBtFVHTBHhNzGAVFjI5oXwfq+Aan+Uod/a45
   ###Rhh5bfVrd5YqVdS16VJeYVeSPwJWvCwqaZjC4nmcHFP5QfOnMx1RmfNSZP3yyizW
   ###/ZwDWXhq6YlXk8l42uEkwa7lKNcycSP6lTIwj4Z6KmAt92H2eqirJjhu3uqxMrH/
   ###xvf/WrGjZ8YBzbj/b1QbdSP+p9GsBsv7/+X9//L+f3n/v7z/X97/L+//l/f/f9r9
   ###f/rrZDpAVSm1U4rYoFMmLfEMPNK6kzoOWOLU93Eb2P/ruw3sL95t4F/kwnsRhe8d
   ###F7nccgrK7/voof37+CMocbL+O8++ym5aQRMXSiL7e0rlgZhtnVUmhDerSlQOih5j
   ###zOVIh/P9TTwgS7JqSoLDjRIELagYK5YfrVRfNa7INMarOMI2YqYNlp48y8bjVTw/
   ###QOsTWXJUK7fI5TW72Haeuc2RwSzQS24vIqtjgWzASn0wd8rdnEeJmSD4m9OCyIsd
   ###c8MEN3GraaZTasPsalhqCVFfxvTqNbZMAU8jz+sjr1LxVc20Kjo0aTejGpww/a0U
   ###yhgY+Biq0YQxESRWt7virovsspXVamplz0xzs7BpPLkYWRskwzT79phKE5h2IsrE
   ###zrawfXXAtjK/O7CMP0aIU7rvzdzSgjNYa6GQilGzg5uXeAJpR8UOezR9s6lcKKvf
   ###WYWjECZlnLeubLjSi6TsVTLHcdYbsWeQVWDEBZu7BxG9o86+UmD6Zh0TtYaMvvT6
   ###nt/SWoqzQM3jzXN4qwBx2qA8wulBovM4RL3W5RuJIr9JTjuOwjjjuJMWMBPlSWNU
   ###okAhShxFvlxAiwqfmfhkHgkq4DmVcbQR3tq1cDiC7fRn2ourWxkyxdlGKqq4uiQv
   ###JAaq7fO0MXdhHr2uEet3g0HH7zVUYJx0+9wJV58x4dw8vsVnTN24Z2ycd+3oK95M
   ###pIcd47CiQqVHvgHZ5mYFsA+D37N9njIvA7MK8BhT70fJBDsjcEAw+UpbXmbGOlIf
   ###O+4+tGODZsFUEZq2W2Qj0A/Zl4w5SaS+yAJF800AyW/3ZI+Usb1DVGtBv/81q1J7
   ###OgmlijbFh1MJ7fR+SSQ/fOUdRePrtEWWuIpZydHmgznrhfRa6lG28soIeMLqYmRZ
   ###47C0pMm17GKeLL/khOVL4yWm37qzW67/lcp56xvrTC7Z5XA66KJhkYXi3ymR0aby
   ###Ifb0mZIqPmQjIslVP89aEWQhGLxaBPwv1i47iu4uuxEHxErW2nq/s9eSldSx+MNK
   ###tua3ppeBzuhsb/+o9ev+HtYKOMSqzm3Wr7Ep2qgvJntxP3qMu3vioCw4+qfs0dun
   ###+/u770IyDvF/yv1wdlJt/Pf80bXEtwwAqraQn2rVW9DowImwSIM6vDW64258QaPD
   ###sMcXkpTY3ElmsTaE/W/VlYvDTcSKNFOgtZ2XPmDk+G9zHbqM/+b3v7bf4dMvgPPv
   ###f6uNZr1p3//Wlve/y/vf5f3v8v53ef+7vP9d3v8u73//vPhvxYeTsvddsYgNumNV
   ###4jbS215H0MYySvzf7bpXgjlG60fYHyaJUsXFYRUDVrV/un+MPOroV/Oa6GTQf2SB
   ###JPC6R4763DWWAqc6t7GebE6O6emhDafU9AgehHDWdIxwicEBhaycxmPWbmslzxok
   ###yZyZSJX8bhssjz9xyVJOUSrVQJKCnOvFn1Gwtextspu6qlKAwJVbcC++iqbM8ifi
   ###Sh2xV4WmW1UjgnWQ+fZXCozBj238LQkn0WWf1+osMMx3TsGWm/+/WV9IBYAZ+t+6
   ###HwRm/v+g1lzqf0v9b6n/LfW/pf631P+W+t9S//uz8/+3gYVp+f9l9n/MeTwr8b+W
   ###//8Dy///4egI+4i+Rr0+yoToAIYVAOpFVQ1n/v9mvVQk//94cfn/9Rz4SuLnpp4M
   ###Ky09MCv/f/M5Sfg7jhRcQtfbfX7+/7xZ5+X/P114/n9M/W85BM+d85+SSFPMMssx
   ###zT6KdNI1//sm/t+9iTu3PLzzK6hhXb2uKKnKLMPKm23Dw1ALwmf0Ruofw26+Y42S
   ###7VoPoZ8jvXzR1PLFEsoXyif/E8g9LH/UPatjQCmRuLMSvZWQbjuAh74rl3vNd8Wu
   ###V6z081qS+ZqVSoh8plDUAlHGqALLN77qn6U7faagsPT13z39O4/YL5YCXm0sUqCb
   ###LozvAce9Uf+RV5dgMi65MSYTu8J3dvL4FLo1zd/STiDP9qSW573mF0sin85qxiD+
   ###zEE0Bx+2e7RyBEsvgf9l+d95TqrnGoDy7T8136/5Rv73en15/7+0/yztP0v7z9L+
   ###s7T/LO0/S/vPXzv++10cdb3xEHY7nkCm8vJ/AIregLJkARzn5+3w3X5rD/Shk/e5
   ###Wn+gp56n/JclU31naTYxGT2pXUou7LKZVFptWtearqAWZqS5FwlJZ5Z6xH+XrMvM
   ###JN3CIiNMQCwsA0Dxnv+vgF1m3jTiZQnoJ0pZTcuKMP+uhCUs3nPhpZ2yLteGZwa3
   ###/IgU/GF/1CmQ415YvaR5kYcQU1pBSnTGf1jj3iuIYebW4Fe9u6QwiHazfnRtp3HP
   ###ARGxCO8sghSLmCf17M35cAoQWeL0hUBYFIt6srfZCy3ynXo8MPoHgJhmnStGi2mB
   ###UZmc9XuDiAmRWSxHeV4QI8wlTFI5Eih0NBw/PocvZrtLjcc8RbNV/sB5cUAMkbX3
   ###otGo32MCsXbqPcuu3SujabtPQ2SVTRiz5LMvYeM6Cyi8pBOJPTKPh3F8PbXM4C/x
   ###fLC7gieX9skKEn5/EoWX1kEKTxwnIfw8GDuY0nV4FjSt8e4dRShwiLvoAbWQhzC6
   ###TMIuyzGLX+/Dy94ksac5ie9GtQBhHQzvaoGVToQU65AtpPUQaII9oTHO7c/hPb5e
   ###9o7+O7FmgOkmMf34ABMK4BcEX/7Q7X1FjFpvnY8NVI7H+UU3EFddgAnTV/Lpy1X3
   ###ttln9oZYWzSI4mf261hJuvyCHWzKhhWjmXb77GwOnBahKeu54pXYYXQ7I0E8u7yb
   ###3oXJ7xztJQBozDN2vFDWgpO9kYKC4upZc7L9l7yKfMejcFbVxN5KqMDCDcisJLIq
   ###tmpYTKPIMnR7+8UM+sdmb5zirGmAF1C5bwLEDF09VWgUw8SdzmptG5Bb6L00UYLO
   ###6RhYssctfTWw7fsI1P8HlmiVr23ZOBflmjonUZaEB6toj84D1KnNVY9lo+bL52hs
   ###LiO6rSo812M5ur2ofx89Jt5NRIHOZEV58IBj8OoZdH09HgtDy/k51ra+kepLD1g6
   ###kUfXyhKPY32kMQyMjGcg5nxc9jInfz6WU/dmTF6lQLvJW08l+QJUqNCf3VtF7c21
   ###v2bA+M1deEJ08nbbq2ocAI8kPZqa/6Jl/MHfyinYVmgp4By06FNQ0l/L7DVFerxj
   ###hA6LUFIotkr/TbnW6ncfUY5V8bO+PAEKnj35etqPxr0/4lAVVBgpK7uU+F2ZQ6mM
   ###anHrYf9rHB7tHZk9GIR/yXPoWBsdbaMK8V8OgZMTbemkdfvF2vgsQRPlBKJy2/iW
   ###X3dUFWEGAwZCWTkazRIRmfmplS4HPJWQWE4jG7XfBLR+jThrkEOpDBCxoXF8jiXK
   ###M45wwBCIjjlYIEo4eKKDQMpavIZDQUL6Unmw5lVfVX1KKmYcncocVYFIyVWCooaD
   ###47iPLYXuuNzlzlKi+cELkNVqYzRhvI5d0+FahR8wuYITQ1Zb4x7aTo0kXfE17t1s
   ###UF15F1/UB9gSuR7mBsfADtVr4r/x2kVODlqSMQbN+qqOLV6ISMlCxLPKuBPVMMCx
   ###C3FmvgEiaRD5VVVImRxtVD7Srs9LqUSqwyQSEYnJGpAwxPkNlqhszTN2voXtbKhk
   ###5Scu89d8szvX8lW8oGljB6EKmm6uQzsumXZu0luuyxgTqogYikH8NcbrjGgEkgSF
   ###dKhACz1GTz9i1ilxGuXchUqUDlMyEjyH19GSbZxCIVMzDak3fQVzCsL/asShbuN4
   ###5NWwMFriXY1jZrT6+ns4iLGO3QT+gm58OSSunlk8LMCqZ/4GrA8fWggDqnxjNXpD
   ###XjjG7HUaQFaFwAsayCRROE+t/ld17Kw4KsEwARP2FFBHyF4L/Q317BMju62qyiGY
   ###SroAQ8WbxervxdEzQ2x4HWR94YPfFxjVuWj3uB1tqU0tIOMuGpOeutAkJWZ9R1Av
   ###6nON8FWvm1T/TrdQcQVVe1vsl8zjTWltFQLBSldTXlcqo7CMFbj1n9ve8YejIw0i
   ###wzig8wXFjMC19GrGqeA6iWG1Ar7szMmQONZg6A2BQ10hz7rv9fugKI1GMc9tiq4D
   ###ehxYcdy6ARYp9nBfalYR92nMW2oncyo0OYQDLiGU1MVyU/YqxwWe1OrKmiKCvSLm
   ###HDRjTrE55Ao4i53Dt5UZM6EjwpqHz7uO6BYMvSwpxdLlo/dHPB5q3Ijbr1yOlPmG
   ###Lz213UtHOafUWdVb1YIjaxzTcMYG/eF1SQKxSlYmXv6IcXH3FnEM5xqP1a+kz+Qm
   ###WHzg9AhJ2URyNxxiZdFrJXUsJXGc3pW8HY51/ijDdFd8B3LLKzspiogXbpFC6WZt
   ###O4WKhAmXAJHH4VNM3NHq3gNj7/6NEuGWGBLuSaD340qNo0K8cNAD0UnUa40uQd9E
   ###fsuMOMMrBqV0sCGJhDxTgGDvdRFWsxinmEktxxprnesw0fqV5wnufsNMzSjxMimp
   ###2F01CtnyU76XzHFIC0TRPAZx3KXSUvLtLCahTN4BOHsCQnQAXahi4b2AwC1b5x2Y
   ###JrZKDdJXGrDo90O89exESVz2eq/iV5oYUFEzqh4ea2H6Ymvrfb9BQuO9KwwBvRTg
   ###zLuLBo8MWz2JMCrN/BLoMgtz3AFNBRSLBMPpSUP+LQElADd5jInS8C5Ih4jDbKjX
   ###yhqs2ajWeyAxvK5khJxeklMgHNtwpt/H3vVwksbRbPEJDoR7OjBnb9SfJuqsXEBV
   ###EHUEik+Vidf0JcWR/44qAF5dU3lkUgKiBCAAXMDfgOsGaIftdKZ3U71YldPAICQw
   ###9WFZETTNKxeGOgHVmnGNs5KtGwbNoJz9KuNDNEfkRlcqMZQy31pN99V99ylchIRy
   ###NFbDOrKq4ByHQGDyhiIZanJbcjOc9rtCcsvUibkgIpQS1z8NP/eW3MsRniGMbGUa
   ###FexNxHvSmBAgzBYS8UJLU9y0JN3PgLessV5KkpBKUzOgZYcd3bO5pB6EWWDZT2+2
   ###nn2gI22gKs1gJmfKvGMBa6qXmAnIuC0IzDdu3fnK3ftG4Dlwjzsjjarep24EvM+5
   ###fwgyFHK6MxbdoYhmG/iYicpKUekym7ffn5xcvCPXRjQFZVSbFJgo0gPLF7km5r1a
   ###znV6wKyTLhuly1j6YUd8V40Zd6x4oQZnSumczkV5Br24p803niE1qg4Beh16KmCg
   ###y5GoC9Q2BAtBlgtfhXz2yg/PLKxwEEHENEfaKpIuyLgg+JZv3CQaK8sl3Jrdd+Wt
   ###h8zB1JyL40/Hj9wu6GYbmktutF1zJJXR6UcwpzqzxRorBb9V/Ga1ipljNuCP206Y
   ###L+Z/+4GumqbDTE8tQVEM40b3DOOldHxbGdRv7o2Z9ORGS/GxDK36167/ieXZ06rw
   ###cELFTw4Fy43/8qvrQdU38v8015v+Mv5rGf+1jP9axn8t47+W8V/L+K9l/NcPiP96
   ###zmG48tI7RZnJYzITsKKr6YASeDxjRhQ9lpWUKH3AhDX0QGCRZon+uBtfTmmeMhKt
   ###vXveuth9F7YP/3ufIs2C502epTVi/Dbq9x8ZlxQISAqEATxz9FT5Og1bgyjEGmPk
   ###6Bcmk1opIz6sM8Y0qKLVZ+90P9Tdzekn+Lq78/d22L4A8qyRQ5F8wH87av3cBhUI
   ###UFA6WfVqwHzea6650XgcPWZHWFEoSl5MFUWHcP9eJdIinh3qkUyi8STsR9flvK7h
   ###uSiaBN0ncTRGOta8dxxdX82IDmJdM0c7vC7wGhjXJeOEcqCeGdhDXeeF82R23Rli
   ###WM1Db/KY1/Vu2gqQMtFSCWPMihYtqVAcc4bMozlq0YuT70BxoljkgokN5iW6ZiGG
   ###/wrENgQmp5PbvzSxmYneGMlRmC53vCtlLPdLgrWcEaxGDwVmM9qIuBRoRbC8fvns
   ###g4L+wSkGAsHpCYg5IMyBGHh6CEcSiBato1/bIEQcfDjeRdFnoSeFkjSPF+a27Ryl
   ###7IDbj8Nehy46k0kPtZOfvCovQoe+DNMBL0j31ABbvljOyMA2C5cFAuRUDvzg4Lz1
   ###fj882j/++eJd+L798iAJb9/98aRIwJcMEaCalK1Z1z16SDuXJxx7ahCiK34cY/h4
   ###rUA7whmGZHmwnx0XvuFqgioeqNzq8GJoJs3xBnMCUQThRxenmI2QVfjTk+Yfo9Wi
   ###T8UoFTFii6XG+4k7gZByORrHX3vDaeKJM7XI0PjSkcGlZTA0XsEyFm10vuVxlk0O
   ###UaDTWuReIPiZsftwcjOOE5/FJcihDyj6Gw6Ra7Q2QIObYZ85JyA8nQhkdMwNl8Ce
   ###wwv6ecNx1aEDjvV0aNxb8w5aeGi2LzP2NcX5oifB79N40Hn0StB0dWFByOkRVHYk
   ###wzQPnrJXrQRldIYcx14gqmNiWrsnDC1LeebGOWundFJw1uYdCLAVdpRtAPKkWKWx
   ###x/ZFaGW/lK/V817zHXGnV1ibkxIXfPaajudJZxwhP72L7z6DePbS1bcDmpes3CED
   ###yopFlqHRcNr8Zr276xQnS+JHkBhZbUy8nG2Ise3A6gnWUJ3w6OrLCA9FV1B0qjuR
   ###BY2xK/jMJMUyiw8XX0PqR35jQ1hzA1kGNijNYi9sn4N6KvBU9nYp+JmdfCFrqHxF
   ###IrfwwX6eiQF10aZ35ZQJpD4NGOnYAfkUtFsL6N2dHoHG/oaD+F5+pj5IGlYE4xhr
   ###XOAH7BRa2+lYd20dIAj3f7kgNDA80J/wUnyAbrQvVp+60vFcrcNNCwtToy0Ua0Kq
   ###9o22u/FTnX5CTDDBVfPIV3pVNAr5kfeXfsfOrDcxzoKWkH/gb4lv7ncAHvYO+yDe
   ###4d/sdxCtTPQIL3tREp4FVYycv7oCyvlDT46gDAMst3N5G7KjruzRZ9iXVtfsDhxH
   ###7g+vAxLvMdmM/AG/cClB/4HeYQDhAUqLTjsGv7tYygYIOvDK7k7KRbSsvyznLyW7
   ###QME6PQZdjo5cvt3e9ja8f/5T+eoHxveMHMNstI6tcLlGU5q95cWAkbQPj8Pdk/en
   ###R/u/OCurKm+9Ud5q/aK+Zb9mCUYs2uTFC8cT9PD037zxm6tOCCxBx9kVeyK6aqya
   ###BbenI0/N50K+k95rpHKSjK7YrUnOyqm7UiSjJV6MzgPv99+neguwY6UeOrQgvqE8
   ###X4Wf2eJuWV3T3nle13VHrxvP7nWDL81VaGTE2Xa9oU9Q50A5L9XN9hv57TlQnFcp
   ###QhW1R9oGJmzDo/K2rPZ1velGTtON1AXdBQU7q1UoUPbW3rEgUd+p6003cppusJ5X
   ###rHziuxT8bqYQZ86F6uKXsuQLbUOdx4kQ8zHJAmU4Z7900fGVTxJ0qw0PPyhRVDpP
   ###y8p+noqjvADW7OznIoqboBiH3eH9INA7SiVq/lk/aY0iWwawQWFgm08ENqw9B9x/
   ###uKNk1BPGHB/g74weS7MGYvQm56Q4VdlRAVjKHe1IXkTRc0AAdZUAnrjGnIOzvGpC
   ###YVe7LLDsdUWyckhZNEeFwI+G95URIJF6wuz7r3WXNJtj476DR2/JW61S0chFVcoU
   ###b8DW3p7wSTNalI0fKiIduYbuxf6jTl8CqqkoH1s3ntMOsYqIR4kpBsFMS411F0eY
   ###YCVhvEA4tcMRKjpEs66Mp47YwSu+4rEbR50bDxeg9H9XpebMX17ovzQY6XAAGoTH
   ###/RvQLNAROSO4SwZKpvEY58rFhTI67bN6hUJUSMNH1NAkTUo3o3EsyVzzjL/SZX6F
   ###Z2gx3Q5juYPI89UH0TFyOR61bfiPm96XVq9uv9cMUheezBad82jtjKT8r78HiXsH
   ###h+ftC4+UtDLwmngckcwMDAuo/uaP70B6jDxSUwQm6FJRMZMOZuTuonPaGXCghArf
   ###x57w2IGpjqPBNXkVkSOUesdmHSIK3G+3lSXMTGqhvLBmynJvtB7WHJxUDfmUBhuY
   ###s9JrxdBOFz3jdNhiE07bP3O+Wvoalj6UX11KZ6zL+Aqz5PSHw5EKf2rAEnuuh0wu
   ###xPdC4BLXg7irrkw5Bdq0GKjTTG1hed0qXT21W34YIpdU7W9a1LDJPuvk3a4h0On/
   ###rxr3WIdn5xdh6/T0/OQXdTgWM6bCKargaApDnnO5FWOAAQVVM/nIAR6Vg+E9VshS
   ###hseDiCUi6HrjuDMdJ72vcf/RCkPAyDQNIop06yKtaRYYr+uKTBDrU6nYpWCeuHme
   ###soG+3yb6DtvBxFOr203dKXkR7UF8z5UgchQdx3fMu1RpxUSkfhdvIHhTA4sKNaxt
   ###u6OXxG6QAPMaR/p3jDEt/L4xYb0z86GFjwXvOXXfdefbbK5onqo7UCitzcSIwBsN
   ###ewNF1DcObEyIouHBkUHkEl3RsJJVev0DXcJXkC76enJDLjSziksjrL2U3AzHkwqa
   ###D9AcqarM8pDf3rZs0U6JTecBPdyC2nFp6SfcLULFdC1YFZWQWEyS8cTnT7Zmoty2

okay so this part is literally just the giant base64 blob for the Opus source code ๐Ÿซถ no notes, just vibes and characters, so here it is exactly as the spec has it ๐Ÿ’…

   ###52kpNvCOAk0M2yKvnhWkozRatRgIQe1svDXH1ToCXfFnQ+3KPlTpsWg81wTy2ufN
   ###RSQXpLmw/1O7k11sPXUyOJQBL/y06tiGkgSMbTi923oGer9l1jNnheGdm+E7E/mP
   ###XI3vjdjU9A2IFM+160ZV7mIzQa5dL2s37L7TII/3v3pfb7btW071zd4A3wTGFyYA
   ###T9iNO2NggFh7giZd8l4IhOiCVtkTd6OanbRiST/GXapqytkHJXmE9jyNAYOo9TUe
   ###P2JOWS/qAzTdR4+8BIrparZEynQ1yaulysZdDQsKIernosYBfQRFjhZ31z4LAi1G
   ###TpJ377I0dJI2V91LtDUvlaZeKds6LvldMMtsV5j6AzXJDHqARDyFKDzpDu+MJF7a
   ###SSHwUwcKQny+VWDLtPYqfmXVsmo5N42XOjdV3aOMzF/SX8xOCqb5c+mPeLVPX5ND
   ###nLgl1mX7Ke0qKQRNY4+2mWxDD2F6APtnktr4e4NurxMn6UUabHTd34upFfFDJ467
   ###CbVJwTUSHDhJbY24ZdYieYrHhRpxLUPo00drWr9Gdk5n0gOTc/b0s+IS+MetbcKy
   ###GKfezVslKUp6rKnXTRWvwdZDu/pZo1+tZFHMO6SnZov69pTFFT2pGPuS5nJWJd7B
   ###V8zipCSEsU5nDnDNOKE3nCe0OgdMDCC/MvP3mvZLYJSjNZeoupWNWCdSfRsVSIrp
   ###mFTr1JlnQ6BKh+GLTShag7W1TKvnn49b45daFraxyVOwXZ+F7SxMs+f6+IRphDsD
   ###29goB9sL/yevUvZ3T473bEszsEFimmW0/6CUm8Q8sIguH9BHUWWc3+MuxLgR+Y43
   ###ScYdEktIONcN0ncwxb8ueC1lhlsUvIjJuGHMsog+8RZmY8YtzEb+LczGn3QLo1zE
   ###4BJw8XV4ZWAchOTfYoqTRxnIwxxaNz3MEA8SG8XFpzbJLpDSY/J9tsnrLF8K0xST
   ###4ztBThZO3wtx/rvUDen7a/vroKNH4XIuP+I6aOPZ10EbDsuuZX3VHG6fpFNl3kgQ
   ###Hn9jePxNlZLIGdf7zZUjyUsP0t9M+0HmzVX3h1rdNxZhdS+0NobV3VvoNZSy+NR+
   ###oZdRsghLCr1L9rB1bUq9q9Gk7iHOE9KJ1Kcsk+QtHIlo+mW3ezIz7xvPf2XZTUmK
   ###+cNI5q6AaUzCzv+eJpzqk4sKcS7Mo2m/OLssgGrSF2nWy26VGoaopKnY12Q6YtR+
   ###HXPU2QUHRLdPClv/bNCFzquCm94UUILAio/VIDrEs+HPa1yd0iU0W7UTSDsTMZqZ
   ###uJSbCBqgulpoKeVri1tGg0J7g1kUavWg371kUoOMJngyJRgYcmreNkBVHeJvriRw
   ###c9zb8IBdlDpJFGcsF+9lqIYmZq65HA5vlYTP3Asoomt5GVnF25VRlIxkqgBKIBPT
   ###vRK2EgI3hTaoLJJKexweb6VPw0vHU/aYwjHYSYV1s4RMzSxCKL5OBywvQlcNcRRG
   ###4Agzh1f8LV51a+h16PTpXdEjUkCSyXiIUaGD4VTXRCiz6WUcD2DePL5ZCrDcv95i
   ###nbmOlEr4np6J07pCkUF+lGC95jDZ5LqXOgY6d/TsypRnBA6I12UGcfU6QQyR5Zxp
   ###96WZamb4vZtXNlYDyR1Tp3cWfxikhAz7nmRqZwj4E64dRVCG8Ee2I32UCggydALF
   ###XMYJd9AsgKE8AGfA7X5VVZrS13UDHf/VUAZ3JIOx9Ojzd8UdlYHrbaCfF2XLioDq
   ###gVmMU/zQLcBl3IkomRY170cykNO8rlcDVGbP38niZvaRWftPRqpYd6DaHYUdKOqg
   ###HCD/WibZKmvsZayzX33fdi40r0fpWGx4J7xLXEuuo6TAeN8DHXXD4dbUtAw7qpW+
   ###n7QDZhi8VSdnahraZN2aBgbR/eY6/Uz7QKr9ucwCotLi+JGSnQuST1yySjqk+GT5
   ###APTYobymlbFJV76M0Z2/pVFb3uqX2Ue3TICPLjLm4Zsejuhr4z480xOSN8rJgWtg
   ###3oUyuo3YFQbJdHAXalXQ+DsO6UqFrZeNEBUjO3gJPhneR+Nuwu7GmTyhLVy/4BHV
   ###FQLYeqaGr3Wlnznqo9VMjV+5FjNzLGMYz7uT8wsMWdk5bLWZHGsOM38HGjBKHCmt
   ###hcB4JYcvzD1kWUdGGcuGqEpO5grKPARcJHwCCk/P9z8+B4OO91fNml1ZAl2aHtoI
   ###uARUqxipmNJOjhUioz99Su5GlkaYBVv20meEj2aMxxbakiy1UNLc4eZdmrJ+e7zK
   ###Vb8MfToTFlWJo1o4jgDYzCm7H2CVIx9LczQdvkPKHqxs24O54FfYHmO8aRdvpVo0
   ###+x9IiFbJGRzWuI/OSgJh8/O3poBRZPhdZagBu/MeYsZNut7huhX7hecdcZn2nOKx
   ###coZ8IadfK0YRQ5hg61LO00vyh2B6bYHsG/TPFkCESqqsiWO9SdYzAveVA4oLg13j
   ###TabQ4ptyYhlXEUgVpMGiCmv6JByj52VvgiVT0kwnqab6r+fOoWg+bzGAT5vuoq84
   ###hNpI1g0e0vn0qzu9qNF3gvVJV3jFr/HKRqqGNPTZOCndd3ccyPfoBc4xic7ALJMK
   ###YO5Oaplo3dcwzivCYHreQecGd67FHSgKV7xcoyIzWt8sbKTMlVy/SQ2Ej/OViD8w
   ###OjXSteiuiS9XlSww+WqIirdsVcQYLfuqMuuW0pCZXcr1jBmxTFAZYnebqZ9Yd2nc
   ###u6aUSnx9VOkuzY4iGdiW7il1N4oHCWNFYzhIKURWcexwid8OsdsW0HKtan3b0KUJ
   ###IZS9o8YrFs5vS1O6Fxa6vm1Dc/pSpW+asDgXQh2JzOBUXUpNWCK9QzV9ROSosQpT
   ###4W8VL5Cvq2/xdDapaVbWy8Zf17zAORbPfUNvweeizouSper2WlXZ5ScjO0fm8Aqe
   ###3XW2cztPyoPmIKuWr3buqc6hdohHZp9Mcj1hpcwGztRw+gbbVQoiO7R96Ezm80uw
   ###TtlwTGVPKRsnZm+3TXfzlUGVMoIoxshpgaQEh4x2q8hoyBacZRa1SD/k4dq5GgnH
   ###iF6s1gFkE6lZ6+hKEuzpeYzKJivU0jgp2YPS/KGKldVU9N05YrXETM8eUNtePF9V
   ###Ts3cIlzTTEFk3zk4FLKDo9YF5hw/+XDOlTJ4kWn/Zuwmt7lLu9UowskD3EiXKVk6
   ###Evbggqv5aUyP2KLWeIf11N6nWgNOt7XPKliG4cqw/zoMspQBS3/JsAG7jcA1l/m3
   ###gJncDYNuFC4Kuf1WMdCz7dff7HhNSfs8UJOfNO4YzSeYiK2gx2rm3bCllzyNLTp3
   ###oUmbQK511yWzAc7atuP2OM3wRhz1N/w/lRewIk10mqCUC7rIoJyefLK8osO4bYHN
   ###QTGPuwzkmtAaCeMWDe03W3Iu5q0isrL0sNiI+sJrmVwb2A66UoEKN+1PKG7C7aHx
   ###BE8UfXS6WFaHgQNCeb8jFB5+HTcBrUcAmQVOAReJWhZg1jXCcx1earabQ7GB+Vml
   ###XC0UfdHh5zKzFzykosl0jFJHBl41yxvQlq1DcCGs9QtJ7Zmkl3ddYx4WM51AMjvU
   ###REyWsDJz1b9l4eQ8pqJA3XiEpTPgPMZgbRDGBnGS8CJAlDY5A2WYLkaZINY2bv3i
   ###vG0gw6udCfE3JCxp1AX5ggoQNgrxLja4YSrH31YLk5JdnHVHQyjrruym6twlU4dy
   ###nDjfVlZmkZ+wK87z78ULFzAluqzMlkF+o6j5NImCq4/VvHnmWT9NXdGygtrW0N+2
   ###ZhwF30zFWhw2erDDAtUeAj37wve2LBPIpre+W/m9pty7ZDxUFPyMNHpOf53UAKtH
   ###1pbkBGT86Gq2bVa+ubGqGnUEsav31YpvimFLjb7GiB+mzxn6rVO9JY9Sriz/WYr3
   ###QpXkH0wpPMxiYeSihBqbXsNFCcZ27EpHVOVNWBp+CRAlxo0Q/x3457fn1quwaldI
   ###I0RiWyGo6pFidmD6xyvvEC2i3ZgX7/nKkmag1Qmzot0M+7HmEsmiNfp9FhZKXaAD
   ###GiuZQjabEtFKxQuouvKza2IsSyktSyn9adVteCb/BSSidyXL/404p3LSCyeUe/YB
   ###75ZnZdGmq/yy1+s+5GTU1hL+a+XVvuSkxaZLZj5FNU32j09GPY/NTINc2nrSX132
   ###MZfVR7caFTd3mQ6g89vodCtXrnUuP19sHsownm11a06sZdvIimCrqIfobKvebAyl
   ###7b9lxuRlZWoUSRqRRZzyO1YM9ul1u32K39JuoIsLVpblu+D1Qe7lN2cYHoWS69KZ
   ###sn9veVZe45qLnFdmvegbL0pzJh+ajJrbKcNyGjQzA+hKyt3eGmrOW0/I/KbdAqus
   ###WXvgCh/LjaZTF+yNzjfN11QGq9kJAWzzECiu4hFzn3tln+AYS/5VINRh8V9yQfC6
   ###vTsuzlAkI4bquoRKpE3bl4GoFSXGkERGLtGkdIwrbl5hEp/vPjhmq2gZPVXBwPBL
   ###RNBWrrXdEuCyLe7a4iMsa9RD3sLnvKaSgeMtUyi95RmkhKO2RlKi1y9PDpcSzHBR
   ###OoeubhBhyCtOXGgWEKnlz3vlXaitIpafCbpR8jUriTJfFbcQLUrJeL0snPnvUTjz
   ###X12vYCtn6Qa3IkojryhUAQWCdYB24qUqsVQllqpEW7X+PUGT+H6KAmfh6YlrSFUF
   ###5e4iAqbuWTcrD6IibM+Su4vc3ecK2Co3dAjW2u/8cq9USOkBPBVDjXFFLCVwnydp
   ###E9w0S/jm6aVHKBeDDJ7gHTvebdz3Bl3bjYDjqLI9OwU0zKCXlQGaPcvVgIzVMMGO
   ###ul0GM+kIwIJEkuRcuLNzW2ZNp2LOoUKAzwP691byTBr836Tg2cE08+h4s6JT/s30
   ###Pl1VeIrW5yb1jC5d9P80tfEvU+bdKK8L8Awue5Ok7D2EdFFHT+mz7sVB1I4/R5dJ
   ###KasKlxQSWQdvTDcQM0pJ6hAIgnDulWlTp3ci31Py+zQax1qML0ENIMIEKponlsYG
   ###CQ4+t5TluZJtv8NcB/ex1x0O/jbxbjEipHfFX+QxKDd4h00pP4xpUdblZIivxw8j
   ###2MsZRZE0uLVsF+xXoB1/XZkOT0YuFk9N5fypN7lBdhR514CaCPYLGVcT5tAEzKeM
   ###0CBGUaO8jeMR41w+RsH1JljTMdZTXCAAb6CBtkjpdasTb+yxeLsCk0oTBXxb+Y/l
   ###vz/zH27xyviq01z3m6+RpF5f9R7i7mtiOkenu+jb/arzvDGq8K/ZrNNf+Gf89ZtB
   ###3f8PP6j69aZfq9X8/4BPtWb1P7x/KUSak/sX+bcoz4GV3eHocdy7vpl4pc6qF8CK
   ###V2BJA+9w/+LAuxhjYC069bRvH0exd9S7603i7iuvBQITvZWgr2s8/go/rqxc3PSo
   ###kmCMyWTih8k4oryWFIV3frCLtPrKO+3HyDWTOGbiFTxgnhPdbg95W9Rf6Q2u0GsH
   ###v0Gv53G3l6S1ZRAaSlkDnHo4HXdYEqvL3iAak7Z3B8cdOeFCn/eMka7cDUHH6HU4
   ###70Tz6igew1QQOlDO0HG3y6BBPno17PPgToyqIaCSFXzpLp78tFLxdIDIb5JDgkIf
   ###C0YG5kmVITGf4SWrjyPwPBhOeh048yeIrX4Pz/MrZSSajg4GDNfpR727ePzKMTwM
   ###o8xeDM/qaMUuCFY4BN5TIPDYrFa6w870Lh5MIrEorwHfQ3gyRmk1HveifpLilhYE
   ###u1RBx8kcxz16B58N0GwJkByigDiIJ1572OnFWJ+BiBH6T4mSqtcTIAOyTuIawOGM
   ###q5yWIoIzGuPYHinANGGnZQzq1xjIh5UauxtO4hVZcqwLYH8VBEvISYZXk3uRqBKP
   ###ZDnIaNxDAhsjEQ1WiJyShCZ18e6w7bVPDi4+tc73Pfh8en7y8XBvf8/b+dW7eLfv
   ###7Z6c/np++PO7C+/dydHe/nnbax3veRh6c3648+HiBH74f/+f/2+rDe/+v//P/28F
   ###H7aOf/X2fzk932+3vZNz7/D96dEhdAgjnLeOLw7324Cj492jD3uHxz+XPejEOz65
   ###8MiHDJpdnJRx4BX7Ne/kwHu/f777Dr62dg6PDi9+JWAODi+OcawDGKzlnbbOLw53
   ###Pxy1zr3TD+enJ+39FZza3mF796h1+H5/7xWMDiN6+x/3jy+89rvW0ZEx05NPx/vn
   ###CLo2zZ39laPD1s7RPhsIJrl3eL6/e4GzST/tAvIAvKOy1z7d3z3ED/u/7MNcWue/
   ###lqHPFYxh2j/7AI3gobfXeg+aTdsrzcAILMvuh/P99wjyycFK+8NO++Lw4sPFvvfz
   ###ycke4bm9f/7xcHcfFKSjkzYh60N7vwwjXLRwYOwCMAWP4fPOh/Yh4mzl8Phi//z8
   ###w+nF4cnxKizxJ8AKzLsFr+4Rck+OaaqAoJPzX7FTxAHhvux9ercPv8MKH68QplqI
   ###gjZgbPdCbQbjAQIvlDl6x/s/Hx3+vH+8u49PT7CXT4ft/VVYqsM2Njhkw35qwZgf
   ###cMq0RAAV+6gQbZkW0js88Fp7Hw8RbNZ4BZa+fcjJBH5qf9h9x9H9amVxqbr/T++q
   ###G19571of9zE87eDw5/Ad/Djo9KfAXv8LtvdV7/rVzX+t/B90Yr9aUZ5hHQwSffCp
   ###/HUyxXSBYRqlho9XeOaMxANxSSrpuPNVLb/MXVqpCgRltjg+ah942n2YKnOVUgt8
   ###PMDjYMzq8xpK/ijZH3R2ywUiXA9fn3jePuvKc3Q19z/j/ga1UNc/nCY64ebdnHEQ
   ###T0T7xFvMv8y7PP3fwyzY1Hsn+Heoph74HiCmt57i311vcDj4+jNS5RnoTwVABDpL
   ###6BRE3XQ0hrOeJdikQtPzgmgaBOj32zK71dPsGNoUIqyc8tkj12Ig65NzOKSEqUXr
   ###qpfQWT06Gt5TEUsMC3L0h9lkBuPrall88h19jeltbEMf/FQd/sASOfaZMR+3H3ke
   ###jYa6L7cxhcndyDkNCUTIepHf2Qd8Db64ANReC8/Sjs60V8OzLXuHCXiCGWilxriX
   ###qrT5CjTGpzA6a3pw3nq/LypTrXlG4narM8asFGLwtj3GmipvtZ/X5M+cJKGbE3SN
   ###3lJqol9F0/7kJxDM3OsjeuAVdF7hLBn57A7jq/AM8w7X0/52puNrDySOCHbrI6bw
   ###FaajqykoH3q1AmS3l9A+ZII+3rK8kKv6QlmmiNUEeigbO1PfEmUJa3pXnjF/zTAm
   ###2oCseSgxEHcZa3zxwvtP0YAupHjEeHQFLXEFQeCFNubIeK2YeQ2LzHc06d1hxg5R
   ###RoVl6gWu5FfRH8AMoXehiRNuWfvG0MV3EaBMZALQ8JSPxWA22kSu4eklaYu4j3rd
   ###KcyHX1JgllLKNYza2d9Aq4ySngibRI0R61mTXwVShm4+p8sjvTducWT3gQw/wFXJ
   ###Kg96LbOtSbMkuye9jI1oVRGNqaHKq6TMwJkzZ9sRupo+fuPVAqf9nXfKh8NPRrCd
   ###tnxPSRyj58fgCX4qdrJuMb5nZluR+6wiokIrNiM1egGEbbtYpp2bRqm/xbaRSc+t
   ###AH8vSXlFI9qC1NdWcmPrrEtU+4LhKQkTEga62pA+C4QRJzbJukKLanix/ZZdcDvq
   ###NeLxnzIMPtP05vom6l85s6alwMal9NTQ5v01xN9/Z7+nSLothhx7FVBYRsjMWceY
   ###ftuKrZKQ4shBq5Seg+UMeGeCIi/5TQhoTY4zxQMNHDwFxcEC8nsf2pfESUrHgwKn
   ###zfWKgktDCRs/7Y70XKoitxUiDx85+5i15FztdK7kQVQUIF8C5BcACANMNZwUB8hV
   ###Y1p6raWekqiJKeRvuXdrvJghEjmPEB7djNbJhxXG5HtpAg0Xl/MzmKxLPsT08xyw
   ###rWIFAARpzACimvLaeaDwt3KCavXXFEcEvHWz5Xc3k2BFKWkfKiunbE+0oNk7tIzG
   ###OEqErPCzLsvnjzdvV9E4c+HN2TrP4YI0YBXONBUFccC9kadhVpi0phgJbF6cf9if
   ###M6zc2c9B66i9PzNmOqtbnGVlhtgh2hlU8WbWyZ+XIWEOlBRKkDAPatw5Eb4X5q2d
   ###sYdGpzusmn5/E5O5uzMdj+OBQfDs2I8oLT8m4ndSPi6LAZuCy6xU6IfaiYjVLfr0
   ###bo7s4hL8dHrIZj5njq1pty6iECrRxrf5rhrfbD0sp2NK12M4LNiiA2idfKX66AwO
   ###CkrvK6gj0itfSGp0VqVqKWitHRjoqtfpwavFZNZZ8qoyRU1kLzjXf/7T+2H66erW
   ###0j/gz7r/Z3bscDhKnu8BMOP+vxZUA+P+v+H768v7/+X9//L+f3n/v7z/X97/L+//
   ###l/f/P/T+v927Ph0PO8IFgCJxge0RR7ub9ie9EQjykbjtv8TPdIUbgS6m3elT8cMQ
   ###WWbIGvvN0sx785fdaBJRkYWZ99esaW9QzgibTf9d0+UKagf2dTFevLAsk83F3GAb
   ###6f4AxraSVFYd+ohZ+p56eW7fTPesi+MJFt7cUoqSKYEdAjQ7pmPiqpGaIpHj/bMZ
   ###4COWTmTnV1NkMZftd/u7mDKZVWlV65ny0HHv/fwExtrVAtDTmiFLqxn6G6WZREHk
   ###45edziJn1ddn/sZCnEOy6TFw0iP8vCi/FGf6yRx67H8HepyT8mhNLPqpBQb9yDgG
   ###Zkdr1pWwhqOS0ktZ4hpzUm6wzHb81vfDxemHi588XGiOOEGFGFmxTVD3tqtbvTeA
   ###mC2AdLU3+Bh3/M+9Ly/pUwCfeKb9SqWSlpEYxCQYoUAk0gd4x0Ne1KF1/t6Lkruf
   ###nuk5A12KLx4Dixg0g0spCgLyOCoLEy+AnQQg8BDKVzO6xGiKtJPRMOmh2cbzmxgb
   ###gQaeaxCk54OSvE/ub6Bj6Pwt0P5dfDfE8oKdDmZO7UQDHGpM2VW7uO3R8v3K6tIM
   ###FHKEh2ZEv7Nf2BIhwqytj85DvLgKZz7+YpyuzKGDAkMHCz+KcE0ddk0amg/KOECy
   ###gK3vOIvYrqpuOVkCbjGLG7A3+M4+alFJzuldma8f3+B8K6qH0Tc1FSK8saVGmDXr
   ###JuFg9BYjnRA4yWy5w0E+35N6rKGD8r8b9eCaPZd6jp5HPujqKip1k5mDPWdBraJy
   ###XHRJPkT83o17wWgLo3AwWNrM+MEMF9H3+jgxG4gKzfzkBf/jNyr+8+gLoCy7/SoP
   ###1Vl4nwHjXxbq6plBX4epnDy80lH5ZPqCgXlVdIr97X/t888DnmeZSscBPNvsmjMN
   ###8mNPB1ikAZ9XRBE2JRpURFYCkJ+pKdBY+lmQmCRg1k2AZMx8W3qGbwuDztF12rEu
   ###hRPw8NJbj8V06pdZDFJ4blzt0px6GaX08P5tiEY3gYpasN7cIJ8yEAfuMfQbH16R
   ###bAByiMepe0iWI5A/yGwErPayH99hLVOMXk7dShBihAsQ4FfXa831ZrCxiZDrpFBi
   ###BL76P6iaKA2VqyERb2mG1WaEZ+LAytq8cVxqix4r9hpm3n+Kd7yMd5YBoH/p+5/R
   ###OGbuTAsIAM2//wka6+vrdP/TqFWD5noD4z/Xm7Xl/c/y/md5/7O8/1ne/yzvf5b3
   ###P8v7n79y/OepkJa4sz2riXQ2jQaT3h/E65SIQQAN4y9h7/cGfXTmS435XOoyAkBT
   ###WYziNvEpKXWn5ZkBn0UCPQvY6pNJyCq5B3aopDCcJzdD9OwHBpZ6A5oxkgWGergP
   ###z2oZAZkiRlQiJO5mhmEWGOpdNL5r30Sj+ODw/DTq3MZd5qivzgrbDAewVgk0ZEd5
   ###LP3xit84XOCqnvn1ck7MJrZxDDPvrI4OwuRm5B5MXroN7ytX4/h3INDOY8bUCswq
   ###J2NtOlTEaovfmIic78om71rGuErEI5yIIsmwhGytKPdncCqP4q4rkCPdheyfG+m0
   ###w7LplXZhm3bh5yEPePC/zMrX5h6KtmDgHktsjXNj631miPsypw2sQz6fvnMjCnTv
   ###qq6pbHJfnmBuI96Yg0Ar4to1pWJD9aO7y25kXoLrQ30CekDyvIqy7WvFLMWZSZdt
   ###eu1lRpQXGIqRVf7WOGCnE2tair/Gg9XCcd6g6fRcwd2dDmDSL+MdNvv/IA26Ze7G
   ###pEKAzIzjaTG2wum4xCF6gck9uaVRvS4dMOv2gFm3McjcGxgG7rRCF+ARtIwR9I11
   ###rM2QLYRPtYTjbT7bu5jdtiw++/g5pROjQjpvbZYBZCQMYMK7vla+VYMu6vdzoPMz
   ###oPMV6AIYu0JTmQGkT0CyNRGP+IKZwUBDFhemZVc1mgqI1CUPyimTIJzosz4aDkcs
   ###ENKYdWLFNaIFOGBXGAQLflzb9gJXdGMhZM5Y7p6C0B7lleVI9bOQqiC2JxBrREEV
   ###wJivYqyHdnM7NeycU/Qzp7im0U2Pgq5n0Y42zTUnDT2FOHouy68yFmMBNlrnRSnr
   ###x0IrPzVxd5r7VvWtUPcwy0us7JLw/OTD8Z4y9qbms2MJ8KrwYOdwEQK8msNldgKS
   ###75jDhZ0uGqBk+xj2Gag8zcxk3J+Zw4VOGwEi72SRaWZqGZe6eWqDS076FKMFK0d/
   ###+C5pZgp1J7DYHsUxpvldRJ4Z5WzPVClfnmK2dVrqytuEq7RW/hJZUc3lZhfWgq0M
   ###74/Wuc/1klpWk9GD1Sf8hgtrQSFVN5YyArU2oWJZfWSpeamiZL3yQCpAmmal/WFH
   ###T4nyxXbs4Cpy1htrM1Ow7MB4VTrjUzmqHU+86cgbsRpZ8uwcUb1bji6GIvyeogqz
   ###Qm97p5W38AFW8qs7P75Y6927wavsXPmYOWfURWbzMRr3ost+nPBs5DeYQxtN4Bh3
   ###bUdWyxA6PoQILWMUfYEXASDyXfx6uh9+PDnc3d+zTnw2Dcl9Km+pjOkRZWDOyvRw
   ###POzhtQAuuJdaalS4LOIxvTyVAc22dV4/1W/WNuoyPl023RkOk4lslpmC34bATCLt
   ###Jlpc9cx/mlTn2CBBgf7/mXNCzurfp4rXmkQh9iSLQVdwJR58xjxSWmkKuSmNN9IH

###xuorjEXyL/YKPiHJAMdgWYva71pAbXbuIrHdUhsW4MVjLBK0QTPwcobRADde0jpH ###sMopYyiroJZh25ZXrChWvlPumRKqBHPyB478EeIJM6tkpSbhBdtLaNjsP66ipuSR ###BQgOfEyT0J3iPFMrTXw3usFiAOq+4QxKUYB06UhBPVIFHiHKjtH0InZWmH5tVFUG ###EIjW2jYQ2eHx6YeL8OLw6AKol5xXc7db2bGvyNOVasQ3DX3LMT77VRsFBBlciN+n ###Ub83eWRWNRPMd4c/vwvPWxf7oQqwH6iOtjPGZ3xHjF/JwyTvc55/NH49e3x9GQUU ###pMkuJA8fju9XHaQEorpAQUv4w4d6ziD1KFYoT7pCqj5ByhlMOr1CsEA7uCmRQN6d ###0mZMQXCWXvRZjYOszecudaAC+1txYH+zgdWeVpgy54Y41ae0CeLYaR9Z02BdK6zC ###uobwTsvKtMpc2ihnSlWppVs1RJOlOBMIlVehaLO2nY13pSGJPTPbcukglYXcEoVL ###FhLY+ba85Fle8iwvef6lLnkc7tS8BN/RxSkh73J6FcIPliY3CLEFEckg5Gtaxc9H ###mGSjamt+8Pv7Fl8PeAm/M+EPv1tq3ktl/FTRuxiiSwiQOmh76JU0AQHM+yr1LZAB ###JuhBCtOeJohYyiw4GWN0DUes0i3P+YTnAf91y2wSsoJAShMdH/okZG/2zPTZKw3T ###HzMCoMRBarqsk+8uENRbhycqYGo6GA/7fcBUH03MrqRsUstqnb/nEj9s/vCiddpG ###hbNm2jwZKliZNicyxD9JGaYzsroz0w4+e6xoUcUJyWsPi9L4q94Leud9q/13TYTV ###FbPVmZCAiAGyqEK8c0EC/xYJyc7TIVl7Ck6cLsgqaFWnuSDd36YorpN6KtaogwqO ###kCZYk2Z42dWF3ZWi4q6WLe6hPlXlMn0/ivE+7FAUYHpy89sNVYdXmZhRZNDYvEav ###Btxmr2zyeDbwXlcce4DzmZL1W4Wu/NJ13lpx7iDzNWdILVceHLqMiV3fBJVJIr0M ###jdZEh9pVSl2r2n3AikxjN3rU2bh3CbRLtXtJYOOsy+KrjJwcrNZirLKlymtlS2sR ###LN72bSXT/5udLSz5z80CXKPz8v+s1xpm/Z/60v976f+99P9e+n8v/b+X/t9L/++l ###//cT/b8H6ABO9nqY+4fdizbZ7d+t/B/4Ha1yjkeqvzecVdBQdwLHGxT9Fy4rkTM4 ###9zkPw86oP03wfytwgAEb8v5r979W/iFdzV/Phl+7y0TmKStYSPmxQC98DsJYoFtF ###XNldjqJkgpcOh4C7h61C9jV2DZPcTW7wxmqruE2OrmmKv0d6TNr8G8+Agz2lVtOt ###oshN7bmuykrPR64rl5KQyplis/PhINuhwH6X6QOfnReZa8xSPcvClswyfjneyLZm ###ZbU31ZHc9vLGYnbbcYSVkOO4u1XEasn8Hr5lmtcLE4rucaU5bz2LUPKqe+E9xFax ###q7Xd4d0diE6sa0wuHo2FpHTVH4JcNbiukAMJEys1a6xrA0kQaItuFQGBWs7rkaaC ###kHH7Ib2QZoOQ7uZ2cTDwlODv70yvrpSrHY/uhUiCHSgOJZIFq8DvfYI9GLbg1DxW ###N/8Ds2AE3PXA8AY6avE9jLH5X7bmh6CIQR12++5wPMbc0Fsz8HeMmlK/90fcVevW ###MRGWQYIG0jjBKkHSMR5A+Jbh4Ji3u7RdJZwEmafh67y3nLuIrb0ob8aq7NHNnO38 ###k8db6J49LfQl01Bzppq30Dg8S5KNBrgA68LPLrflWinqos7OBvbmSycwM5ac54Sz ###HNtczcX1pznMiuVN5UYpXl0gUcDDAltCeuQ4Coo5XHNmdxfM212xS7XP4icDLSm3 ###iTq3iTe5H/IsH1qa9hEr/wNDsBQ4c9yA6d4eLhBmdmH4xTylC9U7y3s6FIbf3NyU ###LJzUq7Pb0t276qUz+xXbsyel+rs4SqZYt6bAkiWwKZJ4ECfAPTZmExmm5Oc4aRba ###zcRc+Cvrs/s/j5Pj8fVnN+XqLP/cKNrAHTmZH2dBRwJXEwbC2UwY0C3I6w5RoZJF ###+cxCEngJmHNqn6YMCXvY3Tn37lDIKcrwPwx+z+b5eVpSX9WSNEnT4UFf+CxsT0ck ###wIh73dfPlihTgY5/fXj47IFyfwI8MTz+8D5Ek83x/lFb8lv0uBhiJ3bB2aRND2cT ###4WCnN0n2HzogqhcR1ge7N9FgEPeT1unhHK2ZfS/qF3gFV2j+10DWidug5sftezwm ###W2jFjLvhXTL71Qjb7oA0ct/rTm7Y+wVOY6yz1o1x/UJMFRne9brdfmzSFtCTy9Dw ###LQ1kZ3+fkf+HahGTcBCC3Pe8IhAz7n+aVd+8/2lWG83l/c/y/md5/7O8/1ne/yzv ###f5b3P8v7n79y/p+D1F6H0pKeod8hSn2fyOB48ZHB2THBKojFIoNVEL9DZHBW6Qqs ###aT87Ljj1O5ca6AL+/WtFBiuaCV4P9eMBpQYma6Id7Xszvul3WdVBXqIxK66XDOFl ###/jccTcaWOfQTTIUbmw6AY4enhxe778h49+nwmFnI4X1sZb8OsERwRIdotWZ6vNFF ###5gUZDDzGeP7GZ2Hhcr5pWw5b4VmgmNaKvIXWSmYfnvUWN23Mwej0WOFLdo0g8pDH ###k453GaHQAuLVQXptMPcInCQ8Pd6mHzHWJio8859ZyUfuz68/6k9G4V18J2N0JPjR ###1eTR69zEnVtnrhgx/lsdAMZYEYMgYJoBRURxGBktInXzYZgL3fvsKiSmSuZmpU51 ###9xftVzqOyqqgMKMuWhyUoCLR6IDqIh+10AnVS6K7UT+1Vsp9hjMnDKxJ7FVmIo/R ###rdhr6GGKnxVjfDQa9R/DpDeIQwZgSbYup2OXPb/sppTVdM3fk3nDmyJc6WT12aSQ ###rLlJb8uYdG4zmgEsfWf0mAF2aTZ5VXRXaNdoFA4N/3kJTf+Ih1cllROsqjhAf4uM ###hcyc+rOgmoGvBfQ9F5kEs8kk3RHI6dXryYRFMMc6x+CNSunBUPZe0DFWJhjKMyfs ###aMH3O4yq1K73VTCxAP39TQ/ApAtbSg1/hbYLhHR4ZdRGVg4tI66VstxoT8vWdzMG ###WTlNPr0D1SQ8PgGBGy+dd1F/YIH58J81zNZv45WZ3q/6PNOQxstYwFHSuZnKItKi ###lvO2qEEFz0r8MC2rWC+CRQWDykUuliyS6S6UcE3l+kQMv3f4sRaEX6PxmY03tt+j ###B9x5SqVxJVdB6q8/+AoHTSYaKHm/BM9Vl5nGug2iEhMQyhIhc2JBQHKA5gMQN7Dc ###EMZvAwQAMn3zA4JADm3GVhUY0Q68askIkmJBFiUhCFHMia/ElmglE3Y+7WsYuryP ###H0bRAEAosSELISiX5HdAHf50ePEu3P/ltHXcVgh+bnlKnu94rEtnC5kJIkPCn7d/ ###xk3t9BFEopw9lgV2pDA+Dx0VSL7ynzz5yvEJy78SIq/4iDq5qM8tpLmMMt68NIiW ###KubiBp7dDPtdMsYyVp56jagpCKQCAdRmrm31VRNWsKGljFDb62kbFFXE7KhSfVWt ###1llfhRH47CGpLtK6Zw6ZkN4WUvl3unPeWMxo8DOfoLY7tdmO469tufRcOpk19qeC ###M/Wb5kzZffyE+RHMWkbGWNQnevKS+bZWerb1LfLLy7r6lHFwkzH/NZIh5GaGAyjm ###W9lKNVBOc2yp+7IfXdNdcsZjNJgMp2PWZMWchnhF8fcqW8t/FF3n7gC5cyntjDWG ###eiCoRKExiiS8ffdH7ii7QxRxH3pojnfmXBB5QCUA/8hMk+NKKKXmk5oRH1qsqw/H ###VmfuQjpCtQDOWHIte7UsdQHrqb4b8+hDj2WdRSrO1gqVpM+XpXiW9X+U+38Uod9H ###k3Hv4fkFgGbU/6nWm+b9f6O6vr68/1/e/y/v/5f3/8v7/+X9//L+f3n//wPu/xd0 ###GK54aMNLjdRMjsI4LVCKI8Ya8aQ6agvVNH4F7yxu2i4vhhXV3ptoMT68lOwvf3s5 ###0T0XsNFHepg6Lcy6y375UJ7rLvtBDP/5yFtLc7h/kYyWDiMsZo/nAeLxl+det7+c ###zAfiRTS+jicpnF8W7RHg8PsvBqEjKxqDMvn+IPK6EYVBfB89UAgZUr5Kfd8xKfzL ###X4qttHD9OGVptpHqaDM4NklGnZsnY3Gc3PSuJklhLJ6T6MdfImlLgpgsxvVDyfrX ###y8zUPhn7ZfqTFbWbFpbnpjx8BfMzP2iFGrbo1gfRThcsZGjmt6Bsdv3p3cCr4udf ###fvJ++fxTufpF3grB6Fg0Ysu+zhKsTNjoBJbf2vZqBaEooBLXMSuUsDTk1S36IKuU ###wBdHCth04rrtxXVLc2TfwTi6WdNSU1EqKjX3HCKWX8EgRjCX1WpZztjI1vZN+/bL ###5DNNCe97lAVDtCCq4dEXBZHSigQDVirU6uchrtoAVDSxVLhQ6gt5tjLh2SFg3TZy ###oM+Ne3U+vPq1mFQY9XvXg7jL8MVQVfaOMMPx4mfLE8ZmHLfiGPvby1/s4za1ufyL ###HrfLs+z7gHgTR91wPBzelYuBuBcnPcwDgO/hawv0tMw+bn95xnH7i2uTiMPiQVYJ ###enpYIjUreN4Kf9Ufddz2ylhYhQ5dDmHYH3aifjld95A/yDhwmXNJoQPbPi+5Zwqd ###wIMum2/KEXoTNNYwRwTd2SGZ3oXJ7+OQXih5L1g/Ze+FMQnMuquyG8HludMMxy+M ###hXI2mXcU6vWIfPmwFjoEq7+LHkrpU+GwtHv033hg8vnBuZgWmOO/WYermIM9Egda ###mxuezo4lykQx0BATcvgJUqquasIN7ANNyKEw3TtmdhukxkvZTYpSw3fMlDVkQ1vm ###4KBV8uWMBy5kPPCKXgalpq4fhtDFH79J954hgbW6v6GpUfeOKrJCssOKGxR7sbbl ###O1a2TsdCjWNUoJn9FhcrUVbqN75Sv6krddDr9z207jELZXSNVmh8Cb87uBt/k31D ###b7iShyy0Sv9lC7YKMKtbO0eMPsgTnjWyUOobcHnqNzdJ6AlhBd5nS6NHANZvXCJN ###vzpoRl0qfczW3t58Y1aUASuzRzOR/hv91430byuqwqHiPsjHva/h3uFxJwgs7sd3 ###5Eo2k1jsnfUspcYvJFjjcYiitMdN3Bp5sZQr9AXe1hkZCtWmRC3X+enaEe/iOZqR ###zSps/UhbsHSxhldXcncb3AAOOdeUTWKjgz5zj2e9VeUv5r9l7vCSJFZc6FV34ZIF ###7/mg6J5f9N4PCu39nGWBBczjBHlv/6Z0kP/2N1PDDLiGyeusjVLB2LSIqNpnCYZb ###RdGsiMb9F9nzhdXyP23/LGzTf8eNWGznzd5owsFQdJ61m/7iW2exO2dFUxS3dUZC ###xYD+Dfx/MI2Yo7TdkxyBZuT/qDb9dTP/R7MRLP1/lv4/S/+fpf/P0v9n6f+z9P9Z ###+v/8afk/lBu6DKmoVCgRBRV+o5iQYtcjGBBsFlkE9sQjco2UpyUMTkwD7vXymsU9 ###Y+a8TVRucLTql8Sm4RTEI3rikWlexjkAnJgXkGJKucl6Huedgolyy/I2UTZBfGph ###mygtxFHHwGVOBsyCV3XunLrZhRpPReIYUH4GcQrWzFycRUG0L+x6g6+ZCY/LDhAP ###MSIVTrvfWbXTSIboJvPDXBCLeqnrea6Nn4y8eUEUMUvlgtvleHp3CbsFZQwO3dPv ###tovSYsoV5rx8R0nKsVeTSTQmozJs7xcPn6tfstdeufB0JYWh6H/4C4TvTArjeTtY ###DtrY6K5c2oKz2t0QHLeUxuY3x8UpvhcnE5kthOfMSKtl8k558TT4tpXeotwyU/Wt ###90YSAnzjNh2lfjWfHyXjwL8VySC0OvaW+VtM2W0GT3HD4rU1vojl7lOUrWETZ/3D ###19QsDXNOi95b1wUKZNrhsqaQmBtSBY8C2Af5RQn0FAANB9cVqjCshNsbpjW+bmYZ ###TolrlWCwpiQWz5b4qtoWLdNUp+A+y0hngYCWtHD49ap/XxIPy9kQcYtdCpXDzvYt ###b856oUI5ICvaDmgcD6egfaEGVnnrnVVF6hi1aMP0kjRrr18Q48YiZmUIKKVbbDVd ###aJixmMGqvehtTM6RSjuzB9eKdeqn2S0i1nrFHFSuzNpa1tbQbYqJCpXKG/AWKnNH ###KHyAErnQP+ONNABz5S9j/wNldRR3QyPfytNMgDPsf75f9w3733rDry7tf0v739L+ ###t7T/Le1/S/vf0v63tP/9efY/USzybNfz/Gr6tQ1f6+Tp39LFJGZaijwmRAEbYFnq ###Hr3ooWckB86Ws0qKuJptyHnJ8qwV9rk+j5Npf8LDmDAb3DOC2TQpPdsE8ZJn3isK ###IuoCzOPCcoXjsQsLT8D7kqyX5cJ2z0MydlKUBBwFAsLvamtCQsHk05ibpwiIn1h7 ###1eL5vW1Ns211WbYmZjxeeKbljECPOQzcahgve7cUf40Hq4vLtMxyLPeTGzvD8t3I ###D8/gRIYPAXywGrCU4WftnIqgoCn/w6t63/R3m3Wi2fBs97NX5F3hvcoSpJFgCJIQ ###IsKZqVc4Or2gLGNqVJfWDAsjAg+tIF99u6145pMRaDjyQNgcO93aB8wWNfDeeMLw ###NDDMNBx5wlJwJL0HVesEkd1n6OdLGSFRzC8aCFG/PwKgQdXoMO6eYxvjLnU91PED ###l0/dyXSCtA5Eb3RrGj34qpv52NJFJ8dW9StbtUpKOArPMG1LWjeY5Je/pLdKqQRb ###6e62zbriinlUSkdNu64yT0x1oVe3noMQfwZCCAMmUgKBlGAepDBkMsQEuYhhLWci ###J5gLOantL31DhEA5FiuFRzRa4GJxqxjwKIH73aP/xh7lqPQuvFNrbJlNSVIu4S9l ###r+IH1HHZq1W1EZiIAK9USvjrGnXg4hm8IbCLCnTx4oX44c025R/dki7y2MFbMz2l ###OyZmzRUTI5BqGTuBbTAUvNvfxWSIqUvykcS0xAttUZqLvbZuD93vBt15BnSVLPBs ###5GvLzTk2nZRX3uU4jm5hV5VB9+2MyTBztovVYZc55f41/T9ZoQ6e8/WZGeDy7b+N ###at2vkv23UasGzfUG5n+rNepL++/S/ru0/y7tv0v779L+u7T/Lu2/f+X6b0fDe2+n ###B+fUJEa2Oh10IzT3lo52zs9XWdEzePEVPMMThzKTp4WrgcHwumiMvWGR4THmWhjr ###JkWYEmprwDN6gz4aoBW/VBiHl2n7fuXlFGfPNnTtYWdPLTn3ncrL5YEoSs7xgtmL ###8qR8uLoPz2qzK8zppuOFlG4rmvQET+RdosCC+e7gDMXy4tppDtAyKmYnYDL0rqIx ###L9veozo3WS6zaNZLSZVTaXcYfmztzUus3p9FrMJw+7pQ6ZCPQxCLvBYv8+DtwT7X ###LFqvCxYIQQz9HE/arfBso6TVBXBUW9ihOl/+E0qe2BMQFWhYwQpPFKwAxgP4BKhI ###stu7+MW7EuUunzWiWavEUSfjjVV8As7w/d13smZJCOCEF+/OUYTZoFJH/1iZL9G/ ###VQbFnWZ/MGTlF3eHU6Qw1X3MnIfRFCaBXtYM7oPz1vv9drizDxLLPgJvGXh0qLGF ###ljKB249mjfmWDPwk2ex+gHmxsdaeDInZ/3ZeT1szJpT+06fmRDzuBqK3zzpAB+RI ###vU+bu0vmMFHSwLSw5c3DhCEP2Py2xQtJPG12/paaZc7aUFiakEkTjCfTT1YreWao ###TFlae/5lBIiZKclGg53HSZyczLjddaQkG0hn/VH02B9GXe8Se9qaF8S4gzjMaTZK ###zqPBdTwLlQKLneHdaBwnCZy8dAHN5JnpOP4RAkR5EQIEIBfF4IWCeBc9gAA+M7Yq ###FcOuMG/OT/he7256p6z2kN1HUa6zhYIIc97dOS9+93yAKRFYRkYyCYEcGg0mFaEY ###DEfxuHDWQUWEyZS5hajtiKDolb3eBDMkAroO6cMVupeH09Eo/UJ6CxYDnqTcUQ/T ###eGAcBjN3oe801UyiXxyhGVyuZqVy8VwJj/aPf7545wwAkd19pvsr6501LLDJSsVR ###MeEte2fKTRiifatsfA+Uu6hB8jvjhl5y3D4TzcVHV0LcJI67vN2AUSn9ERhjXzgu ###Majq/bQ/EQ/ld3ru6JyisA73yuKD+iJ+dbxHOJMdn204ngJueM0oqiNE0DsIgzdL ###K4s5Gm6Qr0eUTNBHP+1NRdSUN4PusNgdPv7s+cF6QymI7JFVuIdpAiegQT9608Eg ###hpM2QYsl6tB30eCRuGOvj2p1iantyHCuO51VstZOhkOvCzsdt9U4jvo9FKBkylcH ###jEDJylLJb4RT+KYvlvqDaFEV6Y8dIkIbyMIop0y7QUqW3guv9nRpPq9INNNC+WkH ###9IjyPJALyvxMaugNuFMOLyftPUPId8Ehgyp4AiBm+qDgMkpuSECQmZVEGVnZWNcz ###JfJEmeOcIs984FlDGJwJ87+IXyh0Y54h2FtYSFJGtkiZbC5kpkWnBwme9MndcAjo ###uoRlu+910SQ+jgZJT/NOma9vXpASq6j2oss+7OPpZHh1pWudr5Kj02zNs5xdAfwp ###OqmijI4evUF8n67Y1RiOrdRvjJPoEwj0tV0TWpAYHRnML+p9G86UWWXuCmJiRj1o ###1Ob+0yjcd9Xr90kW0JP8Pakq4gGmdx2JeGPY+L0BUA3QpVbt9JlVEQmfmEiWbyQc ###ibQKjysML1KrntxcZYn5QsUftVkdY7llL7mJRvF8kzBgprLNIfWThvnPAlzINHOB ###P9d6obE3GmdWHy7h2q1hSNrq01ZuxhqOSXiJr+ZYw7Jqc3wSQjQsnI6HeNAzkaaA ###N/LrJ853xMYJaZys2T53ZubU4rS2MFpTByktj581N3tysZKxwjExJnE/k5Bf6y6U ###9rXIhFknUmP0AtbNvP7ImVzm6in+njzJAXp+wu6LUUMaPSrKq7hJEJqYAg7Xj0Bq ###aKZmHkXSdpQ69sleqcaBS2VKtzIpKpf+gEv6wuOOUe/hnrv+MwXKHrIvWRVYra4l ###OBXffiYgUp+JY3vEJSG8lucZQiYGyrTT94WphqnGEXFycr1Nc1ozekkVM11+gd/T ###fgxtTu9PqGyGgK7K7krqYoe2ZLxoNLHeNVQo99tpIzNvwIQThbdFn12FSWDGklK2 ###jZV1RbiTqqMrQEZ8emqBdnTMyGJ2x4p+anRsv0nZ0JPJEB1vZlOWOvMes4VXnQBZ ###BKRSnUWSeWSY2aODDFUqLUKS2aZ0TZ2UlDv7TYMmMeVmptpfoJ+2avLOswzoSQ4c ###qzz/OeCUBpFfaxlrsoKXnj+udQ3TxgVM9uJ+9Bh39+JOD516gAJ975//1Fqq/ugz ###CRQpphv34X8d80LQRWEOMkmPQk3NmMKGS8orOSZEcZa+ApGly1ONBOQLXE6fKVlI ###lF9b5wH8UlN+eReN79oo4+BxRK0LDX3BCsqrfR8dgMA+Mn6U2SCU30QZ7vTN6O6y ###G0Grqj6BkFzKsUfX7svkTeoa/ei1+TMX56+1Os/gJk5mwq/STlN3nVmBkM8eVb2R ###44RhX/6n51P2bSFlvM4QeBeKnf2HTo87cLZtx5bvhx22M0qZ6LDvYt3P6Yw4ubpK ###4gk1mnng8S052+DlEnvgZJzE/b4KtrM9Hin8zohi6F684GIe/8L6e7Mt7r4yTw4K ###znDtlZydI2Wm7W2p1Djr1EE7VWMBuHLETDj6GNRvFaCzwFaEPX4nx4Qi8qqNo3G/ ###h17EE3ELRm7X3V7Xu4t5ESGhn11Ou1hXyEFM8wh+wZySn4iaMXp5NQQ6Y/FK641C ###omMKU+Xt5fSqrN6SlN3dP1siDZ4uktLJ8Uq7S8H0ZFn3P9kUmUG6DkK1aWo2oWpb ###6q0rWFOhQ16iCIlKGgf+lnhIXa/RE304ZiQ4jroxFgpAuwG6ukdjjAuIv/aG08T7 ###L9J0/gvNZdP+JMmkR/sEVOpiqHUw8o9K5Uc/a80yTQrqvzw9v5BUpI/iu0fRL9bo ###WzY42hWbdZE5awL8+0yOmKq3nNVKAqt4DSe56LYbx0wdl4l2o+xbRdcMVfX7P4vo ###9S67TiZKsow5GkcuwlltblrUtJPJWVXGODdX1ZioxWKtrgtxVJV9PtHupKW9c95H ###5/DZghTttKt86k1uegOga3J8gVVmp+ZPXqc/TLAq2nB6feNa6WIs2pASNJ4gcgS4 ###AeO8FynUizqd4ViYYW961zcVOuBNPtyZjr86qVJxnMD+wquIipuDKuLehUoDwYP7 ###w+ug3xtoMb+CQVRSN6R1mM7rbPlwzTYDN9lLq4UhuYNf8RwwHpetroEaxSWji3kU ###OT3zwIgeioHhv6plA/ItmwuS1VzL92gNpbZdLW5LVEnrkryb4/FoiOk+gMIc5KOD ###ZLDpNQbj3uHHWhBiHkz6ChCXzCOrYjn5pOeKekCsaq5B5sMtp+0rvmfTuYPeRyQh ###i3Qdl/HkPo4HXtD4/5B8sg5/0d2t34X9A7zOKw2GEx5LaQD8xgB4NcvKqiLorUtm ###yfducmAmyFEQHBTy/NGyZJuZ830jyzW5IDC9uxY03+ePNqdeaCYpcF0gZdfts01A ###Wj5Xxk0xj6xW542yfGhvfhj8Ll82dr9xm+aYAmyTMy7E8xtls+R3riYjIemrD05B ###yjeSiaR3caQzFLmOc5jIHJTwIgdAzeADx+ruyR4Fv+0dYhhh6+jo1+xLPxNLHwa9 ###36cgAHdjQNZVj7nHMozxRFwG4r7jReQ3o14rz83rcgASMhlWzS1pDmKpVEZfP2ef ###z19SvJdyPL4KeAnBPpjh84NeAKl5cRDH6OhPrgBYsUw6jFk2KHZPk7rCGbbUz26c ###snqxzt60+5t8O1oK+v5DbyKjmo278ozwnmyfJu94KL3tFdpSvPh1NXUcT6bjAf4x ###6vnO62N20IOJIUMQo+eYeefsXSMJrEnHwyyiK/TFwKwHyqSIFhgESDNiSB0BSj6X

###ktuaCHS5XvZqksRUPH0TEauVRUSsxqnpF+t96KGry4jVZcTqv2TEqpGmj3B4Ed+N ###MmumsN3bhqPycHA15KcaEgP/SPSOtaMdbJWe5Ud9ZUcf4LvPc65lNIa7nBxq0afY ###I2ifxfsyYzv5xkcf4y7aX2fEfb611EjqwAz+LBD4Se8VjrCzPJkGLq8CyUcQaZqn ###AV9bdlkxjq+nfaA9wVZz3J/Emj7dcUm/OlDpL+vSWXRrku+q6SLXjr5iwpPeNZ6W ###tuysDa1tFy7fIVusvDV/NSUUW1yqBQYslreFvoZkTjLcLAouf4VlvnTZo2SZdxkh ###MYo6t3B6UwoYbuRnz0CTZnuIdZqhXwiwmCSnaxm5Vj67TjPPuUaoxbME77sm0Rj/ ###EBxjh5lWJw6+LvwnluNtu0CbNRvLDFIGUrI195jSuNVjStOMN8recXi0/3H/qB2e ###/dw6PKYlXM2q6bEXk9jCUcRIGDNAPYLYRCEo3Zgdvk7XW+/kazzGXD2xNx0IHtDl ###3dDr5o/m9mA6UTdWVULHtsies64QvphJSwtRCJ/o3Dy3J9ZTxvl+nlczPa4Ubm1y ###Wu7IszLbi6DA8a+xT4eHj/JU9fFxD87aSa8f5Tfb70d9mnr3qMOl/j15o7kPAuHz ###o/an3Frqs3L7/Titu5leWMv1+tPXS2PG0r2jmEjhBtAlaBQXKUQmhWX+Tz3/pwhY ###BFE9Hl8/PisF6Iz6T0G13jTrv/vBsv77Mv/nMv/nMv/nMv/nMv/nMv/nMv/nn1j/ ###CU2AUb8zxRI/SZrKgSSjHuMZPAJNVnW+B17Erk3S327QeoY1VkQRGpasC/NEZJRE ###f5adPb1rcchyxYpLDcZoLZtVxlwrLqWg5hEPxyfX4S5YXApBPCsAowDxzPsa9afx ###s0DLvW+xi0s9zL5q+d73LToWbRAjppwG3heGyrQSkA66ALF1TikIkrT2N0PkTdS/ ###WggWbVok1bDYQhOIZ1al+mdjcdEV69uC/ooUaF8MiP8CFetVDlkERMx+UbSs1xxp ###0iwAhxQfxErJl71xctO7gm/9P3z8v8CRQos6xNnwQtFlj3/57JVcKco00n5p7MNV ###Vsd8y81xXlJ16S13SsTJ3agWaCXu0xr3bFIYnyGxvmbUpk5dJKguPDvpMAvCOI4m ###TC/QMxzZLIHll7oDfY2SFwmylweoWttL8S2T5pu3b11FcNRjmXEe1q0GDWejaS4w ###x1lrpZMAXMj0LyxnRkmsXZmhsCxYJjmglfS1Q3DJ7UeQTIpc40KNbv8poxFdLEnM ###cCd78k7tiDl2nTNTi5KntMZXFL6hi5IY3kga8BtDNRa8d84AHjn8+ADs986VfDQv ###mAiZyfQuTH4fh7RfSt4LJlP0ADturK0BPIDSF2KDaRtIq7PuKiMPtMxP+ITf9MeC ###7roZUHIJYgZEGPfCQLJHfY9aMWYMRX8tiROzhr2yOGvbnDRcKW/NDpWTVenyQXSU ###T3uGW5TXGo36j4SV5PdphEiR8Gq216yt6NyFB1NKxzdipbhYPyxzir6/8R/wS6WI ###GLp5MoIgN1AsIaYEzQBbNdpyIUBpqxb8qwV2ub/0DWLT5gak/EoCFZb1Weuz/Z58 ###uem3Mn/E6l+dsVqG2H3Fw19FejdBlYQXFzbEZvjiHsSYi2xNxw7Zr/nwkobxPhaf ###rekQSbAsoqdCcRlvLK3j/772/2TY/xoD7T239tds+3+wXq01jPpf9UZ1af9f2v+X ###9v+l/X9p/1/a/5f2/6X9/69c/ysfDnLQRE6ExpHpgGVwvYmjLoZSuKpzmPNAz3ac ###CI8DsHzTz2pNhGli2X/O6hv8wTdgt1/DvRC1V1R7KHYWA0yY7oOsdtx7gC1KFX6O ###9o7YGZAXwLF3xENwoZv0SsFlwH3ZKptxD2rYwyPgcgxDtBko7xkoTwsieF+2DIRt ###nCaw9dn9zh5Km9URczjKmBWbzAcKvISBowFzAc+GQvjLs3XSH9GPWQjksXg3wz5Z ###tXpUuinGBCTRNUVBxP34jjIFAxb2hJmTEUIbxXzvCD2OL8t4azXwjlDoYoE8Ctx4 ###lN9E0MUAD8kBP4P5AHlk0g5pDPKcTsnEZe03EYp/lWkeEUgXRVD5FDLx9np3Cpmg ###g27R4hq5dxgvL8vWUJfeR7Zmz4+g0SjygVxZtfuuh+cNpZPJ/0xeppQC1O0mFSY0 ###P5FO0Hf5TyET17XEkkzmIJOcle32UHrHUfMPigvlplQEyB2jdhAhaF/nhnAmS9Wp ###yPdeA3/8+iRE5DEbx6VVF1SgQVKYcPK2ZeK1+KaMkmR6h0dAC/dl8njHD1bNGYAb ###duD0zl0KbcBWoftr125MxOFuyhkLDhh8XwzC9OqVCwV3TxEKnnaBre7wObF4+USi ###LMINtGYKZ5gBolkt7QFU3D4zrDx5AznCLo9YsCXdcbxvgfryS9g+/O99fj2q/vLF ###kn5//cxpw90y5Qr06bOz4YqVdOo9ZpkyWz6j5uZLejEVyFuYiQYF8GTauWG2pBbe ###5r3ce3n0N+a0X/jwFQcviyF/cj2IDHnfA7YA+44fx0xEfQ4iGCZe4o1UMulNppPY ###wzmTyPHrK68X/8SqNL2Uv15622/h+6/08Q18xk8ASOlo9eXlkyetT9uSX8WEYeqw ###o39dwJTTWdIk+Becx97qS1DSL+NOhJbKPVjxFXZ6cIGKLogx1U8Pr/Vo7f3X3bC3 ###kAW3zm3vV77MMPkFTFtM8uhveF/Jpgsffn36wjnWTcqTyrL9ipf4yOhWKRvCUsP9 ###36nh2o48zHXntkxB29OkDOxzOAo7WG5ty32GvxxNxn6Z/tiF/XB4ClQlhwO6Ew7x ###2jYe2644X8Oz6mf7hCl7e+4HVgfA03E/hjToWQ2WRf+lXrV+2Zj7/GJ4SVNX6jM0 ###M76pN9Yy+xZP3tTioW7wV+Zx2tkpIfm+Z3f3eIdvJ4k7ODzeCzF8DENUw4PWbtmr ###0VU3ZjF988bbFEFb5KGQrh9zVVC+v4FxXryQM8IpKY8NJwY572q2i8x7tzsMEoi3 ###zQXJMOqOJaf5jfJvvzezUTEqsdOtmi4Xv2Wn0WLEpLkNfDj69KkkG+yJBmWCj3tM ###MG+Bqit5GweK5RFiPR61sEdB01/n6fGbe8IiYxnSB8cX9EVyxG/03/e4zLy56d2D ###Yb780RuTLl04co6qkaJCLFSzzexUBcUhAXM+h6H+oyHW3vuKl5F3vUo3vsKqasAQ ###gGf1+v30RsxOBeBa+PfZC4//DMz16L+4p9IUeA4Ey2Z5s7KTMJoMYWbiT/Ubo0Lm ###PMUG3cpTKaL+ffTIs+yWdofjcdwn28qqp/rT8MaT+2ElmcQjD2UUUqQNzJr8UqDn ###8Pjj/nl7vxZgqcOzlMBrKA5kQIav53Zfr+qeRyUHu667+8fu69YOgiPEIF3ifkG9 ###rG94Ab0FzqoYDfsP6jPA3zAZCYzv6nTLDf6Ga4UoWYj/es9Kr8fVLaCLV+LmAoY3 ###EbaV+Q6/1LDekeeda6ekPPk3sVuajQYMg6D6r6p4HY0ioZkjw+burUzOjkJCxlHA ###OIzrJbn7qc1MDpB1esiubhkjuWUnyG0OIzE4pJPh33KGH9DH3CPkWzEWLE8PhRHN ###t/sFB2Bvv2Zs5rcv3k/eHukrKDE6ljKDInoKRaj803DHc+0yzDaZnRVaJGgrsF+R ###9xCDyCjR4V0PpTtoZ9if3g1ckyPyWwPhLosnazkU9RoFUkqqzlKKltbcxVtzHZqK ###Jf/zA3RutUAwxQJShuPI5Hy3p/DqrZWcQ0RtLy+fVyyGcEFN0p4uNGl2vh34vN0m ###PFyXl6HLW6659ymeHTmGA8d2Fbu46JakXtwyRc+WJ1zCganG9txqbL4wQGB8ZpEZ ###D8wk/xuJA474hQcrrTM/+S/NY9+1+ZZXzMvN92M333sKJIGPb9lGrFSK7sCq0KkL ###7kA+0m/eW9qFxkCFd6FmxOCy6/fZl8vwiH/b+I/L6fg6ZO7ucfeZQSD58R+19fq6 ###Gf/RaEDzZfzHMv5jGf+xjP9Yxn8s4z+W8R/L+I8fGf/R7l2fjocdOwSELvfiImEh ###/4c1VTJ90FW79q+2UTdNvVqKg5dpDgyM9K++qlYb8KPfBAkDrwuaFOpfh4fYE82Z ###j3qW42IZNGSz43AH6C58t9/aC89PTt5rzdIpHB5zA1vb6qziN7WpZrUrUVD5WWuV ###5dMa3o3QwWscX/VjFhGDCYWAIfbIj4M4Z09NhKQ5sWrS6Wwn1peYeGEwvi4XyFm1 ###IDOxOXR4Vp45tMhNtSCPzhYpfFYCJ+a5OYbD34H3Eic8Shey+uS0V66UV670VmWe ###+ugnT0nVW/L2jCQ03mpxV9s7zHv+lWVErlXLxtBf43HCHX8fMBWMQALVzHtu9iJX ###/idnUq/ESPxUQlbyCqZtJ6dZLTa0K69TXg6nZIKlC7oohD08c9Z7OT7MJ8/Iy5SX ###i+kWxLayhw5cf4hUTIn8EJLGAF8xCxEor+iuhOubkR5pF4hkML0re8Qgxh0gG5/8 ###HFMaaqFp5KzFPvhkKWH/H5S9B/j0EDwlL9NuyMpBjYf3n5kfFPJPSveEKYgcPmDi ###Paw8x16b573WFcyB+0TPNV7rygnfWlpJzPHOZd47jhvIjGOPO6spB6hSNk2cIhGI ###6J30yhhIAZRAoG7QVsYK0av+oWZaIqSCF5KSHsoqQzKzDgl3JN7ce6sdfKpNb7dq ###Z6TBkcSbFf1No4qLwA308pZdzIrH4v1t9X1utzMz4vf/MJLo7FbNRDvaxoHWllRQ ###gV62tIoL+iuu6glmp6KsR8ncpyoKKnJqhptEislzFyb5KLMqA7hhih5smBSJpwBM ###+upWsoGyVnBtWx9aGF/lJmI1UWgP8o9VUWqW3426XShPd1UXygCvPGnhyclkdnzH ###WUnMYtWsq5jESJMp8yJDuGOv5yfd1zeQTj5kMWfumF6iZZ9KHFdXDzzh2QPixdiu ###Dl+bAXmzwZ83JGfgxwwnGY1BD7jPKqbcSuezqpBks17K9gbpDUDGC9FC4DfDqA9y ###AJxM8IZIJ8fzedGxprKbCgy8Ws6iQMu3wyT6vzgm9c1TBHsCd0URVymKOY3EqdxE ###es6WdXKfi9bFWXU46E16rMYk309/oe0tHGuEyIMLi/6GNX6NZYpS6QWXJIQqJwSb ###CNJqrSzLIeCQ2QnlgS3C8ErCOsYacq/+VaMGE+8MF6dIX9SOd4We/8Mxk3vHMSkD ###XaHrOAfBlW1dZT+76vdG026pdbXqlQp1rbO9SmBtl/l27Hy7llr76ONdMY4tlaVR ###f7hN3WmLQaxVT0SNqPymdWpoYwcFx7Z2MnGM8nPGRpndPq7nmPdZC6GwvIRp7LNW ###xW9mDRsUGjZryk8b1nQFHeS7gmr8+VaNKzhqYfVt8zlXewTCKvAb4+nKP5mcMGXB ###LkhNjQZHt4fXnpeRkuTwFuLWVFfVIsNz9Q5G5SrSreqblkVEAjimDEoVcSZSnNw4 ###eyVNIlKGDexhs5Ex57DfCm6gCps+N+45d2eR02j25g3cYwfffWxjK23P3Et4lrv2 ###EP9dmA80Qvni6slgcIKSc/YRShTOoS/ToWfsHB6ZNc/Q37IkK5cK9pc/3ypuKirC ###TJ59vj1j7Gefb/66c9/g2PDoexxtc4+4oFMNdsWfdqTxsb/7eebr5pLw/OTD8V5J ###OeCEZLFejFtmL4pJfDRDB4vji27BmTX8zBEDc8RZOCw/ecTM05COv6KnjfcsPPMZ ###06H3Y0ZcyMn3yTr5VrIgKcK7KqyjSmpB9dNYN9fp/sRT85N1aj4D7OyD1jWT55y4 ###K+7qCIPhXY+F3aBLTjdOv4sk+RRbxGoUKHeypVE0Bt16Vb0kNBKk4y4wzDtfthZJ ###m1kcj+8HlZcucujcsQfTO4/ti+/zL3fs8bVnRMoIS1I5NSStbj1vbN89eMETeLZG ###Zd1KsBuPy6QkX141ryn09+gqgcv+eBFoWvhabolIakz0xrNwBDCuUTdWiKI6NCZF ###SIdnB6Nq39Ou87Sjkp9WqobDgZ4lCainozV+YI5v2GYXMD7fH47x6aZVHx+JVzJ2 ###h3zwlPH1PaLXUDDGtzbSLbulLItza43nqlhZ9C7Pnt+MXZgyfAJxwEGkKPuFSiO5 ###iOYLp4wd/LCxkcB0HkiERXS/uvXDxlZsETS+v4jBnUvvPteffnKjHTpluTilVWTn ###sG+se1zyiBAz3jv8KFMnpF4TmKJl1tWr6IaNxq78/q+43gFhCW9UvJ+0Hw6PsyqH ###cxN8jzv0mJ48toiiy2X8coMOGJUXCO8PDqwe2OObOR7UNzV/EbGvtSQbPIGJj4K0 ###7qTkLLHk8E+KH9A5KO5ueVizy+06p6SNc7k4kT991Jn0H72b3iTj2Ch5Fn7UZTc9 ###rLSp16oO20XNShigE1X77PwibJ2enp/8Unr6HiZFpmGOBL8ex/eT4aByHo1uEkBE ###bxKP2VVRLlCpnwH/fU1BhThIBaFkbn03UPpIR8ZIZYe9v9j0oU8z2cYV229vHB4a ###/K39ARXzirqYTS7uZvpkYsQzMpzhuHfdG/AKZC7tRM6uwj7l5YjRLx110tLfc9xB ###+jN4jt45HY75/ASnx2tbymnnSL8lOv1WeX26W3dYra9LwYs5m1oZW5cPpIhxWwse ###KJ2K/KmgoJu9Y/IGUk1xBSVaNnShgVJilMN9yWIAdMyRnDbP3pRD6lfAJjE7joBz ###1sbFx8UJgGUKWHyRQrCTofdHPB6yEmwPwOUx0ZWJXUnKA+YycMvu7rPMO8qqW6ln ###9A1tZIVybjN+q44A0sfLnE2WQpi9vYSBaet7i52q3SFVW9aeuc9mjyktawvbckXG ###1Cf4/N2XP6aWnWbmHjFZcQbtyup7WSw9dZTnxF0pZDVvur36cLjpJcUrCqd+d3lv ###im/YrWZ7hlR/uGMIQFPJ822bw4+t7O0Vc1r7My4I2TwNwauQlxmfVlGXMk4QrRH0 ###+NDDYEajdrxWilQEihRWMtDdy1Ax0mCTtFxpkuEWTAfMZDoe5AHF7SjCqvjD1HvO ###10kN8ZuLtbKSRN7ME+v2so2aha/VmvM5IdjpylQTlriRIF1btUrNutF62vHmOxJQ ###+DL4Ye4R82aps96WKaJnbQ4NIeoOcThHsn1SyYQ6DyF5G+p/R34MO/+Do/r1MwuA ###5ud/8KuBH1D+h3rTr1Vr65j/oeo3l/kflvkflvkflvkflvkflvkflvkflvkf/sz8 ###Dyuv5xoZREoMChJSlMekqKwoZ7yh2PlPrz2hG63Eu41HE6/HK4b2HyUXla15dzxj ###cjKJxsBziDOS3S+hjpTWGEvT9YDrUAg6t0AgM0IjorAWzq5EauFXSa1oy4x6VgZX ###VamXAFHZFsYpP8EJB5bFy88dOO4Mxlab9AaF8hN432HonbKXNfT7lmroVU1WoFaC ###LPWZrnm/FB9aT43Qj7Nn3Wbz5T5qC5i1PnTXrRHS0AeMnIdPyRWQlySg9yAzRFpA ###AenVAtA9MTkwfsyK3+8NWAC/HbDexXyR0gyoPSp1vRd4LSTSaTvefbONqJbxgSwZ ###JSY+7W7h3zf4FD8ZZggGDjR70Rt8xoYVJZ5em5ea0B/zRLI3P3vMTWxHOIlphioh ###pN2PoxHwh+EUGE8y5PLs/ZB+T7xONMD/deK+hwZaJqu98i6AQ42BqajqfQcE9IQn ###ckUOBiL+tD/h/fABsLvhoE+yFUhb19cxBtFdPqKxK+ojg5mM4+guUbRyxySPWjs7 ###4fDrVf++pK6tmHXF57P29Vk/oaeA9xQ8u6ca76n27J7qvKf6s3tq8J4aek8yhWmT ###JRHu4p+1bc8OX3zCmL/Ri2xc/tk0rT6pV+7FRr2umSuv30tJo73CfnMJDjOnitE1 ###c61qPxewsGAHitFNe1Iz/ctbCqxcULVGdtsclUk7uosm0zGKAfzU17sk1oEWt1LK ###65i1v9268Ju87zQTrIhhbseTLHFCiBGuXAF0zlfL8JIdJk0prKjkwDIX61/H/odp ###/HEr0L3bM61/M+1/9XrgG/lf6/Bvaf9b2v+W9r+l/W9p/1va/5b2v6X970+1/xVK ###q1qXzVohEYizmZnPp/pqc3NzvUGOA6tK2tgPRyDeH8DChWelCMs/XOL/nWFCyJKq ###ZZQs3aBZL0nd/0i+u4ovr+rpV3tpQkw0WBpehmVi4Hm2FyzDFgPb77H3NScrMjBO ###oks4xUsRHPOjIeoJyP+A808HvYnX6Y07/ZhnuORVW9Ta70wQRQBTYTQ8a5VcliS0 ###GjJ/liQzKgBd6JmLS3d4R/NDx2AvP5lqizw7QNt352gsp4asrJyqT7OfCW1ttlXM ###Hn4+U5rbhsZSbGJt8eDMMqJpjkhK0AQ29+Wv9DKrK3LWsvp42Rr2uxSJ97I1iO+p ###CbXh39CbmXDPZvNCsXTlZKqSvjzsrQrzbX1Lrj1GwRXcBzdx55akRqTUXr83eTRd ###8koCHual8lbu7VXvn/80n77xKuljK5CGuVtVM40QIKmc71K9nz4r93cdoWDJHdJV ###wFIPe834oMKieitrw6jL5I2jwXX8k4c2ip+84H9qaBXUx0nbPj+IRjOCan2/FUEn ###fiMrnBtBj0kUFSgGrnMV9fqaP2f2EG/0wBY3VoIUI4SNn8wAJQ09bHdg9u1A4MCK ###ZtVgWNWSeIohMyrT6vuJj7XGImzygqHMCChooW4YOcGqc8n1vVXMFVGfo+GUqK2I ###2jvWW9KSa8x+JX8N2/fRCI4ZujrTiIJzGuQogtPIRwazudUYjY5gPTLE8iBUsuDd ###ulMhplHRDCAWblDRz/r04a2aLEWJQTADncWuZ7ELemci2lkSm6Qky4E5tfPlsEWD ###JVZzWWI1jyXq7FA3MhZgg7NYYNXFAtHpNZvjLYjbrczelioc9jZc6Bacvf1mNYRN ###5795o7AdvnI9NVKLFfE7wIrndH9K5ZQDLmjhxJSTX14ZW9JdabFyXdEr2RYzo+cL ###VfNdx86S63LEu+fKczkynSWE8WwIOQKuQ25TeajyYG83HMfJiAUImZKcGMcW5ig3 ###amdMxrwzQTCgkOTE4pkO29Sp7bQtADJS9tJqGykpNCkuN6dV+rZw9VYuSsR8GPR7 ###u2i/nA6YFlT27mOY3uBvEy/+Gg+ArzFDUnfIbGRT0JE6PLKbrGcKxxUzgT1br242 ###c/mo8lu2BiWzYLD1YDWfub4Muun+Xnh6cnh84djUQX3eTR3COyXbxeM5u7qAxwFu ###6qDu3NSZmtqsDf38Tf2sXf1DNvVfYeO6dmMajUkLy3cgUKM44BUp4knkz41A//b3 ###f8Bo6E4XI6F6X0GCCaejIHx39vRrwBn3f0GjXk39/+Fz1W9Wa8Hy/m95/7e8/1ve ###/y3v/5b3f8v7v+X931+j/qMlHfHwAO/DiD1A19XIu4qo1H1Q9m6AU3poy+JGNGyK ###XrHBgJeH8KJ+fxQlIkogkSk5gwdvyjoFzlnmTJT5xkbqDRxw4c6NCAr4jQ5a4tPH ###j79PgUu+mke/SF36s8TA2dUWqau2rXm9PqGSh6xXHqXw2WvKrBbGLZwrZMAVNuAO ###GUDl5yX5WH8pZgRyhQU4QwI+y169WXeHuu+9Ux9Mi/PxapfcnzJD34Pubx23cTXh ###xx764gP8Avv7F2etNX19cV1vfg+rwprr9lnPfMl/yksBWYbnecl/Cnj+U8DzNfBS ###VZcF5HhfI5BJLimEBv3jiYzxZCeLZ9VjEmeWwktu/bd2gZzdIeqpFI2DnWj3MbXA ###tALrTsZcFfate6EDctUF9lIh/pLwpF7IX8gCpbnwqmP+qmeZIW/nEiezthU68IvR ###+v2HIyw68Gs5n9AsR3XfyOjY5kb8X9SmfHijKQPtF+tCKEZhdHEYkFusbUUSPAEJ ###zliEwEaC70KCbyNBQmfhAfSp8cLRwGghmIEGVoDi13IuJoKC5BC4MBFkYcJFEa3R ###qP8o7YtnfqOMhwJtvcuoc4v7j50MbG8Px+STn+FEjyfMba4ffabbvs/26xw7dtjt ###PnnD1p5Hq37xDVtzrVBtIRv2CQhQ92v92Tgoul/rLhzUF7Rfn4wFRgmNZ29Xv/h2 ###bbgQ0fiTt6vIZfacLSvyvxQQl0MMdhuJcFhqnyeBt9vlImJzaTpAO8TqUmzOF5uN ###pSHkwf+Ppx0gjzZSQW6L1XZ7y9WPoRF57crb5PDwvMwinRAbPLjzrx/VZNv/6bIy ###CY8uTp8d+FMw/me91jDs/zX4z9L+v7T/L+3/S/v/0v6/tP8v7f9L+/8Ptf8zIYhs ###+4r0OwVJdYOb4i5OQ9isILt244ewt7t38LmGaoW06vnrm0wo3uR/verKt6287sg7 ###BXsKq583tL68dZ/10Wiyv/Ua+4uenxR6xJ9LL8bm3GP6n/2mPgEOuN9ssL915k3l ###c68qvyomyAfb4N5W60qJt6YAnP+tcwBr/G/AJ+I3OMAbcwMefK4FGuBBnQ0WBKzT ###wGff5YQ21tnfdT6xJp9QoyYB9zmgPgfU54D6vph8w5g8B3yjmk5+nU+S9+811vlf ###vmocoV6Nv1vjyAg20z6EC1vA3/GbxkoL6hIIDLIQyFQ3HYF3vW63H4fR1+vwfC88 ###8+sYThOAED4b9zvAr8Kzhk2rfCn9Gsc6n53822jof9dr4m+RJRfDWuTqNQU5ipXi ###/fsbbnjq6Xe56nxl0r8N9/cm/95siu/zwG5RrIQtELDWdRitvw35N6XYDFiz/so5 ###pBSr/qbPr2muFd9JfHdspuUR1d9cfwO+c8zvQVB34/Altz84tv5oMk4+H+/Qr7s7 ###f2+nSHUx1XLWEz/zSTAPSGJ5i0Ild1A556Gf9zBw7HGT6L7+Tlv0cwPAWPnHihKQ ###UtfPCuksuy44ysq3stq+Wtb/Bsb3qt5ecChO015dnFGcy1XqevvKpn4UiKOCc3Eg

๐Ÿงš okay the base64 blob keeps going, bestie, it's giving secret code in disguise ๐Ÿ’–

###cAMe3l9FcNlAH6eyqbWv+BzOGp8fP9YADg5/zYBHnKH8ebOp46eyYcxXcGaDq1fE
###WQ39F1sv4m32ggnEBeIM3TTO0MCYAEdErakfQ4GYQNNoz38XiGo0dGHDX3cvgPy7
###YXz3jfYMjgo/jr11cSzWMhYs0OFYF+8LwjMWQCDaq2kHQTpfg4CCpo7Hxqb+vrnA
###JsGvC3yJ+W4a8Gzo6yWOe0lYBj7rVf1IF/AJeKz+1zXRwK8Kwhcb2Nwwcl7GBms6
###N3BFbEQhljQ39I0fmBvGWK96U9+gfiMDHt8QYoWQ6xfdMHSg2htGIFoQgBBGa5tO
###DicJUyBGyHSSU/ruCfPTUnIUwVEtDicWSBB0TZfqrf4FRxSSTV3Kh64NIwlTbBCp
###eTQzCGKDbyguF1cDbeEqfs29YIIAfGPDeQYD4oRcEQsrFYSA97+RgX8ubVTr/P2M
###De9v6Jy2vqEzRIugOR7WOZ42ajp8vsmwGhrD8v11fUObDELSW01rnzKsWv6G3Gzo
###J6axXvIEExtTMCBOfxVzgwl683TFTa5fJYNBCHyK9QrEOjTcDFHQQd34XjPwKfAs
###TlypzYr94mccYGK+m4Iuxb5wM0SxD8X+rYj3zAOgqu/vDUF/gm43M9qLA6Ch0X/F
###OiAb2vjyANjMoB8p0RgHvdBsTHwKehN0wyWflN6M9RJ8r7muM9pKBn8T8+Tj+IEu
###GFRqTYM+a9o8fblvBf0Y+Bf4FniSB2nNfUBaEuemLrBsbGQcGJa8DmcGSunh2bpb
###UC8p766+cAjU1S/w33KRtv4cbQPWNv/Qg3aYRDFDxdgo07LWSDV40v3fu9NQuLiF
###nelkeHX13HvA/Pu/6vr6etOo/1Fvrq8v7/+W93/L+7/l/d/y/m95/7e8/1ve/33/
###+z9H/oO0NUa3y3AgrKVoPTs61fqSV4lTLNEbjqIxMBgM8BERQ++Ah1aUyB/G3JjI
###Bawj/n0aDzqPcJ5FI84dLyNkPvBh1MOQn350Tf6AwAp7nUQP37GluFJqSIZ+4YAR
###3m4HDw+pg5386fOX3IRz6JW4z7ph7yRFcxcoqQt4WFR45je2VnRvQJphiFgI3/2B
###RQLL6k/94TXI7mVgtP1JxH46W6cu7Pl5L0cJQLqLDqov0umhS/OrZPduwDxO0dkU
###Ed3DA85Ygp+8GDBMBTzhGEPOT1VdaQ3SdaK8WtyvEXN28FErb0fj+Csrr3GBss/2
###tnfx6+l++PEEOMKeEggCIADlXMVj6C5GN0IY7VpJtsFaWYgRzrRUlz6ULqxaxiDK
###FyQBukrC23d/oDtrlXIFYQ72sg7vEZCW9Nu1EC+G7PcGAfxScgCFaZJK2PObN966
###4tYLk2SF5vHMTwlaCZBj7RTSgNEkbOTtGYqHlyAuJNiEVSedBa5wb3YQkuYEruGv
###okBCaZXKGmyrZS0Xlz02okFHlpkA9CMwVjy7cM++PzwOd+FMOzgI3/03WxkTlVrU
###ANKM3AOIKG18eJEwV3kreQGMkdxNbvytFNXaJrL6YHNQvKIVQrJ6ZUjaSEkHN4Le
###/xuztPFr9DdGL/e74RBzg16TFN+NKbMIfjU2WhmlL1QJbkGqAo5Kr3T6w4R8v1H+
###u+sNenfTO63WqDnJdFtoT0BzToH/pmC5jxoLa0sA8FSEvbsRlo0AdgBCXb+H4Zs9
###wZ4509BqSTjBIGEiRE94A5ZKLqm0fgn39o8uWuHB+f5ZGUmj7M35gk5JU5awjC0E
###8PWU5+QuuLW98slD2y9ajRr5IgjHMZAgYLb3lTbahsHqZ021/f7iHfy+f+CLPbRl
###raWbcxeebbpoc89XY82SLWSyAZzshsloinYEa252xAmcFbC17T8fW3uLcvwuZP+p
###1Wr1wKj/4DcaS/vP0v6ztP8s7T9L+8/S/rO0/yztPz/U//tNMun2e5evbt4aVh5h
###u2mDpASC1h5wjx4wgX78FcshagI/L2jQG/SxnENqmYG3wp/jyTG+eITvJaWZySy9
###0S+fcbjwONyBlW9jYK0IhUyml6gHs2SZvXw7jFqdDbuTpWKVJqOkzR9bBp9Tllsb
###2Z9EgKMLafDZKlQ4l5LYHA7gzAC1+g+GP55GUo5SrDhtmpA0nSJ2XCqcAkdPTup9
###jfpTON+qmGo+mXY6qKcuCqkui9q8CDazgV6WUWBQMvBS0nws88t6uYvvhuNHZ5G+
###FEKq1Sfq9BmzWlVTovSwiIeyARIlvbVcT0yOMoajk07uaARn5APox4Nb/cXSKCEJ
###ajQcM9mNhXbL6iRSWVvVMqtcsswql94bdXfAD0aGlXRylbfpxtvpRclneFnmGL2L
###HkKZvT+1p1HXJ8C/wiPgZ0ftcOewBQflJcWSo/3MrpSoTJ8bIZ8L9RGDVInWJ+uF
###X62WZ05PicBXm2KVP9GvakQsGUUPyk5ItKTHaoPOcEpEvO2hWVcjFm5a4MzqsTIZ
###VhgZjHHbPxtH4+tz7KcNund4tiEmBijyXnpBo7mV7jb5m1epvAVtxevueO3jc7FM
###Wh7ZEu2pVZHj/FOMsi/ZqSjJF0/Y1etPYHtFyXQcK9zfYurYjvWQGBwdXTi8GuqO
###Za9J/18BpTj9633bKl6HnHjqzzHTQ5g5xRPmFH5aYUKFjXmqfru4KwzRbgGuSz+E
###u+p2fZW7ogWmPNd9xfMreY8OB5+/zK7L453uvudZCp6a4hlRjIbVEZBo2N0h2yCz
###hCM5bZnNu6BaoO7UDa/wzonV9EYLWicEYYF+C50/Dq+u4Cwo405gY5TxREmshGPJ
###9K79+xTUmW6Zb+kQsz2j4X/LTEbx7pTQfXE3sh6ZMs1nD81VB+et98hpj3++eOe9
###xmQj1vi/DMbXxrtWG2AGF0NihsQTiB/kv8GtjtB32XsIJybAjB+ws9Vx3qtH/Lb3
###gpFk5W0C31Mm2I6uQA/1OlhfI9FIW6QkU0Hc3vbqzrxlFpreiiuSylt1eZ0vOxu+
###2fYaflC8PYC2QdV8rWsBvSHZ0xWZIYuzyPxHdBGK4uweJ+JUppjxbrWy4d2++wMF
###h2qlTh+xnzr/WUP2IArxzhUvkG5Dv4RbWeEeL9RDpTWI2rjAonT6i1/osulz+q0m
###v2WtQQpiPQUxkCAG/OdcEI1xXSD6n7NADOS3Aivm61KegJSA9iXQPv/5uUAHmUD7
###8wAdFCCzGQT07lRcxA/x6vUeC9uRZlUS17Ig0sGBvzqLJPPGcfJmPcd9zk5i21Ng
###yt1XhSc40nos8Ioix6Y8G/op8KpSeq0Hb2S23ILHVIqtZ5RiE2P0OPRZ4PcsUPW3
###2XFc2TZfUEVVhc6wpUqTfN5blkjLHwBY6nE2BxFIItvlFT6YQZUXuMBSFxFIaERt
###cxHXEyRmYrPcMCtXylNXitubB8NBZTrooTG4/+h1e8wCS3fu6tXqMyiaKV0YbDkw
###jr4KCh76D76j4NeoD0qFhBo4lBBl+I8moKb8Y4KZITmRHQGtccetI8yqRmdvOzw6
###+VmrdOaQpRRVXGb6ZKU3+dKPUB6dXlYY1GbVNqlEkvYMYted1J1QK+5H6NQupqy8
###zAQkpv6odIy/t7E9PdzS65cljIASTkD2hOGZo6hZKgymspHWb4/124N+HUsADxyd
###ykR4ElH3vX4f7e/kKzC5iQbO9Xzppcqr38R7VBAh8c7zf7zglUO+t8cbx1eYRu4+
###9jowRtTpTO/YfqUlGAy9cS+5pQv/r/H4Cv2BStMBAeWC5y3GdK86hyMR08HoLhnf
###WnOS0xfNQSFjEeRtPF6qq7I6Dcn/aHtJ3VOKiOoCW0+gmw5L5cQMyL7pI5CPVfd1
###EoH2R44GJj13pmM8ZZ0kLbxJssmT8wibkNTdIPIOhqcnbUz5h9YO+bysTsici4dO
###f24yPRoObyvRTRx1M0GfFw6VKNQl9PUakg4su8hmbdu59YwCgOapp3MLBFoCYti7
###8k480sEczjA5b2XZyUEsJBRxYVvqW08T/BQYmXteZdSfJtwghYUHU8tUUfBnjuVi
###lqkmn/4214meKq4orkkiq7jMdltacVvlzbemXxbDzB4d+2VxAMnil+M4GfanunOT
###WjQ3BeOFV304ONggrwgYYXvbMRCldHQo7BmWSeH3omyYDebCaJsp1zy/8FYuBkLW
###NnWMzvxtXCBYnFHJAO5y++T5U8kwY7lfZsGNnoOopsMZtGUN2J7eVYZXlYTIMTFH
###KnagCEMRh0ut2wsjYD4ZvIczD1nDVGpx+JQo34hyr0HVUVBZTKQT9bGy3v2ATLhk
###VWTFS++w7ri4H+NWUHlN5mDQOnqd7qDsydn5Rdg6PT0/+UUDF0iQXGklOow112aq
###7nrNfy59UtbNxURQdt9Ocs4mZTSEZ1Z+fR9HAwdV2NSgeBsr9KBK7EAMBg1g1dPh
###cFK5w0HYCPxGiPNW2FC0llgVcSdh5efRM0LN6svr+wrIUpOokdO3BILSS9dyKSe8
###gHFdAbH4mcHo6XQ8vBQ1cvefcEqwdszCK5Cb9K7v8HtJJ0TELk73oLV7cXLOneLT
###+eNupwXY/7l1cfhxPzw5OGjvX4RnjSIHZGqDk36RtFHf6xt1Zg9C00upWPOaVLdR
###Ok1lM+As/GYNY8/9Jx/s2joxksJ7EBgPr+E5JaXRFMN7ICjzCvOJI2qH8VNOc5SS
###U62DZU+ucLchLpwIHsaqywDsqS8rU89voq+xd8f0GPIVUyukpwBiYVRxjWlac2fI
###EeXUNJ1yj1NCJO5hvB5T6peqLN08/3XSF8OLK4/0bpVxOeuAqAXrzQ2twzT4wjZa
###Y22N9CHFQdgKrbqCCtUKMV29J0Dn4hmceK7uGnpZbpUoGMOsjIGDZizn9ozTaSsD
###54K/MFSuaRDxltZSo7snbSo4JaZ9ug41rxnlBaPKFmzXbnn5LuxATjogl296Qim4
###8Fp6Lu4g2cE+0zZJo2AeqSAzPE28T1mMDF1w1Ic3LshMpAum3n5/csKd1qHZhhGS
###ItAglkPO/TnEbkL2FnR4X1voeRlXhxu38u/5yeil2joLXuQbUQb57cuFxKHK7H4s
###NBlGSJ7f3lAYgfi7O86JSiGzllqr0kCqHGguNYFe3c4AhQig2hanXMmrvgoaNAQT
###EehcZTKPhnb1uHYEVimoN8QSuUXZhKj7lyyHYV2tk5DpSpHvvXCc6VmX++Yi3e4c
###Xnf/Cm53RWpED/pljxg8OgHBB+uuG8m9jKFURPhbpmdT/9G7ihKEKo3bUg58lz/Q
###Gx5w6P2De+BUURupYnkTlSLFkBlxjdywi15Jmdo3H5HR4ZolQ/zDNVbVZnxK3S6N
###8Tnqd6GrzbDfdbmDMl1UmDZNbjDoGyZ6lK+00vSawRWaC0Prim5W9S57kabUKhKB
###YWdEsr7VTWi239it7jemQyHsRToUh8yC4dKwOZXNcDMzpBRtTNGDa/pHaH7n0Wv3
###N/FA35yPGEVCZRhVgK7ENDS9BLdFzWFq4ERieAIahzaeoF7NEgfFUG9w9Z7W8QwR
###U90umtWCvnySyCsTBOWZ03jzRrdYfTOWeRYHMGFCv0oS7XSmYl3nUT/S7dNFRy73
###xdt84UBpJrmdce5rTQRkTirMGt9FleKmT+UJl49seiQwR9eGiY+YQVE/THX41fnY
###BYVfGQ6416BdRMA1YxC1L3sTioShGw1QOO5W3VDCQrItU32oVg/on7WmVJQJONMo
###GlN4kOYO6/JyZcs56NsutZ1xTFHj7IJFHCtSwbD4/9rav0IFnr9a/Z9kehcmv4/D
###5KZ3NVlIJOis/F81PzDq/9Sr/jL+cxn/uYz/XMZ/LuM/l/Gfy/jPZfznj63/0+5d
###n46HHZHwa0UV52XpSRKTMRcMsWOSl9g90/SO+Ai/Q4WPkfc1xlghZr1iZSsnfpPe
###votu4RACqRb+10MO6OXUw9QtPal1SxPaSjNLa75kinHZEZyzL72xHuCEuyL9DjtF
###7s3z67D55hi6FDOS3YR6K7vigo51zKpojUajfk8wXgLwCQE7Lx/KWUE6rFQpX6R5
###/xWYtVnHVBn6iNnrZSnTuYBwm/t6ZUDb1cQ2+o2vmQcgGfxWhJVIiWmBt9JvAHSl
###Yvh2c0dOqmPfwwvEQDNpqNdQ5C8SDr9e9e9LzNb4QD7a4q+qtRZ4b415fqef1fdT
###G4vTi0lxETHcPtjApRRJq2oB4ClZLUqy9As8JoAC07eDIy7Qf70cx9Gt7WwhEToT
###l6qLqMiSlItE/QUDkdz7cyYyM3CCVkQNL4QKEzlsEMLHX2191rQFUlcDwevhlRnV
###7dVNuyeDWJTa7sdX5KAFgh4FK+rW1rkXqziSnXhVvHbwCCEvDQCO7v4jdItH7/Ah
###QE8aFH7vIhP/Ix4PvdLkfqj9QuL/ZDiJ+quqHR+hRAe+Xa7WZm32edbDWIt0GrwU
###dTS+Jo1A4pcdGRQUIrkaP8HQUoS8DDpZ2nIWY//pxqh9qvlKO9/V/uMH63U7/7tf
###X9p/lvafpf1naf9Z2n+W9p+l/Wdp//mh9h8119ceCUReKhCxfT2KHvvDqKvbYSzh
###Scm6zp65spfACOWZ2dbbBbKWuByOxLDEzYZ9fdjdybhfzh2WzX7sGa8/1RCCp8Pu
###kNSO3KQpGPk5QVFBPVGiPp6M3BKFZ/cMI8gt7PoHK+3I6PiofcCc2zCRxtHpbnhy
###DuyTPGLwWdX5cMthX9rwXnYub7GWFOWfF4rMXvz7NAIgfgYq0tN84I1/AktCz9Gd
###gK9B5S215T79+Cte8HfhdE1e0ZND9iX1anzBWx2BloctDrEQeVnFL6izuyd7RPp7
###h8hEgJv+KnsfXLJwwGwv2tfpdGgDIGqy/eOVSRJ+GdmVUmxb88IHYlri2Sih5rs7
###agYKERqFj9RtCEQAJ8loDHJMh6QHnr5BccLVsY8dBC0N7afw9i7z7Aw+M6OIDTFS
###wXCMu0CB6vDK+42JSJQzJ351/aoMAkInYkIlih5Ar4Cxzg3ml+6WvS66iIIYjMIQ
###azEa9g2vY8woDsJOnJAk04lY+rNR1LkFOaY/TBIRnX/VGyfCFYKZaSMvuafE49aG
###ZB55NBV6jUW3h/RayPLDobuwkVjLsVgIMsNWAJp3XVPglUGyX3pDLnmafUVkRFDS
###/qW4ASGKdqSwinKJKjbQxzJxlY34eWyHxQx6w2lC3fhlKZIKfzz6uThHddlCTSJx
###R7SrnKXHA/MZyQOEKUfqUciiHv6rVHDIR2/Zimgb6T1XsgddNaw03wxfpudvweLb
###sKqzYvc+dHrDicgEaKnDgJoh2zI3Uf+K0VESI7dkP5gw3sV3ndHjTBjzGYkJ9UuZ
###VlE5jkxPaXt4fbnyGVT2EILBtDizUHkKcKadT/u4/QTiEgfvwKa7g4keQ4DQXt7H
###DyPYWfG4EMIUeMs4btg6AEk3RNFYONjP370/b/fZbCspUKwlK0JEY0BCchTVehKd
###QWWIrVkdUGCrvZuEyIltrKnAoFwwMB6gODecjtWHDKvUz5FsL2rFZEkNOqAgecSX
###w+GtR/1q7qBSTJJRUHodThPA0/1z1skXitHEM2qU+sGDDD3m1gY+ooo503vbAN72
###4MZ/hw8pTxZAAIwEhOGS7ToFcDokKWYnNFGwDK056dax75fp68D9e6lDq/BLTtH3
###GQG12pe9nHBjjZUXploYwQzlK9RDBh5DCu0lbG6tuDHCmiBOFBqhq6EknFBhDULX
###4YNM6GSyfyOjrUXUWvVYXdCRlG1zUGi0ajElxyjKolIO3XSNXhYYRT0KHAKY3A96
###lp0cDMqIhjwfWNv+3xsMQCpEW1YIi389iLvfuf5rfX29btr/19eDpf1/af9f2v+X
###9v+l/X9p/1/a/5f2/z/V/1NNE81iskwhiYleJbcT4kv2C4uE/Bh3fMv/EQVn3QHQ
###f5IT4syhgwJDBwsY2sgaiMgpe86hbYda7u+zmKEzXC9paD5fkSx03lm7bh1cydKN
###TDCWH6WZz43eMNzBKBxwelfW/csYNXEnM7a+0pzHcilpZRpYFD72IyLjHPFfw/Fk
###sQUAZ/j/1EX9vzT+K4D/LOX/pfy/lP+X8v9S/l/K/0v5fyn//wD5n7IMYOYEZEUo
###B3klTHHBjpX+OI66j/D3bohZ1+Ep7HCqbZas/sTkQXh/B6tG4LU9/HRSGqwymQ+j
###ukQH6puGPInVpYZj2QG8/z/Bqnifp8XoZ/XA3n/6P/Z++ybGnKk3MAROyruZTEY/
###vX4dD17d9257IzgyolfD8fVr/PaaGoeEKHo/R4FKXaR6AsP0InwVhd5zwtZeRmWn
###c5L3YcCR8RqYPH1whk/lOSa97HW1uDBRpIrfYQnHA3ZKCNzH/ZiFKOSrIEdlt3eT
###91FVPJ6m3vw9w3NKCaPrDMdjGCglmdEw4UezU39hOKd7xi0nwnpl77d5qhn93Xvr
###pWnhtUdHuY+24VXlzvoTJYFll378QgTlh566QmotDEXD+rutX8GCCx+MnhmDglQk
###epSLfPkoapWl1Orx+3ZjVD9zVJaXeNuLaGyj9sJvCAsrkYJfWNIW78UL+Mbee4Pv
###/UYhRN5vRvUU/EdPWSSXxwb5DW9O0wgrUqlZX2bOZUSHeHlbfOUvy1d75o1uer9o
###jM3oR104a1hzSAVQ9oY22jfV5yqt/3AkbsQpj3ByiwIXOgGx0gUsNyX6ceJisZZl
###xc8KxDpvOMCtMQLu7+2efmBSHQujEiL837nTiDIS31TWyv+d3wMXX3l0PVBW9++8
###+I25tJJAsEHwVAJ5JpE8g1Ds3NfzE8z8RKOG+H2TsgAcR/uYCw1kqxWq94GK5nTA
###fJfgM1EEifiXj9zN7iHuVsjzAEim1zf8fY3DrBsL9sCsbyXT99Tm8FE50/W26On2
###1Ehs4+B7yuH3RJvcUTnb87fo2fjEof+e43Rc9Ogsag5kx6X2Ez9c/42P0HSP/OAj
###9O3Tj9AnH6DL4/NHHJ9vn398vn3e8fmsw/OvfXQK5biABhdGoA6ytVbPv7wD8Duf
###f3lHwZH33Q4hx8VQllo1r0qVMv0FqyxHf6LKkm6m7I3kZJhyB7jp/9sy/+Pc8f/k
###aZmEPA4n/LTzneP/g8Z6rWnmf/TXa8v7v+X93/L+b3n/t7z/W97/Le//lvd/P9T/
###jwlBdHOlaBBUekiJcd7d8UE+okoxDTjqUBxVRNx1ptkENfa3tsH+Nursb3OT/d1o
###0F+/yuJSfL8pwzj9GnMU9OusL7/JvPf8ddaXv8n6Dqrse8DHCmqbaSioz8cP2Dhe
###nTsfNhoGHLzdJu/bT8NJ/YCPX+fjN/j3dQ7fxjqHg48fVDkcTQUOPl7Ax69xPDT4
###9yb/y+fmbfKxqgo+gib7rcb/NnibJoeH4zKo8r98zkG9qsBRNeBocjj4702Oh3WO
###l02+Pn7VhoPjMsVHjcOxacDhc3ysK3AI+uDj1tZ1fDQ2dXzwPv3qugIHH4/j0udz
###8Jv8+0bdgKOejQ+xPrXAWBcO1wb/vtl00MemQR8bGfioZ9OHt2Gsi4GPZsNYF0Gn
###NQd98Gecxv2mgIfDyWkrqHK4/A0FH4GBj7qxX2rGuvC1r6Z9+D4fT+7fjQw65fvF
###33TsF06X/JlcF0mvTQMffg4cYr/UjX3bzFgXlU45/gM+3zqfP19jb71u0CfHeaDs
###l1rDoE/+fYN/5zQV8LECvo4B7K+UPgQ++N8ah6POvzc5Ha83DP7h2i98HTgOfc4D
###xbr4m4Iu6pKPWPiQ68LHrQs6Wc/ESwoHx7/ES2DAIdYlkPTJ1qXuoFMOB9+DEh8S
###Dg7vxoY8Z1I4OP45baV0KtYnMPDB4arVHHxMnHMNAw5Bp+s5fN3kY1l8XaxH4KBT
###jm8BT53D0agZ+7aRzU/5npf44Lwn3S98HapNna+r/NTb1OlUrkvVwIe5Lgof42ua
###0qm5b83zxYUPk3/w7/UNgz6aBh9rOPhHYOxfc11MOm066HRdx4eQgyQexPnC51qt
###Z5/79U3jnBP83M85bxsGH+PwcJkq5aN8boIWglSWSs8341yRfKyeIY9t2OecoFfJ
###PxoGPBs6PnzfIY/xfcNlBX+9YZxv6zly4box/mYGPlI+Kmgz5euCbwh8cDxw3udv
###VjPOl4Zj35p02jDkwmb2OSf56YaxX4IZ+8V17nO887M7haOaAYfrfNnI2LfrBj58
###x36p6ftFwlHT+dl6VZPbdf5RN+SPzXz5w3nui/0aGHw9MM5/Qac1h5ws+Ommvm84
###7DY/dcincr+Y8ljVkE+F/rIp96+tRzVn6FGbOhwuPUrwVaFHNQU/5883mobeoO7b
###DYOvC34q5OSagY+GLQfJdWkYcnLgPufk/g0c54vYv3Vj/wo+wunTF/tFhWPToM9N
###XU6XdCn0Wj5nRXZI9Vpf5xtyn3C69AWd8t/rSqojc79KPGxY56sGR6Dq2RvGPuFt
###ucxSjJ+a5/16Bv+qSvnH5qe1shsvzXw61fQ5U89uGPvFz6BXVQ6qljU6kfqdb9DH
###hnHur69825ppMunt7h2En3Y+e826bjOR9C74Y9XX9FixP+T4jZTPStgbNV229jf1
###89xP+RRbh03JNyQONze0PSzPQkFTgsYEToVMVVfONcGvpd4m9Kh1/ZwR+rdXk/lJ
###JD44vwwavjw32d+qvi8FnoRuvqHsdcHzm02dthvGmRnUDbwousZmVef1gpbFGSRs
###SA1D9lb1Fd6/pEuhRwm9zuPveHUTH7NpKgjb+0f7uxdEVUGjaZriquWn/VVYt2Bj
###1UD7K0lC/BXiizimNhU2I8RVIUoJ8t0w1OEN49hUWLfXrOvHjjme+KvMQZChJKvq
###ht6/2NZCpBHql4BDHNsaSTR10aZa18nMwJP8W1Oz1PnF1sE3VH9li3gbxjYWR3p1
###PQOX4ljyLXyI7STxId4RZizBWgJb5JLr8Awak2xk3j5UnAqVRLA/Aatkgzoe5Nbd

okay bestie, this part is just a big blob of base64 source code from Appendix A.3 ๐Ÿงš I'm keeping every character exactly as written so nothing gets corrupted ๐Ÿ’…

###3LD7ELgSZgKhDoq/Yg8IFU7pQ6ry0vS0brDyQMepwLXCMiSdcngCgR/B/oUKL9Sg
###wBbJJfsV4om5T8z9IsQrT9kvflVjvxJWgVtJY+u6CUxlf5vGulQNPAj+Io843+pD
###tEnZ7obxvWnwhlQNMPmHuU8t/uUFZXOPWmub2YeBW9FO5UHi6BIiecPgSWL/VtcN
###80Rg4SOQYoqg+UBfD9+g51rgUJUy1lDyN+OaQF0XjlNhLpT8o27QhzhyJZ0qovBm
###kMG/i/MPuV8kL9TFabFugRBzG6mZKcVpoIsBQoX1TXO3b/AT1VRbNWioapxVBp1K
###umnY54s8M/V9YvPbQJqFLdFHiDjrGX1t1A14A8e5v27wQt1c4W8Ktaw+j9giReF1
###4/owFf34mnE+GQgzszBXSDEpsM8Tjhu7r0BTH+TVpNJX1hlt9+VrKokUAT2F9zl4
###ibMvoYZupleTaR/1crG+hKgcyPMmlRVEH+vl+eBSeJ9Ql8Rfv164L7m2Uq7Y0ExJ
###0hQnRWG7L9lHfUNTiaWqKmha0KcNVxG63Dm8aNPVdiOPNPW/4jZFLJUvSaRhg5/R
###h5xO1biFExp4kT7EX2GxEZYhQe7ryjHEt++svoSlRmo+6g1Is6bfFmX1ITR/oQGt
###r9vaomi7MWNu9YbFuqUYJvva1I7UvDmaljLJmhu6aCHZ4Gb22kqxQIjrAmcN/UZG
###HNdKH7NI8/R8f094XNSqOllKo4C8xKrqxpN141JanAZN5SQXu0gasJvGRdiGZhAS
###v+MJlpJDYJxuVUl2qgFKOH5Ig5CvSs9NXWIQFw9iTulFhIky5mafomxv/+iiFb4/
###PCa8YbZvf91AXNWwQNRNi4T5tyFZn23FrxravXhHHDGbBgtO91GtrlqPVH4UJpPx
###tGP89mnH2+Zu9kKeE64z7cOjv2PkOXr9tC9KXvUVshFMsOp+7r+qeq95K9nI4ebj
###esBPcPNRSqn2S4q1wvUwo0edLZtPzWUuEyqf4v/NC32E6IPaWUgiqHz/7/p6s8ry
###PzVq1aC53viPKnC1ZnPp/730/176fy/9v5f+30v/76X/99L/+/v7fztyROgV4UQ2
###o/8DzXpYFhrFr3iglHULDx4eeBJPx7PDX2CofhJb3R6dPqfbo9N0BtKBfYqB22oV
###XxxAPqaCCGGcYMoKHDPRstyyUZJ4Mh1heSgqfq2VsssAjqJfR8n+oJORrulpiSoo
###5JTqkGQE62YE4W65Z3T1V5hJeZ6ZFOn2lMr5tHt/xOFd8jwEdYa44A+9yWMWooyu
###CFG75QUjaleCMdeSI4BwrvYGfdxLrvkd7Zyff9eZ6ep4zUqnfBGNr+PJOVLc5Sgp
###PLMVVoiLyjByoPGRPkWhvvEGTyd1LyM8Hud+mlbiaUPXEppkjhqVBs4IREQ2g7/N
###NH6lWSyflWeByKiHIYqZDjArxdP/PWlZyzNBZO1BsHzAzNdjRF0JXlxdGIh2M6o9
###GF7eh6xUYHkWiAf9iIptspqF7CWU46Nptzf0LkFcv+91CyZIKAgilkscxP3jy/Js
###WqSFZu1FGvFn/SsIIuhHnThkjNyV60Gw+DEWVsTU39SA9ljlbbJ7N3gFWsTexS9W
###x9teSuWVt6zRluvl3Z3z2S9DI/vl1ukhQm6epfrL2Igd+0jNdidAsoe8wqXamd6J
###0qid1xfWLp3ZV9oor69unPTGcdfsT+/LaJTXHyDxcLADVH6wv5uHadnI7mLA6TMB
###nGZ2oTbK6UKAnNuFaGT3wze/2LScB2DyDZ0r2G/KPWkSjXywpVbTU15k4PWxPgII
###n3HYj0DmFKWT/xNzhrx4ob0xGoNA2u8T49lmOUX+oaX8cRPzf26bvXwN06fGGFyY
###fGv0zrnKLtVrRfsELhltA2R5xJ+5Keau1+32ycZAJx9xRFFQ0Ui9gzxgbTtDovb4
###uesATivFqXSG+fvhj5l0ayd+HJK1pZewOnnefezdDoBpC3MUZnmC/w2GsiZq/5EM
###TV1WRVZWlhWrczm9umIShrvib772xeHaQ+XjDiUxWRJXx6jBep8wCkfYti7/0AmV
###EnsJCyZLJJeVrSMwjbSlMnaVNOQQagO1sMLTkHM6jke4JpIimAmS8A7L0o0m0XOR
###U4j8UpJ7xmTa8cSxxlfj+PcpIPvRW8BK25O5MidR1pgiJ2WhFT1/gnK7dxzKyfeY
###oKKLZVJw5a0KzfMnqVaGpT16F0eY142SYl4BwQKRPmOSKrNjWusRjBSO4nHHONNG
###8ukpPEQj8XX87Nmh9udNE+hqtiC4kCUkddNYPEMDXHWIiPlHJ6btWlkxz4Rvf2kb
###zpOMOLZ0zaRqusM9Pgn3z89Pzq2iOwMm1SXhJL4bZcgmHBqQHPinf/4zT4YwJIz0
###wSr1ni2kiMNj2y1uHA56k17UBxbFky6KswAvs2CREIRXeE+AZwUdm7HCXYd3XgoJ
###KGp8sBwhRA4AqOpNdMJ8lT4ksii7pyxPjJfoPFAtY+l4RVwxq7LyibZAyuwgO7mX
###Oe69BLZ4zPLLwkINx3j7NB2J+ZW9DZxTfcMjzp6AHspLvXtNc4qK88NDCEdounKf
###vZIXAKjvW7+EB+et9/vh0f7xzxfvwvdtb807aoXtd63Tffy2ylvhqwft8O/v/tus
###+mtgkO0d7p1AUzAfbrmsyhlwvyTAoaEnSY1+2eJW47zpwlufnbPUptj6BSck0p2o
###/Wkbxqw+rFEzyoohy4tIC2/g8KWD9rfIFj/IQwONdwWsbRJQ8YGQqhuU5OTKGkbK
###Bryr7knpu0vfWSm9KfsJBHrqn4leWNxe7q15dpSLEIzCXTaSyrSXsHBXxp6rakW3
###+fwuvsM0MmdgbKyysjrWelhaVdTvTPu4/dN6b6z7hKkoN1HiXcbxQK5Mry95Qdw1
###AXfS697hx1oQ+s2S8fhlFkoLLolrPv+SbFubr0l2vnPZeLredH7MxnupEZyusjxr
###erNmlpKcRY02DRbiOsRvAuI9guvovCYdcp6DJFWqOGvS1flvtsRnCBwZ8kZxsW95
###0ZUlRDpFSIcKhDXaBVwo1uljGxKh/tA0Wzlehp1HGXM1knS1Cwq2qxds1ySeZkho
###Ck72j3fD09bu3/cvwvbhf+8DjuDDh9PTk/OL/T2XXcrGzZttNjt9DM2qeUBWJ9Ds
###2JtMpclsfRkm08urMbTSB9qmgf4vbMyf8t5XxRZxXAhGqHWoWkOyOmO350enu+F9
###b5DR6cHhMXCcw4vdd9Tw0+ExMIYwCNsHWSNk6w0bznTkNkSoMg6nY/IgFfDoT/wq
###TDE83qEm+vBOsf154zgGydcSZtCHccgb6+Ziy6uFKArfBJy0P+wcnD+NhDAq6DvS
###zZ9JMt+fWHLJZMXVs3EGGDxhy/mOYXKh6hbKsTQZ966vQbwZxPde+/icDHxT7pVo
###FVKYZet0JW5X1+af/1S++oHxveks6eGm3W0vMO0W6sO6at3ONX6o5AIzRG9cPAbH
###5NNJxV9I7lNEOILuLr6DhorQ1r6JRmalZ4xfwqN0qABB7Zhond/hKV0ITcqzOuTt
###inSJCEiO22flGV2Kdjl9WvIbeuP/Th742X3qDQtDfHT66nAAXCFsM1E4C2K9nd69
###2pBqfu9Mrw4fPMdlctX9EmfL+wN2dVTsJZfDi/pSwU244ta/BsNB5Y94PPRSbzeV
###Tk3MH0XXTkERBYkM+KmKScgOgOgKBgjZ/uCv2S9xYnzVj67h49eiY9GmeHUUJZOf
###I7zxxqIc5mtuCJFMs0bLmRi9RuR4jY6IZ2qFjm2v2WjUmluZiGz3roH/XaBDvzHe
###xa+nKDWGH08Od/fD1u7F4cfDi18V7dJ1aHnqtdq8p5vZVmWC6vH+L3Qs5slq+WLU
###D0fGny9NFiIa46DUjuA8VQWIvdvrTEAeO6EKKoBFEMtQPDs539vPERlHCQ/dwk3x
###QgtfgzV4v7NVXBx2wAAr+TwYPu1szRC0iGxCWQUH9MMPO5aQ/dLauZlis2eKu1mD
###ld0EnHGS9ScjPDMzROqji9Pw/f77FGKXOK11FzEClPxM767F5fPZHd1FD5yU0Z3F
###7AhTKtjvP3nzfjdNYzZtLlwfLrKfUU7OAepuGuLCn20Kq4YS8Pn+A3v2oXVMUZje
###5my1DVYwJDep3iTReNV00MOAqQ2DQXGs5cAfLAb+94uBv+mGfwEAHi8GwLoJoKGU
###7fLCddHEA9lsAhoZqzj3FaTErlMly2Y/xpVByn9w4TK522px2+y/sI+925ha1Q2o
###LkcZ1xIoALzl3oDKT9yKmKqw6jNP3z8MQZW3REz7yaTHAj+tGXJiRUM98KDdk/en
###R/u/bM3q5uIGJP6bYb8rZORtR5T5RllR3nM6k4e4ImrbLyWgDAAGrcbpSxv2S3B0
###JaRZZ/zb9mqCtqG189yG3wekOSZ7cT96jLt7caeHIYmaRmG/RH6woBuNhnjN10Uh
###I8nXDuEl4BJn02gwORreu2jRPRLJL+/bH8/C9nT8tfd1OE6MSQb2S/fRGNGp6zgu
###8BTGrZFb/dnktrdYcsPEFk+lt42n0JtffQrBNf7FCK76FIKrfweCa/7lCK7+dIJz
###0U4Bigv+PIoLnkJx/g+juI2nUJyOFUCTucifWuenh8c/hyC1XxxilPe5uuRZlLrx
###l6PU4BmUGjyJUut/HqXW/tqU6jf/PFJ9FlW2flkwVT6DKJ8kILre+lFEidjb2z+C
###/+2G7YvWxX77r02lteDPoFKpNO0NMaELD7S86V1jMhNmhIolXXiw1LyIM5Vw5zZB
###5WfVxT6HrrhifdcboAZXmtW+nDYwrJCrWysmRcafeoMjo2x2lt3QwN4auVeZhKoP
###sZsReLGtnEhcFbWvT3NQ8oZRrGGmIttq9nVszibk/TGXsLQr+pfXX9bGeuPaUd7s
###/rJI+A1S/Hpz3UXWef1lsQ/oT/MzLtpfFslAfynuyFqYdprXX9ZGh/7oETygdflw
###/vHwI+aO8bwsu82iMgl8hywCT8kg8LRICpxiiFFA4QSPOBxODVZBfowt4gFWzOym
###zFfaPXf1CFkZiwm/m9E/b7PCPVMW4bz8c8AIgNCveM0CxHMOuyXcOW1nm2e1IRym
###2Zwx3s8Yo3BHnzI7Wsl/W1raP+2U2Bf4XHI1LmPaTa8i+X8pazHKXkCeCWWHHIO5
###n8n6rjoMIyYNsnzrBNcRA4MWQ7yAhr3WGVNaN/Si5hZECtiKHzo93RvHEgt0MnT5
###AopW7HKdjSTRh3c1dBiuC/QIhGZiyMZMXSCmjNbJDFu1zmb+3Px/dv5HVvo2HE2B
###dGmi4WV/2Ll9RibI/PyPQbPuVyn/Y73p16p1+N1vwn+X+R+X+R+X+R+X+R+X+R+X
###+R+X+R+X+R+/f/5HNX0iCUGUFNGdjp48e5iIRG0/e3Wz6JhR303WF23mZLk3pS5y
###efiMl+Bf4P83+BD/MAtsyiLpQdMoLtcwBvclUFbBYpmifb1gYTZnlZCVb2UFPpEv
###v9rQC8MFwV8CPlEiQhYEFSULNvQSClYxv6BuF6A052KlujfhrTkqpBjwiUohouqO
###gE/AJYoZywppPxh/vDxEIApEbuhVrmSVlIZR4cR3FVatGnAuAD5e6UgWTvTNiky8
###zkKgV4jC9U/rOTT1wrv1QC9AL/acLGwoCjyqRdKrGfjTKzJJOKtG9SNBY6KIel0p
###GCwLSjYNPK4vYH0bRvWhzbJKl6JwcFo50C5qKutciMpANaNgvNw3VWPd67P3hwmf
###qP5Tb8qCxgzOmlbw2F9Xiq6KaoeiPMymXmVOli0RZTFEgdfAt4uuZsJnVnFa1/En
###+I+oMtZUS8MExl7fyOAzTWudnfib5/ihghNYBGjTfQClVXf1cm2iUImsuF1tzF8L
###qMBfRx/aAsjyhrIa77qsyszgbP658IkCMut1o+p6QyvlJhmUUmk9LVpTc+NaVjvP
###qEukHGLKb/oBLgQMAZ84eGTZyHW95N1G8EPxJ4v5iA0omI2obiyrLgd6FWClUq+F
###P4GvoP58+GTpw7pefViWoPON7+t2MSBZRd2gAVErqmkWKUr/pqUBZR0rnUEFRhlK
###ASeHSwpCgi5l0SK16n1VhysLn0/An0qr2txE5XQxtoBXlFHcUKs5GzgX5SBrRtVz
###A3/a/khpIhc+C5+NhrH+aYnGtP6SWZawqfMoCa8/kwdAm1wGT6b4fvw17idctQiQ
###sW8iX1/5hyo4+XrNMlE8SwjAXCCVfKHu2zWhzMNQlEsV6yHOjHrVKLEpBIVNeeBp
###fRacnzy73FOUpc7W9aqdKalXtW2XsuS6WglVZ+eicuHmplbZT7LRTZ0tpdV5FXYU
###1HKnmNzEfVadiWme1c8owhglvQK9krAoTSdlCc+oaCvaB47qkaIq40Zdq2OWlviq
###atV5A4UEZL9y3HX3O4LFiUq2G4r+InAn5diqUemxqddmE/J4w6GjKUXWNf2lJmD3
###tcqonlJI3RM6jZ8Fj+jL12XN5oaNj40NXaeQc2wafQYSvlRnbeo6jKh3V93QqzEL
###eVXOve6oDCrk0Zq+Dpx+5dEi4N5U1kVuU7+s6XEWjuuGTF6zqgDLqsf1daOCrdC5
###6obOUHXJtsbxUpXVO3X2syHnZq2LKHTf2NB1PFl5vJlZFdmqQMphlvQgKupuCDbe
###lJV20xKODanfaXQhZf0ClUHlmm7otC2qDpuVdeXc1Sri1bJO8xuGbl6bAw6uK9YD
###zVYgqxULPuvEB8eDqPwtdd26VUbQ0mMLc1DfyUE39ZmJOtSNqsFBxQ4RWmHVwUH1
###op4pBzX6EphSLAeyX8lBm26uE4hV3ZQHtGUh8OoZHLSmFfX0hZWmqVBEUM3oQ8dD
###YCiAeBKmmuy6UWO95t65Ysf661KYsk7tDd8QPPw56u8KAVXn9rLWeNMv63MuUFtZ
###WkZqugVnvarvsg3FciNoSXA1Sc1+PkfTTgOBo2bGaVC1hClBR7NrPAfG6SDWuFqA
###gzYNi1/NoJ88Dhpo+yY9UTfn4BjrBgf1M8efzUHX9TrzYp80awYHrdlVYIW1y998
###AgetGyeZb6xDQ6/9LPiMr9CpkGYtC6wpcQTP4KBBIQ5ak3KZzkHrBget5XDQui4X
###mBxUYEqTpzd1TmHJbYFeMVz0re7UoJ7BsWo6xxI7Q4zZaDpshEFGH3Wd6zWFPVKR
###22rGpZJFPTV954hTQVGHpQon5ER5OqzP6LOpcFBDxpUctKHvfsnZmgU46IbbVr8u
###yljXpAnCPlE2Z8pHuiyqyKBSLqrrcxGnlOSg64YsFhTgoHVjbnVd9ln3HbpBw5B5
###AoNzBAU4aD1DBq5KemAcIz35Us4l5PpmhuwbzMG5fOMEWddP3lz9oqHb232j/PRc
###cASGDlI37oNs/SPloDX9DjAwpbf6AjhozcVBawZ3qxraiadrnLJ90CygxTcNajZl
###UNXKUdUxkKmlmhx0fQ4OanAUebHQtIuMWxzU0DDFjhaUrHHQhrGb/Iy+NvU5KWd7
###Kh83DC43i/v4ZfNmV1ochLwgLEd109pQn81Brd1W02VDxeKV4qOWUbB9lkyo7LKa
###oE9h9DRu/YWlQNLAxhwc1Lgxk6dD3b7Jk8bJum418M2b+Odw0JquRcvTQtWeNw0O
###2ngGB63ly8LCkijGUmVQyUHXM9b4CXDIvb5Zdp+eG/L0tGXywLJIzYBnDg4aDq+u
###kniSACNdN11xdD6ajtPQb1AFfxF6X7Bu8w1BU0KKFTxA3MwLg7kw6vsqfTby5tO7
###HnCbfN04CMQiePVN7RZTDipuEYV5WVG6hbkrdQ3Z0DejYAqCgOr2rYw0RwlXiPUN
###/RZALL5iGhciTopUX3ehEcQgFBNFmZTjKv1qt6G+cZun3BAIUUuaVpu6OV+aXqU5
###P8BF+Y9/03+2///lffwwigbdePwMl/85/P+rjXpT8f+vrf9HFUR9eLz0/1/6/y/9
###/5f+/0v//6X//9L/f+n//yP9/9u969PxsIPBnRQEQOkFe+ORV0prXjMxadU7OvWA
###oDHdM0vA8HXY6zKRPhWlSlpYtSubxMtobBW8FkHiaffAeIAH8V67XkmwEzgLKVbW
###Xy0UTK436ToqbYtgch6WD2wxmru2tpGD0C6YjsW+AalGboK0sDcinNd7K00eR3Dw
###9vuPokztmKr0VhElzlk74t17VnQ7G/+uN4BfhoOYINlWoKqIHNgiTcfxzk/eHpwL
###JDooUcJlACuZwCrQCYK/n1PxtPD85MPxnhKUvcoihMuwjnAmvlJKTXo7vYhOYaVb
###rxMNaHFxmlMYATVdTgxJQfzDaV7yeizPes9743VhVj58XFvTQrGj8Wd4/IXl0iil
###pLqaN5sUVWW1gzTzg5nxJkXt2rbasOggrgVb1TOqiMnQPEmRfupsRA9ygG8r//v1
###Px7/TSLYYjTAfP3PD5p1M/671qzWl/rfUv9b6n9L/W+p/y31v6X+t9T/fqj+x0o6
###UwB4+iN01hvE+m9KoDgfLgw7o/40wf+twNkFHMj7r93/AmVEjAKS/mkv7sSV+x7w
###D8wtFiGvG41kadjL3gQDGZBF3mLGJGA3PBfS79Ooj6nv4El3h0okwUStRGEk0Cq5
###mNj92PHOZ++idf7z/gXLMAUbNWz/t3LTJONvq8zRYLPO/vp+gz74Nf53nf0NGqwh
###5lNTO945beOVSkGw3hcFa5ODBaIiA6POwdng4PDvtUZjAWB9KgqWX+Vg1DlY6+xv
###wLEWcPDqwRzYAnWDaYHH5xyeM38GPPJeT1w+b+hhAOIOj1/gSgfFjTpdSmItaaJl
###EqJAlR3HQ5FgMs3FZVGbAJS9EOIL4e+YnRMArn0GjrN/vn/C60AQyIf/va8AXfFr
###63ghWPGrVbxpr2wEeMdYWW+g51qlSairMDqrBJt0GQ9t0vv6DXZXyx9xgmSveawT
###j3XJB6DxDHyzS1h7Hr8N4YEIk2ooUJNzCHkkkMsJ3c2jg82K9C0iZ3/yhyBXJ/Tc
###YYuE8ZI+RRzRnS15D0gXF7r2pLteWixyNJJ+BXR/y3yOaIXp6rU6eyrDQf+RXZPf
###9bpp0BdOxkMXw6pnLz+lXLvqR9eJseLKfTVlUqM2YcC7rfFuyYmHQvSo85nv1/j7
###6+J9vNf18YKWHMQoegqdfAln7i5fcguX2TV2HI4mYznnNFujNYGy8xkDTtsjDEft
###HfeuUObYTy4NjFPAohPlF6ftTtSPcxB+cZpgCwPZ5DuXtZAJlWjzJqh0oTTOfCRm
###wo3tuT9F+LG1J9wSDK+Emunuo3ptzO54MFT6Nj0ealpnxqwwkServ0mJg1Fx4GbC
###zBlR7k/tlZC9wsdvCNJD3ylyaqEwUArWkYiltMO9P9iI3N3EyRLZmGrz8IQ1B7ZY
###5RGJ6pT/AWLQQRt4+4ePR9iknH5/h9+9b+W0jdFEtHCQqJumFLYtWiTylKkrlNVo
###oHeLHwToM7EBCBGI+MAq8oASNBmDNugxKSgb+7yCT80kXXRBRnfXHDahFf+RNMhX
###RyP93Pcb5jqjb5qPvJbCbht+kU6avJOm5FPI53ASBAnOBMlndkcbvKMN0RE647Ap
###YdwM9YYOZji3muB5eZS9/8uFwUN9PALx7EdjJpwVCKlCyt5+v98bgfr+ejeagt4s
###TMrdGFmG0LSrr3yUM0dRkuC9hzfujUb9WEntUcXHd71B7256B0LDcETNItRlp8JK
###MujK9p+rrzYb3k/YL/tTa3xBBfyOCnl2vc4UTQhXspJuD0RrKvxJBT/V/T7Cs5lx
###A3410hnGV6BQ92L8nbR0bjdJb2xAqh4kZJvwkrshMzJky8+yMZZS3QnPgg2QwEDf
###bR+iRhYeYmWrD+9xJyu/Hu+IOGPuPbjeXPfJBapR9Ru1epXEMvm752H4MHfo22iu
###1yisqQ5iQg0oFI94+XvaFCTMzY31DZIRatC2ub5Bzk7yd6VpDQb16yRrBM1atd7c
###JKdM+Xva1NvYrFWbTWLmPvS4UQ+YW5n43UtZzJ+7Fq2ia9FS16JRbdY2AV24FkFt
###c6NRr61vptOvg4DRXN8kNz+/udncqG1uKogEFKzXag06lnyQSjbrQaOm4BnwVV2v
###MsfT9fXNxmYNCD3Fba1R31z3WbKMxnq96sNKCXw69MZvUln88fb/cUwFreMxCMG9
###r6gQdYf3g/Dg8PyptwEz8r82QJIm+z9gN2gGlP+17teW9v+l/X9p/1/a/5f2/6X9
###f2n/X9r//0z/r/SBJR2R6d9dKQSU7JcsK1GmSBXSIp+eHGU7iL0EdlHOdKR6eTm9
###Kjs8vFgPL3GIXRDGk3JmOVhswqr85DY5gEM4yYaDVU/oxg/kPZPZjDWhKg/I9LGx
###5agF7dOeUCwIz5qW4xbOG+16W/arTDVBaLbciHkp21AHzOp3j3WBSik2NN+oDkoa
###wDRbWAzsPNwDLsTq+eAaVn/SKk0wdysxAe52Jb++0TGlPlrbdqHHKpchXORgDtdY
###IyoaT7xrOG4SpodxJ8Hp1VU8Jr1rBKeNUTID/3H8AXzwyVtTHbBKKv6Z45MLAqQI
###JmipQOhmOU0RdEChrpZZxyTFzAuv+nAA/8opJWYBdTgYxHQi40mcOyKb/Au5Qz5n
###L7D3mgpTacB+2bK6ZqRqTsNA+Gev6n0pa2DQT2Z9bFeHRy3skP1aTjv07Q79Z3UY
###2B0Gz+qwZndYe1aHdbvD+rM6bNgdNp7VYdPusPmsDtftDtef1eGG3eGGu8Nn7JmS
###smXRmbKi76LVIvsoi+zXF76RmoveSX5j0VvJry96L/m1RW8mP1j0bvL9RW8nv7ro
###/YQpJjM2lOukYjczKAiWvSSaTMnjAzXmBPRNMkuA4IeHdzQeg+rpOMpQMlxbc/k3
###t1sXfrPkcqoWUPPqXWp337Rvl+M4ut0qJgH5/6YS0ExhI18ioB9be3u1oKRQEdFl

###ehTXmP+5wnKfxuTcg/n6YIE9mL+4wQJ9MN8eLFjcYDV9sKo9WG1xg9W1wfxNe7D6 ###4gZr6INt2IM1FjdYUx9s3R6subjB1vXBmvZg64sbbEMfrGEPtrG4wTb1wer2YJsL ###G8zXOYhvcxB/cRzE1zmIb3MQ3/+3OAOD5Rn4vc7AWuMHnoG1+g88A2u1H3gG1oIf ###eAbW/B94BtaqP/AMDDZ/4BkYbPzAMzBY/4FnYND8gWdg0PiBZ2BQzzwDFzFYMEs/ ###8BfHQfzaLP3AXxwH8euz9AN/cRzEb8zSD/zFcRC/OUs/8BfHQfz1WfqBv/6/RSLr ###xlfRtD/RRS/qP0qSeDwpYUF5NS6cl94GEDGYG13ZzvndHHMtiLwAvaTpAijNusD8 ###F0COunxEPBp3HFrKh+yrPnbDRy3zYvbb7bIrBYQAE0MzcEly8iy4skvQ8+nk85ey ###1vUJ/j1hC8pdxQtkj7AH6A20nmUKh8NBZs9FskOwro/igaPr4+ndJWBjeMWFW4ae ###xMz+YCwKIS9k0V2Aa6TS3Bar7bZ1wzhos6EOB9Yj/RbUJchbr8BGVa3oGB2007rY ###fUeRMuHhMQjlVGZeb0LXlKh6CPu5fckpN3yavAJ9tFKlQGAMFAWY9Jicd9hDsTas ###0ml81xk9EoMpe+3K2wQ6pg/pVelLaPlHPLwqqRNblSxGQoJ3B/AiZ0MBwi5AO4Qd ###hXQ9/Ar9Ue058sW5Gkd3cRs6PxwY68xBdOlK2whdb/D1HPdnivT7m14/LoEwr+pS ###6WIKJnvXG5QY1dEsL6NJ5wYh0DgmcsoYPZ0qJq8ocf4InPJsY1VlkBn8oXUO3Bvx ###eoh4fUH0oGGXjMoEC7vJV2FWYdKIT8zmiPgsHhDpW5Y6p3n0ivQiSCFs4ypzQNel ###ba+wUwO2LzPKST0RtNmVNdbNnzBfgwK7SZsFYByUZ3N3pjykoj9Mn17x9fbeGsTB ###cfOeTj4iUHJrgw3THW6RH5zXj2DbjfjuMRFH2Xque4MBur5Zu0ujC22XMSJQlvlL ###4Q0nj00v7iexMRfj9PzGD0aNPcyaEDrYsSPoasjd7eKHiYepeZxsQ3KMZ0zq279t ###es4/If/LCB1hwjiZhCzeOXl1833zv1RrtWrq/73e+A/MBBP4S//vpf/30v976f+9 ###9P9e+n8v/b+X/t9P8v8eoAM46c+n++He/gFiFp3AmWjjeJKbA/TJoIBwvYcjcr6I ###xxSJWR6IWT1gc8NxZgbH189BAJ8mzJCMBu3w7+/+2xgClChUcaIHFsKL0jnLQ8Mi ###cB8Zw3P0drwTAqkfnGu91dVW9Dg82j/++eJd+L6dtmowfaPh3SVmz0cXp+H7/ff2 ###WyWvDhqCo9dVe57nrff7Zg8ld+9r1nQyBskZw0thzIDgpbEEud2F7YvQz+zOe/vW ###C2Z3EOR24NsdtA8ccypxXLBHjmmYvRy1ftZWmlec0PVp+A4LX3nrNZreuz+QAtRe ###Do/dvQSGVh6ITqpVRy8MFntHlQxI81eGwZLVSwppPmL2wjacjCaxUB4ZrR2S4AXw ###wBp2q06/YTbb3fl7m7VVsVLLboUJAsRq+Fpvuzvh3cBle/XNVg+uVkE2aDXEiACt ###ntfscC9FSF6zY8mz8kb1q4J2/CAHI2mzmtZb+x0ciLiuO4ctjQarr4IrTnvIwPvD ###6wiktps7EOLuY5SHkW8ypq10B7LWR1dvT+zu4Kh1gQf6yYdzvcvqq2rjasU62ZBI ###d0/QcPxL2tTRas9q5dutgMDNVoGZmyWo4r4kuy0xd54CTbdP89QVQFWUYieZRNdY ###Q9JkxV8+Z1Dyl63i/dYK9cuIdUa/R9F1SGmnZc8u1KyRv4hz1GDWCIPLsHN5GyZx ###NO7cJLOHsVLj+E9GP2yI8C6xwcbj4gv5mM+D9LzeEBN+MC+yZ/XIrhN+VN6E/732 ###P5n6cKGmsWz7X8P364GR/zlo1htL+9/S/re0/y3tf0v739L+t7T/Le1/z7T/wdw/ ###7F5Yxr/0ZzWpM5xR0EjP/JCZEsKVFhoYWjzoWL91486cqaKLmhePh5hMOrmJRjxN ###dJqokt3WFzUlvl7hs/e4D9Q/ZjqXPfz+WbPTvPQsm9OXLSpww/wf8JTmEAKTHOa4 ###n83tMZaghS+5GbFElhmgFOjldJf1QJYxYf8SPax5x+2zENvsfDiYp9vWeaB0+66F ###FknoRXPkyofrIGydi/ltZebrEP9AHzsdx19nNyS0octor/tQsDUC4XzDBTjocV1Q ###auPu7KYjADi8BpnH9pZzwTKO729AlKRcvVsr37gWnfzO/Pi2Cmwh2j4fW3sOx8o5 ###rPAzto1rpq1B1MYhmerqLMEFTfqPCROGgT1cRoNbBuZPXrWy4d2++2MxZbgEKH4G ###LLNAqS8elOCJoASLA+WXwfi6Pb28Gn9G+giPwx04ddspUOgEiI9R3IwH8fi6Fyfe ###E/4VAOV4fE3ejO27yU14tmEBhKCwLJpdBsqj14+/xn2UsuOoc0OJN+cHxcXt352y ###rZXVBYJCOwlEaTjE0NcUOD3dcXFFBn2pQVeYAVIRrBxlrEwKCjsXn4OSYqD0Bl/D ###PHDIxfJrjBrD4DkgFcEK9n+E/WJBORskiRU2dnoFeQnNX/MM4Qsq7zecog6WRysH ###tH14Qy1XLF2XYnKhG9TzZ4HCWT9ONmX93scIFEhMh92ZTiqYWRhor4LpjIW7rhSO ###5mbfsJ6YjNbNwmHoo+G95xxpZsdpatyQmEs4GG4pHe9yXMHBByQDbBBrhzClNJLz ###TO9vjRGd+LsbdjM3NIYJjMj3FQRLbFj23lR/4gmzeKTI2/SH6WjLg2/dIdonbvgd ###hrVMgDhlldqE8+k4JpUbzn58jZK8oyHkcji8zVyh3MiEwccYU7wnW7Obkht3gXYk ###t7Yn8QhdwlMRJfcd4A1n+mv2W7xwg4qs3R2fJfc+2yjaHFOAF2lL5S2KdRt3QHDr ###F2xZdHxoiqVWkvCsUQB/L7txfxK9J5GwIYU8Qs3uDg/VAEKaW2+h8iYhCZxUrCQw ###ZXDnS8n7Xrdw23avGzsaO7c9ludIoH0Y3YF8X6UkPEXGQJGAcmrbSoHzBdaWT7vI ###C4Bu9Lcn2OCT/saGl4HYw4fPqfLVDk/3z8PT1u7f9y/4ZQ2/UprZF6KFaphQOY7M ###PokuWMUTYHuSu/zFiULC3I0LwuzE0c/AM5PDQbfXiTmG0lvHAigGfe4Qgyue8Cru ###Qm3gVKHlF5Qz8QHLSqMXGA2Ph+F0XLQ5sylcADoLNCbOzqp0FHyDzR3jZjCwJTwL ###CrwDJFsUetKyMRyz6AttUrC/eUhfh4OrIV+Xwkrw/gCP27FbEf5OSjBKUe+ypKhU ###AnnXu75xSFML1bG8r1xYRICQq/p03mQqN1e9MRYcEsULvisoQT4oCcWizQ+LGrAj ###RDKHMWxrRjeZ0u78C6QL8SYo8GBrJigfhz28zOtMel+xVF43npAUWBwkFRRpSjJB ###OW6fzQaF6Vntm2gUi+JBgJt2cdwUCe2lswp50e9IJCYXpg2FJQehVW84TfqPiu2V ###ZOyvDD1zguJsk4ziuHMTCtyjiOkyD1CrdIWeazBxtonwyjGU9UZCpp5smdonHD4Y ###WEh3uqB00N0ta8pj9ijWGy3TaekSULkiHhBuguJm5Dvn57hIR1EywZO6KD/Hd9oZ ###R5iX9cIR2kFnt6QgL6SSexCrQai7ntwUeA0jMtmraG7Nonpk1mjgGQ2TpIfKN/N1 ###RlSXePju6rM5ZOv0MLxKwnd/bOVtQGjl8mkuvftjdXHMmjZgPjzKBnwyTIUU+ejh ###kBNsFjSKt7ek7XnBKQQKEvpsUHjtqO8KCha1Qo0kBxxkS8MrdHiAQYF2r8hcOR9M ###RUCBoW/zaFaJxs4a+bYA8RYBZXAZJmi+3so/wmSeBXLXT7jBm9xFIuZo+HxQmJmL ###s6EZpkLWqiAnecIRhhOcCYq0+z8VmiKg9CcjDKPOAwYlLwYBLBAoDB60H44fF36a ###9iPG97dmCIHD20p0E0ddJcQlErc1BXBUEBS85o7nAmUgr8fjggAVohXs7xPlDshZ ###IGjQBemYU8oToClyBin1iy9HSRYorJWsL12CpqsLp5XTqHMbT8jQeZdszeYrd71+ ###v8c0GMqtwLNn0IXIiPp6JihHIIeEo3jc2co4mdkgfWjmEV7u4iiZjlm+n6toHC/g ###UoaxOG66LyBp7Q6RGB5APM67PElbgQo4mejW9kWt54D0lWQv7kePcXcv7vTQP20r ###cz1JXaLzoctegb/sHd0v5QmgTJNYSVTSRfUlse/8SKjHfTZN5EWCnrJpEecEc7UB ###EZqyV2SQ1gHThlmSGH3r06nOq24+DxRepXteUPhrVD13JhxFQUGWv89uFKFjFxXr ###ZMvuIAsHRD4dFBd2kDmj98ggXQsVP4UAKqQg6KBc3Izj5GbY77Lcr5I5i5/nRscc ###WAEZgQwRR8P7LBaj7iDQcr1OulooYeTt4fkUhCnFY55t5mpweKRV0Nt3OKYR4eTq ###xnjDCfylEDhFQKG7pPftj2dhezr+2vuKd4Z5R1YiWiEUxF/w5YUsEFkV+b1vdAUU ###iYmW4slWxgJ1YzKjMOuFzenKnI6UvV4cFPJ/Hvb7Md5LDTogoEcA2ih67A+j7pYF ###SjwAtDBvd7zN4G97eHfjjafo3w59oMO8caoXAeU+GiPDVDaMU9JirTB9EaBvwvcx ###vguHkM55n75AcAbt7pzP0uAIK+QmztwP8H4TCFWKXguhFVhV4Fr9g0xjjAYKN3Px ###cAlaFpaQKmGRDKyzuIsu8aJCvArKjCtlYRYKye7WmyTsNliXtNLc1PiQ1Q2XjAZf ###wt2Vmoso5ZcDK0VA4XdFJhSzQWHD89dtEJygOG6kGSgJ/zFPilNA0Z0eFinFUfa8 ###ELhlHw2zaMxMmLlYdw8q2tEETkt2HT/zhfbxedjdCc/Wc/n8GYPsiXIsQ8JskypO ###dtY9ciF7Lnc4nX3eirZ5I1I3xq2diXR+lTfbaDztJ7E6mOKgLJMt4hK+5o7XjAcg ###yotcNtDq72AmN2uANX59lzp6K948vUFBJ+85KRpGOizgsuwNyHiUnMZjpu0Vf4Xd ###ina3Zuqx3C5GCv0fzI2tMx2j92OeGmvRrRuW3ZtoMIj7Sev0cGuO5sKQWOCdDnvl ###+DKlk1NxjibeATBGFLfwQhrXc5ef7oWtewmXIYBdIvZX0rsgioOK+v1HLkVAv6NH ###cQAV6R+EjbyrEicd83eOpO/BzGyxxs/pFPYufikqOEDTOQUH7HzxKn1vMAsSFRS+ ###axEUkN56w+4iQRkM2XXgbrarqPB5TJChdOLOFARedKMdkOgbc/oqM+fRy0cnzsQu ###I+5HbrZ4Y73DpbHzuDsddCMyryPHXvW60SQqbpLYgQ4P9ndz7MURluZAr1a6/eFn ###HAuEiYvYawvpdnjWMLrpZoOyF49itLSBKpDCfr5blqIpImdkmsSeAgq76+yMMU43 ###cV0Ek9uSJzO6Ej74vscOBEediZUiR2eIPT7n1GcHa3437mOXOyzGzL1Gso/U85Um ###zq2QaKxE7tqJoz4h5SleNSTCHrmu33XBUwrasMsxFhrh+IruE1221TgIz3FPgEOD ###eUdh3BPq+4pbgmqvh7MFi8WKWrFzA1QAFGL4FNkV2F4SBYKppF4O22KSae2PEhqI ###rnr5HRE0X6h7UBpOlbu86A/G7KADjkPOya8x+KCAJbQAThEUqhlAvqTZoHCxAcQk ###CQy+OrwrKBMWCjYYdEIWVjF7NZXGYXLTu5psFSMf4ZNnu85mBbP9zGPZHO6hORfE ###M9vJ29vZ4XrqjaZgRqdHu6nntM6Ido9/fhLTgffC+KFDUYEyyjEv9NKFZOyEPJqZ ###57vLn6kQIMnjAJ1+mFvh03pAKH52BiLOEeKYt8R8KWiwdCmKJRP88Z6aOYGZruZI ###CYWoIC8AN7wUmmbm8rmIaJinor50B/Xqmivug9mByQUkIRGCO0PUls5BoJB4T/lX ###wA9Ndz+bDQqudbb561miagEvGCY1W94vAFKx+M6ipwaAgq5bN3/kn6XSaSt+khtZ ###IawUcMj5UR45BRxyfpRHTgGHnB/lkVPAIedHeeQgPxxm3fYqoJzu8hvNJ/4rKFZn ###n9YSlA88cU5PqTSC9/cL5SuzL8/muT2bBUreNUSBC5EfdSNS4EJkUTciwsaC5sLU ###sMyvDMkiirG86PSDNVU431KuBItwSWaWZSJQAWnLtvwu0Pb4BNOj2/KYN8i8lxbP ###vLMofmUxv7k077aswGXZom7LVtJLp9R5gBuKihiV5HWMLJ0DOpMW4G1I9vqJBr8r ###VDiBfcJsl2QGOtotdBQNk2R3UOAawyTPFLpUBfQS+AyPuELSjXVD1etCuoi475+p ###g2ToHkz0FF4KaITk23CU3kIUQAwzfeVHMrrkQLJFMj3d9SqGNQz73UQ9vroE5VUP ###1QO0XQnjVdmrVy4f0ZLaB8Sz7OkS63uf4GQMW0eHPx+rbAKnzu1kAQ+PnVvtyTC1 ###vczFRYaTkGrlMMiCLzRaMB15rL7J5FX87zLH6r9W/ldQuIL+8PpV5wflf63W64FS ###/ymg/K/19foy/+sy/+sy/+sy/+sy/+sy/+sy/+sy/+uT8r+idPqu9XE/BCQcHP6M ###2V9lPlbY3le9a8rRKiTWrGSvaAAewfZ+4B78yCb8YANEa5CUgtKqV/qKXhwd0Mrw ###QGF53pCVoNyMTUCoKq2uMrUIb/ehxYT7xFHaLmhDrlUxV54UTYX1wYSykiNZkq7M ###9AZHvYGtNB9ydznkutBXHI3T4YoqzaKktjJw/48yGnE66NypaJa7R/+NVoPdEgOn ###7L3Ahi94S1m0lzwQ4k5cuUfPbFTzLod9YImRhmquPPHK7UpR45JX870KwQB9emvs ###Wfv9UevTTkmAVWa/vv9wpPyES1fxJDjww/omqzO7spT/yQbDfFUWpAPMqP9ab9T9 ###tP5DbR3k/1oAasBS/l/K/0v5fyn/L+X/pfy/lP+X8v+PlP/vgOnmFn1lRReU9Fnc ###uzfv5sMW6xVZq1RECsdcvPj3nIThxDvf875G/SkdYmdBI++umntGOf2DXipZHMvu ###YQ/JLU5ctY0iYMN84p89I+VjzrD6rcXLkXAbKGfN9vA1zPfMma9MHffLPFF56T1j ###9rDabIeXv8WdSRHfhLw0ti9Hn8KzT+W8tT0Usci8AmT+VLOGdYQ2303Ds6BazhsW ###46zFsFfsSPz/s/fvDW3kyMI4fP7mU2iyZ7M22MHdNoaEy75cE84QIJgkM5vN+jF2 ###A54Y2+O2Q9iZ/D77W1W6tKRWX2yczOw55pydQLdaKpVKpapSXZC8BsMxyGpWeHWO ###YfsqkDodya9bX7RoavLZkIkVseofm3K2UcbPdCTzG1GGF5EvWGXVW/WnUn0jdRv0 ###yxJeB3slEA7CMV3pl1AiuGq+2aCYirD563rC9eP75hhT/T5PeB2MRrBs9Q/aQr57 ###Q8UP38GJhude0r3mxQF8uPaBxb9svIWT6J3jWzWlcXA3FLzA+5Dv2w3Ht37St8s5 ###LzZHgQhQpZ9pvqlM9Q1BSeuQ6WysvhEL9/7DFOO8b7Y6vzTfrGV9o7vviDzdU80H ###03B/UQV5nN/EnIWWh8Aggx5F4ZTYMrr/NIfjkW7TaYWgno0L2sZmW9sJS1zcjH+n ###7cydbVZhT5/qj6Ar3/mZxr6wUdVfr6/jt/pz6k8zKhEHBfZx1e1JzqXfwNOn8jWc ###u9oppE6G8o6ec9x4wd3ptOGOInb1gr17Ex/r3ZuC3MulhNG0XO/Gc5nBPh2CxmDE ###NU4jGQYMOYh8Jgicbh+xioUFQvik2eXBWaCYaQDq+z8BFo0GNChOBoMhAwVxpDF0 ###MTgcKEABDNZpE/7Z0jqAv1dWWFH4gAjfGg9ammwoVD5HMi1IEHY7E2Dh8SNDkzw0 ###soYun7oR/oEPuRxHsdguagZdPoMuzMBuC0+tecR5SxcO723dgunVC6wQbeCiBi61 ###JsPmptGj4oq8s2HkeIkPyvERo8+/Ggh8H3CzC+moyodKCBwaCnUybnL5IGz2WqNB ###t1VQfLBkjJtCrNKbejjsPbAQyHUUlEeDAdpPRN/62LMhXZ6qEteNNxeXzd1z0LF+ ###Kpj240J0cBYjlk6I9zYkMkFqgyGcy1CRy6AvIo1wIUYQJum3J3t7BWPtShGYaH+u ###6QOYC/UabU4PwnwvkdRqtwEDsHF7D/NAmDyZNAo9OH5X9ZtIoYkoI4FWzGYNp2Hg ###MHlGb/vo7am8LbmfqfS+o+hT7gc24HEYMogetqzwPXWS54R6LfDzrySPTo0WuZxm ###k+LlKMD0cyopskH8Uo4KI7xQZ3A4UMZ++qjAnppyTxiXcUqSYkoK2xqIHGRjTbSV ###04plGDsrVorEeOsoOlIylYHMTdrp8NhfXIQEBislBQd3xVcfmHnwY6nuoslp5ami ###c6rudUEcA3SyW+QqhGsY0l+rwy6VMAg+rnM8FvTCIPFz68MyKa+p/anfhFyPW59t ###sK0tuoEqm3d1aiRtIzgICi+skDtor5TeIG6vJDcxls+PuNJXTRYRJldRY2tkZc8i ###mSCvSMAhKrGnmmaj63XRXjKqQFRMlrhRNI9y1ZnELIFxF9y1hw+wlYyuPMSFtbui ###7x27LEbTy9D9v4MBEFSkrBR1qYW7r8aFNu7taEiHhpVEjaQ6EzeUch0rFPq99B93 ###//e61R4NDoKryc28SsCn3//V6n6tHvn/ra/h/Z+37i3u/xb3f4v7v8X93+L+b3H/ ###t7j/W9z/zV7//fXu/sVZ8+Bw7+1Lrfy7+XSJbEri1R2KQOx60m9zPkZcBwu090PM ###N8VtkzxkjFEHVBfzGUqBu6H2XbvV/9uYmEaf99wRvJLONv72fjD6xAcQPodHxz81 ###SQajnFfPbpmYCreZin5YgUNexGc/qIfc140mtn/29vSyCF/S2Fyw3T048OpLGNYF ###jKfbR0dA3X4ctdHsGaxV0ttcFWMl9EYqphJ+A8m/xVbYlcOUS2+31SjNxi4ZwKD/ ###K1YUmoyQoanLrzHgq34C8PI+ldpoJgodePjLBh4ePQJ4GGka4Ou1BODrNa1NQXuq ###AQ9/2cDDo0cADyPlBh44WibZUJtHkk05E3jM2jEl2cAnmWRDbR5JNrmBn4Zs4JNM ###sqE2jySb3MBPQzZqj2dzHLmoOv2gPUunIPhfkTmoKJSAhC5DrOhY4w6GCbMAwxRL ###rAC9FyN7ioWFMMLCrmmzhx6gA9h1+hMOqY2fMAk/eZiaoBudQqu+SaMwsINKDeTA ###TwF+4FP0li7gJ3B+sMqXDaG0FrnB7e85PFH+adjUVLdP3d3+wLsVBicArfkapIgX ###jD5aEZ+8SOn391Rw9X53f7L7zbGoBlnUa0X4XF9UeAJdTbOoeZi93E/61q3XzM0L ###/7OJnjawc10BTFpX+NdElPw5OXncCuMAT7MGsNa6XlNrDZ+tiI9fpIzwe84p6COI ###VddGEEuFpmTEEkAFb/F81FAqg/dvg/YnrrbfByxsweJSdDdoeahOtgejEfr/oCEi ###AM2Se1zZdxCSskzaisADOQ1fIhDCDA5LRdCIP3dYwf4G3lQZ8SX2++9LrkVyjgbo ###zhxtyxoNvtFGk3Zl235OOZkIPSj9gvrP+kE7CEM0GiQhRACoYV8arTO2kjrss0WP ###73N+cDHhG5wf5ZnODyVPZEs3kselHyAx/DiPEMWUy487QZL4DFMnCfX/L71zc6ik ###A6WcfaBYvdIHLLX76FwpP+5cKc90rij5K1sa/BbnSnlep0o+AhAHDQ36L/eISZAk ###nTzl7JMncST6lOUcMjqKytFR5DqLyouz6A88i8pTnUWv355kcFmMMJxePrcS+HDl ###rF7b1LWzKuashO/VQ2i1HWMryzZbiXMnvYHQ7Xhvxc0YBYrkl+jOdY2ZyMwoTJe6 ###Bwggb0IXniYmoujvgv4mQtfEia+JhTAnauJznRiTNZ7pOJsopM0HEye7WcRysptB ###LMbf7VTiiXCxQqf4MrbPtfrZKo9JVW2JoMchJ5FMTAzloxLzQTsv2fwnoAr9xt7v ###ZUl31Gh21sNRgoINseN6UZ8ISri6SHwlTAckRNF5iGfgEfxkflYU3efDdgp3k2Do ###3aUiEePBM5FIQeNz3pK60Yn60xeM99jWxT8dKfm/dZqlU7/IgzT46jIP5V3OmfKu ###or+S6Sxq9GiqSuoqi6Iu81DU5bdh8gUdSzCHtjYHQtqVC2lGM/HvrKyv4GB+id1n ###0NlJlkaDbQrpyozTxq2JUSQxodS3jK0jyxCKgD/YPoaGxIgfIQ54J6s0mCWSYket ###zI6urI5aekcWnhDEr3QliZX48PRA34l+EHREkkjNrRjPEZs69/Lwu729b0SdqYdH ###yilBR+bcz2KjY4sU8yD40ongPNt/75tt//Rz1tiL80Ootr9nRealE5mXeZB5+a2Q ###mcRKZ0VcImvOd+i+z3Povp/l0C2x8d3Qo//6SVqnQk/knMzFBxqEbFX8U+xKtuHe ###yc2Ls7enB0LQQAumaujLhpSEh3qiz4uu8DIdo/xbE8ssruuavQnIjMW2ZLEIDwmR ###au6mLkHLeK85AtOBo2EH7XHaaabhU0dWIiYsbX0pl4jyPo+I8n4e24owEOHfIJ73 ###uuyZKh3jl8UpXC/UNyyRIb2e9MbdYe+h3Gq3J3cTyjlPzj0hN7G10C8xUsmko6Xw ###IGWFbkDFcDkkoqT91eSG3H2KGi+LdNbB5+vevfIxMh8X5KoTNorc9ChvYwvyeMRX ###xaLZMz+vXZ3rb9L7Tzo0uDU79WSWMOXh8SdLVNQvrdHJbr5GIMYkN9O8pfZP/uHV ###czet+uRQpe0WCnXK2CzUJh/bNcU+ePWDiE/VaBS52Cq3XH11ANNMvPQy4GlqLjez

okay this part is literally just the base64 blob, so I'm keeping every character exactly as-is ๐Ÿซถ๐Ÿ’–

   ###gxR7uRWZcL06GX+TWu6YLY9PU6eZRT27lxuZdEH3gdmNYD0zGp2fNfI1RJYjGm9M
   ###0TYbTK3xVFCgGmNRMI/O20igmQ2jURSYY7k5URk0i79vxKQmDHbSCqYZNgt8TNHY
   ###xaSXW2xjFl29qEbNFqNkaG3GrbGKwHX7rCXgQ/qtzREhs1kvpsdIJouTzZId4VwY
   ###cQjWj8VIbj3wkRjJvEyVzRK86wx8TD1LgNnklRranOCK4z/PIgp5INdCJgFupU2R
   ###zImXRnMbsbOnkOeCSGtqWv/TaXEyX2KcK71d5OHPF1PwZ+c0cvFdtVSglrqX6iIf
   ###A72YioFOD7Btis2EOJPBXUzF4KaH2DYzZUKcyYAu0hkQNnsMxNusXp0S5Fw7+GLq
   ###HTwD6FNgG4UnzlVyuNqKTAfJ3uBTHYnTHgswL6+4afn0F65sXjONXSpusNdYV5x3
   ###OVJmRYAjw09Ebi5P5mwpY4HgJATn2nxWc+cGnOTC9OTxqPb/81B9kZdRXPwpGYVk
   ###gnNCrupuCuSynQzk5mIUF39SRvGfgODcjOLiT80o/ryoRjfbnIee3vRPRMvlx3Li
   ###8jflxIi1i/wIvviTIvgxFFz+phSs39rl0pvEBd/MxiEHSnUzA8CLdy93rVF7wKOc
   ###+R0Mj5K+bfU7vQCwyr8cXLN/B6OBkbUnRRnD2yZ6DDj22N9ZgXQFj+5FWuwp/vYC
   ###r0rwqeigDA/xvcedWWawDxiXLvDAw+2h9160qSPTgMCXIKfWKBsn6I4JKybDQ/+A
   ###FdMNYvNasfiVIB/5KsTUMpTLAyC+7g1amFSvFw5KLITJDIJQxuY/e/aM5/TWlwO+
   ###z9gz0MLYKg49t0W3MFHAiQExur6hHz4gnNH8ccJl+McyzK2yPcwkMAquJ71SNLmR
   ###SBB+Pxr0b9j9bdAXCQSDXyeYUGU8UBc3P/2EFzdLX+07BeiGE0QGtal2BqFlz7fy
   ###qHkvz2neDs4oJpR57qh2j1poJJRWMbbh918d7v/YPDrOMhpG7cyAH5Z1kaPlZ2vl
   ###8z5omZd7/GI+BfJMC6LWMh34+K2Lfjv9jcDPXH+tZTr4DqdXPQDw0eBb96rqzvCU
   ###nwMYcFH1m/E7RldDr97Mvrm86/Yzm7S+ZDXBxJBLxHV4+QX+D6U81VOz4A5d1On9
   ###fvn/KB1rOK/cfznqf617a+tR/a8ar/+7qP+1yP+3yP+3yP+3yP+3yP+3yP+3yP/3
   ###mPx/jeOTH5uXSB4NLf+f+VSr/cXfU10w9YwXjwqpJJgoK9Zstoe9SYj/W8LcgKDL
   ###Pdl/svSbqiYGguyhSHEP/By5HxetWIG4GOalJp77MA5Cnv4eI/3JrVj0F6vTwgXn
   ###GzgRRHr1Kvv4gZ02TwDPJ43mm5e7sDirbIN93MxTS8yvZQ9GdVD0ITHn9sHhyeVu
   ###E0drvnkLW56VGejS8cdUD2yTD1bzyG0xfbRhd9y+bfZaN2Iw8vVn58eX+6+ah41L
   ###qjNzsvuy+boBQ2qPYUTxuAgDwmgYJbCaazA+QTGclwdzMTzidzlHwzMFzni5fLVp
   ###x8PRqrVpRzvdEwN6000QR/OmnptXad6FckA//4A0mj/baGqG1bzj4WjQOgdNTnph
   ###EDbhaG5e9QbtT2Kg0+bF7uWh2Hq4DZE2z9+eNODIWGGxacNw3kYlx+Ts0fbgYKDi
   ###HOaAVK0gcVAcre7nmBxmF2n2gs9BL1Rb7qNzrM2sldvInpw+mprX1ANGo2UMd9f6
   ###IvFJrPcDq02/vzmh1HIMF94GvV4TZXc+XAXIf82fYYfjV5m4tEfzvuto/ncdrfpd
   ###R2sOrq/DYBxauyvPHljPQSa98CraalNTo0GVeXY4mtnEeLXZB8ThanmGm/S7qD5W
   ###p2XHScw512g1OcFHjFbLPdqaGG3tEaOt5R6tLkarP2K0eu7RNsRoG48YLQ9rpuIp
   ###hz9diuHWHzFcnj13cnlORyrVj5qZNHNQ5bJeehZHVZIzlhQClgKCCj7e3/uxkTH+
   ###zKOJk3W6AdNGE+UlzVHuup0O8MrW55smlrzxapvuL7GWZQzOz78SdM0369NgREk2
   ###G4lwbjBmjIJaVjjtGDMIidB72G4BPh7P9mq5FqGBowm5BrE/w5gRa8iYHJbJFYdi
   ###893uwYzMNi+X1UfrD7QBpzq9Us9HHZchvAwGTSrGRiXVAJsgbzQuDy8Oz7gei2aC
   ###ZuP4H4fJAJBelkfW0Eb7ZQAv5NzWpp2cv5Z7tEG/98DlG9i00yMzj6hh7vC9i4vm
   ###NWjxYTMqpuZPo5h5lbxnSBeNvMNBj+zHzesWFpOb6nyOjmNzOFfxcOPZ+70Zt7hX
   ###qcUVwczhgIW93ptFeVn3+YEMv553g3ZQvu+GAcMr7Rba2IdDugtGU/VVd0wF/7p9
   ###9ulqSN4SwnKF3hPd8QNFwO+xxulFIo/CGtQE92VrdBOMsXKhYFKnex8Yu9y9eHl4
   ###yZU92lX/yJaqk/ZV6mivv+to77/BaIpDAboVn1eFnR8xGlLCG71SsNB3siHRv2qe
   ###8a94HVRS4nNucU1IxHrs+gZmQ+SJoSg52cPSvu1BcH3dbXcDfE63L+I+7KrV79x3
   ###O3ghNGr1Q+58Ft4N+OVR9hqqj5on58295ht/4wO7vNg9bRyjxb15DHz/9O1rnJf2
   ###9HTPnCPOpV6ZdrTdvKPtJo1G9WrwdomKp5JBuT0I0a5NKWFzrCWwlf1BeNm6amJi
   ###hDceaPTEac4agpzweabai1bktQ1Zo8a2i39VxnDx78Lh4k/v/7F/+vJZe+6uEcn+
   ###H36lvuZZ9R+9tbXqwv9j4f+x8P9Y+H8s/D8W/h8L/4+F/8dM/h8okL7afXcIYu3p
   ###0TGVf1Q+HbC9r7s35OchhVT17g6YLjl7gHz7MugHqBbjUdTuCkaFJw1ISuzkfJ+F
   ###D31gIGGXhG7TZ/zzoNsR3uKnL5vwfcH2DHf/wGHY7YDOTcrVx5IUtc/wXxxWvmd4
   ###uwP/QDNnPyLcJnM8gKx5NbkmQ6IYDsc7ppr1wJSBj4WtuyF6r0Cza2C07hHzjvcS
   ###LchvsESPoUocy3fIYVvDYe8hQ5W0xkts1wv6N+Pbkq260Hgn9C6fOSXv/JZB3es0
   ###QTbpmOOtwgo2An6CjDhe6UqC3XAiA6qyxysuxaIJsN9Ne+LdEut2vpRoKe9a4SeR
   ###j1H+ybaRcJp7b4+ar3cbP6InDe/i/hYErULUbkcgy0hlrPWihZhFX5WYFyUz5vEM
   ###OMttDRH8LeybAuvCi8om/LMlxoLfV1bM3Mn8cz7YLiYWpSdiDMrf3PmiR1IUCyZk
   ###2LyEHk5YwEWBr31vBFxgZztaTjxng604CvX2xp6FyX3MrCcl8mPqm48Ggh0oNwjG
   ###stWYlSlao65tQQyAdZPXXIA4PS5EoSWdAIXKURP5U6AR2DA8CNqp+j0R7QH/nFmf
   ###J20Sm2iROsmQGY6DIcxrTfzZarfxL0GrRgu5+irToZWUsMQI9PIOsODmYITArURU
   ###qPdO1OakPruHOB0a/axsmyBGay86ClF5RuyHd+NbbrmFZpIYzBlHy+n8WBGAAl5v
   ###phNA1Vuvr63XZSjQ22GHDis8JoJw3EUpukSiODLUbhCSjIxvKTxu2Gp/AhH5vgUS
   ###/CAc8+UzSCkvEZXmTUSxYUkgH/TMYffHo14p17DW53kYPFrL7J/rEWgK6pRMHrbB
   ###j+ZZzpXkIyx9p2rHGSgySkiYaqfSSRJOrq5Hm7FzZ3LXfFNHVeiLos9NG1+73JZI
   ###npqwr84uQDNhH2N9EaF3bzizxMZHF7uv0QHs9OXlK9jJzu8VdxMXJEABSMjb7Km2
   ###ObRqW+Lpddj89OrfGIVJ7dUDq/YWsUxBnHYFqYil8k5VFma+M/Vet81h9Z2uwQSb
   ###Ldzvj3nltKdP5ePhKPjMCecSDSXw9vLn88Pm6Vnz3RloEE2Q44/fodhswc53PW3r
   ###YQsJFFRfkkeNellkHEc9HKgDmNHfQqZPdHruqE0+geutWInEtWmaDcvpHZWIYOhR
   ###4/XlK+KM2tn7VZ/mUVfYHYiK0RigzAa33RuQ1McMPRj0qesUHXFcWn3sQ/5hvElA
   ###V/+qyXePE1uKApBtlXdwTLxBqXMk7JiA2B87IE3sazP2pTWTrtniqxuXGl1p2o/Q
   ###AQitulIU2Tsk5u19dBfc3Q0+g7z5VFtuQwCSOxl7aAqm97HE3M1LrGDjnZxHMZ21
   ###q6NlcrsfXBulMIsxqQ+gbA8fCiZ1G8NKhoMPCWw+9nIy+NMAE9+0RLFhjt2aTn72
   ###HlOU5NynThotJ3bC9yi5/yfvUaEewMR2O52YGNIVUgjoQZ3JCDnVweVPctYO7onz
   ###05EldXWbYF3sHLVx/RiyD51kmktGgNQzJXVHcpq1qvuD/mdQLAhO5GqoEIoLT7S5
   ###wknTTwAdW/u7BX7OlhK5pkM8tkAwcMXtCCV29aCZMzhAuAqObUwbREOfCQr2wcXE
   ###knWUZ2/BvDpiTEmLzRizh1TY77+73xjUKYkSRV+0hY/JmItzb7GrLkjHV0G7hfcF
   ###esGwImv17lsPIRsNJv0OOUyUu/1rHV2c86LcZOvONkyaDu3+UAyqxLCYCBUheQUQ
   ###V2Z4d1uSAlkF9u6cu/e17r35d1/Vuvfn331N6746/+7XtO5r8+++rnW/Nv/u17Xu
   ###6/PvfkPrfn3+3T/Xut+Ye/fAUqLun8e7186pGMNxSHSPhUbf5J5jl89jDGOne99m
   ###DH27e/63GUPf817124yhb3yv9m3G0He/59j+X5fsg00I8nQkh/YBlTHgR61cj8yP
   ###nPlNSU2nZkgekQnF7lnYRqOXJVeBKdlr3RQavroFlCSZ5KkBfiSnTyOrxEpSy5GF
   ###mcA9csUhmS2z9IGWvi59N/8fQModCpDzcwJK9/+p1KuVtcj/x6f8L2ve+sL/Z+H/
   ###s/D/Wfj/LPx/Fv4/C/+fhf/Pd/D/QfvPEHbxF7o0RZvYHV6EXk/6bWmK074XZQXR
   ###TV66Cl3Dbu6Prwteif3trx34T4lbhgpeBXOtsMIHjz1bZQUPROTgy7BQLngv1opF
   ###LAL6kezW5ssKvSxi7tPIsygWYEAC28nby2bYGwwDLtDWSbLmkqlfXYf+16oltg7/
   ###q4L8iXbD9aWvm6kgV/31+jrAnARUPpiGg5Df4egQefXqRq0EgD1fW4N/NjbqMHrV
   ###8z2Ez/fWN/CftdrGbCBOCWE/uEmEcGMDUVV9XqkjBtfgydrGc4DYe46gLUWFwESg
   ###PQnOhcyrXLQWryVc3z7mx+l40e9oF6J85C2rUDmMfRrcAJ4+ByJdrqYf8k+20bAJ
   ###v2j+N6q7nW2MImWksZjmDZHjtqLnjN7vdYd6/zEtSrQ74QFqRnwfHs+9weATmwxF
   ###5IulyOLNn2VmJRhh4WwVWeZRjRMCdoLbUauyXnDuMmpYElh4yipfvCOXUhqbIUbi
   ###DTAayInv/Hgl+tdx2/6z4laxAY7blfnhFr1eFmE8c9T/qcLxXCOAMvK/rtXW/Cj/
   ###a3Ud9X+/6i30/4X+v9D/F/r/Qv9f6P8L/X+h/3/X+B8uBBkpYG11H3oXOWSP95uX
   ###Z/tRAPz749OqzxsUeDLZToE/LKIviv5o/7BYjMbYAh7ZGdyHz253ZIEdYpUwmb+Q
   ###IC+F98kX5DuvW218o74OH8JV/AA+V1Oa9NGzB3hRDwuikNT9Mhi/AvZ9EYSDHvHP
   ###S/imgH4vRRFjhJ0gfwZehyP8tqQcZHl1lRZv0QYlfMw5+V23PRqEFEggtAZRHWik
   ###RsGzfAiqBh0unWAIAALb15oDo8U244chnLC93gPzntV9gEHvQzY/weQXmDTh8CUQ
   ###eW94HozoqO+3g32EatPZ6mgU/DoJ+u0H/vrNJBg92F8Go8LTeH9F9xeqQ/xG/WFV
   ###tDGWoFgoeFxCXC7Eh3n2ZtLqnLdG4yIshQ5w9GKTkiokEYO53DOutHCuxnefWz02
   ###/szncxOM8dHgutOC+Y4/l5hZyqZQGH9+Nv7cxK7EHIsr4hn2XxSwc8I0TSM8RwYS
   ###e5OAHIXc1zaxFRDQ+LbZHo94u/Zta+RsN27dhB+439zb17BV4ZBqYPTIR9fD5uXu
   ###S/RA/7gp9zLfyiYdab2HY1gSZ/ebfJFc+y/Pp4Qj9S1hQfu23U/6UitDYyHirtuf
   ###+ptwcjf9OK0vU39Di5nwlbkSUWAKfdlofQ4KtPbLqC40UYaTFjC0ozjICqvhFanB
   ###b5qJa8w+RZaFo2MQJJavh9GTDEaShyN5JcdDf9OAoRP0kJy/rB/xn+htZzBBi0zr
   ###8w13q4BfNnVzkgz0YSCgj26DVockceCiKHQPo1Elz457En/i/pafsPI67Fz4zeFt
   ###OQXH9CyT0BSf+tanjhaKH7LytgvZ6n3cM6uAwYKuLk8G99TjFq1DMeazw1cn5UuX
   ###M8pUJ4ZYTDJ346k36Y1D4RhsetJzCsAVe1a53kxcyDj5u5cVBZXYdvz0kWJTkjzW
   ###cPyVbVbwgjpbtpkGfLtqM6xPaFIFHCadbGYv/IvsEIXrIUz3egDSREFxgBJ7cv9E
   ###9ycW9wfXQ3iTZUMHPql+xzniz1//qodf8F9oI/2z/6T4/dFvzOevZX8jfFKKnXmf
   ###PtouYdwWnDKYlzkYg9HW5zSanz0aDlef03DVHMPheGvTjJfdI3ZZy9el8Rff3vPb
   ###XeZYJgVtPPOvAUIxWEGlTq/XCpYAIUdB0S9NRE0ey/NhMPbXOh+SzjM4bp5VYGCc
   ###8qriLQ5ukN1xjlmAeDKHWVQ6sPVLqSB+nZX/cE1q0O+EFntp9+AF9KJ5BXIh8w+S
   ###ivIcVd+FP8+NMasvFgx6waDTGbS5xh1m9sCZZSoPucZPClywL7o4vONdDj4Yg4QY
   ###3n8KN9OTRVLwo2Zgk0km+UOqDrrEmZJIEnA1uQG1ejAKmtfDD0ypk43Ls4tDUicx
   ###Kla5a+jtiWdwS4I1Ng1DI//fuf+lTNFtwMucboEz8j/W637Nyv9YrVXWFve/i/vf
   ###xf3v4v53cf+7uP9d3P8u7n//qPyPj4CA8jzAphf5q+DM4oZg5LWfA+Qep403DJTj
   ###Eed+J5fnbIVSStLHjxg5sgho4tx/dCIv/HfOiby+/JqSxUtLuMmH7SDPDtq3uWZr
   ###upubTXhFQkfSq4/mbM+xnUzwOYPnNyXy+lRivRbdFJQYXTk2KUlkiNWQMJ8J/eUq
   ###pAJflcTgmIkqluZrWeQfWd7jOVGWh19+FSHJzfHdMCMBGHSAILiQEM86hrCS8zBW
   ###g83xARX7wgI7bzCgAGEQf1VUXsUKehZ/5oWs3lS9EqXXabY6v/A0LiptS0nUxsBP
   ###YuMsU7dYrHY4HiEGRDKgEr0JeU0s6xvxnE8cjorsyQP4yR848qQtJaVFwZxbYsaA
   ###/h9Etks+oJqk9PBOrvQheqOCxUH4LCIRTFVJNUmtFlRUiXdBzT7GE7TJpkiIvB7I
   ###/iC4br7x8TaSbW0xP56UMU6vALuXEJmd/EVl00pLxHe7I3mQnnPRgruRmN9UpoLD
   ###mPZmUiIbI51nlPHUSB5kZZpUeae0GHoZmV+I6KcomQ1F03s1I4FqhH+jtx0rOiRp
   ###1PI249WxqGhrc/fgf942LomGYMFqm1YQQuawWzmHXck77FJGLxrRm18ihBHuHXC5
   ###16DseKyDk7zcuwcHVb85+Hzduy/ovEdbPCu7LkkWwweeflpPWGgkP5DMI0o/Jh4g
   ###68+f64BnHxXTiohfPBDJSb/8KhPLfflVJGvUzpjoq954iPDJvSBnczIYDMl5QaWO
   ###Uy4KtvU+lujMvlOVzBc+Mdgw/tABZebNOwcuztkNZtP4JNiYmSsL2vQGrQ7hGwsS
   ###yXpEmKZ6NALNEEsPjVvtT8/YS1D9QOG7a/V6hueFnXLQWCl1bpaivF6xHBH2+nhW
   ###Cgw6iaMEf0+1OcJSiCnWcIrLdEYaJzMHSfFyFmdyujCwZCXyrogx4wmuYjnkPiEn
   ###MlJv6Sex7OP4FJSdxiFsi8+t0ZvUvmrrseRqrV570sNdQUiHYx00fTQyMF4fzg63
   ###Suycpwx1nJ42o9LFB5iCnrlYg9/qpZQ2K56dzA7coqqPLLwdjMYMDrO7eLZS1yFk
   ###bHR3HjW+YaWsoR0qMkm1KSCZTRMvSpy3MBau6HyXeWQtTokzblGQHMdabP+o9Nw6
   ###Cf1gJfJ2ruB2MvJNYqKMcKx1NZoMx3qlMTLuwLs28PHzk31kBZO++LuPm77H9T4r
   ###fZ4jiWFm9ldK/XoA7VyHo0MQ+8H+jvgmUsHpHsqQRxervpk6MZa9Rkj1ICdHnCKb
   ###Ayku9CH6bNUnYqLbFKw0hkYWYA6VZ/6alEgsMKL569PYjE+eL96wO27fnvD9Gh0z
   ###rRvg2Z+dVMXvwJOwXIyHS77jq2rtMi4/ugGJ79yLoHx/2x0HfYseJECfeCbg339n
   ###4ncf1y1Jbi06NzANw0fhltJ+cM926cCKpXzijr5CIUw6nlmZZlmOn0ZljS5Wme/I
   ###cKVvz2igHU3rcKLAd84sdmDK/KuDyXhvcv0hAXzgo6iV+rmzwboI2pFPS4GDCGkB
   ###IT2E3bDJ02UCbFy1jSb9sRSDN3q5QuexO22sEw+mgBBbME3LT80AqrO4a553NCJQ
   ###NKOjNYofL90QWBuVN+64yEgj36S1Q71qQD12BvfUFY0ygEHpdoFIvCySwMrggPaD
   ###a7QkiUFqP0YaW1PJNwWiJi/YjDJTEWnEuewx9wE7NylsjxWd2SUfr0omJluGIR2X
   ###eVY369SNwc/pKmnhZReZ80j0jYjSxEVrT9l5qSRL+7bVvwnCJAowjvUf1LmeiIpH
   ###YnJqbDpkmIyvHYh0E8XXRDdVXZA4GfRvyiS0od2o27az+059LDVgr0yGvGRqMLLX
   ###RTdOoTaQOF0L8cjO7fThCVYNnVslrxZSVX806PUoCmIwdBHQt8q8S575mjkQpuA4
   ###q6wWRk5G05ioI/UDY5QIVAg8CZk3Z+277Gl9e3Pu29f69ufcd1Xruzrnvmta3wmZ
   ###NfUvVlbc553KfI3qvDtLuG1L+OBOg1n1C8oyIoxs5gS8pDM3NR9nCnOLWfsMCB05
   ###pG1TDCJlCm1NM6YMDYuPxeBmZhHIyFCfTWON/zGZvvXLhhnyfbs+VxvDuMcw7wVS
   ###En/zyxgHc5rbWL41lvcNx6paY/nfcKyaNVb1G461Zo1V+4Zj1a2x1r7hWOvWWPVv
   ###ONaGNdb6NxzruTXWxrcbS8s2zsd6fMbxuYFms5mk9ONzGzDGa7xvPKDNcJISk89t
   ###QJvrJGUpn9uANutJSlk+twFt/pMvfzlWi9GEAzh/04W3NCCSBDlTkjInVUs2x5Op
   ###zTZPi0uxXIUgrQTnusqaOo3InQEtGBt2fjRd+SQ/du4K30S3swIap58N23clRo4b
   ###05jH7LJi0mYA6yFK2LhrqMWvJZ9G00uomzRt7Rh1Tbmy7RRBl7S14b+kNYxuW+ka
   ###Iv221XnHGs0170y+Lv3R/v+U+uS75X+r+lW/Yvn/+361uvD/X/j/L/z/F/7/C///
   ###hf//wv9/4f8/k/9/HwMAokBO9P/n6dfMh1bqNtmmuX9x2Wwc4upiBd6DQ9g4+7uw
   ###sJgh3BE1MIazDT418sZtheNOdyAyupEoSQcbbnjhCaA3xWKLsi00hQcgWpbo37sh
   ###04IaWLPZHvYmIf5vCY5IYHTsyf6Tpd8SMr+lpALbdOcCw+iFu9YnHVNa2jbg1e3B
   ###3RCmMvpbyKIwWYzPFQnuJDZxLhK/PGpXyuDxtUC80hvDZdTVriLa8ckKfKED4WjS
   ###008rIakjXBXZTHUIi7rbgM152ZDNJkQxeohxFqAEQASvG1atwsAR3rehoDIJ6Q6c
   ###J2BA1Olfyphnhl8nJBucY3bB4ah1c9dicETh9X8Bj1dKAf6C1Z4/R6WPRSQ5GIKc
   ###MG5THWnAMR5mRKZIOwBeofiIdIWr+aJqOOCyLkNI6ITTF3aW2FM5+wm+tO6GveDF
   ###YzLuIz3NIXE/dIPIAw2x+MhuOgPUMwvdfvMzxvKIu4YWegEVKVn86iq0IWVWuq44
   ###oTmbCzRzwg2KkpjPzJIn0bETpLJrjLIKvnCWWiCxCyO4it8KGivXyhP5Nwx/0Bq3
   ###no2/jJ8UN78XbmT6FZQv+4N70mjiAKV3kyuHzKY4FL6w/uTuCnYgSMuCfwG5AdPA
   ###quB4OvQGXEcKizpjcyT4i8OyVpFjCCMQjEECPSblkCzm2bNiiQgUfskYQeZ0jEao
   ###AkMVJ2ZWEsrNzIYqD6Vq+q1SUYrTVIzyiJSUoofHZKa0u8ifoFJ8aeaCzJVyMuvL
   ###5MSTmV8mpsbM+jI1cSWQMQjBpyAyv+Dn4ioe6O1WH/T/VjiBzTro9x6o3MaAVZ55
   ###TORJYa2xzLDLBSqHZIr9IYWc7r4+LLLfcjGLf4rkrlQPh5eG6fKkJzN9fXyAMS/e
   ###5hRj89ImOCj3Fcz7w7/+bUYm+U8ro9XsXxO6vM2Zvp4iOaDja+UfRopAIZ6rqMT+
   ###EtGDdMW0OsAfWrVPm1MCL3+uRkErLwL/afkczor2r49bcpCScc5IqtNtFANjrtXK
   ###9XX8w5WVzdxjx1jN8cFHE5ro/HF8TWJ5jFigD51aNrPHRnbOR07hFYlfI0uf/Wtk
   ###zuLrL0cyL27+r+FQmGLs2Wnt66OYk2tB0+lE/zoxtW7sUAdUGOstEwgujpX/m8fK
   ###DEfK4kxZnCmLM+V//ZniOjpgxm4zcuxMkYZxp+pyNv0ZY8KWWfzjm55Y6SdXZaZz
   ###YNYTbD4n2XxOtPmcbPM54eamQCWcWdOcePM5+eZzAs6HO82HS+WUYV21eBJ7Samo
   ###g+lKXEwtypCu78a02jyiQgYvcINBusnYTe1mB7NHJ3PAfy4ln5p5+HhKL/L0XNlO
   ###w9gmS5AYUyflOimLuU/UHODkh2XLdeZnwqJkg9ywzGcHuM7rcnlzil5i2tyjT1rT

###RgzHOsK3+YgzcnHSLk7axUn7h560YhfnEeZz9JJwqm7m3o0F2VPWqZqOXdVNxqn6 ###x520+binebqpSaWcqtNpvuqkzQGOG5a0U3VGLTw3LF/nxncfc9oaOi45urgqFaAn ###Bj+H71pYBIG1QhbcDccPjLt5GT4/huHVfYCbl9zRJT2WQBAt0gon2JUTVnOnsEVX ###tYB1WuOWKvCC/jYUJ3CT299G9nYoXW5iESnjIBxj7zwq5enF8emHCiXCqiyLWAkt ###hga4FHnD2Rf/WrGHzB/gN/KGd/o6EppjgLucBL8BPmqFGBBzjynirtF5aiTTqxBC ###NRKIR+ioleWeos3zy4sSO23u/Xx52DAPYUNCUglgpbBVYu1+HqnL6IVjBOv9zLTH ###0Eaq5Kzi9ALTvGUbjgH3SmXxeItr2ASCXX9UVY7+oq3ak/uryA1onhzsmvZkoSDJ ###olhiBUEY8KtXSgG0uCk42BJPlNfjDuoiZAH4B9IpOk8VijGnRJ1E90/OGodNnGwj ###a3X/aeYl7m4+ZuZWmoGEvSczDaRJu7wAjRtVPKvdNz+N+CpQkRz0/oi5Mr08vESf ###ElGyl/+MufBWiJxSiml1ndFpyzykopI2Ux1RMf6Uxp6KuQhnKbnajsvNObFAkHDj ###xg//a/HzyPg/5cT+neL/4BSu2fV//Hqltoj/W8T/LeL/FvF/i/i/RfzfIv5vEf/3 ###yPg/zKV4cHhkRwBGj7U4PhKtUQ4KqQaQ7IekbJhn8+DsLdBaE6MBASVnp82jk7Pd ###y4Ypu6c0JDm+Eg8g3LruDVpjioeKwugKIAO/PH2732yyohVW2B/rsVPG6PAOM+A1 ###0XKCRgr8fcyNQNnTYHpPBBNXPXhBUtd7bnA52DvBX+Q1VFI39GtyL0cnl6IXpxuJ ###8RlQdHN/t3F4DBv3tHF8eUylnl4DozksfCmxhyJr4jmBFxH0pxO07E7wLgOEDb0b ###N87rNWF6Kuj6WeXL+pH5c3KC6hyGAPn/qlcp36it+4nejk/jvW1UzB/VW5l6c/RU ###9QVcESgpiimHq+oRXNvwu1dbr21U67X1pL4tKKu+BmXR7rtMfePPNvwu+95w9e3V ###DbgzFGoOt7cm4a766/X1pG4tkL26ALno6rZM3QqQsVsntBvS7ojQZqr/HNp1Ahah ###9fz1hE4JVA3WDQK1mNBpGTuVsHr+RtxQOtEoIvKAo49haXyBvpr/vPa8vu4/X4uB ###NdGWvfJFkmG8jVw+PoiCEJBZF4PU19aq7v7lGvH+4+83FGVEdMFRuiH69tfcPUuM ###Ys8WZi4v3h4q87D56mj3pCHfVch2wpNRkqQrIp8LZugzXmP9oD+CM1V7VJCMvWg8 ###jYKSMXqX6YcPHxEeMnUOtEfjztWNHl/OPz4U9jtmsDqRPxNEggMkn6ZsSw+gsR7N ###jEPjyIenKFmJpnBMNIzxZXi7/bDXvaKnBpNvjVu9AjBTZMvGgxIccmRPauJvJyAA ###AVai0DeBp6VmszXmInnQbBYKILoH48moX1QMWTkJ9HBQimnUR+Jl2XhYI42qP0CF ###s0QGffxYlFMT1a4ZAAlSPXzx5Ah7QuM2KhetXpHB4wGpM38FLYHG/WvnBfxBNbV5 ###p/iUovh5pirQo2ARKNdT2vr8hhT1A/8D/tLm8USRHrtuwQgw3hP2F2q4+RU7FQuY ###2Le21O6S21IsWtjU/q/Z/1r9FlUyaF61+p+a3hxqgKfb/yrrtVo1sv/58NyreX59 ###Yf9b2P8W9r+F/W9h/1vY/xb2v4X977vW/250b85HgzYWLBNlwBnWT1R1H/Gg8ctX ###yOBEyluUluA/yB1QKu+OwnGZ5+Fu9XpDkL1FQ9IVLU8d0IZ3m9dXXtPHzMpr1ec1 ###qp2zmdzOI9MJaOgVyt6lWzEKfqXuV6mDorzlbwx73bEsJQ3NBmx8P8AMwF3ksR0E ###vhOKhFQZoEd5YixBseAofG1W3V7u9ksOewUVuz7uDycKwg+nH6fxo7BKfYPeHW/S ###KLlMJVTMvEEZfT8HVBnyg/+YoV1VxpeB3Z+UYkNTZfGTwT3hHma8Ot3AuYd+lTA0 ###uorMOrazyLmJ9lO3bYrW+lQlD+ryVSePwDDv0I5C5/DzqcROfbvkxqlWY8OEs9uv ###+iX2U4kBEwQsNT3+j7+pcskdCwWffW6BEHKFACK2eP5nPMpBgMHM21zETCpWe+rH ###69MSM+l/DrCG54D60KtAAWBpBZ27fV4HnRcJrdilT0GgLtOWDQOeKB05VfA56Bu4 ###1gf8WdoKuS387R6mQufoacQKh/xkNhbp338mNCrWpLUn1DKjznFBdAvY11uKscyW ###YpVi9V3ngL0VXiMlJwYHnY6BwBLRAqgaCANMEt8APWP9zu5gEn2bG89eOp55NbgI ###yRUbyb4DyZ4LyV5eJO92Oqvh5IqULzKUEcqvWu1POGfOcfiGwORrERq0KSPnk3U5 ###p02AL4CjuYktiknuPc/M944cbtYhxBqkDfH1O6dj/xPYf6hobdDktcfnYP3J9P+q ###Vta5/1etDr9X1/8LHq2vrS/sPwv7z8L+s7D/LOw/C/vPwv6zsP98V/sPBsAIw890 ###g2KpJRKg2K+TVn/c/Tfna10YoM3Zi1myatr+I/OLIadx40vQxqcJivMwvMD6zQeY ###EzpBOUdryP7gDutghRjhhxFqwGaBp2G20kwThKtbDt6Hj6VkJxgyRxxGWBFGoCnN ###D2aTqI5yKWlYMkU0ujfo5ze71cNsQmt+dn0dBmPn2HJYq91jh70ewdkli2alzPYI ###27HkdtmGlm6J/VJCWwuIb5hU/Cps/gpH6AmcGxdwWp8En4Pecb8TfNm0vwwnd4JW ###eSmz071m49XhyUlz7+Rs/8cGqqr9k/C2ez1OahDrcpn3h36OmzaOyM+HLbc71/y1 ###sOq4N5XAkdi4VBm4hzNh6l3yd+a0MZiZNmGzC0NjTbBo09Guxc6b1DnMYv/g6INe ###8ntnh+vsG0oX5zF67UkPYYqSboe3AQjOV71B+1No1CKT9XGp+PrJ2Utf4HD/7OBw ###v3l0sfv6ELNKv7x8hYGZie+E9ouLbJvUdForZQwhu8GcG1ShPHnELZOIdXOZMTGj ###FVa4RGsOGXEQV6+xXkWUWvm2NRwGojwAtLkL2f8PP/j06t+GzQhAk0WRv6YRShZv ###FgvWmNyV3wcoIAed8jmRKCctFICTN/jsYwoilysld0UwahKFCDqzCFVsJzueEpER ###r9Mc7UxezbASGWD0fc1fJm4AAadO3wJlJ409fkTGSjne34IaWIiPsk084vztSQMk ###NLTl2XVODZDtmteYmvs26LP74G+g0LR6o6DVeWA3gzGSCQCDqh8QEnZAGsWYimGA ###1A8aD16KDO5ZwRy/GKs/mRsvSy6iSFvJ0+bF7iXunHeHJw30dfwIEBTsRaKC2EWB ###bJWEZH5UTiyok0LXc6byfJRKmWcs1O/wFDPxPBTERoUgBZ0/lR8po+veXgGPvGQG ###h9za4PHW0DrqXdXVZQFJEARmHr+S0iBeZtIuEjovesAtfJCbGr4rPZgbw0UNIMBA ###R0Y7k2FEkga0m2mdzP7sa6KkL+OXR/KHRC/oIIKMzODxur001C98qF9gKJgr/JLQ ###q96zcYkiJD3PVRk4+mglS/zphVfExCy2ZJKjG/HSyk8j2dWCLeb+ujX6xE1BSmTi ###HQED75f/HYwGJBOg6KVY2LMsDv77NtEJCFZrj91AtsgpL5MQoBDPGRpXakLTbhVN ###HhRKIvVrLgefWcmS53S9KabMRAj5/nVqFz/f6/6nN7jxe93+XG5+cvn/rnlr63b8 ###/5q38P9d3P8s7n8W9z+L+5/F/c/i/mdx//OH+//uDmF/f+ny4wT5hP+vQpEVPgfA ###MCmVGHA0+CMk1sOVnW7fB2mqUCyKQo3Sb417kgETaVFkYAs0kXarFwi1WHNU5N1w ###gayQ6XPZ7Z8Mbppv1uOmfz4ggA19RWNN4e5pXwXAwMDFSHtow4jCmseTKwsgtiw9 ###m4dqStOh0JiQFVqapsxeJw3OssMSW49sF2Jc+FaN95SirjddgPiV2obtgXneDdpB ###+b4L6zVsjeBk6wEzbhlrbHqyaV5zCjbCAT19/fZE/1N6Rgo4S6apQD3F6Oyymkyx ###xMreeg1nSZMVmLLtRo8BHsDSwTTmQQDMBXq5xNqywwgLlfE/Qv+jcOZwjunfMuM/ ###/Zpn+f/58OtC/1vofwv9b6H/LfS/hf630P8W+t8j878BKoFS7PRv6mmUaibKNyxS ###vD/ZfwLaj9QRV5Py2lMWGGAhYesmCBNc+6x82qdnHIAM/auS6obIR+/THbbIRZMB ###hYYiinND3VB41HRD7uIA3L837mKkGDBEcp0pIaeLWmFBIGK3LX44DVvtT4Hqxp4o ###UFPz+PT87SX8993uyfEBTv3sqNnYhd132JATLXsVj8erYpAVBaOOgl8nQb/9QGBh ###ei5UO+AfhMar4y+vQKP+t3PEowYMc9lsvD0/BxoH6ov/wIg+jXjO4ad0eX3yAymB ###EFNitQpNvE7eQ65Bznf3fzyEQY7/cZg0GgxS5SYEOAbbFHA7bD30Bi0QNybX14jG ###wYCFt4PROGGIn0/Odg+ae2+PmpdnZ83GK9yy9jxqNMTJIAy5BxvO4ioY3wcBKN10 ###FHuALThg2nDaJqwQXxvkUeRi4sTXmoiGxjC4L13MFR6Mx7hWOODnVq/bKZFcVXn2 ###7BkPzkscCJPsnRz+BFyg2cBM58BctIHqgjwpSPXocD9xIKKF1IGOT/eAYTahE9dA ###6zTQweVPjxgBvo51HY2wwXG2d/GIEeDrlBGeC2SJmNXA4AfubuF0Od09SeFAZc+r ###TN+t2N9vX+8dXuAeR5ng9PCkoQaCbr1sjsZvxmfiaGc8EDGMMxGQQiXTkvm7+P0/ ###bElH83j9g2iCxLpgLZpHFyQy7P8c4c2vVART4bucuErwpR0EXD/AfPtfuneTO+5L ###FuDW9Gvs6mEchM5BJQfA3U/VTx2L5QveKQe9bYUgz485AtO7TTmEoFt/2m4lirgj ###C3JGV7dV55lr5/hfWIz+gPjP5u758Xe7/6/5tXrdvv+vweuF/Wdh/1nYfxb2n4X9 ###Z2H/Wdh/Fvafb37/H71C+QefTxEPaigtjckQ/0uhk6kqy+qSKLck4izFNa/mu0tF ###VcfafX0btJd+0OOPPzAQuM9g71OFQqlqSTdwLD0YDMgf2+pEeDg3qMFmZhQnd5Lf ###5yOHgJ1pP5EaZM7vMI+O9F3GSK7mXbfT6QWbS18N1GwmrYexGNeTfltl6U5qr7wu ###VC21pvi+2QDtrZCWxZ0CWC/onjsU+iod4NOk70psBlNFAPZINzSHjPJocc0RTlTU ###wYRGO2L2mrtCOkG+YNumNVI4c5gjb6tAEn0BVByXuOWHfzZFUbsLEOfGFiiacwvv ###5rjfHR/I8JusZPmPQTOFTac1w8la6DLzwz3KXYaBtOjEdMJmXzY2OaY2KhhoXy5K ###eIvlHaOtWA8K+ujzoI8+23JyCXhjRYEgiNJTBMtuaqFRFtfpR7FNX5MoQMY28BCD ###+OLz94UcGJ3D4i+nNJO4LM1n8dWawgT3UYQc9PhJsGwMKV6VHBH49EIcH+7I+xk4 ###SW8Qjo96rZuSIzC88gLEYGwRYogP/9cXm5ddx1MK5ByyH9xzu7o2bpTwkcI9g5An ###nFScoo0lSa9JJge5WVwrREOmpThISnMwS2qDnBkWqZnIX3iGTlQWxR4I46LIjQZS ###f9C+lbkmZ0tlSc36DTUmSzwVZF5FaeGcMtAfeFb8COb1hBN5mQa4BiItxsnexUUz ###fLi7GlhSAOA1wqDXHN8NMUffR54F4KjR/PHVP9gy/0OLjGu+xrhb304LYHTm887w ###U5BZ0vv6GJvA60YTyKXTfONVCSCY8W+swr7GBlwGoqIxm5hDTmUjMDn2MAQsICe3 ###njPFyvOfBtRXjPEbK3jbCpshqMzWYyERjgfNu0F/sJk7bE0FrF0GsFe712LTcs4O ###coe8z8ofqraqHDUNLmGcR/YpFnHN8k5ctIwdZw5pGc6tZ31KgxHKrcnrYsPU3grN ###nioI86mFfG7EgzSHSivojx1fs9eATlbeYVyiZuNRqx92ReoXtJcDrwlady94NWu+ ###jrhDA7SWSCCZhpTUqbIdSQLxV/Z5vpLrPPdi57lJKYCldIgw3Byr2CTCBQ2wHo4z ###eJSZ85VXM5yBXBDNYzR7pbJsgV2B5bwOm5jQoaj5IDta2Yu+bXknz4HU1CbjECGy ###zTBVe13FpkEhu3kXxmHSk3GG4eQODWjynp2OaDRfevJm2v4qmfLPg5G47say6rk+ ###vGqGk6trDH72rdBb7p2cPTXPPbc/GZT+d4WyNiOUtcdA6X8vKOuPgbI6HyjjwxvZ ###ZCquIHShyaRcZ6ZFn0ebnw77DL6GGX8QTSs28SB6ta5+2GYbyF7NR57veFZ3Yn32 ###accvutOmrx85SooJxs3r0KlEljToSwayUGALI0Ql5axIPCvhe3nmZB9d1KoQO7xE ###Hx77/ffUg40SBtsZi2RWD/GhsLU9I5GS7FsgV1LyDmlYSWtoZu1I6z9sgNSX1i81 ###cPfXHj44RYNnUsAVEmkp1qjiamRYjKy3TWHvtKJFXCsgMmEnrfKm88NoeTKOcjcZ ###WdS3E9chUBxBukj5aosc1mIS2fZ0e4zvywJ9aopoCLTU6nHrH53svpT+aCdnjUsk ###6hlEIRA3jlJVckPUNxNZvNs9YNcADr/7Q5WP/tQbz0HSslO/5DhS4plhUo4VmEWT ###ZmGlbgI5HqPxhgXdyOAV0/iho3dShAkr+Tv+6sC1wm44Z/Qa7CVtAqHBZ1Jbmgwn ###QVA3seNarISP4gLEtiMlWJ41CWUZAocwlyhTUCmPyLyRmQQwGo2S4fDsNnmmVUY7 ###BOXOiUsM32Rz5ERZNyoqIEMKNXyU4H2RPU0C+GtGGqCv2i4w8jop3rcteB+3cjdP ###zy5e757E5kOXEjeTXmukcv68YOGn7hC98PhuIrOgpUtl4LMyFT7nsDvz7h+ZgSxl ###VZXGqifmNBJXfdzM/hhNGPuETi2pnwvafGJYP1kRjidwUxeclAp3hNXS9d2mmfCS ###EleloNNzUXke2BLgu+t2yJRqwvjUYWTNgPXr0vRvuIEr8s4BjItkbV2tbgk36LU+ ###t7o9SnnosCvoCOtSNrW4mBEnxDI3MWUgLiIl2CK0l7Fa7TF6QOyenPycjJVU1pzc ###+/HpweH54Sm6haT2vpS6ymIBRY7nBD1HX/JuCaPcNXBS1tuR69mZx8uxAgKgZ1pS ###r3T8JHcRywXmaGsmcH08rzdtrC/h+HvdQEoFiMZUcBnTmOY2mRJ7sTMDsqwz5Pff ###l0w7ZVJ7Oj7c8ra+EbLF8Y9KoVQjuzJXzs74ULwH9KnzTt7yMOA9ZUqbS9IX/dbF ###TBadoCzA/luoifTootnCTWfxCMRr5tkcx5Rnyt05EYW82FqjmdbJm22dKsY6xddq ###3gdBIptzX9QlKSbObmzRxE8WP4ybsT7JfmnGC2qzmXOfc78RpDp1LSL1ULH38VIF ###tJMBd1Q1bqLIPZR/yxnrdOyBm4piiNzmZ5yYYoJvUlzlcFlpHGQ3mIz3Jte6JpXV ###NtMW5PgyPDnfh7WoNa/yjqV/YYyY/AnsnXPAjmxIdzZ5vjtpheOXrW6fZ6am7/J8 ###hivRiLKnbzOsWo8X0u/OjvcPm7v7l8fvji9/ztMVEVGTn2Cta6AJtFfpRn2XySVb ###7ZC3sNDPDy53Nudm1D9KpzlrY/7+Oyvko/LpuKOXxhu9xBNMt+vxPPbRVqaaev0g ###cg2ag3JEd8l8twImFBYTr+kIaq1YQX7FJvoSgM0+KsqsHzuC31LkQScYBvAfGkvK ###4v1BbnEcZ6zBspWkm0wl+Gr3O6lkkjlQhk6gAc6Vg787JH72Yhp4+1IdyWDVCZes ###x9eU9f1TdziEVWvxg0S5OGj+SJQdvjPo/2285PR6gq9PLs8p0RYSDwUl0AO694du ###7oNer8zD5jrPnJe36SuGTA46bDb2d9FsnFNImEq7yrrW4cwyh7LzNObc00fnHjJk ###PbWdhCIntQjY6XKop4wGp545niM9Ol2fOQ2vmZ4kVg2Jed1MJVSOfd3trNJNznjA ###ToLr8eoFBQVptKQLniCxjQfNkwtMMm9IaqW47xXVZo09pcIkmuBXYom+GDE0p2Qy ###26MAeE1Ui91HueGzL7VeYyS1n2NBjb6dvTx1jfjBntPH7OEioTbyyRtoscmBMtwb ###/nximx0cv8PqpDGKTb5wsvK0payPx++ltCozDdjgkyEbDuiSmnKQj4O7oUhQEGYK ###0oqozdsu0y8Op2Y65yUQRuqHBnJtmYEvb7efDGYpY9MVI8liyTAdi9LJKl6cJ2cH ###RFnXfhoh62xTXYA6eWb89tTGQSInpZ0Z33E68DS5XtD6HJBKz33UBCnyGr70hDup ###GbVxplpvl7lcJ+1ku3g0M5zUCm0tfqlgo8FRnCFZmdyH+cCKYLF7qUyKWVNoHnm2 ###mZOeD9f2LMEUvT5Nf7qi425CEBiP7pTwoqTcD+57D3Ai9nqtITopiuX6BSM0QTJp ###t0JbFUAB5R4agYgCggoPQaWv8dd7LH0Tgq7cvsU/gYIJJEsMyUm73qy0W8lDu/Oh ###KO8RFJVoKpkjRPqbSvQmL5Uffhli6pghLigj4ekuaGEVLBBix6y2QQWvVHqLkcaj ###EpwlbcVaaNakVh+YpA2qC6YKao5bVx9YVThJ10usVoK/vkYzMFzFoPtzBPakdeNW ###oKQhYVnrPOVAAwUCr0R3diJ/8Ni6pQBQyVbxda8Kbf7oc983fTJHwR0GSaPIf4OR ###2+0eIF5sMxw3IOfsz/QE2gT9YHTzwJ5cDSb9dkDl1Z8s6Roe7mTKLsxHCfnu1T4F ###deKGdnhncK+nfUXGYVBpkouMoFhtVLedpBuz1ESGGhvdWbYylmgNSQgmeiny5vBK ###XDzMfAy45MXdWpqTthlkdBOMm5dn+wV3fcBY8Aj3bXGFyMj8J3RF/PhKkaQoUmjd ###cd81XCQx8tzNV1r836zDabfUcprx4SiCUDi/YxCrdPdxhzgBaqUnVwyqhmjgCOQi ###thIt4tThdN0SE/4nyfGLZBAQGAbq91zJqMueTnX0hY0kymP9+++OFzusmt7nUkw7 ###lSgx/GYUngyBHO9oQqGiiRQYPJcCedNwbyy6s7GjB3gDyxtDrKJQntbRJBWbD7po ###FGK5uOPteLW9MjfxLfEqqnwG6OKK2bqODvc59xTAKNcPdXDGe4X+kE3toA0LfimX ###Tfd816QECRg1qSJQ3u0eHOneKRYozsZY48lq5wxv/N+c/0cIqnTjS9r+ozMBZeR/ ###rtfra1H+5xo8h9/qi/o/i/w/i/w/i/w/i/w/i/w/i/w/i/w/37f+j5bvh71BSQgz ###eIKwvUp3gsoJjezilFtEv2yJRKdCZjS/8qP5WEpy26TcBefRkAXgHy94dU6AqlPM ###SiKw4XLe/CJi7NFkk5JxQ8y9JSKZyRlwGkWNEgn8UpIX4Bom4EDg10iAtCH/rfe5 ###x38JRiO04Ud/0C8RWsmtjew2UltSa5TgSuBwZsLLp9FkHJShbRvliNaoDYf9ZzhE ###ftVn3cOa6UaIhQZelC0F5tR8vfvT5lKSkbABu/nwrPnmLbDIJjBJnhiVqz0Oi6HA ###jxxAkBbNniOCHKtiVkKJTfkdXgZhKZ/0TlboAr6sFiVmuyQF++j4J9xHDVC9Ks/W ###2Ko5JeB7TXhwDkeIfefmKkPs/ja5MrEgjmheJ7t4yeUgI7Se/sK11LgTqqAm2U3r ###Ct1pDV+2shrK8TmaCGQXWwYhJLk2m8QivnU7x8YIXADibo1bmO5/eLxKN6OVR61+ ###mTKqRSW2B844AnkbZDhA9YDdB39D4bcVckl3MBxTOuMEd/GbAQhMnUE/2JzS/ZcM ###t/Ddi6XYfDAhh3FV2vTqBQMpaIHWltDAV3nb7GlZDzi2fRvNdbHvdhuTK26dEckc ###SOjjTomRs3LhNugNhe0W2k5avd4DFuzqPQhDcBgUJfai4QWk0QMPt/tczQ9x/b/N ###reRzLACVrv971ZpXtes/1f3qQv9f6P8L/X+h/y/0/4X+v9D/F/r/I+s/ERbOTuwC ###UNFjTfsXOXnJAJC/LpRKOIuuQiouX47miBRIKPZkfKE7HiT8eM4xyEc74cdPLb+S ###nFE3ykh5Tfk3SVAkpxJZGGYADEzVn51+DGcyZDSBvDDuqMWNZ7jJvFWfzfoTz7Vo ###phX5owa3UpNICHidLuF1aHrzwFFKVbA2KeHIKhXIWqXqWKtYSaOyWqUntZqH/6Wk ###JC4ITD9Ga/jXomKNqpuTF4TcCLhrfTmOZUiyoej2vzUU6NySAUUDTnNGVYIw8oy0 ###40eBE4eiE4Rd0PoyIYkn++Q+G+QMA8PfdWF/csUUCRboAQigslrPiQ9mZvWyBt/r ###jmmanQk5cIOQDlKPzHEq0h6u8sE3FYpA7+1x6T/HYkAPjkm/RRR/0t2uKE2jqGxW ###qJSBzIuz70XRMVZSO+d9tm5sELTyZ6ATBJugqlNRvPsARUqP/roFGRkJpB21zQ1C ###9I01MHkpkPhJjlDdfpmXRxuMQLzsCGPN/mA0CnigZOHocL8I4K16+QYG8fa4v8d9 ###ONKHRlEeToBuf4KRSpTwUoiurHBw+VPaoIlDw3cJg0547oJw3IKWV4LwHs93sd/9 ###vYsEXtePEqwDKatiXdL5hocGzTAocDrYO/Z22m8BMCHGHd0NQAEif7677hfln/vY ###qY4Hr/Wcr3zQM3irTu+umCPu5gnFAHAvYYY0dt/tAFDTDoq/7Lf6DeonGvuMn2hO ###rokaVml6Vu7iH90U/gkgcOJCdT2aYOQX3Y1WvHAVtHF1cIdjOnE0FiC3g/1ZTJ0+

###dbAnO3diIQKCXO9GE66Kv98jzqIUxs8tUIVx352co2kE5sUKCBESYwSzLPj4fm+1 ###Af872ivGQOr23+9hz+95x+9EvyfnFlwiky3Hit0Jv0l4j+8wRtj69DLogdKOW8Qg ###L240HgWtzoNGWzNQMv/yAjuCkUVNiMO+mW19c3ohd3b5V8a1RvIvcmWcqv4WHWkn ###4Syi8UJqnlFqlrUg5yU2Tyk1/7Es7g8VEYkTnMuYBBzfCmsuVNC9fdInftopalEL ###aJIVsEYBDO7BNU9+VR3Grruwuag0OcX9z+lJ48jfnWP5x6z7n/WaX7Pvfyrr3uL+ ###Z3H/s7j/Wdz/LO5/Fvc/i/ufxf3Pd/D/BKm1Tek1yIoldWkt7ZhQvNuD4Br2bpfi ###DynRdeMo5NIpdDEYka4H27zXQY6BMZ/TaDjQRYsNu0E7uO+iyaHbD1ojdBYaDb50 ###+WkGzGgY4qhsq7wD4IQF+L1odIHcMABGzjk3HK6T3hiPU+DZrNVuT0gPQbhLDDgc ###NcIweb2LqHAici71UZcwxHll0EKfSeK88YlouG50b85Hgza6EJqFNSmeM+Q3beIW ###682uuNeq04qg55RWxZHOeC6jFp49I/MGqtXASbt9RBWL3HF5qyZ02mkOB72HZG/c ###5YGq3SU9X0mvuoOVxynj1/3BHZxFJQTvQ6ez4n1MDb/kvS+3AYSSEdgpan9RYKdM ###ytBh/rJYxLAoRviYVmSt04kFjEYgCgIsbJOqvSyJlp4WE/10P7mcdK8pRQd/Ohl/ ###qKgsz1qAIEArvOywiYdNyjhtaK0F/X2iVGrwzxYAD/9aXp44EIaC43f+8qePm5YT ###4ptdzbUQx/m04sWAoedl72NJBCgWopkUtcDB5sXZ29ODeq0QecieFAiCEu/iIyvq ###0zL8iT9tUpYpmErfClGUkPU/YtoE+q3sf5wdjD7MJA7IVwMLHvkHXkeJVES0NF4f ###TIBu729BzO6j4OXiXCSe9FFC7qEjOXEaEkxA4O7BW7zg6kNby8tdbL7M2njLreYb ###zy85/crvBn3YsenggYDIv//AOrqXunO/mQAsn6p9F9souSZMY6+Vcg1tZeJMcOIn ###KtJ2IiuYJ0Qx+2CQuxbLsKFQSf1QQo8WRgRP+iSY3uHlBbrC/zqBaY4fQKYCxn+H ###IjRMrA/C9gg0mJ7g5+0HYEVLem6kGNcsEjm1RlzufYJXMJ3WqPNEja8ymAlGzNEz ###6aPRLaD45JFq69U/eHXKEiEGrcBuBURvlNg6ZY3wgKXgqqMjN/xWxdu0EoMW9RJ7 ###Dn9gE07rm7nHrHzwKtaYz6nDKg3Jh/dowHW9b1eny7LXTQcH7ZaQu9lcFFg78Kij ###5pvdD9zpBNOsn11gPdaT831H5cFzZ7tV5nNHfeAJ6Q3iHRJXeUP/vcZn+M81rH6J ###gPuM51on6I1bsS9bVR/g9nICDrTXugKJAv5DfXY7X7Yx0r0NnKC+qQXEy0pEiJb9 ###swaPh/gHigeUPsffkDzPaN3Z3vYqv/+O/9T1WPm2yIlGYhjQqDpNi1gjjcqm2eIU ###0P7nQChoempFtae2GZVGgYH+rhEve6FRlXW8VcTxFj/d9Eng9sIjhgLdrTRN1/zK ###rI93gLBFA1Ype/46K4xwbwMB4o1g0Sj2QR9YYfFiBNxXcPqsxwfhCz/CDH0vWOXZ ###M39tzewUG0CvEtSyecwKAnL0rs+Tg4aztJOvGQ22XCRgQYwXPbjPR9yEBMI6A+qa ###uJaP71qi6Eg6ONofhJetK4pfgRPlg0CbKWRIQcPz9b5oUzCW2ZcMoBFjb8q+hAmp ###xbGNUh/iu1Ih8Vgb9oRTJYmEwHSVC5U+J8FCJP3BylhFN7hEYaVwUPubFw2hdyBq ###FPjUJB9AQcOvwARI2uASlxxfhDp0OjahdUpaDgj45AYz0qC4TBoPLtUAPooE01Bs ###Rtyug95En6P75GHnWGlK454U1QF96swh/tUb6ysv+srmGImQAhfR+BpShSaihEaY ###mb73HZv/nIu2wNNBZgUiWaFf9bitN7zFG9miTL9iC51EUEOjvhBc+oQ2AV2RcBsT ###+qnw7KMA/XWXbnc4/BolKYb+SQg2IK5Tb2XqfdMQugEc16edMojZFBrDcnwahcqQ ###2ZfnLREeFnBQICUEYkPD/sC3msatS4QUeSStqw9/w6JUapJYhnd1yRV351XiAXZU ###4grQmAAGYrhLEqhWYoDEVjrfzNTqOfg/IY+ORCPuTOLz00dXbSTxwY4c1BVgpuDh ###jR3xap0vfI0/bWYGWqnOHCxFHuzAFZDVlbH0YHEz/8WtJInyjuSwRopBMfSOCqb0 ###6ihruEv4kDn6rnXT747RhMAvFl30YoejmROkJJFyXl69ulHdoCnBGAUrqJPKNNYi ###/hkBuC2/tIbiEo/MTGQETj5//lxESJaNRJ8G1xaglq3xSgRGaSkv2rWVVEMQ85fz ###RvqABUXuHw/ZpOZX98GXIWyIYNTELgTNlpD5i0lm5ee9GgWtTynlG7uO8rD81G/f ###BvwCoYeBhqArjsTNS7vXHdKLpOXOuyn5Gf6JeFkh0iW5nt7YvcSYQsd20JmotSkk ###DVnkboyqs2DLhqEbCyLo7I1nI9NG+1ymn3vKm9m73bn4NqdG7QKLDjT4FcI/DpvH ###l4cXu2j/bsR5eFdWlsRPhE2SB2li3r0CE9YHzGu1FduG3rMKqEs44PnF4cHxPo7R ###PD97D5rNy93jU9AMK1ZNTzGv8wRWgxbSwngwANLEZH3jQRH1RpJNN3mgp+ZjRjuK ###bMzMpg20H/PrPvgcdYCOdQRKyQWOeMQtHlXCb4K1KOFgosdG3m1dX1ur1m2h3+dF ###3FxB3dl09q1oLX2bfZ2JLQFt/t/2/yCaJdkZZOi5uIFk+H9Uql7Fyv9VXatXFv4f ###C/+Phf/Hwv9j4f+x8P9Y+H8s/D++a/4vzS2Baq6EeFNoumBwuzOeOOiHofmNcOcJ ###FEiFga7A7/fgeezOMsmq7DCKr4gUPqYUu+E9t65Y4UnFfrIRa7NeKVn9rMXaVGP9 ###VGrWk8q6b/VTqVpt1p8/jz2p1a0nG8/rZj/rGzVr9PX19Q37iWf3XK/VrH7W6vZX ###NRs/67WKDU/V27D68X27jefbPVfsNvXnvoWf+oZ9JV6vP7f6qa9tWBDWa2sWPPVq ###1e7Ht1enXlm3+ll7XrXws7Zu089avWbBs7ZWsdtU16x5rXn2LNYq9grWNux51dZt ###PNfWbDqsVW3qrfk2DmuVqtVPdaNutanWNyz8VGPzAqRa+6LqVa019Z/b+PHX69a8 ###/DV7f/lVm3p9b8Pq2XtuU6YHW8Xsx1uz8ezVKvZXvj0vr1Kx1gs2qtUGyMV+Uos9 ###8WP90G26/lOOjV6O9VOu2/2UbXjKBLP5xI89wbkvGU9s/JQJh+YTG89lWgujn9h6 ###lWlNzSf2upeJNox+YvRTJhozn9h0WCZaNfux6blMNG8+sfdFmfaO0U9sf5VpD5pP ###7H1apr1s9BPb72XiCeaT2LyIt5j92PynTDzKIhYb88TrjH5i/LBMPNN8YvPVMvFe ###sx+bP5eJhxtPYny+TGeB0U/svCjTmWI+sc+dMp1NZj/2+VWmM858Yp+DZTorzX7s ###87RMZ675xD6Xy3R2L5nb1F4dkgHMJ7acUCZZwuzHljfKJJNYTzZibZ7H+nnuL33d ###/L8ZvPXN4r9EzZY5BYFl2P+89fU62f/WqrCx1tfQ/uf7i/ivhf1vYf9b2P8W9r+F ###/W9h/1vY//64/P/yyv8z1n6VafdHKg4JD65uZ9LiOeLTYpGasmVT9FNIyLp/QcWm ###QnZxIBzSMByhWklLxyBiQuLREF+ab7xKUnUBbUyRKOODiE74OHV9O63MgCgUkDiq ###jIdwVhdIgCA+plnCjzw/0FWi+WbDNbAcc6/V/kSpsqLk3Nyl0zFuVrgHTwxOmeex ###mBt6Q5Uy54nNqfbbFLjV1pMDmepp5ywgKGzRU1RuoNoNWCP1DUZgiCTklSgcDP+K ###XCGVMw8BWFbF3OK13GRPtjuxUbxajau7ihhrTGXdiuTXvKkHRVHXtluVpEj8iPKz ###6Ynhr9VwbIdVXEFdOrjA39ErTAFouxbRTudlDU6A/Z00dw/+hw/p8JTTx97KHnv3 ###4GAeYyeiC6sqYLUIuUTa+jtoXe+TsxlRak98pMWkJSY8orsSYqMiMFLmSkpJkmQH ###owlttZDOCJHOhxxBGHCUo+oJSHA6ZB8YeppR+IvGJJz81yy5QtFox5wCSylbdh8m ###cTUYYGZDkHIdo/IroDibiDCxvxeV41wehuJZOqdQww6ufgna0xfjVPtICwfSeTMn ###JtiwysFP4HDTHUIYtJtYm4HlbQ+nKie+nO3fY/3p5pv3H9Lbq/hg0f55iUnqiSrX ###x46j5SEsQdALUKWJwg14ZmBRFYL76ctiD1Fz2DhP1ZKVd/b3PL6miDqNgnhZiGWm ###NRUH16bTq9JuF/ekVLtC7l+3Ryoy4AhawUrXJROIvPzf9jG5FChI4xFoiuKeVJ7u ###qBJGJy+lUZuMRjh7mK/pcB9R9YR6LHDKkEfRRimaWimOIC3YQxPgpARmSHKx8eJy ###mqCxEntqDESRJXFwyjv0WQOYZUPJBbH10iB8H3AbCCmMbbkfBQeIgffuTfOef9Ds ###tUaDbqugaLrENBaXNuIuuaQKt1kWAryjoDwaDNCSITqntWp1SNsdcOkwIcQim8Tk ###HlIHzZuLy+buOeg9PxWSHaCjncqP7Q1W5nvwffONeaTpO1M7LNG11aTukl0xJnFw ###xVb42Oh3H03DGDy2f2LuraQuFgwoqQRw1V+vO3YQnTroPNztSakxRgTydVBIWHKK ###73pNlYcSaAELycTtvzBvyr02EidJ+OhKMBn1X9e8imfXf133Fvbfhf13Yf9d2H8X ###9t+F/Xdh/13Yfx9b/wVIfheW+vCiCVh4u3/ZsCvBuBqkV39hUfWXhJ5QwTw6vhAK ###pv1Trad9d5z4XX3JTvncJLlQl9yAdQr57Te3VhtC/x/Sx/24yePOgX/RYXDFTwGu ###xUqllUK2KfqcIIknKBbDHSUMd6QN59bXQZBtPexNrj9gJuCPm27jQzR3mSgsoeFV ###a9y+Ra0sQdsHlegCzyKescTZBYFMek7y+yOQWcKk9/hn89Orfye/RwtacgOy6B4g ###WjbdxuLlfTRpq4TIbsLISIvM/6EKlwnbg8K4Fy40/8v8fzCIlFcHnlcO6Az/n7Xa ###Wt3K/wx68dpC/1vofwv9b6H/LfS/hf630P8W+t9C/1vofwv9b6H/fQ/97zGH4dIyO0eRCVhYq/cARxmThageMSMUIyOAG92b89GgjfdVBLV6 ###wUN0g3Dc5IneeeKCSP7WRbrCUnJ9dHFf17o5RlfekkP5e8xPDslbRBkbw8trmjkO ###7WqiEjqEH2JZRWv8Lfvc6k2CcKah01z/j0Ks9VVyattUuAtPzutR8OsEdIkHVoDG ###xTkN7crz5sztxrISbuZR/EnV+YTKT79Jv2OOSvqlffWJUiRuOhPiLZ+0brC0/XA8 ###EqYDTODI0YbxAxuxbJxqXvD2/LBpJNCz3fyjzrECO20Y+BMpoUml2n1hhKjYyYIl ###0PArjQIj7O/92AD9HRiZ3zz86TIjwaZpvkgBeWcnngk6E2weqz8j8F7ldcP2J4/N ###Yd6Yrs4EbBUH/SMxXX0EpqtuTHMqF/vEDt9AmFUemZLcBwJosaVc36iUNPY3vL0c ###bUWdAFMnwtWYqMgByjsESX7U/YIYLGjYJF5gsnyFK93LItapXlPdehtnLrrhauHv ###nzv/I2a9nFMOiOz67xXr/r9aXdz/L+w/C/vPwv6zsP8s7D8L+8/C/vPH5X9MLQG/ ###FJWAd2dPo5z4PEVkFbUDK+X+KuiuINFCN1p6P5muz1cp94wEjGnJE0taP2sygaRI ###C/hcpgX0zVR/fjWeDc7oZ00kpuTf+b6ZG09loFMJIbU0hyl55XgiRw0/CTUdXCUl ###hFO3kT5Tps0U0FZrRvJHtu5ZiQxlQkctbaVKZFi1EhqKfHn+hpVbr65SZUbZ/2om ###Vn3fTIKoEkY+t5Iirmt5+upWys2alXrTNzGuMg0+17zbZQLF6VNxRn3w/H1pVeIX ###GtT/Uv2PktKAnn6613y99zhFMF3/8yvrtVj891p1kf9/of8t9L+F/rfQ/xb630L/ ###W+h/f7L8/0I88rh8hHnqWNWvmDqJktOlXiHT7suE7SJRvdTIvDWhqW1EObtVEnup ###e0idQGpxUgtbF9/KpPCaTuKtiWfra0bieN9O8S91orrQFTYifcITOogntcm6LEcg ###9aznQu+qmDqKrhtJ3UuWIRBZ1FXZApHD3BPvQYgoyYT3sezqUiuuy4zssvSBhFPk ###S1977sDpmjV/S1cTpRhkjnVPrAFIpxpO66pfs09rneQYCl4tgb6CWcAqiw/UBV08 ###l2vvm+vka33IRP2yLITAWYTTNatPAa9esED2X7V0ZFEUwJMFFGSfip50nIqiBEo3 ###tnTnmtwDayZOtbmokhZCV4/mL3BXtcpWCHpGOopKYHgWLsV4G3WTTiVcCqc6nVoW ###ElkwQujlXk0WXKgblhXfex6n02rNLKigwcz73LDWSZvLc7G3vHWTlqR9QhZnUHCK ###uWtR7hGsaxZOq+Y6STjF2uIejehUwrpuwhpbJ9+0cfjP43tfVkxQtC/7rFl0ui76 ###9JLptLZh8qvna1af9XiBjxisNQunnslP5ZpXdTrdsPZ+xaRTRfsb5vpsaGur0T+H ###9bnaU+61rys4I5xWFU8xzhXPKgSyLguG1BTfi3C6btHpmolLeUaJ/aIqYqxH+FCF ###VyR9qvWvW/z+eUmvE2GUrhHWSll5Q+FU7k8JX61qWh3XNfud2qc1C9Z1i0c/t2x0 ###Op3WrLOpZlYAEbUtPMEbdX4S2REryrZo7NON5+aeVziVVUc2NH4q5q9skDY/fW7W ###2thYixV5iXhg1Sh8E9H+urmPlAyh8Q+xLyIYn5t73pP2Vt+CT7NnyiI6cv0lTtU5 ###IvmoKNzjV5TlOsJp1ZJR5PrXTR4t+b+LTivrFp0+t877dcPy7lWlpVvb+3J/bmyY ###xYbsojeSBuRZsqH1UfXMEk7yHNkwCxYpOq1G6xSd+zXVr16wSNGWlE8U7XtSPkux ###ySupFi3yXLT9ACNZpnaJnnV5dFnkLFDCntfN6lMb2pGi6g2tm8u5Jpdk3ao/5Cmy ###V31IspWihSSNmqeqWhnbsBodyRFZeeZyqVpFdj2iqn3ZUopdkMirB1W5q25W8BJk ###J1m6r28zeRzKrbAuxQHPPB4kSfpritVFR4pviAFswzOvPuoWSUpWWtWPg42Mawrr ###6kFdJ+QgK7/ZODwBXVwSllePKUx1hd3Uf58/Nw/+qlZRqmoJXrG/E/7d0A5WqVTI ###b1X1r5opFFQsQbGub1CrlJRsW98w/7UP3o21WB9yk0t4IkHUsyp+PY8J5kq5lMxN

###KmxKsFk3lFBfUpouNMnDRfYvmU3FVDrsuRkHmmRMsi/577pV707CpeBdjzFf2VZv ###owsL6rCWisuapgxLhqnmZAl6G1XzAFmLDgMbp3InR33WTCGubgpxKDBHAo+JUzWn ###+vOSE06tzwinpjCvcCzm70tBSCoB8tDytLUVa6XGlzRVtUqgqfGjMaIr64qF/+fW ###/KWw5Mdoz4ZDHYJSeLdpzzOf60pX1HbDVIblv3L/qud+/ESwadiibYUvdUh7iTiN ###KvLVTJyq6oIWndQ0GpPKldqfz82/5anjbdi4z8OJ9QN+3bfv0uWNvwBLlqaUB6mX ###6+645O7LN8BWtrH0wn4JfZkFH5XwwLTljHtJuPuS5Pa8pg7NeEHHrL584+D39CNl ###w7cKG+btS2ddFUN3ZlI3zOqrpm/VmqG7q0qGUgBSfgHxvuKeJXVDv5Q6o5JXle+B ###N42QsHd82ZBm1bU06jT/lVK19HSQVgq9XVYfckZSm1BWPKnt5OlDwvPc1MqV9Uaj ###LMU8svpS1qOqg2HVjTaJfXnSMlhXfUWidNUQu5XFIKkvh5VZiZlSLJcaY7WSMTeN ###6cmdtm7CI61nknEqi4NzbSVsVVOwUv5K1uGwrtYgizrPLw4PNIO/t2FSptKN5fFT ###q5gK0polzK9V1fPo6DBtjcpeJvmH5HHPfcO2grOJeI1qY8+Ih/xFM+KOVehiJaaF ###dUi8BN+qiEfXrb/tf6PzIeLDZpta3dNg0xlAk2fvMJ8RdOQnJ+4+lgRfXnJn8cTT ###BbN1ut97zypsVbRSjdzXOq530dlpvzUIJP6pqQC53id3HeOMdgPHUpYQxdP6//A8 ###qieX5+SbF84hBiTd/wf4US2W/xEkp4X/z8L/Z+H/s/D/Wfj/LPx/Fv4/C/+fPyb/ ###Y5REw5KLsvNooAhW42ENKrx8mWEHZxewW5le2FJmsitM+sWoZCa0ZTTYVDk0rj41 ###qRSfNbSrjqZMcKFKaFIY9kypO5aBdXXheGx3xw98/FJaCU1eXiL6xDmyM4GFWc/i ###PSB5w5zpskLxsolsmdjikEoWvg+43AHnEHQxZbaQu0nzzfNSvlwYctjXE55AhBUu ###Vg8YCDWdYHB9XZxmWDhFMddhL/jSxeMs17CU3h4FI/gYUCm/fmyWkKxhjewhjuQh ###KbVJ6ecXnh3AyAvipL9xcDdsdjsxct9MLjC73O5h/gFQotz5RkQjGJtarW8ml8hd ###vsJdzjOTJNLqMlFp1MhJyiOQdpoo1lCHhLSS+ZDnNjAeqUyqszBIsVwgiWOfvOYq ###1r8MRljBWFZfDbnQFb2IvsTPwlWEZTAiia9EIl/7djAAyegqCLXGswIYm7LM/0D4 ###i1J/2EkqqvHsFGrVmcohIbg516zfrOF7nkciSj8RkYH+1edfqS08/SAbxr5SST/0 ###r/Bh+CFadvpqSds9DRBYJ0M2xJS0KNAORO0PuY302qqKrmAQ+j0CQNElvNrTSCVG ###ao4qub9wNP5i5Pr4xcKmsj68e9N8/7o1bh7uF5ZsbvA02p2/6CeQPAF4zVhgEkQs ###ViHl7NRGxlDODRQNRSOoWraOGrYrwNUZJ+qMoRRuS27eZxT/tutgTzcrtcIJQ/EJ ###oWrFc6xMmZbKFhw4obtTUanVmS35ljGU3IkJsyL9txf0b4Dx4NEVtNq3eajDMVTS ###SS2HkucwLNL4Hku9KBLhVIEMzSaJFASKPZ9xJMpC4d1+HqxaQ9llhJ3cESsTg5Td ###bOxSaWLrHHFslVi3EQNZ2Y6kVjO1UcR/9Da6lKtnNtK53C4J1v0Az5xrzCIOFNyK ###VfxOnB6cCgXrGGBlvGYyW+tzwmRV5tstx+FiczjX8WOdwOlSMLRXBa03ip8cJZ3v ###grv28KEQCe4lJdOUItFrmSFpDWASkZxSNGs+6/jdGwWtT7BvRr0HpDKQ/cqa7HeH ###+6t7zQk7Or/R3HYVoJw4vh0F4e2g19FXAjFoSKDs6VMWR6p5st51O51e0Gx9vmle ###HAgU20i+QmATcmBlH78OnOs12XIdZrb0ENFvTIrQVLtfDH1uxchORVXBCxr4H3TN ###DA7D+Le8xnkMDYCI7xn/CwuPOQeDUbMzuO/739z+X6mvr9ds+79fW9j/F/b/hf1/ ###Yf9f2P8X9v+F/X9h//++9v/EVNuRdAR7W1WIBkGJP2ZXD6DGXLdIQfXNKjiWYFXI ###rNK83CgllrxpjFF0F5owL5A0azZs193FMvCoUoLV/mwyRvNG2L2BMxbGBj099+hO ###Y7MJwHK3X0rSoI/7xsjXvQHI7TD+ql/MBCFHWexu/wTm4h76VCnv3LrD1zLMO2vb ###1g3Dfyoh6nypMVyQxoDKOoFRivIQa990++h6DouD/8D+/UkouEZ+Yxe1NStsh1Vk ###j9nNPVCCKkp/RiTQYQpo/9yCMxmj4+l4D4kO8WSje5QK4xKXUUha06twwnGVCrrf ###H/Q/AzR4smIvutYJU7a1qkKEkmK3/4EKK5MC5VUMnR8NDb1eeQhTxWrKJGKQPelz ###0DfWUR/wZ/6PTKD8do+vCWK8wYt7aUraT2bj1ye7WJz6Z1qcBMRqX9NCMs1mg0M1 ###RDmvn/SWDVk1XG/JgfrJnvI8cLnCS4HlxOeg0zHQye8BQBJHGAacX8DOGY6Cz93B ###JPo2N9a9dKzzkuBJKK9kolxsqPhAaa3t9fHyrs9up0N5r2mRrlrtT4glzgf5lhrA ###dooQpyEJnsgc2IWIexY5FnYvsXi9xkuaF2dvTw8UvJ4XGYyUVSGu/0fm/Dmlf87y ###/6tW1tcs/d9fX9T/Wuj/C/1/of8v9P+F/r/Q/xf6/5+i/jMorSN4ATubX7aX1V3x ###uzcldtsadcq8+ivwh7Vy0AuQscnL3hI/nUBA69/gyUbiMpWrFVq8YSywnSpSXe+6 ###/U4p3SVrameLHNrysnWpnDSsw/Ei0eMin33APd4jnDByOBpyH65Spt/bNA4ZzmHN ###FV5uX8UcMh7rnBEfdmKPix5yMe+MRzpq5HA0zHKrdDptPEt32cjhVnkytU9jtgOH ###27/xU0KBM1jl0eBeuRpqlI9+d/y2eU1ea2sEGk7uPL4b4DcffqtHFpuTwWDInfps ###t4rlPA51CiR4T0To9rM7iZtzIpC5yYJvWP5X2b4eF4MIm4dxAR714xn9eKn9eCn9 ###+EY/fmo/fko/VaOfamo/1ZR+akY/tdR+aqof3ZbwXpI+EbxmKpCUYRcCE1uM9je3 ###Jeg9moZB2cXONovZgbhTIgCH24F4ozU6UaNtook5bvPlMldaQ1W8H25gk89Lqh/f ###7MeftZ+q2U911n5qZj+19H7kekf9eLMNWzGHrcSGtYhC9WOxkVJ8I1sEEAao6c2B ###AtbntHIbc1q553/MytWzNsJsK+fFVw400tEcFs6b01bx/pit4mVyjNkQ7scRfj2Y ###jEBAejzG/xjS9DJ31myYqsYx1WvN41DxMylqNoBrjzgt0baoBURIf0r11ZYtldk+ ###h3GhTXxqeaDiSEk+p6aP6MsB6kX94MsYXRM1NTRyaJYiYNwFeFFO839p/Zfjfo+X ###EJ/r1UjK/U+96nt0/7NWrfj19TW8/1lbW9z/LO5/Fvc/i/ufxf3P4v5ncf+zuP+Z ###4f5ndfkH9k86RkhQV4LNEltm7J9Xo25wbb2BnXuNvwFzwifS0xA2djsI8eKGXU/6 ###5LoUPlti4o6pj5dMKsXY8ekJLh/eNPHOXK/k1VR2VVEQ09uDSX/M4LSjILl/B6MB ###sSkp4NdrCAj64QE3EXDrFmKc4P7JP+q1gv4JcF+HS2K335wMgQcJ5UX+qesTVb+o ###uRhBr+iuCQ+5VtC9ZoXoK1CELDe/RtAatW8F78dgMmgG4151gWvqMX/BeAKogDcr ###agLoUKVDQVMQuggLesCKU0biACWPpA+i4Nd9paDHGzhJohsAcz3wpLtGMYUEDzZs ###jUAOwoFpPH5et67H4oCS3w76QXztojtAgKd5BDu3EF+mUvx6gt93TesDu9z7dyl2 ###Z5c0y4yuEAGoLOpd4XTXc2HBQY49Puy2vjzdvlStl+E9vOONNsUjCYN0qj27oG9K ###aBMoi7ZF9pRVvqxfb4qF3R3CBv/S5YIiSQC/TvCsHg0GY5b7B6aAfbXbEwDh4QUo ###9CurZeZV/sq4iyR35qMMICHbYd5aZl/RD+/Lf7b2V3dffiW1r3Tm0HhzcdncPYcz ###6KeC/vKLi0OAEIUUI9As+cR1AVpvkd1D24Vib1U29XhOk7K/lNhT7O+p6LCo9Qir ###+xQtVlqPD7CuVX+9vpGw7/F9re57tU2NoOkBEsSvo3EB+MYy70JS8Fd1YYYbPGy3 ###ekiUnFhFkwe2s2N4aRcQZk/zju722yN+2z/hx4TFC5TbuOrRtD0BWh9KxkWNj0VS ###JFbkSAKjD5JyD7ooFrPxPfmPwvIIkqAbUN4W1KpJD7ZdyCTvYC1200UH6DflzgAd ###HbJJ5OD4XdVvfm6N3hS0i30+Qoj9DQYd1rK30ZNCCzrY2mJvAIgiW2VXVf9J6l17 ###S1YRcd69YpoSoP7Cm0ox51266PYqudtO0B/cgdaT1HHapTVOK6FbhVpAg1iBwg4d ###h2m3w63mLfDE0V2JXanfeuFt93ocu/iFKcFvn0uIsmafPpG/8PFcgQHQhP2wnRAG ###QLMxbJfkSn4HVBtoJwKxcgQO2eMdUVofleweJj4gGlfnq5yOycDFqFchUgfGggOT ###5OCIqVjma6IJ2VVxMyc3BtjfvIggSCKXqwwQrywQr5wgEn1dzQbiVRqIUfDF54CU ###zWtOy6QGA1OjxeCO9e1uqHnUC/KQcPL9q9zDo5wJOzuYO1znbIqMvDp6iys4/ecY ###E1AHVNgQa3Ae0aWwyQgERGIXmKZ7g3gB3py40yBSK6zDpUEkCRiG73YmwI6vHjCT ###DpmUkFELnR2RqLMCkueSJ4NLMv5byM5+JD99WJxrzJpwFbRbaFIim0eXB8tgwi/o ###XNJ2CNp/D3hl7771gMkWWAhbp6d2jEleFAXRHHy+7t1HqNIIT7ySKAWcFiwuUATZ ###nBURrbENoSHpghSVOy25k71adEjxhxbLyV61qVYrilxBdhSdT5T9jFghAJXYV5k+ ###24xECP7Fllsw0THJ86TIGZb5h0nqhdE1cAjzokbvXWwq2a/RrbNrIz3KpM9VyI5c ###DysTjClgWTkjJNsY66LB3CWD49N3hxeNw5mkA28q2cBxiH/DgzzzMI/O8oTDPP8R ###rvZsMBo13+A0H3WEP/4E//Ofjv8JZ+Ms52KEMk4aMNBmfhWUQ1P3HIe0BdCcj0Uy ###dAs9HkcQhBwLNfS2tvznRenkJoSAK/s4oTNL1+DeuNyPY3PKdYq9V7xYbbZpTrF8 ###uM11iJldJZ1c23/eowt7/hYHl8s2+jXy0ad/ycIXs6viMIsr/Ufe/79utUeDfbQ5 ###z8sFIP3+f61SrVet+/+q79cX9/+L+//F/f/i/n9x/7+4/1/c/y/u/2eK/xR38y9x ###jVBU3D0/Bt1uH/46e3t6aVzSp7SRYaFb4bjTHTy73YmEVKGBU/smfaC6/NwaHfDf ###tHv3wTBs8gt9SrstL/1dLeCt2/YCjbhC0/ockKBWEGI8F6sLqoci3RNld3IBR+/Y ###6ElrBZ1Gt08AtQYfb2lMSAMD/nEBQKOej6BzY8QhPrkuPNH7+2uH/bPPnpSMe39r ###dn8hXUOswtuTDHMVmki1Z3S3YJpkirErT0KAOdWVbVbb1HCC91zL+LWOAP5hHESK ###tnTBOTEBpb8L+psI3IkT3sl8ADbgPdnNQunJbgZKjb/bj0DxCpm/lrGPbESf7CYi ###2oQ+H57NB+3HIH6aaXAbSdYNPjekzIew13Rw6QZ3Z4cMXsvGNizoCYjIELjCCgVq ###j94VqAMdwU/mZ0XRfQohSibLryEycUF3Fd+GIk3c8AtMmjY3hWYjqoCDFY2PcmNL ###fstHKRbz0c5lHtq5/BZM0aKdq+ivZEqJGuWgi2i9L/MQxeX3Y1MFfbYwrbY2LZr8 ###lWvyRjPxb65F3svDIPbmxSA8Y5GTqJX2Rsbez7O2e3k2/N632vCeY21TmWDKjNsJ ###M44vZ549u5dFzmy2TZu6oNYezTEbWJs8m3Pv8jsuYMZ5ZOzXXAt2mWfBLi+/yf5L ###YrJpgOsH6mWe5bn8nsuTxDqdM8Jr7rtJb9wd9h7KrXZ7An9gJoQ7tGKH3BbXQutT ###5KUhzWnCTsgK3QCtQIzfopIdrBNcTW6oSkYRFEkLaygykuOF0vTMx5Hg7GBmri/1 ###Nwbjc+ylxO8vY99fxr+/TPz+Mvb9peP794nwv4/B/94B//vE8d/Hxn9/Gd9oJ1nK ###LLaZbptJDTdGmhtutlivFQvibFtd1p8ur5I8l3vjZc8F2mgDsFa9NuW2yzc36Nfg ###ijjDq4QZtpNm6Jpg4tFtTFE7u+1JenV2hUHY2t9tYAQ5J1nLnCRnMfFJZglemO+V ###JwinovIn//DqyUzUbqkdONAahoo7WfOss8qeYnLMSnRJjJ9TlIXrihhTAUU3q5j2 ###AcPP+90ryt0sLmRVLyiMHh1VzJ7MtxXrLY8QgbfoHO35GU5NfE7RssR62IhdBrvu ###rjVgj+LgqEE2Egap5YXSmI8Dj+RdojlTufC5n4zMDVZ0XYiL4fWLcQQyram3mQNZ ###h+nD+fmHq2oxMWI3mARe9fNuhapfsDKby60gkXzbvbnFf5EPSHy3I+8KbSOpaBRt ###p/j6RhH6FupaFZuQxRRjG9VQvqkLQymLoTxPPzRN8haKIzJyR8rjjp/3mNMwUq8Z ###XA3lrVVuBHQB0Uzjaqbr1PSgWKavZFAau5cbCWBsRC2MI8Q6IDbY+G6YLHvCSzNf ###RqHQAvVbeYNtkDPY362/2Qv2zyWXnxB9vaW3Pj41v4a/4WtoZh4yBQCk6Jp+4jIA ###3WuZv1MwAA2nQQGSu4kDr24hQTxIxIKNBmxv4EE8SEWEhYfMbcEdoVLwAA2nwQOp ###hwYehGfg3+0HufGA7Q08iAe58aBqOmbgIqr9+Efgg88mm7q1KpUZm1xvaUyppAuC ###V4/e+jjBlcJVkdtlNypF185XjbLXS4M7cx8bbfNPcpbdbU+zYkxU7O7MiSbNNJM6 ###zeqkuWc6C73GZ1qxZhvR7Gyzrdcy1Byjbf7ZwqM8s02Yofw5OdHnWq9NN1epz3FX ###04w9KhpF+0mfIC49eZDaOzSPYQgDBTQn+lTVk0ORudlkM10dywYXGn0beDO3jGxm ###yFqZ8OY0vE0PbybRy2YJ9G5B64SMBEMNtCSyFDalPPgTEVM5cfg4qPJc82tNzRvo ###9JWdzGlpbcgv8mzzi6m2eQoOQZtSOHQCkrmJL6bcxI8BJnOHXky5Qx8DTOb2u0jf ###fthsFmDc0OQi9YsZSH1GqPDA5TsrhxwiglMSF+1qbkwW7zbUdowbGB0RJzxQA4Oy ###l1fjpBBBn0vgyj5B/hOmmovWrOZOepvkmvPkD570RV4yvvi+ZCy33xTTxMjE9Gnm ###IuOL703G32Squcn44o8h4zlOuvF2Ly+b0pt+j/Utz3nHIvwX+ad68b2n+phVTTj6 ###qcZgLslIlCOcj/5S1WcnQiphzqDqFkg28MjRqoUZhIpc3cWnBd6yDA/JCM/drPJL ###xnwKOYUv2ThBBEuYceJ1Zv07z7h1JeDJmKxq57Y0JopwBWFLpEB6nARCXSa7oUWI ###ewFrt0bB9aRXUkOq9AL3o0H/ht3fqoKuwa8TDBkaD5TR46ef0MbqJGIBfOZuVe0M ###8s0hp2KaG25RMcxHd92+HFH+XQDauMqLti1GBh+JNvrLNj3etb6YY7S+TDXGTo4x ###MEGiMQg+KORafRqhAt17SK2Mzwr/LuODCisWE0T7PHbURJUQrxJntOmssKs8+4Zq ###v2bLMalcf2ZxJS+EeWyWU9oq3RD6M0EIh2P2rRe2mf8ql3NDmOeI/xarnB/CzFWm ###NvNf5QwIlWyb91JElDbW19pyC7qC/8krfWPFRUoFOEVOr9h9t9fDGE6CO8CS1Wz3 ###x/Nmq9PBxel3tOvUKINEVq1lUevZuHUA8Iolxh2MVM3lKO1OEjJy6T/mnUl+V9Iw ###jbJwlnRbGQU1cGdY89KEfI3+nicViXkdqvp96u73B96vdSn6grxb8ZqCPnmR0u/v ###qfA6bie1fnMvT66LHn7Jw5Jc2nBX1WsxWqWdlXuF6jW+QvBv8qVPvrVy4BN7f5rV ###u7VieK8kVgw+WxEfv0gZ4fec8MdvrvQRstcO9axcThSy3aP4jJ6OqVLM4D3h5KrM ###/ZTzcxt+pjyO24ip5lJRObdhWaEGbEaGo3Zw+ZH8JomemeI7NMC/9N7TLoQj9lPO ###Zj9Wr9x7Nsd9s9597mXLc6h/Ly5UngsPmmItBW+iYf/lHjPfJXjErMrZzCpxJPqU ###TXXvrg9ppfW1Fj3ypX578v59njC+97NHmEzDpFRGLQz91QNQiaBL4iguMfFn3ARE ###DUosh5u1lrgrT4jf+/mFqTwWIRSFqiOkxLj3vPrTgZf2VHi56/abyRHORhuFF+MO ###/iryPZ/O3iBNAS6IMk9a3ihNc3skVA6gMs863ihNWZs/UJmcnDdK088eu35o5pX2 ###pyLDRIqUuIen2XkYBm2sxycCpmTpC9YWGWvtKbW+ZJMjb/NYctzJh2MYLJsaqdE8 ###qDE/UNnUSI3mQY07OTcuDJhNjtRoHuSYBJUh71COnUyKUq3cNNXDTGOe/cCP5WtN ###tLkbQWC8N4Jf9INzEDOSL/8e/fpC+v/qzeWvwuVXkzlemH3Fmut9xQbCvkyBIsrA ###Ekdrtn+caJa8M2zUykcx5Caa3v4T0Wuj1oHbxO1tNkre3jZm5SPfESv2vwazTrql ###cCQZLBp8eSdTKsWTLFkhpVFqJJkyVGUQXST9TM3/eXrSOGq+e9O8p8ryYbPXGg26 ###rWftb5X/s7Je9+pW/s+1WqW6yP+5yP+5yP+5yP+5yP+5yP+5yP+5yP85U/5PlMxf ###7b47bAISjo5f6sk8n8D2vu7ePLt9EuWWV++4LEnv1DMR140p5/HF0ury0sUzdkLi ###UYmdwol027rrDIjrwV9HrREIpx2sPfjkYnAlD8DDa9j1XSxS8GbS6o+7/1YFURrD ###IGjfspPG+dJ5awTcCLhXyN5SPbnGeAScZTICpvIuaGMpBv3rJ0CEABnsnsPDQ2R7 ###z7AIwTUcr6AQhONnJdF3aanBC5qeq4KmJTYcPmP1mleu12ol5j1/7sESUPFUMTWs ###0gms8G7YC750xw8M5UMmhEO0AkX1Kt2SY8HWBeM1HIb45fvmmybQU0mvHgk/54Nu ###nypGDoR/12c+fwnBh4OPGdUuzZIvJgB86OYbb60UK/uSOLT8mXZos8lBSsUZWENt ###vA6cl32qYFIIPgf9YmYdSkc1mk+bjkhKD38t4W9YAcNZb+ZA1pOJvcF3vD7jtlU0 ###jlc74fWGBCLkYNJQLu2ATOH/A/TxsYT9bTq/iMq0UNmgAhbQXCFibALlsGIp+iLq ###wc8a02MfWTkVCH9qIHwdCJ20qXfXBa800kdTWFEdleyoXNdaxEexqgC9RiGyNxgM ###5YKAiFdgnxia5+CfLVjLMv8VvXmM7Bh5lu4TupbaqPxkoHI+axpH6af5oTQDrZ8s ###tOalMUSOH0cOYSyOoEfSmwtBfG2+F5L4aBrXiAqsnrRy8wUxY5hv0UQcEeqcOYU5 ###BTHCd9iociSBrK9Lfwb7T9BH7RPm0QHdLnyM3Sef/cf3q+se2X9qda9aqa7/F/xW ###Wa8t7D8L+8/C/rOw/yzsPwv7z8L+s7D/fFf7D1ZsFEYedkgCEchxnaCsnShsGBlp ###gB8MWw+9QatjWkRMWaoQyYP8xaiJ98SBbo4IYbT9UkoRyuPVMyZAGjHr8zRTRNDG ###QROaDMOLVv8mgG5LacNi1VA4pkO0SbTGLRheWKWSh3XbPvjPEeLvuN8JvpQSZ6va ###yQK2+WabNqxYlJO9i4tS6rC91g2jpWtRTVT8gM+7i5W78RHvqpNrWDwX90F+gM9S ###Z3sJJxi6XhlnaauHMgF+C6SGUkuaradbYp9K1MfZ9XUYWJWHIwy0rsJBbzIOmjBR ###sQydoDduqb83bdMdEFH3ywcG2k3z5Hy/eXYBpw77uGnGmW9gyd1O881GQkNuFGvA ###djqG3XTM9wbSoPhVqNeYt1NbKjPXq2oMWtpTvmnKO2KbUfMPGnXJgeMZX9O6sZTX ###aTiPWE7FOMjmSmuKEtGv3HJLxZhxeaKi8tOOES0xFkVny9F8yjt81EscdEV/TqPz ###j/ClQ0fVesU4d/b0qf5oi9Wdmq2+VGQQ/P13qydffmevrKultkqcczW77Q58p3Mq ###7aOyKtWMD5scsc13uwfN7v7BUYltsKSkrTl6d/TcHzg7TyAWmyJu4HQJE5ddteaV ###lsPJ1TUxQC3FsMZLANf7Zwd0wB0co6gAMtPPBv6gJwcf0SrymhaKiFReIpjiL2FV ###FPSQ2miLtv3B4cnlbvPl7vFp881bkAphiV7D77HHK6YFLHE50oYUC8SZFyI3c9UB ###J7DNgyEc/HgVw3FSIp3kfoDH6k0QvmCvG3s88TBXYIDRXz2wKjtp7IXfFH+nzRMQ ###nE4azTeIqFzo0Us2Z+CqyqTzuULVhwTO8VHD4cyrw56ydTHgpN9F+WkjceOAwomi ###FxKopPvQMFl3ucm6C1iS/Lp/1aS28HRlxaD8fAvTzbMw3e9P2N08hJ2T46DZMYvj ###5IEQ+zGpSR2bw5BMrPt75Z39PU+QVSGBsDAJBSvSiRX7us9vOEOD+qILxkl/2Gp/ ###KnBZpCRljVK8p1TA3dbZODCDEcrZwGTVOxiv2x6DVHNGr0Q/ijgrJnHaXcWJtHtd ###SAS0u+Jx4uT2b6QrNC03d1EBv3x7cBjLgJ+4iCgeJPXiXkVEMC2ikPpwC9gMYSa6

okay the base64 keeps going and it's still giving main character energy ๐Ÿฆ‹๐Ÿ’–

###4bMqp4ATrfbhT5c2zWsMPRt3W9us/HjkVb4RhsrfHkW/zWOtVr4B6Xy1OL/GqRjd
###uw8HPa5oX7foGlyTf2zWjxsUwTrdw+jHo4tcpwCfJw60Pwium2981ykQb7TF1qbl
###67FO9OUz5trkc01g8xa5a/wU5n/58/lh893Z8f7hgaj2oIs7yUqEif5hd9y+ZaAA
###GhJOju+FsgzalvY8SdFkKiwkt0RLy8JXHVAOXPhzI3n6FtUDeAd4hPJJWtIv/phq
###L9vWsayelm0ATgw1WZ+N1d8WK2+glmM9hjPQi8HqBKdiDuHc2s4PrQcr7PnmUoI9
###xLVIcJihI06/90BGB+rNxt1X4y9js9nzFdsrhh3fy80xzW/FPiKiFVKSixMalJY4
###XQfV7IpG/CMH4Wj+NBwILFnSRJ2hJB6A3kB/m/OzGsevrh0EGBPyOTFeh81Pr/5N
###9+E2Fk0IEslaLxEZn8a0g5rs1oRgy+qArUZWgZTvIzxtsaqfX/5wTkWA1LpxkUqO
###/uRkNIlT9SjfpVNhAhtxr4/mbAIESTEtg8kozmoNtDG9J7zGgk/4GHwTJvlyFBK/
###A8TXdB4s1g942Ib+WD+QMb/A77+7i6SkjAM8MT4OdDf3cfwp5+PPNg7o29PNxzf3
###VB4BQx/SpkvxTifJ9HPdJRacXJ6bVqt8X58fXnA0GE4/aUKZ+sIhi6l3W2jDmA5D
###8lvBBGA+zWEwatI2SkANbLZOcDUYfGLKRh3Br/znKtx/Lm6M+GTpeWmzBnAIOuFk
###Fp+62QCdmjbQt8mFnOIs+pnRv4YjZXNoDsej8INzwLhgnyE3JlJY2G71rEM2s4cE
###4fH49ODw/PAUL3wtc2jGOjQRiCCRBq0WFiVOgW6tlwjf9Cz98DBA/0GbOciXyXBu
###b8f88VKkabeSsem2NcWuO4Kgk2RpWl1Kw34Dv3TgnJ5vIZ/fzG2owm9Mo2NNx+vX
###RRRoavwnyNLwv3aTbose6wOY4f9XX1uvWvGftbV6feH/t/D/W/j/Lfz/Fv5/C/+/
###hf/fwv/vD/P/Owh6rYegUwZ5qEtReJEDD543dGEBh1e3Q3nnYWA7m1Ncoiqk+rDJ
###2McLkeL+4kDoz8Ay3/hrefzeNhxNhF/Th4+l9GGNuFTxEfvA+E3ox6lDLL8033iV
###xEEjvzce8pgwzvSRnffNN2spo6ph38s40hwDx4ed2Lim6+g23fJsuIaXw+612p/g
###QOgwcZ8MhIRfOeHIMVt+z5YHyXw56QAbj+AkV36FLaoLrw2fY7Yw7AgO6TAJ13LY
###C2zEPnzMk/UzR+gs7aFmOA6GzRD2IRBYveQa1qBkbM6w+cwk1e1/bsaGrpccSMZE
###eoHkE6nDO4cFxqH93E2ab/xKNiVfrB4wEJU7weD6eiYkm7PldMAyhz3lfrkgOIkg
###aWRV4TSxyQK7JfYLSGMNdGkO0RWr0xzfDfkvGHd31/oi/mh9wQf4B7KWEjJf/GXT
###3S93EMF2wOOv+W8ggVXUb57oBcaFh2v8N3i4FguZ5j8XBwgYrAk0RcDULwgY/4ND
###yP/QOIIs+h6fO0wrHIzGH9QT7b794PAE/rffbFzuXoI48nHTzemhjw8mtlP6SPPh
###1SkBLUNNwBHxcNuHJB0wHV+ACAnbzH0IhH6YFkFGH3yFcvcR433Lkt25YuULyf09
###TXlZxtI8wkAndxYpX6BtDAf3fG+hWyLKNPhe7JHoEl1imIeXi41gLp3xSjkr8T1O
###kd+brFsuG4ZSOVX0jdYZveHUoUUd63QuLzRFcUUjX7lxRHIvN8PWybc19MAlB2yx
###adrdf+F291/YlsQF/OEwt8utL6ERaYpNUEsWpn6JnMMUJjiDYaofKj2i+I8axvpM
###sDBmD590jshhMroh3aMQMchE/yb0DCqxtLdlzzEYoYAvr1EcXQyo3ZEo7+K7IV6S
###Awrh35CkYgk0mgDk7+gRad+fC0Zs04uaXBwdkmPLT3i1H42lexW/FpvWteqTR1s7
###nCdsWMQqRx03jk9+xOwvqEw0AEgNs+SvC6D8D4fYHt4Fd9S999juNW84OUnOT9yz
###/L5glL1c2I4t46Ph+K5jplPm41Hr3jU2Z4lm4hCREzeSoxdvml5MWGJITWKPsfFj
###+Er60mbY0Q+yLDly+jcr6hgV33j8myTmBkr4FHxN3wP4ehoXXtf321N+L8/vCj+/
###o7M76jSxv4+bid15vDt/oxJvk7jrLFhUfnz0NoKeQPyoVVOdk2tVpQ64tp0FnE5K
###kUxfq7o+/ZrFv6ZyH7YXbnvajy1MOdFszda1st6Uq/vtVq48w9KJA2mmpYtPIWMT
###WFpAJqrmiHlzApFSqT/dVqL9L/bnUpk14XMLqIpHW3jUOnf0IRZaFbYwFF/DZzBS
###rBVUxRK3wJEYCX9II4Zaj+KjpuOlT8dk7t94Op41Hc3/BbmBhGQrRd10uJ52BpOr
###nop6xmsp3g0ePHgDZ584UylGmqSvoUrK/KYOsKK7ascJN1JGDQFe2XFiGoYCNIIw
###DTeZE7DBLlsTSgJe5/ZOnQBrYwxGY8x/CCtA18XDIfx22+pd44JwcgMppdUd3XfD
###IGtFZpnidcHYpDsGjaeYLxKPF90I8kuKsTuF8zCHTSZvVyvZNhfHMJlDqGF0gLK6
###S0fgto0qd3dIJPetoRIvpfnTogWHBhKzOrgHiBsnth2y7NRYnaqLRKE6br/kAKb2
###N6UAYpNZTsrUifyRFBibXaY04lIi8PYfvRPQHz0Ix+pWj3wO8MV9t0+Br8RflKMD
###ch+0QfYDWYenNwhls1J0HHSvWT/ApK7owGFRH0DQuh4HI7xwCqPpfOTlrdDNQfqY
###yOs+AVIyqiSw0SysMe9vu72gwNzKv2YtlweHKowXR65mTo/HwsgFEl2mNOC9uBvM
###gVdLfq3PbSdGiklfxrGSi/3EZ/+Lu+HXZHg17G7FdlsqvMa65OK+8cXIDe/XpUxs
###bxsgJYF+NQpanzZz9E8bF7eWhmDKBRzB72Dz5l2O3lgIKfZb0fNH9q9peKZ5q2IP
###43grhpmS/5nnhD2M4+1sw5j3O/YwFfcH0WWOicdsjsKTeQZ37eFDgcuNxpAl7Zns
###tWTdmC3TZe7guqDdxGWY7SjpRHsUoLubCOABrt3F9BPoeia8xQJdzPwGIqUp3G+b
###8V3GUVdK7r95cvbST56tPND5nLkx2pqKtQvtaOAepooNW5h1/AW7BrDoxAlGJbUl
###6ZzC409UFlNeMjJOWFphJPlErMpFHjZqU+8p4+iVvEhx/UQOanBMN7eMQP8ljiEX
###sCK1QAwoGcX9S6Qgyb6fskLKFi3Twf3Rgs247TQ639lOv4ZKjDgzetnaZixPL1+X
###jNlVEgiZLpDykbAbpgqHKQ9IRgeKELSoC0Gl4tWfJgIh7v9PXq+DXrNxejGP5L85
###6j9V16pW/t9qtbbw/1/4/y/8/xf+/wv//4X//8L/f+H//8f4/0dPxhO0dzWjpL8y
###PGCfy0sM5CXkHujOjZEAWpSAFhLA5URNxJpfTmCtWlEDuhN5Ttw5gq1oAdPfmP9c
###tkY3wRgdt5tXwzAlXS21Q8MLpkrE+zBWgA+Ked1/P5VEkVpyjjk9awLNn13EXDiv
###QQZovqlvur2lyS3zEj3Yo5I3DehVQLQqfNxhSXpYwkpM35qi6V5nvixRjr/L3YuX
###h5fNC1AfmnvnDW4SsB7qSU6tAX6IsshZb3SlLaHJttWbmargGK2/9zGgYfb9sIdr
###glRxetHs7MVTMegJtfT0FLbiqnAsMaWNRtEDzdO9hAxtdueeP0Pvr/cykptld/F+
###LyFNAQpDKOVIEkZB0quwu5CByBeEQliBEdutXnvCc3WFSUi0k3mYUFrrWt5mF4cH
###b/eBeI4viYi8SvN1A0kpCdajLgmqHFLa9LCmBCJNnrsmyaRigTNrhaj6pNMunNvN
###xj/ceSscxLy1HeGbZ6VwWZvEtjXyGxXMm2IbH2a3othPnRVLS2zaHwtAV9cu1xK5
###jnzDNN+s25fb3FsA3nKqeuOZkLIV4WXw9qQgMVByf/RRpV9y9eYCzmG9/ppO0xbz
###u78N+sFnOBgo9zIqWH0ct1NCHnE9CtD+CPLqXcBT3ybQOH7cFF/G/a6TECidMGIN
###SsgSymbvmA31GO2loOaFcefJcuUZ3r6vm1ZXw44obC5UIn2R8SGn/ef8ZP/Z7dxN
###Iyn2n3q1btf/9tbWF/afhf1nYf9Z2H8W9p+F/Wdh/1nYf2az//TRAESSI4g1aP3h
###hb31R66sD7LZ3nu0HB0eJSkYlWfPn6vG75rnx5f7r3gNgAaoVpdNNBq88Wq8sefV
###6s/jVpTKs3VK7CCb6daStK53f9K6Xlurr7m6fr7m7FvrGvvhnZ/svgTF056itxEh
###bbd5+QpYR/PNhhMbaxXVFNjCQXPv7VGzcfyPQ0dTz9+It3292/jRmVzT7I3uptXX
###eIvbPD59R64ZhJ9XwCg4oPh11W0y8/9VZWjk6Owx+JByW8ZQE+/65Ox91DPbSOp6
###A4M3arG+ta45xg8uQJ1sHu3uU2CV/lNfW3N1XXlW8fiC1mMLqpUdQ8K+AHFqrFkX
###O4HTuqhZGQ+CttOyeBA4DIloytu0xpx2tNI0o8W6FkZUd9f741GvlNS18aVlCnXV
###p9eMGXeBledCWl9Fkadpa5HJn94gHDstrCeDEERhTK4es6Ta6G/e9CZBk9dMmctS
###dFKW4pH4cqFrKnwF/RuQBOP4Ei9QjNOHEPiShv6F3u/U/0eTfvMzL77yLLydq2q8
###jnp9gv/Hes239H9/fW1R//m7/PyF2Yq759mKe4n9T9Dql1+3Rm32DjP0Jujtf1n6
###C5YvnI/u/hd08NLUd+p8Dio89DIHLR56UYo8QfZYbR77eIw6/SwJjOm1+kdCIhV7
###6GYuur2Y1+MVfJzXo3X8v6BL9KPVfOxF0/T5xnm8uo/d/L//Rwr/3/7GZtb3sRtL
###5WczqfzYkUvrZzNp/dhbXPFnMyn+2Jeh+7OZdH/sxlT/2Qzqv+glZgFgU1sA+Mo5
###jABsOiMA9pNkB2C57QDYS5YpgKWZApb+8sMqMK/V8HZpCXhXb3ATNu8G/cGz8Zex
###ehACDwj4o6XuNfvAnvz3X56wMihZT6pP2MdN3Pt9kTf8dsCeTMLWTfCCmbIO2wq+
###gPozbI1vd9gWfy7/wkvDnSe8hy/dMfOWrrtLS/uvD5rnu5evtv/bW3oHdHZ2If70
###l/A6dfu/q0tLZ+dvG82Dw9dn2/8tm6+SdNsJ7gb87f7Za9gfh3YDETAmZlTusP/W
###xohP6hJDxMRsgClP6AbY+GYJ78ujD04HbBz7hl7/5WDQ/xv6c3zipwM1u251ewy4
###bwDcsd3CI1e9kj1QKNkVH+IvioMDdwwD9JkZB72HCIUVQiGf2xf23wpP8ZmRzoYH
###DJ0OUUtrPuQ08kJpeHB+8Sm90D+xVpCTw7bx82RJ4RMHRWJLabe0hEILF3b6DFTz
###is8qVVapscoaq9RZZZ1VNljlOboSeB7z/KXOQDiH4MwDY4VWEZ0cm/+NXT67Akh1
###fBirTSkbzQ/4/CRaVOu97hgWI2jdcUA11DgG5NEFXQmktjJIg0jYzMuGenw3fIan
###386OuWeZv/PUc80onLQxdPF60us9CLWzkzAdsdIdSRdImqKxtr7aNP5b32esPBLT
###SJ0E9J4+CT5Ab9AaN0Gm2/7vv0fL+uS/1XNgQ8Gv7EnliXsdeb4sFIXatwEK0tew
###w/rtIH3m4qvOAD7BxaTPrY/dmCCS7Qz6QS7a53z1/wz156B8f3rKjw6nPwPth48g
###f2sm/+kbQGwB1GNx9iG7bYESNMQIno6xJEs3oC0p5xmTE/zOWvef2N9+Cyd3K9v/
###Xft6eHrwGwj6/TF7svs5GIGcQSeI+robPilB53erpxcl9uSvT77+zdG7hugc/fPW
###aSNM4/8xaq9+I9NIiv2Hfuf2H3/Nq2D8T6W+Xvsvtraw/3xn/x9YfxI/he/w94j/
###8tZgsW37X7VWX1vY/76P/0/cAFiJGwB/6g5vn52NbtgRHp7CcpbHlwczrHOjB7t6
###sO2IZEf6cQDv3g3I03B1mRz35mVDZJYNcYnNxYTI5mJCZJoJEf94tAWRPdaC6IZi
###egMim48Bkc3JgMin9Xj7IZuH/ZDNxX7ITPsh7Zk5mA/ZfMyHbF7mQzZX8yGbo/mQ
###zcd8yOZiPmRzMx+yOZkP2VzMh+yR5sPHxYBtheNOawTvdvT2QW9sxoUBdwJpyXxG
###MSPmo93zY/NBOG61PzVbwP6sj7ny1G6F1kAomJlP4By9jbdpAqv4DMzRegOKxWQ4
###HIzG3MEpPa5NYO3o+KfDg+b5GRCSDmD3S9BZBQ6LTAw98jn6UF2zZhE1Ojk3cKz5
###HgGFnAE3QveeI6C12kZlaYl/xs5gNociiu03kfJB8wrAtaBCkIPr6xBd/GMtZFid
###0YIeYpgB9wJp8LF4RhgYytFNazjsibPe8bZ92+r3YfaOVx2sHES23KAfJn0Pp2o7
###aKb0wh0ZmmMqwRl7C2fNqHkFR+N9tzO+dTTArDZp76kDAqKThIDPAzjMsQBAd+Co
###rXAUunttfr4auTq7It8dWGMQZMaO/kRkEw9yi73l87WbGCPIQMqryfV1MNqM6I2s
###IZLg4FA7vOTOdIybiNQiONbAbOColnH7cDXqdoT23iRko3+eYwafWyC3YKTPq/Nm
###eDe+9aGdXmvkc6tH7W6HmKLoQ+2ja1HdC0X5mNLepZAZvefeQ91/uzpIIyLaPlf3
###zfAea05vqhhMTOCD0h2PCxXiMPBC1gs+B71ilKtH3xDdUTg28UEY5ruJL+qHOOtY
###9j+KmEhVrwPROMLqsEcgwPY2l75uUsTuJUZFkiAqqx5dcxGPEzoJpyDmdtvP2BHC
###AkJeb3LXR2VEyIF33U4HtJMCrM9gBHpKGBbhFWg9t4MeaEKXt6iXoLhrfgpEQvQR
###donECphelhutItmVd02YQb8rLmKa0a5oU2ryPanWpKmGDz9sYLKfKCLL80AfxbTy
###+F+Y/uneVnnn9Z4e2eXVzCavscl7o4nPX/qyyXts0rDaPDfbNKjREbUB3KfOhxCe
###bz4xYMkMiEfpfVR6mPuumvC4plXLnla1OtO0BCv4My5U1X/MjP7ES1XbSJ0Ybn4J
###LJ4zZUriTdufcy7kVVfB+D4I+tx0i7xA2FhTdqSx1Aod6AVcB0hyIlT/rsq/cwOc
###AC/6tK/yY4jA3j88uSwP+r2HdF7SCfQF9D/C/2trCABwpri8KuoSQS8K4b8pjEcr
###9JUQT8jL0S7CLTJnPAd0A2TzJhhT5YkCvpGHl8whIPMpgDDXgDZ7D5RwGsVC/Ul0
###Wo2UkHjNCrKzLQ8rp8u/2A7zi1EFJB4/WlEZvGQc60sAS0imTRyowJ7agER5AFgB
###vkzqNPbZNuwOEPgK9gvRnT07aC/lYBNhCllG+jHZN2Uu1OTrYnHFHnAljsivjhXq
###9rtjvSdc0pJOYUdUzC1aPf6XJlPL5SRn5mUps3OwkYalCrAsJxqtaDAaGctbiuGT
###iwTd60LhKPxhm4jw6VP8lWiQ/+rVo1999Ss2Lf7+u0IkvHz6NPrDh3dqTQvadDDN
###Awmau+fnJ8f7u6h9N9+dHZ9jVfusdrugP5+pbnN8AFIsKeSgp52cvT84PNn9uRij
###Nfpqb/eguXvxUshI/GLw5HD3ooAzHC0X1bIlk1JRCXb7IA6PeRiNSjQidvt8t4kJ
###+iw7JhyXdyxFUPskvhGirywFE2cV72slTnG66okltCR+VxyfR7tattZIfrlYMD+2
###ICrKKnTYr6mhCGC1PyPRX31zhM+P5BNt4Y5hUwsYCmoqJVg9OQE8NrRMJ7hy+oKR
###5el090Qmc5FkA3pYa9Ibc7qJTA4qvkPv/ll/X0CM+oKV6t3UYxK+4+ZdLcwg/TsY
###pskzjl5YkRLbAluur0C9luM0zI+3mcdPccdHmNkg4aONhG86oDaMgo7ju5SBhq2H
###3qDVQeJs3oXmnHznFyBkXDgDRfCLtcRh2p+CMcaqnAejNhrsbwL5kfMDtIn08IL+
###IT6K5/wC9P7j/h7INUeH+/YXSR8cXP7krhSQ9MH+3kXiBxbrw21qsz6MQIGd0wXm
###8m93Cziw7BObDlD5pETHpXV2wwaD737Ypq119mP2TjP6b497WvcIVJMMH8cv4bOT
###49OXhUqxuJn1HQ2G36EzycnhT8eXPxc8+lBhUph8orKUKMa3PgGHVuYekPnfAYrp
###jkawgkLYuhaVtAGxvfK4e0cXKEWdKZg2o2gEMaxhEGLylHx7eRa1MhugQrdyFC7H
###2YF+3m7HLX+cYpQ9zj2WaZJztzGscrLJ3u7pwfvjg8tXzaO3Jyf4V/SBaSZMGVgz
###5blbadY8huX5ojem4UyxvVWvotE/lUNnulETL8RqmCup4D9bw39xMZHF/03c3rLe
###YPCp3LoNWspZaYV5Zlu8MyaWNgp1pUuUx0YxUSeIuGU1gha4lEaVCXY5pCG2tcWk
###hY4Q4zLMOXP/9Lp9vze4KbB3uxd0f4SfYLDvPmD66Kj56h9YJEhVNaX1I0uSQbli
###iV6fHcD3P+9dHGvLnYs2lmxB6exHEtKFsodbZdjqcKNeYdJHwoUdiBIFW+60xi0u
###iveCPv+lH9w34Q8hj6NEBn9hEiv1wqHByGY7Ca08KYGzQgHH/FD5+LTypVrc3q5Q
###S6loIgDdTe2PIV7k929KrH/V9NfWooRn4gVTcLEyzkF9CyPJJjvbkTqnpSgSPaK0
###JVqW/SLQzZpe/g8Js9Ddhp5hi3R3tuE/5XLRLFqF8+muiO5WSHHmz/SE3mLW7Hc4
###Rr5U7RceJbj/UtOLLImhK5vdLTn57sqKc2wakyA33xgwqUmurS2LF2V/0zXVleqK
###GnFLoDdpbCMzfzwhW378eTPjTSHtq4s0LZgigqQPon1i7oyboN8cD9pkccAdyvcG
###7SE8Qfifanuauq3cOki+wag76NBYZv/Q96a4wIcGCodUL4UV1Dhsi4GGamwRpr3c
###0iYvulpZETMTm4CzF8FfKOHB2enJz2aPAAzuAjWdssVrTndBrHiPfxe3tiIiw89+
###x91DA8Pm2dqq6iiPDU9iR3x4RBRPdJ8IwevDg+O3r6OzUEyOijOyikFPRrZ/NbnK
###l42KDTh9vcViE+LzsSYDZ94rblXjB9Bvdv/1WP/JCG28PceL8INDgdNaDpwuaW8l
###pW1vYwO+iQVhE2F9jdJe6Le3UaD4VffXCZ4JeD9bsLNpyqsWjJju9mOB2y/wl+M+
###et86A7i1IO6YoZG/3Gu+8TdK8U5f7zKsx33dbXdBewjZh+rH/J3uJnS6e2F16n9M
###CjeXd27Ry4YrJB66pdpyIurF7jHeqRkevzyYjEtmp2cE6Rl3aU5Caur06fh2LVSD
###9yYi4guypHzwGc7oqFMyoo6BugOVmxWFPHJ+Qa+Y1+z4mF1e7J420PXmgBVAyAyZ
###D1uD1zEJNXwUHSH8n2I3m58BC7GH3f5nvKGznu4CgktsD6hBnMy7eCDIquTUplig
###5cfny6zgPVst6LXmPdgjG0Wp3+zyU8PxtZfj6z3H2Hu5x95zjL03xdh+wtd+xtdy
###RU+DG1womq4s2UVyNmg4Y3K5ux+gSYanfFwysoVWeLZQlAVi6UHxkoUqZZTwX499
###fMHeeL6RNhKXlsqPfGCfljmt6VVFkB4w/68o5EF4Xhb0oBqJt9jMw6SZ+NEyUcMK
###odb1gUcfqLYeb+vH2+Ic2i04fq9a7U/ouPemwnHTAsZqpVCFvvRpwAARPaNQIX1c
###hGxBjPd22GxPxoPr60KM1xKb1bY0b9d89e+S0YoYh7YxlrlzgCXARyZ2w/4u9rX2
###jJMOq+Kq8Q0AO5ovif5lGxSg5yU24vwV//E51oxqJwpkzAlrltZhq7G0naj2LbPq
###M6/mrT2H9+LO87lK48lHNTLGNrH6q1GiNX+vJQ2+IppXUJuVVVmMeYiBsRTo06fy
###ry1W9dfrpMnRUUvbZ9sxPt46Ys7kspb71W5VefbcLzECSnQvugUCvMKSwjCHD5ib
###F6RzpN5NQXhYvw9ei1fQCBtibb0ydIkTP2r/C0vZsNG//Ogrsch82xDgm9pjLyqU
###JVXbslhoWbJ1T1FG1IEAp8whwJytR20CAIfn4xKdqNq9siCP6FvWj9/VgYuqz7/n
###Df2S+UxSosQaDGvj1scVYL6v6Gg3Nk9rBA4npYWJu7spnxYuLrV6VBeoxIQAI0QO
###uQtpe9I2VAaaotCOC9EjOx20Y4AVzz3Eik+D4GvXMF+F/53VKRfyvincaohHQE4M
###86vJMoW95rrVCdKYpos9woMbz/zTL2mnEXT1ORj1WkNNs6OLLpuJxse97/Y7g3s3
###e9UtGPQrXefQjeOqvDq48eDRG2/t7PSwfCP0txtfe+arYmTSACBgjZRwtQzacYCO
###RJv2c5x4id2r5/doa3p7cunVgZ+iaavAp/OhC/hsf8Q4B+3PKKcyWloary6qfuH1
###7j59XFDdFO5LN76dmltMBvB04wGr89aivhBQ6O7wJ/Imhu9f7Z4cQc+6YANyQldZ
###ZvGsT3y54n0sxvo2p3jDi3hHrfD81rvfjj0pW+g0XnNjRfzZivbR12gNYQEj+ppi
###Db8/nvw/BFGw63Uv32XjArpNNy2FaXwJ+IPlYDQCbSQyxkjPD2Ms4WT4jX0Dvo1r
###wGM8A37TDKUCUZGmSQ8im7N2767sDKdvT04iwwQZtQsGYou0YuTaXsjlUYCQYD/b
###1PeUQO6enJztN492j09S4eS323HXFXR70O/cSoZrigLPgEEBIOlKeC+odTj70ZgE
###jYqp9WE0tcEIcTEYEfBwrFvxNfI3rrrGA/lrwSJr97mGN05oOW1ekXMEbQ6g/R+i

###dsXo121xl1Lj9718geJ3bdvb6n6pqF9G1CvLooOoS6yKQM+WdccE7F2ZDFOGkMUx ###QKkwRjJntbwRH1eOoH/lGkjazmKBD8J5XCOdZh9W5rPxyHaMiq9JXJoYtu9iSxWr ###95B4bWOvp4jAyAUtF9tsmIUwNy/Ip4af5MCZfcG6hifYdiX6s6/55QRt8rMxviQA ###mmOqQxI9HY4Ak72e3hHsyNGYrm0jOzMfr4NRsf32Q9JzPknzLU0BdjHOMnrzbvfi ###4HD/pBChu8QA3XgnW9SmdEWXnyPeb/QcusNuo+50X3gJzrg5ouszHZbI7ABiO7Cq ###X+kG1Ita8FvjIIxHbAS/Trqf8T5ZCxpIi3zhNBO1171RgSbMjtqTUSy8xYWi8d2w ###KVZMGr34wdC43N3/UTwxSQ4wcPz6+LTggYJfsslRu0GOIgg0nAG3At64rLG3H+QF ###NB7Ofso7L/ndkpZLOfF75q8lv4t9VxUc0RI8UTo4uziU6MlyuvuqZm3iaUvc4j6y ###4+/qLSdPGsPVI6cAtZQY2RXRhp64JNFPwbVBEpxVkk59ZM36Ie+m4Gi3RR4S5uHo ###XNcqekXbsGwBNUX9LW/IWULTQvR8a40MaFaP2odb1UrF3T0K3sWiRVGcr7WFt4R0 ###nDBvA/lr6VMQ3ajpLhbqCtT4NAJrx6ukfa6uMBM+B/DXphteXnBvqztn8UlJW7WU ###sleWnwgWm/47S7zAZS/MDzI6tvxJI70wdYN7Nrv4QfMMc6xr+2qkHc64t8UDyZz5 ###VtWpZIXVNFoqrhY29D+ZYx/o6DJ2lhpsmZm9qG9iJ4YJ8Fd1rIgNpu0OWzKNrmIO ###8cBs9fD2zK+U70Kmgjpw8VcFylejpe0E7W6oV5yLjlyxI/R5lVH8LsTl7zLSp8UD ###DV82wQO5ZyDqpfuHip7V8Y9eF/56xOnydPX6beN439lVxdGR7p+GFdSdH1oNl6v+ ###+s7OhqO3LC6P6rd7ljIoU+fneoPahoVM00Xvh0g3QnZoemMrv6ToIi3ZidsVIax8 ###W6TG8vYf/xCR97L6G5DP4I4CcVaFM52kI+0+S8JuGnuRfYPY0ykUn1a+eEdFi7G6 ###Qa2WHc83I8u0gmsclDsBnHudgFxs+oPylPApWPSyc/GwKhXWtGnAbr4jHDujsFZY ###oaDWezn6reCO9iq7uykWd3a8mlHIT+0YG4X61BKgLW+jW1BF785IlOb+aiX+lXsN ###Cxpn2Yn1U4TzxYdzJPI8ctThzA5GiL6WSp9Wsw+dhvHUDINeQH6fjNMKuvNhDhht ###O9MVLXdyIK4jPRoeK9/9pp8YKSLAV4flwvC+1dxvZc/Z2xXnrmL7zI0Q7UlzS/5m ###EZe2d+2tmz2rZKIyP4vLMw5ikLhRgenb2w5/sO8Bm8mHpBHZvDTRQiJpc5f477Sj ###XS01BrOkZYPAfaTTO/pqySPAPiOirRQNC9/bYZn4wUeQFc3WPBozqbUXtda5nfZl ###IoeLYClHzRUn06j2lQpod/BstegJboAsBp3N3Yz9pbrbqSR8rticYwMbnG2bGTzN ###hO1FjIa0Cb+/DfoMQ1CiwqkymdUoQH/3/mByc8t4QAyWdQlLlF+MXNzjKEqIbxHE ###khFgs8MKnr9RVusG61Ozj+n0XSEnRPY/5DdRAgSMndGLw2IAHMZtyIAWLCiNc6IB ###MLMDpmMbkxTbH9wXs+aK3cMsI3lqh1nqVwr0+qlh8RztKxdP3rSOmrPPwYgceXBq ###7dtBSHHfHaqXTSmwwwlm48I0bWL+I6AjgJfSdmEaMRKtrZOHevjBpnmcryaOb2nR ###FcUcJ85ShujgSaoxEn3AGz9OTuPBaxC74GjQ8C0aJcNubukf3Fv6N420eKQIFyKw ###4/6AFyTnqTeuHsjljGccYeGAp8sjmmoDD+0MWIuFd4MB6j+D+/5d94tGU67p6P7g ###CVKIv5lINI7eKga1xLka9xSKgoAL0+AvzhKZuDSMutmeZRls84lpndbCDCz7cwr0 ###mvRKOr3+ZbRlzRrQ6FNHYozkFDI1AfSg7RxgMbzOOmm/o0DztDNNLNR6Z9u1aRyj ###O1iBlRtH/4ms5p5VWdtVZt7E6XYluRi3aQpRVKby5FgrlbBQ1jpZNG50mEi0s1Ol ###raU6s2d1Jnd3D5tmo6QYYmqrUZS8Z/Fs3rw7GQ/u6Aq0MDJ0xmIULaCpCS4eHN9A ###wuzIo7HEH9HWp8Qke7LzhmuR4l7Yy8kZXkpsOTlZSoQCrbOErCqbhv9S7sDBxJsa ###X/N+1Z5Cf/ZtTjYVJXAAXMHOL+h0TrUiIiFttQxb/q+mWqfFA5scIAk49IIs1NZW ###ksKKi6tr5sbEyN09qneP6ZqYCgvAc+j/89inq9XQGtptvnSDVt4ml1O7Dr3LgqEd ###yDFlIAGVyQQWWS+S2xhoSCZH2xCS3pWLM6aCmZG0Kj+QGdmiXEtAcdkwt+Ggh+J/ ###tH20jg1y5GIwFhrgqYN1ytB88zbM0DgDGc6NTDFzKemTuh+dRvlEPS0lt1T3Yzl1 ###oJhdKkIXiF7miUc3MPLjkpbFzDz6dC3TOaq/XMgR51X8aHYbDffIflc8q2e1w+k4 ###yJIn5EaOyGdHg6foXDlDtU3Cm9um4dJuk3r4GpuWzpwMdTc2yBUIyZ/0jS0iEctl ###Nbed5KjAzaWE2yg7XaDYh+cjjD8aY+zJg64NoJD4fm/1aI9N+uNuj84M0gVAhQBt ###87YVMl6OQRfw6HzmqZbf73G9jXTxyagf8PzSMqSbnZxjQnFAHhtcXxvRKQYNZGtB ###P5gnTrf/fg9/ec8TNr8T452cy540arHPahUGuJRyq5f0kVPMi1YslmPAUDH1/mMt ###LVXTymbwQ8yomdSpnZlUynWU3X0o6WAS8vzXwKuA98r0ZWP0G2pdB3hmrwJ0jCdq ###y61nqyu5LeZh0hKHYVcHl64azdvRxMWyxVRF0eg3xedy3+Ilaq668BiI+5qMBn2Q ###N0Ku5WKKb8qaHhnoAnb6AHsWk6sj3INretbVgy2t2R+FGHBDvqo5iM0MPF3KSW3G ###V5uO4ck/diZan4rOrUH9fINqvD/vsHa4sTnwRr5xNf6Yd9zok2ijHF/b98+Ydz8I ###idpIih2jtXmDhNeSYIfIDKPMf7RDNLqx+tsyHBh22Bp6EHDsvqDJFnVvolWFimW2 ###Ucxts0LJG1PhUBus2oP15UQyanYXdLqTO0QMt5MCegJysOuClhW0OjnVutiabG/P ###gRgiGlQTaenA33ZveEkBWAUFOMqHOz7ZNIRtS5uCbsuQpgzhLpOttObZXhajk65y ###hhcm95ZDMoiOb+FUyCE2nl61+FFXot80Bol/Rl7T+Nd4QLWR1OfIES8CbruGKY/Y ###aGh2TY6XQzTR4riA5qUoQ4dA3jZz4cxfA0KtApFGaSyszlDQNoh9VfVZrkbaLzkJ ###FiQ+StHAy1Z/JdOTVbsGIQV7pE2TO5Y/HQ21RhKLqXZp0S7rINWaZngK6FvUkRwo ###5kvlzF5kkJ7RNJaTyOkAoIErCETPpKeZXCN4cato7e1rgdi4nnFjZLW27OGpQJqZ ###V8Ru0JU843KTZ69oaslnsq3J5sVLdNNLggPZSUWyCcHHS4wYeSv8xKvbSDYvcmn3 ###6NKFCN6wXnCvOG7WBO7S3d6OyN9zXLo6qCP5AlZM2oynEG7m5JY4bN+tdJcNs8ey ###4nbFUsT5IlYE7WM7znoQc6IQcGzZN9xpCdKMVnIGxu5tt2jzpoMmho6BBJ3OAs7X ###pQygQLfgQHE2leTj5gQhM19cMg1ItpXOIQymlc4hdKa1mXH/4jpSUr0PVYJfIZ2b ###zuNxVqZO9dvBIAx4ivbWcDgaDEGLGwdcYqFky8MgaN/K0ZZPsZDKciRwrdLmtaQu ###KpfbCnlhH6qOS2kHuh3sORzc4ctwcjcc6459TjFH3XziTrbmlFPQTko15hyPN3AM ###trU9/Wj2NTqgm0oYXhee/LXD5P//s/+kZDsyllycuqQGKFnQqfhzI55DKnfmhomN ###BRJtsqDLyjKLGe0+NMTIv3k4iTjw6X7DtT+B4+oxCQURz1Fihbgb+IoWj2VESukR ###zcVYmHC8IzPMSj/DxPDcGhk5o4vKCoV4JsByvHcTtpXux82lHHK6AsEIMplHij39 ###3Lc7LxTk9RMPE5B/FZG6kACOvnz5UPn4LNy/6z+zkwB6vDpHviSBjdcnu+/3CskN ###dadrE8xyykexZAc6ThqvYR/unx0e+SXQxnn6A7nT2oP+52A05sIFYJOFlOYERItX ###8PjfKrGQypAh5gFNfViAgpnCIQXADW3c6T1vf9NWTiRKoQgzLSrpqSTaDEL/yLe2 ###THCgx0eYm0lExbgdArSNFfWQvKG0PZUBHlthtOuguUp2F5mSeFrk0QCLz2ref3mu ###335LSGIRv7EU8Xt0nWx55xqBVdSUx57RPf+mqTLJ5yZel3WER90UDZ+d5KTD22xj ###Wefey3asmEiHy5LOrKJlt3cPs5quBKhRbPkh3TwWG1wH9oj76FQq5knj+kQQg19j ###n5DyuXuE5ReRhcYCKyS8W6HiGCIYV6bsXWY8KQ78gpk+Vlk1fkOR6AthwevPG15v ###RnjzeXLMvkC1jUctUNJ0N1zTrfLprjJ/+oWRcPrzhfN5yrK44Uy5snIPspxjn2JW ###+QEa5XqB8B5DMyK6EgnraOWvLOZUlDSrHTFfM5zGEVROpFdbXXPSRzouc/ed7FeU ###wEWtZO/cJcGWbPVM9hk59xO89jPT7WesGlVfyeKsmgk9laWnZcXfMD0yIm/izNE1 ###W/HMo5MZPd1hwsw/lnSmYXmaLICjM2hzVnDrif4r+Y9bdPqkzUiOVJqjBbq2cTct ###9BQe3KPHr9gIVGFY3Pvp1xXuKbgrJ8TBd2I7V08W1Sy5vaDceXXjngO69xWoUm00 ###kTW1gEEz4t0NqLPCRGzK8YDUHSsglfQkFxDxh8v+ajXWtePbLeZVK5Yrps0Qc87G ###t2czFfmKSH5K+5fzK3OrfM012+f1uUx24/Fz3ZjHVF3bZCbiSzyTRFGNbaZ70pmp ###N/eBWZiVhGQ5RslDdJbQ37NyN6wlW1uc09nDS/lt0c/yhuGdckamduJdkyGqyc9B ###ehBX8XSZj5BpvMryI0lgk8VU9Ap49OytzjbLz1e9Stwn00Z1Ah9KHDZB8koxh+k4 ###E7FrgaoF3+X1T5iwvskwiu6YBa2wy+NGQC5o82KXSBp2gtUUAer49e5PBa/kfl/G ###zV9M8sCMfKtzrEZ52/1iteCBxBthZlVGWfuVqBSKqkEgspEk+Mfj5dG/g9EA/ceT ###VXdlWxDO37a1zlLgbeNF3JSXasQwh+P2waOTs91LH0Dy6oWYrbD7Ma7Z617imAgp ###sX5UZFsoOaqPlCg3FnyDSIpykkpuk4IyDV3CKrOSZR21sDi9+ScNa9OYhuLo1Kpy ###TYNQ3Q7DDdNP+6JAYoUVTWMKDhGX5K65mR73PqwKrMcTjUczyoD2Qlrusf7XpiW3 ###YXQg8O6eaGtt8TxXdOYO5uAb4awxDudK1aMn2yh7eraN6CYhpoPZlwul9JwYyTdT ###8dwYMdfkQyyR0xbKa1cqUZHsTBdQ5AGGNkEQlrmnIp51piOjQ06Pro7sBY4rwV3H ###OS9cnhxabuxuLcWhyWGtyDs8d0aaYXxH3YiZxq/POL7pv5ZP9IrrgznByyGIoXix ###3+o3ZJyQ+ZZfZV4Erc5DmohhdJKwD5PCzeKRTBW30qNHM8X2zFfTpyxuLP/NiJQB ###XoprtO17ukhIvVtWgKRzut0Kg2TafhF35OYjIuwOo6TlbJ00QES8LzLbSkJLBWV9 ###ZlAME3fqGM9nHkMGLaV173uZ3X81QxszCuAdnh4QCAUxhpYhN9f3+692T08PTxqu ###eNxiUc8PlKesnshvWYgluyxuJt8BWcaH3/LAr0Z8t3cRVf6TAVuk+kQ119ikT36m ###9wHlZuFx0Z1uSC71INNjOI1xsudB3PkFUPc+XgEW/JjUnKlCxaVocr8ynnLfpELQ ###bo6DXo8u5osr68WdnWo8/iNBMZDdrGwnGr+4A6K36TxWpUncZR82kzcCpDSQ6bZQ ###zqOZoaG9sMGWzcvMzHsBvBi+DdqfcP7SYt7hCi+oaxNgvI5LAifQOybQf6eHLxwJ ###NXOef1rMQTziLj6RvGTuFYubs37Mr9wvdkFILcRLUc7asdzu1oWAq7sY4m1rR85V ###j/WTa5WWnPfj8c7MsOPIq1ZowdYtcZRd2OHVks7q7AgdM345FtC8w+zYD0s9dsBk ###K3faPKbwmXFneSxHwxTj6p+BxCRAXYNpjuUOZRfIypiSQ493zaq7knC1/3HTyHA/ ###lZXBPbbUkdPnUY6P5PJDSqai6EbFcWhva/G3lnRMcbHv9dqhW1uycqjk+InlMuhg ###HQ57MhUGs69ECvxORF2IFF1qXVId0y1WEIVMi/F4dhtwvbF9MlnlM26sG1zuRIKH ###OKXn4gmYuWvoUk7uRxLAS+B+uBaFp6oHm+tRlYyUOVutfb0wFnCRQioOipnmNhr+ ###xgNyqFc3anCo8XoWcK41Xp149QJgxys6YLjxkz/x6ZO4rQ7GWt6m8l30Zbxb663L ###1qZVSlGOheoXvpQlppBd3pHVTxx+AMnuUtr3sgiKU+hIL7mbujIJqh5u5IyYTFPQ ###89ZXfJEA0yVJUhzXciF2Z2DL0LBrj2RtYm4l4ul/lHbbxZtLYEEjygU0uONXFrza ###Xr6LAZ5nMeoR9q85leo6h9Y8bouGXCRcUIF5oNveULihRr2WmOdbCVxcMm9crqZr ###L9XSXGb3oLp+D8MWN53CXdYNiUqpqhsS4utVNpFiy0GugOo8vRZcakMx5nNyKe43 ###YMlDDL4ATJRVGldtjFaobrNGQTiObTp+zdRC0PCiyV9b53KZLYI7Uskrv2Z9rS2B ###chUNRBb0SV3B2CV+xeKXYo2Kj1hMSS2Yhj5GngLzMKS/Vo9d38QET1eqfY1R/OAg ###7aQ0OXl8K6OM/9toQ8nhox/PvjTO1EUFfjqDfsAbbCYL2lGMg4WaWEtaVAeF27gv ###WZ9Gowu4wttRt/9JrJyz7dclZZajou6q0oAITcItQOERO3oePJMVUbxBLLGUZc4b ###jaYz0jQudy8uuZmnktPAk2wggdExA3T0KZxtcHQFbe1rdfBGN4M8JmDFRFx8C/AL ###L4tT45B2meNcdydZE0Qx7OgYP7zYPX0J0phRHGIaVF0cCkRfHpqx8VOuT7TVisW0 ###zZm40+zWeTXD2OlnliyhfFUf/I9xS3ZupFjX5edclzTzu1q9Okgrpk5LDZogBP4Z ###o6DpDXIGvZsJdK7ZdQsYTgmNga3eCK8K2NWEMiGSe8SkgwciGmvvg7/1emi6xdMN ###5wHn25Pzk32RFfOJLR0ZvNEp8CTdNIzz70ddtOU3y/aGtDivVtYptgOnub/8ms0a ###kaTLO3Shkcgaf5iKN2aRMH5wigSjSd2nflQhwtede05r0Yuanl51Bt7wDRl3Ij3r ###ZHx6dnn4gr0PQJ+d9DoU2NfhIXpAq2Gve3M7BkW9IKJrgy9oe6BsHHTrzY2uVw+M ###8pq1OpQvqsWuJ32uyVNyD7FHQ7Et0EqRYCJPplfT8qJZRcqnfvm0VsSVc2z8WY6q ###tKFwHP8/+PxCuUQF19AVOnFdXBg6A7DsNfwev1DHGZfLm0vuMh1zcBxwVxeC+T3D ###2kz/Mms1acehiOk27Wla/kZn1LahC9kfmEkApgqYV415YDn6iunpGrRZcgxHYjdl ###ZCPcT/q97qcA9hxdDNIGUrmfpD+gOGbQNYubq+EwhANDT57TCVRa4jb6E+IzPHI0 ###fmoeMzsO5W95w2KstPTkM1LZNCO0zSycLr8TKzu8lvxcSTBPn8b0FS1/LiUIAAo9 ###Od9nUVhxd/y3kA2DETqn6umwYHnCASVrRhxgefIhpbrCewoievSjErplK1zS8ovx ###nMboOMpoHgqXV8Ft63MXzifgjuNB9AlyN/wOZ9d/xvM5tSkxyhUmeOkH7B5Bx55f ###H+xrxjWcQEjJj+jG6SpotyZhYKxfH/gxjsY+9Qf3JpSt9ngCCBYWFkqGgCUmeYDh ###cDIaYgz3s4jTUh4zPL93/KdPaSXh94/oQAT/ys39VbkTDCZwJl4O9kmE0c5e0SEu ###Owb+rth8b9NZ6waPbPxkZ5tV7bo36ByIpZNxoxR4vPAIadoK6s8bwm/QpdmHPkeH ###f5IeNu/2qcNnfXx4cNyggFNybGvunh9PVzyQXqbWDcxdJ1AVde2WlDLsClzsiuQM ###sTJw3WvtkNsiaojXJlNfFrDWdIIXoBXiuDS16yBW6XW4C3K/SuYoWlrg1T1NcTY5 ###JUR8zc0lF+ZkYZiepoRlFEj6TReU6CZlLXMsEXXxqNUpeM8q16tVf72+UVzWIndj ###qyP2wLdZI3t5uFjkLP0qctSX2LNnz/Tq5Mp2lFJK83Or2cMsdK2hOKr5LEVZW9WG ###tPUC1lAXg0mZ5pHF+YSBriB7tR1blPcQCvpmNZc3bwGTLxIM2loczudWb4KCCswC ###hAmag+Z7HzdzYkp2/k1a+ebkFkbhZiPffvI3abUH5Q9W3YtnrrTKQtMQxQxHCm2J ###rZLPaZ5c8QhOI+KfD+2yJlh9RWv6cuY1XU5d1GVrVVVrC+ipgNXcOL4h8VkkIoqJ ###mU9jtZHTc9jyj7e240YNces4APHrCgQUANCdqNbsZq2S0JGc61o82CnWz44RAIMx ###ZZWKwZjTh8j4OItw7VrQM1Pv9AQxI+WmFQWNq2V4B7heL05N30dnF/uHytPxm5F5 ###gRPBloc8jX7dMZbewSuN7LMuKdnJyJwpqWZb6ZlR8whW5SoEOMVqAn/QnG6/Nc/a ###SilFKpc5nr5KugLPuLhGIuP42hrXBGbTKSLQHxPnaVsFMoBIDkR/VGRtopPgrJHH ###sbInmftnVmJ8xPaxslxPe9Z/h50zn60zV3YZS/aXsqXstn/MnsqE4n/vpvrOG2r2 ###zXRw+dO3kya4MFGJhAlvRtqPVaybVViYbrqPWBEb4qkXZv/s9fnJ4U/Hlz9/z/Wp ###PHqBtAJCThaVx+EjmntBqM1TL/RM6JvLekcImHrNj0+RbzSPDvf/0/ZkVDFz1p05 ###09zntUEV+FMv2fnu/o/wz8lZo9E8P7zY/w7SfEUXPbzK47ess6bpzJvXxsjMW/gR ###qJ0LXbjQMjV9YODSn38vy7sy56In5JHxyrNt9Okw8oiVVDlupl2ys+P9w+YFWj6/ ###9W7ewTSHcvW2yo7lS7YBUgwclR0boc10ZsY723QfsS4a0DNtpygO8D9gZ5lRirMv ###0qzzfsw6GaBPvVSN45fkFfRNl+iH7bg5XjwT4xN5J7x7/bZxvD/z8YleTM3xwzCY ###eVWnRtGjzjUF79Rwnpyd/bj76hBQ8V1Ald6NLsuGdas2032dHG1FD7XUwxunt0FH ###DnC5UDTJwNEkG0mRp9NU0GqOoC8Sa5x22LJMbWRmBslTc1i2E1fPxl2zfCHumk2H ###bIJv/+Rw90LeUFNWJXp8eLp/dnB4EYF/cekIm8MblsG1fhVfLMdb5eod4/4l6EXL ###c3w2Z1uWpxyzlTbUXTw98UItPeZPBJzGvpAugV7sTVKxCq3JVBWQWY7M/Y+pPTD1 ###hRrN7DtYka3IeU1/s0vP57MYp0uFjvIxec+nTnDdmvTGL+woO5GDLEpBNumjX2A/ ###7gdTlH4omJPsieaVEoujU64Ob0+P0Vjz+vAU2LY5HQ28r9LjJeh3APXFuOecQMiL ###tIbmof51aYnYnTGLDoA7GjzYHj3Sf4faXo8CvOItYhf/NZcf7LY8um7X1736ajhq ###r9I4d7AYXc4BnrUfPQZex9frNfoXfqx/12oVz/8vz694a9WKX19f+6+KV6tVqv/F ###/us/6cee3H/ID3m+Dh9GGPgAR0+RwTp4ZfiPz44PL4/Y5WiCLgU/dYe3z85GN+xo ###gM6vKK08w2xBjD7EqBbY/J+DzjOk1fej7ngc9DFO4n+CVr/8ujVqs3eYvg6daVeX ###6VQjr+FrrDQM/wY8BZ4MpL442kd6fMbOewGyzzAQnuHwgjv+djpUNrjV476D8IwX ###6n5GfV8EHaTe7tWEp5zGSCRyVmbhYAL8iZ5cgRAzesDu7sISD1OCnu95Hd8l7q3c ###vRZCX4m8lofB6A6n1sG8Y5+7HQodEQ7r1wPMnYSO1qC8cOjIyxq/uwuAteEfZQu0 ###ECNLBEwUYHKHcSXAM1oiMoGKxMIrsULYR38wBkW2xINWyFWPolPkmLwCsgEQjNju ###tbp3wehZAhQwmoYOCQVMUuV1nTMgIvICu+kM2pM7NHPJtVqFZRiMsbDmHaaX6rZ6 ###YYRvWidyGNcmIKd1GnTHvCBnwPoYXAUA8bs2rA0waHeD8UOJ0zWModN3n8do07So ###7CSuyzBoIwHgnPhQg1GIPpwP6OdOHuxwHAK3h8cBdghA3g3G1AlH3RjLyo+6n6ME ###AYCpcHA9vkeqEKQWjQOHHVIg3z3UC9JbGKoZXr46brDG2dHl+92LQwa/n1+cvTs+ ###ODxgez/Dy0O2f3b+88Xxy1eX7NXZCYiWDYZXxqDBg3KyByf6RQO7+X//b7cBX//t ###b/R29/RndvjTOUiPDXZ2wfBMPIYeYQhQLC6PDxuAsdP9k7cHx6cvSwx6wRgq7Obk ###+PUxnJzs8qxEg8e/ZGdH7PXhBTrJXO7uHZ8cX/5MQx4dX57icCANkRMvOwfR93j/ ###7cnuBTt/e3F+1jhkOMOD48b+ye7x68ODZwADjMsO38FpzRqvdk9OrAmfvT89pN5g ###DvqE2d4hQIpCHA5Hsz04vjjcv8RpRb/tAxoByJMSa5wf7h/DL9jX4U+HMKndi59L ###otsGCm0wt90TdrD7evclzLEQx46OGuwGlmn/7QVJGoiSxtu9xuXx5dvLQ/by7OyA

   ###0N44vHh3vH/Y2GRoeMZWbxuHJRjkchfHFr0A4qAFNN972zgmFFIwwMXbc9RCi7Dq
   ###77E0Hdvfha8PCNdnpzRnQNbZxc/QL185sRol9v7VIby6QPQS1nYRHVyX1ZvBkIDM
   ###S22y2M/p4cuT45egxhxigzPs6P1x47AIi3cM8L3EXnHw97sw8luaOy4awMZ/PSZy
   ###lARdotVlx0ds9+DdMcIv2gM9NI4F+RD69l8J7D9bggNFxi282n13iNaqo+OXzVfw
   ###sN/uTYClPoHte929eXb7JHJ3V+9i0g62Mt7GnzRhn34GzmS+Ccet9qcmRaQYL7ZA
   ###dgXp8NntjtaY/MSboBqMre7DpqgtjM+X0GqCMwu5xisKbZy0HpBtKLd5DMzT1TLx
   ###jE/IeNQeTIa9oGO8Mt3071rDIXDqD/5a/SMImeaQoI4KSFBGfd2QUipBYgLXEx+I
   ###sYV3Iv2NGW/Fh1R9LQS1ghdLhLX8ao9xEOQZA+tOBGl9umJb/gIPuv3AUcNUfyRi
   ###I/I15gEAis4QFuDriAFZ+bHJoS6IdErGhJb5OzMiAp2WxPJyc4D2ALPw0SflnWjB
   ###V7RHrgWXZcBFHzv+2ppU9ISywm1gWqyE3qMdJyG1VuxWtpNU1P2I8U86wKBnOhqB
   ###0qlBYQPydcnIoYwxnRpib4Jxsxdcj+UQaZjl0RHCstHt8D/RU1ZHOUcS2pDwzVal
   ###yP7OsBw6/rXiRah5FF62txUUy3584t3YxMt85tbESRb7D575ijf73LEs7H/s1FM2
   ###6WwYUfxFmhOm4jNhNMMQdny4FWcrm6FjjiHbYtkz0Qxb+FFsx8p1AuG67BW3t+0L
   ###SYMbmP2YG2DajuIee7Jfg7im7tbNtTSLni12qFXDsdGcXDAP8VLCCa4toXpDgdcy
   ###hRdOIwrF7l4Xoj63vN9/j/eorbjrdRQuyWerj2rGwmlzETZKBUxiQ6+ox78BRd/0
   ###C5pxXUkcWjzTigMrbFl8q0Onf6JhoexAqvpeQVzkx04UgudaOyoCLEYxBaTlKPGX
   ###RgRHYWkpysahAha1Z3L19WYmrAnBloLn6B9qN1hLU5CNwSB558OxKOCDRl++N55p
   ###zBDzTujiqNlKLtE202USqydrObdZTI5ZiudHjUOix3JqLTTBY5tFfyjh6AdbVnsa
   ###fUw5Nn9IYrZ6Q0umit3qAhb1eyqgyjR6/0abLR2NFtLtQ87olohft10vF2GGJSRy
   ###zE+iUZ+6sEAMrGy7tmp03ukpZmNENDtEXg6I9M1v8XMVDAtMwdrpidyhDX+Ng8Kf
   ###iA3oj5epRovOGGSscIyTIdVaD4s0HdJ9C9lHmzrTbL5bVFswHG9vUzYZW+AgMLXT
   ###l8Mtb3R4ePjR7vHJprn7sC9jFeWuSOTjaBREStELRrvBLkke4qApmUDqBxVAHafX
   ###6E5HcioAzgQ4NnM1bblKYp4hT+Tg0nZTjq6CHf8fbyIi2/X8swlHnJYjgCcTphwB
   ###KgTdzhPgyhKwpGcgjcLlZzi2UHCyTy7xajwYR22N/BEEdgkzNxWlceF16wvd8qPZ
   ###WuSpCVR2Gl4ZIeSVzWgZxrewpnyqMpGnOU9M5UYZSarLWMFuZf2j2msXAXcAhdFG
   ###bDRMS3tAec38eMltLZn6n+aUkVaHaDlBdfCXnXxdyNdylzgLKxnH6tujo8OL5uXZ
   ###WbPxelffODKvC14+YGoXvhZy6VWuHk3xcR80tu5j3NFq7iqqHIXGqTEdFMxc+XIQ
   ###nkbaKnOG83Q0VCxA+LDYZ9empXmlHtcu5YuguwbORmqTpk7hU8pvZWlmmkAj1R/t
   ###K35puO2wRKR/58zCYSXdN50hMDW8vywzxX9wi3vL3RUE/uOm69MVL/NjmoL+tRYn
   ###niGruHVJcZwLDBkq5eMRJKaWjRP8VZ9VmpCjTRq2Tn9ydwUEPrgWaaOISgorl4O2
   ###lqFe0ncs9xArmzyWiVKRdFHMMEsUJVxTtT5boZR06ObQV2/oLjB0jFjeBg5ScLOQ
   ###sBglhOblYOKW2wJ5QMWyQ0rmXFIjFfWdB71tVRy7K6n+m+BUGlvQUPw+oIxXeHbI
   ###TFg6a6Dc0B1+jRoGvetyJ+h177rEz3geLC2TF+W7YuPWJ14mDj9ttymrFd3CYok5
   ###dVstz642kGd/cC+A1DN1yfrpuFA8UyV82mLjLvxWCJ7dPGN1qidPaX0xPZlGE3EW
   ###B0IRcjgduQB/0bFCxmewqE3yOGx274Y93oMsGWI0xA0Gq8+PXOKl7pQ7ZUmSsOtk
   ###jljX+SMBwy9xt2irp04P7fHX1EQ+0TZ4RJatZJksUxjTkm/NWw6bNQdXYt6mOAub
   ###KslWuhFginRbDin5W6beShfP84nbWkqu77DMM2fmcq1wvhxd+RYXy2Wk5upK3Enz
   ###XWC1wqlGQ5nDy1zapCxeenIuhyZUslSguNZjJfNaSk/m9U2suzOoJK6kYISP7GxM
   ###v1m2lRJTvstTe9gKYc5t0FxJF8dlH3ykVW4jlQ9z6x+mxJGkhWRrELatDKlQ1GUQ
   ###NMfhXM6haLC/g6z2gmk11qL7j8iPNjtNkr5SrjXKG9mh2lUeiV5tbOW88O0R/xTH
   ###0pWBKGpEhyIbx3bAY740a3nySeQKeZ8iqDY9V0K+sMHccWuZoVB5YpByxZBnGQtE
   ###gSFOvgw6YsPWiAyKlF0c6GH0oKWnFrqRKWRPtzUyiDOWzzKRMWgm8STyS4pNSt7m
   ###00Yn6R+BWmHu/+3KH8lcp7LQ5LUwuIoaZSjzeRf1KeCvaMFv2a1jGSDFOv1rW0d+
   ###Oltq5GEXjVTe1ci7uxs52FcjiwM0cnHKlBwaU2RtSE+QkyuMyLm3sFgV+h3fD0af
   ###eDEqvmU4s3Hyk3zi0Nw21v/mnaWxy8SttZSYaDV9O71+e3J5DLvgcPc1sVwZT0gh
   ###gFPJVsovadN1Zi0bYVyqbSaB8Js80ZpHtUcf7yQI0sWlHGlpHQSq08yym0blHN10
   ###+WehrK+2HOveDrJZRBhWEF1WpFv04VepB+qRa5YyG8WrubRYPXbN0GQTo9eWltBn
   ###95AIFnlQqneUKA7wv8I7KjaXJP051jDTO0q4QOvZnmdwj5rdP8pp6JDTiHtHSY/t
   ###P8o7ahY3qMgOtvCFSndxym3qUVT7jbbMo3ycYGrbRteRV5GAW/dz0k4+PONF1g84
   ###4XVm+q2cn6YC1ZsV1JxeUUvWFk9kC38St6gs/yeNV0X+T+phqv9TjCj/rP5PBt3M
   ###4P8UgZ/uqzQnpyjN5WnJcoZPmJq89s06hfidSuJViXLzME4t29mJJZRFwacCnOug
   ###PaNPEyxCgoG/M2gOe21h/Uh1a/rGTkXfg62L63gs6STva2n6KquIaKCXoEvyx6XT
   ###TnyOUUr0VbqDUqwu07vdk+MDoeXP7likKBLmrXsS8etukcNGCCJy2oHSm3Veb3Hw
   ###HOoN+7vrSGIvHNxf40om3ra2Z3CPSMKgpukY89ft+xo/Mzc6/CVv8HC7xl09oo0I
   ###/O2H7YTFLrGnxtgx7wDjre7TUE54J1ngjgbNjDhzOr9pWKPjZKci65H9sP34IdOX
   ###SRVN1QqM5B9AkztkhxG8evnrx7nB8atAjO7SPaPgTxjCqCQv8mOwJ+j89IS1Jp3u
   ###AL1y0C4vnblg29xTsGkXK+D1Bv0bs3w7d8wpEMfs53Gzo+i0Iq6VEWpk+sTldBLD
   ###eWW6hwFQ0sXO9J4TKNEvKy3HuDSckUfdHJGW7mT4B2JtxZsKb8m+glPR5Nzwmuqa
   ###+EehdTpS/Kr7/L5q9Ts9TKYy5uIb18U5FghSFJDaSZpy2xXoGFeZ2x+xtIAWt/zb
   ###1A6c6bgwyo5+zXYz0wuvfs0fA8DPwG8jFNsuSdMJxWJeGdI8airaGU8VCd1nfFHi
   ###ZRpfO/m5qm5pYic/XtJqYFoIEPN3edSh3UX35pEBDgnSPG3iWVzsUnXEBNRbg1mo
   ###N8SeirHDtO0Cr3P4eom9Y/p7PSsu43yVN9/XebnhiR3yqMXPKpqZTgHC2e4bLb7u
   ###ffefs+66E+fUy55jr8+bIdpeuH8CXpjqoagsdMpD0SD9P6+H4qNvWGawbyR6KE5T
   ###o0cXqZIMAXNwHHpExuQMO4NTGecURKp40q240idMH5P8yY51zBl33I9KfZzgYOR2
   ###MpzWI8JRnzNtzfMhf7Zr7NxX2c7r7HzOErlJw3ZFyuuOlOiSZBBYJqW5ElWnUtfc
   ###1/z/0KKnp63O9pVxZBKeZq1t/xnhjuDwn8nHYxJ8aWLLvByrdpLfp2YefjXpvjUp
   ###/jWSAk02meVj46D6Pyu9fnWx+OTNpzc3icyR0Doz8/R0DjkJHjlyj5keOZrk9o3z
   ###SS9+/rN+nPm/55DzO3/+70qtUvWs/N/e+pq3yP/9587/XWKNT1iF5gQDkoPOTOnA
   ###MdD7xwG8ezcIF7nBF7nBF7nBF7nBF7nBF7nB/zS5wdOzf5PhVISQK790buZ02IWl
   ###qxfqPmiF3GL+mm9YCiklVOUj1SSKsqZESUTjV8fRF9DXCvX7tPKlaniofKDUN/Su
   ###jBAWxUfFnR3fGsMX6gfoFwvR+P+u/C+1yDnpAenyf73mVWz5v1qr+Qv5/4+S/ysL
   ###+X8h/y/k/4X8v5D/F/L//1n531m4B0uuZtUIAn4F8pP5DOthWs12z4/zVRBKrhaU
   ###WIzIrCOkD4GldSxAeGUb0me00jtG4R3Ua8w6tDBD3afdaEA1VNMaGDGR2tUZY0fh
   ###pu7nsMwarbthD88HTH7DCuJABdyxXvA56MmkgzQkgGyWCI4e8GtVLD30ORg9AK+F
   ###Hq+ChwEdQ8B4hwNRViRkbZArRsCV8cAhQWaMY8j6P3R/Iy8K9cK9Vr3cOFLM9yKA
   ###RW+hatrGEYbkE3+KHrFN9yvdF9T5GcwQBbl++4FDovs6ML3IM1ZPcriSqmirnqqK
   ###xL3bGrvkkBUt6pci0z2YvrAdhu566+zv4t8X8GyLlcmHDx6KX14wze+x+IUAkXs0
   ###clhyRoZLHOsFToA+gBoa0GQPU7iViIr1J5t24B/q6bKnLQ8vWZUn8Q7znSWT+BUf
   ###0eJLAEhsoSaOUWBPbRiYdI7DO25nf7EvtpUnkvlCBFlZU0JvabFXTSQpBKUGlCsP
   ###pxV7uJU48r46FoUCCY2bbxSnzBhP5lgwrRS49ILBLKOqFzkp0xXSBjIKESschT9s
   ###1zZAK3v6FH/1a+pXrx796qtfsSlfEFh1hS1o8vRp9IefHf8cLy2uEJC8JirpOFbs
   ###BgEXTUVYw1nlbOUcL43WnrrpQ7hTuGPXQFRA/yoQGM4uREj7dNSnCq1HnF/7Ik5V
   ###6iPrPBEZ9qyuVuLLq5007orv1hEkx8HGGj0tFwvmtxY82uxSS6Ibsf7ykyN8fBQF
   ###9kcn0jM4w5ohnm7BBR5t26K9q2lf1G8K8dyjH7sa+1KUXVl6jzoIBSlKzLoQ4c5g
   ###Q1lEYdIlotE5nMF3iA/IJ2ZYsT52LAY9EQijd/QmijqnmuZRXqcTkDQLlWIxWhF1
   ###aCrnPSpGr8eYHYWrwCE2Uwp+mHHtVix7CoMracHmCbHmGq/c/C4MLH94ueUo5Iwt
   ###j+Ljk6Pjs3gf92/C6JrvEgOfGvf+xwW1RyHtdB6Gd4PB+LZ53eoEhXiNjW7fKzHX
   ###Y98VpK6q4g1AGu6hd5crx0K8u/tuvzO4t45wM01wdCh3KZcXUe3qkVZgjsdeJUZb
   ###aTEBAjo9AMBOz8kBu4eB0JnPqzfh/994awUO6YcuYKD9ES142p+6xxcFDixLYHjM
   ###VePVRdUvvN7dp+4KquPCfQnwaTYvlmJuZo4fgOjs9LB8j3j27A6Yt2ZnTnVkMxBh
   ###xDxaT5FAyi0T5Q6QqgEQp7j0eVr5smEGYQheSMnkiHuenZ78rN81EQeKPq9Xirg1
   ###6Zekfl79vHdxfOC6sNJboVSjjabRP4fcgQYZwIDsOi5aThmOo6VsyBeOM7Vg2uVi
   ###aRNzs1S4zsF/pxYgYuD5Kz/QfUjxI0uHc0WDAehNbFtMTPeALcagz4XdqCqRq53U
   ###B8dNiiotRvop/W3lpNBUzqhzMSuemqU1GjdRodVkdKlwau2ih6JmhDyTiR8htsYD
   ###mqD2TYTdI7+5Btwa/+cBdo98mXXLzbc2bT03mvOof6OGjgVTfT8hE2ag5MDVNQ4O
   ###TA1FEr+ys8NvgI/W8G8v+huwgE/W5APcr5o8s0Utinnr5oCAd9566A1aHTJ0e6zg
   ###M24qEkV0imjOrsC6d29uhD39/GR/9eDyJyEByiIZ217scls/76Qwya9J0Cu7xDqD
   ###/t8wYKjfDlo9rQjFvbxJwSI+YetBC2k2JLfj18enBX0bm7Jd0SypRRD94JAyFMmL
   ###1bB2YsTG8KXaDWpHi4I+KI8WDGa0TFfvJVX5wuKN+rD6kFYcsibBulMsIFqv2X3A
   ###blufA0TozQC2cf9B5KJgD6gugzyGTbAASGeA92yCMv4djAZmxLh2IisIlw31wxnY
   ###3P1ohcdkZH4w+YwzSl7Dumn7io7OpSg+Crff6u3D1QiYNlAoUnNEUT4WL0GCY+Q9
   ###DVoYoKKnosQlefA0TJg8Q6OzHdqo8Izg+cE+zYp2xk10widFL9QxAkNbCQDieUz4
   ###OYdHG4JBtU/otILx4Y+EtKLw0lmf1qlO6UuG3vHwsbm2UQttGrxhtFAiqYDWYovZ
   ###2y6jkpe1x75GYazmEYYM34DQyk+kr94PavXMfbPDaPlkiCcryN1kCkHxD39wNflB
   ###tYmOs0j5Sv4utpfNJkUmV9EgqAgTKsuRLK/m7saSmFMpy8AzMVM8XdXOLCqiUzw0
   ###4lmxXDa/KS5/PRwBfV/DcHAUjkrsyfn+a8zxcE0Vjgag28DWe8H+2mGfQ/yvmAr8
   ###Wvxn/4kGgBnNiq2Km4pVZdeJ0/RXi7kYp4jJib4umaSIpz4iZ/enAokd2qxddCmD
   ###6lUflqSVh56BoZEFcDgatIMwxIM4YlNuAosxod4gHDeve60bGQXckXt1052xocnD
   ###YOWUk4+h7e1Eiku3OukJqoWNE/k0HEn9wZhJDwNRRhG4N8Aacu7tUekptfKWuWzI
   ###5Rc0FTYpZSYtFq6VB8ooZi9VRLsqpC0zn1VMMDDO1yTjHPcmALll22UtjBhp97rA
   ###jL2qTg5WNAOlsCV2pW6G8BNByjKI+HQXGPl7/Nv+Og5qV0DY0M2OqKAb4VNK7cse
   ###/PXhwfHb148YnGxWs44O/z18zNj1hLHn05kk/1YYBqNxAY4cM0otCh5zDYtZbLjo
   ###QqRiBG/PApAY7asgc8UNoCUXzDm1s7+DxP+C+bBJIu1X9GKxDU2WMUQZ9ChD4ZL2
   ###s2kbjrIeYGA6P4MQALtjQ26UCrQ0YnNWEnGSEntq4iPbJKPxQg0S6Ii6E7yvxG/s
   ###NDVcX0CiTwlZbNuCAiSHiNMmaljA5q5b3d4ExNHwdjDpddBjCl2HrmExetZySyQY
   ###h1RcJ0lNPpQhsEsRECcel9yTdkaSRJ8vYZy9C5YsOFDKtOe9zNzCqU1C8U8tYbUQ
   ###+0SXWFlRO/ojY0ZknqCkh2qDxHQBQ87TTxMCAp6BkjgOej1SEosr3voKiN0FqU2q
   ###g4Gb0YqYSm9jGbVGU6xi+7dB+xMCI3Q9clgQ0gWrlDfYp1f/JreCiKBigqIYQ1fH
   ###pBAL0xUK7VV33OwNboZcqQWuHZWUMSJtjW89M9uhKRobCqtu6UketGimQIvZju67
   ###wHWuqE4luoaO2fh+UBLOhLC9+mWuCxpkSsHgnUkgs6jJdSmCvo645a6N+nZ0mKw0
   ###IYhjk/3d3lzapVBRTA+NUGJq/lq9uOKzF/ZXsOTlQsGklfXizk61aNTupTyTNlwm
   ###ssijFv6/xcIWiGMPfHrP2PFY8Z/gM/Dp29ZwCP2RHy2j3N+mXk8GhBILBba+YFHR
   ###qwBorzuYjHAAZGN97nH7OXhmYE7YhZY3YKsZc0rMKsfLglrHaqLN0E2FFXfeQhSp
   ###b0Er+aSOqKug3UJPYBA0R617BtRnmkHQpyscD0atmyAN318N9ShFOLc5i7fOZVBd
   ###aA/6HXy77XtKPuWZZgqGbGRvqSjFgUtOfKHXW+nI0asanoxYdldnkdz3IqWVlM/c
   ###A65PM2Dj7Tn6D6b193ya/o6AFyd25XtJXUkCynMBfXh6QAMWRMdRfbw8X6Nf7Onh
   ###SaPgUCWK+unkZq6GlaASWUW054lnVnFpvuYCocGuocoWHU9c+LsWdrryzv+/vS/t
   ###aiNJFn2f+RVl5tit0gKqYjENiLk2hm6f217a0NvjMTqSKKBsbaMSWLTNf78ZkVtk
   ###VtYiyXb3nYdPt62qyjUyMjK2jAB2UQu1ZAuzcdLzwTgDSzkCgHseX4mmcw3a4Gzd
   ###jnqkMhzZNTQU2ds8j7l0SPYcXmVW3hXnqPLEMFEY684g+uqXk1M88C4Z/488JQfg
   ###nFDRVMgn+rOSuk1sOq2DRwWlQwMIo+58YEwvcL7szAWv/87kgmunJxEcIzylNNDG
   ###aeTgWx5Z+t9M7V62Wq7UUrjC0kDKGqzBh6gzkgu7nun44sIrzTL+k8tbux61TxbJ
   ###LSqomwV2Lro4jQqmNZTtoGjYi85CYPE/NWfHx2yPsr/v91YWFB7Sqn6hfhea98YB
   ###lwQ1qYAbNRGbC7foICRfvTg8JSftiDEf4OjQgCsQ3TsONtB6deQEBPkw0MOtTxUc
   ###GSBEDlUxsIjgi5fFrS5EdArpjpgd4wiVor9t05B7k/bnqv8cjrvLLjP37xWPNaUe
   ###5OEX/0HEgcW7UI0TC7VfoXE+7V7RLViB5ZPhwAIweYU6FIQztRkVrSSQY4Br5Ymq
   ###qheTG5XllodvjQNiaL4vPPdgWzQOCCVJH3yPFjn5MsnXIoi77HH5rQ5F4IyJhxRD
   ###kBpFtSqxCjfQHp4amVkeN56DKpdpmG9aU6cvXaeUuplKCSW5HSt0dcqFKjMGNQwo
   ###O/q0HXPagku6jM0NU8AXAzUNwtKwFg4f84KX+L/YvoTEfAUuFPlgTI0lx/Btcsdm
   ###MHMLUUm5pcBVADF3jWIwOrV/jK69HoF8Orq5uvam8YBzc3Bww/2ZoUclgy47xdmJ
   ###D24G6IfwsXNnDIanJwXtDbf78MvDHt78mcIVpXE0YSzTtH+H90bhkmUMml4wDxkN
   ###dUBqBwF+Gg3GTFLvg/t5B+xlfBCx1HaAU0Q3QttjtwPcp6nmAI+U7+BiaTSd3nmD
   ###mx6/VtqNkqn2mVgD3xXgW7nrylU0jCadKXApcKPIbE9LXfFUNsu2d/9Oqqd4pNZx
   ###v9MztU3ZqMIZhEw0+AKLbvIZmBCHidk0iZy+J6T4P8IApEqABgU8rf5lel65fbPV
   ###Oe1gyzyqfkmdk3u5AaAVr77PxIR/6sddava1XA/HnUkiInxkuxhq50KGY5Mp+AmC
   ###IfwTdYkyPaKqQmLSyR3EGBuB7X8p3C/37YghsgnxPS9kiBxDuMgY7OKbVRlZpJbR
   ###NwklkuHLyqEas11eBqo08VvUv2T8QZ8HHkjFWmFCA0OFXm6cbm5UPtvcOZfLBRPj
   ###z+iiL2zI0j3P8HHuGvfFeqObob7j2Ovy8JBmf73rOiM22nORd099KvudZErCYmfB
   ###oynWWsvpUIcki8u7jqR6lV5GxKlYWEHajNQKZQ8HP/pvy2Db3Yna52w27DeOqVbD
   ###N6CsbvBfci6sBHtrBMhm9TBAjcJBdpK8GZryHCrsmkqzCPBtBem0taDW/jjyDp+/
   ###kz4CpHpgVleBbvgcDNPEIxOfMlIDs4mwgQd5nlUZRi7ELIzRYwFmPbQ5qdTkfnVO
   ###LjQmBxpLBR2hEScUi8SDN1Qxwm5gKK8lQgGp4XFlxdgPPGl+KjtxmRvLaN8CQEM0
   ###71zbV9Ivjy3wOoFDBcMlNIHfCNCLT94BljFXWWWE0sauoR7Q9LfsFIDJuRl0owmw
   ###FKJ3fgnvgkfFmCZ8HFtEFXRtbQuySr1rQP1jCmz+CVJlAbTVBq3y9wfe1tPt5lxj
   ###1rtQ+vJeoOYEbf2MzQIGadvUm+CwNpsZmbLGvIEWtaPg+z1DYWMabpQLcDNlZi5p
   ###F/bGaTg6ZijNUnySkIqt1Qq3ttjBHm5t7hqDVF6KvIjDhCaacSU0g8k050UeRFoC
   ###96cETZAMPeKw32kaKdMfsY9ur15oEFGbsoguapsSXRCf2JFuCizmohXTjlrsp9Yi
   ###RUMsShJTShKnKcl8WOGkKjYc5Ihqok+3BRCXVdbZb85L2AlXVXyAgK2+xNqta17C
   ###MUZOFB61UvArBbxCZJAnVWycVNknlEy2dcIm31CTRxoGe/G6A1F+ePQmbBhHALIO
   ###tM1J3RpRfDlg+Kn0oVYTUyp3uInCFDHlqy910EkXdLbonMliclZnPO7zvBwIDnZu
   ###gJsUSn9I99cssuykAqlJqKPiW6CF0XNqJ1RSoJRYVB6g90qCJH4uz4VpPgapfDia
   ###qlM4mo37cS+e9u/q/ON4lCRxtx9pMIM24Doyt5y8CFEBNwexBmqZJJrKDesD+e53
   ###JvyyS2eomwrCp1tr3rvofdRDW8bAg8R7aybXoXb4AZafC7VMeNq7UsvmHH+yrlFy
   ###ouK+RCnkIFxcLlekSK1FRC21gBC21L1Y8cyaQ3lHFrPFKVHafC3G0EBBR6WjQqGd
   ###00UaZIIKkXPIjxmyYqGUKFektKxIEzalBV5Cv5qYQItKrDl/+IjqIsio1bErCofM
   ###DPXt7krmSeoCXDSXriFZ6wskpnjNBqGv2JljpmL1dGQk2mWUY3PHm3nhGtpgWkJe
   ###kCGDjKXU92TVRPjxoJ8PgjI5pHk+aqyp7g9Z9crc8KHwFeyhocVpFkr7GhhGpAOh
   ###XnNeKsb7w6okcb1OFVffrDqGJ0BZHQNVPLrjbNgtkfRwcgArRNAq3nQ2Yj5BIsCX
   ###QBjU6cVMIqqlMokL2rRCSCbBQbIK5IPRZtUCnCspdOG1Tb1zhKSWeQBQ7w2STTnv
Part 81 is all base64 source code, so there's nothing to reword here, just the bytes ๐Ÿ’พ๐ŸŽ€ keep them exactly as they are, bestie, or the decoder will be sad ๐Ÿ˜ญ

okay so the base64 keeps going, and this is where the source code is still streaming in ๐Ÿงšโœจ

   ###8plYJn4QpBC0oftOp/7TV9Nc8hPpP+O4MeFnfRR31mTuQNst2LywJvu612cSzSdu
   ###Xfeo2tnGLdoiJkAJljvnqk2Qv/2tdQfVmTtdIBImYbUtl0M1lTf1f3nW1HK5UhfN
   ###k0nhO1/CzBLpUS+F38TlMglShW/Hl8bmb5YSlYknum1GizLPzTIokJEx9e+3+l8o
   ###SeqX2sx/HwJmZz61s52WyXXqSFeazoBaPmbIN4w1UZRWNTOdaZlUpp9WFs4xqsoZ
   ###/KfGWK19Kpcb1BjKvClAjcHQkJh5o7HzR8oRpEMB4q21rHCi9ZQCxgqf1zAKlGrT
   ###a2iccrt2lfYkK4wmVypiHi1pCA4iAooMwpa79G9fnh668Q+FzZKIByQXi5oC26eV
   ###cgkTnZcEsn1SXVely3jB4Vz5OP2MG1gG0tI70WwQb2FT/9S5cgHVSljouLN/M/ww
   ###HH0cpsmlL4kH3OBfJaREKcKKUh/Ol/lQJz50JTtMpzpMZTpMa5FMkbZMbC0rWG9e
   ###gC0qR2ffn67pIFsHB1u+kcUFmi93DZsgVE63+i7QAnG+aLukeMCK/zPrmk36apvr
   ###T96dH5czSqkZZgOWBhwjy3nvRo+08qKQ7ckKk2dF1MrDHRoSiExjw8QPo9Rxsq/j
   ###9PiaiM61yEaLunhzBxYZg1N5u/BvYLY+37BNB0w2jA2CvrSJ46S63YS+mm6ilzf/
   ###gB4i6VBDGatNFUxF5EA0SsC0CVAKGYSCvA64LtfZPC94dq7U1wR7iL+R7dWQpZeU
   ###ejHRLI5xw1RstVq2XiswlY7C+Ljhu9y8HA5mxQYOsoaipBhfcC78JO4zIn1rrYuA
   ###np1FO8/3Kw+2TuWzW/8oVk/eiOUxvQyQ7udoCnUMBa4CLKY2siM2O60txVgL4MyK
   ###t791dCtD0Y18CG+vGm4xqVI0Ud1YeKGIzushhdZ/YP6v3mgw7kyib5L/K9zefLqN
   ###+b82t4ON5mYT839tbz/k//ob5f89jQej6fWd93zNO2XiQNxlf93l2iutVF8LpQd7
   ###yAj2kBHsISPYQ0awh4xgDxnBvmBGMJLgKx4Z+b3gVT/umu8YXbm2S00YgYJ3Zl6o
   ###ty+9ysZasBlsfR9ubx371ufDNyfHlfbM11pbbkfqjRJ47ZulGUicpZN4yEsb6QGq
   ###GNBHZFngbyCGlg+iTXxZgd9CtclldEu9t/rmBgnyIGJCxN3a/xuuCik9msXTytHv
   ###L08xpQJDS3wPwrQQBaDlVLICLs8M+GhA0G5PPe7P8EnXpCMWRXkZP6O9SWRPr16m
   ###bVkNKzh6EG2wYhftcW8QbFeEzbmq3BqOXzKCUG2zxamDWNgeqlAs0KcpX0Jg07Og
   ###GW6imwJvSmlniYApulXRdbM/9bI/zWJXUzAVfC88QmTMbdlHq2f4irBTvLK3JxAD
   ###K7cu4e8Km0k9rOrZ1mFa6xX6yq8DVASyMETD6uD3T1Ti8Fp0WMPvB7J//5MOhtyz
   ###B7e/H3xWF3V40LasZpQlQTQhV9A38EaupmRb9SyqsqWqMLXIhZJqdq7TB0DNwAA7
   ###i/c5kGdgdzXiocQkkkalB4V78b7uiT2RGkLrQIIdtgB7wirrhgC51ov9WnC+v7/z
   ###OevzOW2jUkmeQFSP42P/X6BSbDb9Bv+XlOITPNMwncW+2eh5y4xqJf5WFVoK0eCD
   ###2i0loE8gP8yFvHSzoU42lDCA3rYNN2+v7mSvbTC0y9/jpM51QGgMQh1/IrYw/70i
   ###dESyQmqHKxIzFL6X+JnfmW0nf7IG8EUyjcb8E3svhovLLBrWkSHEixn53SO/6S7n
   ###u1sk75u9Jw/jhPUNz7xdC+SCmlY2amSjVvWgFaz5Gw7qXos/1XQ5HEqrZ72ZtRLr
   ###DY6mpd/xi224W97Dbnm/T8rP3qsNINKyzN6ft5prW8cN+Kuqj0pGaMSxul7RDTQC
   ###36/O3qtzqLibHvbgbFdXmLPNRLeJB3XJNgXxkMhE6QelHvB79kH/7or3ZWgK9gMJ
   ###M2YfjLF/MOjO7KwXE4yozT6ct+RyfDiHfXCGRAbwmn20KYOLLkDH3biFcOvC+HCH
   ###sZ90cIim47PwvPWpSYMOVRDUWOOM1QjOKbDLk1PZw8SIisrfxQP6jm+kaUzfTWPj
   ###mhtrpRUPzFfloMsr11q9s2l8XnXA2rosNWi0knJFp3GtxSmBESZ6Gh+Q/edP40bL
   ###3KKOC1BshNUWIVcGdAaZnxhNRdTATV9jCG4fGqxZNnfWQjyoBagMo9XHbIbntVZR
   ###K6nIxcSsXgEST6ANjxxbOcrVusZJdt4anzXPGQkh2NVQD+dmUF9drdUKjRUt6IU1
   ###yvoJSvVzn9o9SCDARC0oMndSEuLAa7BjMtExDLSI8Pr43dHP8A4ubq6sV59DN5Cz
   ###ljFKvWuMUjEajG+mXB8zTqKbi1Hj9at3XuV5Z/KhIRQNK9wZCY/RxIebK+Jw1Ycm
   ###9n3GhwBzBJA062F9s75d32EMYT0I68FmPdiuh+z1Zj3cqW+wr8365k59a7u+vVPf
   ###ada/32bFWNEtKNXkOWXFRE6PTk7bv718zcjo/z3yKptgAE1/Oz1661UCSGyBFqFB
   ###hwlBeNp2Jlc9ccRzw1wVXt3iyiHXDlw3awwZSfoipNw5PY3Z0535rWs8/m48Ye6q
   ###i9EN3DkCcWkyMbj+nw32fNaPhlfcZUC9u3O8k6eDUZfyAp44KdSjwRx44rxQj0Pq
   ###caOkFciobBQz97t6fcfpuPGK4eq/zVeDzkyaDfaEzAlrs7/x+TP+ONjOkDx/STpX
   ###0a73OPHOGsk5+2uCIwvPvX1Q+AZryccD/jOEn5AQgm8fXGi2s8XGEqwilVXl0av3
   ###dCDGxiT43mBc4U0E5/XVRrLqgw1UCEGqgrhZjwX5TWSUfdkAeUJGeMMB1OJ7BF8g
   ###eFp8j3IEkZDNGcGEjgB76ExHsSgRnmsZC77xHI9PnvDfIvWjeNgmDyJVJH/gwRzU
   ###WWwuhKROq2bKbdTudiNME1Dn8frrPLh83cPG66DMxJa11iBzNSTNIwDhGQIlMqoA
   ###t/DCNwLa4hB2BbCDjb10kFccnSqx5SqxTUs8dZTAOakS39MSfOjG4q7bZyRHFI42
   ###SNQZ6WldjsbRkCz1pMsBBT7J8D1PMXOEiSahAViS7x4n34F2pi4bK0Z+oHXGCMLU
   ###CMLFR6Dw8rLXHyURzqd4TOvVd0xylMGP8OoH6P9RbAGkS3ps+dkxlow7PXGhUtDO
   ###FlHTPJnVobt6KKdCzu5AToZw3ZL8ItM9O5sxXmVti8nSTKBmv2v835qAKYLOmtOd
   ###Ywx3MIawPjQShuqKamyi80ct0UjVkhPTcOfpHLiDQAIaErj5OkC4VB73bx612F/+
   ###mqaHOtdYfzS88kWHdeu1o/vC5dLD3zeO64yBvxwmN5eXcS+OlEsFX2MY9v7juMSg
   ###zW6KCTw/MFtymA2jfs3gI/x14xEl2q5bgBbNVjllr2qlhZSfZ10uO/9eUB9phaP+
   ###77z6H/nVOcVxVP+DV1+vHlJeL5o0MJA1WIqmEASN60fETWhGreMrDMgFcOcmUU9Z
   ###3zCtLd9wVLUy69Z/ryMQ6hwW9ZnG+LrUjKDRiQK+bkC6zjcRsrkz/Em7wLt3f4hO
   ###OPmt35XphJBgsz/6wcJ2HMOdv2eJ5Q6pfL16jP6sEGhs0Ek+AAms9EcfwZh3HV9d
   ###+7uQjOji+Tqw1V7SZ2RSXgAX8nAAwrDgDbq2oC4l2kyBdtZFmUPw3yByGGJSraUl
   ###lOZacFy1yzcCq4ZLcndOEmYHs2SThUlu5U6S99eAuTYaB829rzjJ5kZ6lrUyswQq
   ###Fh9o/me9eirDBIpJ73qNDZhmuLY1SMx5qpk2s5az5Fznmi3Md4tPl1WBtcyqlSdc
   ###op/YM2lWT0YDdqhMRknSmHb6H2TQCfP4DI0FLJg2kq5+faLH0G/lTbJJRjvJLRmQ
   ###kvkt1loMMxj+T8pVCFSFvo0qCmAYrkNuBxPdERp3Lv0WVxxyoZkJ/aDVkg8FSq0c
   ###jPmdTwRPEdSV5CKMgwpkIgs7e7AkP2K+bNsuLccKB+1thGk0uAdIEvVu4DaXDLHF
   ###aM4AYsRzaTJORkO2FcGNhC0HpoBLIoyBKROz5K/JXCtSbj04ws+mAxpeir+8M19C
   ###Ga/F1m/2PnMF7niZP/LKiEMqyDikUuMK99Lv71LvsSQOLw+9jCp3oko+1hhV8luH
   ###m9kWJItwEqrc2VUEpNOTF+C1Z5+JnJA5dzTBPc+A1oHjL5pwLlbKxDJP8RSwlHG+
   ###I6/T457CMrwRb3yj2fR+/FME+mEsA/iiXcSQ9TIyEmdz9Rs6w2HUoCCExE11HjMX
   ###OmIkaAyhZqfXPJStCIejgil1ufAEYskdFhbhZzdxAPwIE3qDllACEHVNi6r4cO1k
   ###PB9eAaVqRwW+13SFzBIN9DVnrKU2N+dwXEKZdnTJV+voUirgi2ivrNiVy3zU1br7
   ###AjLw5Al7piqsxQh1WeMDg1A+jq+X35PxgMmjjf7oqjKJ/AZNXcOw+ZVFSC362Zkw
   ###tOWcP0SjX0dlMOcNRreYnNWMr6zQGK+zARd9MRroGMb9aTRJ1ozkdcB0vT9oPf0e
   ###IdzaCXwwLcBBsmeXarV2ms6vR91ai8LPtggcdb31llchy9lQ60wAp9DiEijIUbcq
   ###MUXySL8kPMfEZTyLLngWq378J/c05NfqBhHbs2xffocOeX2kCHz7R+OpOqVWVJpB
   ###IB3/vmGtTNFX0kVMFLyOLteJChGeqy25CdjeqbGHKn++F7tpPPpYYf+uS9EoWGuu
   ###i1yzP7eCZrNaCcCkWgXcCGqspL+OP9eCDV+qJX7eb2ZI8acQ7fqWiZBs3CBun2j1
   ###XlrgF5lPP0YAAQjMhTqjOPEeX4KsD30XCvFARIqH8vbZyclR9lg47FfhQoiC/CCa
   ###TuLervd4Lbj0Hj/2KnHeeDHl8M8ZQz755fDw6OSED/k/4fKD2/+fwfSW4eba9Tfw
   ###/28+bW5tof//1kYz3H66Bf7/W2Hw4P//N/L//z0eX6+9mVwx/gTCrqMb9YNH/4NH
   ###/4NH/4NH/4NH/4NH/1/q0a/CkXEPvHcvf312etT+0fLNV6+1I/8qO5iu165XyRtg
   ###f+DNCqMubAPjzeJ3Eb98G//JaMun/BCU6mZwdh4HHVV0T8eh7EdDHYbSzBAB3jJq
   ###LmY6Ri0jgaOVWUgkvqN/WKHALKQTVdNCoXVxAQLA/PqGoWf73TOGaDLaiq4SNIMd
   ###s8oPJap8D45LwH8ML+Ormwmo/sAEhbF9J98BVwAWLDhtI3ZAshOCqwxvRzHm/al6
   ###o/F4JMgwO7IYBVUnB7dtoU6likX/i51WkUiDDCfCJWTaYQ+9mwloY0DTC7enO8k4
   ###nvCTCC9SM6aECxGQKvm7BJuCvARwMrE6aoRsBN2YR7zusHNiIC4WwCA8duQxGn4Z
   ###RxOVhUj1ig2+h+M2uY4vpxwCwgerG0/RAwNmh7xBZzxGAZUL7R125k6njH9i5cg8
   ###maTfGZzFw3Nv5u1Ppwdstvvr7N9diJ0GkKPQFFwGBjfymo0AvDlwKySQvZk3eM3O
   ###3XjIznQQhuF+/XouclRmfi7S1L12m98xxisakAR75iMe/BBNbQzoSdS44Kvu4dpw
   ###Ybzu/Rfwha6+bGiwU5aAoyrh8VXA8UMGOH4oCw64pgIgcexBdoCx+rhxyX4KcMfm
   ###FDaWJN2Ge0W4ox1fCh5zHa8qYFg1VyyMvS8RetiO1jxv6OGyQYf3gPKQTLSQ+5xr
   ###VxnSsYXFcbF9Jwzt/MKRLwLRay/JeNgHkGNMF6iEIIpFPAkVFySumc00Av9Jw3xl
   ###hrqYkPMGvE7biJA8hm3qPKpOxnyK3egqHtZl2vB6NnwHnRlGy0vDCuDCI+NhWh7j
   ###2IRpP4RL+M+P/0CR75vEfwg2tp8+tfU/m083HvQ/D/qfB/3Pg/7nQf/zoP950P88
   ###6H/yIjpg1P0fn/161GaTOH75Ayh/lEqHC5Go5hFRn9PqHvONtn8ZX5J2cjMejyZT
   ###VBBl8OsYvQ3EJWDtzQiBJIwvZeE5959m7NNtg9zplABkP+PGgVJAqawfMnzquHQ/
   ###vUnEZk9n4OqUNz5uOUbE3Zi5F3MOiHwZ77zCmuFXEMRgZcQCI/Z3GhaTsW+FhDXK
   ###0LiwGSDTwWFlW+5l7XWmGbJXsTQrurKUhoNxmyoOQSWk4wrWJzqHzUnET1aQzr3T
   ###0SEJ68ejPxbF78N48iZqtKzQ8vCZp22ys/mORWzmOXO6iLSxVuBR0Q0EJzj0IeUG
   ###CZrJ3vhm3q9UCGIYITsQ8Q7ErtecPZ55twn+CzZ7OYm6nIMZgTg36xgqa40VyI36
   ###qGLOKwQ2KxctiozdiEsK3IoI2MhE83hwM5D5yRDmerWtTmrGmvpVc6kOvO+tmK6F
   ###MBD7rZXOr0Vi7D8RiMt+6Q7PjKGci2+g07Y/0CwHmBUm8Gl45zQVq7WshaFkQcXd
   ###v88jx3rd8minpJKkc2yXRPH92toZ0lWOksbImKWjwZLKkKtGxRcW2chlalAnuarK
   ###+UpUw+HyBFj486DFRg1P7J8DE+8K9uzjCw//wx0qoIAQMFtxb1UaxPaeRrJlLTSw
   ###MT5kSPfY8gTO1cQHlS5NfBK7Rn/NSDspsg4JghdAAGnAZJmH76AFSdjtwKikRtPM
   ###oYD1rAwKwa6V4fAQhL+mTgCpmqthYlBGzGpGzmr1/UBgSkZeQWeuKLi3zDPrCshI
   ###kpwZbT80A+vzkweyv7fk8DKSnsK0AiPlKZ1ZWLXnVmJ6JWdoTNI6eD6zMyOw0lc6
   ###Bh5mDlwMmwOhFtYq/AVBjW86l9CRtpFq7vno+LnoW4kcM7MA2Ni5QdKTsj14C4nu
   ###xfMtSQyv89QEBbknJRrF58AJmGiUSk7MumgFZtgL4+6uM1CEV7l1JlE1cHDOZKi0
   ###rqINsVh69swf97LxRqdP/eZ4suEsyGkqfN9pzgmMLGSLU8iW2mQULDwGtthU4d7f
   ###CS55u+U+4xAxMpAkF/xwskEk0cAClEqDdyEPbJlnGdS0XBWHNmlekm/Jwlx/IvbR
   ###2z8EJ6fSvtYFvqb6J2hMI+drzqI0Z/TFmSJHVqg8ngw6o3wHb1XyV02/1FQyJvHV
   ###Bty0+KOMYa98efuPMOAORl/I+FNo/3m6udnctuw/4dOn4YP95y+y/zSfpu0/hycv
   ###3715MAM9mIEezEAPZqAHM9CDGeg/ygz0JSKB59mULqLuzZXDzDS9G0cF5iftrvvs
   ###d6Gt9YKtZlPYPFDb1r6BEGoVZEKrHoZlOvekF1pKIUfjrUXn3n5nPO6L4+2ATcgI
   ###/lX58U+fvVT5GyvBesherCpxaXW/GzPyNgaX2wiI/oHnnY3GSPlZ2/FwfDNlDTD6
   ###Bj9QB2hGbUsNTzTMhte4mH84eX2X6R0cbXfB13TMBENME8b+nYAZKQa+pMFOMCbn
   ###de5YW15WG2IIu3llGpEjZcquNxr277wJkyqoH6xX4VPAdwzcDZ5V089t/6JE+yKl
   ###FqR57VwkVvNeB/gB1m1+P73uxNFPNOx0MXTVMJl2MH4tujLvKQWTd9thJ3qXey/D
   ###p/xObtO9mJ1MGKcETsJWq6TDmyEpmNubTiu4//r551fPP//2/PMJ+//4+QHrlSOF
   ###LlPBI50xTZPRR7yHz5iBy5t+H377pH8Dk3P71zac/XBt6/PW56D5OWx+3mx+3m7C
   ###CPA7tw0x9mmQkE7CppfbNNxwH3fu+qMO21vozQoNaqsT/yKbxgJ13TpEf89fpxEY
   ###A2dw53Yffh/gOum3TG7F4EmQHRTyKEPoJIwzhOlCaUe53cQYgPUy6rnQAe5GeLyE
   ###d3x0mA/pEeO4B6PhyGgI33r4GncgxlyIbpkkAzJHwvjIaMS3Rv4OnM6ydwaO8sXp
   ###77kt9EdJ4u2Df/oBaSFha9UHaiiMhFAKdCjSkd2roOc6hacE5706JCFI1ka48g+u
   ###84XzhR327cNnJ0cvGXPz+uTl6Us8RV8xluyoMqt7dz7EOGdUcDDmjyIf/D9Q8DJO
   ###wwSPw3lahliYTMCjbfMTmoZ6h4NuOoK0jJMKzecc22qY3vXZ5rk8/thDExKhxwcH
   ###4eaefAWWC6/C3gXbPkbKV19C+WXH+rCBrYh3Ogo9HQn0DkMED/qcIUm/cDoLH8e5
   ###vx9ugkYy9Qli/7Ohai2lo0zIyng7UN2zP22cpwLnc19/mVSRH1kV4vEPJ4X0beDK
   ###LVZGmh4vvQopZuaod5+GcJ7HCT9/MAxKxDcWnsnQskrs6cw3gpftHeMXJyQdv7gN
   ###UDR+UmyR8UvCMNf4+QWK/oedNqOr07NzhhMMp2TPn8yrXfXslLZ1MO1XN+pecF9f
   ###sHK4ROU63DlZqPLmzhKVxZzDZeYcLjPncJk5h/d4j0+iQBAuhAM60fMCOGBXDpeo
   ###PN8y0spz44BjzuEycw6XmXO4zJxtHNheCAdkRuwFMMCsGi5cdb4F1FXnXvvUXMPF
   ###5xouPtdw8bmSNb++607ii3BzoVU3kqGLgZWHo1Ubx7Zwbew7XKrvFFQ2FzsTZX75
   ###uQGiK84JC6vHcNEeCQR6UX+aM3t1RTunSfzjBEF27TIYlV1bV1ykb3pA0tqLTdy5
   ###hKUnPmdta+Jz1rYmrmovNvFwc5mJz1nbmvicta2Jq9qLTRySiSw+8TlrWxOfs7Y1
   ###cVV7iT0eLrXHw6X2eLjUHg+X2+PhUns8XGqPh0vt8XC5PR4utcfDpfZ4uNQeD5fb
   ###4+FSezxcao+HS+1xnLhxxF//+4ud8uWHttw2Wg4XsxZUQkVlccIkTkJNw81XUleG
   ###GqnJRGrhoEA8PI77Ud2rjm6m8It/4xlaIUEr+5t94W/Ba+tIWFGq0bCnMqHyTyoq
   ###xUVEP4khJfoJvOHCc/1MQ1CY4UWJ85ewQbS740TGoXX4i6l27ShBqH1PNSrNCG2d
   ###MAcGdJNEbfTIlS+Ipr9NWkJkVPp4s75Sq5uvL6YzMnHQjZszxiYND2B4I66PgHIa
   ###7gb1UhNBR8VWU9xgaHd60xapTnIfQjxj+imZjtSzuNuAq64WHZdPGzV5ksZnb9/+
   ###9PIQIq+8bj/75cXLN3s02DAYMSEefB1/tRnwyBMOTT6F/OdwckWyM0pjUEuG36V6
   ###R/W1zdXjBKtGCdxlYM3Br/Z4Et3ChQNdYDq6uupHGrBU2cywGTLvdvrcdVChES3D
   ###0JqW0Q0T7S0sAVGGUkgDDmlMZ8MASXqbrDrcy8F0wXR5PkbRGHDexAc2gIvRoK1s
   ###W9DtMPoof6JRNbpoA6FMt4brUZcP8bDlaJjtYPK2UgVLbhvckXxGbq3NPey24TOg
   ###IhahNXFS8NX5si3QlgAJvXrxrkd7Gg8ATCIx2Ir0YAby5u17Wx5X4CsnaMN4D3TP
   ###03cHcvJnua1FjxOhi2bLD5eebqMJeAwJpMOrllgRCBvBMvBe5pnIkPDC13O0T/Nk
   ###ZOaAKd7oNmSrPD2aceHP2fSFs2mCgzlNq0E/ouWfPPEEjJ9+SRjb/VhNZ00QvAfI
   ###FMUsNEFi00uRpF/fvHyrxpULPoczwrydvTvinj1HL9o/vfntxdFPz/4o1zfavlf9
   ###R6w343pGChlvhh+Go49DOhDwONEeGNiib+QFJQuFGRzNeOkZK0UzmqYRxTgswa6n
   ###zx+/Mx31K6mx0DaUm0nLw0R8uYULcIXwAqXGkZqO3q3GnB618KYt7IDUB4zbz1tz
   ###ft7Oqogp8LIr8gQC1vZNocAJvyrP+Bkz3Dl6whrJBFdXbDP5Ks0viA6k2OcaTTBY
   ###mGLQOLmMSaxvSeq8XpVG8mRXXm8SrJQmQtrXQ+6lX04F+5DislgR7agleQHlFMGa
   ###lIwg5bf0SWmwV+nuBDumy9tclv6Sd3Yb5zZPxH3NGOkKPxv2OS1teKFHdzkD1Xgy
   ###6kH+ADajASwKBj8T3k70qlx8Wck1+nMSwHs7F05Eq6wzuJXu+dbFL6eh1zDy8vq+
   ###eTlMr2LT/EC3lXFazTlmhRVLjVy34ts5nU0SzHuueQH2/vp5iuYLOmPjqktINXty
   ###Unyzu1cLdKftX3N399sC3UkBfu7OThbpzVA2zN3l8QI9Slna0dmnVDtpn09xHusO
   ###HidrDsKbIsSaigPZfv287r1i///G/j+Bv46fk1SOOX9sIFjIXnTEpzKXCzbWvL65
   ###6E5WMslSO1m3MtdODte2MpAh5/zabDbnRroFugkX6CZozt9PsEA/4QL9bM3fzeYC
   ###3YRbc3ezXaqbjWqJ+ZSiBona1tqZFF3CB4uQBYbDdY/9FwDLxv4HLeF28z+AMhD2
   ###binaQNuxJujiIFHaSEHG8/e+1jw1i7ocG6abscZq8MDffHqK0c6cnc2OB1+HZ1T+
   ###xsudNKoVC2S29PCVZgHK3uXw5DbNr/cMketLD5kJTatLDBirp+ULLop9pSGDTFcA
   ###Zct71/DcFQ1Yo3bIi998N6IWdyn84S1YI6R6528+J1u7vdT0Uo1Z47a/fz0cVNr3
   ###5ZcLW3EuGfvwVy5Zzqkwz2KxZjKW6WseKOhN/gHNysstEWnHZlCkHQX4XOW8bpax
   ###7Sms6M7Xm3AQfqEZq4YKpiyctf/SOW9/qTlvl5zz9l86Z+kr+wVmbTWVM2/DQbdw
   ###5ptfc+abO19s5ps7ZWe+ufOXzlz5wS7HXKpWcuarChXOdSP8ipMVHkHLz1c2VDRl
   ###Ue4LrbA5WKFl8FaPIJcqXLidsJFeDRmHcuEl0XQaD6+4EVCbAQVA7GM+z2hbrBK4
   ###T5nMJJ+h9CvKk4DNlZjmiM0+LZfvexgOM/3hgJh8MsxiHrlhnqqPYVa6EftvyoY1
   ###9LjFi0fMzNGfkE5L2cSExwK4TAG/JSyOvYZ0HLlEaFyOxhE4ZXEfq9VJV+IUGjhZ
   ###meIZHo5u+pA+GcKxsungTVke4seyAEPf5e15uCrKqcMyxYvURKqxyySKPlTQHaxZ
   906Ojv67ffT6he5M8M2X06jfh2L6S0pbhgDjV6ITCGWKi4bzgJd+XpcndG0cjiLQ
   wLqICo6uTP66FN/X7V2ZPcATbBMMrJgmDHMZwUBFaGYcqt25b2CF8KQz0CKQaAGx
   aSReiIKs04/dmokZ7NPcqCHiGrhxI6C4cdljMmtkrtSy/huMrsogz5LEisDnhppV
   e/jVqT9D3XuiU0TLS7GTCRjIRVRiRW1yXSUOWdsMHrxnGfJBOUvg6CAgA9BUaN83
   KKETLPo1rMncbhQmQKZ90CvUdf6w5y9P3z07PaoQsknGVFRZ2rMqyhJVvvKvz99V
   hFl3rkoQDIadzc9evj6t9OaqDKf3TwCtPypag1m++ktM594+PjqsGArG8i3wZG0Q
   OOn10U8nFUPBV76VF6e/V4S+qnwlfrS0IQxR++3Ru8OKrTtSHmX5bf2Ajbz572c/
   Hj17UXkC3py+n/Lmsq+T6z1zEaldKvVdRbv0a2xM0fdftjEh2KOnokqT7UOghaGa
   M63+uytpO7PwDmQAXtURTFbJyEiMXVfr2shf0PoguohvBnO2Lg3sBW2z52jOlg37
   fUHzyQ3D9gX6kBb7guZlrJjClsENqKAtSD2a0Q6N7JzdgPDby2iDHKupU9W1g16I
   IA88Wt9jdvL/+Kc88yuPL9SO9fM43Up/NLzyM/a62EQkDnt6FEciVIMcAOdHO1Pv
   8drGpfehu55kWzxXY4z8gHwVn8RFg7NVIoTu2txDJ+dmtbnWbAaZ1e0FqhNrsKS9
   yLNz3rHqD3jCFdP1qyphVTUYTQE5ztwt0cClNFqaEU8Wakuk7XA01tONGbJTXTQD
   pXzCjloGPSpXYyfBsp3ca7c5dnrBlQSb+eW7RHu1a9u+KTYbFn7hEW8Ku7QV05+N
   eFqnjAJPnqAGuuI/DpuGa4HZvegREgHw0tu2jh7PG1HMdFCwlBVAqZq7yqs/7bKS
   itiu0yFk1ArzaoVZtYK8WhtZtbZyKm1mDnAru9KWruTw3HBVMx0ZBHbJFdpPuZnA
   GhNy0rjsdJOKsoP53j64jASh1bdzKTUmVFth2n8pawwB9yAmOHzgcO7Jw5rSTDAm
   MjYvnPkOZxHjIolldbnP9JAp3IP3K+lfdNsxIqM33EbOhisvMojGNqEtfy+jf9c5
   bPs2pCNRWW5DE7C8X4JDMKNxdS+oe5t1z2ZdeX+XQAjhk8N5MY3PcG2O32ECekvD
   Y/WuHY2T4gdpNdnnz7S9/UKsSjECL4e3nT7EzBRh7lhrV9PrXaFpI2070Kpws5YF
   on1tqyR4aPN4gol62BEZeta6sfr7dIbzwu5dB7U1EA8Z+ad6GS+xaDaOelNkvYTa
   zLtiElWhZjOFPHVDoCu3KM7NjkmT0tBRasVHPAndcvRKKzlUu2fqAtk54z1cdKs8
   DXQ22ly8UaVdcDa84WzYIJjOeuF52d1yKcJMGhxhVUvz9K5tGrnVXQZIsSEvChOH
   KJkWQxZTDaeTmWQstLh3mwZC0uJDPwurcQ0i9O181i/OXeUrlQQDCB4f+/+CbCvs
   aGzwf9OlY8i/0UryoAioq+e/T8WDov3NE4a4oLLv4NbTsKKDTN+xwNkynjjt+HCf
   cz4QbOWICqp0uvom4UudEC6/a8kMPWoVnRf0hhbkX5E1UzNzW5SyYS0SqpHmD7zs
   +mlnpkb2UKhzMe1gXxu4luvg3n6xXmXs3WU0vTNSYzmnuR80m01X9+ZduMCF/Uvp
   oB0jL9BPHr98/eyn9rtnr384qjzJOKH9fIYFzIMlT1WPBpfUKC8zRkYqW14+S5Kh
   YsxXNC7kUW3dfobtobflnpskkeIHadMX45VVKQY529bVCApAqSpTq3TGaFPUifLy
   BjOdUkIXMdNgpb6Mo/5FiqemwWoN9kxVcTHXkPMhqqgiiouEVcSbl34aFGl9F2ik
   MX0ERKY3r0wutv50Mhm743/pxPTYCphqOVClM/Lp5vzmg89kbrl2VWbltaQxHm6C
   DJyJliBWpUw7B00izYKMv5/yHE6tckXkkTto5SjfyDGCgjrkBhoNVSjrj9fRkNUG
   iSEeNmQIb8dRg/2Z3Tj7kUV1fI2sUmJUnek0Gowh8oaw+HC1Lx0Nj/cezWSME9fw
   1LljLIdpxwLZnUf+8P6JaXG9XYvDMVBwBEKXqU1leOrvOfvO1HSQqU6iq5t+ZyLn
   udQsuFK1YYycPDrH3swa+8pcs/naIHYN837FxeKZIzlw8D5ZCJqqi1bS7OVziLFO
   qcdqtoHNFnP12UMVzCNG3Un28oq0WNdnca0CXaoe/fO8OkR4aiUk+HpRaSZ7tSqJ
   FbG9FGKlj4EiYdQBUOfp4IS8nwfURU6MeQ6PQkDcl0TOfY6c8LfXaOWeOIaQghWc
   omLe/k6BBQ3uKn48Z0SlVb5QpyRFAWW4N0fvF+71TN7xkZN5lP0pzwUmeiBNcose
   VrwmOhxGsMEFBa5bYgkPS6gUMRMGittO/4anLJNv4ciSSV6s+AxuPu5fxpl6zqRm
   DAFCJ6fnBh+QtsofeMIa360JwR4p1XHqmE6LTsLL9B22y6cI+QEibxAngw5k3i7Q
   UK5Kf0sXtIrqxkNxc/Zx/2LXa84e7/Rn3m0ifuXjIjcLI7eUV0qJGli8FNjKN2dj
   mqU3yxIts8XKAo/cFcqEykhn8JtkQUYUv+HZgox4IvhcMzjXKrl3IEO2gUnXLMNE
   T/XRZyyA+XFXfdxbWYCPHU7AZaK51kzLO4+cZpkcVZz3ASkj+4dq8byqDi7ofajV
   MplXGAqDTzw8Yy2cs2oVHtfOF2/KUzVlQK9go+vsX+d42FB8Bt0g2nIOSsbNy1k1
   fTVYhP+zRXlzUAw5foXkTsNeilXFsHx2T/T39qbLfIYd005VtL2K+FUzMcD3nkh1
   5v2Kmyh1bqNJ50qln9o1Zvr4qXQ4yaYPQdTYqMKELKNthWhl5eLiBHwze5DpaI5Z
   nXLG0v0wLjUY2CPWgAxXlFy8d0CpN41vM4BUACU9JNZIWRhB2Ww4iWHA6TG86Ezg
   DLiNRciyvNHgUJJ/T6YVRMB1TjYaiI44xPUKz2turVcRICEjL1BZdh7doWt0AtLo
   x+u4B3LoNJqALx0MeBIlELjK+xhNYPSjCSPuYmtgGPoXR89/+aF9cvrm3VH78Kc3
   J0dtCJJ6wt0I4/6H9imkYD1hOFsR6QjjAbCa05m6SGLoTS8g8tzoDlRA9LPkbeRn
   9ixhPYmEYkUl3AMsMTeVdvFWpZXnd+ocSp8/WEt/hyfr4yU1DtBj6uSXw8OjkxNI
   jfR/Hv48/Hn48/Dn4c/Dn4c/D3/+v/nzP0cUzKcA0CAA

A.4. Test Vectors โœจ

Okay so the Opus test vectors are way too chunky to fit in this doc ๐Ÿ˜ญ That's why they live somewhere else: in the proceedings of the 83rd IETF meeting (Paris) [VECTORS-PROC], and on the Opus codec website at [VECTORS-WEBSITE]. ๐ŸŒธ

These vectors were built specifically to poke every corner of the decoder, so the decoded audio sounds way lower quality than what Opus can actually do in normal life ๐Ÿ™ˆ That's on purpose, not a bug, bestie! ๐Ÿ’…

Here are the SHA1 hashes for each file in the test vector package. Check your downloads against these so you know you've got the real deal ๐Ÿ”ฅ

e49b2862ceec7324790ed8019eb9744596d5be01  testvector01.bit
b809795ae1bcd606049d76de4ad24236257135e0  testvector02.bit
e0c4ecaeab44d35a2f5b6575cd996848e5ee2acc  testvector03.bit
a0f870cbe14ebb71fa9066ef3ee96e59c9a75187  testvector04.bit
9b3d92b48b965dfe9edf7b8a85edd4309f8cf7c8  testvector05.bit
28e66769ab17e17f72875283c14b19690cbc4e57  testvector06.bit
bacf467be3215fc7ec288f29e2477de1192947a6  testvector07.bit
ddbe08b688bbf934071f3893cd0030ce48dba12f  testvector08.bit
3932d9d61944dab1201645b8eeaad595d5705ecb  testvector09.bit
521eb2a1e0cc9c31b8b740673307c2d3b10c1900  testvector10.bit
6bc8f3146fcb96450c901b16c3d464ccdf4d5d96  testvector11.bit
338c3f1b4b97226bc60bc41038becbc6de06b28f  testvector12.bit
a20a2122d42de644f94445e20185358559623a1f  testvector01.dec
48ac1ff1995250a756e1e17bd32acefa8cd2b820  testvector02.dec
d15567e919db2d0e818727092c0af8dd9df23c95  testvector03.dec
1249dd28f5bd1e39a66fd6d99449dca7a8316342  testvector04.dec
93eee37e5d26a456d2c24483060132ff7eae2143  testvector05.dec
a294fc17e3157768c46c5ec0f2116de0d2c37ee2  testvector06.dec
2bf550e2f072e0941438db3f338fe99444385848  testvector07.dec
2695c1f2d1f9748ea0bf07249c70fd7b87f61680  testvector08.dec
12862add5d53a9d2a7079340a542a2f039b992bb  testvector09.dec
a081252bb2b1a902fdc500530891f47e2a373d84  testvector10.dec
dfd0f844f2a42df506934fac2100a3c03beec711  testvector11.dec
8c16b2a1fb60e3550ba165068f9d7341357fdb63  testvector12.dec

Appendix B. Self-Delimiting Framing ๐Ÿงš

okay bestie, to use the internal framing from Section 3, the decoder has to already know the total length of the Opus packet in bytes ๐Ÿ“ but what if it doesn't?? ๐Ÿ˜ญ this appendix is the glow-up for that exact situation: a simple variation of the framing for when the total length isn't known ๐Ÿฆ‹ here's the tea: nothing inside the packet itself lets a decoder tell regular undelimited framing apart from self-delimiting framing, so which one is being used, and where, has to be set by context at the transport layer ๐Ÿซถ It is RECOMMENDED that a transport layer choose exactly one framing scheme, rather than letting an encoder signal which one it wants to use ๐Ÿ’…

for example, a regular Opus stream can't do more than two channels โœจ but you can totally build a multi-channel stream out of several one- and two-channel streams ๐ŸŒˆ to pack one Opus packet from each of those streams into a single transport-layer packet, you could use self-delimiting framing for all but the last stream, and then regular undelimited framing for the last one. why? reverting to undelimited for the last stream saves overhead (the total size of the transport-layer packet is still known) ๐Ÿ“ AND it means a "multi-channel" stream that only has a single Opus stream uses the same framing as a regular Opus stream does, so you don't need any extra signaling to tell those two cases apart ๐Ÿ‘‘

the self-delimiting framing is identical to the regular, undelimited framing from Section 3, except that each Opus packet gets one extra length field, encoded with the same one- or two-byte scheme from Section 3.2.1 ๐Ÿ’– this extra length sits right before the compressed data of the first Opus frame in the packet, and it's read differently depending on the mode:

  • Code 0 packets: it's the length of the single Opus frame (see Figure 25).
  • Code 1 packets: it's the length used for both of the Opus frames (see Figure 26).
  • Code 2 packets: it's the length of the second Opus frame (see Figure 27).
  • CBR Code 3 packets: it's the length used for all of the Opus frames (see Figure 28).
  • VBR Code 3 packets: it's the length of the last Opus frame (see Figure 29).
  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | config  |s|0|0| N1 (1-2 bytes):                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
 |               Compressed frame 1 (N1 bytes)...                :
 :                                                               |
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 25: A Self-Delimited Code 0 Packet

  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | config  |s|0|1| N1 (1-2 bytes):                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               :
 |               Compressed frame 1 (N1 bytes)...                |
 :                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                               |                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               :
 |               Compressed frame 2 (N1 bytes)...                |
 :                                               +-+-+-+-+-+-+-+-+
 |                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 26: A Self-Delimited Code 1 Packet

  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | config  |s|1|0| N1 (1-2 bytes): N2 (1-2 bytes :               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               :
 |               Compressed frame 1 (N1 bytes)...                |
 :                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                               |                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
 |               Compressed frame 2 (N2 bytes)...                :
 :                                                               |
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 27: A Self-Delimited Code 2 Packet

  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | config  |s|1|1|0|p|     M     | Pad len (Opt) : N1 (1-2 bytes):
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 :               Compressed frame 1 (N1 bytes)...                :
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 :               Compressed frame 2 (N1 bytes)...                :
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 :                              ...                              :
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 :               Compressed frame M (N1 bytes)...                :
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 :                  Opus Padding (Optional)...                   |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 28: A Self-Delimited CBR Code 3 Packet

  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | config  |s|1|1|1|p|     M     | Padding length (Optional)     :
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 : N1 (1-2 bytes):     ...       :     N[M-1]    |     N[M]      :
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 :               Compressed frame 1 (N1 bytes)...                :
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 :               Compressed frame 2 (N2 bytes)...                :
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 :                              ...                              :
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 :              Compressed frame M (N[M] bytes)...               :
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 :                  Opus Padding (Optional)...                   |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 29: A Self-Delimited VBR Code 3 Packet


Authors' Addresses โœ๏ธ

Jean-Marc Valin
Mozilla Corporation
650 Castro Street
Mountain View, CA  94041
USA

Phone: +1 650 903-0800
EMail: jmvalin@jmvalin.ca
Koen Vos
Skype Technologies S.A.
Soder Malarstrand 43
Stockholm,   11825
SE

Phone: +46 73 085 7619
EMail: koenvos74@gmail.com
Timothy B. Terriberry
Mozilla Corporation
650 Castro Street
Mountain View, CA  94041
USA

Phone: +1 650 903-0800
EMail: tterriberry@mozilla.com
๐Ÿ“ฆ where this page comes from