Skip to content

Instantly share code, notes, and snippets.

@jehiah
Created January 27, 2015 06:20
Show Gist options
  • Save jehiah/b0a4216c5f4fd91b1f4d to your computer and use it in GitHub Desktop.
Save jehiah/b0a4216c5f4fd91b1f4d to your computer and use it in GitHub Desktop.
A set of scripts to compare hashing between Go (gomemcache with ketama) and libmemcached (with ketama consistent) from @davemarchevsky
#!/bin/bash
set -e
# Run C test
gcc -g -std=c99 -L/bitly/local/lib -I/bitly/local/include -lmemcached -o test_consistent_hashing test_consistent_hashing.c
./test_consistent_hashing < testdata.txt > c_hash_results
rm -f test_consistent_hashing
# Run go test
go run test_consistent_hashing.go > go_hash_results
diff -u c_hash_results go_hash_results | head -50
We can make this file beautiful and searchable if this error is corrected: No tabs found in this TSV file in line 0.
127.0.0.1:9000
127.0.0.1:9001
example.com:9002
example.com:9003
example.com:9004
example.com:9005
example.com:9006
example.com:9007
example.com:9008
example.com:9009
example.com:9010
example.com:9011
example.com:9012
example.com:9013
example.com:9014
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libmemcached/memcached.h>
void print_mc_behaviors(memcached_st *memc) {
fprintf(stderr,"MEMCACHED_BEHAVIOR_VERIFY_KEY: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY));
fprintf(stderr,"MEMCACHED_BEHAVIOR_USE_UDP: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_USE_UDP));
fprintf(stderr,"MEMCACHED_BEHAVIOR_USER_DATA: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_USER_DATA));
fprintf(stderr,"MEMCACHED_BEHAVIOR_TCP_NODELAY: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY));
fprintf(stderr,"MEMCACHED_BEHAVIOR_TCP_KEEPIDLE: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPIDLE));
fprintf(stderr,"MEMCACHED_BEHAVIOR_TCP_KEEPALIVE: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE));
fprintf(stderr,"MEMCACHED_BEHAVIOR_SUPPORT_CAS: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS));
fprintf(stderr,"MEMCACHED_BEHAVIOR_SORT_HOSTS: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SORT_HOSTS));
fprintf(stderr,"MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE));
fprintf(stderr,"MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE));
fprintf(stderr,"MEMCACHED_BEHAVIOR_SND_TIMEOUT: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT));
fprintf(stderr,"MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT));
fprintf(stderr,"MEMCACHED_BEHAVIOR_RETRY_TIMEOUT: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT));
fprintf(stderr,"MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS));
fprintf(stderr,"MEMCACHED_BEHAVIOR_RCV_TIMEOUT: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT));
fprintf(stderr,"MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ));
fprintf(stderr,"MEMCACHED_BEHAVIOR_POLL_TIMEOUT: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT));
fprintf(stderr,"MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS));
fprintf(stderr,"MEMCACHED_BEHAVIOR_NOREPLY: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY));
fprintf(stderr,"MEMCACHED_BEHAVIOR_NO_BLOCK: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK));
fprintf(stderr,"MEMCACHED_BEHAVIOR_LOAD_FROM_FILE: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_LOAD_FROM_FILE));
fprintf(stderr,"MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED));
fprintf(stderr,"MEMCACHED_BEHAVIOR_KETAMA_HASH: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH));
fprintf(stderr,"MEMCACHED_BEHAVIOR_KETAMA: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA));
fprintf(stderr,"MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK));
fprintf(stderr,"MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH));
fprintf(stderr,"MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK));
fprintf(stderr,"MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY));
fprintf(stderr,"MEMCACHED_BEHAVIOR_HASH: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH));
fprintf(stderr,"MEMCACHED_BEHAVIOR_DISTRIBUTION: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION));
fprintf(stderr,"MEMCACHED_BEHAVIOR_DEAD_TIMEOUT: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DEAD_TIMEOUT));
fprintf(stderr,"MEMCACHED_BEHAVIOR_CORK: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_CORK));
fprintf(stderr,"MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT));
fprintf(stderr,"MEMCACHED_BEHAVIOR_CACHE_LOOKUPS: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS));
fprintf(stderr,"MEMCACHED_BEHAVIOR_BUFFER_REQUESTS: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS));
fprintf(stderr,"MEMCACHED_BEHAVIOR_BINARY_PROTOCOL: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
fprintf(stderr,"MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS: %d\n", memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS));
}
void set_mc_behaviors(memcached_st *memc) {
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 2000);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 5000);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 500000);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 500000);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 5);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 60);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS, 0);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1);
// Set distribution to consistent ketama
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA);
// from diff
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, 50652);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, 87456);
}
int main(int argc, char **argv) {
FILE *f = fopen("server_info.tsv", "r");
char str[100];
char server_init[200];
char **servers[100][100];
int server_count = 0;
char mc_init_str[10000];
mc_init_str[0] = '\0';
while (fgets(str, 100, f) != NULL) {
if (str[strlen(str)-1] == '\n') {
str[strlen(str)-1] = '\0';
}
strcpy(servers[server_count], str);
server_count++;
sprintf(server_init, "--SERVER=%s ", str);
strcat(mc_init_str, server_init);
}
for (int i = 0; i < server_count; i++) {
fprintf(stderr, "Server %d: %s\n", i, servers[i]);
}
mc_init_str[strlen(mc_init_str) - 1] = '\0'; // b/c memcached will reject otherwise
fprintf(stderr, "Initializing memcached with these params %s\n", mc_init_str);
memcached_st *mc = memcached(mc_init_str, strlen(mc_init_str));
if (!mc) {
fprintf(stderr, "Initializing memcached didn't work, probably because init str is messed up in some subtle way\n");
exit(1);
}
fprintf(stderr, "Found %u servers in hashring\n", memcached_server_count(mc));
set_mc_behaviors(mc);
print_mc_behaviors(mc);
while (fgets(str,100,stdin) != NULL) {
if (str[strlen(str)-1] == '\n') {
str[strlen(str)-1] = '\0';
}
uint32_t hashed_server = memcached_generate_hash(mc, str, strlen(str));
printf("%s\n", servers[hashed_server]);
}
// don't free anything ʕ •ᴥ•ʔ
}
package main
import (
"bufio"
"fmt"
"hash"
"os"
"github.com/bradfitz/gomemcache/memcache"
"github.com/dgryski/dgohash"
"github.com/rckclmbr/goketama/ketama"
)
// Since we use non-weighted ketama, this provides the Jenkins one-at-a-time hash
// function to ketama. (When using weighted libmemcached chooses md5)
func ketamaDigest() hash.Hash {
return dgohash.NewJenkins32()
}
// create an address struct that fulfills net.Addr while still returning hostnames
type hostAddress struct {
hostport string
}
func (a *hostAddress) Network() string {return "tcp"}
func (a *hostAddress) String() string {return a.hostport}
func main() {
server_file, err := os.Open("server_info.tsv")
if err != nil {
panic(err)
}
var servers []ketama.ServerInfo
scanner := bufio.NewScanner(server_file)
for scanner.Scan() {
endpoint := scanner.Text()
servers = append(servers, ketama.ServerInfo{&hostAddress{endpoint}, 0})
}
continuum := ketama.New(servers, ketamaDigest)
var ss memcache.ServerSelector = continuum
data_file, err := os.Open("testdata.txt")
if err != nil {
panic(err)
}
scanner = bufio.NewScanner(data_file)
for scanner.Scan() {
item := scanner.Text()
server, err := ss.PickServer(item)
if err != nil {
panic(err)
}
fmt.Printf("%s\n", server)
}
}
DFnqFvsihCQZsDqL985K
7sFH1EdVtlBf8gPFufe4
oDDnkzgzdhgY5gzy3MfS
QuQdf3Rys8PieMv48tXR
cTe84aCqYBGFWtv49dTv
odvqg4Gg6W3rB0CBleiL
JTuaLu1p8a1KKa3JrMHb
003CrQy3mqiXpvX9FZzI
fVYPK1i0KacnRitoPsdW
gy1HM9LaMdaYQLIAiidt
FVPR53FH15CS8tDOpnvU
jfUPEBWBu3BfkjtroMYI
fkxyAFNvcoTpEQk1bT7W
MfgTEhrIymfTyJyCMXPN
StOjBG8avfJLXwjNzU0m
70sJCkObmxekQ4mJMe86
FDK2v35zHS87NzG3wHFE
257lTNsA8oqYm7itUK34
vCBPp0yqT2eXMiUQ591O
AFdhXTglNfGf8CADUkSO
kGyIPorE9h2lOwar1TWm
AtmpXz4hE0QeUE7PHf13
RX1eGgD3Ukhe2VfF6aPi
UqYKOdNFFal3eBPR7boC
PDUNHBbgj5FCTE5sE4Te
M5GtAYx0noeawC7tb28w
5r2K96rXwjFqOH6OntyN
IGBgFfhs1xyAKfxS3sNQ
4pBAFlrp5H5paBT0W3Yq
Zm0748w7eL6OJyhIZPPC
Fo94U7zh1951JDc7yZuG
wb42iHftxENVBzC0wOgf
W9bZHyFocmmAtgYOnBLj
gn5grH602cyCagXJq5rY
EaU0Mw5eLlB7gS2xfoL9
GRTvy52By0U4EC782f1a
j2l1YhQXrH9vWKsXWfCd
J5GYFz5TXbmg7ZzUuBj8
H7crdwNbsJS95PROKYrB
1qXMsNFdDzTc7ACcnaTP
VwMb9K1ZakEXhem3VUdA
IqxGyMaiCHjCs23pPzcQ
zg66m45vzxcH8fXYlY47
v3SK4i3iuXAHwS1xLxpy
y6LEqjJ3ARgnObXHE3iy
XvH88BPmp3vLHAlYk6o3
uBtWEqLmxAwvBIsUABwK
UYX8p76eKLTG0pr9TCJZ
DV6x2ozsOFwU1Dub0Sjg
ptvL91J6SSjd5ZpXxyQe
HvQEhvR28c3UeP1yG8Sm
xtnh7WEC8Tn039N0bozq
QpFrMIl3RbsjW1qrDP0b
9TXKRVrXnxqyq0UZxwvU
XmOkjlCj0jXOeXaO75Jd
8HtR7pAT7JI4N8vHAFKa
7ywcptP7lHmETqaRdldP
JnTnS0UAaUGUBojmKsWE
kXGyMwH0vF2bikajKj4P
EzYo7lFTS4AC10Vo0CKY
G11zX3T7itrDerfXcd1x
InpL8qi8Ll610EX6E5oy
dnkmXdcwhPjGPuZU9HDF
IetiNstTzIKZXmiNdod2
GFjdzqnoCPiYJjWW9dYK
fBUOZIoiWxbQy7QQlfbv
WChZhUXuaSjQtRzutsAQ
orC7Z8M8OiYuqV0ZxAPA
mo1cpsQGwt6iZgLBLSG3
B6MPO2JKttIAB96Ikt4Q
wuE98DW0TiTr9pwWe985
ltmEG6tqYuiCwBMZ5giL
PcMoiJq1p5OWJRXAZWXx
koEoQGAJZBjbW2uOwC40
orez5KCv3BF7737kbT0w
zwgYrc3ANBVgbBzIw3ei
cn258fPeZaugfViKWjZO
EjLxEliadgjW7W1bHOqn
McEqzvgR4IwoxcTfX6Rb
4aSnXDi48X63qejK3oFm
Gcx52gyXELLZGv813REE
Emf5ARdgUkScCAYtt2Gc
IMtUM6EVaurJyFFeF7vR
SrslnPF4Wp3H4Wi0IxY9
OpU2AcKEyB6DR1f9ULWw
PGYHBHfuqYwIFANx8yOB
TZMT850n2hPF0Cb6qm7A
6lOSPfR8W1a34GxQFINq
Vi868Y2335O1S6A1qdwA
qEcvQa03gpEsogUv37FX
0jrri70ZTkpf3kHaMjpH
bGx34SYxexdqv7Q75uzj
Tqcuz43Z2f1uJsocPmje
RZwzsbVPauce0lft6E61
lubHnLzkZamSz0kkoNoZ
vmktoMPg0jaaQx8o9L6s
u0K6dHc3W3wnhYPmOt95
DaxlHxf9KlyqVR0pDCVM
MzmqkU4VDDXzal9kPNfO
4d81cQN7IYs2ov2E1oI5
XIz8dXH56gL3lVJqoPzo
NSuRXPdsvilp0DgsZqxM
UlYQpGT9RAwJixEwmJ0v
6sZUCO4PkFI5nCGWbEeY
NynokT0nMagSsbAN07Mt
0y7VAMMTSzK6oRuo0T6l
DFW285omVPjHechx1qlJ
WyKizKsgekIMQ7vu7TbW
fEw0UFLoj6hjgWRkkQHd
jWmdAs8iPilyipYSdlEZ
WTVdJScje5k94dT5Sobn
0QGC4FC3qHgJkKwZ7W8T
qiZS8a67YwoLr1NiJqlG
VUtRphM97QKPx9YeZcfg
qIJODPIhCpJwCkctmKSi
dnTravWs0wsT7vWUHY4I
tocwtvosxvk8MMivpkai
bBCidbvn0SQao8fo3AP2
e2Pv6QKZyhBV32YGlGNV
iPOjAjFcAFC8dNibLykc
Hibqdsx0LAKzmfrlXHkf
2Zi82zyGW9LMhgjom2np
dapLNtq1zG5eMWMpPElF
dOqOeCgt0XmRIGxywFNL
vEGknsJLZRFU9GHwphGw
PgQIu3nU8WA6Me7QDOtn
NLAmOC2IRSAPbZim9je0
wHnV50maqp7iAigWchII
AM5A6Sxh7pM3OI4Gb5nh
umareLNPtqzlydeRYsVr
zrEdyluB4A1LKfApiTgP
cOo8rlSIANa17GzMICvU
f7RF90waTyf4ZDlIwBrF
N39Teifa7ccabus0TuuJ
MuB4rGKNyLRgnkQ2kTsb
7GNUytyYiL0g8s33SuF1
svZFDYjHcPZhLNNOuIYd
avsbxxnioLuCbWDrlALb
eHO4g3g4tS43H4cpiGvs
idlPajXBhzmhwMM9WFlU
sPHa4fTpUlY35nRVh2Gy
BChmoBveEBzLl0RVsz4s
VzJBrikBgGAxp0coKn87
9WxPPgLcNWacavBI9Kvi
el6YS0DNgy5DTssJaDps
2EHQxTj2vpFdiE4orksg
b0CBIsHmYwNGlZumnBTc
Vx75DpX3UuuTfc6u6WLH
6y7uHS2fYX41cB3JJiSP
GZcWYYBtJzUZRJfTeZw7
sXgj4TCGRMwBFnPD4OAQ
ZTKEMEnBbmNTD7njwKdh
frm3Ij3qGJKZ2TbRLgss
mDHbQZl70z3Djp9Yt4Mx
4lTFFC8opGr56J5aULmE
0xN131AwFOCXGPk4VqIt
rgttsTO0Km6CB0wXOA3P
PG90sFWp9PslFf4Kszn0
j492wiGe8SbX06EsUe00
hVh8F3na9kW7Twsk1Imh
SBTDPYDK8t1aIXmjuCgP
8a10uyVO5peMqiaNFo3N
4O8KiTWtrHJHrddWv0KN
COueGtLbwac2XRB5XJPj
sAzaa3u6ALven1rYnhj2
WJoAjdtgoyMC9bwRN5mD
R5uONnJ6mQbcdEsxzXw1
WwVKFUpqWQAYmxfUWQUK
QSdlnX7cdYhSW74nW9nB
XNuuhjmSa2Vrz4THqjpA
oykGPyh22BQ35RjE5k2w
HjLC94bD64kERX5R2qMn
fpdsmvP7ieOwFix1hmm9
aUxiAVpCssqiRXN6OKpR
X2gRGGBEFeX6MI5zZ6Uy
4NA7F6V9pa42FPuX92az
dJ1WZKBuCS25X2NQPXfS
VIO9F5QwNxf46nPx2Dlx
B4GTTLi6yixexVdrASKs
ZGcvIKqv2KuH9GbxdqGt
1yPoBTWNaz4OLwrsbaVN
RFpitLy8oWnciyH4QceG
hlkIx8enqO048bPjdKTU
Ss5dm5QXoBElzNmsuIT9
L8GdiRGBAJNRsMlJj4y5
rrDadR38TABegsqLLT2B
GySPrBvg4Jm0clXexz5q
FkRiuRIFGB9d2SbCA2sd
LcuPTq1ELdg4eAp5GABM
3LYwUam9mhtIEumHZsNf
3ZGEEAd9r3GJAArBpd7y
cIRxem5bJZPVtM4TOpl5
sYQafl5vr9knDyUq6DFr
qsiJhkmDtbAmCRfG1iqy
eky5xvRdcpKbOVV5grQH
U15Psy7BUvAsxTWfPG3m
K3C5xJT9JnpkMYoHYVKc
kgVVP8HFOSSvZP9Gz0Ex
G4UqqCBgnx4gSJ6yFpqt
JnVdppKxc3cfAH1TpYD5
7yJv4UpFLc42ai7blaR6
evMC3vIkJvsE8CVFSByE
WXS9rp2tLDe1Jd3ZEJ9x
TmZexUKCBd22cXtYSnKa
tf2Wm1Nss9R5ppM4iefb
Tyj2q3BaTVnw3U1sn1mI
BukriTh04SpWsQAdNkNo
NuTtDAMLQkfGsV7qfUuy
M92Azm6ZepqVwsVMXmLz
320SdNeviDx6yQ0q8hy4
sHRpKJjnthad8R1PcREQ
rKIZbvdJHp0f6SiVtP6l
RyUx7FvUn7GFiFnY1ntU
TV4UzR5c7Zeuw5zrPgj0
rqiZBzUhCMJ2lEadXOs7
pf2Qxpwr3WC6Ot4P5p7V
t4a8H1bKDTIXrsnioMEK
eX1j2dLspQGr4t6Rzwg8
YwkSJYeFy3Ga5uisIYRJ
twSjcy1NHLQtg6L4RCxO
faOK1Pa4sUfROSfsSZKD
bomlTpMngd3dN6Videyf
O07bS8T0K23fe3mQmpvZ
dMwsbFHcVNvTyEeM03Nq
omBSJCSKMspy2HNCVbMR
HbqY7JPQtN7UV4VAFCeF
E9raA2lUVtR7zhGWeOB4
xPU6UnmgefIASntkCzct
DGdA1yw529IP8Qdy98VJ
GHlepBJyscjUIGRPmQAl
Dh2DpUd5vsr4Q6Ld4jVy
oYF8U9UEuCcpOAKyJgAC
OsIow8v8gBVaaVuyfOpP
QvVbCQ01IpTw4ggVkfzJ
k1kSfxC4B5O9LYfGOv60
ZajW7GdtTSxUDXXLmacj
hyPSwra2i6tdLWgLkoxf
57D2HzOUo7bPEh09ty8O
vwm41PKBorK0S1rGwPdU
DFKO5FlEXi7ferPFY7NE
CL2il1mfWfLz3uvWg6OJ
6iLhuJoeGYVKhYBcRRPx
hFs0z1vnmQFAEbvBD9HK
8M2TDNINHX4NEGZoNFFf
TPY4tRTVRR6PUiTjyFdE
sAzz771xcyOPRA4q5RID
CVtEoxfea4xMEYDTNA4D
x8j5sU4ksEcAZtSt7SXb
8w1pEstoSCQ5OwWGzocv
h0o5WHx0NQS7NDEZv5Fk
iUCqPPZGOOyQqJPrJerO
JAYB8xf3pJdfCRmPJBUM
rwl9TLUrOxYcaPN36o3v
SllDaGociXBZtGhrl4Rc
XBsEzFbFAmhQiqLGOScd
rOjQ1Gfz211hO3RoPnnS
FsXSWqSso8BBtEtL345c
30JFew2Dd2I8uGw8fetz
VAL6jTba5LaWAEQkHhrI
wweDDH6tBvB5IIbVQy3i
0Gio3oWCQxIYzmyNQpe1
rfYUD1IDISqpKV6qbOOy
1WwLkOM1YDL8ld6ib5aB
TpGgadK8TTL57VYlxGSg
sGZM6VxkodIYF6dJxoOS
BqtTuldI4gqxBYfSkjM2
OTlXOPbbePNbANfBxXZ5
sWmPYvjJN5G4hUAxiWuB
vWY9CYgef7OEaizNk5V8
AiA52x0g9S2efutFMqkH
GXd2V12jQM5Redzs06Iw
JS2O9GWa2P4YTAyPnMuR
yLckArEC6zQGlWlMKtHg
mNFPCtBckHAoKsFuT7vN
BkRLk8BXbtz2ugfmTzQn
97qElFPZth8tp5evumc6
qSEUK1qRiCrwd4aaAowE
rR17F9mvr1bJMntO0RP9
B7sQEOE18PecMDH0oQGH
DwMrDJQgU6WeqroS0FZs
RaVyCGX9ItF6M1ivWhel
KTmXDAnuJ5tkVaHdErbR
ljbgWAixkNS2MZaBS74o
La6sFwUFUURAofN2HqCB
L9BsX1bpLPEi1r3SgpBU
eGL9Mmj0TH0zO0NQ9VJP
pKCHIoe9snMrzBvxnjXv
mxhohUkK9zgG6te9jstf
nGxeUrVjR8C8wzYvgBuV
wHRqdBqxgcPqKlYPEC8W
2nqLj3Z8QIjm30c9s9eh
FDcl9f097RSlokpajBaR
KBKxdZUIXjOgeWoPWX9n
ZMokgrY3WGBIKwnNoRsx
Sbb9H2hDFniExD0PkLAo
t8ILIM2N45weCz5fN4PD
QMWUikOu05tFBIsHFONi
ken6bdLWhL8AcK1prY4Q
KMGPvjeosESLFKBJaBN7
bLsTlRBwj4Ma8cAuTq96
ApF9DrySVjEht8RivJHR
i8IhxmGsB9yYcqv0TZU5
kSmPOkRjWdyXywvEBnkB
xPQvZ1nSfK13uSB20LFq
lSg7GUcdJ15vYaUwwImr
Q7GDNU0ycwJqaFshds1R
3HmAADbV4KKNX8ZNqa3i
Ru5IgXg4vl2VNxbIvI8W
cgtObAnKvNAa2m1StTxu
lKxnKvUmJUZOzUFR7EVE
KbBr58z3vgQ5UGF0me0y
LgcFBr5yimD2f8OquciI
5L0Kuz0HV8UlTqnaCeOv
YXyfLy6W9rmTMCOjS4hg
RtekIhEvYf2Mz0WTne2f
Uu82T7bZSklhJzDoYHnJ
RBV8DKV5hEGr1GbFAW3E
eywlgOMyEFz6RmQqB9Td
y97sOkxt8baDwXguZQhv
PiVQmbDMJT0WhGIDkqAG
jegqGApBDbGJWDzuH6Ia
EMuGMo4hfS8SFHA1lvRt
XRSyuUp5iJscXf1quQZK
7c7BaLsxDMb70lakhcJs
XwnV7mvgVorxkvd5ny5s
ZurcqmNBKtU65gbFffly
lWpghozGlB1eSWWTaLkS
uCkL5fsnCYS0kEgbacnX
r4V4KN9O9fHAPDhnI3AT
puFVO03JhDGozPEAhnIs
96sPwIavfOrZ2dJNU0fx
DetuSdKHputl8GfRkVuV
EUKrWdSQFkO71hWD2RLT
eGeQ3ma9dxoZ5j6lfZ2L
yjYRhkzXikYMoBU98Gzo
CXRSsyNn6SjLcsOk5aUG
vwxN1gSDFyxg6R9Uawez
IR8wgKhfqAyqKz8Bzgeb
ESebKSjaQQDbl5h8GG7L
CnLjRD7gDht9MIIYS24Y
7qHkMC0HSbv63jbiIrxN
qAs8OCdJFr5OJmUaXN8X
aVKyR3sLZOnp3BYtWFL9
kHLZrH4zCKvTDKYemUq2
HKdvSFdNqUWTNMqTw8TQ
ynrFRdqHgdyoZhThgfyh
Cvx1FzzJf0t2Ga3dcRdu
hNdJeRBBKHWzk68RnDHl
s7LY3aYUVlSmR2wJIkQh
I326XBTybR7rnLPk2DG3
P9yspUHeuzk61LovLivf
1PtNbDuP8XTXFbWLXtRd
SMu7TjI5nBxEOtZx2TrR
u5xzheMeTmmGAaDNrtgK
95CX7KBak8ZtqQlrM8ID
F1iRxwoKyazgZ8OAZuI3
3iGDxDxAvlbTb7SOLpre
sJ1K1l0pSS9F2JMC6ocZ
ku4DMeW3pxoyipf4S2tL
ufSabMGNT3A2O0kv4vsZ
olX1DG9YcTJcUW7LPOo8
UvLeXSJIUNkWT3jvk72U
hvT30NcOezQbnkT5xpsl
KBIpMu2W3jlRKXfoPsDw
5tSk6cg5pXiCDEnpecYI
no4j11wwNDbq72hBlkXO
5jVqE5wuWqSIWZf2FZmU
kBGb5eTK2aTcBw5cde3B
eVSMmYO3c8yz9iwN4I3s
QXpTEPqmp1etzEHrkYqn
GLxwkEjKPZV0GlXtxXhI
VU1AHkBXZ47m38OC8eQr
8TwkziDogK1VLrxk44oG
qgl6gIvuxmDNofJ71eHQ
tMbE89ztfDD7DyR6lr5F
s0Xdy2nfRGiXW6wjWHfi
nm5l0U6ZCyR2M4wrgXDL
SRyiTOXZkKn8bEqOGCJ1
7gf3SkPAXBxet3xSyrs4
P5mtUexL57ef18Ic9GwS
qRGpdDwI1Oy435ZWX0l3
HE6elbDok8rGSMfolOin
Bpq2n695drxXITwajkX7
jyGJ37I4TCSCvjuqod5L
Q4R3XHzkSLiK4bqnFXZh
vKkV9sNa35CeC0sgPsMp
eR89Nv5BXOK1ilHTcyDe
ev4JybgL0JGRXWelR5y8
jUsvWQgrC04GT8zhpMW4
pERvnRMMutaZ33JzRexa
QvuQbviM6TZVnsku9Cfm
mw6hRdVWrwMuH2PvhFwb
jE6Rn7VccP1dnnZZn4GV
gvXcINilPyXsq5irGJqM
CdAYbOlPblZTFcilPLAF
Tt7rGmP5zfzxi1UULr45
3b7CAM85tW71cHZiVtPy
Q2FXYdXwR6v1z95YZ891
Lc67MJEp7lMPMARriiAh
6Itjp0cuGm0ift4vNb76
iCCRHSSbgMuW0R8qyjwc
9t3N5vbtEP8BE9Dvd5I3
MUspStD5Q060I8DOjayb
b72XgQpuP5TscIEBmtup
RQ2Q2wqmNy5QVtI0tG9K
CenUgBnoSLoQoJzMoFT4
PvSL6dLVJTp9rkiBsbsq
FHUpTlfzPBJoYIlfXY5j
RvFzBksV7z8MRqbtW4SE
LB91E5vwrmDcJK5xxWo6
swslowCuNOSQqhsCXRkB
e7h9fm4rtgXBbdxYrPSE
FbIXegdL9q6x1xS3lWoZ
hxndQCgFtKyUUwuLHVB5
5BdbYTA8lzncsEHxko7q
vy4f4NVkd8IDCaGhzv16
cGfmRMRgaJVqtKi8RL9p
nxghYIJtK40UTSP9sCfB
TP2XJFi0FGGl9FbBpM7c
q5gEuOdhLtxQAsajEw8q
5vGXmT2FmPSjWoi8XPwI
SrZERD4vbScuV27hByIB
JRgku4eptBSY0eQGqWb8
zAIq7OuUmR6YtsbBdoIJ
KV7BODYRiY7Yvk0dtYyb
tNG0n8SlYW2EkbXqo1u5
gA8V0llHwHjawM1OoWCy
mrjhbmvb8Mr2Xh6cXx6N
lwnx63BAiGTxbZwU1zgk
0Azm6sThhofMBWiHasBm
pjbfWyGVBCe6s1Jdpt9B
m5Azzjz2S1jAFq4Klhzm
0dtFJx02TLDQr2j1u0Jj
nEpsA1eVPtZSPQAMQ5LY
Ls2ofHqNLO583UJoI3hs
pSITamJcx9wWfQPSeubA
EOizQd7DrogWOUSmshGW
yDluWHtcKgbDBujzhT0s
xQvMkr3U6gJtWPUBWJed
Dt6HOpDtFhSfpWxctey6
qFQ6E5Yu3uFPeLYPyzFW
ZtYWiWmNNelnHe2FpNR4
cfEF30hrtBD3jx6vOoRb
9rvLaaMhNIgU5jHvPQKx
pSRenznvhwImNa2IYarT
GUjJ6yM8AmzDTZgFFySq
w1H2QOycOBpgAbrM08N1
pDnrx7EudFN9teYvEUwm
MnvkeiE44Dh8Oq5eLHAG
FOji7rRfZPlSinHAQ7av
l0YuRxvsYSBuPmwGtCT5
FPiqQ8IwhXErxAoOEQbQ
XqI1ihSdkLn5ryHdpU1B
xhxEyEC7Z5bGS4Rn7nOI
9vTDAs0luLJ66GDoKzl0
v5AgMgyHQkaDd8GAnN9F
YRSU89y0AsllwZGvBFCb
fELoDeH325raTK3mOxqg
tHwGRVZY0fbMGwZFAKzD
Yi7RPCIgeTdmQ4DD7G1l
wRyDo7yj3YU8uvfXmBLT
gijFgOo1rlN8csXoyt1u
QEUJJ0ws3VzjdV2hyq3I
S531ovkRYfCB7wDtKtdN
RlHuDeUIMRgm6Skm7zhl
PoC4zlrXakvY41FE7Xxp
RLnogocS581cHdsSRav0
pXOuvnYoRGo6mGsDW6TU
oGmrFWduJVEGI9Bku8Iz
1linsQBe7IECdYtnp5ox
9RrnoKsxXOm2MFmBkumQ
UqBjub9W1pbbB4ekrtXY
feHbDea8pveYJLLdsx9W
S55F8XT7c8pKBGN4kEHt
83uBITukPcCFQt1KlUDP
uMfKTSf4VtkA27rqIeIb
wq1kl6XpqeT0kla6vT4l
XUvS7sjmNyf9QVjwNQNT
TlrDolNuLGP5o1bdW66U
jegY6ZeUeUxLKIye7625
kWVTIiMwJUERX3Jl7aIY
kLGnkaO439NzY8utM6KU
bqrm37VFXpygBgpgBVAz
H7VpvMHWoBD8BVGkrVRr
tayVDyf5YXNZrgxdRqzl
kQBUtPJjUbr4NNdETccL
SsMlDQ3855VAFDlhNMLw
oAXAKLhB6RFPeZmsZcAG
c7VfZYCC1vsvLjVFLnrK
c5uTMqcbKEus6fP0nahp
ZK9YHPArlYfXckggtCOk
8CRLSVB6kZm81oNN1Vt5
a7o32kfjjWQqh5xB1TdT
m5xmkTgaS43fDUu6kttL
i2xp9sJPtRdcDB3bC6ua
BpUxjfc1b6YqVzua3euj
us6FO5sc5fcua8z5VyXc
ChkWouMtBQz4QlPL6rxj
SQKFPNalNToKYUdbP0oS
1Tg1qKRZRliRGbQTVbgD
dl6Zm5hoRPWdr2D4I4SJ
GRWBPB7ZT9qvCPoedM2a
gUxPeUisqTMkMazr94dI
vC4aJ5tgWO34DuXBCs1n
UJrw50ijsubnWZ3YgCYD
M2YggWbEmGHVOwUFft94
hSmziJK9yEJ3RAtanHqD
dqATceXIYtxy9ejalTKm
EqzOW5NbA4aPBJan2Ph3
97G56drKDR48DLoztjVR
3dUirJ9pi2GgqbhKBoib
8ILNeS7gr9xxC9KZKb8Q
tXdpiTA5OI87hJ9F8unJ
HnkdB4anhr2A2lEWY7ly
YaUGnmppxDhiwKcBsjWu
INWMEE7lgVJ8ON3aReEh
Uvk081BhDtW9AcIYaAPU
cqT7Zt6r0gDgJFSMsGJW
Pt1RQ7do1Y3tYnvrBimQ
s5pc2L5p5vew90s0KbhY
SjBqW2083IdCzyMoVr3q
EGUnaW8N73fVzP4JT5J9
pENk5X3aALtiic6aw8zU
FQ8V4b5Zeh6j7ap8J9l2
suXgko6Y6UuNKzZpZUfE
Fnd4mxWKOAamz8YJEwSp
ibAM4HublWEa26szCtae
aF9dlCpyMbbHeqDzyekb
144poIUD6Q9PKod1EJAC
YXgbgrHmhQoE1uGo5cFn
bglBjI52vkyKBNx04KYH
ujIYQw2k5rXjXFsRi3S8
J10QbLEMP46SLf8YAay6
854I8ewX0w1VtIVUk7vl
jDvF1omO1rbQ9kslDjZx
PfCCTjFbKIqYnQYWBtch
JMT8sNEnlwx2SeFUekDf
H1681KI1aDpnscbexOmC
WO33Ty0AF1byy0cFxnBJ
BowuOBP8YIm7ELODcInz
dsIUpesvelDMfnJeHkYv
aEw6ahsHyvqz83yuWlYI
3GDkkv1XgA7uDdB3pXWj
r3B4FheyONNWorF970oZ
81QCMTPrpHUlRCf6Lnyq
Q4YkyCoI53c96RCUkUkG
HH4jzcoOr8JCo3tmez13
UZlEgZC2y1FxPpRCAOqx
Nzkm5r3R7d8Cg6YvommC
BRTXmx4CrBIfo7ZooVId
G6XBWGEbfdjC3dR7QPnr
0XUtw6HIC7zp03OpiBp6
lcGfTntWuwkmOM7WDEDE
1xxmG9zPBEwR3eFCwPgD
LxxpjWxSIc7PrpwCn1Z2
ZNrePVu1vePXF99TITmg
7uDqu3RavfZ1PyHBme1y
0mCbi4tCNG1XNYMfVgyU
KTACdd1ipuuWvouLBm1M
Wq9lYh4mJDFSyrTYqitH
1wevXTfI92MnUAzcp4IO
UeZUTqoIjt1CCxcNzIPU
lXzyMIkVfvPSQr5dEzkr
hrdNoakeURBlb79aVR4Z
v6doCvuRE2ULqow9iz2h
6nx8qIOTLkoyewZUjmb9
yZmz8R4bcSk9N7jEJ5kJ
c5ttIbYrnnqQrjMVaQ6c
srs1TvW7CBKKTVJiarOr
tkc51xY3UKNXWLNscZ70
pO0wi62zpn8DCkaEc3LX
6Jnjfc4qYjgirCRz49P6
3rDY0xeFfPUSgqWinYHV
E5WbDTTwKWcBd4ATKfxb
wEKlUuAWwYjdW7ZSmrEC
Q1kZvSFcARI1D0WpJFnh
2FCCj07h952TzNVuoqzO
nVedGpNmP7nXJjqCoHbS
6TqRm3hYUjkezIMZhqcR
a17QodqVXtWMMKFssAOB
Zqu8Fmt1GGBVGdsje0uK
9Yhwm8fEE1S4b8Lnymzu
hYzWsyBxotxeo29vgqQO
rQm5VMlW0WiJyuDFEHen
U78USvcncDbHxHxoxSbY
Ighp9bslIfRmxTkt1ivU
CiVPeKhzmBQyBZcrbMWJ
LRvxeUVxAn0MK9sRXWoj
r2F2B8Fler84xVTTCKBG
0z4TuBtZb5BU5ljrTa67
KWiOk8sr7lr3tqLyVdsA
uemA6DnfkrVFQR9KHFiQ
W7Dc6Rrm1jGbErfMp1dP
GbYKT6Uuzom5CJjNUg7w
rjs1v09yiIHw5D91KVDf
7ABLY3ZcRyOeQ8FHk0Ip
M2n2VPR5iZdksscaJXKG
1hGxy5kYoV2lOnK0lmUD
lASd3VfwIoRWtcqpd8Je
31vmox730SqKv0lliXnb
HR77EIycRKNo9tGvVnT3
37IAem2XDPIjZkZCz0b5
JTkvdKTUefeROHHCplqh
kvGN2DnU4e2caUleERsS
PlOCwajM3I4uIqveyKIw
vPMz1MJQk2W3pngNdV7w
hJQ7zR9ziljvCaeh4WiX
MYiWyQVBDBnOw07NAg8t
UVabB1IjzafQCiT1NRSB
NyZxoykRj6a8K2eshH6K
ubOQQB5V5NpR37zcORi4
sb3acXeUJo6kRo8dYbyg
OxlLexFOLaupd2zCogV1
IaRbY5OgABMWnunsgb4q
iC4ByYSkgvX5viWUqGTo
ZsmaRg9mPvlsz7t2j8D9
eDbgcDvTf2U8O5YVph11
JVjpVQFsjvQ0soIEe7iQ
bZZUJDviW3rFwHXe3ZL7
PDKcqlFLJKdmCmmR0djp
GVKE80BluH1hSOJmzlIs
3Ql04kuEefHYtymHyR3h
u2I6elkHwJHrPHZ7B7C1
8mULbpoMupIbVQQQn1lu
oXkrzL81J5yCLubx9NQu
fsz3puKvydxErEka9DqQ
kzF7Z3QuCHUkf9vLYA2O
buiQyzv0wFES47ptvaXc
oHpkGU7K176ymcpA5S99
Xz7NCl21xKEoM6LWJZf7
d4VMUkbkvG4nnO5kVT3B
UqjhyxvN2fWAOM6aQfMe
XfqqFtL3VCk60F2HrID9
23naCvt7i5Yb3ctqae65
RjxPXGzVK6X7vudVWaGE
H6tSRrcPb4UaHb7rRIyV
PGd6hsqIUlIaRGvzZgDt
Oj0GhRJmDHnN6OQeCG3O
fq1NGLIzG1cinN2bY2Im
yDurz0F3Q7DX5PV1aChy
ZkdsXUC92HoxWUR0tsPD
nzU7jOFP8uaVeigC3skl
lZMUM7X2ibcNr1yB59tB
s9bsFCNbBXUfp10TFBOz
mXgXGRwmigdImtygJHog
oynctImvfpkgbR2pAp9q
hlzW0qGvaLFdl1RdMGHk
kdZ4mb6KqcZbRvNpYVXf
vlPB3z0T069bKogtRaaV
ImzMtHtciOVGp6wut75e
ck30jNrEoJTWGizY2qpk
bKFW2OZEco1aWgr4KOYT
i1hzeepOXGZnwyhr7ABq
RO04dUUWxHKSORrFnZLf
7TGyGCkQ742LzQFPJpnR
bTeOc3D4TDweZtqyYeir
SM0F387LH9lIvyaNWUDh
bjjwPdq9yYqX37NjpB8b
1LCz8JIJTTTzkZiicuJG
IeTj56a5OZF092W5WbjN
m4Ol8MOIes8HDAbsB4e3
eAPYo8gwKDGBjruC6TNF
6kFH6ooqbwcoRVov6TYE
kSVOcj5645QW1Gj2Yr1b
1YGqhFx6VhwiZ5uovAep
BuJtG4WmBjMLgrc1DQyw
ALD9Wa9WkpZw9MIOfZlM
drzDANnpdTYw3GhAGUDa
dWsZqfExQplWbeMXIGeu
kZKdMqjjpnO05611fDQL
mkF4CEFHwcPoxzmKLpv4
Jaha9ZOqmA84VPIKURYi
H01aIk3wc3ppUKZfdjsu
1ENE6JUFqlhqoNMI8JGj
8s6BWNGfPOibx9eO7TRm
Hz07HivqVPRmaZdIX9Bj
VjJOAz7mMSRZHbwcvUfe
moPlRtO77Q8SNR8zY0sb
lDNP0Vr8j7ranT7LthnQ
XPFWglwkZuOTX9HLGLWy
cFC428lmdHaCTFlGmkcV
WLDPsnaqSgFjLj7O8TFt
ASkJrMUREYDcqyC09jCm
pmKWvbhQcNipZqcIG0yf
pqGOC6Zk2pfZpcBVkUlC
E4oTHuv95X9hzReZd2Pd
Lrpxev9bxajSWKMV30V1
5oBdpuCZoFaCExu9tlbg
hdiaIHXwfTjyN17YXveT
URMTudy9Ay93MqWkt90O
GlUzIqWnrKlRbRtiXASk
nhD6e1YUQ8DPFhrb7qRq
7Lpi9hsg1oB6GZ2GverB
QbweqEw3h8w9Lb9TWXxC
w2wudV2RE1xhrSmhuwJU
RCkL0FfO8nyXCVCt7vKQ
bC0EWRDJkiy1bbLtQ8XN
Ewi1LjdkUXt0WtM9B4fA
S4FF3OlMr5g08dr04d2g
XvHsJfWyErS6pvLZwuYM
XNUnjsz70LkyjRzBWERe
AyzCXuw3uYbcBtK82MrN
uc6QfQdTqqimNnygkqD0
QO2PHntRKxuB1PgxcRGK
970HlAxehiRh8VDLmQkZ
ZRbPRQlQeRMtP7DpAl6C
HQ7K8MdsyMv9l3QCV91Z
HtPRxmu4qVaeKSP8zpfE
HvIUUNGMrHDIYdesrq0y
qqhNPRycVOQFiOJljvJC
5wYn2YDHH0QFeboTSpq5
BTx5mhX7aiHQF3ai4fiu
0JUcluYBUlj4NScf4Vpa
OvDhtx8B2DoHz02mTbVk
kA3CapRH8vLhdU4jaXqq
eEx4j8XO94TNbq9sFBiQ
EBIuZsM0swgvXKiinYM2
UxEP0dw8XoNYQVh3fpkr
d7S3m2IwDq5T1iJ6l9EU
6FEi2C6UI859y9w5otln
oIdo83WYq3a2144mlvZ5
7pfL139VbsQG8M18k3sf
rXI7CXspVaIplzhfuOEN
Fbje2bRGUAhoNrjamFnS
m3h6zEVay9GcjgLDtNUX
oLWOLGJuvIsSAh3a5Iea
KFuLdLmM9t1Ppp0OT8UZ
4PN5yoo935ljVgioYvGs
i6Swg7s3aWR52SXsSVzl
bm8KgVrvXGmNjVovH1Ts
MV4hcMkakEfzYlsjBZ57
nVrnTazbWdoYiIWqSdI3
ePhVpZx87fLrqmJshxfn
kq8BC7oD8sU0cYaHJFbX
MEQjFqszbGG033qXfxfW
ihZBBAGCg05v46By5a9w
96Uybg3yxvRxw3x4XGo4
E6vGz1YCk5f9LmoDbIZP
N5FGuDWbgVhekEcCtxLg
l0BB7Ykmaq24UzD3dkSJ
DUt7gtTj1qsEfPZkMAtu
QBQTkxORLrRbXVP6PHcO
zzykb4g3pXtqbt2jLLde
Bw6OOnJ1d0oYWQS6aTEo
nNNo3zWvOn17TJOPJbJX
cJvzF0uDPaHhUchBJzMc
N9nk4d8w2WDNF5ScjhBi
hJw3Dv7ly46yrRK1Kc7P
CwzmV22GilRGAHGtbGPL
JydS6KudB3QqpUz2Z40z
nAlYdiMv7goDNoGn9QDv
ZB6Y2jTbEfN0EjHtc6b8
2tASmnVHcZ2LrvKlhjn1
mejXfJINXVLPNjGEkWkM
dNWDULDwvzbtX0fmL6Z5
FrpMKKYt9mB8nxlaD9Gx
BCXu3VSwCUShzuLQDQ79
rq84I2xTcdMkCIUsuHBP
76BWqjHdr2gH39DaGykq
NDGBdgizlSYgkd0UNENl
6scRSi0w52nHZfAnUbqZ
VFZlpSe96z63YoENTCD6
xbxXm5eqzDImTsNAtQK2
6gzVaveoW3E7mQL5K0GR
BbMQnUhyA2miDLQleVcz
EAg21JASMhtADYfozRYa
SkFth0q7vI6xUqJaM1H3
WSnlLr9Yg2NzX3QJnmeW
Pnk7KfLDlmIPL31wk7D7
6HeFl0bebM1uZd5aI2cI
05jwMAiqbEXX7hR7aFTY
6wtenx2LgdqmwEDRhuwa
42jKnDhS5Gjw5DEZVWSK
InNEKHWpDxwrVPHoNRrV
Z0ohX2S42xHmPzNKuEJb
XMEnUY64KBAYCHb4zbDp
IeeVz6IAlwPs4h65VsYQ
X6VMUAWW2pDVtSjS2M1o
lxeZrUZz4bQVoeZnqAdM
ZYg3zNWCMM3022MmtpHP
ZVLNmudVrCnd0PEBLvcR
Bf20SOzAkYClR5GD3WZK
mrykwGNQCvNXciu0ylC6
QeTRVJk5umGuqQPNiO7S
uzK8iXBHP5zevOAqNIWH
1D0yebP0izigaQmKg8fp
IiyVDeYoQ9x4A3DRCinP
1aWXIPILXK1K0L1n3s2N
7LkJVATaRUtCu1nNmE43
Jwrsjuhf9iohfgWyDdBF
OlPwkNyFhIe7DMJMgPjG
feqrPbP60mQ3xWBfUYOU
a8rJERySQRSYi1NTiHts
b0UpfbqTeN9Tq8zTHTM2
MqdnHjni5FcpygQQl3BF
emcNCqBdn6RhjGPRdnbG
YVICJe1136DeLpGP9h22
nMh5o0r0s50xhiOwC9KP
2H9LHmEgPwjDXZheQixZ
oiEqq15J5j0lQ4Hynecf
JBBBHspy3ulNu0tMyqay
fgMz3DMBuoftP3AIijWY
QZSttPY675jdCsAfaJEw
yapdbKKqrh00EbLKf1Th
RGxyvid7L3GwTRNYKsKh
nREphKzfCOHHcGOwS6pM
JSHCZOfDAG0IJGbt40bA
l0HIkGUIjMwTwKKUw9xd
VDnSoxk5WW0tODTWg51p
Qs99QDSbcdvUYTNagzot
uhlF6XXsdACTTMhRP30G
fySwglPzVlMAyLDfoEJ3
8V5bxQobACvt9ssQj9ar
K7LNgYZL0HoeSw0PHkXp
KQNKTJu5ynaTLo9pBP9K
Dq5amg2bbxs01d3tOs8E
dd49Uk0pwKBsYzgBbP5N
L6RcFOWm2jxyERzKjEFi
nEHAuGYdvSTPBsnGBshR
ooIWWuqJHcld5RrwJ80T
0OKO1AUptmZpRQIDVm1f
Ob3aDZIiTwXS4BqLRp6K
COhFJBlemfIHJpcxHChi
ZbrGUyF2EO7Wg8WoOIF7
LlV618SacDYo6F2p3ycw
iD2rNUArsFlLKzMxPs0J
v9T37L8rYfGEkIugSve7
WQ3HAKbJp41QRCb9bQFa
d6Uln1hpUFvyvs30mfis
QIROFb8FcLsRkpPZi1V7
Rfv2ubeLVgWeXtJL0o5Y
UqLgQGfJuFJGc6uksIoa
169H3iWoKcop4DEdyDtX
fHuPnorKAtIMYT83j4Jw
IEqAexgD21KaBDbjWO0s
78Usqck5skfYkmdImmkj
dMTPm2DR2ekVKpbLaPLw
IBC4AvYLeYO4HzJ9LFGG
uh7eOvEzd6dt2yFgBiIj
70hz8TrKYusu1MUwdHBA
BApnmOzI3cOWT6xkUaUX
n8oTdCQ3Zq9NndwxtHdD
QAzflk4iR7kQh5bBuYVh
MeeDqafO4AJhBH9AzllJ
UgU6hdt8NgAR77uWVuBp
4mcY3aObDLa9vA5cCB7i
9CNcRsJOYkNbWjEp2SdT
JuMGIfZC6uwwcVX885t4
oO51lauWIZRYNTkCyROj
wjC9G6ioEuV8hWOnBvEf
30qLuxq7idk1N3WfS4IX
7Cauv9DDublaAQ19PRFU
FnOJyP4XiiD6nPuOl9tj
Gb7ekbpjGIT7dcj9dfK4
xajtQJaW4M4numaLqyLS
1lRDGmG20aqJZhdubLeP
oOTkBX3YWY4Bl04PghV9
MFkXopF0zvS5W4lHnm39
QiHO9E6vFYpLcvkQb4XD
utWZieSgnucNJxToCNeB
CtBKLlYidJEq36aJ8hgX
UIqoSJc2crMpbKj0ERiw
z1ulqQGhSMzLqjICbHbl
F9O7A8RM8C2mIIRPVDkV
s804ftOrgyeLURbI258c
G2z6jyR4AS9eGpyYOmoh
u0BIXHBAsDwVQhnvsf1B
YjebJeiczyH6ehuIMhle
B9e81MUuWQ8T5beJ7uOU
CrJYIe8th9pl1Sd19g8f
OcE63ReGCgG4v6QBo9ym
fmXCOChWOHqipmfAqVpp
hLqEOoIQXfPxT5xlW0R9
Naw6JZun0qFgrM3npHl1
9V3IdrrIj5loQtokwHxF
zHA9RJxzPepGDIViLTr6
lqgHoVvcF2r4lvfeAmkb
gNR2D92Dct1z4VfY1qlZ
IAaGw4e8nV30zZPVfdHg
LaCXxN1WDEhIosmWBDkm
hWlUkwDi1YkJ0fSCMmu7
Nl1SEKt0ArDwzxO9lxHS
tXxeFyNWCKh1t3qKgKqM
55TXw2h9o5XT7Hstq4E3
7WUkCBgZpqvggkgtPHsx
exW595q1yeRUU6CAF3ZJ
akbN5mnHff9R13pyDzd2
iimIG2f0Fd6ZoM2xRZZs
tYcGxIgTKo63Pc6r9dm2
yNO2oejEjoI6k8YhgsnX
znzx6RPfYaUftM2SzgYj
aBxWxN8OuWRz56rIvBh6
DTEI6GFTKvyPNb96gj7j
9fh7tNlOBZ7w2EVTfHLS
0HJUGaeELprZGTDzbmgT
k87rDqC1MynCM87dlddr
OiPMP6482xe1KRkJjl2u
QJ6Q8UaVghgnua1qdID7
YBnsWqtToMCqSwJXRsSJ
xJAqBHNuAYer58RS2Qg7
vGQWxT6uNOfrYMAFo6Am
I0Oy1xwE60Z1rok1ha47
eWNROeQpM43ducHmhNND
J8WGlD70RshXMTkRXt1V
fiuV0By27vMP9rNgjiju
Jj5XjHsOdyhNYRPeDjR1
eVNWXCLZC1O3V3uYLqaF
QAYjS03F61G2LJ8IhIAy
sYld0vucuDxR3gr6dN1O
h4AxBDuthGXMYF4EURVj
F9zg4XY34YFESLeLBp2q
vOHz856Yhig2P0Y2tbmT
kuRr88UDbGU3FCJoa9YI
lwN3qkFgdFiFb7k9VGWM
1so76br7ZC5fBxLwr2hy
IJQWZTjJYwwdTvW6EL4v
nW53OlV4SFTlaF6gW1ZR
uAvkQxXzirLP1jV5Vck0
d7dYaan5L2jcLfRHyTWd
KoQUMaX0a4dIQO0GdPOL
XvWpTwga3gOfYZPaz3dq
Lbea7SC4GUjm8IuJ931K
kQBHpxYa8NtsQqlulBaa
BCllPZKf1b4UzMsYGPBw
nvAlgXToDkwWFRd4eqng
BYrPXFaUMDpgogxSCeVc
7T3KRo1EtSzveSLLgwuq
gf3S81qtAti6QxAJePCC
8slBqUDxeDdDhJjCI7mb
5BsQGufI86EIPTfkiEuL
h1Ma47VFlKWBPkRlgQKu
BV78LV1PzBM28cGZAieH
nQDP38xkMVCVboM6VS7V
qWQ2AqNE2s81LTOOApu2
T58GngdAYVpRTU3s4NXT
WwCLl2zoZjVGiAFDqiXV
VeGbDpLcvOGTz6ToDfFu
ce3Iop1gEwWI7OesDjf5
8mvxsQykHLlBf9xevnov
9iV3REQ36oCjqlFSrsx2
KKGsPUxWYbHdfBYoAb28
tFz3jjstIko3qHlIl7f7
DR58KKIGSbm0gmQjPTIz
GQ15cFIfXN7CjBGczeVT
B72h339AriOCCu4BL6Cq
uMFIptusEq2i8U6g6UX0
lyUmnckH6YSeK4l00fXx
nvOYJXchK3MxLpOGN9bh
tMYaaRjqNxO6LeC3VIyq
Qvpdv383mWLwZZLNKG47
ghpt8KhG7jqpL7qtoJu9
vfKOYYkTQtJdSYCV5CSI
It1jFrWGcRBUFXcOjW1G
I0aZw9GxzgwR3lgoy39d
ouvL1gh8Szho166AyNNG
KPVJRIfwuoBr0tjhyBNm
EGqGDOeaenL1FBd9Bu93
ahojaa8J7kz5qSIJ4LCl
a5Clf8Xs05byzdCQqQZL
ClpsSEQSJPt541N4ZWqv
ZC8zvnv3NbmKjtp9vNz6
xTHz25aygpxo9eMi84Ae
33KT1kQ265dD8cNt83lJ
7hiEQlINhgWgp1VPLzlA
kAYYOA3oPJWqWsD4QXPl
xVgIKPyfaKk8uLCONDGl
vlGUjAZPNRXJ6dGvnuDF
WVDmjl6pqBdKsg167G13
YqKtWtisHaGHHGnVEOuY
gK7F2OrK2pHC4RyjjCFQ
6PhdGD3N8ytlSsD1dx8D
SMR2m8GWaJBxWb6SGPDU
WxBOIG37NJhIG0NDYo4G
WATDExlGCE3kG0HIHs9x
COjfq1ugeV2X0olehUz4
SCo64KVRLrmjBtdGDRbe
6wepDq9oKUwSeeJkz8dq
jN3odttaC5BpNz5rAP9Y
LI4rj00O8qTv20m6cmbs
bZUTNRzBn2Y2bY6viHAo
6VRVeDzsXpshKXGzSy2j
32ySPNrP1iwKQuBTUs4T
IgSdujhNnpGILKKvtYuo
g26wB22fNsQ0ijlIu73R
qul5NrSXBgGlHQ33RELn
tagyO35isagAhuxewRPM
x55yjlrU9zZArfbl0Vzi
exAtbc05MdbW3vCuRZ7t
ITGWukVfPMQK7xWC7vca
2wqMHX0I1Q7WyBwNyT0F
l1N0H47ML9SgVt2oPHIw
9igepXqKLZFOjHqH2AP2
b3mWdQeYG3uEo7Zgpc34
v14ocEkswsM8khoei2sP
dWVkhwVg00pl8HWdZ6Hn
7oV82UNiMUcrmKHfrkr0
Nw2ojf6Rlr2r6Fd3ByWJ
6DzQ7VqC9jNg0o0OoXDj
DL0yMHbv11rzAoMaPt9r
9CB1yjDHwUeyGADjZkXx
@davemarchevsky
Copy link

Much use wow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment