diff --git a/css/favicon.svg b/css/favicon.svg new file mode 100644 index 0000000..1cc2b89 --- /dev/null +++ b/css/favicon.svg @@ -0,0 +1 @@ +favicon \ No newline at end of file diff --git a/css/focus.svg b/css/focus.svg new file mode 100644 index 0000000..b2426d0 --- /dev/null +++ b/css/focus.svg @@ -0,0 +1 @@ +focus \ No newline at end of file diff --git a/css/main.css b/css/main.css index 5941ad4..0f86350 100644 --- a/css/main.css +++ b/css/main.css @@ -1,1825 +1,919 @@ * { - box-sizing: border-box; padding: 0; margin: 0; + box-sizing: border-box; font-family: "Roboto", sans-serif; } +:root { + font-size: clamp(1rem, 1.2vmax, 1.2rem); +} + +html, body { - --accent-color: #4527A0; - --text-color: 17, 17, 17; - --text-color-light: 85, 85, 85; - --foreground-color: 255, 255, 255; - --background-color: rgba(var(--foreground-color), 1); - --dark-shade: #f4f4f4; - --hue: 255; - --saturation: 61%; - --lightness: 39%; + height: 100%; +} + +body { + --accent-color: #256eff; + --text-color: 20, 20, 20; + --background-color: 240, 240, 240; + --foreground-color: 250, 250, 250; + --danger-color: rgb(255, 75, 75); + --green: #1cad59; + scrollbar-width: thin; + scrollbar-gutter: stable; color: rgba(var(--text-color), 1); - font-size: 16px; - background-size: cover; -} - -body[data-theme=dark] { - --accent-color: #a293d0; - --text-color: 238, 238, 238; - --text-color-light: 170, 170, 170; - --foreground-color: 26, 26, 26; - --background-color: #111; - --dark-shade: #222; - --hue: 255; - --saturation: 39%; - --lightness: 70%; - background-color: var(--background-color); -} -body[data-theme=dark] .flo-balance-card { - color: rgba(var(--text-color), 1); -} - -a { - font-weight: 600; - text-decoration: none; - color: var(--accent-color); -} - -.dark-text { - color: #111; -} - -h1 { - font-size: 3.5rem; -} - -h2 { - font-size: 2rem; -} - -h3 { - font-size: 1.5rem; -} - -h4 { - font-size: 1rem; -} - -h5 { - font-size: 0.8rem; -} - -h1, -h2, -h3, -h4, -h5 { - font-family: "Poppins", sans-serif; - font-weight: 600; -} - -p { - line-height: 1.5; - max-width: 60ch; - color: rgba(var(--text-color), 0.9); -} - -strong { - font-weight: 500; -} - -button { - position: relative; - display: inline-flex; - align-items: center; - justify-content: center; - text-transform: capitalize; - padding: 0.6rem 1.2rem; - font-weight: 600; - cursor: pointer; - border-radius: 0.3rem; - color: var(--accent-color); - transition: transform 0.3s; - border: none; - background: rgba(var(--text-color), 0.1); - -webkit-tap-highlight-color: transparent; - font-family: "Poppins", sans-serif; -} -button:focus { - outline: thin solid rgba(var(--text-color-light), 0.4); -} -button:disabled { - cursor: default; - background: rgba(var(--text-color), 0.4); -} -button:disabled ~ .loader { - opacity: 0; -} - -::-moz-focus-inner { - border: none; -} - -.bottom-padding { - padding-bottom: 1.5rem; -} - -.top-padding { - padding-top: 1em; -} - -.bottom-margin { - margin-bottom: 1.5rem; -} - -.top-margin { - margin-top: 1.5rem; -} - -.flex { + background-color: rgba(var(--background-color), 1); + transition: background-color 0.3s; display: flex; -} - -.grid { - display: grid; -} - -.grid-2 { - grid-template-columns: auto auto; - gap: 1em; -} - -.align-center { - align-items: center; -} - -.direction-column { flex-direction: column; } -.justify-right { - margin-left: auto; +body[data-theme=dark] { + --accent-color: #86afff; + --text-color: 220, 220, 220; + --background-color: 10, 10, 10; + --foreground-color: 24, 24, 24; + --danger-color: rgb(255, 106, 106); + --green: #00e676; +} +body[data-theme=dark] sm-popup::part(popup) { + background-color: rgba(var(--foreground-color), 1); } -.space-between { +p, +strong { + font-size: 0.9rem; + max-width: 65ch; + line-height: 1.7; + color: rgba(var(--text-color), 0.9); +} +p:not(:last-of-type), +strong:not(:last-of-type) { + margin-bottom: 1.5rem; +} + +a { + text-decoration: none; + color: var(--accent-color); +} +a:focus-visible { + box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 1) inset; +} + +button { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + position: relative; + display: inline-flex; + border: none; + background-color: transparent; + overflow: hidden; + color: inherit; + -webkit-tap-highlight-color: transparent; + align-items: center; + font-size: 0.9rem; + font-weight: 500; + white-space: nowrap; + padding: 0.8rem; + border-radius: 0.3rem; + justify-content: center; +} +button:focus-visible { + outline: var(--accent-color) solid medium; +} +button:not(:disabled) { + cursor: pointer; +} + +.button { + background-color: rgba(var(--text-color), 0.06); +} + +.button--primary, +.button--danger { + color: rgba(var(--background-color), 1); +} +.button--primary .icon, +.button--danger .icon { + fill: rgba(var(--background-color), 1); +} + +.button--primary { + background-color: var(--accent-color); +} + +.button--danger { + background-color: var(--danger-color); +} + +.cta { + text-transform: uppercase; + font-size: 0.8rem; + font-weight: 700; + letter-spacing: 0.05em; + padding: 1rem; +} + +.icon-only { + padding: 0.5rem; + border-radius: 0.3rem; +} + +button:disabled { + opacity: 0.5; +} + +a:-webkit-any-link:focus-visible { + outline: rgba(var(--text-color), 1) 0.1rem solid; +} + +a:-moz-any-link:focus-visible { + outline: rgba(var(--text-color), 1) 0.1rem solid; +} + +a:any-link:focus-visible { + outline: rgba(var(--text-color), 1) 0.1rem solid; +} + +details { + padding: 1rem 0; +} + +details summary { + display: flex; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + align-items: center; justify-content: space-between; + color: var(--accent-color); } -.label { - margin-bottom: 0.4rem; +details[open] summary { + margin-bottom: 1rem; +} +details[open] > summary .down-arrow { + transform: rotate(180deg); } -.light-text { - opacity: 0.7; +sm-input, +sm-textarea { + font-size: 0.9rem; + --border-radius: 0.3rem; + --background-color: rgba(var(--foreground-color), 1); +} +sm-input button .icon, +sm-textarea button .icon { + fill: var(--accent-color); } -.hide { - opacity: 0; - pointer-events: none; +sm-button { + --padding: 0.6rem 0.8rem; +} +sm-button[variant=primary] .icon { + fill: rgba(var(--background-color), 1); +} +sm-button[disabled] .icon { + fill: rgba(var(--text-color), 0.6); +} +sm-button.danger { + --background: var(--danger-color); + color: rgba(var(--background-color), 1); } -.hide-completely { - display: none !important; +sm-spinner { + --size: 1rem; + --stroke-width: 0.1rem; +} + +sm-form { + --gap: 1rem; +} + +strip-select { + --gap: 0; + background-color: rgba(var(--text-color), 0.06); + border-radius: 0.3rem; + padding: 0.3rem; +} + +strip-option { + font-size: 0.8rem; + --border-radius: 0.2rem; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +ul { + list-style: none; +} + +.overflow-ellipsis { + width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } .breakable { - word-break: break-all; + overflow-wrap: break-word; + word-wrap: break-word; + word-break: break-word; + -webkit-hyphens: auto; + -ms-hyphens: auto; + hyphens: auto; } -.separator { - padding: 0.1em; +.full-bleed { + grid-column: 1/-1; } -.no-transformations { - transform: none !important; +.h1 { + font-size: 1.5rem; +} + +.h2 { + font-size: 1.2rem; +} + +h3 { + font-size: 1.2rem; + line-height: 1.3; +} + +.h4 { + font-size: 0.9rem; +} + +.h5 { + font-size: 0.75rem; +} + +.uppercase { + text-transform: uppercase; } .capitalize { text-transform: capitalize; } -sm-button[variant=outlined] { - --accent-color: rgba(var(--text-color), 1); -} - -.loader { - fill: none; - stroke-width: 10; - stroke: var(--accent-color); - height: 2rem; - width: 2rem; - overflow: visible; - stroke-dashoffset: 230; - stroke-dasharray: 230; - padding: 2px; - justify-self: center; -} - -@keyframes rotate { - 100% { - transform: rotate(360deg); - } -} -@keyframes load { - 50% { - stroke-dashoffset: 0; - } - 100% { - stroke-dashoffset: -210; - } -} -@keyframes load-btn-loader { - 50% { - stroke-dashoffset: 0; - } - 100% { - stroke-dashoffset: -220; - } -} -.action { - position: relative; - display: inline-flex; - align-items: center; - justify-content: center; - padding: 0; - background: none; -} -.action:disabled .primary-btn { - background: none; -} -.action:focus { - outline: none; -} -.action h4 { - padding: 0.5rem 1.2rem; - font-size: 0.9rem; - clip-path: circle(100%); - transition: clip-path 0.3s; - border-radius: 0.2rem; -} -.action .btn { - z-index: 2; -} -.action .loader { - position: absolute; - z-index: 1; - padding: 0.4em; - stroke-dashoffset: 220; - stroke-dasharray: 220; -} -.action .loader:not(.animate-loader) { - opacity: 0; -} -.action .animate-loader { - animation: load-btn-loader 2.6s infinite, rotate 1s infinite linear; -} - -.clip { - clip-path: circle(0) !important; -} - -.animate-loader { - animation: load 2.6s infinite, rotate 1s infinite linear; -} - -.expand { - width: 100%; -} - -.fade-left { - animation: fadeleft 0.3s; -} - -.fade-right { - animation: faderight 0.3s; -} - -@keyframes faderight { - from { - opacity: 0; - transform: translateX(-1em); - } - to { - opacity: 1; - transform: none; - } -} -@keyframes fadeleft { - from { - opacity: 0; - transform: translateX(1em); - } - to { - opacity: 1; - transform: none; - } -} -.logo { - display: flex; - align-items: center; -} -.logo h4 { - font-weight: 500; - font-size: clamp(1.1rem, 2vw, 1.2rem); -} -.logo .main-logo { - height: clamp(1.4rem, 2vw, 1.6rem); - width: clamp(1.4rem, 2vw, 1.6rem); - fill: rgba(var(--text-color), 1); - stroke: none; - margin-right: 0.2rem; -} - -textarea { - width: 100%; - max-width: 100%; - background: rgba(var(--text-color), 0.1); - border: none; - border-radius: 0.2rem; - resize: none; - font-size: 1rem; - line-height: 1.6; - padding: 0.8rem; -} - -*:empty + .empty-state { - display: grid; -} - -.empty-state { - display: none; - place-items: center; - width: 100%; -} -.empty-state svg { - stroke: rgba(var(--text-color), 0.8); - height: 12em; - width: 12em; -} - -.container-header { - display: flex; - align-items: center; - flex-direction: row; - width: 100%; - padding: 1rem 0; -} -.container-header h2 { - flex: 1; -} -.container-header button { - align-self: center; -} - -.btn { - background: var(--accent-color); - color: rgba(var(--foreground-color), 1); - padding: 0.4em 1em; -} - -.back-arrow { - stroke: rgba(var(--text-color), 1); - stroke-width: 6; - fill: none; - height: 2rem; - padding: 0.5rem 0.5rem 0.5rem 0; - cursor: pointer; -} - -.card { - border-radius: 0.6rem; - padding: 1.5em; - background: rgba(var(--foreground-color), 1); -} - -.solid-background { - background: rgba(var(--foreground-color), 1) !important; -} - -#confirmation, -#prompt { - flex-direction: column; -} -#confirmation h4, -#prompt h4 { - font-weight: 500; - margin-bottom: 1.5rem; -} -#confirmation .flex sm-button:first-of-type, -#prompt .flex sm-button:first-of-type { - margin-right: 0.6em; - margin-left: auto; -} - -.refresh { - margin-top: 0.6em; - margin-bottom: 1em; -} - -sm-popup .illustration { - position: relative; - height: 4rem; - width: 4rem; - padding: 1rem; - stroke: var(--accent-color); - margin-bottom: 1rem; - border-radius: 5rem; - background: rgba(var(--text-color), 0.06); -} -sm-popup sm-input:not(:last-of-type) { - margin-bottom: 1rem; -} -sm-popup p { - margin-block-end: 1rem; -} -sm-popup .action h4 { - padding: 0.5rem 1rem; - font-weight: 500; -} -sm-popup .message { - margin-bottom: 0.2rem; -} -sm-popup .message + .copy-row { - margin-bottom: 1.5rem; -} -sm-popup h5:not(.tag) { - font-family: "Roboto", sans-serif; - margin-bottom: 0.4rem; - margin-top: 1rem; - font-weight: 500; -} - -#reader { - overflow: hidden; -} - -.my-qr-code { - background: #fff; - border-radius: 0.5rem; - padding: 1rem; - max-width: max-content; -} - -#qr_code_popup::part(popup) { - height: 90vh; -} -#qr_code_popup::part(popup-body) { - padding: 0; -} -#qr_code_popup .popup-header { - padding-bottom: 1.5rem; -} -#qr_code_popup sm-tab-header { - margin: 0 auto; - transform: translateX(-1rem); -} -#qr_code_popup sm-panel { - display: flex; - flex-direction: column; - align-items: center; - text-align: center; -} -#qr_code_popup video { - width: 100% !important; - object-fit: cover; -} -#qr_code_popup p { - margin-top: 1.5rem; - opacity: 0.8; - text-align: center; - max-width: 30ch; -} - -sm-input[type=number] { - font-size: 1.2rem; -} - -.popup-header { - padding: 1.5rem; - padding-bottom: 0; - display: flex; - align-items: center; - width: 100%; -} -.popup-header .icon { - margin-right: 1rem; - padding: 0.2rem; - stroke-width: 10; - cursor: pointer; -} -.popup-header button { - width: auto; - margin-left: auto; -} - -details, summary { - margin-bottom: 1rem; -} - -summary { - cursor: pointer; -} - -details h5 { - line-height: 0.6; - margin-bottom: 0; - margin-top: 1.2rem !important; -} -details p { - font-size: 0.9rem; - line-height: 1.4; -} - -#sign_in_popup::part(background) { - background: rgba(var(--foreground-color), 1); -} -#sign_in_popup h3 { - margin-top: 2rem; -} -#sign_in_popup h4 { - font-weight: 500; - margin-bottom: 3rem; -} -#sign_in_popup button { - margin: 1rem 0; -} -#sign_in_popup p { - margin-top: 1rem; - margin-bottom: 0 !important; -} - -.primary-btn { - background: var(--accent-color); - justify-content: center; - color: rgba(var(--foreground-color), 1); -} - -#main_header { - align-items: center; - padding: clamp(1rem, 2vw, 2rem) 1rem; - justify-content: space-between; -} - -.icon { - height: 1.2rem; - width: 1.2rem; - fill: none; - stroke: rgba(var(--text-color), 0.8); - stroke-width: 6; - overflow: visible; - stroke-linecap: round; - stroke-linejoin: round; -} - -#navbar { - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-evenly; - position: fixed; - left: 0; - right: 0; - bottom: 0; - top: auto; - z-index: 3; - background: rgba(var(--foreground-color), 1); - box-shadow: 0 -0.5rem 1rem #00000010; - border-radius: 1rem 1rem 0 0; -} -#navbar .navbar-item { - position: relative; - text-align: center; - cursor: pointer; - padding: 0.3rem; - padding-top: 0.8rem; - border-radius: 0.4em; - opacity: 0.6; - color: rgba(var(--text-color), 1); - font-size: 0.8em; - text-transform: capitalize; - width: 100%; - font-weight: 600; -} -#navbar .navbar-item h5 { - margin-top: 0.4em; -} -#navbar .navbar-item .icon { - stroke: rgba(var(--text-color), 1); -} -#navbar .active { - opacity: 1; -} - -.banking { - stroke-width: 4; -} - -#home_page { - padding: 0 0 4rem 0; -} -#home_page .left { - width: auto; - border-radius: 0.6rem; -} -#home_page .left h3, #home_page .left h4, #home_page .left p { - padding: 0 1.5rem; -} -#home_page .left h3 { - font-size: 2rem; - margin-bottom: 1rem; -} - -.user-panel { - position: relative; - padding: 1.5rem; - padding-top: 1rem; - align-self: flex-start; -} -.user-panel .icon { - stroke: rgba(var(--foreground-color), 1); -} -.user-panel .action { - width: auto; - justify-content: flex-end; -} -.user-panel .action h4 { - border-radius: 2rem; - background-color: rgba(var(--text-color), 0.1); - color: rgba(var(--text-color), 1); - width: auto; -} -.user-panel .action .loader { - align-self: flex-end; -} -.user-panel .action .clip { - clip-path: circle(0 at 100% 0) !important; -} - -#deposit { - padding-top: 1.5rem; -} -#deposit .flex sm-button { - margin-bottom: 1.5rem; -} -#deposit .user-panel { - padding: 0 1rem; -} -#deposit .display-balance { - grid-template-areas: "rupee rupee" "flo flo"; -} - -.display-balance { - grid-template-columns: 1fr 1fr; - grid-template-areas: "rupee ." "flo flo"; - gap: 0.8rem; - margin-top: 1rem; -} -.display-balance .icon { - height: 1.4rem; - width: 1.4rem; - padding: 0.3rem; - stroke-width: 10; - cursor: pointer; -} - -.balance { - height: 10rem; - position: relative; - display: flex; - flex-direction: column; - border-radius: 1rem; - padding: 1rem; - justify-content: flex-end; -} -.balance h4 { - font-size: 2rem; - font-family: "Roboto", sans-serif; - font-weight: 500; - text-shadow: 1px 0.1rem 0.2rem #00000040; - word-break: break-all; - flex: 1; -} -.balance h5 { - opacity: 0.8; - margin-bottom: 0.2rem; -} -.balance .tooltip { - border-radius: 1rem; - color: rgba(var(--text-color), 1); - margin-left: auto; -} - -.rupee-balance-card { - grid-area: rupee; - background: url("data:image/svg+xml,%3Csvg width='512' height='512' viewBox='0 0 512 512' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23clip0)'%3E%3Cg filter='url(%23filter0_d)'%3E%3Crect x='312' y='323' width='240' height='140' rx='18' transform='rotate(30 312 323)' fill='%231C783B'/%3E%3C/g%3E%3Cg filter='url(%23filter1_d)'%3E%3Crect x='431.283' y='302' width='240' height='140' rx='18' transform='rotate(50.0235 431.283 302)' fill='%232DBD5E'/%3E%3C/g%3E%3C/g%3E%3Cdefs%3E%3Cfilter id='filter0_d' x='225' y='320' width='301.846' height='265.244' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeColorMatrix in='SourceAlpha' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'/%3E%3CfeOffset dx='-5' dy='9'/%3E%3CfeGaussianBlur stdDeviation='6'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0'/%3E%3CfeBlend mode='normal' in2='BackgroundImageFix' result='effect1_dropShadow'/%3E%3CfeBlend mode='normal' in='SourceGraphic' in2='effect1_dropShadow' result='shape'/%3E%3C/filter%3E%3Cfilter id='filter1_d' x='307' y='299' width='285.477' height='297.86' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeColorMatrix in='SourceAlpha' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'/%3E%3CfeOffset dx='-5' dy='9'/%3E%3CfeGaussianBlur stdDeviation='6'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0'/%3E%3CfeBlend mode='normal' in2='BackgroundImageFix' result='effect1_dropShadow'/%3E%3CfeBlend mode='normal' in='SourceGraphic' in2='effect1_dropShadow' result='shape'/%3E%3C/filter%3E%3CclipPath id='clip0'%3E%3Crect width='512' height='512' fill='white'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E%0A") bottom right no-repeat, linear-gradient(200deg, rgba(var(--text-color), 0.1), rgba(var(--text-color), 0.2)); - background-size: 9rem, cover; -} -.rupee-balance-card .tooltip { - box-shadow: 0 0 0 0.4rem rgba(var(--text-color), 0.1) inset; -} - -.in-process-balance { - background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1920' height='1080' viewBox='0 0 1920 1080'%3E%3Cdefs%3E%3Cstyle%3E.a%7Bfill:%231b1464;%7D.b%7Bfill:%2309083f;%7D.c%7Bfill:%2329abe2;%7D%3C/style%3E%3C/defs%3E%3Ctitle%3Ebg-art1%3C/title%3E%3Cpolygon class='a' points='0 957.24 232 957.24 357 828 434 899 485 867 594 959 843 957 889 925 938 953 1301 953 1447 807 1555 915 1590 880 1623 913 1673 856 1744 957 1920 957.24 1920 1080 0 1080 0 957.24'/%3E%3Cpolygon class='b' points='495 959 594 959 485 867 434 899 495 959'/%3E%3Cpolygon class='c' points='232 957 357 828 247 957 232 957'/%3E%3Cpolygon class='c' points='1301 953 1447 807 1318.32 953 1301 953'/%3E%3C/svg%3E") left bottom, linear-gradient(135deg, #fd946a, #ff4857); - background-size: cover; -} -.in-process-balance .tooltip { - box-shadow: 0 0 0 0.4rem #ff4857 inset; -} - -.flo-balance-card { - grid-area: flo; - color: rgba(var(--foreground-color), 1); - background: url("data:image/svg+xml,%3Csvg width='1920' height='1080' viewBox='0 0 1920 1080' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23clip0)'%3E%3Cg filter='url(%23filter0_d)'%3E%3Ccircle cx='1814.5' cy='977.5' r='437.5' fill='white'/%3E%3C/g%3E%3Cg filter='url(%23filter1_d)'%3E%3Ccircle cx='1814.5' cy='977.5' r='243.5' fill='%231B0980'/%3E%3C/g%3E%3C/g%3E%3Cdefs%3E%3Cfilter id='filter0_d' x='1344' y='515' width='913' height='913' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeColorMatrix in='SourceAlpha' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'/%3E%3CfeOffset dx='-14' dy='-6'/%3E%3CfeGaussianBlur stdDeviation='9.5'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0'/%3E%3CfeBlend mode='normal' in2='BackgroundImageFix' result='effect1_dropShadow'/%3E%3CfeBlend mode='normal' in='SourceGraphic' in2='effect1_dropShadow' result='shape'/%3E%3C/filter%3E%3Cfilter id='filter1_d' x='1538' y='709' width='525' height='525' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeColorMatrix in='SourceAlpha' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'/%3E%3CfeOffset dx='-14' dy='-6'/%3E%3CfeGaussianBlur stdDeviation='9.5'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0'/%3E%3CfeBlend mode='normal' in2='BackgroundImageFix' result='effect1_dropShadow'/%3E%3CfeBlend mode='normal' in='SourceGraphic' in2='effect1_dropShadow' result='shape'/%3E%3C/filter%3E%3CclipPath id='clip0'%3E%3Crect width='1920' height='1080' fill='white'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E%0A") center no-repeat, linear-gradient(270deg, #2f69e6, #1b0980); - background-size: cover; -} -.flo-balance-card .tooltip { - box-shadow: 0 0 0 0.4rem #1b0980 inset; -} - -.tooltip { - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; - cursor: help; - display: flex; - flex-direction: column; - background: rgba(var(--foreground-color), 1); - z-index: 1; - transition: clip-path 0.4s ease-out; - clip-path: circle(0.8rem at calc(100% - 1.5rem) 1.4rem); - scrollbar-width: thin; -} -.tooltip .tt-icon { - display: inline-flex; - width: 3rem; - height: 3rem; - align-items: center; - justify-content: center; - margin-left: auto; - font-weight: 600; -} -.tooltip .tooltip-text { - padding: 1rem; - padding-top: 0; - line-height: 1.4; - font-size: 0.9rem; - font-weight: normal; - overflow-y: auto; - max-height: calc(100% - 3rem); - max-width: 30ch; -} -.tooltip:hover { - clip-path: circle(100%); -} - -.user-type { - font-weight: 500; -} - -.options-tab { - display: grid; - grid-template-columns: repeat(4, 1fr); - padding: 1.5rem; - gap: 2rem 0.2rem; -} - -.option { - position: relative; - display: flex; - flex-direction: column; - align-items: center; - text-align: center; - border-radius: 0.4rem; - width: 5rem; - text-transform: capitalize; - transition: transform 0.3s; - -webkit-tap-highlight-color: transparent; - cursor: pointer; -} -.option .icon { - height: 3rem; - width: 3rem; - background: rgba(var(--text-color), 0.06); - border-radius: 2rem; - padding: 0.8rem; - margin-bottom: 0.6rem; -} -.option h4 { - font-size: 0.85rem; - opacity: 0.8; - font-weight: 500; -} -.option:active { - transform: scale(0.95); -} - -.request-icon { - transform: rotate(180deg); -} - -.notification-dot::after { - content: ""; - position: absolute; - z-index: 1; - top: 0; - right: 0; - height: 0.6em; - width: 0.6em; - background-color: #E53935; - border-radius: 0.4em; - transition: transform 0.3s; -} - -.shrink.notification-dot::after { - transform: scale(0); -} - -#deposit .container-header, -#withdraw .container-header { - background: linear-gradient(rgba(var(--foreground-color), 1) 90%, transparent); -} - -sm-tab-header { +.sticky { + position: -webkit-sticky; position: sticky; +} + +.top-0 { top: 0; - display: inline-flex; - background-color: var(--dark-shade); - z-index: 2; - padding: 0.3rem; - margin: 1rem 0; - border-radius: 3rem; } -sm-tab { - text-transform: capitalize; -} -sm-tab::part(tab) { - padding: 0.4rem 1.2rem; -} - -sm-panel { - width: 100%; -} - -.request { - display: grid; - gap: 1rem; - padding: 1.5em; - border-radius: 0.6rem; - background: rgba(var(--text-color), 0.06); -} -.request h4 { - font-weight: 400; - font-size: 0.9rem; -} -.request h5 { - text-transform: capitalize; - font-weight: 400; - opacity: 0.8; - margin-bottom: 0.2rem; -} -.request .action { - align-self: flex-end; -} -.request .amount { - font-family: "Roboto", sans-serif; -} -.request button { - width: auto; -} -.request .flex { - align-items: center; - justify-content: flex-end; - justify-self: flex-end; -} -.request .flex button { - margin: 0; -} -.request.placeholder { - pointer-events: none; - animation: pulse infinite 0.6s alternate; -} -.request.placeholder h4, .request.placeholder h5 { - padding: 0.5rem 0; - background: rgba(var(--text-color), 0.06); -} -.request.placeholder .btns { - display: grid; - gap: 0.5rem; - grid-auto-flow: column; - justify-content: flex-end; -} -.request.placeholder .btns h4 { - width: 6rem; -} -.request.placeholder h5 { - width: 50%; -} -.request.placeholder .time { - width: 3rem; -} -.request.placeholder:nth-of-type(2) { - animation-delay: 0.1s; -} -.request.placeholder:nth-of-type(3) { - animation-delay: 0.2s; -} -.request.placeholder:nth-of-type(4) { - animation-delay: 0.3s; -} -.request.placeholder:nth-of-type(5) { - animation-delay: 0.4s; -} -.request.placeholder:nth-of-type(6) { - animation-delay: 0.5s; -} - -.deposited { - color: #00C853; -} - -.decline-request { - margin-right: 0.5rem !important; -} - -.withdrawn { - color: #d43125; -} - -.container { - display: grid; - gap: 1em; - width: 100%; -} - -.page { - padding: 1rem 1.5rem; - padding-bottom: 5rem; -} -.page .container-header { - display: grid; - grid-template-columns: 1fr auto; - grid-template-areas: ". ." "search search"; - gap: 1rem; - top: 0; - background: rgba(var(--foreground-color), 1); - will-change: auto; - z-index: 2; -} -.page .container-header .search { - grid-area: search; -} -.page .container-header .search input { - padding: 1em; - border: none; - width: 100%; - background: var(--dark-shade); - font-size: 1rem; - font-weight: 500; - color: rgba(var(--text-color), 1); - border-radius: 0.2em; -} -.page .container-header .search input:focus { - outline: none; - background: rgba(var(--text-color-light), 0.2); -} - -.copy-row { - display: grid; - grid-template-columns: 1fr auto; - align-items: center; - gap: 0.5rem; - width: auto; -} -.copy-row h4 { - margin-bottom: 0; - font-weight: 400; -} -.copy-row .icon { - cursor: pointer; - padding: 0.4rem; - height: 1.8rem; - width: 1.8rem; -} -.copy-row .copy { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.time { - font-weight: 500; -} - -#report_popup { - width: 32rem; -} - -#profile_page { +.flex { display: flex; - flex-direction: column; -} -#profile_page button { - align-self: flex-start; } -.complaint { - display: grid; - gap: 1.5rem 0; -} -.complaint .complaint-actions { - align-items: center; - margin: 1.5rem 0 0 0; -} -.complaint .processed { - color: #007732; -} -.complaint .unprocessed { - color: #d43125; -} -.complaint .processed, -.complaint .unprocessed { - margin-bottom: 1.5rem; -} -.complaint button .icon { - padding: 0.2rem; - margin-right: 0.5rem; - stroke: var(--accent-color); - stroke-width: 8; +.flex-wrap { + flex-wrap: wrap; } -.complaints-container { - padding-top: 1.5rem; +.flex-1 { + flex: 1; +} + +.grid { display: grid; - align-items: flex-start; +} + +.flow-column { + grid-auto-flow: column; +} + +.gap-0-5 { + gap: 0.5rem; +} + +.gap-1 { + gap: 1rem; +} + +.gap-1-5 { gap: 1.5rem; } -#helpline_page sm-select { - margin-bottom: 1.5rem; +.gap-2 { + gap: 2rem; } -.complaint-placeholder { - animation: pulse infinite 0.6s alternate; -} -.complaint-placeholder h4, -.complaint-placeholder h5 { - border-radius: 0.2rem; -} -.complaint-placeholder h5 { - background: rgba(var(--text-color), 0.1); - padding: 0.5rem 0.6rem; -} -.complaint-placeholder h4 { - background: rgba(var(--text-color), 0.2); - padding: 0.8rem 0.8rem; -} -.complaint-placeholder .demo-btn { - padding: 0.8rem 3rem; +.gap-3 { + gap: 3rem; } -@keyframes pulse { - from { - opacity: 0.4; - } - to { - opacity: 1; - } +.text-align-right { + text-align: right; } -#main_loader { + +.align-start { + align-content: flex-start; +} + +.align-center { + align-items: center; +} + +.align-end { + align-items: flex-end; +} + +.text-center { text-align: center; - place-content: center; - height: 100vh; - width: 100vw; - position: fixed; - left: 0; } -#main_loader sm-button { - margin-left: 0; + +.justify-start { + justify-content: start; +} + +.justify-center { + justify-content: center; +} + +.justify-right { + margin-left: auto; +} + +.align-self-center { + align-self: center; +} + +.justify-self-center { + justify-self: center; +} + +.justify-self-start { + justify-self: start; +} + +.justify-self-end { + justify-self: end; +} + +.direction-column { + flex-direction: column; +} + +.space-between { + justify-content: space-between; +} + +.w-100 { + width: 100%; +} + +.h-100 { + height: 100%; +} + +.ripple { + height: 8rem; + width: 8rem; + position: absolute; + border-radius: 50%; + transform: scale(0); + background: radial-gradient(circle, rgba(var(--text-color), 0.3) 0%, rgba(0, 0, 0, 0) 50%); + pointer-events: none; +} + +.button--primary .ripple, +.button--danger .ripple { + background: radial-gradient(circle, rgba(var(--background-color), 0.3) 0%, rgba(0, 0, 0, 0) 50%); +} + +.interact { + position: relative; + overflow: hidden; + cursor: pointer; + -webkit-tap-highlight-color: transparent; +} + +.empty-state { + display: grid; + width: 100%; + padding: 1.5rem 0; +} + +.observe-empty-state:empty { + display: none; +} + +.observe-empty-state:not(:empty) + .empty-state { + display: none; +} + +.bullet-point { + display: flex; + align-items: center; + justify-content: center; + margin: 0 0.8ch; +} +.bullet-point::after { + content: ""; + height: 0.4ch; + width: 0.4ch; + border-radius: 0.5em; + background-color: var(--accent-color); +} + +.icon { + width: 1.2rem; + height: 1.2rem; + fill: rgba(var(--text-color), 0.8); + flex-shrink: 0; +} + +.margin-right-0-5 { + margin-right: 0.5rem; +} + +.margin-left-0-5 { + margin-left: 0.5rem; +} + +.icon-button { + padding: 0.6rem; + border-radius: 0.8rem; + background-color: rgba(var(--text-color), 0.1); + height: -webkit-max-content; + height: -moz-max-content; + height: max-content; +} +.icon-button .icon { + fill: var(--accent-color); +} + +#confirmation_popup, +#prompt_popup { + flex-direction: column; +} +#confirmation_popup h4, +#prompt_popup h4 { + font-weight: 500; + margin-bottom: 0.5rem; +} +#confirmation_popup sm-button, +#prompt_popup sm-button { + margin: 0; +} +#confirmation_popup .flex, +#prompt_popup .flex { + padding: 0; margin-top: 1rem; } -#main_loader svg { - height: 2rem; - width: 2rem; - stroke: var(--accent-color); - stroke-width: 6; - fill: none; - overflow: visible; - stroke-linecap: round; - stroke-dashoffset: 210; - stroke-dasharray: 210; - justify-self: center; - align-self: center; - margin-bottom: 2rem; -} -#main_loader h3 { - width: 100%; - font-weight: 400; - word-spacing: 0.16em; +#confirmation_popup .flex sm-button:first-of-type, +#prompt_popup .flex sm-button:first-of-type { + margin-right: 0.6rem; + margin-left: auto; } -#upi_txId_section .copy-row { +#prompt_message { margin-bottom: 1.5rem; } +.popup__header { + display: grid; + gap: 0.5rem; + width: 100%; + padding: 0 1.5rem; + align-items: center; + grid-auto-flow: column; +} + +.popup__header__close { + padding: 0.5rem; + margin-left: -0.5rem; + cursor: pointer; +} + +#main_header { + padding: 1rem 1.5rem; +} + +#main_card { + display: flex; + flex-direction: column; + height: 100%; + width: 100%; + background-color: rgba(var(--foreground-color), 1); + transition: background-color 0.3s; +} + +#pages_container { + flex: 1; + overflow-y: auto; +} + +#main_navbar { + display: flex; + background: rgba(var(--text-color), 0.03); +} +#main_navbar.hide-away { + position: absolute; +} +#main_navbar ul { + display: flex; + height: 100%; + width: 100%; +} +#main_navbar ul li { + width: 100%; +} + +.nav-item { + position: relative; + display: flex; + flex: 1; + width: 100%; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 0.5rem 0.3rem; + color: var(--text-color); + font-size: 0.7rem; + border-radius: 0.3rem; +} +.nav-item .icon { + transition: transform 0.2s; +} +.nav-item__title { + margin-top: 0.3rem; + transition: opacity 0.2s, transform 0.2s; +} +.nav-item--active { + color: var(--accent-color); +} +.nav-item--active .icon { + fill: var(--accent-color); + transform: translateY(50%); +} +.nav-item--active .nav-item__title { + transform: translateY(100%); + opacity: 0; +} +.nav-item__indicator { + position: absolute; + bottom: 0; + width: 2rem; + height: 0.3rem; + background: var(--accent-color); + border-radius: 1rem 1rem 0 0; + z-index: 1; +} + +.password-field label { + display: flex; +} +.password-field label input:checked ~ .visible { + display: none; +} +.password-field label input:not(:checked) ~ .invisible { + display: none; +} + +.multi-state-button { + display: grid; + text-align: center; + align-items: center; +} +.multi-state-button > * { + grid-area: 1/1/2/2; +} +.multi-state-button button { + z-index: 1; +} + +.clip { + -webkit-clip-path: circle(0); + clip-path: circle(0); +} + +.primary-action { + display: flex; + padding: 0.8rem 1rem; + gap: 0.5rem; + white-space: normal; + font-size: 0.8rem; + border-radius: 0.5rem; + background-color: transparent; + border: thin solid rgba(var(--text-color), 0.3); +} +.primary-action .icon { + fill: var(--accent-color); +} +.primary-action:not(:last-of-type) { + margin-right: 0.5rem; +} + +.page { + position: relative; + display: flex; + flex-direction: column; + overflow-y: auto; + align-content: flex-start; + padding: 1.5rem; +} + +#wallet_section { + background-color: rgba(var(--text-color), 0.03); + border-radius: 0.5rem; + padding: 1.5rem; +} + +#transactions_list { + flex-direction: column; + padding-bottom: 4rem; +} + +.transaction { + grid-template-columns: auto 1fr auto; + gap: 0.5rem 1rem; + padding: 0.8rem; + align-items: center; + background-color: rgba(var(--text-color), 0.03); + border-radius: 0.3rem; +} +.transaction:not(:last-of-type) { + margin-bottom: 0.5rem; +} +.transaction__icon { + display: flex; + align-items: center; + justify-content: center; + grid-area: 1/1/3/2; + width: 2.5rem; + height: 2.5rem; + background-color: rgba(var(--text-color), 0.03); + border-radius: 0.5rem; +} +.transaction__icon .icon { + fill: var(--accent-color); +} +.transaction__receiver { + font-size: 0.9rem; + font-weight: 500; + color: rgba(var(--text-color), 0.8); +} +.transaction__time { + font-size: 0.8rem; + color: rgba(var(--text-color), 0.8); +} +.transaction__amount { + font-size: 1rem; + font-weight: 700; + grid-area: 1/3/3/4; +} +.transaction__amount.sent::before { + content: "-"; +} +.transaction__amount.received::before { + content: "+"; +} + +.fab { + position: absolute; + right: 0; + bottom: 0; + margin: 1.5rem; + box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.2); + z-index: 2; +} + +#scroll_to_top { + border-radius: 3rem; + background-color: rgba(var(--foreground-color), 1); +} + +#transaction_result { + display: grid; + gap: 0.5rem; + height: max(40vh, 24rem); + align-items: center; + justify-content: center; + text-align: center; + align-content: center; +} +#transaction_result.success .icon--failed { + display: none; +} +#transaction_result.failed .icon--success { + display: none; +} +#transaction_result h3 { + text-align: center; + width: 100%; +} +#transaction_result .icon { + justify-self: center; + height: 4rem; + width: 4rem; + border-radius: 5rem; + margin-bottom: 1rem; + -webkit-animation: popup 1s; + animation: popup 1s; +} +#transaction_result .icon--success { + fill: rgba(var(--background-color), 1); + padding: 1rem; + background-color: #0bbe56; +} +#transaction_result .icon--failed { + background-color: rgba(var(--text-color), 0.03); + fill: var(--danger-color); +} +#transaction_result sm-copy { + font-size: 0.8rem; +} + +@-webkit-keyframes popup { + 0% { + opacity: 0; + transform: scale(0.2) translateY(600%); + } + 10% { + transform: scale(0.2) translateY(5rem); + opacity: 1; + } + 40% { + transform: scale(0.2) translateY(0); + } + 80% { + transform: scale(1.1) translateY(0); + } + 100% { + transform: scale(1) translateY(0); + } +} + @keyframes popup { 0% { - stroke-dashoffset: 50; - transform: translateY(4rem) scale(0.2, 0.6); + opacity: 0; + transform: scale(0.2) translateY(600%); } - 40% { - transform: translateY(0) scale(0.2); - } - 41% { - transform: translateY(0) scale(0.2); - } - 50% { - stroke-dashoffset: 50; - transform: translateY(0) scale(1); - } - 100% { - stroke-dashoffset: 0; - } -} -#transaction_result { - z-index: 12; -} -#transaction_result #transaction_heading { - margin-bottom: 1rem; -} -#transaction_result .copy-row { - grid-template-areas: "label label" ". ."; - margin-top: 1rem; - gap: 0 1rem; -} -#transaction_result .copy-row h4 { - font-weight: 500; -} -#transaction_result h5 { - grid-area: label; - color: rgba(var(--text-color), 0.7); -} -#transaction_result h4, #transaction_result h5, #transaction_result p { - text-align: center; -} -#transaction_result > h4 { - font-size: 1.2rem; - margin-top: 2rem; - margin-bottom: 0.5rem; -} -#transaction_result sm-button { - align-self: center; - width: auto; -} - -#success_svg, #failure_svg { - height: 5rem; - width: 5rem; - stroke-width: 4; - align-self: center; - stroke: none; - stroke-dasharray: 50; - fill: rgba(var(--text-color), 0.1); - animation: popup 2s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275); -} - -#success_svg polyline { - fill: none; - stroke: #00C853; -} - -#failure_svg line { - stroke: #EF5350; -} - -.rupee-symbol { - height: 1rem; - width: 1rem; - fill: rgba(var(--text-color), 0.5); -} - -#deposit_rupee .copy-row { - margin-bottom: 1rem; -} - -.activity-container { - display: grid; - gap: 1rem; -} - -.activity { - display: grid; - background: rgba(var(--text-color), 0.06); - border-radius: 0.6rem; - padding: 1rem 1.2rem; - gap: 0 1rem; - grid-template-columns: auto 1fr auto; - grid-template-areas: "icon type amount" "icon receiver time"; - align-items: center; - cursor: pointer; - transition: transform 0.3s; -} -.activity:active { - transform: scale(0.95); -} -.activity .icon { - grid-area: icon; - height: 3rem; - width: 3rem; - padding: 0.8rem; - background: rgba(var(--text-color), 0.06); - background-size: cover; - border-radius: 2rem; -} -.activity .activity-type { - grid-area: type; - text-transform: capitalize; - font-weight: 400; - font-size: 0.8rem; -} -.activity .activity-receiver { - grid-area: receiver; - font-weight: 500; - font-size: 0.9rem; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.activity .activity-amount { - text-align: right; - grid-area: amount; - font-family: "Roboto", sans-serif; -} -.activity .activity-time { - text-align: right; - grid-area: time; - color: rgba(var(--text-color), 0.7); - font-weight: 500; -} -.activity .pending { - display: inline-flex; - padding: 0.3rem 0.6rem; - background: rgba(var(--text-color), 0.06); - border-radius: 1rem; - width: max-content; - margin-left: 0.4rem; -} -.activity.placeholder { - pointer-events: none; - animation: pulse infinite 0.6s alternate; -} -.activity.placeholder .activity-type, -.activity.placeholder .activity-receiver { - background: rgba(var(--text-color), 0.06); - padding: 0.5rem 0; -} -.activity.placeholder .activity-type { - width: 50%; -} -.activity.placeholder:nth-of-type(2) { - animation-delay: 0.1s; -} -.activity.placeholder:nth-of-type(3) { - animation-delay: 0.2s; -} -.activity.placeholder:nth-of-type(4) { - animation-delay: 0.3s; -} -.activity.placeholder:nth-of-type(5) { - animation-delay: 0.4s; -} -.activity.placeholder:nth-of-type(6) { - animation-delay: 0.5s; -} -.activity.placeholder:nth-of-type(7) { - animation-delay: 0.6s; -} -.activity.placeholder:nth-of-type(8) { - animation-delay: 0.7s; -} - -.back-arrow { - stroke-width: 10; - margin-right: 0.5rem; - padding: 0.2rem; -} - -.select { - max-width: 50ch; - position: relative; - display: flex; - width: 100%; - border-radius: 0.3rem; - background: rgba(var(--text-color), 0.06); - align-items: center; -} -.select:first-of-type:not(:last-of-type) { - border-radius: 0.3rem 0.3rem 0 0; -} -.select + .select { - margin-top: 0; - border-radius: 0 0 0.3rem 0.3rem; - border-top: solid 1px rgba(var(--text-color), 0.16); -} -.select label { - display: flex; - align-items: center; - cursor: pointer; - flex: 1; - padding: 0.8rem 1rem; -} -.select input[type=radio] { - display: none; -} -.select input:checked ~ .radio .outer-ring { - stroke: var(--accent-color); -} -.select input:checked ~ .radio .inner-disc { - transform: none; -} -.select .radio { - width: 1.2rem; - height: 1.2rem; - fill: none; - overflow: visible; - margin-right: 0.6rem; -} -.select .radio .outer-ring { - stroke-width: 8; - stroke: rgba(var(--text-color), 0.5); -} -.select .radio .inner-disc { - transform-origin: center; - fill: var(--accent-color); - transform: scale(0); - transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); -} -.select .remove { - width: 3rem; - height: 2rem; - padding: 0.7rem; - cursor: pointer; - stroke-width: 10; -} -.select .tag { - grid-area: tag; - opacity: 0.6; - font-weight: 500; - border: solid 1px rgba(var(--text-color), 0.4); - padding: 0.2rem 0.4rem; - border-radius: 0.3rem; - margin-right: 0.5rem; -} -.select h4 { - font-weight: 400; -} - -.add-upi { - margin-top: 0.4rem; - justify-self: flex-start; - width: max-content; -} - -#transaction_page header { - padding: 0.5rem 0; -} -#transaction_page header .back-arrow { - grid-area: back; -} -#transaction_page header h4 { - text-transform: capitalize; -} -#transaction_page h5 { - font-weight: 400; - font-family: "Roboto", sans-serif; - opacity: 0.8; - margin-bottom: 0.4rem; - text-transform: capitalize; -} -#transaction_page p:last-of-type { - margin: 2rem 0 1rem 0; - font-size: 0.9rem; - opacity: 0.8; -} -#transaction_page #transaction_details { - position: relative; - margin: 1.5rem 0; - padding: 1.5rem; - background-color: rgba(var(--text-color), 0.06); - max-width: 50ch; - border-radius: 0.5rem; -} -#transaction_page #transaction_details .icon { - height: 4rem; - width: 4rem; - padding: 1.2rem; - border-radius: 4rem; - margin-bottom: 2rem; - background: rgba(var(--text-color), 0.06); -} -#transaction_page #transaction_details .success { - background: #00C853; - stroke-width: 8; - stroke: var(--background-color); -} -#transaction_page #transaction_details .flex { - margin-bottom: 1.5rem; - align-items: baseline; -} -#transaction_page #transaction_details strong { - font-weight: 500; -} -#transaction_page #transaction_details strong:not(:last-of-type) + sm-button { - margin-bottom: 1.5rem; - margin-top: -0.4rem; -} -#transaction_page #transaction_details strong:not(:last-of-type) { - margin-bottom: 1rem; -} -#transaction_page #transaction_details sm-button { - width: max-content; - margin-top: 0.6rem; -} -#transaction_page .transaction-amount { - font-size: 2rem; - font-weight: 400; -} -#transaction_page #transaction_time { - right: 0; - position: absolute; - margin: 1.5rem; -} - -#people_container { - display: grid; - grid-template-columns: repeat(4, 1fr); - padding: 1.5rem; - gap: 2rem 0.2rem; -} - -#add_person_btn { - cursor: pointer; - display: flex; - flex-direction: column; - width: 5rem; - text-align: center; - transition: transform 0.3s; - font-size: 0.85rem; - opacity: 0.8; - font-weight: 500; -} -#add_person_btn:active { - transform: scale(0.95); -} -#add_person_btn .icon { - height: 3rem; - width: 3rem; - border-radius: 2rem; - stroke-width: 10; - padding: 1rem; - background: rgba(var(--text-color), 0.06); - align-self: center; - margin-bottom: 0.6rem; -} - -.person { - display: flex; - flex-direction: column; - align-items: center; - cursor: pointer; - transition: transform 0.3s; - width: 5rem; - -webkit-tap-highlight-color: transparent; -} -.person:active { - transform: scale(0.95); -} - -.person-initials, #person_initials { - display: flex; - justify-content: center; - height: 3rem; - width: 3rem; - font-size: 1.2rem !important; - font-weight: 500; - align-items: center; - border-radius: 2rem; - margin-bottom: 0.6rem !important; - text-transform: uppercase; -} - -.person-name { - font-size: 0.85rem; - opacity: 0.8; - font-weight: 500; - text-transform: capitalize; - text-align: center; -} - -#person_popup > .flex:first-of-type { - margin: 1rem 0; -} -#person_popup > .flex:first-of-type .flex { - margin-top: 0.5rem; -} -#person_popup > .flex:first-of-type .flex .icon { - height: 2.6rem; - width: 2.6rem; - padding: 0.8rem; - cursor: pointer; - stroke-width: 8; -} -#person_popup > .flex:first-of-type .flex .icon:hover { - background: rgba(var(--text-color), 0.06); -} -#person_popup h3 { - text-transform: capitalize; -} -#person_popup h5 { - font-weight: 500; - opacity: 0.8; -} -#person_popup .copy-row { - margin-bottom: 1.5rem; -} -#person_popup #show_person_name { - padding: 0.5rem 1rem; - border-radius: 0.4rem; - max-width: 30ch; -} -#person_popup #show_person_name:focus { - outline: none; - background: rgba(var(--text-color), 0.1); -} - -#activity_page .empty-state, -#request_page .empty-state, -#settings_page .empty-state { - justify-content: left; -} - -#settings_page h4 { - margin-top: 2rem; - margin-bottom: 0.6rem; -} -#settings_page .copy-row h4 { - margin: 0; -} -#settings_page p { - color: rgba(var(--text-color), 0.7); -} -#settings_page sm-button { - margin-top: 0.8rem; -} -#settings_page .flex { - max-width: 60ch; -} -#settings_page .my-qr-code { - margin-bottom: 1.5rem; - height: 14rem; -} -#settings_page .my-qr-code img { - height: 100%; -} - -@media only screen and (max-width: 640px) { - #home_page, #deposit { - display: grid; - gap: 1.5rem; - grid-template-areas: "." "left"; - grid-template-columns: minmax(0, 1fr); - } - #home_page .left, #deposit .left { - grid-area: left; - } - - sm-select { - width: 100%; - } - - .hide-on-mobile { - display: none !important; - } - - #transaction_page { - padding-top: 0; - } - #transaction_page header { - padding: 1.5rem 0; - } - - #deposit .user-panel { - padding: 0; - } - - video { - height: 100vw; - } -} -@media only screen and (min-width: 640px) { - .hide-on-desktop { - display: none !important; - } - - body { - padding: 0 2rem; - margin-left: 4rem; - } - - sm-popup { - background: rgba(var(--foreground-color), 1); - } - - sm-popup::part(popup) { - width: 24rem; - } - - #confirmation { - width: 24rem; - } - - #navbar { - justify-content: flex-start; - flex-direction: column; - align-items: stretch; - left: 0; - bottom: 0; - top: 0; - right: auto; - border-top: none; - border-radius: 0; - background: rgba(var(--text-color), 0.06); - box-shadow: -0.5rem 0 0.5rem #00000008 inset; - } - #navbar .navbar-item { - display: flex; - width: auto; - padding: 0.8rem 1.2rem; - } - #navbar .navbar-item .icon { - height: 1.2rem; - width: 1.2rem; - } - #navbar .navbar-item h5 { - display: none; - } - #navbar .navbar-item:hover { + 10% { + transform: scale(0.2) translateY(5rem); opacity: 1; } - #navbar .logo { - margin: 1.5rem 1rem; + 40% { + transform: scale(0.2) translateY(0); } - #navbar .logo h4 { - display: none; + 80% { + transform: scale(1.1) translateY(0); } - #navbar .logo .main-logo { - height: 1.2rem; - width: 1.2rem; - } - #navbar .active { - background: rgba(var(--text-color), 0.06); - } - - .page { - padding-bottom: 2rem; - } - - #sign_in_popup { - width: 24rem; - } - - #home_page { - padding-top: 0.5rem; - } - #home_page .left { - margin-top: 1rem; - } - - .options-tab, #people_container { - grid-template-columns: repeat(auto-fill, minmax(5rem, 1fr)); - gap: 2rem 0.8rem; - } - - .display-balance .balance { - height: 9rem; - } - - .request { - grid-template-columns: minmax(0, auto) auto; - grid-template-areas: "time time" " . ." " . ."; - } - .request .time { - grid-area: time; - margin-bottom: 0 !important; - } - .request button { - width: max-content; - margin-left: auto; - } - .request .breakable { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - - #deposit .user-panel { - padding-right: 0; - } - - #settings_page .copy-row { - display: inline-grid; + 100% { + transform: scale(1) translateY(0); } } -@media only screen and (min-width: 800px) { - body { - margin-left: 11rem; +.cashier-request, +.wallet-request, +.payment-request { + display: flex; + gap: 1rem; + align-items: center; + padding: 0.8rem; + border-radius: 0.3rem; + background-color: rgba(var(--text-color), 0.06); +} +.cashier-request:not(:last-of-type), +.wallet-request:not(:last-of-type), +.payment-request:not(:last-of-type) { + margin-bottom: 1rem; +} +.cashier-request__time, +.wallet-request__time, +.payment-request__time { + font-size: 0.8rem; +} + +.payment-request { + display: grid; + grid-template-columns: 1fr auto; +} +.payment-request__amount { + font-weight: 700; + text-align: right; +} + +@media screen and (min-width: 40rem) { + sm-popup { + --width: 24rem; } - .complaint { - gap: 0 1.5rem; - grid-template-columns: 1fr 1fr; - grid-template-areas: ". . " "header header"; + .popup__header { + grid-column: 1/-1; + padding: 1rem 1.5rem 0 1.5rem; } - .complaint .complaint-actions { + + body { + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; + } + + #main_card { + display: grid; + grid-template-columns: auto 1fr; + grid-template-rows: auto 1fr; + grid-template-areas: "nav header" "nav main"; + position: relative; + border-radius: 0.5rem; + overflow: hidden; + box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.05), 0 1rem 3rem rgba(0, 0, 0, 0.2); + background-color: rgba(var(--foreground-color), 0.9); + } + + #main_header { grid-area: header; } - .complaint .left { - border-right: 1px solid rgba(var(--text-color), 0.2); - padding-right: 1.5rem; + + #pages_container { + grid-area: main; } - .complaint .right { - display: flex; - justify-content: center; + + #main_navbar { + grid-area: nav; + border-top: none; flex-direction: column; + height: 100%; + } + #main_navbar ul { + flex-direction: column; + gap: 0.5rem; + padding: 0.3rem; + } + #main_navbar ul li:last-of-type { + margin-top: auto; } - #navbar .navbar-item h5 { - font-size: 0.9rem; - margin: 0; - display: block; + .nav-item { + aspect-ratio: 1/1; } - #navbar .icon { - margin-right: 0.8rem; - } - #navbar .logo h4 { - display: block; - font-size: 1rem; + .nav-item__indicator { + width: 0.25rem; + height: 50%; + left: 0; + border-radius: 0 1rem 1rem 0; + bottom: auto; } - .user-panel { - position: sticky; - top: 1.5rem; - padding-top: 1.5rem; - } - - #home_page, #deposit { - display: grid; - gap: 1.5rem; - grid-template-columns: minmax(0, 1fr) 22rem; - } - - #deposit { - grid-template-columns: minmax(0, 1fr) 18rem; - } - #deposit .user-panel { - padding-right: 0; - } - - .activity { - width: 60ch; - } - - .request { - grid-template-columns: minmax(0, auto) auto; - grid-template-areas: "time time" " . ." " . ."; + #user { + grid-template-columns: 1fr 20rem; + align-content: flex-start; + align-items: flex-start; } } -@media only screen and (min-width: 1280px) { - .request { - grid-template-areas: "time time time" ". . ."; - } - - #deposit { - grid-template-columns: minmax(0, 1fr) 20rem; - } - #deposit .request { - grid-template-areas: "time time time time" ". . . ."; - } -} -@media only screen and (max-width: 320px) { - body { - font-size: 14px; +@media screen and (min-width: 56rem) { + #main_card { + height: 80vh; + width: 56rem; } } @media (any-hover: hover) { - .navbar-item:hover { - background: rgba(var(--text-color), 0.06); + ::-webkit-scrollbar { + width: 0.5rem; + height: 0.5rem; } - .remove { - opacity: 0.6; + ::-webkit-scrollbar-thumb { + background: rgba(var(--text-color), 0.3); + border-radius: 1rem; + } + ::-webkit-scrollbar-thumb:hover { + background: rgba(var(--text-color), 0.5); } - .remove:hover { - opacity: 1; + .interact:not([disabled]) { + transition: background-color 0.3s; } + .interact:not([disabled]):hover { + background-color: rgba(var(--text-color), 0.06); + } + + .button:not([disabled]) { + transition: background-color 0.3s, filter 0.3s; + } + .button:not([disabled]):hover { + filter: contrast(2); + } +} +@supports (overflow: overlay) { + body { + overflow: overlay; + } +} +.hide { + display: none !important; } \ No newline at end of file diff --git a/css/main.min.css b/css/main.min.css index 99af61e..d950434 100644 --- a/css/main.min.css +++ b/css/main.min.css @@ -1 +1 @@ -#transaction_page h5,*,.activity .activity-amount,.balance h4,.request .amount{font-family:Roboto,sans-serif}body,body[data-theme=dark] .flo-balance-card{color:rgba(var(--text-color),1)}a,h1,h2,h3,h4,h5{font-weight:600}.action,button{position:relative}.balance h4,.breakable{word-break:break-all}#navbar .navbar-item,#transaction_page h5,#transaction_page header h4,.activity .activity-type,.capitalize,.option,.request h5,button,sm-tab{text-transform:capitalize}.option,.person,button{-webkit-tap-highlight-color:transparent}*{box-sizing:border-box;padding:0;margin:0}button,h1,h2,h3,h4,h5{font-family:Poppins,sans-serif}body{--accent-color:#4527A0;--text-color:17,17,17;--text-color-light:85,85,85;--foreground-color:255,255,255;--background-color:rgba(var(--foreground-color), 1);--dark-shade:#f4f4f4;--hue:255;--saturation:61%;--lightness:39%;font-size:16px;background-size:cover}body[data-theme=dark]{--accent-color:#a293d0;--text-color:238,238,238;--text-color-light:170,170,170;--foreground-color:26,26,26;--background-color:#111;--dark-shade:#222;--hue:255;--saturation:39%;--lightness:70%;background-color:var(--background-color)}a{text-decoration:none;color:var(--accent-color)}.dark-text{color:#111}h1{font-size:3.5rem}h2{font-size:2rem}h3{font-size:1.5rem}h4{font-size:1rem}h5{font-size:.8rem}p{line-height:1.5;max-width:60ch;color:rgba(var(--text-color),.9)}strong{font-weight:500}button{display:inline-flex;align-items:center;justify-content:center;padding:.6rem 1.2rem;font-weight:600;cursor:pointer;border-radius:.3rem;color:var(--accent-color);transition:transform .3s;border:none;background:rgba(var(--text-color),.1)}.action,.align-center{align-items:center}button:focus{outline:solid thin}button:disabled{cursor:default;background:rgba(var(--text-color),.4)}button:disabled~.loader{opacity:0}::-moz-focus-inner{border:none}.bottom-padding{padding-bottom:1.5rem}.top-padding{padding-top:1em}.bottom-margin{margin-bottom:1.5rem}.top-margin{margin-top:1.5rem}.flex{display:flex}.grid{display:grid}.grid-2{grid-template-columns:auto auto;gap:1em}#confirmation,#prompt,.direction-column{flex-direction:column}.justify-right{margin-left:auto}.space-between{justify-content:space-between}.label{margin-bottom:.4rem}.light-text{opacity:.7}.hide{opacity:0;pointer-events:none}.hide-completely{display:none!important}.separator{padding:.1em}.no-transformations{transform:none!important}sm-button[variant=outlined]{--accent-color:rgba(var(--text-color), 1)}.loader{fill:none;stroke-width:10;stroke:var(--accent-color);height:2rem;width:2rem;overflow:visible;stroke-dashoffset:230;stroke-dasharray:230;padding:2px;justify-self:center}@keyframes rotate{100%{transform:rotate(360deg)}}@keyframes load{50%{stroke-dashoffset:0}100%{stroke-dashoffset:-210}}@keyframes load-btn-loader{50%{stroke-dashoffset:0}100%{stroke-dashoffset:-220}}.action{display:inline-flex;justify-content:center;padding:0;background:0 0}.action:disabled .primary-btn{background:0 0}.action:focus{outline:0}.action h4{padding:.5rem 1.2rem;font-size:.9rem;clip-path:circle(100%);transition:clip-path .3s;border-radius:.2rem}.action .btn{z-index:2}.action .loader{position:absolute;z-index:1;padding:.4em;stroke-dashoffset:220;stroke-dasharray:220}.action .loader:not(.animate-loader){opacity:0}.action .animate-loader{animation:load-btn-loader 2.6s infinite,rotate 1s infinite linear}.clip{clip-path:circle(0)!important}.animate-loader{animation:load 2.6s infinite,rotate 1s infinite linear}.expand{width:100%}.fade-left{animation:fadeleft .3s}.fade-right{animation:faderight .3s}@keyframes faderight{from{opacity:0;transform:translateX(-1em)}to{opacity:1;transform:none}}@keyframes fadeleft{from{opacity:0;transform:translateX(1em)}to{opacity:1;transform:none}}.logo{display:flex;align-items:center}.logo h4{font-weight:500;font-size:clamp(1.1rem,2vw,1.2rem)}.logo .main-logo{height:clamp(1.4rem,2vw,1.6rem);width:clamp(1.4rem,2vw,1.6rem);fill:rgba(var(--text-color),1);stroke:none;margin-right:.2rem}textarea{width:100%;max-width:100%;background:rgba(var(--text-color),.1);border:none;border-radius:.2rem;resize:none;font-size:1rem;line-height:1.6;padding:.8rem}:empty+.empty-state{display:grid}.empty-state{display:none;place-items:center;width:100%}.empty-state svg{stroke:rgba(var(--text-color),.8);height:12em;width:12em}.container-header{display:flex;align-items:center;flex-direction:row;width:100%;padding:1rem 0}.container-header h2{flex:1}.container-header button{align-self:center}.btn{background:var(--accent-color);color:rgba(var(--foreground-color),1);padding:.4em 1em}.back-arrow{stroke:rgba(var(--text-color),1);fill:none;height:2rem;cursor:pointer}.card{border-radius:.6rem;padding:1.5em;background:rgba(var(--foreground-color),1)}.solid-background{background:rgba(var(--foreground-color),1)!important}#confirmation h4,#prompt h4{font-weight:500;margin-bottom:1.5rem}#confirmation .flex sm-button:first-of-type,#prompt .flex sm-button:first-of-type{margin-right:.6em;margin-left:auto}.refresh{margin-top:.6em;margin-bottom:1em}sm-popup .illustration{position:relative;height:4rem;width:4rem;padding:1rem;stroke:var(--accent-color);margin-bottom:1rem;border-radius:5rem;background:rgba(var(--text-color),.06)}sm-popup sm-input:not(:last-of-type){margin-bottom:1rem}sm-popup p{margin-block-end:1rem}sm-popup .action h4{padding:.5rem 1rem;font-weight:500}sm-popup .message{margin-bottom:.2rem}#deposit .flex sm-button,sm-popup .message+.copy-row{margin-bottom:1.5rem}sm-popup h5:not(.tag){font-family:Roboto,sans-serif;margin-bottom:.4rem;margin-top:1rem;font-weight:500}#reader{overflow:hidden}.my-qr-code{background:#fff;border-radius:.5rem;padding:1rem;max-width:max-content}#qr_code_popup::part(popup){height:90vh}#qr_code_popup::part(popup-body){padding:0}#qr_code_popup .popup-header{padding-bottom:1.5rem}#qr_code_popup sm-tab-header{margin:0 auto;transform:translateX(-1rem)}#qr_code_popup sm-panel{display:flex;flex-direction:column;align-items:center;text-align:center}#qr_code_popup video{width:100%!important;object-fit:cover}#qr_code_popup p{margin-top:1.5rem;opacity:.8;text-align:center;max-width:30ch}sm-input[type=number]{font-size:1.2rem}.popup-header{padding:1.5rem;padding-bottom:0;display:flex;align-items:center;width:100%}.popup-header .icon{margin-right:1rem;padding:.2rem;stroke-width:10;cursor:pointer}.popup-header button{width:auto;margin-left:auto}details,summary{margin-bottom:1rem}summary{cursor:pointer}details h5{line-height:.6;margin-bottom:0;margin-top:1.2rem!important}details p{font-size:.9rem;line-height:1.4}#sign_in_popup::part(background){background:rgba(var(--foreground-color),1)}#sign_in_popup h3{margin-top:2rem}#sign_in_popup h4{font-weight:500;margin-bottom:3rem}#sign_in_popup button{margin:1rem 0}#sign_in_popup p{margin-top:1rem;margin-bottom:0!important}.primary-btn{background:var(--accent-color);justify-content:center;color:rgba(var(--foreground-color),1)}#navbar .navbar-item,.balance .tooltip,.user-panel .action h4{color:rgba(var(--text-color),1)}#main_header{align-items:center;padding:clamp(1rem,2vw,2rem) 1rem;justify-content:space-between}.icon{height:1.2rem;width:1.2rem;fill:none;stroke:rgba(var(--text-color),.8);stroke-width:6;overflow:visible;stroke-linecap:round;stroke-linejoin:round}#navbar{display:flex;flex-direction:row;align-items:center;justify-content:space-evenly;position:fixed;left:0;right:0;bottom:0;top:auto;z-index:3;background:rgba(var(--foreground-color),1);box-shadow:0 -.5rem 1rem #00010;border-radius:1rem 1rem 0 0}#navbar .navbar-item{position:relative;text-align:center;cursor:pointer;padding:.3rem;padding-top:.8rem;border-radius:.4em;opacity:.6;font-size:.8em;width:100%;font-weight:600}#navbar .navbar-item h5{margin-top:.4em}#navbar .navbar-item .icon{stroke:rgba(var(--text-color),1)}#navbar .active{opacity:1}.banking{stroke-width:4}#home_page{padding:0 0 4rem}#home_page .left{width:auto;border-radius:.6rem}#home_page .left h3,#home_page .left h4,#home_page .left p{padding:0 1.5rem}#home_page .left h3{font-size:2rem;margin-bottom:1rem}.user-panel{position:relative;padding:1.5rem;padding-top:1rem;align-self:flex-start}.request .action,.user-panel .action .loader{align-self:flex-end}.user-panel .icon{stroke:rgba(var(--foreground-color),1)}.user-panel .action{width:auto;justify-content:flex-end}.user-panel .action h4{border-radius:2rem;background-color:rgba(var(--text-color),.1);width:auto}.user-panel .action .clip{clip-path:circle(0 at 100% 0)!important}#deposit{padding-top:1.5rem}#deposit .user-panel{padding:0 1rem}#deposit .display-balance{grid-template-areas:"rupee rupee" "flo flo"}.display-balance{grid-template-columns:1fr 1fr;grid-template-areas:"rupee ." "flo flo";gap:.8rem;margin-top:1rem}.display-balance .icon{height:1.4rem;width:1.4rem;padding:.3rem;stroke-width:10;cursor:pointer}.balance{height:10rem;position:relative;display:flex;flex-direction:column;border-radius:1rem;padding:1rem;justify-content:flex-end}.balance h4{font-size:2rem;font-weight:500;text-shadow:1px .1rem .2rem #00040;flex:1}.balance h5{opacity:.8;margin-bottom:.2rem}.balance .tooltip{border-radius:1rem;margin-left:auto}.rupee-balance-card{grid-area:rupee;background:url("data:image/svg+xml,%3Csvg width='512' height='512' viewBox='0 0 512 512' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23clip0)'%3E%3Cg filter='url(%23filter0_d)'%3E%3Crect x='312' y='323' width='240' height='140' rx='18' transform='rotate(30 312 323)' fill='%231C783B'/%3E%3C/g%3E%3Cg filter='url(%23filter1_d)'%3E%3Crect x='431.283' y='302' width='240' height='140' rx='18' transform='rotate(50.0235 431.283 302)' fill='%232DBD5E'/%3E%3C/g%3E%3C/g%3E%3Cdefs%3E%3Cfilter id='filter0_d' x='225' y='320' width='301.846' height='265.244' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeColorMatrix in='SourceAlpha' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'/%3E%3CfeOffset dx='-5' dy='9'/%3E%3CfeGaussianBlur stdDeviation='6'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0'/%3E%3CfeBlend mode='normal' in2='BackgroundImageFix' result='effect1_dropShadow'/%3E%3CfeBlend mode='normal' in='SourceGraphic' in2='effect1_dropShadow' result='shape'/%3E%3C/filter%3E%3Cfilter id='filter1_d' x='307' y='299' width='285.477' height='297.86' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeColorMatrix in='SourceAlpha' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'/%3E%3CfeOffset dx='-5' dy='9'/%3E%3CfeGaussianBlur stdDeviation='6'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0'/%3E%3CfeBlend mode='normal' in2='BackgroundImageFix' result='effect1_dropShadow'/%3E%3CfeBlend mode='normal' in='SourceGraphic' in2='effect1_dropShadow' result='shape'/%3E%3C/filter%3E%3CclipPath id='clip0'%3E%3Crect width='512' height='512' fill='white'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E%0A") bottom right no-repeat,linear-gradient(200deg,rgba(var(--text-color),.1),rgba(var(--text-color),.2));background-size:9rem,cover}.rupee-balance-card .tooltip{box-shadow:0 0 0 .4rem rgba(var(--text-color),.1) inset}.in-process-balance{background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1920' height='1080' viewBox='0 0 1920 1080'%3E%3Cdefs%3E%3Cstyle%3E.a%7Bfill:%231b1464;%7D.b%7Bfill:%2309083f;%7D.c%7Bfill:%2329abe2;%7D%3C/style%3E%3C/defs%3E%3Ctitle%3Ebg-art1%3C/title%3E%3Cpolygon class='a' points='0 957.24 232 957.24 357 828 434 899 485 867 594 959 843 957 889 925 938 953 1301 953 1447 807 1555 915 1590 880 1623 913 1673 856 1744 957 1920 957.24 1920 1080 0 1080 0 957.24'/%3E%3Cpolygon class='b' points='495 959 594 959 485 867 434 899 495 959'/%3E%3Cpolygon class='c' points='232 957 357 828 247 957 232 957'/%3E%3Cpolygon class='c' points='1301 953 1447 807 1318.32 953 1301 953'/%3E%3C/svg%3E") left bottom,linear-gradient(135deg,#fd946a,#ff4857);background-size:cover}.in-process-balance .tooltip{box-shadow:0 0 0 .4rem #ff4857 inset}.flo-balance-card{grid-area:flo;color:rgba(var(--foreground-color),1);background:url("data:image/svg+xml,%3Csvg width='1920' height='1080' viewBox='0 0 1920 1080' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23clip0)'%3E%3Cg filter='url(%23filter0_d)'%3E%3Ccircle cx='1814.5' cy='977.5' r='437.5' fill='white'/%3E%3C/g%3E%3Cg filter='url(%23filter1_d)'%3E%3Ccircle cx='1814.5' cy='977.5' r='243.5' fill='%231B0980'/%3E%3C/g%3E%3C/g%3E%3Cdefs%3E%3Cfilter id='filter0_d' x='1344' y='515' width='913' height='913' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeColorMatrix in='SourceAlpha' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'/%3E%3CfeOffset dx='-14' dy='-6'/%3E%3CfeGaussianBlur stdDeviation='9.5'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0'/%3E%3CfeBlend mode='normal' in2='BackgroundImageFix' result='effect1_dropShadow'/%3E%3CfeBlend mode='normal' in='SourceGraphic' in2='effect1_dropShadow' result='shape'/%3E%3C/filter%3E%3Cfilter id='filter1_d' x='1538' y='709' width='525' height='525' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeColorMatrix in='SourceAlpha' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'/%3E%3CfeOffset dx='-14' dy='-6'/%3E%3CfeGaussianBlur stdDeviation='9.5'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0'/%3E%3CfeBlend mode='normal' in2='BackgroundImageFix' result='effect1_dropShadow'/%3E%3CfeBlend mode='normal' in='SourceGraphic' in2='effect1_dropShadow' result='shape'/%3E%3C/filter%3E%3CclipPath id='clip0'%3E%3Crect width='1920' height='1080' fill='white'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E%0A") center no-repeat,linear-gradient(270deg,#2f69e6,#1b0980);background-size:cover}.flo-balance-card .tooltip{box-shadow:0 0 0 .4rem #1b0980 inset}.tooltip{position:absolute;left:0;right:0;top:0;bottom:0;cursor:help;display:flex;flex-direction:column;background:rgba(var(--foreground-color),1);z-index:1;transition:clip-path .4s ease-out;clip-path:circle(.8rem at calc(100% - 1.5rem) 1.4rem);scrollbar-width:thin}.activity,.option{transition:transform .3s;cursor:pointer}.tooltip .tt-icon{display:inline-flex;width:3rem;height:3rem;align-items:center;justify-content:center;margin-left:auto;font-weight:600}.tooltip .tooltip-text{padding:1rem;padding-top:0;line-height:1.4;font-size:.9rem;font-weight:400;overflow-y:auto;max-height:calc(100% - 3rem);max-width:30ch}.option h4,.user-type{font-weight:500}.tooltip:hover{clip-path:circle(100%)}.options-tab{display:grid;grid-template-columns:repeat(4,1fr);padding:1.5rem;gap:2rem .2rem}.option{position:relative;display:flex;flex-direction:column;align-items:center;text-align:center;border-radius:.4rem;width:5rem}.option .icon{height:3rem;width:3rem;background:rgba(var(--text-color),.06);border-radius:2rem;padding:.8rem;margin-bottom:.6rem}.option h4{font-size:.85rem;opacity:.8}.option:active{transform:scale(.95)}.request-icon{transform:rotate(180deg)}.notification-dot::after{content:"";position:absolute;z-index:1;top:0;right:0;height:.6em;width:.6em;background-color:#E53935;border-radius:.4em;transition:transform .3s}.shrink.notification-dot::after{transform:scale(0)}#deposit .container-header,#withdraw .container-header{background:linear-gradient(rgba(var(--foreground-color),1) 90%,transparent)}sm-tab-header{position:sticky;top:0;display:inline-flex;background-color:var(--dark-shade);z-index:2;padding:.3rem;margin:1rem 0;border-radius:3rem}sm-tab::part(tab){padding:.4rem 1.2rem}sm-panel{width:100%}.request{display:grid;gap:1rem;padding:1.5em;border-radius:.6rem;background:rgba(var(--text-color),.06)}.request h4{font-weight:400;font-size:.9rem}.request h5{font-weight:400;opacity:.8;margin-bottom:.2rem}.request button{width:auto}.request .flex{align-items:center;justify-content:flex-end;justify-self:flex-end}.request .flex button{margin:0}.request.placeholder{pointer-events:none;animation:pulse infinite .6s alternate}.request.placeholder h4,.request.placeholder h5{padding:.5rem 0;background:rgba(var(--text-color),.06)}.request.placeholder .btns{display:grid;gap:.5rem;grid-auto-flow:column;justify-content:flex-end}.request.placeholder .btns h4{width:6rem}.request.placeholder h5{width:50%}.request.placeholder .time{width:3rem}.request.placeholder:nth-of-type(2){animation-delay:.1s}.request.placeholder:nth-of-type(3){animation-delay:.2s}.request.placeholder:nth-of-type(4){animation-delay:.3s}.request.placeholder:nth-of-type(5){animation-delay:.4s}.request.placeholder:nth-of-type(6){animation-delay:.5s}.deposited{color:#00C853}.decline-request{margin-right:.5rem!important}.withdrawn{color:#d43125}.container{display:grid;gap:1em;width:100%}.page{padding:1rem 1.5rem;padding-bottom:5rem}.page .container-header{display:grid;grid-template-columns:1fr auto;grid-template-areas:". ." "search search";gap:1rem;top:0;background:rgba(var(--foreground-color),1);will-change:auto;z-index:2}.page .container-header .search{grid-area:search}.page .container-header .search input{padding:1em;border:none;width:100%;background:var(--dark-shade);font-size:1rem;font-weight:500;color:rgba(var(--text-color),1);border-radius:.2em}.page .container-header .search input:focus{outline:0;background:rgba(var(--text-color-light),.2)}.copy-row{display:grid;grid-template-columns:1fr auto;align-items:center;gap:.5rem;width:auto}.copy-row h4{margin-bottom:0;font-weight:400}.copy-row .icon{cursor:pointer;padding:.4rem;height:1.8rem;width:1.8rem}.copy-row .copy{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.time{font-weight:500}#report_popup{width:32rem}#profile_page{display:flex;flex-direction:column}#profile_page button{align-self:flex-start}.complaint{display:grid;gap:1.5rem 0}.complaint .complaint-actions{align-items:center;margin:1.5rem 0 0}#helpline_page sm-select,.complaint .processed,.complaint .unprocessed{margin-bottom:1.5rem}.complaint .processed{color:#007732}.complaint .unprocessed{color:#d43125}.complaint button .icon{padding:.2rem;margin-right:.5rem;stroke:var(--accent-color);stroke-width:8}.complaints-container{padding-top:1.5rem;display:grid;align-items:flex-start;gap:1.5rem}.complaint-placeholder{animation:pulse infinite .6s alternate}.complaint-placeholder h4,.complaint-placeholder h5{border-radius:.2rem}.complaint-placeholder h5{background:rgba(var(--text-color),.1);padding:.5rem .6rem}.complaint-placeholder h4{background:rgba(var(--text-color),.2);padding:.8rem}.complaint-placeholder .demo-btn{padding:.8rem 3rem}@keyframes pulse{from{opacity:.4}to{opacity:1}}#main_loader{text-align:center;place-content:center;height:100vh;width:100vw;position:fixed;left:0}#main_loader sm-button{margin-left:0;margin-top:1rem}#main_loader svg{height:2rem;width:2rem;stroke:var(--accent-color);stroke-width:6;fill:none;overflow:visible;stroke-linecap:round;stroke-dashoffset:210;stroke-dasharray:210;justify-self:center;align-self:center;margin-bottom:2rem}.activity,.select{align-items:center;background:rgba(var(--text-color),.06)}#main_loader h3{width:100%;font-weight:400;word-spacing:.16em}#upi_txId_section .copy-row{margin-bottom:1.5rem}@keyframes popup{0%{stroke-dashoffset:50;transform:translateY(4rem) scale(.2,.6)}40%,41%{transform:translateY(0) scale(.2)}50%{stroke-dashoffset:50;transform:translateY(0) scale(1)}100%{stroke-dashoffset:0}}#transaction_result{z-index:12}#transaction_result #transaction_heading{margin-bottom:1rem}#transaction_result .copy-row{grid-template-areas:"label label" ". .";margin-top:1rem;gap:0 1rem}#transaction_result .copy-row h4{font-weight:500}#transaction_result h5{grid-area:label;color:rgba(var(--text-color),.7)}#transaction_result h4,#transaction_result h5,#transaction_result p{text-align:center}#transaction_result>h4{font-size:1.2rem;margin-top:2rem;margin-bottom:.5rem}#transaction_result sm-button{align-self:center;width:auto}#failure_svg,#success_svg{height:5rem;width:5rem;stroke-width:4;align-self:center;stroke:none;stroke-dasharray:50;fill:rgba(var(--text-color),.1);animation:popup 2s forwards cubic-bezier(.175,.885,.32,1.275)}#success_svg polyline{fill:none;stroke:#00C853}#failure_svg line{stroke:#EF5350}.rupee-symbol{height:1rem;width:1rem;fill:rgba(var(--text-color),.5)}#deposit_rupee .copy-row{margin-bottom:1rem}.activity-container{display:grid;gap:1rem}.activity{display:grid;border-radius:.6rem;padding:1rem 1.2rem;gap:0 1rem;grid-template-columns:auto 1fr auto;grid-template-areas:"icon type amount" "icon receiver time"}.activity:active{transform:scale(.95)}.activity .icon{grid-area:icon;height:3rem;width:3rem;padding:.8rem;background:rgba(var(--text-color),.06);background-size:cover;border-radius:2rem}.activity .activity-type{grid-area:type;font-weight:400;font-size:.8rem}.activity .activity-receiver{grid-area:receiver;font-weight:500;font-size:.9rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.activity .activity-amount{text-align:right;grid-area:amount}.activity .activity-time{text-align:right;grid-area:time;color:rgba(var(--text-color),.7);font-weight:500}.activity .pending{display:inline-flex;padding:.3rem .6rem;background:rgba(var(--text-color),.06);border-radius:1rem;width:max-content;margin-left:.4rem}.activity.placeholder{pointer-events:none;animation:pulse infinite .6s alternate}.activity.placeholder .activity-receiver,.activity.placeholder .activity-type{background:rgba(var(--text-color),.06);padding:.5rem 0}.activity.placeholder .activity-type{width:50%}.activity.placeholder:nth-of-type(2){animation-delay:.1s}.activity.placeholder:nth-of-type(3){animation-delay:.2s}.activity.placeholder:nth-of-type(4){animation-delay:.3s}.activity.placeholder:nth-of-type(5){animation-delay:.4s}.activity.placeholder:nth-of-type(6){animation-delay:.5s}.activity.placeholder:nth-of-type(7){animation-delay:.6s}.activity.placeholder:nth-of-type(8){animation-delay:.7s}.back-arrow{stroke-width:10;margin-right:.5rem;padding:.2rem}.select{max-width:50ch;position:relative;display:flex;width:100%;border-radius:.3rem}.select:first-of-type:not(:last-of-type){border-radius:.3rem .3rem 0 0}.select+.select{margin-top:0;border-radius:0 0 .3rem .3rem;border-top:solid 1px rgba(var(--text-color),.16)}.select label{display:flex;align-items:center;cursor:pointer;flex:1;padding:.8rem 1rem}.select input[type=radio]{display:none}.select input:checked~.radio .outer-ring{stroke:var(--accent-color)}.select input:checked~.radio .inner-disc{transform:none}.select .radio{width:1.2rem;height:1.2rem;fill:none;overflow:visible;margin-right:.6rem}.select .radio .outer-ring{stroke-width:8;stroke:rgba(var(--text-color),.5)}.select .radio .inner-disc{transform-origin:center;fill:var(--accent-color);transform:scale(0);transition:transform .3s cubic-bezier(.175,.885,.32,1.275)}#add_person_btn:active,.person:active{transform:scale(.95)}#add_person_btn,.person{transition:transform .3s;cursor:pointer}.select .remove{width:3rem;height:2rem;padding:.7rem;cursor:pointer;stroke-width:10}.select .tag{grid-area:tag;opacity:.6;font-weight:500;border:1px solid;padding:.2rem .4rem;border-radius:.3rem;margin-right:.5rem}#add_person_btn,#person_popup h5,.person-name{opacity:.8;font-weight:500}.select h4{font-weight:400}.add-upi{margin-top:.4rem;justify-self:flex-start;width:max-content}#transaction_page header{padding:.5rem 0}#transaction_page header .back-arrow{grid-area:back}#transaction_page h5{font-weight:400;opacity:.8;margin-bottom:.4rem}#transaction_page p:last-of-type{margin:2rem 0 1rem;font-size:.9rem;opacity:.8}#transaction_page #transaction_details{position:relative;margin:1.5rem 0;padding:1.5rem;background-color:rgba(var(--text-color),.06);max-width:50ch;border-radius:.5rem}#transaction_page #transaction_details .icon{height:4rem;width:4rem;padding:1.2rem;border-radius:4rem;margin-bottom:2rem;background:rgba(var(--text-color),.06)}#transaction_page #transaction_details .success{background:#00C853;stroke-width:8;stroke:var(--background-color)}#transaction_page #transaction_details .flex{margin-bottom:1.5rem;align-items:baseline}#transaction_page #transaction_details strong{font-weight:500}#transaction_page #transaction_details strong:not(:last-of-type)+sm-button{margin-bottom:1.5rem;margin-top:-.4rem}#transaction_page #transaction_details strong:not(:last-of-type){margin-bottom:1rem}#transaction_page #transaction_details sm-button{width:max-content;margin-top:.6rem}#transaction_page .transaction-amount{font-size:2rem;font-weight:400}#transaction_page #transaction_time{right:0;position:absolute;margin:1.5rem}#people_container{display:grid;grid-template-columns:repeat(4,1fr);padding:1.5rem;gap:2rem .2rem}#add_person_btn{display:flex;flex-direction:column;width:5rem;text-align:center;font-size:.85rem}#add_person_btn .icon{height:3rem;width:3rem;border-radius:2rem;stroke-width:10;padding:1rem;background:rgba(var(--text-color),.06);align-self:center;margin-bottom:.6rem}.person{display:flex;flex-direction:column;align-items:center;width:5rem}#person_initials,.person-initials{display:flex;justify-content:center;height:3rem;width:3rem;font-size:1.2rem!important;font-weight:500;align-items:center;border-radius:2rem;margin-bottom:.6rem!important;text-transform:uppercase}#person_popup h3,.person-name{text-transform:capitalize}.person-name{font-size:.85rem;text-align:center}#person_popup>.flex:first-of-type{margin:1rem 0}#person_popup>.flex:first-of-type .flex{margin-top:.5rem}#person_popup>.flex:first-of-type .flex .icon{height:2.6rem;width:2.6rem;padding:.8rem;cursor:pointer;stroke-width:8}#person_popup>.flex:first-of-type .flex .icon:hover{background:rgba(var(--text-color),.06)}#person_popup .copy-row{margin-bottom:1.5rem}#person_popup #show_person_name{padding:.5rem 1rem;border-radius:.4rem;max-width:30ch}#person_popup #show_person_name:focus{outline:0;background:rgba(var(--text-color),.1)}#activity_page .empty-state,#request_page .empty-state,#settings_page .empty-state{justify-content:left}#settings_page h4{margin-top:2rem;margin-bottom:.6rem}#settings_page .copy-row h4{margin:0}#settings_page p{color:rgba(var(--text-color),.7)}#settings_page sm-button{margin-top:.8rem}#settings_page .flex{max-width:60ch}#settings_page .my-qr-code{margin-bottom:1.5rem;height:14rem}#settings_page .my-qr-code img{height:100%}@media only screen and (max-width:640px){#deposit,#home_page{display:grid;gap:1.5rem;grid-template-areas:"." "left";grid-template-columns:minmax(0,1fr)}#deposit .left,#home_page .left{grid-area:left}sm-select{width:100%}.hide-on-mobile{display:none!important}#transaction_page{padding-top:0}#transaction_page header{padding:1.5rem 0}#deposit .user-panel{padding:0}video{height:100vw}}@media only screen and (min-width:640px){.hide-on-desktop{display:none!important}body{padding:0 2rem;margin-left:4rem}sm-popup{background:rgba(var(--foreground-color),1)}#navbar,#navbar .active{background:rgba(var(--text-color),.06)}#confirmation,sm-popup::part(popup){width:24rem}#navbar{justify-content:flex-start;flex-direction:column;align-items:stretch;left:0;bottom:0;top:0;right:auto;border-top:none;border-radius:0;box-shadow:-.5rem 0 .5rem #00008 inset}#navbar .navbar-item{display:flex;width:auto;padding:.8rem 1.2rem}#navbar .logo h4,#navbar .navbar-item h5{display:none}#navbar .logo .main-logo,#navbar .navbar-item .icon{height:1.2rem;width:1.2rem}#navbar .navbar-item:hover{opacity:1}#navbar .logo{margin:1.5rem 1rem}.page{padding-bottom:2rem}#sign_in_popup{width:24rem}#home_page{padding-top:.5rem}#home_page .left{margin-top:1rem}#people_container,.options-tab{grid-template-columns:repeat(auto-fill,minmax(5rem,1fr));gap:2rem .8rem}.display-balance .balance{height:9rem}.request{grid-template-columns:minmax(0,auto) auto;grid-template-areas:"time time" " . ." " . ."}.request .time{grid-area:time;margin-bottom:0!important}.request button{width:max-content;margin-left:auto}.request .breakable{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}#deposit .user-panel{padding-right:0}#settings_page .copy-row{display:inline-grid}}@media only screen and (min-width:800px){body{margin-left:11rem}.complaint{gap:0 1.5rem;grid-template-columns:1fr 1fr;grid-template-areas:". . " "header header"}.complaint .complaint-actions{grid-area:header}.complaint .left{border-right:1px solid rgba(var(--text-color),.2);padding-right:1.5rem}.complaint .right{display:flex;justify-content:center;flex-direction:column}#navbar .navbar-item h5{font-size:.9rem;margin:0;display:block}#navbar .icon{margin-right:.8rem}#navbar .logo h4{display:block;font-size:1rem}.user-panel{position:sticky;top:1.5rem;padding-top:1.5rem}#deposit,#home_page{display:grid;gap:1.5rem;grid-template-columns:minmax(0,1fr) 22rem}#deposit{grid-template-columns:minmax(0,1fr) 18rem}#deposit .user-panel{padding-right:0}.activity{width:60ch}.request{grid-template-columns:minmax(0,auto) auto;grid-template-areas:"time time" " . ." " . ."}}@media only screen and (min-width:1280px){.request{grid-template-areas:"time time time" ". . ."}#deposit{grid-template-columns:minmax(0,1fr) 20rem}#deposit .request{grid-template-areas:"time time time time" ". . . ."}}@media only screen and (max-width:320px){body{font-size:14px}}@media (any-hover:hover){.navbar-item:hover{background:rgba(var(--text-color),.06)}.remove{opacity:.6}.remove:hover{opacity:1}} \ No newline at end of file +*{padding:0;margin:0;box-sizing:border-box;font-family:"Roboto",sans-serif}:root{font-size:clamp(1rem,1.2vmax,1.2rem)}html,body{height:100%}body{--accent-color: #256eff;--text-color: 20, 20, 20;--background-color: 240, 240, 240;--foreground-color: 250, 250, 250;--danger-color: rgb(255, 75, 75);--green: #1cad59;scrollbar-width:thin;scrollbar-gutter:stable;color:rgba(var(--text-color), 1);background-color:rgba(var(--background-color), 1);transition:background-color .3s;display:flex;flex-direction:column}body[data-theme=dark]{--accent-color: #86afff;--text-color: 220, 220, 220;--background-color: 10, 10, 10;--foreground-color: 24, 24, 24;--danger-color: rgb(255, 106, 106);--green: #00e676}body[data-theme=dark] sm-popup::part(popup){background-color:rgba(var(--foreground-color), 1)}p,strong{font-size:.9rem;max-width:65ch;line-height:1.7;color:rgba(var(--text-color), 0.9)}p:not(:last-of-type),strong:not(:last-of-type){margin-bottom:1.5rem}a{text-decoration:none;color:var(--accent-color)}a:focus-visible{box-shadow:0 0 0 .1rem rgba(var(--text-color), 1) inset}button{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;display:inline-flex;border:none;background-color:transparent;overflow:hidden;color:inherit;-webkit-tap-highlight-color:transparent;align-items:center;font-size:.9rem;font-weight:500;white-space:nowrap;padding:.8rem;border-radius:.3rem;justify-content:center}button:focus-visible{outline:var(--accent-color) solid medium}button:not(:disabled){cursor:pointer}.button{background-color:rgba(var(--text-color), 0.06)}.button--primary,.button--danger{color:rgba(var(--background-color), 1)}.button--primary .icon,.button--danger .icon{fill:rgba(var(--background-color), 1)}.button--primary{background-color:var(--accent-color)}.button--danger{background-color:var(--danger-color)}.cta{text-transform:uppercase;font-size:.8rem;font-weight:700;letter-spacing:.05em;padding:1rem}.icon-only{padding:.5rem;border-radius:.3rem}button:disabled{opacity:.5}a:-webkit-any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}a:-moz-any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}a:any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}details{padding:1rem 0}details summary{display:flex;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;align-items:center;justify-content:space-between;color:var(--accent-color)}details[open] summary{margin-bottom:1rem}details[open]>summary .down-arrow{transform:rotate(180deg)}sm-input,sm-textarea{font-size:.9rem;--border-radius: 0.3rem;--background-color: rgba(var(--foreground-color), 1)}sm-input button .icon,sm-textarea button .icon{fill:var(--accent-color)}sm-button{--padding: 0.6rem 0.8rem}sm-button[variant=primary] .icon{fill:rgba(var(--background-color), 1)}sm-button[disabled] .icon{fill:rgba(var(--text-color), 0.6)}sm-button.danger{--background: var(--danger-color);color:rgba(var(--background-color), 1)}sm-spinner{--size: 1rem;--stroke-width: 0.1rem}sm-form{--gap: 1rem}strip-select{--gap: 0;background-color:rgba(var(--text-color), 0.06);border-radius:.3rem;padding:.3rem}strip-option{font-size:.8rem;--border-radius: 0.2rem;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}ul{list-style:none}.overflow-ellipsis{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.breakable{overflow-wrap:break-word;word-wrap:break-word;word-break:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}.full-bleed{grid-column:1/-1}.h1{font-size:1.5rem}.h2{font-size:1.2rem}h3{font-size:1.2rem;line-height:1.3}.h4{font-size:.9rem}.h5{font-size:.75rem}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.sticky{position:-webkit-sticky;position:sticky}.top-0{top:0}.flex{display:flex}.flex-wrap{flex-wrap:wrap}.flex-1{flex:1}.grid{display:grid}.flow-column{grid-auto-flow:column}.gap-0-5{gap:.5rem}.gap-1{gap:1rem}.gap-1-5{gap:1.5rem}.gap-2{gap:2rem}.gap-3{gap:3rem}.text-align-right{text-align:right}.align-start{align-content:flex-start}.align-center{align-items:center}.align-end{align-items:flex-end}.text-center{text-align:center}.justify-start{justify-content:start}.justify-center{justify-content:center}.justify-right{margin-left:auto}.align-self-center{align-self:center}.justify-self-center{justify-self:center}.justify-self-start{justify-self:start}.justify-self-end{justify-self:end}.direction-column{flex-direction:column}.space-between{justify-content:space-between}.w-100{width:100%}.h-100{height:100%}.ripple{height:8rem;width:8rem;position:absolute;border-radius:50%;transform:scale(0);background:radial-gradient(circle, rgba(var(--text-color), 0.3) 0%, rgba(0, 0, 0, 0) 50%);pointer-events:none}.button--primary .ripple,.button--danger .ripple{background:radial-gradient(circle, rgba(var(--background-color), 0.3) 0%, rgba(0, 0, 0, 0) 50%)}.interact{position:relative;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:transparent}.empty-state{display:grid;width:100%;padding:1.5rem 0}.observe-empty-state:empty{display:none}.observe-empty-state:not(:empty)+.empty-state{display:none}.bullet-point{display:flex;align-items:center;justify-content:center;margin:0 .8ch}.bullet-point::after{content:"";height:.4ch;width:.4ch;border-radius:.5em;background-color:var(--accent-color)}.icon{width:1.2rem;height:1.2rem;fill:rgba(var(--text-color), 0.8);flex-shrink:0}.margin-right-0-5{margin-right:.5rem}.margin-left-0-5{margin-left:.5rem}.icon-button{padding:.6rem;border-radius:.8rem;background-color:rgba(var(--text-color), 0.1);height:-webkit-max-content;height:-moz-max-content;height:max-content}.icon-button .icon{fill:var(--accent-color)}#confirmation_popup,#prompt_popup{flex-direction:column}#confirmation_popup h4,#prompt_popup h4{font-weight:500;margin-bottom:.5rem}#confirmation_popup sm-button,#prompt_popup sm-button{margin:0}#confirmation_popup .flex,#prompt_popup .flex{padding:0;margin-top:1rem}#confirmation_popup .flex sm-button:first-of-type,#prompt_popup .flex sm-button:first-of-type{margin-right:.6rem;margin-left:auto}#prompt_message{margin-bottom:1.5rem}.popup__header{display:grid;gap:.5rem;width:100%;padding:0 1.5rem;align-items:center;grid-auto-flow:column}.popup__header__close{padding:.5rem;margin-left:-0.5rem;cursor:pointer}#main_header{padding:1rem 1.5rem}#main_card{display:flex;flex-direction:column;height:100%;width:100%;background-color:rgba(var(--foreground-color), 1);transition:background-color .3s}#pages_container{flex:1;overflow-y:auto}#main_navbar{display:flex;background:rgba(var(--text-color), 0.03)}#main_navbar.hide-away{position:absolute}#main_navbar ul{display:flex;height:100%;width:100%}#main_navbar ul li{width:100%}.nav-item{position:relative;display:flex;flex:1;width:100%;flex-direction:column;align-items:center;justify-content:center;padding:.5rem .3rem;color:var(--text-color);font-size:.7rem;border-radius:.3rem}.nav-item .icon{transition:transform .2s}.nav-item__title{margin-top:.3rem;transition:opacity .2s,transform .2s}.nav-item--active{color:var(--accent-color)}.nav-item--active .icon{fill:var(--accent-color);transform:translateY(50%)}.nav-item--active .nav-item__title{transform:translateY(100%);opacity:0}.nav-item__indicator{position:absolute;bottom:0;width:2rem;height:.3rem;background:var(--accent-color);border-radius:1rem 1rem 0 0;z-index:1}.password-field label{display:flex}.password-field label input:checked~.visible{display:none}.password-field label input:not(:checked)~.invisible{display:none}.multi-state-button{display:grid;text-align:center;align-items:center}.multi-state-button>*{grid-area:1/1/2/2}.multi-state-button button{z-index:1}.clip{-webkit-clip-path:circle(0);clip-path:circle(0)}.primary-action{display:flex;padding:.8rem 1rem;gap:.5rem;white-space:normal;font-size:.8rem;border-radius:.5rem;background-color:transparent;border:thin solid rgba(var(--text-color), 0.3)}.primary-action .icon{fill:var(--accent-color)}.primary-action:not(:last-of-type){margin-right:.5rem}.page{position:relative;display:flex;flex-direction:column;overflow-y:auto;align-content:flex-start;padding:1.5rem}#wallet_section{background-color:rgba(var(--text-color), 0.03);border-radius:.5rem;padding:1.5rem}#transactions_list{flex-direction:column;padding-bottom:4rem}.transaction{grid-template-columns:auto 1fr auto;gap:.5rem 1rem;padding:.8rem;align-items:center;background-color:rgba(var(--text-color), 0.03);border-radius:.3rem}.transaction:not(:last-of-type){margin-bottom:.5rem}.transaction__icon{display:flex;align-items:center;justify-content:center;grid-area:1/1/3/2;width:2.5rem;height:2.5rem;background-color:rgba(var(--text-color), 0.03);border-radius:.5rem}.transaction__icon .icon{fill:var(--accent-color)}.transaction__receiver{font-size:.9rem;font-weight:500;color:rgba(var(--text-color), 0.8)}.transaction__time{font-size:.8rem;color:rgba(var(--text-color), 0.8)}.transaction__amount{font-size:1rem;font-weight:700;grid-area:1/3/3/4}.transaction__amount.sent::before{content:"-"}.transaction__amount.received::before{content:"+"}.fab{position:absolute;right:0;bottom:0;margin:1.5rem;box-shadow:0 .5rem 1rem rgba(0,0,0,.2);z-index:2}#scroll_to_top{border-radius:3rem;background-color:rgba(var(--foreground-color), 1)}#transaction_result{display:grid;gap:.5rem;height:max(40vh,24rem);align-items:center;justify-content:center;text-align:center;align-content:center}#transaction_result.success .icon--failed{display:none}#transaction_result.failed .icon--success{display:none}#transaction_result h3{text-align:center;width:100%}#transaction_result .icon{justify-self:center;height:4rem;width:4rem;border-radius:5rem;margin-bottom:1rem;-webkit-animation:popup 1s;animation:popup 1s}#transaction_result .icon--success{fill:rgba(var(--background-color), 1);padding:1rem;background-color:#0bbe56}#transaction_result .icon--failed{background-color:rgba(var(--text-color), 0.03);fill:var(--danger-color)}#transaction_result sm-copy{font-size:.8rem}@-webkit-keyframes popup{0%{opacity:0;transform:scale(0.2) translateY(600%)}10%{transform:scale(0.2) translateY(5rem);opacity:1}40%{transform:scale(0.2) translateY(0)}80%{transform:scale(1.1) translateY(0)}100%{transform:scale(1) translateY(0)}}@keyframes popup{0%{opacity:0;transform:scale(0.2) translateY(600%)}10%{transform:scale(0.2) translateY(5rem);opacity:1}40%{transform:scale(0.2) translateY(0)}80%{transform:scale(1.1) translateY(0)}100%{transform:scale(1) translateY(0)}}.cashier-request,.wallet-request,.payment-request{display:flex;gap:1rem;align-items:center;padding:.8rem;border-radius:.3rem;background-color:rgba(var(--text-color), 0.06)}.cashier-request:not(:last-of-type),.wallet-request:not(:last-of-type),.payment-request:not(:last-of-type){margin-bottom:1rem}.cashier-request__time,.wallet-request__time,.payment-request__time{font-size:.8rem}.payment-request{display:grid;grid-template-columns:1fr auto}.payment-request__amount{font-weight:700;text-align:right}@media screen and (min-width: 40rem){sm-popup{--width: 24rem}.popup__header{grid-column:1/-1;padding:1rem 1.5rem 0 1.5rem}body{display:flex;align-items:center;justify-content:center;overflow:hidden}#main_card{display:grid;grid-template-columns:auto 1fr;grid-template-rows:auto 1fr;grid-template-areas:"nav header" "nav main";position:relative;border-radius:.5rem;overflow:hidden;box-shadow:0 .1rem .2rem rgba(0,0,0,.05),0 1rem 3rem rgba(0,0,0,.2);background-color:rgba(var(--foreground-color), 0.9)}#main_header{grid-area:header}#pages_container{grid-area:main}#main_navbar{grid-area:nav;border-top:none;flex-direction:column;height:100%}#main_navbar ul{flex-direction:column;gap:.5rem;padding:.3rem}#main_navbar ul li:last-of-type{margin-top:auto}.nav-item{aspect-ratio:1/1}.nav-item__indicator{width:.25rem;height:50%;left:0;border-radius:0 1rem 1rem 0;bottom:auto}#user{grid-template-columns:1fr 20rem;align-content:flex-start;align-items:flex-start}}@media screen and (min-width: 56rem){#main_card{height:80vh;width:56rem}}@media(any-hover: hover){::-webkit-scrollbar{width:.5rem;height:.5rem}::-webkit-scrollbar-thumb{background:rgba(var(--text-color), 0.3);border-radius:1rem}::-webkit-scrollbar-thumb:hover{background:rgba(var(--text-color), 0.5)}.interact:not([disabled]){transition:background-color .3s}.interact:not([disabled]):hover{background-color:rgba(var(--text-color), 0.06)}.button:not([disabled]){transition:background-color .3s,filter .3s}.button:not([disabled]):hover{filter:contrast(2)}}@supports(overflow: overlay){body{overflow:overlay}}.hide{display:none !important} \ No newline at end of file diff --git a/css/main.scss b/css/main.scss index 017339e..a9cd50d 100644 --- a/css/main.scss +++ b/css/main.scss @@ -1,1866 +1,855 @@ * { - box-sizing: border-box; - padding: 0; - margin: 0; - font-family: 'Roboto', sans-serif; + padding: 0; + margin: 0; + box-sizing: border-box; + font-family: "Roboto", sans-serif; } + +:root { + font-size: clamp(1rem, 1.2vmax, 1.2rem); +} + +html, body { - --accent-color: #4527A0; - --text-color: 17, 17, 17; - --text-color-light: 85, 85, 85; - --foreground-color: 255, 255, 255; - --background-color: rgba(var(--foreground-color), 1); - --dark-shade: #f4f4f4; - --hue: 255; - --saturation: 61%; - --lightness: 39%; - color: rgba(var(--text-color), 1); - font-size: 16px; - background-size: cover; -} -body[data-theme="dark"]{ - --accent-color: #a293d0; - --text-color: 238, 238, 238; - --text-color-light: 170, 170, 170; - --foreground-color: 26, 26, 26; - --background-color: #111; - --dark-shade: #222; - --hue: 255; - --saturation: 39%; - --lightness: 70%; - background-color: var(--background-color); - .flo-balance-card{ - color: rgba(var(--text-color), 1); - } + height: 100%; } -a { - font-weight: 600; - text-decoration: none; - color: var(--accent-color); +body { + --accent-color: #256eff; + --text-color: 20, 20, 20; + --background-color: 240, 240, 240; + --foreground-color: 250, 250, 250; + --danger-color: rgb(255, 75, 75); + --green: #1cad59; + scrollbar-width: thin; + scrollbar-gutter: stable; + color: rgba(var(--text-color), 1); + background-color: rgba(var(--background-color), 1); + transition: background-color 0.3s; + display: flex; + flex-direction: column; } -.dark-text { - color: #111; +body[data-theme="dark"] { + --accent-color: #86afff; + --text-color: 220, 220, 220; + --background-color: 10, 10, 10; + --foreground-color: 24, 24, 24; + --danger-color: rgb(255, 106, 106); + --green: #00e676; + sm-popup::part(popup) { + background-color: rgba(var(--foreground-color), 1); + } } -h1 { - font-size: 3.5rem; -} +p, +strong { + font-size: 0.9rem; + max-width: 65ch; + line-height: 1.7; + color: rgba(var(--text-color), 0.9); -h2 { - font-size: 2rem; -} - -h3 { - font-size: 1.5rem; -} - -h4 { - font-size: 1rem; -} - -h5 { - font-size: 0.8rem; -} - -h1, -h2, -h3, -h4, -h5 { - font-family: 'Poppins', sans-serif; - font-weight: 600; -} - -p { - line-height: 1.5; - max-width: 60ch; - color: rgba(var(--text-color), 0.9); -} -strong{ - font-weight: 500; -} -button { - position: relative; - display: inline-flex; - align-items: center; - justify-content: center; - text-transform: capitalize; - padding: 0.6rem 1.2rem; - font-weight: 600; - cursor: pointer; - border-radius: 0.3rem; - color: var(--accent-color); - transition: transform 0.3s; - border: none; - background: rgba(var(--text-color), 0.1); - -webkit-tap-highlight-color: transparent; - font-family: 'Poppins', sans-serif; - - &:focus { - outline: thin solid rgba(var(--text-color-light), .4); - } - - &:disabled { - cursor: default; - background: rgba(var(--text-color), 0.4); - } - - &:disabled~.loader { - opacity: 0; - } -} -::-moz-focus-inner { - border: none; -} -.bottom-padding { - padding-bottom: 1.5rem; -} - -.top-padding { - padding-top: 1em; -} - -.bottom-margin { + &:not(:last-of-type) { margin-bottom: 1.5rem; + } +} +a { + text-decoration: none; + color: var(--accent-color); + &:focus-visible { + box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 1) inset; + } } -.top-margin { - margin-top: 1.5rem; +button { + user-select: none; + position: relative; + display: inline-flex; + border: none; + background-color: transparent; + overflow: hidden; + color: inherit; + -webkit-tap-highlight-color: transparent; + align-items: center; + font-size: 0.9rem; + font-weight: 500; + white-space: nowrap; + padding: 0.8rem; + border-radius: 0.3rem; + justify-content: center; + &:focus-visible { + outline: var(--accent-color) solid medium; + } + &:not(:disabled) { + cursor: pointer; + } +} +.button { + background-color: rgba(var(--text-color), 0.06); +} +.button--primary, +.button--danger { + color: rgba(var(--background-color), 1); + .icon { + fill: rgba(var(--background-color), 1); + } +} +.button--primary { + background-color: var(--accent-color); +} +.button--danger { + background-color: var(--danger-color); +} +.cta { + text-transform: uppercase; + font-size: 0.8rem; + font-weight: 700; + letter-spacing: 0.05em; + padding: 1rem; +} +.icon-only { + padding: 0.5rem; + border-radius: 0.3rem; } -.flex { - display: flex; +button:disabled { + opacity: 0.5; } -.grid { - display: grid; +a:any-link:focus-visible { + outline: rgba(var(--text-color), 1) 0.1rem solid; +} +details { + padding: 1rem 0; } -.grid-2 { - grid-template-columns: auto auto; - gap: 1em; +details summary { + display: flex; + user-select: none; + cursor: pointer; + align-items: center; + justify-content: space-between; + color: var(--accent-color); } -.align-center { - align-items: center; +details[open] { + & summary { + margin-bottom: 1rem; + } + & > summary .down-arrow { + transform: rotate(180deg); + } } -.direction-column { - flex-direction: column; +sm-input, +sm-textarea { + font-size: 0.9rem; + --border-radius: 0.3rem; + --background-color: rgba(var(--foreground-color), 1); + button { + .icon { + fill: var(--accent-color); + } + } +} +sm-button { + --padding: 0.6rem 0.8rem; + &[variant="primary"] { + .icon { + fill: rgba(var(--background-color), 1); + } + } + + &[disabled] { + .icon { + fill: rgba(var(--text-color), 0.6); + } + } + &.danger { + --background: var(--danger-color); + color: rgba(var(--background-color), 1); + } +} +sm-spinner { + --size: 1rem; + --stroke-width: 0.1rem; +} +sm-form { + --gap: 1rem; +} +strip-select { + --gap: 0; + background-color: rgba(var(--text-color), 0.06); + border-radius: 0.3rem; + padding: 0.3rem; +} +strip-option { + font-size: 0.8rem; + --border-radius: 0.2rem; + user-select: none; +} +ul { + list-style: none; } -.justify-right{ - margin-left: auto; -} - -.space-between { - justify-content: space-between; -} - -.label { - margin-bottom: 0.4rem; -} - -.light-text { - opacity: 0.7; -} - -.hide { - opacity: 0; - pointer-events: none; -} - -.hide-completely { - display: none !important; +.overflow-ellipsis { + width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } .breakable { - word-break: break-all; + overflow-wrap: break-word; + word-wrap: break-word; + word-break: break-word; + hyphens: auto; } -.separator { - padding: .1em; +.full-bleed { + grid-column: 1/-1; } -.no-transformations { - transform: none !important; -} -.capitalize{ - text-transform: capitalize; +.h1 { + font-size: 1.5rem; } -sm-button[variant="outlined"]{ - --accent-color: rgba(var(--text-color), 1); +.h2 { + font-size: 1.2rem; } -.loader { - fill: none; - stroke-width: 10; - stroke: var(--accent-color); - height: 2rem; - width: 2rem; - overflow: visible; - stroke-dashoffset: 230; - stroke-dasharray: 230; - padding: 2px; - justify-self: center; +h3 { + font-size: 1.2rem; + line-height: 1.3; } -@keyframes rotate { - 100% { - transform: rotate(360deg); - } +.h4 { + font-size: 0.9rem; } -@keyframes load { - 50% { - stroke-dashoffset: 0; - } - - 100% { - stroke-dashoffset: -210; - } +.h5 { + font-size: 0.75rem; } -@keyframes load-btn-loader { - 50% { - stroke-dashoffset: 0; - } - - 100% { - stroke-dashoffset: -220; - } +.uppercase { + text-transform: uppercase; } -.action { - position: relative; - display: inline-flex; - align-items: center; - justify-content: center; - padding: 0; - background: none; - &:disabled{ - .primary-btn { - background: none; - } - } - &:focus{ - outline: none; - } - h4 { - padding: 0.5rem 1.2rem; - font-size: 0.9rem; - clip-path: circle(100%); - transition: clip-path 0.3s; - border-radius: 0.2rem; - } - - .btn { - z-index: 2; - } - - .loader { - position: absolute; - z-index: 1; - padding: 0.4em; - stroke-dashoffset: 220; - stroke-dasharray: 220; - } - .loader:not(.animate-loader){ - opacity: 0; - } - .animate-loader { - animation: load-btn-loader 2.6s infinite, rotate 1s infinite linear; - } - +.capitalize { + text-transform: capitalize; } -.clip { - clip-path: circle(0) !important; +.sticky { + position: sticky; +} +.top-0 { + top: 0; } -.animate-loader { - animation: load 2.6s infinite, rotate 1s infinite linear; +.flex { + display: flex; +} +.flex-wrap { + flex-wrap: wrap; +} +.flex-1 { + flex: 1; } -.expand { - width: 100%; +.grid { + display: grid; +} +.flow-column { + grid-auto-flow: column; } -.fade-left { - animation: fadeleft 0.3s; +.gap-0-5 { + gap: 0.5rem; } -.fade-right { - animation: faderight 0.3s; +.gap-1 { + gap: 1rem; } -@keyframes faderight { - from { - opacity: 0; - transform: translateX(-1em); - } - - to { - opacity: 1; - transform: none; - } +.gap-1-5 { + gap: 1.5rem; } -@keyframes fadeleft { - from { - opacity: 0; - transform: translateX(1em); - } - - to { - opacity: 1; - transform: none; - } +.gap-2 { + gap: 2rem; } -.logo { - display: flex; - align-items: center; - h4{ - font-weight: 500; - font-size: clamp(1.1rem, 2vw, 1.2rem); - } - .main-logo { - height: clamp(1.4rem, 2vw, 1.6rem); - width: clamp(1.4rem, 2vw, 1.6rem); - fill: rgba(var(--text-color), 1); - stroke: none; - margin-right: 0.2rem; - } +.gap-3 { + gap: 3rem; } -textarea { - width: 100%; - max-width: 100%; - background: rgba(var(--text-color), 0.1); - border: none; - border-radius: 0.2rem; - resize: none; - font-size: 1rem; - line-height: 1.6; - padding: 0.8rem; +.text-align-right { + text-align: right; } -*:empty + .empty-state { - display: grid; +.align-start { + align-content: flex-start; } +.align-center { + align-items: center; +} +.align-end { + align-items: flex-end; +} + +.text-center { + text-align: center; +} + +.justify-start { + justify-content: start; +} + +.justify-center { + justify-content: center; +} + +.justify-right { + margin-left: auto; +} + +.align-self-center { + align-self: center; +} + +.justify-self-center { + justify-self: center; +} + +.justify-self-start { + justify-self: start; +} + +.justify-self-end { + justify-self: end; +} + +.direction-column { + flex-direction: column; +} + +.space-between { + justify-content: space-between; +} + +.w-100 { + width: 100%; +} +.h-100 { + height: 100%; +} + +.ripple { + height: 8rem; + width: 8rem; + position: absolute; + border-radius: 50%; + transform: scale(0); + background: radial-gradient( + circle, + rgba(var(--text-color), 0.3) 0%, + rgba(0, 0, 0, 0) 50% + ); + pointer-events: none; +} +.button--primary, +.button--danger { + .ripple { + background: radial-gradient( + circle, + rgba(var(--background-color), 0.3) 0%, + rgba(0, 0, 0, 0) 50% + ); + } +} +.interact { + position: relative; + overflow: hidden; + cursor: pointer; + -webkit-tap-highlight-color: transparent; +} .empty-state { - display: none; - place-items: center; - width: 100%; - svg { - stroke: rgba(var(--text-color), 0.8); - height: 12em; - width: 12em; - } + display: grid; + width: 100%; + padding: 1.5rem 0; } -.container-header { - display: flex; - align-items: center; - flex-direction: row; - width: 100%; - padding: 1rem 0; - - h2 { - flex: 1; - } - - button { - align-self: center; - } +.observe-empty-state:empty { + display: none; } -.btn { - background: var(--accent-color); - color: rgba(var(--foreground-color), 1); - padding: 0.4em 1em; +.observe-empty-state:not(:empty) + .empty-state { + display: none; } -.back-arrow { - stroke: rgba(var(--text-color), 1); - stroke-width: 6; - fill: none; - height: 2rem; - padding: 0.5rem 0.5rem 0.5rem 0; - cursor: pointer; +.bullet-point { + display: flex; + align-items: center; + justify-content: center; + margin: 0 0.8ch; + &::after { + content: ""; + height: 0.4ch; + width: 0.4ch; + border-radius: 0.5em; + background-color: var(--accent-color); + } } - -.card { - border-radius: 0.6rem; - padding: 1.5em; - background: rgba(var(--foreground-color), 1); -} - -.solid-background { - background: rgba(var(--foreground-color), 1) !important; -} - -#confirmation, -#prompt { - flex-direction: column; - h4 { - font-weight: 500; - margin-bottom: 1.5rem; - } - - .flex { - sm-button:first-of-type { - margin-right: 0.6em; - margin-left: auto; - } - } -} - -.refresh { - margin-top: 0.6em; - margin-bottom: 1em; -} - -sm-popup{ - .illustration{ - position: relative; - height: 4rem; - width: 4rem; - padding: 1rem; - stroke: var(--accent-color); - margin-bottom: 1rem; - border-radius: 5rem; - background: rgba(var(--text-color), 0.06); - } - sm-input:not(:last-of-type) { - margin-bottom: 1rem; - } - p{ - margin-block-end: 1rem; - } - .action{ - h4{ - padding: 0.5rem 1rem; - font-weight: 500; - } - } - .message{ - margin-bottom: 0.2rem; - } - .message + .copy-row{ - margin-bottom: 1.5rem; - } - h5:not(.tag){ - font-family: 'Roboto', sans-serif; - margin-bottom: 0.4rem; - margin-top: 1rem; - font-weight: 500; - } -} - -#reader{ - overflow: hidden; -} -.my-qr-code{ - background: #fff; - border-radius: 0.5rem; - padding: 1rem; - max-width: max-content; -} -#qr_code_popup{ - &::part(popup){ - height: 90vh; - } - &::part(popup-body){ - padding: 0; - } - .popup-header{ - padding-bottom: 1.5rem; - } - sm-tab-header{ - margin: 0 auto; - transform: translateX(-1rem); - } - sm-panel{ - display: flex; - flex-direction: column; - align-items: center; - text-align: center; - } - video{ - width: 100% !important; - object-fit: cover; - } - p{ - margin-top: 1.5rem; - opacity: 0.8; - text-align: center; - max-width: 30ch; - } -} -sm-input[type="number"]{ - font-size: 1.2rem; -} - -.popup-header{ - padding: 1.5rem; - padding-bottom: 0; - display: flex; - align-items: center; - width: 100%; - .icon{ - margin-right: 1rem; - padding: 0.2rem; - stroke-width: 10; - cursor: pointer; - } - button{ - width: auto; - margin-left: auto; - } -} - -details, summary{ - margin-bottom: 1rem; -} -summary{ - cursor: pointer; -} -details{ - h5{ - line-height: 0.6; - margin-bottom: 0; - margin-top: 1.2rem !important; - } - p{ - font-size: 0.9rem; - line-height: 1.4; - } -} - -#sign_in_popup { - &::part(background){ - background: rgba(var(--foreground-color), 1); - } - h3 { - margin-top: 2rem; - } - - h4 { - font-weight: 500; - margin-bottom: 3rem; - } - - button { - margin: 1rem 0; - } - - p { - margin-top: 1rem; - margin-bottom: 0 !important; - } -} - -.primary-btn { - background: var(--accent-color); - justify-content: center; - color: rgba(var(--foreground-color), 1); -} - -#main_header { - align-items: center; - padding: clamp(1rem, 2vw, 2rem) 1rem; - justify-content: space-between; -} - .icon { - height: 1.2rem; - width: 1.2rem; - fill: none; - stroke: rgba(var(--text-color), 0.8); - stroke-width: 6; - overflow: visible; - stroke-linecap: round; - stroke-linejoin: round; + width: 1.2rem; + height: 1.2rem; + fill: rgba(var(--text-color), 0.8); + flex-shrink: 0; +} +.margin-right-0-5 { + margin-right: 0.5rem; } -#navbar { - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-evenly; - position: fixed; - left: 0; - right: 0; - bottom: 0; - top: auto; - z-index: 3; - background: rgba(var(--foreground-color), 1); - box-shadow: 0 -0.5rem 1rem #00000010; - border-radius: 1rem 1rem 0 0; - .navbar-item { - position: relative; - text-align: center; - cursor: pointer; - padding: 0.3rem; - padding-top: 0.8rem; - border-radius: 0.4em; - opacity: 0.6; - color: rgba(var(--text-color), 1); - font-size: 0.8em; - text-transform: capitalize; - width: 100%; - font-weight: 600; - h5 { - margin-top: 0.4em; - } - .icon{ - stroke: rgba(var(--text-color), 1); - } - } - .active{ - opacity: 1; - } +.margin-left-0-5 { + margin-left: 0.5rem; } -.banking { - stroke-width: 4; +.icon-button { + padding: 0.6rem; + border-radius: 0.8rem; + background-color: rgba(var(--text-color), 0.1); + height: max-content; + .icon { + fill: var(--accent-color); + } } - -#home_page { - padding: 0 0 4rem 0; - .left { - width: auto; - border-radius: 0.6rem; - h3, h4, p { - padding: 0 1.5rem; - } - h3{ - font-size: 2rem; - margin-bottom: 1rem; - } - } -} - -.user-panel { - position: relative; - padding: 1.5rem; - padding-top: 1rem; - align-self: flex-start; - .icon{ - stroke: rgba(var(--foreground-color), 1); - } - .action{ - width: auto; - justify-content: flex-end; - h4{ - border-radius: 2rem; - background-color: rgba(var(--text-color), 0.1); - color: rgba(var(--text-color), 1); - width: auto ; - } - .loader{ - align-self: flex-end; - } - .clip{ - clip-path: circle(0 at 100% 0) !important; - } - } -} -#deposit{ - padding-top: 1.5rem; - .flex{ - sm-button{ - margin-bottom: 1.5rem; - } - } - .user-panel{ - padding: 0 1rem; - } - .display-balance { - grid-template-areas: 'rupee rupee' 'flo flo'; - } -} -.display-balance { - grid-template-columns: 1fr 1fr; - grid-template-areas: 'rupee .' 'flo flo'; - gap: 0.8rem; - margin-top: 1rem; - .icon { - height: 1.4rem; - width: 1.4rem; - padding: 0.3rem; - stroke-width: 10; - cursor: pointer; - } -} -.balance{ - height: 10rem; - position: relative; - display: flex; - flex-direction: column; - border-radius: 1rem; - padding: 1rem; - justify-content: flex-end; - h4{ - font-size: 2rem; - font-family: 'Roboto', sans-serif; - font-weight: 500; - text-shadow: 1px 0.1rem 0.2rem #00000040; - word-break: break-all; - flex: 1; - } - h5{ - opacity: 0.8; - margin-bottom: 0.2rem; - } - .tooltip{ - border-radius: 1rem; - color: rgba(var(--text-color), 1); - margin-left: auto; - } -} -.rupee-balance-card{ - grid-area: rupee; - background: url("data:image/svg+xml,%3Csvg width='512' height='512' viewBox='0 0 512 512' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23clip0)'%3E%3Cg filter='url(%23filter0_d)'%3E%3Crect x='312' y='323' width='240' height='140' rx='18' transform='rotate(30 312 323)' fill='%231C783B'/%3E%3C/g%3E%3Cg filter='url(%23filter1_d)'%3E%3Crect x='431.283' y='302' width='240' height='140' rx='18' transform='rotate(50.0235 431.283 302)' fill='%232DBD5E'/%3E%3C/g%3E%3C/g%3E%3Cdefs%3E%3Cfilter id='filter0_d' x='225' y='320' width='301.846' height='265.244' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeColorMatrix in='SourceAlpha' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'/%3E%3CfeOffset dx='-5' dy='9'/%3E%3CfeGaussianBlur stdDeviation='6'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0'/%3E%3CfeBlend mode='normal' in2='BackgroundImageFix' result='effect1_dropShadow'/%3E%3CfeBlend mode='normal' in='SourceGraphic' in2='effect1_dropShadow' result='shape'/%3E%3C/filter%3E%3Cfilter id='filter1_d' x='307' y='299' width='285.477' height='297.86' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeColorMatrix in='SourceAlpha' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'/%3E%3CfeOffset dx='-5' dy='9'/%3E%3CfeGaussianBlur stdDeviation='6'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0'/%3E%3CfeBlend mode='normal' in2='BackgroundImageFix' result='effect1_dropShadow'/%3E%3CfeBlend mode='normal' in='SourceGraphic' in2='effect1_dropShadow' result='shape'/%3E%3C/filter%3E%3CclipPath id='clip0'%3E%3Crect width='512' height='512' fill='white'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E%0A") bottom right no-repeat, linear-gradient(200deg, rgba(var(--text-color), 0.1), rgba(var(--text-color), 0.2)); - background-size: 9rem, cover; - .tooltip{ - box-shadow: 0 0 0 0.4rem rgba(var(--text-color), 0.1) inset; - } -} -.in-process-balance{ - background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1920' height='1080' viewBox='0 0 1920 1080'%3E%3Cdefs%3E%3Cstyle%3E.a%7Bfill:%231b1464;%7D.b%7Bfill:%2309083f;%7D.c%7Bfill:%2329abe2;%7D%3C/style%3E%3C/defs%3E%3Ctitle%3Ebg-art1%3C/title%3E%3Cpolygon class='a' points='0 957.24 232 957.24 357 828 434 899 485 867 594 959 843 957 889 925 938 953 1301 953 1447 807 1555 915 1590 880 1623 913 1673 856 1744 957 1920 957.24 1920 1080 0 1080 0 957.24'/%3E%3Cpolygon class='b' points='495 959 594 959 485 867 434 899 495 959'/%3E%3Cpolygon class='c' points='232 957 357 828 247 957 232 957'/%3E%3Cpolygon class='c' points='1301 953 1447 807 1318.32 953 1301 953'/%3E%3C/svg%3E") left bottom, linear-gradient(135deg, #fd946a, #ff4857); - background-size: cover; - .tooltip{ - box-shadow: 0 0 0 0.4rem #ff4857 inset; - } -} -.flo-balance-card{ - grid-area: flo; - color: rgba(var(--foreground-color), 1); - background: url("data:image/svg+xml,%3Csvg width='1920' height='1080' viewBox='0 0 1920 1080' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23clip0)'%3E%3Cg filter='url(%23filter0_d)'%3E%3Ccircle cx='1814.5' cy='977.5' r='437.5' fill='white'/%3E%3C/g%3E%3Cg filter='url(%23filter1_d)'%3E%3Ccircle cx='1814.5' cy='977.5' r='243.5' fill='%231B0980'/%3E%3C/g%3E%3C/g%3E%3Cdefs%3E%3Cfilter id='filter0_d' x='1344' y='515' width='913' height='913' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeColorMatrix in='SourceAlpha' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'/%3E%3CfeOffset dx='-14' dy='-6'/%3E%3CfeGaussianBlur stdDeviation='9.5'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0'/%3E%3CfeBlend mode='normal' in2='BackgroundImageFix' result='effect1_dropShadow'/%3E%3CfeBlend mode='normal' in='SourceGraphic' in2='effect1_dropShadow' result='shape'/%3E%3C/filter%3E%3Cfilter id='filter1_d' x='1538' y='709' width='525' height='525' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeColorMatrix in='SourceAlpha' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'/%3E%3CfeOffset dx='-14' dy='-6'/%3E%3CfeGaussianBlur stdDeviation='9.5'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0'/%3E%3CfeBlend mode='normal' in2='BackgroundImageFix' result='effect1_dropShadow'/%3E%3CfeBlend mode='normal' in='SourceGraphic' in2='effect1_dropShadow' result='shape'/%3E%3C/filter%3E%3CclipPath id='clip0'%3E%3Crect width='1920' height='1080' fill='white'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E%0A") center no-repeat, linear-gradient(270deg, #2f69e6, #1b0980); - background-size: cover; - .tooltip{ - box-shadow: 0 0 0 0.4rem#1b0980 inset; - } -} - -.tooltip{ - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; - cursor: help; - display: flex; - flex-direction: column; - background: rgba(var(--foreground-color), 1); - z-index: 1; - transition: clip-path 0.4s ease-out; - clip-path: circle(0.8rem at calc(100% - 1.5rem) 1.4rem); - scrollbar-width: thin; - .tt-icon{ - display: inline-flex; - width: 3rem; - height: 3rem; - align-items: center; - justify-content: center; - margin-left: auto; - font-weight: 600; - } - .tooltip-text{ - padding: 1rem; - padding-top: 0; - line-height: 1.4; - font-size: 0.9rem; - font-weight: normal; - overflow-y: auto; - max-height: calc(100% - 3rem); - max-width: 30ch; - } - &:hover{ - clip-path: circle(100%); - } -} - -.user-type { +#confirmation_popup, +#prompt_popup { + flex-direction: column; + h4 { font-weight: 500; -} - -.options-tab { - display: grid; - grid-template-columns: repeat(4, 1fr); - padding: 1.5rem; - gap: 2rem 0.2rem; -} -.option { - position: relative; - display: flex; - flex-direction: column; - align-items: center; - text-align: center; - border-radius: 0.4rem; - width: 5rem; - text-transform: capitalize; - transition: transform 0.3s; - -webkit-tap-highlight-color: transparent; - cursor: pointer; - .icon { - height: 3rem; - width: 3rem; - background: rgba(var(--text-color), 0.06); - border-radius: 2rem; - padding: 0.8rem; - margin-bottom: 0.6rem; - } - - h4 { - font-size: 0.85rem; - opacity: 0.8; - font-weight: 500; - } - - &:active { - transform: scale(0.95); + margin-bottom: 0.5rem; + } + sm-button { + margin: 0; + } + .flex { + padding: 0; + margin-top: 1rem; + sm-button:first-of-type { + margin-right: 0.6rem; + margin-left: auto; } + } +} +#prompt_message { + margin-bottom: 1.5rem; } -.request-icon{ - transform: rotate(180deg); +.popup__header { + display: grid; + gap: 0.5rem; + width: 100%; + padding: 0 1.5rem; + align-items: center; + grid-auto-flow: column; } -.notification-dot::after { - content: ''; +.popup__header__close { + padding: 0.5rem; + margin-left: -0.5rem; + cursor: pointer; +} +#main_header { + padding: 1rem 1.5rem; +} +#main_card { + display: flex; + flex-direction: column; + height: 100%; + width: 100%; + background-color: rgba(var(--foreground-color), 1); + transition: background-color 0.3s; +} +#pages_container { + flex: 1; + overflow-y: auto; +} + +#main_navbar { + display: flex; + background: rgba(var(--text-color), 0.03); + &.hide-away { position: absolute; + } + ul { + display: flex; + height: 100%; + width: 100%; + li { + width: 100%; + } + } +} +.nav-item { + position: relative; + display: flex; + flex: 1; + width: 100%; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 0.5rem 0.3rem; + color: var(--text-color); + font-size: 0.7rem; + border-radius: 0.3rem; + .icon { + transition: transform 0.2s; + } + &__title { + margin-top: 0.3rem; + transition: opacity 0.2s, transform 0.2s; + } + &--active { + color: var(--accent-color); + .icon { + fill: var(--accent-color); + transform: translateY(50%); + } + .nav-item__title { + transform: translateY(100%); + opacity: 0; + } + } + &__indicator { + position: absolute; + bottom: 0; + width: 2rem; + height: 0.3rem; + background: var(--accent-color); + border-radius: 1rem 1rem 0 0; z-index: 1; - top: 0; - right: 0; - height: 0.6em; - width: 0.6em; - background-color: #E53935; - border-radius: 0.4em; - transition: transform 0.3s; + } } -.shrink.notification-dot::after { - transform: scale(0); -} - -#deposit, -#withdraw { - .container-header { - background: linear-gradient(rgba(var(--foreground-color), 1) 90%, transparent); +.password-field { + label { + display: flex; + input:checked ~ .visible { + display: none; } -} - -sm-tab-header { - position: sticky; - top: 0; - display: inline-flex; - background-color: var(--dark-shade); - z-index: 2; - padding: 0.3rem; - margin: 1rem 0; - border-radius: 3rem; -} -sm-tab{ - text-transform: capitalize; - &::part(tab){ - padding: 0.4rem 1.2rem; + input:not(:checked) ~ .invisible { + display: none; } + } } -sm-panel{ - width: 100%; +.multi-state-button { + display: grid; + text-align: center; + align-items: center; + & > * { + grid-area: 1/1/2/2; + } + button { + z-index: 1; + } } - -.request { - display: grid; - gap: 1rem; - padding: 1.5em; - border-radius: 0.6rem; - background: rgba(var(--text-color), 0.06); - h4{ - font-weight: 400; - font-size: 0.9rem; - } - h5 { - text-transform: capitalize; - font-weight: 400; - opacity: 0.8; - margin-bottom: 0.2rem; - } - .action { - align-self: flex-end; - } - .amount { - font-family: 'Roboto', sans-serif; - } - button { - width: auto; - } - .flex { - align-items: center; - justify-content: flex-end; - justify-self: flex-end; - button { - margin: 0; - } - } - &.placeholder{ - pointer-events: none; - h4, h5{ - padding: 0.5rem 0; - background: rgba(var(--text-color), 0.06); - } - .btns{ - display: grid; - gap: 0.5rem; - grid-auto-flow: column; - justify-content: flex-end; - h4{ - width: 6rem; - } - } - h5{ - width: 50%; - } - .time{ - width: 3rem; - } - animation: pulse infinite 0.6s alternate; - &:nth-of-type(2){ - animation-delay: 0.1s; - } - &:nth-of-type(3){ - animation-delay: 0.2s; - } - &:nth-of-type(4){ - animation-delay: 0.3s; - } - &:nth-of-type(5){ - animation-delay: 0.4s; - } - &:nth-of-type(6){ - animation-delay: 0.5s; - } - } +.clip { + clip-path: circle(0); } - -.deposited { - color: #00C853; -} - -.decline-request { - margin-right: 0.5rem !important; -} - -.withdrawn { - color: #d43125; -} - -.container { - display: grid; - gap: 1em; - width: 100%; +.primary-action { + display: flex; + padding: 0.8rem 1rem; + gap: 0.5rem; + white-space: normal; + font-size: 0.8rem; + border-radius: 0.5rem; + background-color: transparent; + border: thin solid rgba(var(--text-color), 0.3); + .icon { + fill: var(--accent-color); + } + &:not(:last-of-type) { + margin-right: 0.5rem; + } } .page { - padding: 1rem 1.5rem; - padding-bottom: 5rem; - .container-header { - display: grid; - grid-template-columns: 1fr auto; - grid-template-areas: '. .' - 'search search'; - gap: 1rem; - top: 0; - background: rgba(var(--foreground-color), 1); - will-change: auto; - z-index: 2; - - .search { - grid-area: search; - - input { - padding: 1em; - border: none; - width: 100%; - background: var(--dark-shade); - font-size: 1rem; - font-weight: 500; - color: rgba(var(--text-color), 1); - border-radius: 0.2em; - - &:focus { - outline: none; - background: rgba(var(--text-color-light), 0.2); - } - } - } - } + position: relative; + display: flex; + flex-direction: column; + overflow-y: auto; + align-content: flex-start; + padding: 1.5rem; } -.copy-row { - display: grid; - grid-template-columns: 1fr auto; +#wallet_section { + background-color: rgba(var(--text-color), 0.03); + border-radius: 0.5rem; + padding: 1.5rem; +} + +#transactions_list { + flex-direction: column; + padding-bottom: 4rem; +} +.transaction { + grid-template-columns: auto 1fr auto; + gap: 0.5rem 1rem; + padding: 0.8rem; + align-items: center; + background-color: rgba(var(--text-color), 0.03); + border-radius: 0.3rem; + &:not(:last-of-type) { + margin-bottom: 0.5rem; + } + &__icon { + display: flex; align-items: center; - gap: 0.5rem; - width: auto; - h4 { - margin-bottom: 0; - font-weight: 400; - } - - .icon { - cursor: pointer; - padding: 0.4rem; - height: 1.8rem; - width: 1.8rem; - } - - .copy { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } -} - -.time { - font-weight: 500; -} - -#report_popup { - width: 32rem; -} - -#profile_page { - display: flex; - flex-direction: column; - - button { - align-self: flex-start; - } -} - -.complaint { - display: grid; - gap: 1.5rem 0; - - .complaint-actions { - align-items: center; - margin: 1.5rem 0 0 0; - } - - .processed { - color: #007732; - } - - .unprocessed { - color: #d43125; - } - - .processed, - .unprocessed { - margin-bottom: 1.5rem; - } - - button { - .icon { - padding: 0.2rem; - margin-right: 0.5rem; - stroke: var(--accent-color); - stroke-width: 8; - } - } -} - -.complaints-container { - padding-top: 1.5rem; - display: grid; - align-items: flex-start; - gap: 1.5rem; -} - -#helpline_page { - sm-select { - margin-bottom: 1.5rem; - } -} - -.complaint-placeholder { - animation: pulse infinite 0.6s alternate; - - h4, - h5 { - border-radius: 0.2rem; - } - - h5 { - background: rgba(var(--text-color), 0.1); - padding: 0.5rem 0.6rem; - } - - h4 { - background: rgba(var(--text-color), 0.2); - padding: 0.8rem 0.8rem; - } - - .demo-btn { - padding: 0.8rem 3rem; - } -} - -@keyframes pulse { - from { - opacity: 0.4; - } - - to { - opacity: 1; - } -} - - -#main_loader { - text-align: center; - place-content: center; - height: 100vh; - width: 100vw; - position: fixed; - left: 0; - sm-button { - margin-left: 0; - margin-top: 1rem; - } - - svg { - height: 2rem; - width: 2rem; - stroke: var(--accent-color); - stroke-width: 6; - fill: none; - overflow: visible; - stroke-linecap: round; - stroke-dashoffset: 210; - stroke-dasharray: 210; - justify-self: center; - align-self: center; - margin-bottom: 2rem; - } - - h3 { - width: 100%; - font-weight: 400; - word-spacing: 0.16em; - } -} -#upi_txId_section{ - .copy-row{ - margin-bottom: 1.5rem; - } -} - -@keyframes popup{ - 0%{ - stroke-dashoffset: 50; - transform: translateY(4rem) scale(0.2, 0.6); - } - 40%{ - transform: translateY(0) scale(0.2); - } - 41%{ - transform: translateY(0) scale(0.2); - } - 50%{ - stroke-dashoffset: 50; - transform: translateY(0) scale(1); - } - 100%{ - stroke-dashoffset: 0; - } -} -#transaction_result{ - z-index: 12; - #transaction_heading{ - margin-bottom: 1rem; - } - .copy-row{ - grid-template-areas: 'label label' '. .'; - margin-top: 1rem; - gap: 0 1rem; - h4{ - font-weight: 500; - } - } - h5{ - grid-area: label; - color: rgba(var(--text-color), 0.7); - } - h4, h5, p{ - text-align: center; - } - & > h4{ - font-size: 1.2rem; - margin-top: 2rem; - margin-bottom: 0.5rem; - } - sm-button{ - align-self: center; - width: auto; - } -} -#success_svg, #failure_svg{ - height: 5rem; - width: 5rem; - stroke-width: 4; - align-self: center; - stroke: none; - stroke-dasharray: 50; - fill: rgba(var(--text-color), 0.1); - animation: popup 2s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275); -} - -#success_svg{ - polyline{ - fill: none; - stroke: #00C853 ; - } -} -#failure_svg{ - line{ - stroke: #EF5350; - } -} - -.rupee-symbol{ - height: 1rem; - width: 1rem; - fill: rgba(var(--text-color), 0.5); -} - -#deposit_rupee{ - .copy-row{ - margin-bottom: 1rem; - } -} -.activity-container{ - display: grid; - gap: 1rem; -} -.activity{ - display: grid; - background: rgba(var(--text-color), 0.06); - border-radius: 0.6rem; - padding: 1rem 1.2rem; - gap: 0 1rem; - grid-template-columns: auto 1fr auto; - grid-template-areas: 'icon type amount' 'icon receiver time'; - align-items: center; - cursor: pointer; - transition: transform 0.3s; - &:active{ - transform: scale(0.95); - } - .icon{ - grid-area: icon; - height: 3rem; - width: 3rem; - padding: 0.8rem; - background: rgba(var(--text-color), 0.06); - background-size: cover; - border-radius: 2rem; - } - .activity-type{ - grid-area: type; - text-transform: capitalize; - font-weight: 400; - font-size: 0.8rem; - } - .activity-receiver{ - grid-area: receiver; - font-weight: 500; - font-size: 0.9rem; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - .activity-amount{ - text-align: right; - grid-area: amount; - font-family: 'Roboto', sans-serif; - } - .activity-time{ - text-align: right; - grid-area: time; - color: rgba(var(--text-color), 0.7); - font-weight: 500; - } - .pending{ - display: inline-flex; - padding: 0.3rem 0.6rem; - background: rgba(var(--text-color), 0.06); - border-radius: 1rem; - width: max-content; - margin-left: 0.4rem; - } - &.placeholder{ - pointer-events: none; - animation: pulse infinite 0.6s alternate; - .activity-type, - .activity-receiver{ - background: rgba(var(--text-color), 0.06); - padding: 0.5rem 0; - } - .activity-type{ - width: 50%; - } - &:nth-of-type(2){ - animation-delay: 0.1s; - } - &:nth-of-type(3){ - animation-delay: 0.2s; - } - &:nth-of-type(4){ - animation-delay: 0.3s; - } - &:nth-of-type(5){ - animation-delay: 0.4s; - } - &:nth-of-type(6){ - animation-delay: 0.5s; - } - &:nth-of-type(7){ - animation-delay: 0.6s; - } - &:nth-of-type(8){ - animation-delay: 0.7s; - } - } -} -.back-arrow{ - stroke-width: 10; - margin-right: 0.5rem; - padding: 0.2rem; -} -.select{ - max-width: 50ch; - position: relative; - display: flex; - width: 100%; - border-radius: 0.3rem; - background: rgba(var(--text-color), 0.06); - align-items: center; - &:first-of-type:not(:last-of-type){ - border-radius: 0.3rem 0.3rem 0 0; - } - & + &{ - margin-top: 0; - border-radius: 0 0 0.3rem 0.3rem; - border-top: solid 1px rgba(var(--text-color), 0.16); - } - label{ - display: flex; - align-items: center; - cursor: pointer; - flex: 1; - padding: 0.8rem 1rem; - } - input[type="radio"]{ - display: none; - } - input:checked ~ .radio .outer-ring{ - stroke: var(--accent-color); - } - input:checked ~ .radio .inner-disc{ - transform: none; - } - .radio{ - width: 1.2rem; - height: 1.2rem; - fill: none; - overflow: visible; - margin-right: 0.6rem; - .outer-ring{ - stroke-width: 8; - stroke: rgba(var(--text-color), 0.5); - } - .inner-disc{ - transform-origin: center; - fill: var(--accent-color); - transform: scale(0); - transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); - } - } - .remove{ - width: 3rem; - height: 2rem; - padding: 0.7rem; - cursor: pointer; - stroke-width: 10; - } - .tag{ - grid-area: tag; - opacity: 0.6; - font-weight: 500; - border: solid 1px rgba(var(--text-color), 0.4); - padding: 0.2rem 0.4rem; - border-radius: 0.3rem; - margin-right: 0.5rem; - } - h4{ - font-weight: 400; - } -} -.add-upi{ - margin-top: 0.4rem; - justify-self: flex-start; - width: max-content; -} - -#transaction_page{ - header{ - padding: 0.5rem 0; - .back-arrow{ - grid-area: back; - } - h4{ - text-transform: capitalize; - } - } - h5{ - font-weight: 400; - font-family: 'Roboto', sans-serif; - opacity: 0.8; - margin-bottom: 0.4rem; - text-transform: capitalize; - } - p:last-of-type{ - margin: 2rem 0 1rem 0; - font-size: 0.9rem; - opacity: 0.8; - } - #transaction_details{ - position: relative; - margin: 1.5rem 0; - padding: 1.5rem; - background-color: rgba(var(--text-color), 0.06); - max-width: 50ch; - border-radius: 0.5rem; - .icon{ - height: 4rem; - width: 4rem; - padding: 1.2rem; - border-radius: 4rem; - margin-bottom: 2rem; - background: rgba(var(--text-color), 0.06); - } - .success{ - background: #00C853; - stroke-width: 8; - stroke: var(--background-color); - } - .flex{ - margin-bottom: 1.5rem; - align-items: baseline; - } - strong{ - font-weight: 500; - &:not(:last-of-type) + sm-button{ - margin-bottom: 1.5rem; - margin-top: -0.4rem; - } - } - strong:not(:last-of-type){ - margin-bottom: 1rem; - } - sm-button{ - width: max-content; - margin-top: 0.6rem; - } - } - .transaction-amount{ - font-size: 2rem; - font-weight: 400; - } - #transaction_time{ - right: 0; - position: absolute; - margin: 1.5rem; - } -} -#people_container{ - display: grid; - grid-template-columns: repeat(4, 1fr); - padding: 1.5rem; - gap: 2rem 0.2rem; -} -#add_person_btn{ - cursor: pointer; - display: flex; - flex-direction: column; - width: 5rem; - text-align: center; - transition: transform 0.3s; - font-size: 0.85rem; - opacity: 0.8; - font-weight: 500; - &:active{ - transform: scale(0.95); - } - .icon{ - height: 3rem; - width: 3rem; - border-radius: 2rem; - stroke-width: 10; - padding: 1rem; - background: rgba(var(--text-color), 0.06); - align-self: center; - margin-bottom: 0.6rem; - } -} -.person{ - display: flex; - flex-direction: column; - align-items: center; - cursor: pointer; - transition: transform 0.3s; - width: 5rem; - -webkit-tap-highlight-color: transparent; - &:active{ - transform: scale(0.95); - } -} -.person-initials, #person_initials{ - display: flex; justify-content: center; - height: 3rem; - width: 3rem; - font-size: 1.2rem !important; + grid-area: 1/1/3/2; + width: 2.5rem; + height: 2.5rem; + background-color: rgba(var(--text-color), 0.03); + border-radius: 0.5rem; + .icon { + fill: var(--accent-color); + } + } + &__receiver { + font-size: 0.9rem; font-weight: 500; - align-items: center; - border-radius: 2rem; - margin-bottom: 0.6rem !important; - text-transform: uppercase; + color: rgba(var(--text-color), 0.8); + } + &__time { + font-size: 0.8rem; + color: rgba(var(--text-color), 0.8); + } + &__amount { + font-size: 1rem; + font-weight: 700; + grid-area: 1/3/3/4; + &.sent { + &::before { + content: "-"; + } + } + &.received { + &::before { + content: "+"; + } + } + } } -.person-name{ - font-size: 0.85rem; - opacity: 0.8; - font-weight: 500; - text-transform: capitalize; +.fab { + position: absolute; + right: 0; + bottom: 0; + margin: 1.5rem; + box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.2); + z-index: 2; +} +#scroll_to_top { + border-radius: 3rem; + background-color: rgba(var(--foreground-color), 1); +} + +#transaction_result { + display: grid; + gap: 0.5rem; + height: max(40vh, 24rem); + align-items: center; + justify-content: center; + text-align: center; + align-content: center; + &.success { + .icon--failed { + display: none; + } + } + &.failed { + .icon--success { + display: none; + } + } + h3 { text-align: center; + width: 100%; + } + .icon { + justify-self: center; + height: 4rem; + width: 4rem; + border-radius: 5rem; + margin-bottom: 1rem; + animation: popup 1s; + &--success { + fill: rgba(var(--background-color), 1); + padding: 1rem; + background-color: #0bbe56; + } + &--failed { + background-color: rgba(var(--text-color), 0.03); + fill: var(--danger-color); + } + } + sm-copy { + font-size: 0.8rem; + } +} +@keyframes popup { + 0% { + opacity: 0; + transform: scale(0.2) translateY(600%); + } + 10% { + transform: scale(0.2) translateY(5rem); + opacity: 1; + } + 40% { + transform: scale(0.2) translateY(0); + } + 80% { + transform: scale(1.1) translateY(0); + } + 100% { + transform: scale(1) translateY(0); + } } -#person_popup{ - & > .flex:first-of-type{ - margin: 1rem 0; - .flex{ - margin-top: 0.5rem; - .icon{ - height: 2.6rem; - width: 2.6rem; - padding: 0.8rem; - cursor: pointer; - stroke-width: 8; - &:hover{ - background: rgba(var(--text-color), 0.06); - } - } - } - } - h3{ - text-transform: capitalize; - } - h5{ - font-weight: 500; - opacity: 0.8; - } - .copy-row{ - margin-bottom: 1.5rem; - } - #show_person_name{ - padding: 0.5rem 1rem; - border-radius: 0.4rem; - max-width: 30ch; - &:focus{ - outline: none; - background: rgba(var(--text-color), 0.1); - } - } +#settings { } -#activity_page, -#request_page, -#settings_page{ - .empty-state{ - justify-content: left; - } +.cashier-request, +.wallet-request, +.payment-request { + display: flex; + gap: 1rem; + align-items: center; + padding: 0.8rem; + border-radius: 0.3rem; + background-color: rgba(var(--text-color), 0.06); + &:not(:last-of-type) { + margin-bottom: 1rem; + } + &__time { + font-size: 0.8rem; + } } -#settings_page{ - h4{ - margin-top: 2rem; - margin-bottom: 0.6rem; - } - .copy-row h4{ - margin: 0; - } - p{ - color: rgba(var(--text-color), 0.7); - } - sm-button{ - margin-top: 0.8rem; - } - .flex{ - max-width: 60ch; - } - .my-qr-code{ - margin-bottom: 1.5rem; - height: 14rem; - img{ - height: 100%; - } - } +.payment-request { + display: grid; + grid-template-columns: 1fr auto; + &__amount { + font-weight: 700; + text-align: right; + } } -@media only screen and (max-width: 640px) { - #home_page, #deposit{ - display: grid; - gap: 1.5rem; - grid-template-areas: '.''left'; - grid-template-columns: minmax(0, 1fr); - .left { - grid-area: left; - } +@media screen and (min-width: 40rem) { + sm-popup { + --width: 24rem; + } + .popup__header { + grid-column: 1/-1; + padding: 1rem 1.5rem 0 1.5rem; + } + body { + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; + } + #main_card { + display: grid; + grid-template-columns: auto 1fr; + grid-template-rows: auto 1fr; + grid-template-areas: "nav header" "nav main"; + position: relative; + border-radius: 0.5rem; + overflow: hidden; + box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.05), + 0 1rem 3rem rgba(0, 0, 0, 0.2); + // backdrop-filter: blur(2rem); + background-color: rgba(var(--foreground-color), 0.9); + } + #main_header { + grid-area: header; + } + #pages_container { + grid-area: main; + } + + #main_navbar { + grid-area: nav; + border-top: none; + flex-direction: column; + height: 100%; + ul { + flex-direction: column; + gap: 0.5rem; + padding: 0.3rem; + + li:last-of-type { + margin-top: auto; + } } - sm-select { - width: 100%; - } - .hide-on-mobile{ - display: none !important; - } - #transaction_page{ - padding-top: 0; - header{ - padding: 1.5rem 0; - } - } - #deposit{ - .user-panel{ - padding: 0; - } - } - video{ - height: 100vw; + } + .nav-item { + aspect-ratio: 1/1; + &__indicator { + width: 0.25rem; + height: 50%; + left: 0; + border-radius: 0 1rem 1rem 0; + bottom: auto; } + } + #user { + grid-template-columns: 1fr 20rem; + align-content: flex-start; + align-items: flex-start; + } } - -@media only screen and (min-width: 640px) { - .hide-on-desktop{ - display: none !important; - } - body { - padding: 0 2rem; - margin-left: 4rem; - } - sm-popup{ - background: rgba(var(--foreground-color), 1); - } - sm-popup::part(popup){ - width: 24rem; - } - - #confirmation { - width: 24rem; - } - - #navbar { - justify-content: flex-start; - flex-direction: column; - align-items: stretch; - left: 0; - bottom: 0; - top: 0; - right: auto; - border-top: none; - border-radius: 0; - background: rgba(var(--text-color), 0.06); - box-shadow: -0.5rem 0 0.5rem #00000008 inset; - .navbar-item { - display: flex; - width: auto; - padding: 0.8rem 1.2rem; - .icon { - height: 1.2rem; - width: 1.2rem; - } - h5{ - display: none; - } - &:hover { - opacity: 1; - } - } - .logo{ - margin: 1.5rem 1rem; - h4{ - display: none; - } - .main-logo{ - height: 1.2rem; - width: 1.2rem; - } - } - .active{ - background: rgba(var(--text-color), 0.06); - } - } - - .page { - padding-bottom: 2rem; - } - - #sign_in_popup { - width: 24rem; - } - #home_page { - padding-top: 0.5rem; - .left { - margin-top: 1rem; - } - } - .options-tab, #people_container{ - grid-template-columns: repeat(auto-fill, minmax(5rem, 1fr)); - gap: 2rem 0.8rem; - } - .display-balance{ - .balance{ - height: 9rem; - } - } - .request{ - grid-template-columns: minmax(0, auto) auto; - grid-template-areas: 'time time' ' . .' ' . .'; - .time{ - grid-area: time; - margin-bottom: 0 !important; - } - button{ - width: max-content; - margin-left: auto; - } - .breakable{ - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - } - #deposit{ - .user-panel{ - padding-right: 0; - } - } - #settings_page{ - .copy-row{ - display: inline-grid; - } - } -} - -@media only screen and (min-width: 800px) { - body { - margin-left: 11rem; - } - .complaint { - gap: 0 1.5rem; - grid-template-columns: 1fr 1fr; - grid-template-areas: '. . ''header header'; - - .complaint-actions { - grid-area: header; - } - - .left { - border-right: 1px solid rgba(var(--text-color), 0.2); - padding-right: 1.5rem; - } - - .right { - display: flex; - justify-content: center; - flex-direction: column; - } - } - #navbar{ - .navbar-item { - h5{ - font-size: 0.9rem; - margin: 0; - display: block; - } - } - .icon{ - margin-right: 0.8rem; - } - .logo{ - h4{ - display: block; - font-size: 1rem; - } - } - } - .user-panel{ - position: sticky; - top: 1.5rem; - padding-top: 1.5rem; - } - #home_page, #deposit { - display: grid; - gap: 1.5rem; - grid-template-columns: minmax(0, 1fr) 22rem; - } - #deposit{ - grid-template-columns: minmax(0, 1fr) 18rem; - .user-panel{ - padding-right: 0; - } - } - .activity{ - width: 60ch; - } - .request{ - grid-template-columns: minmax(0, auto) auto; - grid-template-areas: 'time time' ' . .' ' . .'; - } -} - -@media only screen and (min-width: 1280px) { - .request{ - grid-template-areas: 'time time time' '. . .'; - } - #deposit{ - grid-template-columns: minmax(0, 1fr) 20rem; - .request{ - grid-template-areas: 'time time time time' '. . . .'; - } - } -} - -@media only screen and (max-width: 320px) { - body { - font-size: 14px; - } +@media screen and (min-width: 56rem) { + #main_card { + height: 80vh; + width: 56rem; + } } @media (any-hover: hover) { - .navbar-item:hover{ - background: rgba(var(--text-color), 0.06); + ::-webkit-scrollbar { + width: 0.5rem; + height: 0.5rem; + } + + ::-webkit-scrollbar-thumb { + background: rgba(var(--text-color), 0.3); + border-radius: 1rem; + + &:hover { + background: rgba(var(--text-color), 0.5); } - .remove{ - opacity: 0.6; + } + .interact:not([disabled]) { + transition: background-color 0.3s; + &:hover { + background-color: rgba(var(--text-color), 0.06); } - .remove:hover{ - opacity: 1; + } + .button:not([disabled]) { + transition: background-color 0.3s, filter 0.3s; + &:hover { + filter: contrast(2); } + } +} + +@supports (overflow: overlay) { + body { + overflow: overlay; + } +} + +.hide { + display: none !important; } diff --git a/css/sign-in-bg.svg b/css/sign-in-bg.svg new file mode 100644 index 0000000..077c111 --- /dev/null +++ b/css/sign-in-bg.svg @@ -0,0 +1 @@ +sign-in-bg \ No newline at end of file diff --git a/css/success-art.svg b/css/success-art.svg new file mode 100644 index 0000000..7fc5986 --- /dev/null +++ b/css/success-art.svg @@ -0,0 +1 @@ +success-art \ No newline at end of file diff --git a/css/welcome.svg b/css/welcome.svg new file mode 100644 index 0000000..2dead8d --- /dev/null +++ b/css/welcome.svg @@ -0,0 +1 @@ +welcome \ No newline at end of file diff --git a/favicon.png b/favicon.png new file mode 100644 index 0000000..bf699cb Binary files /dev/null and b/favicon.png differ diff --git a/favicon.svg b/favicon.svg new file mode 100644 index 0000000..8e56357 --- /dev/null +++ b/favicon.svg @@ -0,0 +1 @@ +favicon \ No newline at end of file diff --git a/favicon_1.png b/favicon_1.png new file mode 100644 index 0000000..346c89a Binary files /dev/null and b/favicon_1.png differ diff --git a/logo.ai b/logo.ai new file mode 100644 index 0000000..a663314 --- /dev/null +++ b/logo.ai @@ -0,0 +1,2047 @@ +%PDF-1.5 %âãÏÓ +1 0 obj <>/OCGs[5 0 R 27 0 R 48 0 R 69 0 R 90 0 R 113 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + application/pdf + + + Web + + + Adobe Illustrator CC 23.0 (Windows) + 2020-11-14T20:51+05:30 + 2020-11-23T01:48:57+05:30 + 2020-11-23T01:48:57+05:30 + + + + 256 + 84 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAVAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8Agf8AzkB/zkB5k80+ZL/Q 9Dv5bHyrYyvbIls5ja7aMlHlldDVkY14JXjxoSK4q8QxV2KuxV2KuxV2KuxV2Kp55T87+a/KOpR6 j5d1OfT7lGDMI2PpyU/ZliNUkX2YHFX6A/k3+ZMH5h+RbTzAI1gvQzWup26fZjuogC4WpJ4srK61 3oRirN8Vec+bvNV1cXctnaymK0iYoeBoZCNiSR28BnQaLRxjESkLkfsfJfaX2iy580sOKRjiia2/ iI535dw+LD5ZM2LycYoSWTFyIxQksmByIxQksmLkRihJZMXIjFCSyYHIjFCSyYuRGKElkxciMVTS /MOsaNdrd6XdyWs6mtY22anZl+yw9iMryY4zFSFubp8s8ZuJovpj8ufOSebPLcWosojvImMF7Ev2 RKoBqvU8WVgR93bOc1WDwp10e10Oq8bHxderJ8x3MdirsVdirsVdirsVdirsVflXirsVekflZ+Q/ m/8AMrT76+0K80+2i0+VYJlvpJo2LOvIFfShmFKeJGKs4/6Eq/NP/q66H/0kXn/ZJirv+hKvzT/6 uuh/9JF5/wBkmKoe8/5wz/Nq3j5xXWkXbb/u4bmYN/yVgiX8cVeY+c/yt8/+S3H+JNFuLGFjxS7o stux7ATxF46nw5VxViuKuxV2Kvsr/nCX/lAdd/7ap/6hosVfRWKvD7yT9/J/rN+vOvjyD8+ZI+s+ 8oCWTJNkYoSWTA5EYsm0j8tdY1fTINQiuYIo7gFkSTnyADEb0UjelcwM3aEISMSDs9VofZnNnxRy CUQJd9/qVn/JrXm6X1r/AMlP+acq/lSHcXPHslnH8cPt/Uov+SfmFul/af8AJT/mjH+VIdxbR7K5 h/FH7f1IeX8jPMpU8L+zLdgTKB9/A4/ypDuLYPZnMP4o/b+ph3mfyB5s0CNp76yLWi9bqA+rGP8A WK7r/sgMysWrx5Ngd3Dz9l5sO8ht3jcMQlkzJaYxQksmByIxe4f841ys2n67GT8KzQMB7srg/wDE Rmm7U5xel7F+mXwez5qndOxV2KsR/MH8zdB8iw2UurwXU637SJCLRI3IMQUnl6kkX8+1MytNpJZr 4a272MpUwv8A6Gk/L/8A6t+rf8ibb/sozL/kjL3x+39THxA9H1Xzr5Z0fR7fVtXv49PtLpFkhE5/ eMHUNRY15MzAHcKDmBDTznLhiLIZkhhzf85FflaJvTF9Oyf79FtLx/FeX4ZlfyXm7vtY+IGU+XPz G8keZJBFo2sQXU53W3JaKYgeEUoRz92Y+XS5Mf1RpkJAsjzHS/KvFXYq+wP+cIf+UV8y/wDMdD/y ZxV9KYq7FXYqo3tlZ31pLZ3sEdzaXCmOe3mUPG6NsVZWBBB98VfFX/OS/wCQtv5Huo/MvluJh5Zv 5PSntalvqdw1SFBO/pSU+GvQ7d1xV4NirsVfZX/OEv8AygOu/wDbVP8A1DRYq+isVeDXkn7+X/Wb 9edfHkHwKcfWfeUBLJhbIxQkjkmg3J6DFyYRfRGkWf1HSrOzpQ28McZp4qoB/HOTyz4pE95faNJh 8LFCH82IH2N6pqVtpmnXOoXJPoWsbSycdyQorQVpue2DHAykIjqzz5o4oGcuURaX6j5v0OwttMu5 rgfVNUlWK3uAfgHNCwdiei7AHwrv3yyGnnIkAbxaMuvxQjCRPpmaBTrKHMaZVdSjgMrAhlIqCD1B GKkPnL86vIlv5c1OLUtOQR6VqJYeguywzKKsqjsrD4lHbcdKZv8AQak5I0fqDynaehGKfFH6ZfYX lksmZ7gxi90/5xkatl5g/wCMtt/xGTNP2pzj8XoeyBtL4Pbc1LuHYq7FXgv/ADld/wAc/wAuf8Zb r/iMWbrsbnL4NWV86ZvmlGapq+p6rc/WtRuZLqcKsavIxPFEFFRR0VQOgG2RhARFAUklB5JCN0u3 le4WdSyLCwYSKSp5A1HEjevywiNuBr9YMMdvrPL9b6d/Jj81LnW2Hl7XJfU1NELWV232p0QVZH8Z FArX9oddxvoO1Ozxj9cPp6juYdk9pHJ+7n9XQ9/7XwNmld67FX2B/wA4Q/8AKK+Zf+Y6H/kzir6U xV+YP+LPNX/V5vv+kmb/AJqxVOfLX5t/mT5bvUutK8xX0ZVgzW8szzwP/rwyl42+kVxV95fk/wDm HH+YHkLT/MZiWC7k5QX9uleKXEJ4vxqSeLbOtT0IxVW/Nry9b+Yfy08y6TOoYTafO8PLcCaFDNC3 +xljU4q/NjFXYq+yv+cJf+UB13/tqn/qGixV9FYq+fb2T/SJf9dv1518eQfCZx9Z95QEsmFsjFF+ V7T6/wCZdNtaVV7hC4/yEPN/+FU5RqZ8OOR8nbdlafxNRCP9IfIbl9DZyz64wb85NS+p+S5IQaNe zRwDxoD6p/5N5n9nQvLfcHSe0GXh0xH84gfp/Q8FutYv5tOg06SYvZ2rySQRHorS05U9vh6fPxze iAEjLqXjRkkYCBPpjy+L2H8nfzDGpwL5d1OWuoW6f6FK53miUfY36ug+9fkc03aGl4Txx5Hm9d2N 2hxx8Of1Dl5j9j1LNY795z+f0ML/AJeTSSEBoLmCSKv8xYpt/sXOZ3Zx/e/B13akQcPxD5blkzoH noxe8/8AOLzVsfMP/GW2/wCIyZpu1Ocfi73ssbS+D3HNU7V2KuxV4L/zld/xz/Ln/GW6/wCIxZuu xucvg1ZXzpm+aX05+UP5F+XrXQ7TW/M1mmoapeos8dpOOcEEbjkimM/C7lTVudQOgG1Tz2t7RmZG MDQDfCHe9F1T8tfIOp2ptrvQLH0yKBooEhkWv8skQR1+g5gQ1eWJsSLMxD5u/MjyJF5L8xHTLV2k 0+WNbiyd6F/TYlSrkbFlZSM6vs/U+NjvqNi8Z2vilDObN3uPd3JJoWqzaTrVjqcBIks545hTvwYE j6RtmTmxicDE9Q4GHIYTEh0L57zg30N2KvsD/nCH/lFfMv8AzHQ/8mcVfSmKvyrxVM/L3lnzD5j1 FNO0LTp9SvZCAIbdC5FTSrkbIvizEAYq/QP8jfy8ufIP5c2GhXrK2puz3eo8DVBPMalFPfggVK96 VxVN/wAz9at9E/LrzJqk5AW3065KBujSPGUjTt9qRlXFX5pYq7FX2V/zhL/ygOu/9tU/9Q0WKvor FXzpfSf6RL/rt+vOvjyD4fOPrPvS+WTC2xizD8obP6z5sa5I+Gzt3kB8GekY/wCFZs13aU6x13l6 n2XwcWp4v5sT9u363teaB9CeN/n1qLyX2k6VFVnVHnaNdyTKwRNh/qNm57LjQlJ5T2inxThAe/57 foeX2Xl/W9R1j9DWlo76iHMckFKGMqaP6hOyhT1rmynmjGPETs6XDpZznwAep79+X35YaX5WiW6n 43mtOv7y6I+GOo3SEHoPFup9htmg1Wsll2G0XstB2bDALO8+/wDUzbMN2bxn/nJXzDFBomnaEjfv 7ub61MoO4ihBVajwZ32/1c2nZmO5GXc6rtTJ6RHv3fOUsmbp1MYvff8AnFhq2PmL/jLa/wDEZc03 anOPxdz2cKBe7ZqnZOxV2KvBf+crv+Of5c/4y3X/ABGLN12Nzl8GrK+dM3zS+9fLv/KP6Z/zCQf8 m1zisv1H3uUERf6jYafbPdX1xHa20Yq80zBFH0tTBCEpGoiyxnkjEXI0Hy9+bnnOz81eajc2FTp9 nELW2kIoZArMzSUO4DFtvYZ1/ZulOHHUvqO7xnamrGfLcfpApiel2E2o6laafAKzXc0cEY/ypGCj 9eZuSYjEyPQODjgZyERzJeAZwL6I7FX2B/zhD/yivmX/AJjof+TOKvc/P3njR/JXlm513VCXSKkd raR7zXNw+0UES93c/cKnoMVeZf8AOOf5D23krQf0z5htY5fNOqRj1Y5VVxaQH4hAtajmdjIfHbtu q9rhghhThDGsSdeKAKKn2GKrmZVUsxCqoqzHYADFXx1/zlP+eun+Zinkvyxcrc6NayiXVdQjNY7i eMnhFGejRxn4i3RmpTZalV844q7FX2V/zhL/AMoDrv8A21T/ANQ0WKvorFXzXfSf6TN/rt+vOujy D4tOPqPvS+WTJNkYvV/yPsaafqeoEf30yQKfaJeR/wCTgzSdqz9Qi917LYaxzn3mvl/a9NzVPVpK vlPSz5kl8w3C/WL8okVqZACsCItP3Y/mZqnl70Hvd48uDgHL73FGjh4pyneXTyVPL3lfStCimFnH W5unaa8u33llkYkksfCp2UbDBlzSnz5Blp9LDEDw8zzPem2VOQkPnHzroXlPSnv9UmAYgi2tVIMs zgfZRf1noO+XYcEshoNOfPHGLL5E84+a9R8z69daxfn97OaJEp+GONdkjX2Uff1zo8OIY4iIedyZ DkkZFjksmWM4xfQX/OKTVsPMn/GW1/4jLmn7U5x+Lt9CKBe9ZqnOdirsVeC/85Xf8c/y5/xluv8A iMWbrsbnL4NWV86Zvml7h+ZP5mTalp9h5c0mVo9PsoIVvJkJUzTpGoK7fsRn7zv2GYPZ+gECckvq PLyDz3avaPGfDgfSOfmXnMs80tPVkaSnTkSaffm2AAdISTzU8KHuX5IfljeW1zH5p1mEwlVP6LtZ BR6uKGZ1PQcT8Ffn4Zz3auvBHhwPv/U9L2P2cQfFmPcP0/qfDGc+9G7FX2B/zhD/AMor5l/5jof+ TOKst8z+T/zX1X80IfM82laVqmiaIGXy1pVzfywrFKSK3syrbyh5mp8I6JtSpHLFXmX/AEPHqv8A 1KMH/Sa//VHFUNe/85v+ZnjIsfLFlBJQ0aeeWZa9vhVYf14q8s8+/n7+Z/neB7PVdU+raXJUPpti v1eBgeoehMki+zuwxV53irsVdir7K/5wl/5QHXf+2qf+oaLFX0Vir5iv5P8ASpv9dv1510eT45KP qPvS+WTC2xi+gvyusPqfkjTgRR7gPcP7+o5K/wDCcc5vXT4sp8n0nsTDwaWPnv8AP9jKyQBU7AdT mI7V5NN/zkPocbsq6VcuoJCtzQVA75tB2XLvDov5dh/NKHk/5yR0VVPHRrhm7AyoBX50OP8AJcv5 wZDtqJ/hLGNf/wCckPMVwjR6Pp8GnA7CaVjcyD3WojQfSpy/H2ZAfUba59rTl9Ir7Xkmt67qur3r 3up3ct5dP9qWVixp4CvQDsBtmwhARFAUHDMpTNyNlKJZMm2xihJZMDkRi+h/+cTGrYeZf+M1r/xG XNP2pzj8XZ6QUC9+zVOW7FXYq8F/5yu/45/lz/jLdf8AEYs3XY3OXwasr54gkWOQOyc+O4Umgrm/ BcPPjM4GIPDb6Q03/nHWzvNOtbs65IhuYY5Sgt1NOahqV9TtXNNPtsgkcP2/sdcOwI/z/s/ajIf+ cbNLDgza3O8fdUhRD95Z/wBWQPbkukR82Q7Aj1mfkzHyz+UHkjy/KlxDaG9vIzVLm8YSsp61VAFj BHY8a++YOftLNkFE0PJz9P2XhxGwLPefxTNMwHYvyrxV2KvsD/nCH/lFfMv/ADHQ/wDJnFX0pir8 q8VdirsVdirsVdir7K/5wl/5QHXf+2qf+oaLFX0Vir5Zv5P9Km/12/Wc66PJ8jlH1H3oGjyypFGO TyMFRR3JNAMJNN2OBJoPqzTrNLLT7Wyj+xbRJClPCNQo/VnJTlxEnvfUsWMQgIjoKSvzzqn6L8n6 xfBuLxWsgibwkdeCf8OwyzTw4skR5tWsycGGR8nyJLJnUPExihJZMXIjFCSyYuRGKElkxciMUJLJ gciMUJLJi5EYvov/AJxFaun+Zv8AjNaf8RlzT9qc4/Fz9OKBfQeapyHYq7FXgv8Azld/xz/Ln/GW 6/4jFm67G5y+DVlfOmb5pfevl3/lH9M/5hIP+Ta5xWX6j73KCYZBLsVdir8q8Vdir33/AJx5/O/y j+Wvk/X01ZZ7rU7u6jkstPt03dVi48mlakaLy67k+CnFUi/MT/nKH8yvN3qWtlcf4d0l6j6pp7MJ WU9pbnaRttjx4qfDFXj+KuxV2KuxV2KuxV9lf84S/wDKA67/ANtU/wDUNFir6KxV8oahJ/pc/wDx kb/iRzro8nymUfUfeifKUunr5q0uTUJlgsobhJppZNlAiPOh+ZWmVai/DNc6c/s8RGaJkaiDfyfQ B/MzyEOut233n+mc/wDk8v8ANL3X8o4P54YH+cv5heW9Q8mtp2kajFeT3VxEs0cRNRElZCxqP50X MzQ6acclyFUHA7T1mOeLhgbsvAZZM3LooxQksmLkRig5ZMXIjFCSyYHIjFCSyYuRGKElkxciMX0j /wA4ftXT/M//ABmtP+Iy5p+1Ocfi5mIUH0PmqbXYq7FXl353/lz5g88HQbTSfSjjtpLhru5nbika uIwuwq7E8TQAfOmbHs/VRw8Rl5MJxtb5K/5x58l6CI7nVFOuailDyuFpbq3+TBUg/wCzLYdR2nkn tH0j7fmoxgPUlVVUKoCqooqjYADsM1rNvFXYq7FX5j+d/KepeUfNep+XdRjZLnT52jDMKepHWsUq /wCTIhDD54qkeKuxV2KuxV2KuxV2KuxV2Kvub/nEXynqWhfla15qEbQvrl49/bRMKH6v6aRxsR1+ P0yw/wAkjFXt2KvlfzdpV1o2v32n3KlXilYox/bjY1Rx7MudVgyCcAQ+barTSxZZRPQsflky1EYo OWTA5EYoSWTFyIxQksmLkRihJZMXIjFCSyYHIjFCSyYuRGKElkxciMUJLJi5EYvrf/nFTytfaV5F utWvIjE2t3AmtlYUY28S8EfxozFyPbfvmi7RyCU6HRyIh7VmvZOxV2KuxV2KuxV2KuxV2KvEf+ck v+VFfUbf/lYHqfpn0z+j/wBF8f0p6VW+zy+D0+Vaet8Nem9cVfLP/IAv+/q/7l2Ku/5AF/39X/cu xV3/ACAL/v6v+5dirv8AkAX/AH9X/cuxV3/IAv8Av6v+5dirv+QBf9/V/wBy7FXf8gC/7+r/ALl2 Ku/5AF/39X/cuxVnH5Tf9Cuf4lg/TH6X9b1B9V/Tv1f9Hcv2fV+re/8Avz4PHFX21H6fpr6dPToO HGnHjTalO2KrsVYH+an/ACr76jH/AIn5fWuJ+qfVafW6V34duNf5/hr75naLxr9HLz5Oo7V/LcI8 X6ulfV+Pfs8Tl/5VnU/8dqn/AEaZuP339H7Xno/lf6f+xQ0n/KsO/wCnP+nTH99/R+1uj+X/AKf2 IaT/AJVZ3/Tv/Tng/ff0ftb4+B/T+xDSf8qo7/p7/pzx/ff0ftbo+D/S+xDSf8qk7/4g/wCnLH99 /R+1vj4X9L7ENJ/yqDv/AIh/6csf339H7W6Ph+aGk/5U53/xF/044/vv6P2t8eDzQ0n/ACpjv/iT /pxwfvv6P2t0eFkX5ef9C5f4gh/TP6W+0PQ/S/ofUeVdvV+rfF1/n+D+bKc/5jh2r4c2+NPsKD0P Qj+r8fQ4j0vTpw4U+HjTalOlM0RbF+BXYq7FXYq7FXYq7FXYq7FX/9k= + + + + proof:pdf + uuid:65E6390686CF11DBA6E2D887CEACB407 + xmp.did:6806a576-4fee-6d49-9e48-d75b54c46a40 + uuid:e68512b5-97fb-412e-afd9-b665975faa8c + + uuid:ddb85511-449e-4847-a808-d8e6c44f424f + xmp.did:3bd35275-b3c2-5f4a-88f4-4e9fdeff5904 + uuid:65E6390686CF11DBA6E2D887CEACB407 + proof:pdf + + + + + saved + xmp.iid:78d668e8-f910-f343-a1fd-84a62851bbc3 + 2020-11-13T20:22:34+05:30 + Adobe Illustrator CC 23.0 (Windows) + / + + + saved + xmp.iid:6806a576-4fee-6d49-9e48-d75b54c46a40 + 2020-11-14T20:51+05:30 + Adobe Illustrator CC 23.0 (Windows) + / + + + + Web + Document + 1 + False + False + + 128.000000 + 128.000000 + Pixels + + + + Cyan + Magenta + Yellow + Black + + + + + + Default Swatch Group + 0 + + + + White + RGB + PROCESS + 255 + 255 + 255 + + + Black + RGB + PROCESS + 0 + 0 + 0 + + + RGB Red + RGB + PROCESS + 255 + 0 + 0 + + + RGB Yellow + RGB + PROCESS + 255 + 255 + 0 + + + RGB Green + RGB + PROCESS + 0 + 255 + 0 + + + RGB Cyan + RGB + PROCESS + 0 + 255 + 255 + + + RGB Blue + RGB + PROCESS + 0 + 0 + 255 + + + RGB Magenta + RGB + PROCESS + 255 + 0 + 255 + + + R=193 G=39 B=45 + RGB + PROCESS + 193 + 39 + 45 + + + R=237 G=28 B=36 + RGB + PROCESS + 237 + 28 + 36 + + + R=241 G=90 B=36 + RGB + PROCESS + 241 + 90 + 36 + + + R=247 G=147 B=30 + RGB + PROCESS + 247 + 147 + 30 + + + R=251 G=176 B=59 + RGB + PROCESS + 251 + 176 + 59 + + + R=252 G=238 B=33 + RGB + PROCESS + 252 + 238 + 33 + + + R=217 G=224 B=33 + RGB + PROCESS + 217 + 224 + 33 + + + R=140 G=198 B=63 + RGB + PROCESS + 140 + 198 + 63 + + + R=57 G=181 B=74 + RGB + PROCESS + 57 + 181 + 74 + + + R=0 G=146 B=69 + RGB + PROCESS + 0 + 146 + 69 + + + R=0 G=104 B=55 + RGB + PROCESS + 0 + 104 + 55 + + + R=34 G=181 B=115 + RGB + PROCESS + 34 + 181 + 115 + + + R=0 G=169 B=157 + RGB + PROCESS + 0 + 169 + 157 + + + R=41 G=171 B=226 + RGB + PROCESS + 41 + 171 + 226 + + + R=0 G=113 B=188 + RGB + PROCESS + 0 + 113 + 188 + + + R=46 G=49 B=146 + RGB + PROCESS + 46 + 49 + 146 + + + R=27 G=20 B=100 + RGB + PROCESS + 27 + 20 + 100 + + + R=102 G=45 B=145 + RGB + PROCESS + 102 + 45 + 145 + + + R=147 G=39 B=143 + RGB + PROCESS + 147 + 39 + 143 + + + R=158 G=0 B=93 + RGB + PROCESS + 158 + 0 + 93 + + + R=212 G=20 B=90 + RGB + PROCESS + 212 + 20 + 90 + + + R=237 G=30 B=121 + RGB + PROCESS + 237 + 30 + 121 + + + R=199 G=178 B=153 + RGB + PROCESS + 199 + 178 + 153 + + + R=153 G=134 B=117 + RGB + PROCESS + 153 + 134 + 117 + + + R=115 G=99 B=87 + RGB + PROCESS + 115 + 99 + 87 + + + R=83 G=71 B=65 + RGB + PROCESS + 83 + 71 + 65 + + + R=198 G=156 B=109 + RGB + PROCESS + 198 + 156 + 109 + + + R=166 G=124 B=82 + RGB + PROCESS + 166 + 124 + 82 + + + R=140 G=98 B=57 + RGB + PROCESS + 140 + 98 + 57 + + + R=117 G=76 B=36 + RGB + PROCESS + 117 + 76 + 36 + + + R=96 G=56 B=19 + RGB + PROCESS + 96 + 56 + 19 + + + R=66 G=33 B=11 + RGB + PROCESS + 66 + 33 + 11 + + + + + + Grays + 1 + + + + R=0 G=0 B=0 + RGB + PROCESS + 0 + 0 + 0 + + + R=26 G=26 B=26 + RGB + PROCESS + 26 + 26 + 26 + + + R=51 G=51 B=51 + RGB + PROCESS + 51 + 51 + 51 + + + R=77 G=77 B=77 + RGB + PROCESS + 77 + 77 + 77 + + + R=102 G=102 B=102 + RGB + PROCESS + 102 + 102 + 102 + + + R=128 G=128 B=128 + RGB + PROCESS + 128 + 128 + 128 + + + R=153 G=153 B=153 + RGB + PROCESS + 153 + 153 + 153 + + + R=179 G=179 B=179 + RGB + PROCESS + 179 + 179 + 179 + + + R=204 G=204 B=204 + RGB + PROCESS + 204 + 204 + 204 + + + R=230 G=230 B=230 + RGB + PROCESS + 230 + 230 + 230 + + + R=242 G=242 B=242 + RGB + PROCESS + 242 + 242 + 242 + + + + + + Web Color Group + 1 + + + + R=63 G=169 B=245 + RGB + PROCESS + 63 + 169 + 245 + + + R=122 G=201 B=67 + RGB + PROCESS + 122 + 201 + 67 + + + R=255 G=147 B=30 + RGB + PROCESS + 255 + 147 + 30 + + + R=255 G=29 B=37 + RGB + PROCESS + 255 + 29 + 37 + + + R=255 G=123 B=172 + RGB + PROCESS + 255 + 123 + 172 + + + R=189 G=204 B=212 + RGB + PROCESS + 189 + 204 + 212 + + + + + + + Adobe PDF library 15.00 + + + + + + + + + + + + + + + + + + + + + + + + + +endstream endobj 3 0 obj <> endobj 7 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/Thumb 75 0 R/TrimBox[0.0 0.0 128.0 128.0]/Type/Page>> endobj 92 0 obj <>/Resources<>/ExtGState<>/Properties<>/Shading<>>>/TrimBox[0.0 0.0 128.0 128.0]/Type/Page>> endobj 115 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 128.0 128.0]/Type/Page>> endobj 122 0 obj <>stream +H‰TRËŽ1 ¼ç+üíñ#ÎãÊ,â´B+|@ ¸°HËH|ÿ–­fP«”ívÙå¾|½Òåù*ôééJå­©õiþþ(ßéO¹\¿ 7Ö‘flt'ºˆ~Aô×­¼‘’àQÁS¤’вY(¯%#¯åPåPEõÊA¿ž}c™3Y¹¶dwîÖÖ)¢ëôátâ‹Î£<ÂÖ+®ìNÇ`Cš7ˆ™p¸ÂoÁuÒ#Dñ÷x7–ÕOGÂc>8ךÐûýÚxúàØ°¢óaFEÿ6Xa(OCyÈÕYÆ1PE¶\gùY^R”uØŠ¥ë]ÏÙ¹Ò;ŠÖ¸«)”jØÜṳ́{Nãi2„ï©¶ÍÖÁµ;[ü}ãʞꃰ¯á&7_ÛÖ{ØÙ0][[øÐÉúÎñq—µ¹uE+º7´TõŪ•G¬,M*øöB ªRî<ŘùÑ]´ÏÏøi_Ê»ѹˆ4 +endstream endobj 113 0 obj <> endobj 123 0 obj [/View/Design] endobj 124 0 obj <>>> endobj 119 0 obj <> endobj 118 0 obj [/ICCBased 125 0 R] endobj 125 0 obj <>stream +H‰œ–yTSwÇoÉž•°Ãc [€°5la‘QIBHØADED„ª•2ÖmtFOE.®c­Ö}êÒõ0êè8´׎8GNg¦Óïï÷9÷wïïÝß½÷ó '¥ªµÕ0 Ö ÏJŒÅb¤  + 2y­.-;!à’ÆK°ZÜ ü‹ž^i½"LÊÀ0ðÿ‰-×é @8(”µrœ;q®ª7èLöœy¥•&†Qëñq¶4±jž½ç|æ9ÚÄ +V³)gB£0ñiœWו8#©8wÕ©•õ8_Å٥ʨQãüÜ«QÊj@é&»A)/ÇÙgº>'K‚óÈtÕ;\ú” Ó¥$ÕºF½ZUnÀÜå˜(4TŒ%)ë«”ƒ0C&¯”阤Z£“i˜¿óœ8¦Úbx‘ƒE¡ÁÁBÑ;…ú¯›¿P¦ÞÎӓ̹žAü om?çW= +€x¯Íú·¶Ò-Œ¯Àòæ[›Ëû0ñ¾¾øÎ}ø¦y)7ta¾¾õõõ>j¥ÜÇTÐ7úŸ¿@ï¼ÏÇtÜ›ò`qÊ2™±Ê€™ê&¯®ª6ê±ZL®Ä„?â_øóyxg)Ë”z¥ÈçL­UáíÖ*ÔuµSkÿSeØO4?׸¸c¯¯Ø°.òò· åÒR´ ßÞô-•’2ð5ßáÞüÜÏ ú÷Sá>Ó£V­š‹“då`r£¾n~ÏôY &à+`œ;ÂA4ˆÉ 䀰ÈA9Ð=¨- t°lÃ`;»Á~pŒƒÁ ðGp| ®[`Lƒ‡`<¯ "A ˆ YA+äùCb(ЇR¡,¨*T2B-Ð +¨ꇆ¡Ðnè÷ÐQètº}MA ï —0Óal»Á¾°ŽSàx ¬‚kà&¸^Á£ð>ø0|>_ƒ'á‡ð,ÂG!"F$H:Rˆ”!z¤éF‘Qd?r 9‹\A&‘GÈ ”ˆrQ ¢áhš‹ÊÑ´íE‡Ñ]èaô4zBgÐ×Á–àE#H ‹*B=¡‹0HØIøˆp†p0MxJ$ùD1„˜D, V›‰½Ä­ÄÄãÄKÄ»ÄY‰dEò"EÒI2’ÔEÚBÚGúŒt™4MzN¦‘Èþär!YKî ’÷?%_&ß#¿¢°(®”0J:EAi¤ôQÆ(Ç()Ó”WT6U@ æP+¨íÔ!ê~êêmêæD ¥eÒÔ´å´!ÚïhŸÓ¦h/èº']B/¢éëèÒÓ¿¢?a0nŒhF!ÃÀXÇØÍ8ÅøšñÜŒkæc&5S˜µ™˜6»lö˜Iaº2c˜K™MÌAæ!æEæ#…寒°d¬VÖë(ëk–Íe‹Øél »—½‡}Ž}ŸCâ¸qâ9 +N'çÎ)Î].ÂuæJ¸rî +î÷ wšGä xR^¯‡÷[ÞoÆœchžgÞ`>bþ‰ù$á»ñ¥ü*~ÿ ÿ:ÿ¥…EŒ…ÒbÅ~‹ËÏ,m,£-•–Ý–,¯Y¾´Â¬â­*­6X[ݱF­=­3­ë­·YŸ±~dó ·‘ÛtÛ´¹i ÛzÚfÙ6Û~`{ÁvÖÎÞ.ÑNg·Åî”Ý#{¾}´}…ý€ý§ö¸‘j‡‡ÏþŠ™c1X6„Æfm“Ž;'_9 œr:œ8Ýq¦:‹ËœœO:ϸ8¸¤¹´¸ìu¹éJq»–»nv=ëúÌMà–ï¶ÊmÜí¾ÀR 4 ö +n»3Ü£ÜkÜGݯz=Ä•[=¾ô„=ƒ<Ë=GTB(É/ÙSòƒ,]6*›-•–¾W:#—È7Ë*¢ŠÊe¿ò^YDYÙ}U„j£êAyTù`ù#µD=¬þ¶"©b{ųÊôÊ+¬Ê¯: !kJ4Gµm¥ötµ}uCõ%—®K7YV³©fFŸ¢ßY Õ.©=bàá?SŒîƕƩºÈº‘ºçõyõ‡Ø Ú† žkï5%4ý¦m–7Ÿlqlio™Z³lG+ÔZÚz²Í¹­³mzyâò]íÔöÊö?uøuôw|¿"űN»ÎåwW&®ÜÛe֥ﺱ*|ÕöÕèjõê‰5k¶¬yÝ­èþ¢Ç¯g°ç‡^yïkEk‡Öþ¸®lÝD_pß¶õÄõÚõ×7DmØÕÏîoê¿»1mãál {àûMśΠnßLÝlÜ<9”úO¤[þ˜¸™$™™üšhšÕ›B›¯œœ‰œ÷dÒž@ž®ŸŸ‹Ÿú i Ø¡G¡¶¢&¢–££v£æ¤V¤Ç¥8¥©¦¦‹¦ý§n§à¨R¨Ä©7©©ªª««u«é¬\¬Ð­D­¸®-®¡¯¯‹°°u°ê±`±Ö²K²Â³8³®´%´œµµŠ¶¶y¶ð·h·à¸Y¸Ñ¹J¹Âº;ºµ».»§¼!¼›½½¾ +¾„¾ÿ¿z¿õÀpÀìÁgÁãÂ_ÂÛÃXÃÔÄQÄÎÅKÅÈÆFÆÃÇAÇ¿È=ȼÉ:ɹÊ8Ê·Ë6˶Ì5̵Í5͵Î6ζÏ7ϸÐ9кÑ<ѾÒ?ÒÁÓDÓÆÔIÔËÕNÕÑÖUÖØ×\×àØdØèÙlÙñÚvÚûÛ€ÜÜŠÝÝ–ÞÞ¢ß)߯à6à½áDáÌâSâÛãcãëäsäü儿 æ–çç©è2è¼éFéÐê[êåëpëûì†ííœî(î´ï@ïÌðXðåñrñÿòŒóó§ô4ôÂõPõÞömöû÷Šøø¨ù8ùÇúWúçûwüü˜ý)ýºþKþÜÿmÿÿ ÷„óû +endstream endobj 117 0 obj <> endobj 126 0 obj <> endobj 127 0 obj <>stream +%!PS-Adobe-3.0 +%%Creator: Adobe Illustrator(R) 17.0 +%%AI8_CreatorVersion: 23.0.5 +%%For: (sairaj mote) () +%%Title: (logo.ai) +%%CreationDate: 11/23/2020 1:48 AM +%%Canvassize: 16383 +%%BoundingBox: 0 -128 394 0 +%%HiResBoundingBox: 0.000000000060936 -127.99999999994 393.62001220703 -0.000000000060027 +%%DocumentProcessColors: Cyan Magenta Yellow Black +%AI5_FileFormat 13.0 +%AI12_BuildNumber: 625 +%AI3_ColorUsage: Color +%AI7_ImageSettings: 0 +%%RGBProcessColor: 0 0 0 ([Registration]) +%AI3_Cropmarks: 296 -128 424 0 +%AI3_TemplateBox: 64.5 -64.5 64.5 -64.5 +%AI3_TileBox: 62.3622131347656 -484.97509765625 657.682220458984 356.944885253906 +%AI3_DocumentPreview: None +%AI5_ArtSize: 14400 14400 +%AI5_RulerUnits: 6 +%AI9_ColorModel: 1 +%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 +%AI5_TargetResolution: 800 +%AI5_NumLayers: 1 +%AI9_OpenToView: -78.1199999999999 103.320000000001 1.38888888888889 990 602 18 0 0 78 121 0 0 0 1 1 0 1 1 0 1 +%AI5_OpenViewLayers: 7 +%%PageOrigin:-336 -364 +%AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 +%AI9_Flatten: 1 +%AI12_CMSettings: 00.MS +%%EndComments + +endstream endobj 128 0 obj <>stream +%%BoundingBox: 0 -128 394 0 +%%HiResBoundingBox: 0.000000000060936 -127.99999999994 393.62001220703 -0.000000000060027 +%AI7_Thumbnail: 128 44 8 +%%BeginData: 7597 Hex Bytes +%0000330000660000990000CC0033000033330033660033990033CC0033FF +%0066000066330066660066990066CC0066FF009900009933009966009999 +%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 +%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 +%3333663333993333CC3333FF3366003366333366663366993366CC3366FF +%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 +%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 +%6600666600996600CC6600FF6633006633336633666633996633CC6633FF +%6666006666336666666666996666CC6666FF669900669933669966669999 +%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 +%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF +%9933009933339933669933999933CC9933FF996600996633996666996699 +%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 +%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF +%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 +%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 +%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF +%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC +%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 +%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 +%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 +%000011111111220000002200000022222222440000004400000044444444 +%550000005500000055555555770000007700000077777777880000008800 +%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB +%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF +%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF +%524C45FFFFA827FD22F852A8FD0AFFAF43FBFBFB1B431BFB1A431AFB1A3D +%1A1B1A3D1A3C143C143C143C14361436143613361360A9FD29FF7DFD26F8 +%A8FD08FF8BFBFB1AFB1AFB1AFB1A1B1A1B1A1A1A1B1A1A141A141A141A14 +%1413141314131413140D140D1384FD27FFA8FD27F827FD07FFAFFD04FB1B +%FB1BFB1AFB1A1B1A3D1A1B1A3D1A1A143C141A143C141413361436133613 +%360D360D36AFFD26FF27FD28F87DFD06FF67FB1AFB1AFB1AFB1A1B1A1BFD +%041A141A141A141A141A1414131413140D140D140D140D130D130D84FD26 +%FFFD29F852FD06FF43FB43FBFB1B431BFB1A431A1B1A3D1A1B1A3D1A3C14 +%3C143C143C143613361436133613360D360D0D35FD26FFFD29F852FD06FF +%43FB1AFB1AFB1AFB1A1B1A1B1A1A141A141A141A14141314131413141314 +%0D140D140D360D0D0D350D36FD26FFFD0AF8FD0D27FD12F852FD06FF43FB +%FB1AFB1BFB1AFB1A1B1A3D6067606760616061606160616060363C13140D +%3613360D360D350D2F2FFD11FFA8AFA8A9A8FD10FFFD09F852FD0CFFA8A8 +%7D52FD0FF852FD06FF1AFB1AFB1AFB1A1B1A1B1A1A1AFD0FFFA8AF36130D +%14FD060D0736FD10FF2929012901297EFFA87E29532953537EA8FD05FFFD +%09F827FD11FF27FD0DF852FD06FF43FBFB1A431BFB1A431A1B1A67FD12FF +%84360D360D360D350D2F2FFD10FF54FD0529A97E2902292929072929297E +%FD04FFFD09F852FD12FF52FD0CF852FD06FF1AFB1A1B1AFB1A1B1A1B1A1A +%60FD13FF84130D0D0D2F0D0D0736FD10FF292928FD052907292829292928 +%29220736FFFFFFFD09F827FD13FF52FD0BF852FD06FF431AFB1AFB1AFB1A +%1B1A1B1AAFFD14FF5A130D2F0D2F0D0D2FFD10FF54FD10290E0E36FFFFFD +%09F827FD14FF27FD0AF852FD06FF3C1B1A1B1A1A1A1B1A1A141AA9FD06FF +%8584FF5A85FD0AFFFD050D2F072FA8FD0FFFFD0429012929290129012901 +%292829070E0D0E5AFFFD09F827FD06FFFD06A8FD09FFFD0AF852FD06FF43 +%1A431AFB1A431A1B1A1B3CFD07FF363CFF6014FD0AFF840D2F0D2F0D2F2F +%FD10FF54FD092953FD042907140E140D14AFFD09F827FD06FFFD07F87DFD +%07FF27FD09F852FD06FF3C1B1A1B1A1A1A1B1A1A1461FD06FFA936136013 +%1436FD09FF84FD040D2F072FFD10FFFD04292829292953FFFFFFA87E070E +%0D0E0D0E0D85FD09F827FD05FFA827FD07F87DFD06FF52FD09F852FD06FF +%431A1B1A1B1A1B1A3D1A1A60FD06FFAF13361414131460FD08FFAF0D2F0D +%2F0D2F2FFD10FF5307FD05297EFD06FFAF0E0E0D140E0E30FD09F852FD06 +%FFFD09F8FD06FF7DFD09F852FD06FF1A1BFD061A141A14AFFD06FF841413 +%140D140D1484FD07FFA80D062F070D062FFD10FF29290129292953FD08FF +%5A0D0E0D0E0D0EFD09F827FD06FF27FD08F87DFD05FF7DFD09F852FD06FF +%431A1B1A3D1A1B1A3D1A3CAFFD06FF611336143613360D36FD07FFAF0D2F +%0D2F0D2F2FFD10FF54FD0529A9FD08FF840E0E140E140DFD09F852FD06FF +%FD09F87DFD05FFA8FD09F852FD06FF3C1BFD041A141A141A36FD07FF3614 +%0D140D140D1484FD07FF840D072F070D062FFD10FF29292829292984FD08 +%FF850D0E0D0E0D0EFD09F827FD06FF27FD08F8A8FD05FF7DFD09F852FD06 +%FF431A3D1A1B1A3D1A1A1461FD06FFAF36131413360D36A8FD08FF84072F +%072F0D0D2FFD10FF54FD0529A9FD08FF360E0E0E0D140EFD09F827FD06FF +%FD08F87DFD06FF7DFD09F852FD06FF3C1A141A141A141A141460FD06FFA9 +%0D140D140D36A8FD09FF2F0D070D062F062FA8FD0FFFFD0429012984FD07 +%FF840E0D0E0D0E0D36FD09F827FD06FF27F8F8F827F852A8FD07FF27FD09 +%F852FD06FF431A3D1A1B1A3D1A1A14AFFD06FF841436600D60FD0AFF842F +%0D2F072F072F2FFD10FF54FD0529A9FD06FF5A140D140E140E0E84FD09F8 +%27FD06FFF8F852FFA8FD09FF7DFD0AF852FD06FF3C1A141A141A141A1414 +%A8FD06FF3635FF5A5AFD0BFF2F062F070D062F062FFD10FFFD04290629A8 +%FF84360E360D0E0D0E0D0E0D0E0DFFFD09F827FD06FFF852FD0CFF27FD0A +%F852FD06FF3D1A1A143D141A141A36FD07FF84FFFFA9FD0BFF84072F072F +%072F062F2FFD10FF5307FD0429CBFF360D0E0E0E0D140E0E0D140D85FFFD +%09F852FD05FF7DF8FD0CFF52FD0BF852FD06FF1A1A141A141A14141360FD +%06FFAFFD0EFF84060D060D062F0607062FFD10FF2929012906297E5A0D0E +%0D0E0D0E0D0E0D0E075AFFFFFD09F827FD04FFA8F8FD0CFF7DFD0CF852FD +%06FF3D1A3C143D143C141A84FD14FF84072F0D2F072F072F062F2FFD10FF +%54FD05295A0E140E140E140E140E0E0D61FFFFFFFD09F852FD04FFF87DFD +%0AFFA827FD0DF852FD06FF3C1A141A141A141413AFFD12FFA85A060D062F +%060D062F0629062FFD10FF29292829292F0D0E0D0E0D0E0D0E0D0E0E85FD +%04FFFD09F827FFFFFF2752FD06FFA8FFA87D27FD0FF852FD06FF3D143C14 +%1A143C1436AFFD0FFFAFAF5A2F072F0D2F072F072F062F062929FD10FF54 +%2929292F0E140D360E360D36365A84FD06FFFD09F827FFFF7D2727522727 +%F8272727FD13F852FD06FF3C1A141A1414131414FD07FF84845A845A845A +%84352F060D070D062F060D062F06070629062FA8FD0FFFFD042906297EAF +%A8AFA8AFA8FD09FFFD09F827FD05FFA8FD19F852FD06FF3D143C143C143C +%1460FD07FF360D140D13FD050D2F0D2F0D2F0D2F072F072F062F062929FD +%10FF54FD0529A9FD0FFFFD09F827FD06FFFD19F852FD06FF3614141A1414 +%131460FD06FFAF0D0D0D350D0D0D2F0D0D072F070D062F0607062F062906 +%29062FFD10FFFD04290629A8FD0FFFFD09F827FD06FF27FD18F852FD06FF +%3D141A143C141413AFFD06FF84140D360D360D2F0D2F0D2F0D2F0D2F062F +%072F062F0629062929FD10FF5307FD0429A9FD0FFFFD09F852FD06FFFD19 +%F852FD06FFFD041413141314A8FD06FF600D13FD060D062F070D062F0607 +%0629060706290628012FFD10FF2929012906297EFD0FFFFD09F827FD06FF +%27FD18F852FD06FF3D143C143C141436FD07FF36140D360D360D2F0D2F0D +%2F072F072F062F072F062F0629062929FD10FF54FD0529A9FD0FFFFD09F8 +%52FD05FFA8FD19F852FD06FF3614141413141360FD07FF350D2F0D0D0D2F +%0D0D062F070D062F06070629062806290628012FFD10FF292928290129A8 +%FD0FFFFD09F827FFFFFFA87DFD1AF852FD06FF3C143C1414131484FD07FF +%0D350D350D2F0D2F0D2F072F072F062F0629062906290629062828FD10FF +%542929297EA9FD10FFFD09F852FFFF52FD1CF852FD06FF3614131413140D +%AFFD06FF84FD070D062F060D062F0607062906060629062801280129A8FD +%0FFF292953A9FD12FFFD09F8277DFD1EF852FD06FF3C143C14361336A9FF +%A9FFAFFFAF840D350D350D2F0D2F0D2F072F072F062F0629062906290629 +%062828FD10FFA8A9FD14FFFD29F852FD06FF3614131413140D360D360D36 +%0D350D2F0D0D0D2F0D0D062F060D062F0629062906280629062801280129 +%FD26FFFD29F852FD06FF3C1436133613360D140D140D360D2F0D2F0D2F0D +%2F0D2F072F072F062F06290629062906290628012829FD26FFFD29F852FD +%06FF361413140D140D130D13FD070D2F0D0D062F060D062F060706290606 +%06280128012801280053FD26FF7DFD28F8A8FD06FF8B1336133613360D36 +%0D360D360D2F0D2F0D2F0D2F0D2F072F072F062F06290629062906290628 +%01227EFD26FFA827FD26F852FD08FF360D140D360D130D350D0D0D2F0D0D +%072F070D062F060D062F062906290628012801280128010128FD28FFA827 +%FD24F852FD09FFAF600D140D14FD0A0D060D070D060D0607060706060129 +%010601280101002853FD2AFFA87D52522752525227525252275252522752 +%5252275252522752525227525252275252527DFD0CFF855A605A605A5A59 +%5A595A595A595A595A595A535A535A535A53595359FD06537EFD28FFFF +%%EndData + +endstream endobj 129 0 obj <>stream +%AI12_CompressedDataxœì½m“¹u.øüµ!ݸ*á™Ú¨îªö•W²ÙÖ†Ã1AsÚ-¾Lp8ÖÕþú}žsd&Åîá gh{Crº€B"ñrp^Ÿó7ÿÇo?ûÙé‹7ÿzÿ34‡§OþæonßÞ?{÷æí/òñá—/_~ýÕ»·üè'¿ûéÁæ£a«Ó/§ÏK˼ûÕ‹7¯qpèâY{Çïÿä«g/Þ>û÷ë7ïîzøÉOYñûï^Þ£êå›?¾9>{ñÓö@tp~öUÖþÜùŸ;ãÌÁþ"L‡Ó¯¥Í³×ÿñ쫯^ül‘üäùáÍ›¯_ñâõoÞüï_ÌágÖM?‡ƒ ð½øÝýWÛGÓ~’™}â7òqn?ßöÇ䌱ΙlüágÛï—ÙõùÍó¯_Ý¿~÷Û·ožßõÕí›—oÞ~õ‹Ãí_Ÿ½>üúÙQóìðÿÞ¿|ùæ/‡›—Ïžÿß9ý2~~÷âå=&æÕ³wëeO¿´îó›¯_¼üâï¿~õ¯÷˜³ä¢|î?—^ÿá+t‡žùÿòyþü—¯ðÑg÷ïÞáµðPy×ßýíÍz,œ –ŸüóïîÿøBÓû/?­=¿}óå«goÿŒo»9é´§ÓÆúßß¿úò%ÖB&-…c<üLþ^þ·6Ä i#wôÉ9ë­9Eô¦pœs43uønÌÇ49LkˆÓù{­›>ÿí˯Qù·oß|ýå/_ÿÛ›§O~¢$îŒak}qøÍ¿þ;~µ’cvøýÛgÏÑ~om@µ¾üéâ=ßÞ´ß•_ë¿ùþùþß@'–ôÓËëÿ¸ùæËUÇÚî1=þöå³×ÏÞ¤¢uø«ÿšg˜§¥K6¼÷‡Gõ‰ø%¦Ez‘6]ÿïi°ªzÌ£~õâõÐ…|öìí»¿¼yûg.ØrOïÿ÷ýC=~öçûwÏÿÔ÷Y>ýà^ûìÝŸ@óï_ñU›ýu™aκ~ö˜7¿}öòå‹?¾}öåŸ^ù¿ž>™Â§„’QÀ} œPnPnQÎÓånº› ŠEq(aŽ(iγÞé§ùf¾E9Ï—§OæË|w2'{r'Nñ”N™žøssºE9Ÿ.§»ÓÝA±7îÆ£„›x“n2înÐð†?·OŸÜÜÞœQ.(w·æÖÞ:/% ÄÛ„’QdÈÈéöæ–?g”ËíÝÙH±RÜrÂ9 ÄsBÉç錟O|¾ÀŸ ÊÝùîb.öâPC4ÁÆŸóM>c¡ìäå4Lج·Xdîø€}>a‡ßbÁÍ \+ö4÷ó »ø‚Ýë°oöìIvév'we’}È]x‘ç±Û²ì²[Ù_uoù 'ÙUºŸ¸õt'é^òeé.šeÝÈ.â>ºì¯´ÌÿhqòG¼ü ò'ÊŸZæ™&ù£Ïò³(ÿžøÿò÷©ý½”›«ß`íøGÿ>óoôx^~kóþ}Ùü}._6ånõ7N ü»|kìÿ¶{Öö‰çþ‰Òã¹}¶ŒpTÜ›œüÑlCOÅÄäg’§O@æ”pËßg,rÀ‘ì‚GáßAþDù³þ›ŸûOìLìíº G;·)~UªÄVR)™Ðc–2µ?ú÷,ÿ'WhÕIè .!S.P/Ò/ÂÊqJAË’Í g³P4Ò´‹P5SΦ/§Ž§Jw×ì€=“±c¸W.;+ýÐÛoßœ)è1v% %eêʼô¸ž©u¹ÊmWÎCÁ¼¢Ç˦ÜmË8vüqë‚uÑ5Ú–0”8”Ô•¬=æV¦¡Ì]9 妖ºÒ äP÷[Ðù(þÚŸp  ‡;Á€ì_pKÜâ¶8áÖ˜pw$ð&w‰Ãbp5\pÇÜ‚›9áÆ™Àídð9ɲg6äÎè÷Ó ·ÔÎ)‹ + IÕàŠ¹à.»÷u'6'KàÍx4‡âLƒ¹€‡»“v:Íàì2îÄ^σäÛ“ÁUuSu Fîþp§˜À1†Ùc³[«;0Qgܱ7¸iç c÷™p÷K‡‰3ù._p'ßâf>á~žrÆMq_ûì0Õ—âìÛ-îòSšq«gÜí7¼Ç=oÆïâ7ÿ-8€ØÕ ü@W@”Ô€I»€ ¼ 7àæ0ƒH…¾:lº|:}Ú={Œ§2¢PvRy#wÏYî•“Ü•¼A£Ü®¼s½Ã‰?ãäß`g소}IV+­k­«­ë­+®k®«.ë.+¯k¯«¯ë¯;@ö8 ݺt/ènÐý ;{;B÷„î +Ý–ÇNö†îì§OȬËÑ]¢ûDwŠì•²[t¿èŽÑ=£»F÷îîPïÕý£;H÷î"ÝGº“t/énÒý¤;J÷”î*ì+H±ì-/Ò‰%’¦{Lw™ì3üd‘v¸Ót¯Én+ûMw¸ÙuºïtçéÞãîÓý§;P÷ îB݇ºu/Ƥ+óùÍ[¸Dq{ÄÍÎåà#ÈǦà̈́wÀæÁ'ÖÄirبs°6'š)ò°ç²‹a6üÞÕF< ýD3Oêì!¢9Xcø@jM?ÿ¾žwóhõ1r&çèÝÍ^ÔÉÖÅ”=ú5‰\{Sb·¯/ƒýàøô›ó"8WÁøýê_›®ËÓûæå÷¯¿£žrôúW<6WùÙ¬þ³õ¿ºÜר³k÷þE½¹¢åÒ¾vAÏ›2^¿·òg¹^EðBõ:½\½H×Wèõk³\’ÂúÄÕ¥˜‡ ñԮ›U¹måF˜¥ú–´L¤w0Pë²ázìFÌY + rh'°öò/öRæUÙ +6RÞÃrë”™nU¹šÛu×7 +#vY±(Ìé²ÊsaKÇužW+¿ÑãzÍoDÈ®kÎ"«½0Qò·þ˜«l×Ûa•u壬x’ë,n¢ÍJO›ÓÖ=òßKYÙíjÖÇzYËPŠŠ©Y.Ù$"êTVkâ:aMu­N¢,¸-Þy%6ÊMÚxbtß­©•Õ +eþ§2¯·:ceNBcêù>UM¡£LEL¾ñö,Ï¢(¨ ý$,ý E>ö|Q[L`?¨¸8ƒ¹ÃtRj ¸=2nµØQ_<}‚!© +äP”TcÜâò¡"ô]T¹(3nEa° ®(ø²(önD¡GeÞ×e5•xTàUÅ*í¨²›EawSv¢¬SEªéTéQÔr`T1G•œªãTwœ•ÅÂtTµnT†PB[õ™Q¬µš•ZÔi7{ê4YSSù+ý¹¬ÊyUnWåfUN›2ׂ•?«%¯JÚ”¸*aUüª`7¢GWÊ–²­Äœõà/ëŸó¦ÜjÁ”ÝӪ̫2mJ^•´*ÊUÖ6ůÊZ5cWe%¾Õi‡DrW8Ó¥¬nWåFËŠg¾ëÖr»‚ýªmWj»:XôÖ+²Z‰íüog½Ìv7Ã2¯˜¯~NËLnæp;o›Ùj´< óµ—›ÂËk™ O¯%Þ^K,%Hñ¥`ßÉa´¥˜Âùk¹ @Kýö^¤•æ"¨d9¸È*#Ä"'¨¬ Å™A èêï=‰w#ñP}SôÆSkYÛ^VÒñZ>&sÑ4œh¾÷TééŠ|-¬Ê†^Ü­nÝg3öXÀî2»; ûju¬ÌBk“ÐÚ 4ËñWcÐEôò`êŠÉÊSU^™¨–›Ñƒ”Þ‹4FÝÖï7Ã6W>£(¢ïŠâ™œFl¼Æ©_ +áàù½Ö³ËG^ð\?áRÒ³¾GÕ+¸6“ ‘ÉhëtRÖÆ;@ôtNØ'ßÄ„ª=¦³Z_²¾æTXñ…õ>]«-‚Ⱥ'ŠÍ(£8NRÛûž—…¬ËXïÌ7ÎØ)²±\!•X­ÉÕ²­’µ&ZB¶Úìï³-){ˆµåèŽòwro]ËZfÊ›’Ve-…*—¡G_ˆþ(Ï¿‰·<ÑJ +¬¤£HˆJ°Ÿ×RäíFº¼idfnÿöÊÚÜ—"ËÆ&éÄUq¯Lö[Ù©”òƒ×?;ºüšûÒþ­¦†­’¤»°*Ô× +öQ *²âµÒ4 Ͳ”Ñ4°.½ô:”•±a0D±×Ïq;Ë‹¾ =î×}³]®êou²ÿ3œê+LïbbZ LŸÔ8–Å DnÅ)?( 9’ÊTÓ‘kâÕ]ãJD\q%n#bQÈ‚ˆõôI1©å)d‰ˆ¥BÖbšDÔª¡Åt+Ng´&´ž>akkü¹qkç6 +[·Ö&Ÿs¸n6¦ž , öN3óœE®­Fž-H)«‰Šٹñ¢Vá‹üK;݌Dz)$-ˆh¾+ú ‹dg‘“O"”h—¢¥©ˆfâî!lÆÑE¸:å뤀‚ÏÂß‘ÃËÂå%~AÜOl¥î…²ŸU_ø¸…†+¯„‚¯i÷Šj ½VAÕçê¿kšœVÔ8gˆ°OgZºál¤ìr0ÍÕ`¡€kMù5:÷:µÃO|KªñŸê&ŠÞ?Å¥¬¶JÁ•ªsëHQï\9li—â7e«ó‹]I›`£IÌ–qÚh ç"8¯ËM_ŠFs]ÎCîÆRwäÆd§¸ÝâwKÕ"Ž%^)éjiúdô˜»2½·Ì°^{¯Ü<²ÅG·,çÇô8~º·”.èñZÝþ|÷ž¹Bé*ßëVÞ;éPõF©úÕ\ÊÔ<žµí,zTmmý©¤b9BuY*½µÍ;ZKÕ«Þ8ˆÇtÕ%§Vr)S+s)§Vnvh~šN{‡ZtjC¡öiÓÖN±¡IW¨Ñ5*´¦<êá}ö¼‡ætÎjBgD—vÆìP–‡( +z|/yé(…X¹Õø`J±:ýWéÄ#©ÂHÞsªß_¾ÇSýÔ¶Å­x~Š.uåŒ3†0‰Á˜l"ݪªÑØ@ÆuÅpÅt<Ñ% +ì§z¿_äÒQ²–5¦”pÇ#;S2Éê¯e/OQÌÊjX> «Lã2“˜ib&ÿ)fæ§OÄÔ\ãH4Šä܌ΦÄÐð¬¦g!™$†dERLÑæ„³‰$a,I&™Wæi5PocJjT‰Æ•0²„Fë ¢Ç_r»Ž-3¶iTx‰/ÙF˜,”¶ÐXÐÛJ]ªZ©éBGê¹PÍ…Z®i¤RÇUÜPÃ…ny²5µÛR8L hÙBÙ¶´¬£^;œÑHŸÖ<Ï>_sêt\ɺ Ç÷P‘©Æcoÿ?Õ+O>³ +Ȧ3š9¤ÃdŽgçý§Å-Žmh+t};ØÓÅm²GÈéz‡}Cõdz ò ™qÚñO +t¦›ƒ³i²BZ°©†|oœÿ">ÉõŒ•↷ïý7¹£71¬œø¾Ï§ê{šŒþgôð'Zñ^4GAb ¸‚2òi˜e“‰à€>s–ÌÒ«©žlU%ò·þ æÕüÑÐqyñte&â<L÷óŒapÁy©$Ç ÒÒùŒY‡\aÎQ,ç´ö÷”q.K²8‘ꢔÝfјy=?à(¾§ïò‘¯ÇÇN1Ïßçöï½G9ʤÌó‘ð ×ÈÆ¶Õc¼hW.²¿yûüO/¾ wlù¿u`)µÇ”¬·&ƒÃ!Ãezï ›ÀL¶:΂nWZ¾¾Þñiî©oßýaè]Q<ú®CÏ…"w®ÓñežÓî¹–!½éðñ^bû”o¸c>ûó_¹]ø¾VAÈê[±2È/·•™›qþ¶I®ný:ä¶2àЩ¡8ÏâyB=±²¡IГ°žáIè‹ä$ž7§óŽÿ¯úúV I.!­,äÿÌÆI¡:;œ7>£ñ=^Å{?׿ÖÖ–¸Ò¶¸§^DÍè=Q Ô!«O‘¨´/Å«è66G…÷{K5_©GzJõ®_óáÕufß}i¼vu ©üuè^º˜:Ç[•£(C-N·t¹Äá–’å$:ÚR6ºÅ.4â`—Xá:Å:ËÍ¡z"m|™ŠºÛ4Cþ­˜ýT‹¢:“—]Ì8ô&›çIÖ|_ª'§·ùÓ¼üsN,¾|êÃg„A¿ n"+Wëæl­öVõ÷ðMÞÕèØ$f‹©”Y#e—8Y¬Ûe7FV#bS‘ˆU&î¥b•‹¬.%cÊÆ "O"W ù¬R²X l/'‹Ãõ,.×ÕéZ$å*+ã”m¥eî’YäåÛ¢"»4wlWdåØ0¦"+W¼HÊX{••}qÒ^ÐNEF^¤d+–•+ÚBuÞnò1ä肹Ð$d»’)#ÇEFÞ 0ÜT¹«ËÊåníà[œTúÿ¿´ÿß~Z¾+=¶ ”%ekx_ÿÎÿo4®™ì] \7›%d¥®,ÿúÍ¿aÔPÿ];þ¨+Pj¦­%Сþ]ƒjÈÃÜÂÖÁ2P\–$b ¸¬B–À‡%|%¶À V™š\ R‘°ƒÛ!ØÁ‰Ë—o'/µS§çN¶Ž˜Ïþ¼¥kßß›ßßÜ¢c‹ ôÍÏ×T*QM¿ í7-FPoŽm” Þ ¶Å.æàÓÊœÚⱯû(ÁÛF7[Œ ÐÎF=ýFß$´ð&ML)çÒù Á×XÕPp\´GòNùæ#Æz¯âºíœVz ˜Ž¢ŸZÞë{|hÑÛM JŸ]H“¢ƒ0ÑO¸q{yÞ¡å‘¢Aì#Ôçn—”gÌÇÍF)òqóMµ"_¿zuÿV#ú¢š[ôhkå@ù׎• rKÅg©aÁê\ZÑU.•§.NèK0wås•«­ì°«Wñ–C]‚¬E +n¿êú¿æ.áÓë@Ü÷Ë……?•Ø£E2œ›dxjJŠžT¤CAÝ(~ÇÚU,ED9IÑ‚°‚¡\¤*üT&¤ýjØR¿± +‘U]÷j·àE¦Ì¥L¥Ì¥F ¹6–§9)T?µæ»,œ¢ßJleùÉ­Ì­œZ¹Y +z¬®‹,‹óÆÖX·öÞÆ@øU‘郴Z‰›2þL]™w +8Æ|Êí•r~Oi&G*ÿ®¸@ì€ô¯ÞX[?¬µGÁ´â÷¼°Ö^WÍߪH•¯U²ZùáÊ'÷žœ£ÇÔÊKjÃÏÞR×Üs©å·™ã1>T×}©ö¼6¯yl¾·T‰ÝF¨×ØôÅñ¾¢;ÕHôа=_žD>’™ÜÆš/Ñû¹…VÙe‰*߯“¯ä"u,’Æ"[¬eôE>_KæM._ËãÅf+ïk‹Y¼“Ë$^¼"·²øVßÊã[‰\5K¹ÉäÊÁ•U¹|‘Í«tîZ” YÉèw+IýÒS ‚­¨_~æV¦V–km¹¤c+a)‚.º”%Òr ·ö†ß:Ô¬Å`YTPÈ… ÜnÊÍPN]Ùû\-4v[v/vѼ]/Q*^{%|ã"W›€›|åƒ +ÞQ ½8ÛÐÞ§`à»Å*X£ vwÚXá;Üy£?ÝhOÕ"×lrÕ*wjëœË:Utµ}lµ¹èO— ¿‡­®ì¶èQO²=&áwÑÕŠNuk©¬¶JÅ>H ;§„à¨År±YV«e±[оõ$[j­kÕ»ÆÂË{Ñ¿ººC-¬èaïŠ4PtnŠNö$mZê$ÑÐj¸N(®N´µ(࣌hmï$(»†ðœ‹s#ZÜSÑäÖ`žu8O*‚Gjñ±™¶Nû ªG4ØüÞr×ÌÖ{õd2dس¡ r*q£' ;ª“]¿øˆo¨«ðäí.ʼíAæ›°Sñµ¢¨+ªª‚ñ±[`‡Ð;T@ðï ê:T«‚¡Á;t[7j_ÄEÜZ›‰!ÔàØ«ë4ÈÃà“aËÈ}Q¸¤6úS}ì›°¶¼ÅüÎMòXÇðtÝ1û¸½ÕŽºÎº[x3óµÛ͘ó\à¯G ’}gv/Žìe%¶h]è;Ã:-@»èÇQ÷£ÞX8<)­!L1‘º<;{°øD”Ðn +fv!&ŸÕé2m~ò£>Ù§É?ÜH³Õg¯ÃOÝ|ø­)»1û´Ÿ£ûØS÷šÔa•sIè êdRÒn/‰¤  ¾€ã ̹ÐÅCÄr«c–PfRe²l7ñÜSs̪+¶¸gÑùFÃT$H¥*‘ž>iN7ªF:‡›sKn²¦Ä•»M LÑДss»aš“»â|cW8¾r±…ª¤•ð7­ÂV–Ÿ"BŠ0YEËý¯  KìÕM}ºÑ‚ à†âwK¸Râ¶z¿¤«%_/b6ß/Ó‡•‚,ð¸²#¥ }‡åǯµXñ0•[Lª\ +”˜—¬5«ÛM£¼ÓTo¬qW«û§{ŠiG¹¿UÐ\s¬n€«P9žÕ°†ÊU׿©¸þÝcÅEÌÛP¹%éÒTA£nVªíB™JØ\M½ä‹CàB¥4„.o”1úƒíÒ²¨~ÎkZ¦Ž„-"kQ.­UNÂj‹³ÕRü{JèJŠPGô˜®–«Ð•²¨Ú¦â6óMÊ ÷Úôø@‹oZÝã£Ðãwüó_£Ç‡(ÊŠžL%MË¥¦"áTé2”ÔS³à®ÜŠLC‰&gr-wÍ|ÁpnA¸Å±ØSîû(J¥)kª² ¿íp}£*j,Ãݺr.^‡â^:ÚbJv’ªòM™º(b…΀¢äFmêϲ]÷iLOi6Gù¨ Õ1²{CvJGy:úû©Òõ²¢Tèq¤^ï/×iÚÃTïƒÊ=~_=þ ©·ÆÌ[­NÞhuŠJð]U«³ImP«&õTÒ£]J*_3T‡&N6Ê95ÍÍ‚Y·Á¬×šSq ¸+î¾8ˆT'”;u.yúDœÔu„¤… ù¢/„ó,Þ#$;jI¼Hr>#1\,J£¤Pý¹-]Iܧæ-õŒ×5­¬óÉK¤-¾[IVkÉi-må—ž»]ý7øóNñÔ²>dÌÚW°÷WÂcJq‘~¸¤Çôøè¶ÿz\)åΚ:Þù;{¹»œ‘/ $5q™Ïƒ/ öžÔ½Q°%Q®YQ¬Q­6“`(ØzT¦Ñ¸ éiÈÄYô4P"V=1ð5¨rœ¼\Ž¢†D<¦¼*oPåK „$è¬Á°<6ƒœ-!wÍ ·˜àÖæ·X#ŠNÜW@ÓLn‹Á­šÛSÛbh[›Ùübb¯·2±mÌk½q­7­]1ª=}Ò™Õ®Õ6&µ÷™ÓÄýkל¶gJ{„ñì,zÿÇ–»u·”œ/—k +­¡6ìwZþ+ô¸@ýHQ~¤(?R”)Ê·íñGŠò#Eù‘¢üHQ¾»;@µ÷&ÒüðJñÈ8¢S˜s68sóz ÞàoCw:I¥hÓœñWÖ ËÃ1çqšh2û9Rþ„ñb6í¹|J£ª„(²þíÑ€Önü +ºªö Œ5É Àpðá˜ì + î=Mº2:ŽC3Gïæ¼×Cßdé!ç=WˆõçßÞÂ]ñ†pô†ð+oˆÎa}qZß–Ûë¥Þµ€Û)­§ÑMýô^»Ó`#k`Õ ¨:-NÍ}(–Ô—•þto3¯üO«ñ›„ðÛòÉö´†2ª£[ížì‘¶:ýº­Ö½µ™v¬‚Ís¤û¤%wXMÏUq´VÐ- üдZÁ}'m¶$اìÐÌøy–ð蔽O¢3öyNJëÈàBÀ<O(áB<á8ñnŸ±„$ô{Z¹–néh_óý8§úÝóàûóÐPÎ\IZ­gSI]}*Èf—’ÀºÇìoëÜ"skÆ„ŠîJúÎå^¡Š™Ôˆº@ˆ˜KcÁ ˜Kªï›‚p)Î" _!Ð +†,iœ?-Hçïñú®8ލÛÈ© n1 õ4°¬.k ˜åÄ7ĈÇHÍZÃf­¿ +tÖNèW˳T¿j®¥‡öó7qI¿r&ï’¾³ó?²Kw„>Ö#ôFƵ\à:ÜkìÞ[‹oîÄÎ.µÞÓPÇ„5Bðz¸ßMßšLû$`ê¡e*bͰÆF¬,taºëV\å*èñ«ãSswjß¹4WòÅ]Óm\5sApl·i‡;ª^Î÷Mq‘ðrŽçÜžs%›ó”¸ïñ;k¡‡S³ŽÂ^PÑâ&úzˆ¼^¡þU¡·ºÆW¡u‹‰Vã§ÛÅÛÛ©k¹j»‰®¶«؆›VHâ‰kU’ÌM0ѰíÙiõ¤-RÛúi¶Åm_ºgž¶d¸ÅEw¤¸ÄàJnË!D庣ºATë˜kc1ŸTªÏUÀó¤Î›E‘îÑË/FÕ¹©¦Â|Æn‹ØuD¢aÚ»¼2Ýy&¸“hÚ“¤³ãîh¹Ÿ;îññ‰ª¯ˆ-¡zs¬W0Hþ[?{uÖV™S7˘²Å…ÝRÀ‘…ÃúIå¢Ü&\dø±ÙX9ò¯œRóÆõvqqߥµ{ÔVð äÛš!¦¹†®<û𛵣ws +^g®©N³Ý÷©ºèúâp³r~½ #Ýë6\¨©jÚNY‡.Tç;q½»rÄá¡[(…8ÔEq¤»:/Nst•»ˆ{\g8:ÀÑÝÍ‹KÛ,Žjt@£ãX]Á ¯¦²ÕtÓtÑTS•‹Cõ'+/øÛ7?Žî[ŽnÃü¦Ì\&ÎQ”LöÔ/:Ç[É쑨ZIivøP3{Hð#XÚÉÛ9 bžëÀÿóÉè8Á\ç¾ù´†U˜lð¿X7œ6 ÖXñ“•HÞN âì0D2fBIÎ +ßœfꌒŒÈo€<î“6¢äŽÖ i>¥QõàjõªC²Gò9ŸŒ1®VÙQÆ8<ÉpY8X*¦Ê8˜yú~‚]îröòã$!È&MÎäl!raßra†¤:²/÷}ú¶‚cØ•CoÅÃUévŽ±Â·Êo {’ ÿ]”ãÅ=ïñ[¹:5ýœ/‰çÈ1ö±ª›ÎEÝdEÝT¡áÒFÙÔRË­Ëmu>}²MÑÙ%ç\ã"N›Pœ®¤žk)9÷~vÐÜ,Ìþ s<>T>…›ªÚ—¼/K¦qõ>©hP„‚E Xã”(FÆI…²w‚æ¡ Ùÿ^,°‹®$°ÈZ´ŠÞ•( 'qª¡ƒJ¬Xª"ÔÜ€ +ð©> +àYqDG€Î%”aµ•z`Íkp™;%î– :ý’>´HÊï´|óÛQ@Ï©$zQ#I.Q;kÐÞ\ò˜Ïòúy,Ì5[yhyÊ}3Œ,ÌÝêo»Ê_nV™Ì×ñD‹;ú Ÿ{|ì7–,MÇóÂß„ãp” ¤Ê3<¥'’åJ”(¨þM3A¬yu¼Æû¯¸ÿÆÿŸ‹KÛ©d2Ñ<'K#/Ád5ÓJÍͲät)`súT²Íeëë×Ò@ñîqUªø¡\ +[ôØ'ÈÚ–ïaQ¿û›†ïV YŒnãF;ôÅÎi¸9ïϽU4›‹¹§j·¦ž›Â_5õT”¿µ±ÇNFØ&#Ã¥™}ηù¦˜N ý¯‚¦bª?+pkÉ_¶.a(þJqûEr5íû¡=~ðw¿«›{Öb [›Èª‘ltÚª.[SÃ}]c¾’Ét¼×%ûÊc^·X¯‚bÙ +}+ëÐÄ­—m減hü"ù⮕=×»‡ÊmqÛú˧Ðc¯9þáéÒã{Eô¸_sýçvØ ›¼,â6±œ ý,GÛG® qëSUϽ jö½©˜©SË­µäÞ+µÞ“ƒñ\r +i&!Þ^,@w%œ¢S”P +fL énjwÎÏH«÷‹pEiýƒè29]VõÒ/bS¥@Ïë-Wo6½»ôæQ¶HAÖoSÍÕ0‹åMqnƒð„N2úø@ kȶsá•Kt`×·–c @¡¾XyÅ‹ðЧÂ)ªŽX¹Ä“ À*‡(¼aáÉ ’ÿ#¿G.ï$ +ùµfqýá9¤ÿö=nE»QÜ™+l„ÄD¿"·Båâo ÏNþ}.âìÔDÖ­ [?ɋлq¾åü ?ßSï(®eã-E¤u·™îeÚ—²ƒšxÔ¦©ifY‚¹X7GzM©YQhí*ÉOØ$ù™DÈÓ?·%†êÒðu«û}†ìewÁØÕD;s3RVÇ\ôVI¯KMSƒHrÝ–±ùg¤¿UWDŽ+¥*‚€²-£³‚VÒ^ªôØRë”rS£–:AJ0¤LÑZãÓ-FñI¤æ+Æû5rf5ÜÏÍ%aIQë[rÚI»T[~)ÚrÕ•Obn¾ ¹ƒsÄ©oP?<#ýQz|¯HB“Ç7A‹YbL¶e¥jzNàZ‹b‹€V‘^1.{E^ÒØ Ç¹¥²Y'³Yl[+†×YßlÕj1U+XëâD«Ö‰gÑüð¡e‡_g†?ïøoæ0ð€’ùÊF•K‰47ù8yŸçÊÁö›—_i*V¨<i¾;äp´1¯Í­ÿYjï…£È胄hëqUQyÝL,ø#È4ίÍô \ЧúUÒD>” ç]íõ‡¸$V¯÷½>¶¤oüÎgtÊŽyûfõ1ßÖ`w –±÷ußõ@Û\Ýߢ=„5H{Ë­¾Î¬¾Î«N Ã}úÇQÿvåïåÿÖi¯ù]0z »TÿÞ²M±rªÛÖÕ!ü›»ƒùº“®±œKnÕ³ÎiZ‹‹û:»ÓÝ*ûí˜Ýi^å­Ýæw +-¿Fr5ÇÓí&(³êø”櫓égc2öŽfñè6nÂÆˆ—»£óŒús›á ¯SMX·öðî±Ò?ÎJÒPyšÛ› Ü{ÇÏl!“ùežYÍæ9„lÍûü—÷ô€oMöÃ`âq0dÆŒƒù1æ¿~Lšwi>þ6±¡n'}Mótÿîõ~ÛûúQàQ™IVGjÉȸäd¼)Ùj^Æ©åe\23†’=²å½ß¹??Êõ°=í%…Õßj»Ù¯5ø¶»7ï3·yàn»Ý{5…Ô*ÒxH¿´ŽÕ¸m¼Íª=œM¤Ýxæ÷D1¿?íÕ{Ç|=vùú qýŽØ“÷Þ;½yÞøwŸ=*ÑÐ9w“s bÊrˆ\ØÙq¢}Åó,ˆg.ÄÖ4A®±ó,©ìå°ô×Èx|®æ­ïÏç4„oýOzñîþn^>{þgÐÍïßWj·š=þ['w{úD¸Ì’ÜMàøkrr”¡â?¯2To{´¤OŸ4ð}U™Vuéã’ mS ‰šTXÐo»UAcZì–pý½UJC j Õ½ª²S6~ìÄyƒ‰âƒSç _¿gÎÅÝÖ”„0U³±$…©iy¤¥†2KøV•D.My0=L—¦(Þ»ô 1·Î~Ñd 3·…Z%­ÚžÚ0ú†{âñi Íw•˜°¸_÷;ân“÷¾ßçÕŽPù4,É=Þ»'Nð±³/ÄÛáÛÄ)vñ”-?ôE*žÆ=Kž½$6`Õw'AT9â{ìqÏð»Ö[F³$gXínôxî(Þ®¤µ›¢a› ¡Ä†>}ò-£C³Æ‡.Ñ¡ØeZÌu7ª!í?ãV½Ðžì²Pö‘2S~˜æw׳JÒAÐ]Ò´?¸Ž`C’<öëÁÙtdà"Xš0ëœôŸ?ü¥üzÏ¿Ö_êÌüá¯úûßáÿÿŸþStøõáŸÿžx*ßþÔô:¼bíƒã9üj·Y}Ÿ_­±ûá~‡¯ù×ÏOoß_<÷âÍëgoÿzø…*g~~óæÍKÌå/˼~~ùâÅ»7o?¿yöüϘýÏÿâåýç¿»þÿÉoüŸükgžô—ÿñµözÖ£;ÔA¼0`ÉÔEïTi<áhCÀuÉX‰siž3öðÄÐ÷ +›œÖfWª † Õa¥Sv9þðLG°]7oíÑ€åDCœq:zˆ?eY0{bÒ Q³xˆ3*ó´ï˜x® +â|ˆ³LDÍ _ŸˆH¶‡1-ëð\z›âT-£r_o¹cŠìnòGžÊ™Ù¸Ë‡0!>%T¤£¥iÚeœpþÊäjwóÑ€’a3DÆpðhœe¹Œ.c«˜ 1Mü×#¡0~ð’.1¶ô—Ãh»góÁ%H`x Ã1!ÎeÀd¼Ó·b…Ç* bŽãò˜È¥?ÔZ|ûÕ°ìÝÉâè¥|ÏÇP¿1YúÓ ‡ + +"DáÂ+œŸêä%sä͘¼/æ"™Óòà°(veƒpYe:{ôœŽá>CëÍ!Và•˜©;¨Î„K‘x± +k8¨t Œ«÷Ž·ÓÁFlÚ”j/é8Ó¶á)fl.3@Þg¾5Öâ8±C”ÏC–}â±×k/¤F<`“bö°ùìDò"½'Úu0ÈH¥¯º¹6eĆxL“¯›ËÛãÄÝT4¡‡˜ŽT<ãkÛÂðk±O‡°Ù"^>8Œ†ÏŸ ⃄Ña–þpâ¬ã.Â-°ê9?e’¤ž+ {ý%º~9E-7?–Ý%œ1ìòv–HŒx–pè-†¶þà ¦³?cÊ'LÕŽÄÛ%ÙÐsn1³XQT0 ew὎É`‚ÅÊŠÓˆ‹8áÔpd˜8KÅ9ûB×CÇÖÒãoA3hPvzð´3lͤ["D¼’Œ ÷\½)“öÏ«¤Lºù7%¼gÝ·„Oæ:É.„Þ¼Ú­Å9bÀ·œ…<·;Žá@8NfØàc¦´Æ{•ÏËÁ»€íCe¶à«–/aÉq8©Uð«‡tul +lkq¦Á¿†çàÈaÖÜ8ºZ±œàÕ+-ßêg¨=çÊÔ-“ *‰y+h…­éA—q¬^í×=W§<'7 XèXqgT€ÒQ7æx7àÔŠ²×pÌÀä¡{kùZБ:ÃXìÕsºÏËèJo]¥;‚[À^žb¸)öW*Jwý;µ¯õ³Ðteò–ùýÿÀ¿ÿáp.¿ü +ŒÊ—÷ÏÞÝñ9¾Q–ý†¿~.óöÍ—ýüÍ¿ Ëó·oß|ýeÏã̇Ÿüôð‡z$»ƒ yÁIJœÙ©1àÇ'PWÜ àxh{ÃIÅåj¨Š'…Í™íÆus—ÍÉvà U6'LÇ’‰½·Dz#ÿ„‹LÒ y¥2‹ìì$µ Ž2Tœð˜”d2…XAƒŸÈ¸FVàû\^+ÄkÃøPûC-dôjJî<"ÍL2¬4aÀ•â4'r¥¸ÕÙß•Éy)Ò*L8æðlj4Øp¯v+9™dz1yŒxÅçñÚ8=<<÷%Ž<^ƒ½9ÖÏŸ·%ËÊ%‡|°||·‡"­që‡ôeh¥·¾8G,U÷˜Ìui[­(Ýuo´|­›‚ö˜ýyëÏ£=œ¾ü¡.QKñÖÐ0‰MEÄÃ^¨k_–ÃýÛa"T„^Œ‡;tG/–L +ÁàdlÚVQ®¼x¤2µvàò5,3„ê9£ ÍêA}E^鯯ÍGjoãƒfÐ ü;ޝT”þú×j_ëæ¡=gòÖhMiMYçâZœ¨˜ï^lž°©hè,•7¸‡ðì + +)eNrKCB#ÅÝ”3§‹â8 Ò¨rNp:±oAO!F`" ‹ƒ é„æÍx™I4É`8£ I‰pç$‚¥B×…J“–Ö `…ÛQ ©úÊÚuÑm˜”®bd||b2™Œ)\SŒÐþ Wa5P1ÎÎr1ÌK±ÔådÔ8á|b»X¹}ÈVAÚÃp”žßOt¶Ï^7¦Ï^6¦÷n§…Éà”§ úœÛÐûfLX .fNŸ‘ ÄËqãDaDQCY/Q«ƒáR¢“ô™™‡«o¡Ÿ<Ó û ·ÌN?˜0¤ ™°‰¼p¡`Y1?ø•Z÷3ØÐ„÷Žõ†Vryª &:ñ¸î^&8cK%¥ ظê±Õ…ýM§?öÁcH‚auÇb»‚w-wÄht)QóÀÞŠ€T“z´>ú‘ Ï‘P +P’êE0Ÿsaq¹³ðý¼Îù(P]gêa°“±fêMy„¬¨ =Ùü,!vx´‘;‰gÕYé'ó®0ºÄ!a:Ò,ò€\ÏüìÃêla£‘W‡˜h«€Ô:QùAp¦ µFØcDŒÎqÓfR' –=3ÂCôdTÀTbŠßÀåà5±ž¸3æÌ»g‰ €ÉÁŽ˜*@¯‘’‘…§¢Ir°r€-‡”¹J†î†…úŒÍ(wcc$ÞÊTa +!³ÉýÎ'qêECbÁìÐÁ{¼Ñ<6h6¼âÀÎÔZíôã°8 2àÏ3µ×ˆŠîʆfX./Wq>ì ÁbÚç†÷÷*]ƒò aJ†~†Ùì‡òЪ, F©,µ™Î“:°Œ8˜>î:]Aœ‘)2x„¶ QÙvÍÀŸgcØA¦48gØshýi÷dÕBfúõÎõDÍHÌywãD“Uß (+CC@X ¯sØy©®Ey”?‚¨ƒx`©ßéŒ>õïÑ’•¶{ƒZì¿ÕЬŸa,Ã?´R«UÖ@Ã(6cˆÔF‡²˜C-c‚ùª«dïQQ6(ðm3Uð Ø:¨À‹cQjE»Åƒ\,Ü¢˜”öµ4•C#:« e|Ï+¹ØÖzU0Qãƒ'Ñ팯T”û¨­öµ~"ꃮÍß#åíÀ2HU°I$äX·µ’‡ ¦Z©£²~_Õ‹,ø8Gsa¤«ÚÖHmÈ8°Yàóš PUhYUh8« ªÊë¨à=Ÿ·6@> 2j¦ +‹zÛf$k¢ã#K…;ºÚ­˜op—¥aŠFÁµ P¸e± oÍf„¤³È€ˆ-²ÙY³º5ýYTÇAwÂe±ý‘ìbÈÆÞ»Õö'¬æ’¬.ï¼µý Ñ<…DÑfû#ψÈ3¢pÓÕö7|ceû#S— mDs›ë ƒ‚?Ä X!ÛŒ€ÖöÌ[Û?˘r¼ÊLP5ýõrOµ’2Nx#RFl´µ’S‰4³aŠ©ŽXl€ j3¾jú#•ó¹³ø6Bf››¡7À”ÈP©}¿ú æä•}w€gºãb×Cž¼U1ç“á念âM`ÇÈ—UãÝ,ê“ÜlvࢰÜ[KÜ­\ lK2”ÍRÇé¦Ä_ tÅ‘öʼ¼òÆB‡/+ ÂNÔ[U NÑ‘f™¸œ›†l€D°Øšè,5Ñ dÕ8G6˜ríØ‘ó[síô`FrÓÖ6Gþ— u߉*—jš³cÄ;ƒ#ç+WÝU3ò…ΪÀ«2‚Yߘè†Új=㮜x®IÌÔlqÖIf…@ï­àÓÆDGNü¸0ë¼µÛw,Mߨ·XZ0ñ‹p¨ØØÀÆÚb:žSmýà6ºá–oõ3TŸsmê¶·;„9,jâµ’¶&º±¶˜Îx ú96ä}b‡Ðs*àðº­eŽWjá€W&UbíkFÈm FdÕ_±6~µÅf6>¨XÙÆñ­símZëþµ[ÿWfë?µMîÐ胦bßÓaG +4¼X[³—ì&Õé¨kª*Þ½7ØYFìás«`DÈÏËc•Š©˜ +Ž~3•BègCç¬?nÁrè—eøWmÜê‰zÂ%Œoúl“yç¦C{V4tê|j&£ÔWf#`ðIÊíóâýBÕËò¡8¯ä(î%@¡§âÔWÌ3ÇÑL]-‰ŠÁ~JúT„`¥è!Jb¨Dp³rÿd À‹Û«(ó8'¡i¤ê>í|X_[;dЛèÁ0Ú²Q»Ç’O^Y%^td0¦Åich†Û³Aå +½ŽŠç}†¼3™š&RVñ¢µt†ÈÜÞžI‹È³ô-Ê ¿½ž<½kã^G®¸y\‚iw0}‹þ­š÷H×,«d6Ô?…Ã8ª!þR ·ùðV}‹ò¨~z†ŽÆ•èóàZ}²ÒÏà w¥%bvž÷¦Çr¸ÑU”{»žBV4‹ƒsï3* +<Ú¶©Àc®®ÁyÔO…nðÒÙ^¤`˜ nb{BT‰®Ç¥w'uâ'æq¬üŽ[©<‰+Æ'yzwþ¥ô·°iêýK9Œ)Ó}"S¶œGSz ˆBÜèDÎàr +FÒ7.¶à©Ûn.wkßSç¨é%âæytBu䓨* „}piôF¥õEˆ6|žª…opK¥Ó3â3Ð⎭_ýS©m–|¶¡–jU‡»æaU~E‰½¡.Ç^q]åýf?pj­|Xi“ÒiÆãqœGѡž_ëNG«êÎX†ÝKíû¼òÆ$,î=ñœïCe98Š6r4Ç·ZìºÃîô3Lð0–‡Vê=ž² XxUžøÊo¯¹ÌÒÐÔˆîé”0úÎ⌀O±£{j­Ø÷]¾¶uƒÝy`ß ø®7-OR3:ŽÂèUë¨$¤wv©Ø÷ª]¾6LTÿÀ‡&üG‘þ›¹Œx[|5 ä è@÷#ú¹ÙX…rQþ’€@d@þÁäá¤QamhB§zXÐÈq½c 8Z +ð©1)í³¤ÊÉ«¯®6°´ËWK’Íê:‹'ÑINnwˆ3³©§ :xðyTˆ&Üœ‰Lî>¡ ,¨bæ;¨3Hb d[¬/^¿¸` ‡J®põ¡§ñƒ+4ê^=u¼Ô(§HË žfô~?v­š„ÆfV9_"m‰à³é3DÜ“˜rë“8GyzÁ|UrWıEÑ}‚–zÚ2všÚƒI'H#vÆ0¶è^¦<ªo† 6ì˜øŽƒ ¸Ïõ¬.ŠkËðR]ƒçõÄÈœ ßîgsÀƒËòHéú‡÷Ƨ¥JÎ$NÈ·|úÃÈ¢Óª‘µëüóélfÄíRNÌŽ£>N-G“‚ßWItðØžYni*‹Ýè¡Ï»±ŒÒÃ^_º`«ïíØ,*Ññ­F_~LriAS2ÉFïË?´Ø÷å;ê}ñPYÏÁÐcaÇÛŸr—Õ·2Ô´\qê§‹±ðAAOݰ”ŽnÙÂÎ{êawZô{âawGµšhµÐ%­}¿çè!GYr8 ÂFõº*öƒÆï÷~þãÆÝËì ˆ¼2ñ#“ÆÈz ð«²øþ——é+öc v¾?Lè0†‡Væ“ 3 ŸÛ”F|ÛöC³j”üªU‚‡Vl£‰˜W¡7V Þ˜n{ýŒFÍ*A­º%FX"H^¸Z%hÖS† §Æ¦­Ubp ¨V‰ÁÚ_ t3BS´§“(ø§Y‚ư,íCZر¿š5¢þ¾1BÔÛ’xOs Ô1ö¶ñ¯0#CÈTÅAyÔæDÞð{ ëÙ!^ñktRC"ý^E«»k„›õz±ÍÊq·Çüëƒí€€1#Z/ZwÅ!6cOÍõž;6Nèä-×ûŸá0–¡Å®¶~§Y§öÆÒ[ÆwÚ5AŒ“3v4¬Ã0–‡Vêz€Åàsb¹ú=øè¦$:ZêªçÊiͲª”Ø´,¡k¡8SžeT9:ú;¥áD £°‚w˜ÆÍ?K¢RqŒ©>;¢ fÙ"ÐodIWß½P»@7f5-&ªÝf½±¶Ão=“¶0dC´®Ãûô-šØf^Æ~†©ÆòÐ}Â!Ž·I"Û t’ Ë¬ºÇD_ÑPÍZ.)XSG + +¨·šÊ—ÁxÜ`Õ_ Oa0F?:¦’¡n}å‰SG^ð"ýñÞ™©vo®”|”§ïmð ã´»Ðý 7w“ÞADÙ @´²'žï$²†baÒ°m‰ ¼÷V]‹F›ºé:¦xÌCkõ©jipà4`ŠŸ%áÚ³nnHxfÝe}³ÙP¨`U'à©‹qqÉô鎨[‡+ +ä`ŠGãª)ÉÂ$DCš' …v6(b—èhˆt7 Ÿ^.%M´Õ,‘E •…5µª¬àÝmȉ™Žš#‹àïIyB‰f¡±}vjÌ”¡œ@± S¬JR§±Z$ªh‹}»kЂɔ^òîÄ¡Ÿ<+7 Q&asQÇÎÄ Ö &æ1i§EÑÀTaLrÚé(v¦H“@›”XÑÂO³óÐôº(Ëé:‘&jÛ,{ÕEÊ`VÝ DìÀ cå|ÍL¶â„ŒŠJ*ÒÖœõ–Ó¯*xnuÅ,á—‘D™o*š?´õ¸¥:oŒÞ߇¹ »F´ï“)+¸aâØ¢ÝŸÐé äêfêGÃ0\°TÉÓôŽ!ý>Ø…ŽÅá°Q8•z¤7EóÅ•¯ˆÄKLQ”•ªJƒŒ&ó?—ÁŠÃ=CD™[ƒi%¬‚®×uôrå–Íå+i äFF‰$¤·8‘*‰N-¨Uev°\ŽgZ_› ¶XCB *$(·Eƒ ¹-#¶¾-Öü¬/ÓFäL_õxdÂçIbwÅX"Î")ˈ’è„tQ¼sʰ剿x›“H À6…Õy ’9nÜWû­ÀMO˜GÁc°ŠL&lb´çÄ›‡€v:œ {+û,³%”zÓ¢`ìBBL‡(pü{e[Ü€\âÞXúÝ+•õ­â‘¦t¨¢ +ÿ°3Úã#bN>ؽWêZ”' s3tÔOï0–ViåM"§þçŒt¡z#NÊÛƒŒNŒ˜yu¥Ù\ü‹å5 [=ÜÁAy$‰.I36‹cWÆiC ôìÇ%üÍ2z—MVLÆ~pQ æ)œi.Ç2´è^ª=ªk–U™Fsz”¸Ù~0Œ¡R¢ß·ãKõ Ê“úÉû&xËC+µZUlrGzéAÐ(;“©ÅnÅÁšQËb·ƒL@u/&²”¢š('Šó{·ô3Ë“ÄÖ íni—8vG¶ïæo¤™†½! -úw)šQ/@ÞÕ3 d8Œƒa¸eôúå÷r×vo^SÛ?çÁÉ_ŠŽWídzpP ‘¡WWùÖ±Y ZND¼DØÇ‘xgÊÓ“Ü`¢;±IQ1 ý×½ì”sÆåæ§é–.gbŠÛi&ñö  ÌùP÷îz0;-º·*š9UÃDf;¤¸4†Î¡¾8‡Š§ÞðV]‹çu»é:¦¸ÌÃkµZWϰú‹OpÆ-ð:`Œ2$—²¬}+:’PS”ÁÔÓ•œ²ÑNõ$™º²D d.Ž ™IòØây•ª%– M’ðƒcG !¤ê»7™°3†¡Eÿ.Mþìšãk·ÇÃ8°T9Ûw)Å‘´LAm=Ìl÷˜‡fþ“µæ ¸UdsÅwÓ_A#KO•¥Iý5Àˆ‘§Ž§=SÓã‰ÑnJf*Ò+¹žšYŒzRqP¥ˆhíÄá¿"Ipu¨căPÄH]úýâÞ²iÙ©â»K9oŽ tŒË/¶!°¬´Y àcüâÂ¥õàcbí t¢£17 d"Á{Õ¤YqCïÑÈÈLùùç¿s®àGX2zgȈ#6P,ÞÁï_ç¶{ ¸ÅßEÑOÅ*v˨Œæ.Æïfö\œèKd¯$‡VÝÀ °¡Åó¶W8c;ýte;cé[ôïÔôà]³I7J?Œ\¢[0rKeêø*}‹¦ÂÙÎÉØQ?ùu,Êuk݇&.òNÌ „¸™öqÑè6Ä(Ó@ŒÇÞÑGk’ðû€lhQì±€ÙNGöÙ2†¡¢{…ò„¡ä²Ä[rÙT-¼Û1dõf£ÏAµÖð2]‹f\îfe訟Ïa,,ËŠ£ ûƒäö¡š¤ŒùÍg^ä6¸ªáì›y\»F\ÀÁ“R½n´ d‘§Û U‡maèóᧉï±E!±¸‡Ý© óÛíôã‚ÄËÔRagC‹þUÚÍ¿mF?‘Éñ‰Q½Ö6c!Mô³•ü–ÓÎ;õ-Š.E§døú0™Ã\•OØÀ:]‘ŒGut#¨—Ý¢ç‰þ—˜è/äÚêPôH’#a§˜ÈÎ +ÇÜÁéQ›-8q!KŒÞ¢ñØàêI`‚^ˆÆIj†`‚9¤}¡›F¤½¡EÄroü~¢GÕ j­c~§Ål«æ4Ó³¹ê¶»fÂD9a¢ØÌް|¢ñݪ¸4íàó‘gRÍ©5anæÔ¨±j2"?1»Í<Âðq¿Š&ˆV còN‹D³gbÉb#[AÚ&–Ý º—Caú×.ÑwØ|„¦ohQÄø-LߨO¯r©¡Þ`×z»Ó¢ZL©jq¾éí‡fö(ÁÃ=<ŸÏmªÎèéNµ{ÏÇøô$“–è¥ÔÌÝ<ÝgÅñƒ®p‚¬ØÃóÑë•XXœÙd<•¶²|\%ØèÐù'q¥žž—9סó‰îK,ºßÈÓÇÁŠ2˜9- •½œÕ5N£é +1ÀóqÏ*ÿe™gÉŽ8}d•-£ ©Žö Mµì£ NbÑzÀ>2óò–¿ÆiDîÚè×£Åñ„ดxK“®`øq¡@«8`Òxzä:Y¨9Àwõóv„7¸yË·:Ľ-º‘—' ÍŠ}î™ZÏa D[ÓBbÐWè”'õ30ö3Ìâ0–‡–c¥äì!áGh¾+Ù`œ¼¼¾Õ¹G**NŃb?ZD3õÄÚ¬¶ˆftŽÀ©äq'ºÑÎX¨tlá½a„¹Z”Guxy;u{;ƒZì¿ÕÐl˜ža0ý ?°P«5í¡çxè³<ž˜Ki¾‚á'&:BE\|¢ìQïìÄkx+JäuÞƒæõ ¿°ÁܺéÑúÆ‘Œ-ºWz^)L×̪]šñ£ÖäÿOl]\‰追÷JÛåÞf¦ïf˜Ü~$®Ò#•lŸRà>VF… 02ìÀ#cÜÉÐŒVpÉü÷÷Q2 Á%c@P2èÁ}”Œƒp@ÉÀ”ŒŠJ¸Ž1ÀèPaŽ1Äì£c 8„:Æa8 cŒ}ì¢c Ãìø†LF:ÜCÇèpŒú°GÉ07(‒Q±pŒЏ‹‰ÑÐ{(Œ +“8 `TÀÄ}ŒŠœ8 _TÅð¢‚)îã\TTÅÞ¢Â+¨gqËb\ì±,*ðâa1 0n0,ÆÃb€bãÂzPÆ}‹ŠÎ8ÀW 0|E׸^Ñ7à=‚ãbñð%°EÓîƒXì4ë€#LÄ|¢‡TܱÇ~z0Çq,c‹=¼‡fpÄ0˜|¢©} ‹arvú&¸˃+µe77èˆû ;Í:L‰ŠÇXA(ôÆ vÅú¸|­ƒ‰ÜyÐÐbb§ÙMbBÁ¡G¾†¯hïÙZ3Ó?硾f%£6èá‘ ÁPÔp¹ºFŒÍh_$Çí©¾qó‘‚+¨¡d&¯8S-“'¦ƒ(¨ ¡"´p[ã_e©y™Ý^G¸ÇA`Å<½ÝÌТ{«Åθm.œäƒyR€n0E|3*6í½U×¢ !óøúy»þº×¯ß§WóÀ´¯7É÷¯Zì¹ ÕöS‡fTa"’Œ&¡¥:lŒ­µÁmqYÈ¢YðTøEñ‘Œr6²öÍN‚oi0£z/ZOîkhPôøFÃZûoO|‹1¹Q$¬~c‹îEZpR×,C¼§N«ôNÐ!ÐåŠRnwqÕß kñ¼|º™:ê'sÂkòiÑšu%¬ifâ½ÀàC×.¥±–¡n‚ álgçhÈ|SC:©2[,Ú/|¨Ÿ—ÉÍ ÁÔ‰à˜äÙ/_JÅÉÙ0mZZ=¥¯(ƒkưm-îÉû5<'kr¡qtyix§R;ÎByÐÕÉ[¿¸bÌ™©¢óTÚE&8}µ_‹u3uÇr|!ztÎ$.>ˆ.R-)äÏo…µ™‹Õ„ª ZíkŒ\$2#5(UŸÓ^FWzë*y„xÙO!ÑœçÁ•Š ³}§öµ~ꃮMÞ§E…EªÑÔ@)¹”Õz¢“´_ÉzÛfT\$Ep‚FLàc§áûx•YU°ÆIР­÷“BKYEgZ´ ›I2y)NâÓ +E÷÷W™"üó5ºžç¼ó V±T´Ôv@G˃:Œ¤e|{KËkõ_kÑ?èÚü-SL3_ô×”ZmZŠ3{¿ƒwDëež¯á%አ.ïÔÒuÝ"ÿ Z± 3´ÔnAŠÚs +¨QÕù¨½CmÔ¦¢ëìÚ]ó¬e(‡c2¦L™ÖØ+Pc³ÈÉ'¬ŠV„¤ß•‹¥ž¯`I0FÂf7Öâ&ažñ‰­bf¡Õö0 íA=ÂCß..Äø~}³qŽúG?<Ù¬ úx û®DátcÓ=üüw÷Ï6OcïoÞ~þû/ï?ÿ§_¼ûSyJ<üü—¯ßí´üíÛûÿxqÿ ïåW×_¢4>¿xÅ÷xqÿÕçÿÏý_lþ«û{÷9^ýîí›×:æ7_==*iÀˆ&€i|ÿûþ¯ûüӻǾðïÞü¥¾p4W;æÿöþíóû×ïV¯®uΞý+Æ"«ý«7ÏW_ú‚ßN¿ôŸ_^Qú)ÜÜÿñÅëòÑ/?ù»ÿqÿÓ§Oô_QG%ÝØÂ[dç/P/BI-\ðIs69Kä÷Š®ÿüá/{êÉ/‹ì¶1˜ÃßáÿÿŸþO=üúðÏÿb_<•^~§2‘Œ¨ÞÊùÞa~µÛlx¿_­õÞÊý¼þ‡»¬æÍ³ç~ñúº»~wÿü]¿’H¬yøþF€.1Æ9ŠéFº-“>@6ËNÔt"â–Tr¸æ…AnÇ‹ýtšTwч“×;µ?Œ:5 –µŒòd-S“dšõhD“©°žYaU‡K:‰*ÜŒ|¾äzì%~è&ÉÙnôáQ¢£EccR·Ó(@êw2o*fn•Q§FX¢#øº‘·9Ý ÅûÕ[ñ,4[‚š,Hè^³‹T9“Uã,K\´YsÂ2×]¿+Cy[ÒiéË㻸6PᬨJPAV)‰öI*|“û¤;b°;¹ýü1ÈÂQ04GA@ñÉ}™V†ðNaö¥Â»eÒK)½(fs‚•à ږŠjã É:/R†P[*ÕcV]P«sfáUüŽ$íœ 2+Ä«øcãÆ™æŠ0AvË +Ú +P1eªÁ©ª$ªªdZ¾Ðf•Íèº.yqpÅ.TX± Ü;•u¬—$æ¨g m1d4€1mthF­› G3¾(›eyr¬ +« +|éˆ)þø(§#Éô0#Éx5Ž5$'c¥Å¤<É•¼<¸PdJfÌ&žëÈDŠdG¦¢*2EÿÌ®±˜2µq'Bâ‰NˆŽn“L‹Ê/Î3ÙØú}¼Æ$Lˆ‡Ë) Z¸ÑàØDøœ8§eÒ‘&LjÉ øRE]'),ò˜ ñÅS¢£¿¤ZÏ J@·J…µ^˜PHtIq˜Ò$ +&ËH ±/…žèæÖüÏ$ ™N’ÇŠŽ˜O2 2’ޏKxX­húÉ‹v-¨Ù*-‚¶V<ɤ…]ÒJ3Z¬ÅZ53 =$PÉç`’CÓ” ÊS¦òÒH.®ßJd°™Šã¤-¦œ-|j¸Ïx’§€RFmFÛ…B7…n"v–VdQϺ”U4ºÊXÉTž@ >!,yV9dÆñE£/ V–žÚrrR¥¦×0³&—š© ¹K­Œ†<ËÌ +€7ƒXÞx^/=ðÄÈt8 HBÑ4O’Vœ6H,ô!›9m©€04$Mšá=MíÌ£`TZÒ“æ$(´ZZéÓI5–#æ–"Íâ‚åVaŽ6+…™> .ydi1É.!eËÒBHp$m,-h.ãŽeàu{'™• +ý1QþˆL^Ä`j޳/ ’™´ 0[±*1‘Ö,Æs›4MD4:Óš <±Œ¬‚¹KvpŸ$ƒÎž†4'Òn$1Ъvõ8˜æ™n*¡-ê$ƒÈŒ¤ YH8}£ ¯2È<Ðô— ³FKX½ \:ÉlH-ùu)¬˜øq¦ñÁßü\@0çÀ\ã„¶™œzÛrŽÄ¥)Õ$ ?»Uo´ËˆÃ!Þvf¾Ó1Úñ$“o¥¤Ô†[éMˆ Ÿ‡¦÷¢o6!L&[ÂZâÆ R‡‰I& â&ÚzÐ$™ð+“8¤Rt«c£pHä׬IL96IA&UØNP}œ I÷%EkôŠèŸ Õ&/õ]YË,àÞD` hît^'E¾ <(Ø]4À4®¥†‰G˜@+^úÃëUWM¦ â×ιþ$HŸç(YÄP+Ï!ÿ&€c¨ n™@'µX A’¤8‚¢cûd‚,3¤H`‰ 2mj‘º‡L¤5:fO4_2[!}L'µ[”ÙóšA…­‰Qz‘ÆØR’Õ—êÿ©ƒScl—S~H0‰@뙓ZcfMQ&Žz ìÚHf fŸ•‰bQ¶R‘ÚÜ&åaÄ?¸ ^x¬õ¥?c=À1ŠqénÒÔyøÜÒhVð¼n KÞôÜñÞ ¼·!÷'¨=©%z±gæ‚Ò$~-Ø™„Oɳª +ËTÙ28°C†ZzÂ$º’×DÍ6èw'‡¶ö™$f‰ +^Úm‚iÀÚ¬%Ud-}¡cÅç’N…Lj ´Y’¯ÙdÔÞ£F·|¾îÍPÁ„+V:3“DwÄ››øcüŽ/(9ö@㙓 +ÚÄÑ܉!*Ñ3›‚®1{r”ÏËø ÐûNþA2Ä{^¯žÓbGéo5 ”Í8‰ñdV-ö¸ñÉÏ€¯;Ë ÎÕY€,œq¤hi·sã)I碸`I!évŽ‚hl– +CO½™¥Âs¥¡ˆ¦DvBjÁ•Y©Ãw¡B F¨&–þrzL:¾™¬˜ç0“„e&ÈËDnüšD HOK˜¶ÔÉÙ•Åâôá^äôeFOðˆÒÀ§Ww-‘»pÏÏ <« ìV ^ð&‰'fù(î3FNNtgs\A± +ƒŸKºIr>b1æ“îÐ*ÏĦIîr%y¤x»—Ñ+ã_„™6$ù;‚‡é“,–³âc''²%³;Òå„R® ŠI<‚W qùaÍh?3Pâ3ƒìz³FJR3V‡ä‚—am †§p4HIB²Ñ·ž'\‰ ÷%áAiËҹºʆ¯g MÈZ/ +Qpc“‹¥¥Í‚N‡Ô Sê%Ùdn·†ŽL™Ž¸8´ÅìÉ I>'Wžœ–LÚÎàËk"÷`¯™AòcÓ?bÔÅIV’˜¦Ù 4ƒðôŽÑaq’å’Ï]IA¢ì „ +f;aw lr‰(ÍQŒÆ‚¬å"#¼ÒÄüV¼ºŠDÈŠ¨®·N!´yã7“ê?>“CâïS[9&w‡ì‰ v“Ü"Fè9ÛŽ–©pêE+%ߘơv*ŠsAS"ÆË@T –×¥7Åé_]?.'»9äàĺ~§¨xÞœj^Ñ®“*èÇ×"`úZÚ ¨Á¡ÛšŽÞc¨ò#ÔÅÀp·–{Mó¬€ÁZõ7´ö˜9¡Yì9BHÑyÉMAUç†+ÁýÒœŸ)àC¼²ªÕD#H³¸QY!NGfRœ ÒP?K7Þ„•µxƒ pËñÑ«BP<ùñ9׃»ÅMåsÂúgIº#Ûeu+15çl5•=MEñ˰þ Ú]?ÑÊäE¥¬t!â¸rxùD܇å9^SFö&3à2õT9It³tE›@¢$7 Î<Ö¥“¦y’E®ššKÆEÓŠ“¨Ù£NcJb3œiýaE.NØFBé%ýP,ý^̨eæp©uY ”³ð»0ŒÒ ­8YmIDà\ÑË›9É¢S¶f„„z>P 5KÎLÙšA”IÈD.Þᔬ)¤•V‚»U"Ÿ°ø™¹Â]®â–-âaPÄ:OðEE?þ×PŠ`½ˆ]Ë€‚r ‘Mq‚ +ê(†‘¿Ô»ß(`nHaÊœ˜ÒÔ9HBRYÈsXŸMÅãc†i,%15Œäô9æÀ¥e/Ái."Ú§£àÖ,°V|Â’‚®Š Ä#$9¬f©ˆT²;«J9¡ b™Ãö6Ú_là¸ÂÓàÄ4žéÝH΋#›€­‚’-enñ +T^'±ØYrdhŠß×:jðp‡9(Hšyïëðt§ è𬋣ÙDÓ_X =5Ø?Œ'*mÝhVHâ<—ËÊ +*>Ä-RL ªÒjý‰ƒÇ’ØM22yùšœêòÄÔL¨P&”œS¤&†‹I€ÝÑ,'+ˆü$S¯d k4À"•$¶¼-Ä ´ª(†QŠ5™9œjðç(hXàCA yЉ$¬1.¢8‚ëäˆVÚ’5Ðrb1«ê¦òyS©©dÔ®j%¡„šãœà"ÑD¡§]Ñc³Q µ4vG5ïϤñ.ÊK9{”¿r§eR‚¶zÏŒ|UÚ¦ibž +x£ÄlTQÉÛ)øO’–b c+TÞIÜ^¦Q.Ê?Lþ@a]–®è¦$—µÑ/Í;º‰;Š.n"†ÒÂ`ùýdrqÌl"9E¥w³r/Ø*Â@¶(ŠHúØGù6óê}Ž ñb¶$ÝD…¿§-F`C°e;Ù@œ«™ÁÌ{í‚  Øs’–'9R)4c°Õþ“IZ@ +((5I9(J6ÚÂ+-š¯`iÀƒØÝõc(“êtR³ä÷“ðÏܲҀ¶s®‹d÷Â8êèÍÏoNS¸HªF…“Š'´Ü™lœBbi-µloœËá©Ô¡ö&—Xbi!|šr¶«W _ñhVr.°f'ß÷<Ž’4¥2[‚@ ê$ ¯‚† +–™Ñí/Ƶ4kªˆò(«’3Û"OP@4POÌlÌ!c(Gâåø‰'8ïl'é÷¨)‘¨q–HT;×`Iç^*ª^AI&SÍîÍ÷,Ü!°4f‰˜À™}òJ¹Cr¼+6†Lo!n—q{÷* +åÀ @™ŸøÁN"YG¹êª]TŽ…R¶ŽmÒvdÅ©“ÂŽ ÌŽßÑ]ë2‰l{Gñv´èz=Öã°<§KÜeŽ¢÷ÅŠH‚"ªU¶ª +®ò¤ ]˜Îx7¸A·¥j)ÝÜæÑ#÷+œ +H )a1!…3ÓaÌ~»<Øcn0Ÿ3úWèp¬òWÒs‚j)CXaZí—ýXŒ•¼½ !3|K´¦¬ }xÞ2tÆ4p“³=gÕ¯ø5U¼Ø½ªcZÚÑ8Æ=L÷ÆiD>nÅ!AVc aÑšàÆ5ȆzlcÔÃJþ]c'†íiÌš:gèajXH›9&4jd¼6n67ïgJa²Q  ²ºÔÆ.°rˆc'ç2Ä?oê4Gè*†AÔPý%#1××õuøà˜Pì§u¼ÛáÀ6¯!‚þ{&¯}»MÒH=…Ãá÷رjÌJ¥{×­H·^‹_Àƺ—‡èm4¼ð0UÏiÜpxñ’칸þݪ@’óenæ[nx«ÌÄ +ÐÈLEC„.Ðé˜óu!ÔHpªÝx¼ôEIò.púh5Q:Zj}d¯Nêb]ð_ñ<ŸƒõÔÅL„æÑ¨§¿Žf¶—mÜAa2s盦ÌRDGÃÁ)Ô¦ÖBh¯ o¸Ž±—@›éÜ*’ +®8cF†(tͲªe!a'_t°{úSÂ͹ò\ýRÃd­÷šà`é†F±NéGHŸ{5ý-x5!GÞºŒ›D+Ù¥v2¤Õ§L„wÂîñ1NzöOùíhnÚF뉭áñÞÿ€ÄNƒÆn=¿®î>ÙUÜR 鹨wä{G7[­‚ƒu )a—w+*7¶nÞøë:–jŸµÐø^µöM™:°–,höÄçØ¯ð9>7õ´­f+檣•ò†¥›âkä–i¨X‘ÜeR¹4ëG¸Í_ZÛWE·„×»ñÆ‹0f×>r¬AXEEYöŒú‚­cÐÞ9¾0÷œW IƆ—ô€¯¤¥$i×ÃùQ™Ž¤Úóóxvc¸¶Ýå /@Ä,˜#ª²ÉbFä„“&€€Dƒ˜6yÌÛyl?„@çÙ:Bîç¼3.އ¢Ìï=SŸ£GÃûó5Å*ÀÌáZHËí{GêF›¼J‹^y,½Ì­÷ª³‘³¿ã8ZX䎿ٌš ”ݲqçv[³UE«Ð M÷¯¢AŸ”ñÃj?"8ÕD9kœ…1˜2¦C CÄó¦cÜ’¾1X•­Ìn~_ÎÐâÓ”óI  HLe`3œÈl±5x¨èÆšE7½°ºl®÷' ÏŒ:ÐûÛr ž?Áò»sKPÝóÚ#ÍñŽûØÊŽTp¼Í=l¤Ú/‚Q²®ü–2w9ìØËTI‡T¾«†¥€î«c§b…Aj…|nØkÌ0Tò²xt3ˆàºyzÝãƒq»M£¶s&ÖIWñ2è¨ÕŒ'Êp äñu:Až,ó§ŒÕ”8/#Ó"aÔAt$kR¼Ìã§C3ÀEi:t„ùD7èW²x_Ç-Ì¥{’•˜0õ¬ùõŠQÅG`23ÇÜ3‹A1²ƒ0(a]M ÌØäx èÒÃgíÑÃ=ú~ý$2$¿¯­ ÙÈ~]PÕíðœ¹Gp?V´K#&­=þµ Ú[²¸Å„ÀXxÇ1aNm€´(„cK;B¢JIë8zà9ñ|I¶u >"@­!›»ƒ•sn§y £3EàqNYÍ ÕÚüv„xl)«ÕbUCöaš¸YQ´õœ‘ÈNJ!¿ݒŒ×æˆó½2ŒšR€Mb®!ëDÍ8 Ø¥ˆ Ñ—ê.eÏp~=”}ýEªm€®€K|ºH +gq/ÉðF¦Çî'`‚gÕ°p5Ä)"®„T×þ–$Ü_jÜ›FŽ$L\Â5a,‰"¬*‘hj§²ój=‚‹RN'¸6ÖÜñˆëxà]* ½¶áxe’h4.­c>î Qmî)*µ£¡âO5¿%Rà2£#gg ÍÃÕé¬Wñ\8¥m‹½¸Ž¨ÀÔ2žkob]da]c†:?Ÿ«{@AíÕ¨`6(ö^ÖYC*ëãsÒ¿û|¶1Áôpj0`Ëk§æ›[ìk@×GZ}¬ÿ#fß ó‰f‘*¯Þl›¸-À³£è²ôøÙPbܯqñl$>ïÁZºúX0Ù»B-K!þb±J„å~Áhit‡™Åp¡±NzÒ6¦rÒ Õè¢Á§?üø­˜F›@U´nÇ Ü!Í/á.NȉÄA„^Vú3â1zz¼7ŒÈU&ž:€‡›×-tG° 46Úã?L +ÑGR“†tnÔG Ñ‘Ð@∫ZU)>W‘ϩ֒K¿Âþ°¤*a*=ªoÓÚnö/ÃÆßA÷ ‡©iê5ˆ³æ->"7öFÖv*¡~#´ß“Hæ$qÞ¿2ø-E¸6‡;ö¸è±•(p¿XZ¾¼ZìF¹w̉lÈIùÓz ‹Cpù¨õCå/…74zÆèeûwN]LÉ cÊ%?Á-ß” >"%Gc +œˆHt¿¥„ +²ýÉÑ›ÚîeÍäïûí(ÖÌÑÆ|¶PèN †¸V¥ññyøqjqÒ7f #Ÿ +Tt\žEF@Ù»:²ýï@Çõx®ŽÍñ\ÉQ“ÌíS®ú5Ê#:‰©›ÂmÁSBd 7Áw%./5u~õ­Ç»…Äíë>ˆßD¶ ¬ln¢>Rè-‘¶àkS%ù©XÊïI.6ÆZÎv¦øö£Œiˆbn +Œìm¥ ?f¤ÃÜp‘àɉé{(}Pt:.€1  -FljV‹œ"—•ô^߸>‘#ª¨_ç_³ôÊçêÿÀê¾™cvgJyz4œbú6¬»î¤uWxiÏ}½v·å 4ü› ±öî+7^ükfòJ£Ò;n>Á l°GT}`zŸ¼.:£`¬Ä8w­¯»võ¦ŸCe€œ¥c-RyÚºž2@Ž5˜]z’žY$C?ôV²6ÿ A…žV½ù&Î$ˆ™†7CÔ;;¡µ ØŽTÙhm'•xAüZ ‘XàO”ed•¥INfKÄ” ž›!8†ö ¿e¼qcKÉ?Mtߨ +€ûÝãO{ò_<4¨í6Mp8Ç£86bȇĎO!×ý‚¯ˆÜ^ Kí|±N =ä)õžÍ-°¡Þ­‡^pAíÁ(³L"•ìòØ{ÓÀ²nÝöÚî bЛ(‰Eç6ÏÑèÉáeßf%ÍÂ{Á~Q3WS•ze_Ï™:Ç•jìÁ[düÌ|"gG^T´>±AÀW¸\A¯›I»â¾§$–ð”èñ£;X`7?ðõí¨óíÁe¹K|+I—(ÿŒFòý4¦˜eJÀè ögÆef”SՓ½Йl¸vN8O"a†ýc«øBÞo’¦£|Éëë=·­ã9Íw p¡$Ôy[% 0Â]ÀsÁ|&k»×ËŸZ}IÒ„êàLÔÛ"JãGPñÊxÚ/Ò0Ò›Ö?´Ž±^m•Ö¦-ÅHLΈòîàGØà\O›ÉãHáß®l¼4Ãjgg¹˜Öœkd˜õÌ '<Ù5<´Ç-g®;7ÄŸZ`”w;Õ[Ay‘¢dïëׯKuÔíÃÑÃZfpA/<÷Ѩ§Â %'cÞ{fÈÈ9g¬¹ä?<¥›BˆTæÅî”D)ÇðHÓœžý†ë Ø ÷ýL +ííx&ñEÈu7ËL*D)œ(êiÁeöú"Ÿ€@ÀeCÞ“Öa¥†ŽÀ»x6C ~f $HtJ¸üƒÔw9Å]n¸LÅáöÏ…€°ÛXV¸±²–ˆVÙÅš1»X”9ÿ”)C}JJÅÁ<îAÑzÅõÐ8 0c .ØHê46ÁÜOÈÑyÚÊKǷОߊ„´ºìaª¢ïfÆv'ûµÐ(Ô”þ¸n^1Éð÷õL/ªXe·)TÒ±„®Yž7»ó¹án³bCÚÈ$­Ðkð-Àü8<™e aCí3£qšÐÁ̹ØdÕJ @ƶwQït$¸oÉ]ì[]?9O},+œ‰”޼ó+‡åîf2ÝVE[ú,›‚T†ÞϬk˜¦À ÿÇs/ò:^RÜDôd%jÜ3®‚±ÂUPÌÎsÉ !(TÕ$>ßèÀÞ×¾Kß›Öõ_T%ÑØsðy(&;™.Û|R9bF‹[)Nn(•¤k…3^2´N)JÂǾf nâxÀ5X™ÌæqU4b#?‘#“)²¤œ›1²±•“\âpVFá_¸·}}mܼ‹V7ÏuîúP:IÁþ ,# :´ˆ%Õ 1ïýpÅ ¿`<蚃p(µ/"o²ÚEË—tÖ+Knp&žwï +¸˜eÐÉõ˜ R(µ4ÊE)t™ið§Bg Øüç{¢…VXÔçTaàïÛ¿ƒãÓ–T®j?¿ö[$Â=@lø¿g”ÝN©«Õ‹©×˜ÈÞ7#Õ€‘ˆó¾èÄMõZ™€î_+³QÓ¤•ô‘ghéI¼óÞNöœój"ñEñH+ K«XAy¸%ò¦Æ( E¶ÔääC§+•Y[3Å41!—AU¹I–$<>ì¤,›u5®Ega¦•B`>ÈÇ4t¹ÞàzT]¨;¬6…`Rf·ú`ʽM ¹ƒü&Ûc-ÐlÏczŪwdØç3RYmVUY¯Åè£mOͽ…YÊJ¡­Œf svÞð/Z…]§:þLõUu…:•'.fK¿ÆúdƒhœÑÀºÏç»À\r€î ­µ-xÆ…^½~x"˜ðâÆšm@8úµÌt³wÉò '¡R´¦Sÿ—r}'nô&Ïu‘‘<ZGM&Ç­^F x¸¾¨a‘¶Œx,Ï ~ÔýÞf×ç»PP§Šlþñ›Ž( ÞÁöžßÔ`"Ò%cªlqÝû†4Q¢ʈ­¾æÇ›Â"ãjî +™¨Øt#Ø¢a3SiU¼ ç ªò´+†Ðâ±A|ä1>W%£eª!;Nü:WC"«ù£ +¶2†Q#éU@Â)) AGUvÜéW)±”MFÀ@ ­çtƒ“r=öÆ*pË-e¬ÚDÁž'ùÿúÌw‹&væOyÚùzAú¨3…ü۽૊ö“TÞ_ü¥°c8ÿ»_ÿþý—þûø?ýÅ_ýÕøÛ¿ý/þOÿø/Cço¼ÿaÇÚPøÁG ¥ªq) +%J¥^Ý. @/iÙ‰š²0¿£Gúi-Í‚5{{Ô1:Baå¨Q–Fƒ…¤KÖ vÛbt¯Îìv…tÖé&“ÕKæy”)‰g43ä½qg#=&”í*ünä cg°mXòv¹Ùåø£v Ô&ù@P‰ÇØ&Τ’観¡ÔW¾{Ìhé eqÆÍý§ÝsÚ²Ú¦AG;„‹´â iÖPµÛÎFz‡¬–ùe»Ï©î6BÚWŒ(ªRUG‡ +Vó8C5!dùô¶`y‹Û(p/±l­)nN15·Ù­ñ}­N¸â•ŒŒ¿î;ê°J9#€7÷»3Ð×zD¾‡ô&8bã91ãÓ£Æn,hÈGŸê]éj©D‰7D”À$E‡|*z­÷•Ó‹Ù¯rÍÀ +T`àfƾQ pB§EѯÏQaáÚ{þ"b~’¿. lU¬ô§B£'!v5…êP¿”¸‘/¨ªÕÎ×ÒyTîf¦=x³4@ðço· d b˜‚°cÛ¾!ná2L£Õl‰Ã†l[Ù¯ì†Ûmƒ£u|-º{›æM#ècáç¡Ãm»–£"QÚIU¸‹&˜rF c"OgÄÇÖíSÓÈ5aó$¬KAÔ÷k޳ñ5ˆ"k¤*Kl´õÚyU>ÜÇÍ8?ÛyèOþܱ6ô–1¹j)»ðÂËÈê“ÞâGó¨ñê§Læ]R!’F†S?-VŸ¸nV &¬>(Q÷,Ë?íDkKáõÂ[™–kEŠ%zøÑsâG/ýt2“}ÝzÆ\z0½j‚@¶À´k ÓÊ,`Ì¢ÃÁs•[]ûÞ0yŠ8ŒÖnK;æ‚Ζ4ô¦ +ò5¡˜ÿ¾À™îœÕ¯Ñ¬Ž¥HÕ#gF\AŽÎ8¼`_¬vª oÖ<Ü1‡u]±‚H ¥)Ê/Á¬¨CÞe%ëàS¡ …JB›ÚOÀ ?áëñG»cE¡Ô Ê2ìQ²ÈïÜ»a˜TÎWo"_>)Û°;ì,Ë%ÕC²ªHóÚñ$ÇoÎW K4tZP´º™qpÍQËAT ¬@à m•#Õ +÷ù³ÆÕ§»D&¯Ñpaø^Ñ· Š’hg6½s®ØÅUˆ9jLhJ0åsÀí|rÄy|=9œ)-20yß‚*k'/Žý˜…Ü$Ä*ay~¨á œc‰ ᮊ' +°Š7,¬ÃL:p¥ã×¢L„bDñÎØ‰2.b8cÆÊäP¯¸â¸º’c'L6ˆ—Ä-†¢49”ÝFÃ}Ä#˜Z4Pf¡­6¶ u‡€Ep,­T­bÉãkÜs¸Õ}‰Ø¯€E$£X‹(n‰Tý<^u/c»tNsÆ\ÏdC!sÅ|Чφ±Ýµâ2÷Ùšgn¼LM£q‡^3gÈC%…6®ïB»q7Ìvn3"™XÅ­¯å™+æõ}tìïD]wVó³õªI‚X¸Œnð€3¡|¾° kî²§h\ðNUš‡›C…ãé<ž‹ˆ×_ltÕÎ#Ã3ÖdÑzÖÍîÅ^# ìþ ÂØ<¬1 SRž ̉1D©ÓqùÒŠrþ¸ Úêáª_aõáSƒ(Ål#ñ—ÏAp0ô^ëó­ØdY3™5÷±êìž58ZÆ„{€{NõÒø(oØ0sÎÁxƒüÙø6•ƒÊ{•Ĺ&+øˆ¤Â9}H4ÐÒîÒJà¡÷aQ/"©;ˆ–Vy( @’nrùØÔ2hb+¥ V_˜Vv„¢©‰VFÆ[ZmüÄÚXB¡4;–×Å`è‚åÚܹ‘ÙS—Í%ŽvDξ,Šh2í='*É"k>~Ì’y‹‰‚f^$SeèØÁKmú¸CG(…Ž+Â\D³@Û3‘e£>Wµ{Rr”7)(1ECà“Ž +bT­ô®àwæÖ/ «ÊÀŠ=¾b/–Úùz—õiD‹§>y¼òDóP-š_¾îÐ>„AŒp ¯ $I æ…QfÇ,Fyá=9h©Áä%%|ø¬ÙBàI`Hoá#qÌ;Ÿ”Ƴ‡µ½,Ø7 Èé9E Ъ-ØSQ7#_Vb”ÐÑ`¼àd"Á$é^Gjro&ÅG#8ãKÄ4ôlö7ðHXùÇ¿ûžÐë1nýá>|Â@ `ž`©Çÿ^o¥}‘¡'ÜŸÙ Î °zÂÏ6Ä~‡mî9ŠÈµ‰œQ ½T«^ H^¥Û±*šÑ–éé¤DÑ›‚ÌèÑê5{8hF|‰\´ PdwK@œ›x퓸‹–}ÂM@ˆ£æVú“²´«Ï˜€ª¹} fº¿ª¹üÊŽr¯Ÿqš +uqdâ•¥Ö$A‘؉ˆ¾ˆXê¡e ¶¥9E€A·*.s¡ËÍÎì>EÓφWéÐ*8A[믯i"©…u5gÔ÷n#Š^ô݃ÔÓ ÷w„Xi£û¿»Q™æÏeÖ< tJˆŽ¨4çŒ3È?ÿzçß>y¤ÌÍ)£€Ê@Ó©‹ùhz5ž¡86[—þæ„D5DUÙ „?.6Œ¡ž%zÌÝ9¤?Â,r¤¡¹‡lÍØ$+·2Vˆ!„ÚÊÐI‚îÞ¦³Àuàô+¢¤íy 6‚,À]òWk†Ï­H. +(Óö–Ü#2îcp†¥A~Iؽ¤O[$äÁçÎSG¢Ží;Ç˯]°×Ô‚>/83-/ß3Èy0¤É,BP®§„¦š%¬’I ’qËPbÑA¡!$$©LZ¸þLÒÕ¯i‰8©$ fç[}@eGçãŒ_&}§å#­ÔYzš¶=l+xY“­åT'ÊíK–Êú^Í9¦MEÄøŠ9µ\ +„[oòšÀ¸Kä’W J\0jÏ!;ëN4d™ýµÀ “ÐQWßÇë—¨bâaTu^ÀáVãÁ¶Yö·ò§)…D¼sÚ|¿ +‹’!Æb qLŸs­ gx, A‰4.)u†|]<ÿ,§…”¦53©;ë‰ãeÈ¡“zZ㈩Ð-ï\JïUÎ î1w²d}¡ha ÀžmWÅúºåøÚ=T–†y{yoR?`Ë匭)"oÊË@.+4tÉÖDˆÁñ4ÇëRnAƒlèÅ?K½A¿—Èë2Ǿº{wê; Ÿõ\9Ø´‡\lÞs,‚¥z àŸKþœ;|†&i=ÆH+â5ÃXLtÕÃû0ŸÓ[¶WĶFcu¤ ”.GØ<þT|„Îf“lx»¬Úó˜‡ÀJÈ”sSè7YÇ¿RIb-ØÕf +JDñõ_Jkd{ŸÅ³Um˜Ó1cYbl&ä¼dp[hItªOW˜v%ÅÀ ÁßUh«šÝÄUXÀâø›9 #ï/&ðn¯{%½J2dÔ¥4Xáè.)½Ä_£F7ö¾ñùfÙ€D…À„†W‰ƒ dá¾) é¦vWÔFÔ±R[¥"”Èoïü٠zà‘kF<§X'.ÃT ©„öÚ,nEBfß!XWŠ”“¨…£À +Z<³¥â“iJÁ¥¡^¡;ùR=U0ˆ˜~´æhÍ2¨È[ñò÷NEî^SmGòRÇ.>®ÀRľ{±5+ü¢±óC[2îFá\Iø€l©x» +Õdx IÎ-Y›S@UŸˆ»§¤¯þë¬ÔZvÈ_f7Œ5Ä©˜ù¨›Ôؘë¦TàUš&"ñxæ(÷v,]ΰ×NÓ£,tV+Õ4~ÏÛ®ˆZó¥2ÑIñkÍØ¬5ÿv¢åoU˜ÇÍ”óÅ·Sï†~‰a"íPªúš#íw„ÿÉ +Ölf× +åÛÛEûéƒ9^!_’1õŽ•¸ÂO'¿^CVZÉÖ7Er Âj°ÎÐáˆ}ZU# Z²T‚™R¨ôPÆ\Uê;d*Û”%Sy#˜\ß…×Q¹v[€?%PÔºrÄcLµ·WQWƒ±ûMÕÜÃIµÝ—7ÚŠûJ0Åj$b:!¹ü¤§°u1ñ’Z‡• +•M{‰„,{$¢Ö…ˆ™ÜtAý«Z‡Tªóëï‰<¦õ Yú0ç‰Þw§PÆ‚ÊÜÕC9¨¡9ys@ǩǖøº#5  á¸ÖëœÑ _S~è®âp¨>–A—DQ;¶·ŸçW,ˆ‰iYDGh0à‘%(p¿eÍÑ{Èöß:e§Õôgv†å”RoS'÷N‘ÿG/5)7dþã´„ÊÆjüÈõ‡YK¿æ~c¼¸pû÷×8®ìu·CEG&ó¬Ÿ Wyï£ì¾{Ë+‚\(IW¹ÙÓšGT…»Úl˜»·+ðÁAXî¯ÝG`à´¡˜‡D• +Ò_ ÇEí«õj3J¢$-噛âh윮åoAÅãIïÚ+Ç<ŽJ8Ñà¥ÕÃå×@cG®“¦Ç 1†ÖŸ›Þ<ÍŒrƒZjõ>ͯI BÜ&ÏjÛ\V÷x5|OÓæ_£Œ~Eñ9Å×x +ªÒÁ §V³ ¼VÐAµÿ±`¨kâ„â ÅtªYJŒ4ÅÿX­¦·”cK¯S€ƒäES±5T%¨ÆrçNƒˆæ“äŸÇ¢á©¬A;ÖsÛkv¼sT)Fk:âkm2Z>VËz‡Y'—ë#<Íy^F[O#2ðV`M™4¦E¡×õ8*%¼ãç1õûœ=G\Khåá liQ¦¿Ð¹X­–]èá[Õ,Ò U£‡Ûpéy•ç¬aÐ@ ã^1‚£ÝŽH 2›4¸=,LÍc6¼¦âô>ž€âﳑ|‘ºu‡°Ž*m(…ö2vPÀ´€|¡¤Pe¶´ßU,™+¶˜m—‡ $b3Æ£Œx2H'ï +‡þHŠªˆº@ã9ßÛYP¢}ªD̸úwm<1?¸gÆ«(?£ørÚbuæ2%ÿàà 4 =©HžQÞ”Zøå/-+ϼRŠZŒêöÈ b-o >;›‡ ¶E57MÑ”°Š”/Àñ‘"ÎEj÷¼¼`¿›“²„é£(i3õ¥bÙ÷ùQ÷eÿØQ]áú½¯÷mí’k‹T<Ù˜nô÷ 'uê±*¬†yÿϨ(m‚«S½–¯1¡d:^•LÑ•<+=qsû¡Ç\z8WÒ¬ê#xS)¬±2„ôo‘ÁtÍ\ nwBÍ«†þÖKïáŽÊèFd>¡n=^ Bwa]ø5Ó¨ÔÈFÇ™B¤£_®éz—‚¸׎ô@_m60mÅ~à ;kªœh>}tØEbV|-ÞŽFR(·ÎC€¦åÛTÕ:Ùm¤‰Âœmξ²ÅF¡¤v¦)VÖ…ãé«Çù®*óÝšþøpø:eŨ¾³ÊG7V÷ñ“£*ªh©~1_¬ )®£†„.¾ú="æºCÜtνc*¾EϯÀ@dBúÕº¬ÀÍs§ìûLm´f9ùV 6«2AÍbÛˆ‰©£$}[ÛNÚÙÄÓ¯gü-N›ª6‚­ãW~ËÇ)E?zi¶w†€€Uôª ¦$<›Ñ#4 N-nÈ}WØ1Mˆ>=Î=FPPÔ$=_S“põ¦¥Ð$SàhLMïnw¨CƒÆ!˜DæÔ^æ[5‡Ý‰—£óˆÝØåïç:1cÛXšf´abÍÝ2Sw`Þò«œPrª0Ù22OF÷)ŸøÍp2Q«ºc úÿ<†Ç] ï¢ãr_­ö³\»Û:íix=°2àÛ~F^˜ciíñÃElªd;V²€Äu²š-µù v4@†T:Șê­ñ¹tgÉöœæó#Ix@ZÓì6ê¿Û"þéß|7úÿVGûíÁÎ_ÿþ¯þñÿ¯_ñþãÿò7ÿò/÷Ïÿð×ÿñÿþëÿôwÿôwó/÷Ÿÿz|cêçŽÿóßüý?üõŸþñŸþŸ¿þÇÿã¯ÿÇÿü÷ÿò?ýó?þ—ú<ûýë/þݯÿýã¿KPῼÿñPW8ùÜǦ °Bb»£f+ÃI b²# +ÿ],bRWí<ÏRQ8õæªÇ§ÀÂK\á|J+ ÿÖòöœn€K`;oÁŒ•^”6ûç#LFP-öïµæem£O>4uTÑ-ï’OHž°·G=ë²æÆ\2ºì=‘5í‡êÊù©+€3ÄPã©ø¡R'0"+²¸W£wŠËo_šZ§Ï8òÅø[§¤Dwü¹„W¡Ïö; dÝ(cÃãÁˆ»À÷cÂQí÷žê à|oíYo’Ž[²¤ 3ʼn¡çkwÄŸç{k-¾úb‘ë¯"v Ѓ¯rcSðç½B©ÅÁ ²¬:oáº!Òiz¦£â0œBB ×Ò@óxÉóŒ3†?»ZñjQ®=¯>(·Sb‘bÔs një ͸çl¦šÍô|c»Ɔ! +Š"¾.çÌÌÔRîJÐ:!t¼§—ƹý”cí„û$—®¢­ï%'ÀJ2¡zGÁÜvΓuU PÇòM¨Bygk˜\V7+76n/Ö•ô#—hC rWïre3öñN•ÃxÖmŽø:ñ5Ý`Ü<'j‹øxÉé ¹Oݺ›äƒUlz¦` í«¸­ÆßêeŽY3²!:†‚*¡ËªˆøÌñcʤ‰1|ÔáêÞëÊåePS¬W‘•˜zãdNk8†‰;:í$ÿØTé.U¬_7oêð!ϹRƯ-QDåiÍPoi;ÛLÆúLªöðÐn±dº¡åá§Ué°ÈšŽå +ŸÛ Èû0ùøñ=ð&d×±t›Ù¸»J3*=5úÀÌGžˆ‘|8 œ¡YrëÂKu2ѵ”o»)}ƒ“õW¥jQ„Ê¢^žº•H¹§F™™œñ¡2 +ão€<7B5ãÉó'*$÷»Å!ßA¼¹£¹UñOÀ5lm!óϵk¸0¥F +Îl(A€AÛ Ý'.½Ä—ëÞ¥Âø:޾mï•/ÏÜá‚ËŸ¶÷#áÔ¨ÂÓö>Bñ³èÛ\ÛöÞ…]ðh`º]®÷“ø–‚øÖï§ë½|7 icŽ5]ïe¹ÚÁr+an‰C`¼ÒÐÃ}úÝ{­Ešz?ô¹åzÏSȺÌî¯RyxÜßò#Òö¸éŽ:˘£€,{Ã-‹QãÎox˜ÝG+e‰)³¼æiPO¢[ñ}¹Ós"5çVây˜Ý;Z\ò^ÛìÞhÜÃX'зãEs„³‰Ô÷»Û=ù1l“{TëÏxÑeW#S?ûaj£¦‹Àûô²Ÿé¢å`þ¶ãz>dnX~õ$¸Y·–M=z[V2†Ó•žò˜Æöp¸áóÕpßô7ŠsõÜÖóã² ç‰mŽ›y\¯a….wùÊ¥’?MåE»ùé%_å/öm!Ä9§]Îñ5ˆŠ¿ø%¢å¢*çYæðüíyÞ}3…ÈNŸ^ð¡‘·<^~¿ë6^¨å÷ÞD»µmóNžðåáî®hëËÔ.Ž¥š)§PÔmIO ÷¢6SÛÎíXó± ,Ãö°Ÿüði/š1¼|Ú‹Ú>÷¶gço¬R®ìûHÓŒ]DÆ0c/ìy™·ß=Øóœ½—õ:åèÂbŽëD¿¤ÌŽëæ(îm´žZŒ€å¯þV¿Jv“TNdtå[u$UTA +7utâkiÛD ‡åéá® üqmËtñX9m§t¾„|Ôà íoQ«"|Ñ9‚–Ë×¼¦Ø]¾› «þÖü°”„ËòÌ&Yîw«s´}UAŸçHÚBy\Ææv8}ø™ã2|Š*×RÏúöç¥åÇ»iùøðƒs¥¸ªzF/‡rþ&+ø0&/W ÔåGîK{nòýç»ûxQ’äÜîãc³&—éxU–#=½ÆÁb¦RѨªÄqm‹q6Üü‡³8¡^+ÛPœ-‘e(N3ãá#ÎÕp§–}8ˆ ¸¿Ë5¼k6¯p>›žàòƒùû Cq GÌ*PºÖàÄ¥\ñr‡1Frz9‚cÇ@`ð0¹åà°ôHˆ-ßo­isyú} è +4¾‹ù¶{û{ã¸ÍÔý°õÆ.Íéæí..çmâ¡«o÷»w7ܡ̬?-»5l­u;uó7Ƚ‡Aw"ÀCdùr§¨»,7n¾ÃÚÿîÁ… ¥e½Å·¤í¸¥V~m¶IG]þÚðr楿=Ìy?Ý´)ا¼?fìN}ygQÕ>÷é™ýŒ¡º<³YãIÍàmàòáòD}3Æf›uô—öDú§ 6ægá¦V­Ü¢òò¼>œþN×,^ˆé-§kr¬$ÛຸCzøZcGͱ}­©ª—ö²³¾ÃÄäéb àåèÛÅU˜²­«Ó1¬÷•uUÛ)§—A5ÕÂ8ï›A5°·úæK8V½_vÔëï‡ õúp™Oß‘¨™þÑÙöP´ÙòìhÏ‘W^]ÜÉ”í,½ÿ~7”^.i$n8î¶žCîá}+Z¶YtŽZÀv‰ÆC¨ÏÃz#ê—=4@^%»—-ô!™#_O;hÞWÁËú/EG€JYЇ†a þš†ÐÀka Ãg°ܷϳU­ZŸöΘ""§5mǸqrܶÎÌ0Wþpsf-$ üy|.H ˼™YÃ,×ô™[jä²Ìšè¥ÏL·f̘—æ°ð9_æÌÇ4þZžÌdÒòõ´b¦²TÈçMfðÏjï…ñ2³{ã‡ß2+|Ëf ^›å®ŒvÍùiªLŒ`ã9Ù¢(¾¼”ùûÒ´ð {ÀTAœÎÉ@½Â˜"ös ì®PæË'™È ìeÌ­ªlˆA"Ãö0C^.d`±W€ã|NÞõºßXÍÉ6Ëèx “ãò7¦=…ßñËÖ˜yËÍ8O™Íeb .Õ§u18 ‰§c1ªw€Íü§ä6¹M[⪈aíÛ–˜Ï=Èô®ä7½¾»íko0?$aËŽay¯¿VÃûÃé0\Y:%ÅúŒs_0•†‰üfœ? S±pôI¾&mcá³L]š󾿅ÁÞShû Ÿy‘Zéúr|ù ó5Ò5ËFøä½ˆŽ–gZ®¼>Âö:Ë·©/ Ö°Z Éî/ÿàS…¬Ê ÆœÞûoüƒG*mÙ°¶™Fħb8¾r¦óÛ?ØH4Ðãhé7þÁ\QЇjN‘Výð¿Ñp5ô¶ûÛ?8 Â`NÄ\? SÀÏ;à`V +›å4‹•èpNsÒ‡°~²@§°ÌÓ{÷ÛGØnGÜísY3¿¹óñA‘ôi#ì-žFØKÿd'îÁ9\Ã/;aÆåO¯Û ûq–$ÈæW^&0é +Ô¿Äêú§°á³ã!e/õÃNØ1}+t-ýÆN˜úºÈ€Ñ”ŸvÂŒƒƒjÿXÐ¥~Ú Ç«†ôÖ1F ‘Ýv¢! 5Ñ`ÙõÓMX«V$I±jÍ}» +sº¨nÞXÞ¿qæ2Qüø2æçЉh!~óm&ì¥áÿÀ¬ÊoÌ„ÅÏË:¸©ÄÔo3azoaŸ&$åa&l'@¬m¦Kð·™p@õÛ·‡° ྸkJ*|zÓC©!¬³JÉ¿1Öøö¬*Ì_nÂÔ¬Euˆºó-y¸ ›io¦]k‘û÷£›° fí]æü‡›°¹ÎÛbYßfÂwÅØ¡ýÆC…e«Ó;'À”Ò·eðh8¯yüoË`Z‹kÒÃ3Ø/õo§`ÎrO¼Ð—A0ÙÌK_`ó½ â–ññ|øs·DË÷ŒdúÙø¾ÿ éO;à›t²“`*£gù÷/5£´oËßKPsùvú¥a™;ü^$cŽòmìKYÝ/Gߨöæßù¢ªiܧ¯énBBƒÔ™¾ü{Å(nè ç×þÿ^o{rÆcù´ïuŒ^ +øŒßßú·}/þ˜à®½·²cu™õ’¶€:=zù»´‡3/!ò± y9ÂYs}xµá<Χýî)ÖÏ"Ø3—oÔÿ 1Í.^¦meƒûÛÇý^ç¦\F¨Q~ùð:4´vJÊ}lC^–å•b¡ÿáÇk%®•DRãË׆C/Jk¶¯ kÐÀ–ûaÈÕu§SŠeÈuí(Y“mCÞ(¬ÏúùÕî§!/w#ˆÙ2ùòãU¹ ”KzéÛ˜—%㸣ª ï—1/“©hÈ1™Š{ZƼÄP1õã%WÊ´>R1pb)W?ŒymU©ÉBy_ƼBà¬Æ‘ÙJ÷6æ¥AEmÌK€¯>œyiÕç·ïªçvæµÁHåÀk-mg^ªêÉckõéÌ+‹±€Z›œeÑËZŽ4 +3?@®mÑËÊ!xr¬eM¹€w¯Þ`l¥ÉØBçgzõú5CÒñ5kWÓ«÷4ûŒjà\ž^½´&0|0•rÈ{éÕûEô +¯ÞS׉îÇá‡W/­Á`¢,y^Û«×5:ºÛª×ÏÁóy-åiÕKx"(:ô¢àûÕmMç²êõ ýUÎ91l{\Z•Äí«¥åÞ{ê:JКŽ#h+!#® wl|Žßý7Z dF+ÙÅåÞëy²:xK\Û½—†ï Šè‰‡{/;¹ÀÄYÀÎrï …* +l"§{/Ûݽ±2‰‰ôeÞ¢ìŠÆ päíÝ;N?Ãø<â¯ëÚ&¾iåBÀ º÷pñ•f«DB\¤o_œ2FCR]-\|ý\]•ÄBןv¾¶ŠäjyÛùWNñxÇzÌ­;_¯<þèqåUÜo?ßàñþàã˾6û³0_ß/FîÃÇ×]´/¦Á²>¾>cûHß~¾v@=–g»ãçk7é‚Ì­}ùùz)N.çpñO?_héRÔF,Â~ãçËSˆÝ)ëïÿ§Ÿ¯1¶ -€ G_6kà]F¾ búï{‹àäaäËe5ô¦Žx#_©4P¨)ýú/$%9xùS¯0Þ…Óù2Î]_ÈGXöZÃj–ÏÕ‡?AI<]¿;žîϦÑ)Šì 8–¿)©'E§ÞmMoõÝïífJ~E×Á^²¥Îåfªª¬PÑ<3:ïn¦´ÆÆšœw¾—›©ØN*'ãó£©Ýµ„Z0ï&¦šJô@ž¿~š˜ +IOJÑŽ¸¼§ífê7‚oyDÎòÝÍ”EòwŠ>gh`i™Ânæeazå:çRÒˆÓ,ÃR/Ø­ûxáÇŠ¿ K ŒÔ¦P6?K мmì÷Ïm\áB[ã}9Îm\JCèÆœX¹^OãÒ ¥ˆ…RÞÆ¥4èôÑ!é„ßið­Î‚~¬*ÚÏïÖ¥ÆÆ”›ˆY*–u©Z´ìÙ:Åæ†éaúÛ˜ëO;,ûÿœ‰©•&ì¨4á6ýîaj£EF°¿5oÓ¨>å(GšX¦¥‹Š•¬±ÁVöîfj†:‡£UKñ5•)Ôãå*¼ÔÓÍôVMôÃÄ”Û23Ò·´ML¿’DËÄ”B͉‡ƒ±æ§‰©+¶í2xo7SüùX|÷v3µÁúà¸W¥Ë£"ÅËÄ4ªDÔòíG´"ÒDQ#Ô“P8ÐóþÝÅÔ +ƒ/èØ’©^.¦fA¥“ulÙ™šîpyì…Àº¼ûš~…øÓØÔw44_‘;ÈÛØ4ö=¤¥Ù÷¤þ46ý©UdÁ9…ªú´Šelªü-ø£§º‡¯©ÔWt§1[9Ò¶5=u¹uÚP‰Û¶¦So8…Þpؤ¾lM%œ(W«Vݾ¦a6#ó‚lܽ}M€fˆºˆ¸¾¦ˆÀ@Zv¦¨€Üçv1…GEåá^ +ô»)ï[,v!(t/ÓRË*wá ˆ’—i©Éâ6i,áÈ"±ÁÂJ9XXšbÇÌlƒË —ªWÛ»„­Ådö)>eš–z¢êVê,ÚïKÌ)¹ö>¼J­ U‘ýptÏíUjÖGµ†8}y•Z6ÐûìÍ¢”Ä7…åLŠLŠeH*;>•§)â”)–ýhyÒÛví*³Ô§Ù(æð×cT}”PÔØ¢·Ø +>¬E!Üé^–¢=\—“h·b—ž¢—½+oßÐÞC1lº…’\&±ô0 í刦Ihc3ž¹šƒ¶YEyx‚âA@lY¶¨Î,P½ ~÷ýäCâ˜i÷É!îi´yp]òÃÝSà-ØŸ)#Ö©lä¾½<¹x–‹‡—'Tn°ýËÂS‰¿”¶s'–LËÇN¶G).KˆRA’.~ŠþœE¡öôå$oÑCŠÈH™QúráäoI;ïæ›@}eùMÏM0è$j—Õ&¾€Š›¨.¹A›ÆšµF§å§ è¾åÃF“Ùú-MàÊ,TË÷8³fyïö™µSj¹fÖ䪷/!(öôÈD="ýòÈ\[¶å‘ U*æÃYδ1á‚ä€R¹¼ÁêG¥ía„ɇ¼JËÿ²ºÖ^Ûö’+ÉÁ®z¡å`F2ML·K°\ýEÊ@×2—þ´¶äçÞ“˜ [‹1£wY"B…Úÿòž[âå_©‚I-Û·’ú‡]%œ¨Ë¥Rþ}osJHo)œAv*ØqÛ‹òî)_”ü½Î³'­Ë*ŸX‰YÆ“«lºü&QÀ¼âa3‰ ù‹é.©ËF/ÛTòî1”^’”ŠÕ?6}µU²›xÀsyˆ‹ˆ–’çÆ"ÚΧ™¤­–O¸ ×6“<5¦K6¤3ðú3R/!mJ©‘ž3IZoµåÅJ·™$1ÏcHIÿFÆ_k²8þK?ãëÓD’•¸ûyâP²M$å¿RÒ!µNUëa"Iô͸Oi˜o÷EÓîñÚÇ1mg"]9Òîi"LþŽî©²ÝQLýüö ­ öaëd~ãÕ±µËå×—­£=ÐzwNóÉ/_GìD”4AØÆŽ>÷©B__ÆŽ_Ÿ?Œ­^]İìœÕü ¼ÖðÇî¨þ×6v<‚VÚ‡¶Ž/q+ÆS‚û²u¤!%Æ`!¤kÛßÑ-YC‚ÍÓÞј9½\)º*Ý0ÍmwD… ûÇ—™£¿Àg:V–û²iæ(Ñgœ!S$¢h––{)àP. ßÝmuRs©áåæhƒ£ + [jÛÍÑu-øÄ(k—§›£[…øé±÷íæHƒ¢Z£!ét<Ýi@`îvö»ï§›£I&ï¶fG_nŽxMû@)ÛÌÑUàR»C©ûiæhîÉ'©nSGfH¼ËË10H90Hw~Z9*ØzÖÆ½ŒHál`½¶‘#¥Ó¹dê¯O#Gµ}«ÐÄ1ösÞFŽ4ü]þQ‰’0¶x9 +¦U`§ži nQ’q—BÖÓÇÑ£©¶yQx¸8‚j ÑnÔÙSÚ.Žzâ(Q~´JÛÅ‘oø4ÚÐ +zº8‚»es½ÌÅÀ\/kF`ðB®ˆƒÎÀí¿ˆª¸MjÂLiïõ5¢_µÞs»7R8wÄC·àx¸7ÒZô®9xïÚtoDÌ]O°±Š¤<¹ÉúÀ”º¤ÒÇëU¯§{£î 昴nJÛ½‘†Cén,Ìò6oôsm2ÆØ`–~˜7ª—Î<4Z/Ïro !õCñÕ˽Ñãé_3Î3bº‡yã)ëL ›cRXæˆCE©úY^¶y£&#žg¼¥å|x7 +ú8ï ú¸îíÝèM@ºt| +Ï=ͱ|Q»òݳ‘ã¢pݽûöly-‹6U°¥r¨ÕZ4ÒI»Õ†e‹¸ñF{8êÆ¢/ÁëÓ¬ÑA":rðP~2kôzŠ +™ÈÎÝÞ»Y£t'_-%h³FzD cìú<ÕV ·j*ŸgDе€)ˆ¬õÀÔ`z¸6J¹±ŠpŒ‰¬§‡kãWã—k£ÑÖ ã4Å>]}ü|¯ñøûD…}Û7Ò-ÞdtPïökÙ7Òþ#ãÉÔ™\xØ7úUÉeÈ»ë×Ïövs#‘69ïîáðÁ„¦°r î2s\‘o!¾?›7J†rD7EHû0oûì:4¶$)»˜ò2oT3©® R2Xr_æ\Ã4„Gÿ6oT\ .¨R‰tÓ†Ñ9ÏWÐIzù3®$›U¿õá]¢ÜòåÕ¸~´h|µ~83Þdï¨p=›ùow\“‡chžÛw‘„Šù¹e·H5µ•—E*Ò=¦¹b þôöT¼B‰ði¥8>´ +¸ÜáRâZŠäd5ö{÷N$ï×Þ¿Óõ»ZF‰²ÏDT‚ú¬gÛ¡˜qØ!RhCPöá‚«Z%å0?¤Ö‚Æ×ò Ä$ç‡ç!B×^V‡†Žk ×åêÝ×6èÔåkÈß7`¥igÈß(’=ì 5¡DpÚÂ1W¼}]¬T§ô7›i{ŸÖ_wʼàgƒòÖáÌ8ÕËiL˜Éxƒ[š~„m¦§ !Q6»®å=H-7lûÂr#thŸNƒ9lq Âø†Øµeø‘§Ÿ Ÿb”³|³~óoö™Nþt ̸ÂЙ³Æ @¸0Ó»5`Ñ ¦lG@‹.wßF€djMH¾ûÿ‘ó.jÏÒÈ1å%§Û_“ep=MþøÐÉwzûñ¥;àRQ¤;¦仕_í½\~ +$æ¼ûªAz÷°µ<û€o2h§]ª~>Mú¨Á÷XÞ|]çº-ùºò?O#> z@"—ÿ^O!ºl÷øó‡Û0^ŠFËeÈ®ô´Ìõà¨Lðî©Ço$[VzÜ‘]³.FÕŠ2ßÃ9Z´Èe˜'š.œ–Äõ´|Øã5]ìûvÅ[‚bË ¯MÇ%?RkËún«BMË»¬”Ùùtº+g@E—ÁÆg°Î¦±]ÍQN|øÙ)݉jÒ”7ão0z˽®ÊÊOÓ:>Ì÷Ë«N½Î–¶E]Õðá|ZÔ•;ÃË™Ž@:…}šEÚ*úÙGÙR/,ŸÄÑËd7©Ã‡ Û­ØÜùr_+ê1½LטÎbD½y­Õ7Þ^kç\V§Åƒ¢œOc5FÉ2Tƒ‡C-}ª±pú“ßÔ[<K¨ÎÕž€à°À#xº¦ú­/³42fq}¡’¢ ŸÖhc!u¹Ñd/õ—ü¸’?ÐÈæò2>ûÃH{ÛÝ9ۇ˕Ëûz™›ýȹíi6âƒjIoVf9å`–æú½ŒËc@½û•äl}»”±;«aîîdÈqç§)ÆËe{‘à8"cRu©.É»õØ¡ZtÏÛrŒ*ˆáå9v¨‡1èËkŒªkxyN³1>‹åi2öÿÛàLªlžb ðzp½½Ž¥œ½Ä€UÈþx7#=½cù…!“FÊiÙ„)[Xî§;”ê±uéZûY^`üÝ?Àj +Uæeü~…‚êòûR—”"Ó»ÍW­¡dºÊbH\›çŸ6](‰NäÄËÔë:7PÇIxBÔ^€òç.>ä~.î[+ê´|º°í‰Ö—;%<ÇeÊ…2€r糨° ®‹Ù:ÅtÞ +/¨´­³úÅé‡ÑIm¢‘õa»‚ä²lµÖß7­õá2Ñês^nX]mÔï,¨#9PèËpì¢8´œ²ößïYëÃå‹¥-Ø]¶VŸZŒ,4ʤNó+îþ,ó+ïŸ=bÈò˜Ëêª 2}Y1Ðs|éUÂÒ ýÈåguåX¨—¨ý8¾—{yeÕ‡§ö¨ç—{•9øóéYuM%ÛeUeføjÛ¢ŠtmiOc*Kµ,?*‘8¡íŠH§ûÔR^®S×úÓ_fS×|+ö˜ºÄÈ|*'h󽬥ø[¾ü»§”†1”+5`Ç›ƒ¬r¸‡q” ýÞ†QƒõsFIœNO›(ĉÁX.w(Æ#¼ß/S(ïñqýÆ êR¶º~[@Ýkcôéü¤~D½~ãø4-̾œžø Ê3}ø;ÁýVVåG['rÙ§xlïöížðÓÄiú'ë¦kR¦eÓeѸnC¦5›< š`‹¤Þ¶/ÓuÆãø²SêejÃÿhÇÔ®i¬ðÙJ½øeæK’³®òÏ%„=Q{ý²ZRñ.î§ÅRŸ˜Æ‡³R‡‡x—oC%æNp‡_>J£!\~òOjVTÚ·mR;¦›Ã§[Ònx7Iz}ÞHmªÖ~YÏtÓG¡øóm‰$x´üú2B‚X½TýßýŠ" !üõm{TîØE}ÙIHç"ï{ª_ ‘oÈ¥°ƒ~sTAŽ˜”ÝxA +Ìe Öm‚»*Èy’E(bÞóóŸÖÀ®×qXUü»[·‚)@#ˆŒ€gnZ˜iˆ¤<0ìO JøRÊÏec>j‰34vµô¨[Í©¥ ˜VÝ:R&P„HêxñḢ°€ÜÎ °³Î˜ºÖ©Î8UÛâXf5x®P§ŽøUGÁõu¬L‰Ä(4²1E`«=Þ“æs!7 +cO•¯[P®NÍGwRqà©}ÕHpáF¶ ¬#,4¨þ¨~…ðOÑ—[ÎÀØ’!Ç:zßaÈ‚icÒ¼zPOkB\ôvÅK§*ï¶ÈîÓcrìòY9ØØÀ1Ø£>Uí@ã,@Œ%9Hˆ‘»=ÂU6ŸTgÓû‡’czʼ¥äj£ÚB—Æ<,5µêæË•“(¸ +³ˆÐ=¸|çe¶›ÂJç ®šÏ "Ë‹WڎМÂûÕ«±unN"¤&O&¢«éuYvå‡çÎ>‰‚ÞòJm›ZÂy6!òY 2ËAA  5°§¾£h .â>9 °hGH51 IF3‹w¸Ac‚5 ÆÁÏŽn ”ì•5uîìM<Â_t ?C)‘|ÚÄHck¸÷ã-/Æ®„’Ý£åº3¡[ B2Åû’ã@×ÓÑC‹ä¤“+¿ÿ.³‡·ãU´Á,z:vwB7{):Þq„ uì®hUY5ØT“I _Ì(·ýr˜•±`†»v"ô"*KaÏšñÑE{¦J?IñRë,…Œ +ñÕMèãêÉxÞÛ¤ xÓ2KjŸq£R²Û‘x鯬ÚÂ1Ø÷} St¼|ÿa óþ€÷ÈɲL`âÄ|Ö`[èŠÆ!Lc«.eëL¼ïɸÇóL'c½ºMõ@Š$ýQϸäÓ©æ€u=ì¢ÇÅk¾p*6!ɵNUBž®T!|û0çíK§¾ãlÚ7ZÁ5†{!ò:ØêÝÚ³+Ôv´¦z(i²ÈÖîºUÖëDoøÒÃÞZÇqÅ÷Kwtúì3Xøñì+}¡ÔÈ`éÃDÙ–w3 +©’Ý\^ÆlzÆûqeŸWš.=j|ntUºXçøüôÉ$^¯¨AmÆm©Ö|q‚¨¸ ‹ÆÃø Ôj÷ñ§ld2çù¸²¿]ƒXP,ëÊ92áóNU¤yšlÆ«ë˜UWî[`UY™©fãîáxÀìzé®;Îë¿1Ú½/Šç¢×_4\ˆ£X²/å#X”2Qâ|¯J‹÷ЇDâ›õ°6Vùüú)®0tCab,„c{sÐ-Ÿ$¢íÁæÃ…‹‰r+·Ì팹‹éèZÛalë*ê–š¦—úÑKt8½6½Ñ(¿‰é–¨|GeyŠßôYGERÜK!L!(+•FP~<Ô{ÜœBª¢ÂÛ …pçé­=VpeòqÜ»ÆÄZ™ì\‹&[°rqn'Ïw¯Ä•çZ ¹0—Ü Äš™BؾÝZB‹YÇ#ÞD$Ïdü*2¬WD¤ÄÃD¤¡tR[8 ¿çWhÛp=º]§­bùÜ_K†K>bhå³qåx­%’ýxHfBeA8à(×–2£[g±ÝÆ‚{ÎnÄýhpF…ü-hIÖ¸T" ×Q?ˆØÙß2æš=¤8Œ’v\°“¸°ŘÄ:yÒEFÀØŠÌ­pžâªî­sÒ¢ö€©C²»gç®ó^x"96`ÄzäL}â&߯$–(ëúò4 ハã%äUL‡4V˜¨L6ð#OŽÊ ¸ðñ-Tמ°O©Yòa†d§•Ññaª¡4¸ÔÙ8bò7ØS_ŸB¦ü6”G÷Œ+v ì¶w&4IŸ§éŸÞ-–ß8 Ð]¨5n\¶ƒæ 5%j¼ +ˆÅµx¢ºµäè\ç|¯ÃV•èi8ÀnBç+ñ®±•½P {°ôÑCI*æ.0ïÜç–eþ¾øübÈ" ã2uö1_­ÞÎ6÷µS?hì"N‹“K_Þ¿,¢|žÖu.ë“ÌŒØìr…rÏ/E\¥²ñ\/æ«1ë´à“IJFœÈËÙLn 6D ¶¨c'Ôj$š2ûQ<8"EÂŽ%¸·$ + )㊉&þë9­W¥|’|ÝÙ¦Ðñ‡)¨/ýyµ +Þ·®)>J·‹LÅ= ZNݹ*—ã'z°ÓCŒ= ÐǶøš‚þ#d€K2Ÿö¶Åƽ€n¼G7b׆lxŽS©`C­ëQf4¼уT[ä[ÿ‡’i+S¢†føØP&4K'g˜PÜî€KØð«JŠbËÍ‚:~ÔUŽØ#ë{ZoD=ûw™š@LÒöaùá@˜ÚPX=42(Ók¥ÞAЩ9¤¼?Ëñb4‡ÈéÖ¨ÔÐÓ fÃYþ‰ëi¯te¹B¤Ô +܇ÃÁî@›—z:ÅS€¾1~TSm?SK4«`ݾ#f¦zy‰>z%Ÿp›ZóÜäW~ìq^î(ÙÝy¦#Îtoå­Ò¿XwðN"Ï—õXaÿR=rëô^€@úF9«DZ„­!=ucn°ŠM£²µëI±:\o%Ô0*‡5<žÎ˜ƒ‰±£»ÓTÁ“ƒ†f}-?õ¸ÂómLâ…zÉN÷)wÌ~i/Õ ´b‚Å ³x¦³›Ú?y •ÉÇ$q$‰x94z™‰ûÖd›3£ îB]n¼¾ʽø–aƒ£‡.9¹Ë±[l'¯¦²/Üæk6üUDÀ©'·<Ù +½¿ÄEÎýÂ…TüºY}M. H¿Ñ‰Q¢qT Îô¸ºS£ Î|N~7ž«!ÒZ ­á+S‹›yç¥CJ6Ø«çåå1M>‚CBUuËø<ÜGpe=ãÊ.í( +!žúë·-§ž$áÇ4зÍèN)x$¹ªgPàTcÉä¼,ß;¶øEYïÖÇ) ñT2üŒu”=1Ûˆ•Îm$š•…Œ„;SÝ…iOg<Ó9ÊDolªøQAää!ŒïˆRȧ;«A'%޵Œ®u™¬À¡»ÖØ+Žà6éÙq½Q4beF#z&¶æÓ³¹×õëc›Ü5 Âl=‡<'Ÿí)¬tOç7‹Ù¾îuÕ;ð9íñã 4Ð=*¸b/0®›%ÒÏÓg>˜Á3¹„]]çúw©vH|2š©?§£éÿÍüˆ(À·CnµËÐØ‚üðÈÿÄbMŒ¶ù °ê~=ÙDî­¨bF¿y' «ýâxZM 2n<8™‡:3Gª)~‹—0~ËYY€n*¤n…äeÜSDé€s*WÝÃÎnô@ÄÅLI# ‡,„CiÀ¼Û|û-Ü•IÍW|?žŠò¤' ”ÅmL9.Pø´=P˜¡‡Z <Þ¶ÑÄÛÛO*ÉOÀ˜’ñh, ?q*MŠ˜¨6ï—,s–¯Ž_tÄ`8PÆ”u¬%ÛOY\øTt fÖxº ²ÀØ„êÕî'¡$zúÁx×yûJÖ°¾†B*äØÑŠ„+‹Éƒ(7Ö—‚¨(§vÖ)ã [ÊÐO‡€]H¦º—Ëž17#㥕Ö]‰¢y†+„°FpHê? C~ˆ÷‘Ñ oŒæŠeƒÍÜBÙYÝŒ#šã©Ô#Åx¿ÆF˜áX[ß·íøcVבº£ÛÝ +›zÇcV+¾8”nÎhWAEˆáìÊ{ócŽkW»íFL ä}r¥¿Ýê¥ËE’Ñ#4¬«ùð@Æëþ˜s5Ü݆$ÕˆvzI¢”Àô,˜²wCµsÎèsÎß„ËaÁã¼ÝJxÈT!Fp‘êÆ ¼Œ˜±4EXÞNÁVw˜Ìƒ}‰ œh÷t€ò „ŒÞÖc`Œøæ²G¿7Ì%Np´* +r£PVêÜÉoëG2Y|.ßÎhœªýÚ¢Ç oàØþ~&òeŒðL°dgvpïàÁÓ#_NûÓÄáš°’±¹k©s"ÓÿµÁ3m¾:¨€ZÓ +, ˜ç“Çqz£ÿ~tKÒ!Êïuo HÉÊÝ‚uÃ¥óäÓi·ûHL}‰CŽËˆì">Å}Ä™;·ˆGx,œÕÍ¥Ðpš3d*@ª*;_ ÓãÎV×öc.!%† ##ËšÂõÇGÏ¥ÙI‡+OxX6ù¾ÖÅ…ŒÑ ¯ÎÀAYÎÉh‹åµxôX<Ø/]ªIp Õvcý•گřË ‡8‘^VsØ ù¹Ôƒ:½ Ë-¢)ÙãšwsÉú½¢€{ÆBié—·Àí«Íؽ´j,EšÇ‰1-àΈÈÉH²X"aêú:oz8ÄvÕ½+¦yˆ®îL\(ÍøÜy ^[±ÐcŒ†êö Wd +P‚' Ô\…u¶ª` š‚:û½óÞ?qöë@(ÓìvðWçFë'#è+¤ü^¤lBª=®»Î™7mŒ¶¼§-yÆÂÄ÷W·jàŒV%+*W +˜xô¸Š«9iÿjH™Ã­±"3îÖ˜íJD5cªMvh á”êBÕãE!AK/T -íÃâ¦kUÇŠéöš°¡ gn¢G +}®”2Úd>,1ò4Lwfs8è¬7OãqR3&0~sU™‡ÅXž¹[.†=ÐÙ±·IÞèS“ –‡ +Åkþ¨†ôG«Ø©Û*[®I6Œ=P“_3~I%át3@' 3È€õ¦1Ý4áJÓ w–§À™+Òd,+ uŠKÈ ÇÓ±Ÿ?Òì?a¬o[š«N N¤-e:Coµ”£IS*sOKÊ&žxaa´ò“2Bb¤C ÷ˆµÀ`‘jÏ ç˶ܹ „PçÌŒS®“†RÄ~› +JJÍôœærã^æxÈ¢&U›ÔÝ#L…zœgR—/« Ån¨«ÉÎ l—õÑC0Ø2ô…1TÄ‚‘ +GÊò…Ößžu)ê^8B#yuC­Ñ@h%l,íã;ZÝÆ÷£Göö5Ay‰"è1Ö +2X×±wv’\“Ç©¾†è :ƒŒQäÈÒ­ìŠØ®r²?A­ƒÛ¿ž@}K¶tšûê!–Ʋ° :r­(9ò\ÆC!M2ô8Õ墇Ύ…$QAo.†èì…4=ªO½¡‘ +j +zÜjÏ™`¡ÚÇ÷{›!ë©<#ã¨Â××Ùþïî:á9¤—*@Ÿ ¹-»ÝÚV’®Øív¬…‰³Æ‹€^ï¹×)æyMÎ:•rÝFÎ “íj¾ƒ§ˆ$!ZìMDã–nÎ(° M³„[]#©(¯˜ÄN{¹¡ž}· €<YÏX¿T„/äô(Àu5h@$ˆË»c îÃ8§ÄÙϱcE¤( ~æÁÿÐ t‰Ï—-¹þò`ó¡¹yô:'ÏCEœZp€‹Œ{ð›š"í‰@•3d>‘!&gwZª›¶€­O(^ ¤Æò¦œmBèÌòn¿T÷àdTUæ˜ÝÄ6BÏÈ÷Bæ®^ÒÕçDÎK@ ¤.2tÖD’oL}ä¦qžS|=2‘øI,„EÙjÊ"p––ÂKÐQú=†®Ï3µc7<·ýÔ8Z¢±»IW€ƒImɰñÙ³,·ÀʶøýꥨÄ!<^vîð*þáÄÌ1z€úǠ̲ޢ~EÎãêß=æØËÜüþ~ +ÓV 9ÞŽNf#–’¡ûÙCÈ£äuFîÛèþè†dêíM?ÐIÛ“† ˜üy/Îâ ®ÀXO^Á M¡¯ñ¢_±P²3„H·ÛÒÊØkÆqšXú1§Ê[aA:E¼_UÈ5Ý|5À<D°›ýV~§I/dfƒ±spï±G:cÔÙªÓº +=šÏíºb¦­Ð–Î:{¤èñ¢±\eREÉ +·ÓRCN;&®Ò­!š¼G8›''²·S.ÄYz›>I8/ð#Paµ(W*8ÌbøQTYµ[!;ô¸©Y¾ 0EÆSWDp µæ@*•íHkŽkŠþ­;d Ûl'úäú j×s– ³Ržàà +`¼õaR²/mÊ~OÚp¸<† úÜHºÅ©Bvd,)Ò`´”Ìž*¼@ú5éìákçµ°˜s-›-q^ w Ó»4>9Pó™¶® !˜U5b¾ãšË›®ÁëÞ£EÇ» 0/¥`‚&rFؘ>?< a¥ì껓kL¥DEhÞc +ÚjÇì+?"F7™5 st+fI8ägNeª"‚t(c9ŽÐ”¢!ÇμiÐÐd›5Jü³[ è› P"ýêÝCŸÌ¢üØ"õ8µže£GjñÍ`¸àF˜ßÔ$Ž#*ì­L ~À-@“ÍIøT,blˆ³xD¥ÞD¸•`ÀÆ;‡iY'=KX} +­ÌÇ2ÍÝ«ª§ÝK"4¸<è¨É¯ñ‡\áÖ ô1ÉÓ¼±¾Â«ý€èomHr°:ðW“-MlHñ‘(Rù8´ pog÷ænn4¤þ§h™G±Bx‡#ðdO©!ðû&âY2×èÑÒ'…ÍYæ1’=C¬SQ'ez  ˜ƒ¹Ÿ1˜ÏU¢C:´½é—%Àï†bœÍì…[ÌÚ_~w»C?ßÕ™kJ1¿~²JÃï›q¦y¥ã]1`„‘Û‚_ ÔƒWÅwt4×ÉSqýTikEë¦Q¬·‚×;ƒÝš®æFø÷U“ji–®Æ A”´H¡jxŒ h¥N¬Úˆ#˜Ž–ƒiolèPBòû=ng€ẇt]%b ¯vñSü˜Øföùˆ0ãuŸÑ-øðÚf³Žy&©££žê´OþÀ˜äZü×_äoDîÒ£³ÇëõÎS/f hcòC’qžSJßóQã%>J¤Œ¤iSiPZf¼l5çõ4>’mlŒ»ÜÙ1Q µ:gù¯€uèÎ[“[ñ<5“jŒt[þ—¾2œ¯þBà|w»f >veiÊ™‰tkú½×̸4S-ŒPµ0ÃlÉÔBÔC·oŸJû8$ÃŒó„!èpF*<À8%…o4’ÀŒý®Ðc®ÔT!œu¯I‰À‡·ï¥ïz²[Û vn ñ•B?‚°ê¬=¢ªšô^$©x *à5Ü‚Š_Íö{c&úDBu€N- ó yöv·Å²i!Lꨱ˜‰bm•õã´¶4A“þ]Ã6Þ¤ë|—»9ØŽY#>ÇéÅ -?ýÝ×ZMV$‡S¯ Ü[Û±91URƒ¥èq ·ÖÊî§ib3ù!Œ°[^k)|ÀD1:\9|û Ae:v Ý’g*áñy„ä®{æ;Ï…ž×RޏReÃîX±¨Ì\ì¸ÛSÕ@ (^CMp”¨œêâ‚?±w:¢ØE +Siºò™"ÚwÞ„iâ“m¥Ì÷M;eV½}r¶ŽéTáÊ!çdÑkìd*å kPí«…â)øåùhš³È®‘çTº)™Ø— ™Oqr °ê®ƒY6#nbæÑK=Ù©ûs öSFR stÕRE!¤KÉ’ÈÐ}’¨^+#~Jp=0î#µA7ö!tKÓ ˆ +%´;Ι—›s–${ÝFaòè +žQcI‰âb¦'M7v+³4‹ ¢+)÷Û¹ó.1O(ç"©á¢ƒíâú*ªá·®äŽe%#V±õz›iUm&j|!â~­ Q¾’̶´*’$”‰¼.Ë𠈛^·ÙBø‡ÕºÉ{ùEóâ’‹èŠ8¤•JD˜†$p·èSoÿ’anÈ}5Ë}Õ`ª‚ÝYЇ;(w¹:ô§˜¶¶§­6k–|O¶|­h#“„æS"%œP C-ÔªP"7Ö.@ŠÚU²Ú1O%¹[Ä´ÍYJ?ˆ•£7ñ¶¸‹ø Q´ó…«8­[•DùÕ4à&œ…yß^K/ÁÅ÷ƒšÅË :9è’®‘;Årh=|™VvIShSŒd1 +O<ô=8· mgç&è%q³äÅ£a×ÊœÌÛ\ÀëÒ°ñE'K¤¦è `:^ô<„6o‚:'wkúõ#IÉÕ£aòþÕ_BžŽUÆ:I&Nr¾È€%ÅØ°3€²MUÞN¢XÜ!ñÉ/Yñ™i‡:,¨H‹SBèóN4ûÖùX—¬½Å›ïk–§hàØºu|^¡“RÚ”~ïJ%”Ó¹û-V=Ú*‹.Ø\x„ÐC;‰Õch³.•Å*‹Õê¿>‡‰X¨%•¿?¼Í—»4C²D;Í2.í‡}X‹søRì‹CBn¸A5Ÿ%Ñ ¨z«|«ê¦”Hf+7ðøò™)¡CÖ^)\¤åTF®­ºd#{jP–\¹?=Ùí;ª#P[ ÷lqO‘Zñ2I^»,#¶vF’‡ù7’û@crœ¨YÐn6–ª.®­íœ[xNV:ÿyÓ—¿f˜œ­ô'Ô5ë©E ¦¯ÀòlçV¯jÈïš7ªzQâѶ™bá6}!iÍf—¾ëJát’ô˜O¬}mg$ÓÌ)DI,Üë+ á$,&Ûf¯H@N¢² ¬Ñìv=OÌÍÓîÀÖVõ>°»áMú;Ì„ÝpWô!.\A¢Ï.üäë2„É[4ÞžP‹9üAòJš*ðäùrÓø‰@ bþF9ù¾¶ Ü«c!o6 *ôé= ¯0å_nÀ²9Gž¸»…Š|µ…•¹ ëW Žñ-þJ,ˆâ1X\¥1gë1BJ¢’?`Òb ¡[|ØR-•#«`;Hۉà ßNØ\²cøžg¢Úµäò cèÝé–S~­ÉȲC+P!cïisv SçY¬.,a­zòzÊ‘èœÚ{«Ü‚o—¾ËíT$ÝÐB4©mЬTuÊ«Þn|–DB¶9¯¤9¤MœÕÆòwr ¤Š„ʾ`ÿxó9ÃÄ­¦·yKr¯»GIµ iŒ¿ýá¼Õ ú£¹/;Q§°Ù¯ëíl¾Ãª€“o]!Rf—¼…—”h‘PrÄZ•'!´ûpÝiõè9 xPªŠÑ ÝW˜æRŠÎüTU“—ühNS›W·u!Fž­ŸúÆíÈ—~ðôœ^Hl×8ãûDçïi/÷0K£js÷B׊Ö'ûRdm‹6 +qU—®»›ˆ¤·BÔµbv@rͼ“ácïzÄ&+ *¯ï"ÐÇî˜M4vK¬ +ÄÈÙ|… Ñ?‰á£óŸ;9B|®&´ax”ð.(Q@O½H=‰êZ|eåNo†}‰AFò6ËEäÒ8BJ7͆8¡«›ô&ù"…øKòÂ+º;¢ð©Ÿ=’6’„Äyk”ô“?uC¥«¾¢nÒ4¨È¦ 64'DäS*2›%êRÿ”ä¼I¡›u·Cyh1-7óýxãí=ÚÊÙN¨1 °}iEâ +†Õ=d¦1ꓬ¢ˆn…ù"pÞdpªð—R4¨ä;GfD9˜Ü« K ÅéBÒåJÏ'ä²Ñr†eÐz¿‚Þ#`(OCF] ç7ý¾ƒsó_*Ÿ¼zHkôüì±pŒAÁX†Ý«‡˜®kXöôô0%%4ÉøÓ«[-]Û1»ê6gç^t¿8k‡CôIÚE(“8½U\S¯= ±6 d̹Úo£!äu*¡‰|½è\{Ñ£ˆ¯˜?‡À÷#×~»×ß×Pt­ /ÖðÆË›wËë‘><àT²Y¾—×tº ³ö§B*Û=Œínrž¡_20¼ÒÌ“j0Ðí{ÜØw0“œŠ^ݳ ¢3ÙŠqŠKÖýµÜ®3ÝUÒ>£ÇÕ’²¨Æ³J°ƒI?'üÄGk®æ}>…1Æ¿/™ðªTç™3‡Ž5 ¾éBõ”,1ü˜žƒ¨•‚¨Åfø©041}=¿°>Z¡/>îË ðõSÓëA‰ämáµÍºJÆ!gÚ‹;ÔºæðßÔ.¹Á½t‡\ãê–ê @‹¨µ‰Á›…z‚ÀH_èaÇ×[¹ÍqÖÚpà3úSÑ–؇ˆ"ƒé;+A{1°C(?d;ôÓ¢õ]ˆùOý<ÖNèI“ÞÔKJÞvx[¯]|kþÎaKĨÔ‘˜»¤Ù9øÝz9pЭ֤` +Û ˜OfÖUÙÍñfÒޫɸ×z'`î[ÄÍvYšw¤&þE.·ƒÐÁÇóC@ŽKqè+È{ @ ÊÔ SàÖêßÅb£žá’m}­¬œ€&´=C’¢@¨ #M†©áÉ{F¤xT,¦|o¥•í}X—/(œFÖ +åøvsJVÌKs_Jqu ,­ŒcY‚Ž.–Öì,PáÜi£%ĹzHrµ±#½»Q_«G;v¨YVëæ°(õòÞÄMœ²˜¶tHá¥Õñ#k׺ÝÐ4ù%¦6~éÒ}éÎ7|ºÛáÁù¨ )߃:¥ÐîÓ£Ëpææ,Âz±Tuª7V£œƒ¦9}½F¤ƒö<~I¢ŠGS ¯ôÖÞ”º×¾°Ê»HŽö ûI~zÂéCÒ5aúú¥jõb¤@T"g;t?¨õ‘âInMtc¥BR÷b]þµ7Ò*Ãü¢e@¥y´f‹p‘º|ù…É7ªà´xË.—þžçНyó&ܸQ±F“zHW‚9_>/wJ2%­…>eÀë·7Ù”‹`ÊH;軓ð +h¤)x`Âñ8€£ªC2`÷s ºe—^e'#?îPÀ.» +‹[»œâu w^\ËÚ¨¥ô±GÌh‘™ÁXJbµ*Q¨ª:ûÏCßøšàæøZŒ®„®%4;Óóûnw xï +¿H…Àñ9Ã6›¦Ê$¯$Cù8£‰3PÔcÍ +éðº*ŽÎ€íÀD1j­‚šÈëÚåê×Ð͹µÔßÓÆxš`o,. K¸0°rõ2è•gœgncÆ }[ݼ>"¢W=ºZ·Üý²ßÛ+¨0¢ôw>ÇIåËé·‡ +3‘|)¢ç4ªáÀ»šèB(Bq€õÂ+èA-Œ»F”žè!|-I0Å5<ŽMKàžøfu“)©¢ÊdT +ðÂ2ø8¶Wõ´‚Љ=u,Ý’¼3¯QîL“ªôP äUÑØàC.%¶>tƒñB´‡Z)~5EÉÜ0¶’f h¶bb—™–ÊkÔ P¶ Pî”!ÝHÀѲ†%0²ÒïëÅmæ¢Ý&;)õ¤Ɍ͢Œ„÷ ©Q´ eñ@ڼТÖmç„(o›=*ÝM®õ!õ@ÛŒW`ñÄ{ä@5…Åìµ Ái>ÏÃzwÈ(a{—<O´¥YöYî?ƒiÐÒ4=È»ˆÕÅ•úê,tUÄÓž/R‚MU Á®nId̳Ոœ`[¯Ï•œ§¼‡BdÀxdñ6:®?Y'¦òJt–ò=‚'Þ˜Ã6 /[ÏÆ²DXOÜÞqLi¬…šD*SÕèNuT'2S5În=è6LX”ö ’Ä5Ô‰æÞø‹ˆ]¡Ü[–EÈX¡Éi1iñÀ…à ² ”FÆES +ÞE½†¬‘¯ëåüTÈ¥LË QS ¾wŸ¥¿óO’+EÝ”hßû %+ØÏÞ"¶—d£ìÖ½ÍWDëÌX¯¬nšö¢r±bIÜ»ãÝRpÆB)!¸"©ÖõÿÀ%ù®èëà$B€H?¹xmBoö—k0ÛKd‚JU9”ª¦_-S×T÷"ígŠñ¤úåÄ“üÕCE– +yð„e£²Ò:c%b«ó®ˆ¸XðHñçÝmà“kèZ¬ Q,7ÀÄI²cã‹Ìá¨Q™vÓÉ©Ž@ÙR'Öß’LÅ“DR6ÕK7œÆÚ MDví–âè0 Q,ˆŠ)^$U©ó§æxvfŠB4(qŠÒÞ[¯R5=´Gñ¨õ-Ü´&/?†´$=CìØz×ãÍüFOææÃ@WÞðÐ#¶|ìܯjûÐ#OƒÉÀïÖCþØ­[g²ƒ(ÉF©~h“*÷6vº–ô™ØýÁ ê?y+M\Šƒ¤fe‡ý€íl’’í2ÆÚª©¦Å;$ØÚ\aH3âZLÞ±þXv¹”Dò˜¢˜YK¶åZOlÊÄ©hŒû»äéµ¼¨ž¯BÈ%äÌTub}¿VH!H™šëI{³Qº t©—È,<ÂØàö&H í¬ÓDÇG½4 Ùiع¨]ò¡—Ýíl¥oÉÖ0…Ï/òáH€yF× îR¿¾:> g÷¸ìNþî<ÝC¸¥û¨#=x7@ô}¾^IWmóºdŸ\[{2è$„I¦w„½­Ý I6°#tÀDE·*¶œCé>w»˜ kÐZÞóðŸ«ø‚å²^zàÚD»­§;X‹{ º"©Y=æÞ½Êé¼Èk„2¡µ²MGÊUžÉ’E Û!ìÕòqn ¸›PBd1“ÞE%.Й‡Â×bîD-¦/â¢Éa‡¶a72a›ÝSw³Ól·RMw¶ñpâZ“´üW ûhÁá>#,#ŠR×| ÝL朶¹^§9³^ëf!Ð*›Y­ûgE~*¹n¢Ôv??…,ݺÌI‹Ô.^vã3šTba1¬oE%ädé&ÔÒr¡ƒ§Õùèuwƒ|®¥ZgÙK#â*݈|óeׇ)5uœ$¾;Ø1¶ [7ÙìäÁT°!;(ê®· ¡"¢K(w®V,ë‡ç¢V88mšŒÖ4Lµk‡¸IÄŸf¶›Ëð* †%`’ Zön਼—8 7C´°ÈÁ—-(, Òx–Fã•åJ Ùý¬åÅS=0s§‡0«G‘IÒÚì Ï¡Ÿ’95‰ÙðQqUºœ¸x­ðOÆ­ WÐP½yc?:%Ú@‘ÐZö^¤„T [“Ùû…ÍMƒ­…kzìç§eÓEý:Ú”2¤‘üŸ‹¸qÓ,ö 5¤¸m=tI؆–Ó—DûE™¥_ËË +h^õè&sU}1è Es„¸A˜£è ¢3ÜYÍÙ•^Þ¼Þ_)¶“0Œ…S§œíÍ!tDÑàK/ÈØ<¹îÍµÍæÚ*˜¡‡¦ylïŸN& ãdŠUÓUßÁê4×ú·ì"‚“•áŽ$Ê„$ÇüÚ áŠçËá@ËL‚ç»Fç¢%U<öª¤€HMêä7;•Ô®…¥›7®X{R£ûç§ö|ùÉ.MAz E†.Êê @rZö]W@Æ"eé3zà)Á)Íö¤_LâÑàÒ/äˆN\ßS’ÏPb‚ j…¾mƒ¾zHÁR–o-L'EüÊOùÕÔ~>’ Áû=®—X^dhF>†X°Û`r¦ó €Ðé®÷¸…î $ó#gÏBEÕMÛeNR†!€Ì1 (yé ŽcÃ@i‚¬‹if4Evm¡DÎÒϾ.?Z¼Ò_Ï^³`9›Œ6¤ƒªD|ïYBzV4¯òi¹§¸6¦_1[Êš9Fh=àýpÌöj8ò‚ýÕÓ§[“,rRMɺtõX¡FS1?/»ºÍ&Ty^=ê.´.=“Œ=²ìu=¥ +iÝ¢Ô¬˜R0P2 íê.Œ7`%ë˜Pœ(eš®'/ä^#6@óœ<)[úô…'„¯ŠZ”'E;6ÈÐ#‰IÒ Æ®ÛÉŠU® ÞãZz\Ë‘ÜB¦œ¤¨mcWæÖ°·é/*ïvXcLÜ6 +c×XæD‘\ãrC]×ã¼ %öÛ$G7yÓ­3«wõ­ ømìk\‹h‡«½[ÕaXoŠâú}üed!¯‹2¤ + ÚKÔz.ÙA»f˜û’»ôThÊMJVPžÍ xÞÕ%ò.î@ «œò©Ë¦©ÑË'Ò ›XðÉ2ÅzYäÎ öåêq –,ß‘X ,;êhR7˜tëa•ò…§‹¥šz\Žd‡³;‚Ôó·rÎë,‡VBô½|1ä!¯Í°w,¦î¢e Ê§h0-Ôï0‘ãs–…ÍÜ!±;&ð¬šI™‘²\ð'ݯ1IÀbAšÄÆÕ »©]±Y¼‚Þa 1è“21ëÖ 2¦¹R5G1àHŠÓMøOÑIíaïI9ìY7g¢Šrë]¼)äx¼_CYõ3¹Ð Ú*8¢{ƶEw%4õDh! ,ÞLvËq`±)Jv݆*UdŽ0HÆ@h¾ÆEÖ…©¼#\®ÓáòpäíƒÈ!ëœr¸E ¯-‡ÎwÄŽ“ÏуîÓÉQ9* _s ¤HP€m:åt…%ÌÞwÁÄ’²µLPîWüuÈE쯰 ¾õ¸®p3ÑRÓ<­ñü‚X]r@à^­Š’R­Î2úºD {ªod4òqo8¿ú?!§k‘$†ò³ZèA§r›ðZvàëÃ::gv/ªùãzÖd\Ã+fé2Ä«Ž?,:wƒÀ3JLζkÊ ³Ã×ËY&áÆfH‘Šçk"Õí‘cé­EÌ¿QíØdGë×»Š2Xô–¹ò)ËÔ—A1çè6[]Wq°÷¬‚¼ƒ`BÐÝî¡í4šÉ?e /2ƒãÅÐYU{¿ÐAJwÕxcI…6wß0‘R)‡…Žs,©Á^­ì­å¡Îõ¦olœ8B]ê©£hßðO¬LÂ6Z¤1?ðH-Ï¿ƒYr™Õ†h†¤ävï{øƒºÏ·\vòdo!PÇí*,à™·ÞWà{ùéîŠrU%Ñ[ÝmkÁéHúßwZYøá Ñšîa; ~ýŽRïN¨]æç§´§’9[¡;,zV7‰ŽŠH3…„\W?¤âlàCH”ÌéRçd§ô˜ÝòØ$w¡4¿V•x¼’>\ÏC¥cl™²U¾ ,‹šüÖNZ›o‹t½ëÛ +W¨e T1%¨ìG5?n$híÔ?ôk¡1®û WÞ÷\’IKR·Æå‡wÀ@QH?9›ô“¬ž¤R:(zDªg‚ŠDžtM? $¨'À+^àî·?p™ïÚ/³õ¡æ·S­yßMÏIá<óTÈJ¥q]h»Bâˆt s¹Ö¶¹íº‰úõŠä •!mtª)³x‘żR$º)Ç—0¹²¸·Xxë.Å´žस6ŸÉØ›H¸ñªÌãºF·brñÑ…ÔC5 s^¥,z³²"è µ™Z +ãÌW¦DÊûñSÃ^· ¿…rh­‚¹!<Œ{“¹1’x5œn}@ë +÷èoMD<]ÝÅÙË;*öTÛ—(²{â&I®‰@_n¶+r“)°ßi© š5$ž gR6ÍäÑÔ­]{6”rUVÆpµ+`¼sp£…²6VK©D|­Ž÷„ôÔeξ!þÞ˜¢µEZïMVRˆgºGV™±Ÿ‚cÉ/LI›R…~Ð^{½¿Zzîi×ùhL²{ÜGLÚ+RŸ”»0,ÆQíÕŠòeI. c +éóžª ,ƒ¢°SØHXW +#‚f²1è2B®|¾:éX=4¥‚G[ÛÆJQЧSõÒ¡MaCåMpΫi4P|mÙ”8ªèák~cÁFnz¼:L;Tà!%È*æ0€ZKíÄ„åϵF!QVjÜ6‘êç&jÖµžÎxÑÍÈBœ ãÁ(³Û³ƒJQsªÇ!Zêš(ÃgNP~þŽòoÜJ—AM^ñÛŠɇõ#Ñ0f9ˆ\xZW¿ òÞºÅDzÃA3a+QZ³ÅŠDó)Y °p/}/¦.t2b–¬]ˆx®l»Wì>l ÐCþÊC6Bô°Y’,„ÕC“ÐêA–çù!mÉ*°öéÓb^½”“U‡,'˜I>]l:ƒ¼Úè_?ñâ(WöS}¼7Ië¾…¥©—=Ø‘Pvý:û±KHÊä +XZm½ß/¶zÄÓI®‘³ñ§!71Ñn.p(V¼M—2vº(ÙUaT·•‰{óDZȞ »¸n’,ìÞDœ¬zÊ +0r1Á IÕ]Æ ¹PYšc.ë +¾T;n#d-ü+.‹!âM¢Ã.E–±Ù÷쉦-1Z`SMÕi²(j¥˜†ÈÙ‹|2ösS:ÑÓd) [®)sòx&£ù ã ±‡Ð3œÇ'MæóÒ,¡Ú’[¼Ì#^f&[Õùï…EBÙ~‚k“BŇ9”Ž1Q¾WËÝ’%²¤–/yŽbSŠ{ £¾è\³ÑÙp5y€`>馑lÊÝMK‘>§½lϱ”è&SðL¥”Ý­†`Œßâ6üºŠ**铱w.W;Ì +endstream endobj 130 0 obj <>stream +u0WMf*ËMº“E•Hfê%\ÓähÛ~Ú~¦Œ)  ¿2ž’íèê…Z»éŒáMk) ³zH5Q6­10$X-ZÐQé¹ZH9ŒÙ-’TgeƳý²ü©zÊ›¿màFWrº™«¡ìJ§¾î +(Ö±G7… 0 Š0»±é| "^q×”ô¿²ÐìdrdG¹+ÙB9«jg$yÉžwå>FóT6ôaëØOÈ ÕëÒn{uÄ ,y–¤¨c¬7j­ÝCr%·PIáÇB3_2ü‹_’^w³^w®_yyÛv›#–32?RÁ ½®õÃA1—’0¦¢@y6ºÔ*J˜Íú–zŽ'r[èÃE… 5Çüɪ¨Øå·ŸLE|þ£g=¬!øÇí'KoñW?üð/oö—?ÿÛ_üøãw¿ûÍ·?ÿ×oÿî»ß~÷‹¿ûÕ·ë/b¨¯wü›_üú7ß~þá·ÿñíÿôí_ÿê×?þ§ßýðo¿}ÿë÷ÛŸýùÛ?ü=ÿ¹Eÿíõ_($¦7½SUu²ó -úÌ FÆ:‘vZº¥ ¯ß‚}§$óQB”¢ó›xügˆ$>‰éKyD©„Z–ɵ›"8éöíý4TyD,Š-f;4?5Nÿ™ÔY±:U]=_áøúõ+¨úÞ)Ä«¾PÜ^sÆú‚ºTOç´H+Ay ’IR¿á;K§ÂjQzÛð‘~&NWëUdý“Ðᜆð Ï!°31}÷>Eß.û¦cª‘¥î­ã¨—v58¾¿É?Zù´€i{öfÙò¾å&·Éþä>ÔÆÛ6Oä‰[(Fs¡ÜÅn¹õ +æ}[Û^íUq$®²I¾ƒ1,í›u¤U(A«Nt£™"ŽeðþÖ$ßa¯8‡"Ó¢}ºkëϺ­d{£À1C*¯‚wšQôf6Uò0c{íæä‰XO¦ó9*ÿ$ù!r:oªÃ$pb‚d.H¤çL>OA>Ÿ{¼‚l¦€ü¯£¨5ðgÅkITB«ØÉ‰ëïölœò©L›1ì‚0pôôŽñº»UR&6+@…ÐeÀÇb ¹ù\F—å +¸E8a÷dòIs]tÿ$m_—<Þ¡IˆªB¢^ÁLÀ—GÚíÖ§ ?tÕ›ö®k††3¥j¥Êïý@Þº…³gQ(²‹õÝÓa雑£T²þŒÀ[¾{)¤†ˆì޶âõv‡]:ºø¥7Y èuœë~è‘L„ÍßlQpû@ÒÕ®¯hï›-8ŸÂ>Q4 +Q•?«ö-EMœf‰ ©ùö›”…óØf¢ Þ»ßJŸT͵¯•0S²$6ì°ÃÀ½jS\8YÔöžc£5T·›Án·**No³‡¶A©d!ý@ÂrâêÖ\"E°5—ôk—H9§Ñ­ +(÷žõàH­ÿõü3 ë˜ð±Öº´µªEËõ Ú®ƒ€ƒôÛúî8`{5oyÙ.Ž‘ã€.ƒ©Ï£­-§hÜö)káS¶n'>p*H* zØ?¯)‰p;ôLFƒxÞr@7¾Z—gÓÒe準 ìê½Hcƒ´L³ý‹p<¼…ÂøA7¢hN!!'ïÐôˆ×ïÏG†n ’Ë;MӇɗÜGÙ ‹wu¯+Ô½¦; 9Vl®R## •MÇ+EùÕãf•¥ÊØ6Dʪ·F°½zØJH +aÒ€ª=ÐÔyü"†BØñá•ì +@‚uï§œ=Ñù%Gœ×®íÊo®l¢•ˆ/ÞÍû\¢ðpábuuÕ¨ü8€t§À—~Y^bäÛÙwÄjŠÅ½¬øœ«ÝQ®dرž—°}ƒ)Zâfm>à1u“¬]HÔŽÛ³'–Šò[¸’‡°?ÞÚ«¤xÙzlݼì’b_ÏjÓâø‚ü‹ÛµvkÉ.`Ý\¿Œ£[=à ¼þ€±&¦^}<5P«†=v¬+H­j=¼[NÇgluQ'•†¥ ôÿ)]`Ïä[ àrG%?œâ9½Hm +þI*¶¼7ðù¾µ‹µÛFs´Š žE@³j^#Ô9¤¦h–š×z6þ饫ÜJNsˆa¹ŽŠfuKXôþ¨Êu#’p…†¤RÃgõXôH± »=eˆ'¿¨ †uK¸DAk‘@)¨eì_.s ]9­×}¬à{2õ© +3ÔÖSŸÝn¶VÚ³aÄTø1¥ÓÊZj§±šÏF¼IÆ:–ëEÀ®Ó@ónVâê<Ïj}Q{±$ÂÂgË[¤9Hx€¸ÎI”YÖû2tàœ“è ë±^{G FsØYt4Àe|àHÏO£.%Tb浤²‘W¸·¹‡@~É5 ü/eJÁÖEèNñKK.#nÞÞ€r]ªRâ!!-Ýû˜ À–ºðºqаÖ†š½ ÙïÁ×´ýþI~;ø˜U©p[RÕC(¾¾UÕ'£YÚëõ#ÂÌ@ö³hÕg§¼Te½%ã¦Ò˜Yù³¦:-'qß’¨‘@:F =R11Ø„ãçך­®1#âEW"æ8É5¡p¡ 1ÙÛUEtÓÈdÎj¾Ò;ë¦]°…[§xý‡Šök‚¹{}š—õ‹ÅX„–Þ ‘³no'©¡r4+¶Vœè ¨ RUm@¿¾o}@¡fFü.)Sq=a’õ‰ šw¸ÁÎ@Ó˱†Úߺi„®·ð¬°pò +—Öc!^ïÝèáÁ”Mó”ëet¬@á^ñ ‘^¶`7»?Rƒ·6mSªä;ÅÔ;'Ÿm÷Iš[X@´G ó‰À´+¶bßÄçß²KuïÛýø1éä}´ÖørÁ~ +„$ùàu Qª 7 Éó¯VÖÏÏ1,¡‰R5ƒµgÓª½¥F€ÿzÏç°±DþVôj9¾EŒ+x{ÖÁÌÌÀEÉAù+¦îòp÷ß­£âs!ê#íy'rù«ÛˆÌ,'ÖÌÎk‡P)oöÝ›ñá×ÍÏ*ëÝYãq[mŸv¹²µNÔÞËŽú³#¯ª”a&4nI+Fjªè7cÉEÌëµ_ MJ >Õ!™DÆv€#”«‘–ÂÆw–í›Ô?­€Ú:nX$õHè%ªå±‚‘Œ¦ÛZƒPΦs—æ)#õÝu p-ü^ªÔhÈa‡þƵèÑ)Ã×ㆋìJØÂ$’„ +(×õ­º"?¦}Žš +ó,"1!ÎÐ×Bj­ëôê â*(Ê“MÂÔ2™®8óèOÊÝ3Ti»#m‹ ÍÑRŠÈL.¬½ ÎÕŠÞ9àPj}Cgö¿ãÃT« ùŠÈc!„¢n$gÑ”jMàL¼—Ô{·–'9úM×›N¸èËʉü[ݪ:…Ý,ŒÙ[·h…³oEQ¬‘ù—LÎyýŒ§ˆKh-¢‰{u^·MÉ&é÷?OJ]”kOèW€µöÞ›"Êsö#ëö­W‚j(¨#™‚6RÈ\ð#ˆ +".Ùí©¸}Rhëƒðx[&³¥¿q5¯a( PÅQfM³7žÖA¥V_ÐÚZ`Þ4R4í­¸kPÃ$à‡®‰¢HöÇ´Ÿ²dquÊa0*Ï%Vî.áOÅטB™Æ»°ÿ둤ûã‡zà@Ëǃ)Жí'Vz“ª9)ߎ¦Óm•PVtTú)$‘ìëv‡t]HîºÎŽbùmà?› ²601 {¥Ÿ] ;üaG¾¡ê1:{‹OáS^ÍŸ‰¹ ž}‹ZÑ:@ éŒ×ç{Ñû™®ª‰ÿÒŸvPºP¶EÃi.¬Î[¬'µâXЫ­vª ­l¶ ë3ð´*ÊRl $1u‡Žçœk#Ðw™/­v[Û%˜†kÉBâWª}ÖŠ kJÂ~RÙK±°Î #ɽQ +|9Ú®š±ŒAé⑸u³ÚQo·gÅZ]fú‰89KËA¹YW•Ôî?+> ˆÑš&G^æÓ-j-xOGêì|N%˜Bç´KæÌz< x'ÂÛ&ñ} ¸ÌÔ”«>4Ì}tF{„ŒüU¸pö·½PêVm6í¾HvI¥ü#e,ˆ;š^õ9äD~$}óe76M¯ÜÍho9Ço·ÿV¦¼>ßfè’ò›„=CZN½Ä8[3Å'VÑÛ]ùyX{S_é(ãùYøMAí)>IƆìë'œûåeý[¾¸4øèj:ÑÑ;3ï>cœ ô™wTS;Õ°œ·Ÿ *é^Q aGÔ*[­¡ò=¯—-Œ(£ïjŒ”sma¿¼<ÞìoO•É0IýºÇTGDnbyf¾‰Ïñ²f!³Ë¦+Æþ†&–f¥âTëËü +%¦°…F5p¦e¶îØz‹¡ë#¢À¯#Êpç‹ñ°g¼ÃS¿´•ŠŸ“z'žëT•„±prص)üæëª=þX"í\’î­˜ó-ÉhãóÖ”q ôŽx¸öìG˜È™[¸(»Ñ•?Øh)ÙXUÕþ óŽu=…´Ù{ÍvXk!jë¹°6)IØ’ âIìÌÍö‚ Õ‹ýN=Ý®0ž_Y®ÇÚ¸ÝÆ+o­Þ,䦂cPTG¢]foLÃܯëÏì¿Z6eMDÒ\Ÿ9¥ dÈŸv‚9ã%;ÞPUGP_DìÊ.ñ3øÐ9àZY 3®½Ô±½ìÅÎv2²„¯Uïù&w˜éÛikb‰ÿß6Õlþ^+ôM›ÏxŽ–`¸` ³e1$<üxªŸß=²ÐáV0;r}ÎÏQ„œD5V¸Z$œî‰Z^‡+üE{Q%ÇãÜ Gõ±C†‘—UA¨טaó({¦q7$€9„ÉI°œ,+7GëNöHF^™U±€Šì& ©'…ŒøÎ!&r﫨pC,›U +’×Ùî8ë„C,9¶±þ o/ÌzÅÈ|`or]í}´_.±A3“T÷z,žysÕo8/ñ²=G«¥­Öw‚¨*É4}¢nø£ €ÇÛO& žtKLlñ³²2½>Ä5xêMÊÈAå­aúä ©º”É4g³¤ƒ a%}µ ñmHDu¤á]pžpùäÝå,æSeÊ;…šTÀç™?¤¸Ä—Äʂ𠹡2»–aÆZþž ø:…NMV+<Õ"SôS‡öð6:U¹¾ð„ŸHYŠKá¸þ”’õ¸ÛRi}“sÑW~ʳæÎ¦}ëÄ’Û‘Û¤ýêÖ&»˜¬@¨ŠçaqŒVÄWGÈ­à…Í_ù¹fCG»Ägn=<#Шk(ˆg(é‰)÷% ^¹°ÚÁ*ÄÍG"S/ΊÄBzaaˆeDV—ã`Öt\ó•Te1¤¢ !ékÒ©®‡YI7b„>$¦­;[¤€9ïl“ Óë¸È¡êÁ Íÿ®~É-‚€n±GrbÜõtP›ð¤D2Câ®ÄéÜ&@!û(•äÜJ0ƱLN!R“ºpI7M¼Žõ¦µí¤@´KY.amnðW–ù øDkIø’Y¾ÇÉH ÌuN׈†Êze›©ñFíõ¹(Y_ 𚉜 ÝÈÿiœÂâÁê)þåä¤dÙ$pæi$pÒ©{«[Õ´”äº-k-.¤ÊËeúLÁ®iÜÙÔ’‹Ô£ô Y¼¹–5¿÷;zäèñzP¤)y73`rR¯5LµDjŽx9À" +aYQŒ¢J€kEѺµÏ’å™n,ÇÖæb? dÒ +²s}Ó\5ÁAÙIôl ¿«˜Bfºê:­)a»°üF¹)u3;]b_/ËÕ_$.²ô¹/¤AL=”ŽA¯R`®Û!Nl6QR–I+Ú-Ö†Çãê!ýo!Ãí27œŸêbÒÃo&"·¡3’ÄäÒª`*1¹T =†ééÑd…·–ìn‚£1%ز¼j^ðÞb2¢}>PÚDÞ?­x[¤~¦/6þâ:˜ðdÌ=ºV°S|¹^ çW±RN÷®8XŸ"‡>EØé¶,G6”h\ªtp¾R‚RT°:y-Õâ Zw0È–¯è %`]ÔyÿؽBÞ`÷*™˜IÚÆäÌ6TF}/tA’Äò\·~ª‡¥f l?L|ž4F>ß|‡ú_ŠŸºý÷–-ˆ úLu-k£­J%´íYZõµHOòÖqŠQ8™Á(™s8޲î«!¹K5(gÏʼ­ãR®š*¤‚§5ÉDè +CBäÑÚ!G·° YÝEº[Ó …]ƒ’ƒ.9RqÜ‹M2)…I–r7Å'O :ñmÕƒêù%‘†èvÍbè%ÄЧ]%…Ϲ¤æŸR¹Œò!JÒmë–-·eø”}vüå51-ÖrSº™€ÈóË«;D'­EÚ®„„¯vnkºEzUÖfv}ž&c„u^gâ‘Ê*™„¹Í±–I8$+eý(¥ê« "šæ·x{>˜d#“‰" Üj9mA褴Va…Ýç’FÈ[f + ^»!ÖÒàÈÂAÌÊÈU +È*w"÷z. „ä1Ì"(Ê÷ç§$”C7¡5€L7›ÙçQºU’ÚZ³O¨½w’Á˜Ý‘NÍ•ül Ì(ÛvõxŒ©¥J•uÔì+8oÉ"ÚÛ®{WDC$´ *·B‹û +×í/Ô¤ŒØìØìGàv†æsv7 Ý4ÂB—%NÅo‰ø‡ø6B!üádšÝ¡Ãí²ÿÚ1¥àUåB,t{¨µ³Šžu·$±Ççwåk¿B¬}̨ŠIÔ낊duÞh4ÖóÙ¤›ZØ'Z°>ç”vím¸ö6.:kUÎÉõ<É'€•ÑÃ×gn>ÏÅY ¢6kÚ&…²wÕ¨ìmeGU£(tòG ÝbX–S0g¢6à ÈÙ•Û"çëš›xÉRäp©¨´p—<“WD½ÊM«õØ@QW`U~<»¦™(P /L)}aï—Ñ:i— 2‹êaåÒf3‰»_󺽫)g"U!ºØ…8QsêÕ#s¹Ù,¼ÄVŸ½Y]=JÎ.OÕ¬BÌꀜµ¬3?¯Ç+:ìW; +á¿% 9 ý’¸R‹³³Aœ]|”?˜›|Éc˱r—Ö»G‰¤¨²æÊyLààB® ð_"3©6Ë› æöŠBFÛ¬gÝv†á¿ äka‹õ,Á<•?¡oq&cÈÓ êôØZY Ћô(W´ÂÎ É‹!ÝжãjGü‚ͼ@¤—ÐWJÛ#Ç!î#¼•¸ä…¦3$úm­ÚbW=:Œ£|ra}Lª.=×¥GW¯@½>TÐÊJu`BHÎz]:ÚkZ&Rs5ÂYå,/€’‘D^„%‡€ÑÜB{Ú±y’º!«Ñ½=Ò/èD^÷ýñ(Îè?P +…º!½¾öd‹“@ž©*"‚°E\8z…ìƒa`ÓkFâ€ä­¨Ô[öQl ¬!†h“fC«ï ·>œì£Â!ŒSôWèl~ü³^íÉït[F—½v¢ñ§ÜN§@ì6mK3R`:û²_åmô€û½?à­<µ­»~<:Y£›%‰DóŽfî9ЂÇL½·néÄçèe’¥˜ŸE©†&™ŠµDi_Í&ILü‘-iùn °Ò‡?c?¬gª¤åŠA%d{€Â’t®ØÏÛG«jC@_U‘–˜oyyfü@»¿Óò€r”5â¨T7o³ññƒJ¢L¤âFÒ½í<øÍf¤<ÃÒ|‡!Ö Ü¼é,÷Þöû⪻É;S÷쨋Ñ04´q•ãÜ8‚Ç]¥2{‰€ŸTDۆ׭ÍÖ +ƒ+ƒaò]\c‘îÑäOÙn•ì×´4hÕͬ“"‡x[¯Vî«Ä…Bs Foã°ny–0¼0Ž=¹¤·Ú c¸k£ÇS€‘oŒê +eæ%ª½®+ÒÉ7¿#g_È-ôÞµå Ä¢TŽY€×³­1»+9JƒPþ 9PƒìÍîá¾ô–—²KÅÉ•·NÖ·¹È~;ZG½s@\ÝzÁtEsÝg•£HÙÂci…¦ñÆð;XÀfarËä!â@ñxé¹÷dü9›áé¢G´p‹Z3ï«oªº›p=Œ¿.ºµ#pm€Ð]è°V‡¡H\’#ÅÛºâ"ÕFÐG}ÏXn sê†, +x’›D±Š(’žƒS»µ…ƒÛ`ŠmsÝ]QõÁ&/«ñÌå]Q­d)¶×-h=º¶:ж)†ùŒñ?gåX{y¤dÞ¤ˆÜüÛúÉ¢­ýøëðÂZã»Ýΰ‘ÓPÓ³dþ/ 9 Ô–Cªù…¿3e¿k÷×Èû)ÃRûp3×Cd!ÔÃÄÓE +‚kµ[Ûî7D³Ò•>ðä’8Û‡?»l&ïB´ÀbÊ|ÿ×Y\ˆxû{œ8=L?Ea[QâØÆ1£/½^ÅÎsó—v´<зªg8s  –]ze€ŸM8(IhX2ÂÀÕðà}˜ÍñŠþ «½•ɺ…*ñ^Œä÷"¹æ t¨ŠWùù7fHr²€ÛµW·çèmV·P¨¤u¯€!Sa±ü§2YJï[¾03d)T’ks¹@6²·6`ÎØ7¢n ôöš‘×ÈB)#¨³='·"É bqä%MÙ² íߎñáê)H¶º„|¿´JžÉEÉlà$ÇO™ ¼ÐÉô¦ì–šFYrµÜ|T›&Iû‹«Ç/">=<°bä»ãmu_TW²‘ÌÞb×aÓ$ûáªÄT8kw•ï ¸_—¨ÒólH,êû€B2 WeˆÎoRAfO%ô>˜ÛækTSõJ+êf‹âB' ƒIx®IQ“Ϛ؋gŽ(n‚b’ì¿„b‰1)ÿ†ýÅœáÛbäBÙ0’ ~¯•\OòŠsÉå«”ú¢„,0¶2(þõ5³La ‘uš]<û ð½ œœXð7<(Î á‚6d§ÔGÜPMzÐ!…@d7Üe³Æée9ÿàFìóÙ´Yã«¢—õ­ÊE ~¾âu½ëÿN^  mÒˆ€ã0Ñ’FNð'øü 2¸û(FHLâ¨F¬Ðç ÝÁ¦pGU¨÷@3KÅ`+”æð»£—Ø ½ÇŠ;D …’ RP@ÂNŒ€v[ÀpŠe€÷íÇO)¸(ï ­ÄÙDïêÖÎ|+‚ÚZQ^($v×§²ž˜³7VzfÍØñËÚÃuÝ{‰í@P³ÓÍûô=‰²üxÅÖ½¶-äá~´ÌÒšG9Kõ‚Ì:²Ç39+T‡?®Œä™¢©xŸ(9$ÚºaFªLÒA޶ (¼¤ñôòSºæaÌ9ÛâøŒ2g:"ôœkDGúÝaSgÈ©–£ϧނÿ‹Á®ÀÐ3¹×¥=ª¤¡×œâºLÃgŠúY¼«^…?òšÕ´‘‡×—ØŽ ò‡Ä„ø5bã í†Sö>C‹ÑŒ• ò EÓ— +¯ø;f£a/K b¦ÞŸùë]·qd½¯ ¯äâ)!Ëx†”¶zë\ìzD¡( ¹ß*V†jÑŽóKßÇ»`v.Œ:m—¾‹M¸”j\ e{‘°4•”{¶÷ÈêÑ Ýœü­S¢˜g&³í^}¡ƒî™ÝTn ¥gê4a " VMM_˜2´ }µµŽá‹N’îýe”ÿ%Û‘„Ké22 \Fnƒý‰1Aæ:T±"ƯР+²Ð Ù˜>ú²=ßKŽT¶&/’0¹$Õä0*X®Í*§·¦^6MÁÊ;P¬W\%à£vRÃðvÅNÓ6Íêó2мSX¸RáH/ c®8é:—»UU“Q¯—õV·"ÖÔ(ª·¹úL­‰¾âÆäUDíCÓ$*l'>þ.†9Ž˜>ûÎ «•^—QƒÂÿÖ·v·çž›Mzêñû‚ J¡Šn"»}M9&ÙúÁ̺&å÷7)û‘ +.$ýÚ\«ÀÉó¸ W ÛAo;ï±&8ï+•Mìä;Á3o3HÛD|§Ê0zÄ/¼&oV¼|ߤÖD²0_W +íQ ¡iœ`ßÓ0?AíJØH˜á¯!nWü¶‚*xÌY£\Úø†ú}©¨ÿž|ÃÚ.ÅÛ}k CfŒð¸"«€Œ@׆ä׊R >œòÞdšDI¯UL¦+ê\Õ®iÀ‹{ )˜é$€ õ•¡•¡–£*¾ †¾Þ¦níÔ1 Nn—ð\Ý>=Àµ6‚”£®Õ¸aØn…•ê^YWtÂ÷ÖKð-9 ¸2 Ç-t!߯Þ?¸ˆ?^l6!elcÖΙ»£`¤Þ1•¢å©U="™srb¬“#­šY¬N¸À°^ĺšbuš4ÅšIˆÎüPi‡fä‘ènØÇ@¥C¦1µP5hV5@v¯J«»û€r;ëÀ]A.eó¶³yÛ€–ëÞùK¡Kî !Q/Ÿ{ë 4œ0<Þ½FVjÚ†ÝSnZðgrÈ4åo#R8—ˆ’P•5«_BPFþú_±¼žˆèԪɒ´ÖÃEJN0¨«Õ¨ìsö²|LLTŽm„ŃôüÖ]SÑÕH‘Qï¢<‹à)"òHaF¨k×äÙzåhÓx[tþLR2_ãƒ8Ô*8ƒ#iÄš!¬‡«Œ¾×·}2`ä–ÌD»éã L[{Þ6kú¤f÷9RT>?Òà`$P–×ùÍàqÊ!Læ¶xgT ¤°dñ–â-©žóó '½'o×Íïü™q #T)%³Ru ~h†P6+ûö§"vÓú0¢,évEO_AhR5ßV¬ ñ-6pŒ“Ë ”ÜØ<´[ÑW©)9 •dP”¨JâV9CôûÓIÄÝ;:ÀÐÂ[W'yÞf‘ «)¬é[¸Æ Tbvšý‘Ûïê,øŠ×¥Òã,o*Ëò´Ÿx=o(è’Ÿ›r Þñ†œ.Ù/ÈÌè"W1¥X×§šî×P®[-öI‘ÕáÀ|ˆ’É@oàÕ¼b9JxøzÀqmúÀø4+·L¦Åâwr“ûEœû•µgßA 4…åÌls.[$—Qe߆ÂΈ/¬Ï‡ëÆP’¼ÔeHÛ7Žj€Â3ÄVëÅB|/¤¢´¡•®.ãÇ1wóÒ<úætZ÷‘ý›ÖK8bt˜  ÷®`²%¡}g(e?~,[6Û"®=ø'¸oä¿.¹‡¹›äª”~¤âL(Ÿq¢¢ûqjàë=Î@I">ÛÇÓhv¬cr’q©ºª—绎뚟ð`RTòp õÛtÐÆß_õ­rA9lò™@.!°ŠÂ?žÕþ†¥›kîeÃOÉñ8“* ’}S¾ò÷ e—*cß)új†äV‰š$0ómÛmH‰´~[Ÿ÷O‰%¸[é¡þXBý±8·Z ²¬W޽‰ùTüªàu’!ê,·'`6i¾l¢b†‚1în’°á-•3Û.žÀrK´ú¨Ÿõ•mØ>ðlã÷üT¥_‘)+p×ä_§ p6Ýô‰ÂÄîÀ=°´X=HÄé~ÞÇ¥5ÍYÞÜRã -N0rá|¤„öQ·­5¬y~g‰†|è±½f>ï_M¡]ÚxNQiîaL%.°Œôdpºµã&emå3eMÓ9ª¸"9”;ö¥(˯Nµ •VðÕ.‹•­Õ‘t{_«\ìˆ_‚(±-¢ðC’µýÅñ’­«ð#`ÏÃM¬l,ƒ +§§x«—(dª+H˜u?ÞxÈ+ÜÃQx“Í=Ü l¯Û~ö!·L î,lmtV,vïTÕz/¤7ïªN׋›W¢»µÈ¬I"ëÕæ¿×» ‡%䢤¾D”`µ:PUÞ Xÿ¤Û¦ùÙïûÎUlx­µå½‹ÊóHbþ«Gñ|®¨qi#z­¾5¦îá¹’ z{ë®®Ðk\V6q`ÐŒ©‘î*y'(úU_lCSÜtÏ5qT­8r;m{‘m§õ¨èu¡¶ÚÂcÆ^H'S/Ù7X’QÝs€ý‹Áþòs(' `Vg-öŠ¢g %üðÚœrclÁ º0•0Vè¢ %\K×j/°|OÖ40 pãá/äf“Ylød‡L7/z5“]«§£f›³to ëµÎY>ö``z°äU‡C$³Ë™…QRø]í¼-³Ä1.+5¨ŒNíDV‰ü€¬ŸfŽ3óƒ zòb:t{‰OqþñÝÒæÕ„ð›Ï²v½-I*‘“Kª1뙑®ÊÉ/Å + +Ð<·f3O +çhXð26Bñ]Òî¢É¥$øô6!¼F׳ΉHAHœZþØ#P‚PkíÛímú~ ¢ia§woÀÄ—X«u4ž­ã¦kV½ˆiK +’ë‘u¯Ÿ¤å‹’I‘yL2~ ¥f™¦›Mw.ç²ï¼?éIøõÚ¶3íšvšWl•E)¤ž‹jQV(ò§s7 ‚® RåÔÄ)š@=Ž\²¾ :Ⱦ@$¸%.-FCzfƒ¬¡Ú)Tc t{A±^§Ì¾Ú>ã¾mf¿± /fóŸ5•q.”¼é@.“®ÜŽ;¼ԱÙßý­2C +,%Ûey]±–eŽ“cÕbâêƒ5@±¡¿pL¥8ÞXžVëaÞG˜±öÀZÉ–FiŸËÂÞ}ˆ ­ù`_¤ºíáHhBu‹KhCê.ê6ýg’¥=½“´ÖÚ—Š/B‡K„æ!…DïeÖ»ôåª>H„‹§7¸úìÄü–ƒ/¹od™±(©‡¹»mÔêrÙ%»·øá°†T¥¤„ää$Õ~õ¼Ü‘N¬ÇztIyÑ#@ÎÅo¹Ž—SEg\ṳ̀ŽŸ¯R¯G„2,(€ÜR©‘Ú0o³Â–+,Wc¨„Ùo ê׈L.;BÅOeƒh빚‰âÐ@ή«hÃU´Ë +÷ªU±Oe)SE¢ÜÓ!ßçýáì“z£žl§µ»¡EÞžpE +é©[™ÜIƒu­ÅEfSgÈ”œ˜œ˜ÒžED¾¦]ðnsy$_KvHá‰Qƒ××n Û˜C91zôÀ {{¿VbáÛéq‹8Ù„Ô9?e8~#ÎHúÉKd8èì2%o=LÆáj9p@¿îR»Æ4„ 4g>&ˆØë˜#b… +èòÉSn»½XAûìñ},ªåK&·m½¥I{E¥G…yìw‡%0€š‰ÁLš6[0Ä®»L£ÝžÉòª¹Ð{mÔpàP溲6¾Lƒ©¼ÐÚàÞÊ‘«ÄŽM¬„ª•9M©˜“›SlÔvOIYSí+®ö5ÉÜ­ø©:—ð¨áÓ«¡ ÄÊ„âÛDÄø +¤K Æ¡J×C„”¢qÒe¿f5‰ci|[~SŒ”ÇÒý2”TøfhËV“¬G düë‰`_û‘áˆR¨‘p+â§ü ­1®‘•Ò2>-T$²‡(lËYkRØÊr:tú%k1k‡æ¦I¯ùfŽ[MY=03²èûn)؃•:\2xZÖ-ªRu¶Çßg#¹pMTÂÖ{3‚D¢uªîعªËÚý¼µ@HéPÔjºÈNA‘w¦ %§1š€vìê¤Ò@…Ë|¢‹xΨÕ^Ö„rjáXÏl‰¨‚̲j°¡W8#¬,J·¨Žê FÏ +xzz1€¾Œàf'iŒbýæŠP1irDÕXÄa‹V†<4“®Iz`ƈÂcé½g¨«P>A •YëìÅ.Ü“™A>ã +笵&+ç+C:¢šXˆ±„ÝZ̦UÛ‡ž%VÀ¼ï{ì$¾À>Ž*åŸ,Üb?DbRzä*ƒTMݨçh8ÌV ¾'Š ¼¢äx*‰¶¼ýd>òB”×ëÉ–ÕÊ}â!š _°šÙ&x»Uˆð;kø4±öVŸTÐ_` !øóqçÙžMœ„&Ù5Ê:-4ÏRsª‰ŒÞgî¤/YÃM£`uꢒL€”ïd˜ÑÚéÂ>óÎé@ó¾?È'C5UãÿÚpCÍïÏB²83äûœ>LZ8T¸AŸ@IŸI ó[ÒØ23.i£ ×ÇMCMT.)‡]ÍÊa$¿`5sÈ…}hKP#íu#Žš3ØïÚtqáÉzÙòpIX †à€ÄýÒÆmÊŽT®µõ g]K~£J¡% •8€ ·nU &‰ É›ß\96ó%¯yìŒ'G7UQÖ·7>Ilíåݔ¬Úc—xÖ¸DídlÍô&ì1ÖùÍî—f“Ó…Ÿåz{‹¨/~>Ib›@W²èõÉh'&$!BV¤NÒQÂ;5™iÉX/ü¡'À¬]`,ª˜7%ÍçC–€a¿(W®Ü×ZK˦¯v—>)áOÝ÷^„>ŽVaá!ßIÜM†Š„:Ç>ä’\Ò›zÉÆûŒbWMD?@w¬Þ0|齦F‹XÈÖkX72q`MlÅz +c˜{…0¤Ì% "pmPB<<àáï¾”ÓíõUûcLg{ +C‰A•Ãy¥ 8Àvy}w GÎqÙ¶(ùca -ýèÁǬ‘ËRÉž£lH °I#‚ðÖJ²‹ÞLT\î3žÑÊÛ‰¿Jt½ÛŒwGVÎ œs±á ùµ˜ æÑ{l#øjyÄ$‹v—>µYEˆ`IÊn…è15‡„›t5ø PÐ:~ŒÆ¶©lס<%ãF°¥…¤ê˜ôf@3š¥JÚˆ­®m—±Idx/ÏM%œu6ĉÚÂȶ‰([nO¾¦ãüq ŒNÞu0ôŠp:r“(Z²úâò®tã³*)—.yøM,ÁhNQ«>f‚†LåŽ)RBÖ„Šc,Ù]jøƒVkõpÖB#5Xx5*¥¦K4C{êf9Á.û½þlõQAéªjMæÜ4ƒíE_oW3!F¤‚š]ãùöþB6Bø–£Ä&tYñßãŠQX£Á´£ðK}à|w£•€ÝÔæt8®)(f=JþÙW'{$.ʲ1]ýZ+b¤Éj +²¾"Ã¡È :ªc¤>Â'’Üp+<ªóÓ1É‘]Y6t—X“-èÔ¿}2ž§œÆp²5ÆW§Ÿ)É=Æe,j:*¥£o–ÍY‘¸Âm“¯u@:œMj)8ñ{JHõ²jÅR»ê¯0ˆâ^­[áÓ3¬Zà™uhŽ©á +Ûá­5Ѥ +‰“äFtxÍöÕiFëÛcd-«««î½Ò=¬CqM=´Î",N×ÑI˜ÕøþqÙÀªÆqsÜÊþ&_Á–FP.×FèÚvÇ'‘£M¬¨4(^2ê àm£ÚÐ%«ºÖZÿ… ]$ŒÆ³ ¬%Ӝނ ÅHÀ +í£$Zš ÃB±C†!”±†©jfMU[×J´{<àãõ£IH×:Ê>¿µEÛŒ*(yŠÄ×ìàï^êöúw—0.Yk ·#ó_²ˆt¤cǼâÄ{§âoW²² )âV™M2w¯ +•,IO˜A*}G˜GU];ít8*_ q%DêîF¼žZEâ@ö]NÙEPrNøS¥ AUÅ)•8€ñV“ב˜©óö Í4¢]œF'e™Ô'!$.…YøIâÏæe}Ƶ|di²°×ùTJXeË=7Aè/YŽ}R.ÀjϵXí¹¨y¦°ÍQlDÆâht {‡;Ž—€úëd>û<¹´·{¤|?ICÎNv¯ÄÖ‡‚œyðŽKQu ƒëNB’ü,òý±fÏMAv·[Û¢ùèœJÅö“b#Ú¦šˆd`èÞ ¨¶³$æ¬ mx1V’‰hÅ_±± `=á¾,zCÚœý¡øõ}GA. HÁ""Ì£ìzI$yF’ÚDÔâp †?¶HZàÆS[‘!K ¼ +8—¹¥>¿dÈ‚5Hb?•;øãç)X«•* kie'ªàª6ÉÕ™½¡€±ýlÁ€Úâ “Ý}B £ÚÁfݬÒ÷|Nq@º¯UËYw„+Å|H…‰Qmʰ°DÙQ©ÆQïñDÝ»"ˆl¡XmMÄQVm¼„Œ®68od˦~ÈÚòlÙÇc$§U•˪,z$£J%F ׋€È#¤ø4iÕ‰Ñd¼Û­…µ^`€Zpe¿è¥ùAÖòoOhiÞÝ8ï}‡C‹½r¿d­“º¢¶›¦R4µK!JG¶h®“ËgS˜R®"ø§”ø% V{;åœ;E¨x‡Îõ:Z™ÚP µ}ò»?£ãŒZ¤²×D‚dzfJn¹Ë¦ÐV•̦Mº¡]xú¹Ó o$‘PLÀÛŸ+¶ï""Õy›¦@õ`­sÏ*eú ¹½ƒTížL ÛÅ\W$KÅ vÚðê. ½;à˽˜ +ïG'û˜aaÊõú?ÿ¼LûªøíÜ>ª×PQÐÚÚ\º5SJ+Øk²bºaÛZêÎ7‡·¾sf–ØÄ, @…T%Œ4ZÀë!}×jJ%t˜Ìùwì_QN=6yŒg„wrɪ)%JH•à‹iù¡&­‘Ñìýá€ÇõI˜ÁQ‹ë8Ò Ç ëßD{ÉñÜr£X¥]_ál±…¿·}ÓåMíÅW)¢ýz]ȳ G’ôˆ,†•ÌÜÚs[DNaUÕY€yk!ŸÕœþ©Y/ÃsÏç0GMu…Q 'h‚·õôÜF¦—phÒÃû²ô÷=í?¶V2ü–ßä¼.4lsr?z¶͈:ê•.òµ¾k2Ým:jñÚkýŸõkwd¦8° +ëªõzɬ®ÙÑšábï†Z'¨é•%Dµ° +—°ý„ẂrÚ%¸‘jeôÌ&í@®$ýøn9„Ènݲ[ò…äM…¨E1bôן}µ÷¾Ó²sã§ëeï.xvÐW¦0ƒ!Î~©Ü—²œ{’þpÀ·Œctë± 5{á‚Ò™ö,ažkÈ›Ä.+&¤^_ßسôMÊéÃQðìdÎ(%Iði™Ö!jSÃF§ Ï°£=w8þq”D=ÿ–Hª”E*?¢_åUÒBmð¨]'lÝ ìüذ6ArÒ6¨ž£ƒÂP†îú ‰sÎ# ß³èñfŒx3ÖäÐ/3wsÙî 뉋à·ä»Âoèzñ㈣Ʉ{)ÂN ÃB 0J“p}hõR‚0 ïnïª!I÷±w…½Èa—¹ÆBí â×É#†¸ Ø0W-;áFY ä©Fªrb)NHi•?RþD%‚¬ÿð*ÓC.™»DÞ(§(¹ò!¬þמƒHM¥â®ÏbýpS2Zv§ô +\ïÕé9XÅbÁqñŽ•orXBÕZ^«¨€äc ØBœ›øoq¦×ï:Žo÷¹e6­j7Ë•œM„.EÏúºC¾ßøP@‹´÷;¹{0D<›{{Ši%¾Äp…m…Ïòæd¥!òÊhu+¢ôæ0:_œ\hi/¸¤F)\|x8 C/I(Wý¢¿:`4ÄðB…‡vÞa4æ•ûxÖa«³^£þ¦…[¡¦×©òùû½Çç?úîÆ¬Ñ~r°ôöõÃÿòögùó¿ýÅ?~÷»ß|ûóýöo~ñëß|ûù‡ßþÇ·?üÓ·ý«_ÿøŸ~÷ÿýöý ÷ÛŸýùÛ?üýï_šêÐPH_Sô_üÝw¿øâçþ‡ß}û_~ý/ß}û÷¿þÕÿ?ÓÞþâç¿ùñ+=ÿöwßý÷_÷ïëüþå_£ïW®":ÿ/¿þž ùõwÿúíÿñÝüÁîß|÷O?~»®ýýÝ¿ùñöþ/?üöCçwòR¿÷rÿ·ï~ýßþùÇÿÑëý»þ}_o»~r`.øo¿ûÝ/¿ûÍ/W\jpþ¿_ü¿ë\ô´¿ùá—/ôñAÿõú×_þ¼|û׿ùUŒ£†F÷ÿù‡ßüíz\ïãÏ~íõÝ[7èåÈŸþÉþ­ŽMû«ßýÛ¿þóëÏþ¯ßüæß÷«·ñçz½ýåŸþÉõöÿÎÿ¢dóo_üGz˜¹Þþ÷õ_ÿßjû÷·úö7oÿ÷ÿs½ýj ð÷§ò³µrdY¯žÿ‹§ò=í²ídŽyÚ¿yß©~mm¿y?ÎOµ?ãü拳ý?×ÿP1ÇŠ Ë\t¢¼­­T5šæ[Мˆn“êJØ a3Ç’@~«"#I†…­O½•F öË«V^:¬é]ž//ŒÔ× +˜ŸŠÚÉ¿E#‚Èj¼ØT¹¦…ÂÏ{\Ý^Ù }¸•ñ‹«ýŸ|¨¸ü‰FȺÈ>÷ÉOKÙíT¡ß܈”Sü.ë›±aˆåœ ©Ê?šð­ˆFö=¾FÂ^7&(dú­;Ý/#lŠs˜×¾ö+ß çу¢=øÜŽZuÜ»\¢+jØq9šHF¿”_þ~Ê)Z÷x[œÔ8¤ â²âƯßlNèD{+m_A=÷€ÀÃ#<÷àÝsø¼‘v©˜rHT¸ïw;²èÑÞãYÓ:öƒCôê-†ØßOË—ƒžßcÏšöãÀf!~O>ïóÞíIãи"K÷=ŸÆ+E#±ìç3§st­D“uö¯žÁsr(úY«†^öÉA¶‰V‰¢ Úh\ßK4^¾iÉjšŸÏߣ]âöî›Dãð«Tyûêü<©†JÚ¥ñwž• £Ñ¿öx25^pâæx\r‹ñ%¶3¯×ñ±6vuÑxf™mÒX‰ð£g­û–ôæÁÍäö¨s÷ßsê¯Sí{Þ!ý±Ûö,×ðãúê5<÷”DnÚïL3þ-ÚUõu{º÷=åcîñ ïäOŽÆ>ci6F#¼nLŽ¿ú‹g¶Ä÷¶ì·ç†YÿýnO×~á¾E#øh?H&¸hDÒÓò>·ŠöóÊ'´ôãç0úqcö&ïÝk¿—±%Ñ6ûÉïÎûøy2_½Š×— A Bz÷¼K!N7·Q÷ÂÒœsq{¿÷Û r’÷´ý~àçK^&ÎøÜ¾§ÕÚn¯ž.h$Ϭ춖ãy;íÙæ‹ö‰ˆÖ ×hlϨ_žÂ>;R÷ë„zv‰ÅÚí5¾%Ëvã~ß‘‚==>9ô®}zjŸ>Fȧóççò˯çðœÞô€ÛIsŸœ¢+^3ÊWO”g‹gƒ½ûÛn¼âÙ@NùØXö¢ü•_<_Ç„÷Wâáh›ñýiÙíÃÓ(#}¥1·Ýxïw›ô?0µgÈÑ8öÏéSúê9œ{•Tño iÜ+h$ÈíûýAýÙ;vàí«ÑÖâcâs,ñ¢©½íµ[ù47¦6ëKÒWNáõË“K®çPÒóé=h‹O)Ÿ‹Ýxæp¦Ú3ç\Ï"píE¶óî{ïQßýþë{wÝß­]SíûÆ+ÿã¹û£Çû”Î|mŽMÙs\½Î¾öÂ(VåOÝ~ß‹Yûng³÷Ínß_ýyUûµsä«#ŸIÛ¡ôÌ3^UÚŸíðd‡úÍi¿êxy>1HŒO£âª¯Œü\©Pk_¹R‰ŶxoÙlºC(8n”'¡¯×·[¨T·ç¶GòbŒp>»|í—áF“öóOœÛë÷!¼|¼Ýgµy÷Ö{µùø)üãèüÅÈÿU?ê ÍtâÑzèûݾ³´Û§–$´ ë¹<Ï*4–>îýÍîd@†\kÜwa Ý‘…}ƒîh»òŒŸÂ ñ tÜ4/\4¶u-ñkÅÁ½îƺo»ÚëΔ̫×Ý9íô +EcÛ_ë}íMa®¯Ÿ qc[Þ[MDU¢1_iGëÄS'|‘}¿Qm¶üõçuFÈ)íOÞ3±£k~~ÿuº^gÉgî»îÛ·¼x¯¨ØbÔ#"ÿS€Ÿß/ÞpÖ“~‹Æ×ºêž¼¯Ø¢Rzþzª¨á$ZÛß|Å%cŸ¯–Ò¢÷x|hl-?ï½QqÄîÆÒK\­Â.7b¶£¶çïAîg ò {ùÐ;µݯ—’%/gpŸm|ïÏ¥Õóí(œŠ6ËYîÝ(ë§ç9_{ ”†¦']FÝïè¼ã‚Q{Úɼû,?´¿¼£W\Äâ¹—×tFh}O¾bÅ鬲 +ugYwœX™qÜ›Ø3ÂÚ;Õ¼õèœ)ŽûaŒXµî·'ÆÏÏW){a`ÂŽ;Œf̾™1#Ó8Úî\J¼<0nbÜ»œgÄ™Eª÷;ˆÛæ} +gâ—ÚéÙ{}FÈÉ·’×3î¯Ärv²§ÎÝxõ+½4ž®ëô[£³’Z1q*QÏç-‰Ì#íÔSÇØo¼_#öéz9ÆI§Ÿ(bž÷²Ù=Np7ç¾¶'GY>öÉŸcP¢ãù´Àï<×q>­}~bÔë܃±Ÿ ŽÝÞ”ø¤ñ)hc=ï¾—*„dÎOžpït˳ó¢ð?<ëÞYÓù.J¬“q¾ë®³ÛKÚSõ<Ñ— ›Äg#S¤H'-™ö÷R( <‹PÙßKÉ'aÇU{Åþ\÷éoa²Ä½wycf;<¸½ôýqDÜ™Á6_u=™¼cçËyEbœVî}uEç\Ò‰ç”ႼÜ"aWÏ‹&å…Ý*ÁùLã‘´¦ñ™7*|FØ¡†‘='þé¬Ñ,‡§½hSû'^ý‰8¶æE…1Ò~~#;s–ŠÚo!Â,Ÿ÷iœçz{Æ„‘zVÊÈ ºñÚ+Ç5öûŠÖ<ïiÑovû3ÃÆ›Avf´âÆT÷—seÅ#ìOd-"yÿýùü#©E¿½È=s + +g·ç}±÷~hx4ÖggxI˜Íý4ú½;_×<¥W© ÌyÏu¨}ìȆָi$•¿ÙÍ ]y77O ™…¨žïvþd4LÜõsmň¯çá:“k_#œn#Prëg&¾Î+•áHì/7ær¸îm?7M%1 @k¿Æ3òŽFbƒêÆVÚYdâuÈ'?ÀŒw"y¬BÇ™ú¡œs+geÛ3·\C÷#½#½˜åÞ¾ï[†Å¹í‘o‡ °bN¨ž@ܸ÷/"%Ú‹wwÄÔ÷9·tw"¨˜¯ÚŒØì\-žÈŽ˜SN„@kÞ•#(hÑõ:ß²&ÇÕ(5Öà¶{§¤“rRæ}ú!¡S‘wŒ¼_¤žmÊ<·$κQÊj¬'ïăn,×~ÿê™î¤J°w/{ÍGŒ÷ô)íž:6ß{„qÒ˜R0l1BIó|µ>-|1ö ÕϤÅgÔ"{~O…÷”­q4žmúúXò3B›ûÑÍ5Íó°’}ùTÎuœ;ÖÎ$­y¦ïÐ9ßô²¯ˆ/ö2—*=é£çö2?žµ’·÷›Ý^òµw¾ìÒOû•ò‰ª"÷àA.ÇŒÀèÆ^`î~¾D[ÚNí)ï”È4Å„û3gëîIÞ_QçX»XzBÇ?™®qþuŸÂ‰ˆóûyâÞÏDÇõÍnOç^îuœÆü.mDãÕ’}ç9_Ï—±û¥ù¤RæQ9©øRÒ9-€|{Â#C[?ù£j²˜Ûݯ¨/n«]ÂÈn5öªµ¿äí~Œ×Ù &•÷©œ”†ÏGì]Å•×Å–¼W¿ ȧžÏ}F-'Ú²d§®ô’˜¸I¤ñ%Q5OÔ,ÅÖ=Éå÷“G +õüû¼å×óóÌ„ãLzýt>±#>7ј۞¸õ–®²§Ýœ]Y—6õ™Ü¢²ŽTt$…# ü¥ógOLÉÄwß~úÞ®0êuí¥ü:5èÏ{[ö¯]ÞñÈî=lš'Pê{¡‘ñÙ®I<ËõÄÛTü¾4"8ár +Í¥4¶´Ïa_Fö{³×O"Fíc¯u—_s%lg?ëímí`!žM«ò¸'}J2áÚvÍ]‡@¤õåÓ=#ìk{¹éílN#*ŠÆv69co$¤“iõnÙŤç£ÒÙ¸±ÇýÂç9ŸX‰v1*4>åÚˆ[vGá1%ùynÙ•÷'7Òz=õÌ`eôg„'¦š-Íø9%Ò#3¼ÚXßsH;¾ =ÝgQ*‘S&‘r ãÞàlÖ§Tw½$Öb5‘ð0ú1AÇçZG™™¯êì +géѹ×~² #â³Ú[%e_Fxv>a¨dç-S('OÕwNœà £¸§$øÀÖdeèÆë¬ŠW»OcÜuÐàéåÔòù4w©eΗ-„ Ý8ÆkúàáñìˆæVvÅ^+Kn +–ç‰éŸ÷Œ_»O‘zŸ/ñÛ²{L: {®lÜíåž½ØyB°¥wçÚ É›ãÔV‰¯3Âxͬõût>)&¥(<ìšÐYgÍú¯!=ï\d)g@¡nïºå½uFØ EÊ»óøps‚E;\lç{›r$=ÉâD¬9ê:8Æ(K ö«F9Ÿ·ÙèäÖãc™¯µ„²ëÎ’Õx ºÏJ‚Æs+i¿©(îÛS`~ì'9WÛA +Žó§Ùwc{"ßkž‹´·„ÊÝ}³ÛŸÈHâb§ýIXåöÒû>Ò·®ž‹ÌÞEϲ±ZOp%¥ÙX©…WõÛÂ\t¥Ý¹çhÜ`´×„ÛÇkûÇÆ5aü×ÝyG®ÙAŒK$¼Pó*»1¼?}˜"ççR: âÑöÏå³e(‰£çÉ=>P@X²'¿“â«Ë/‰±ÒÓn,'ûðä:ÔÞ7ê/J&j<ËÑžÁ—¶ZÊ3À“»N¦Šö æ(»0 Æqêi7Ý}ÏŸýy¢Oï­WÊû*v„—.qÏ-/[vµŸ©*¥¸4vç'IÙ¼š‰{*?wéÏðÛ=±‰Øwá +Ü +nK§¾“˜2ãϯ¯b> +ÔåT¹oAÙùp=aм^²ƒ‘IþÕ^$õúЈÏQ zBñIì¨øÿÍn‹êñHþ¬oüO4^go¦€ýŒ›Òî,nY4ž% :ë¥Æ}v8Föqò‡4æº7GyãkÛÉŦSj”ýÁÉ?ê6än= Ò=Sâ1p&å š!™¹ÝøL"ãNsÛÝXÏœš¡f¹±€V••¡¾Ôû"Wˆ +ÀÆòJ5°Gc>+Ù¹4Y(ì lÙˆÊaÜG/Æô<m©§ÄÙñÏöÞi0[IíÓÝøÛ™ö‘w³ﺿ2Œ+žag&³ ì?ûÖ›w™›Æ—Y»¤ü2B\Ú»Wç}Ò•wc=Qrþb„zöÏ)–G8zcïcT܉Æ{§÷`?# ý²öGç²É­š¼0ÒÙ‚£ay6XCè¥}páùf·²gù´ÂBoì¨oä¸?°jó¾?…gä§,§}÷áá*\gØÅy§—:Ùåz=×9¹þL`ãY7r}öW¸ò.¢Ãè0h$ïQ£1^žÿ3¼Ãlâ7ž“€ø¹»ì 5׺A×ãì¦ò]_@×Xí‰`œy i¬óÂç;?íÏ׋õiÞË+Åçàʬ€ý)ë&ÃøñÉ‹òz AœŽÎý©iÔËÝ}Ö›Ac$Žù~¸ê~)À”ûœ„ö=ùzôöÙx g[íWJ'€ ²ÌšØGy·ÿêRƒ;síÙ`Ð>öz`¥¯¥×ý¬ÆzŠ·~€öT 6²tùLáý4ž:Iõe„§€£5…F©jí¤ÄÒC§Æ¼ÝüÜÉþ’ÛOÅ-ÜËçÆ£*ô3Ìf¬»ÂìùK øyø=}ÃÔ Ç›ÍBô§ó ¸vÊe5Ö'LyƒíR‰Kûá{—õ|úžé«Í˜7_—úG>+QÞwÄ'•ïz}&öv¢‡^]‰¹²mNÉ<œªÀø)¢ÉS…"£mDj¯íKLÐ÷¨r>‰‹/§ s_B;´–§øXjÜ6÷ÄU_˜Zð¾÷ȇ´P^–­P±Å=Ù4º÷äŠöü¾plw)ÇílkãÜÆÉAg—‘Üyì;íYrg2³‹—Ÿ÷*žª]Èx×ñ‘H-õ¥ý!ŽlÚØ0z9îP¬ ˆ +ì_,«“¢Ùh â#_–-õÃŽMX+o{Yú~/ižêųÇïÓY+ß¶‡<„u”ä²#±˜r.ùÚ Òtaìû“®¹×ôëPEv˜Æâ÷¡tÐY’søHk¤ýs÷að”V÷9Šåùuû¢bŸÛNv)2Ù— •ßË*Ëûõ©AJFºä:7­åèÍMÕm:#ÌCbË'ÎCä/~m”kîx.;}õÄÁŸÛs¶»f$æô‰°ïÍ£ËÃ뎘~cOtm¿%#¢5ŸE¤œÙ&Dyг0ázä“£—òïË6á§Hˆ;°Ì §]IÝoO*ioÍ®s+Ÿº¢7G›”$lã7{×¶ ¡/ôFUU÷-ŽzÒ¨‡ÿùh£}¤óÆ·½Å{¦»±ŸhýbF(/#¤Cå‘ss4Þ{ÊmulbÝC–ÖÎö—g„´÷;TD¼çLÚ=’bCæXù ûz‡/)ž×7»½\{"Jx|¦»kÎh,gލóuär¶Ÿ9‚ÐQq+ŸX‚ƨÇdUía/ÄÏzÒ¢9Šë:¯3ë¿$„ ž"|“á~È;´ý*s1ÚÓÞ]]Á{éœ@rã<æù<ä'½›7ÌNê‡5öIZlz¢©rg€\ÇëgëÆ½˜D2l7žo œ`žÄG¯çûÌO6d²î ‘Ly穽Œ0î=E\{¿ñû£Í»1—ýòå'5¶ÚÓ™Ý_·ˆýd‘ó!2È5Χå‚&i÷|É+í€5*_éö±ÏË>ÝÎÉŒYÏÆ;~Íúþþî“öφQž<ÙPeç;Nï‘%XïÎI>Óÿ~—ç©XÆ +#ßÜøqÚ=5彘ë4¢±ì05=U9‘÷‰lŒ“¤ñÑ @à)ǽó>+žžÏ‘íŽð¸Še0íÛµÅüZß2’.ïÞ™ûìé ×xÍ÷¾“xÐ>9Víbüæ§´ó¼蔎˜Ä¼^økóÙ™’ÿ‡fú¥Õmy¯›ñM‘ÿ=›Ó+höó2væùvÎÈsn¾a)¬¤ƒ„OŽ)¦äø3w—–vz½ŠQ„'µ Üð/F6ôzß,ßࣜpè P{Ùòr?w™âꇀ¹«ºåP²i|-¶´Ã÷Ü 1û~-ƒ’@açJ›f¬·ùŒp·Ù>œÃ}v3†Qi¨î`¹†›•Û7N ä_¤ãë+£0’ÓÄ8³Óu½Œðÿ3öàQËÚð"rÎÉ€‘1`À´«]Ië„É&*íNž•„PDBåœsÎ9‰œƒlL09‰œ1ŽçÜsî½WÏL¯Žísîÿðì#Ñší™é®®zߪêj%×W­$½àF5lyO⨾¡|Ô„‰âÒ|:²¿R«4jdÿŒºËö!Ü®Sêaàõ`´YÙè”ë­•ÇP¢jR=‡ð”—8ÖHzV<rQÿЃ’ñ/U ¼(ÛR¨Õ¡Sª}(θXCªzü› 6ZŲÈŽ8ú)»ñäZ Ê•dâºÌ‘ ájs„\'Y$I°5òƒÙ£\îô ³1[7%®«x~ºh à{dc¬ž½±³é²q§™H +ßSKæSîA­‘Ÿ£sze–må¨ Y+s!ï%‘NU„§K1 ¸XN¦UKfr¹Ò®}Ð'¤gNC”Œë²F®ÔtéYGJWà$Ò³Â~ÕÊîT;¨R¯Õ*m¶Ö¤QÙ¦ŒIƒ9¨o« ›²©÷J¼"×¶—M9ÈjyÊ„(#dGâ÷â'‡ŒRÄÖ–8´! Á¼3ÛÖ–\l§¬Ðê¬Ij‚²\kΨÂéŠ`jå]œ¸v²V~ ­9ÁšÞŸAzPbrµx¹Q«¨[Å7ü—•¤v[;e͑إ]—-ã62$†L¢nñ¢&=˜ Ÿœ +é„j IK²”ñ–4’ë¢lIQK±+¹µbHʃžµä¬%=ØXu"Cph$VNÞpö×[ðå‹e†ÆÄΜȃí㿪ØÛ¯p%6‡š‡Y€Ô1´›M—ò vZåûŠ•ÕKÕNÍp|]‰ +ÈÌIjTœìråJ©ÑÎJA'¸ª éöU¥^yZ;‚t²²ÆW*åZ´æ$™5»•93ÌV0âÓË¥^¥Ì^)½š€µ´HåFkÒ(+k=®ä¡ ³ÃJ”Èc£˜2èÂÖ®«s„´+13žÂ]ó"'aà +çŠ*ÂÕ8Íï¬Uü V²75 +ÅQ°t«À]kÂKá ôJ…*;eŠÔdK°Fªž0SÊ»³UÀ†ÆŠ$§A;AMx?ír¥]gMV²\iG¯!>M@I¦ôæ= x^È»YK‡ÞÈÏF胾k– +¸—¤6¼ILµÜhF æ]›¸Ý† 8D[jÔ“O µ3ÿsý+b’IZ±Cø`:¹‘ô 7ûôP,Xy4[ a€z)É¥ö) ½ŽÄ“ÍÎÔhG܆Ø=3_éÁÖZMV¨í‡4Qs Yuéßž ÖvíÁNY¶j9‘X'ÿ#¯eyætd‰T8IîÀ†øÐÌ5Òôæ ìé™ÿ±”>P69¸†ë#(>`µNéAI”ÑH*ˆô (PЈv$‹×Ö†<z`–\ü¯ÌÄyÀV:Å ¬‘7tÐ+TWÛeÔmIZ·ZÙë0„ÖÆVÉ[þëò ú.>Q\@ZjÔ’d1+eÞô°åŒ˜sî´¾‹'F Àã‹Iå2;k¥%)L¾îRÈÍ•màd]ùbsLެ¶”®TÒ†4]2Ÿð¡åzâ"’ê…ánIí.ì‘’sÛI,ÐÊVÓ%]+§Rª%—œZ¯QÌ ²îJr¾F§Øi|ŠÜƒšäc€¥²R“=SjÅû®ÁgÄšK ZJÛ4VD—hÍ»2@ê”v9Oº˜”þ†@)kI ;6å] +jÅlj5R£V­0mk[;2ÖÒZ—%XÚµ$Mãw©QÉSK~|ÒƒÙ¿h%oþ‡ˆW_ke¥<ƒ q|jm•$pùˆqÅCi-mL²’÷"h»xCac†Ñ~8É‚ô ì TK ²aÃŽ`qÄ~ñîµ5YÖÊfÙ ˜w£€ŸÓ¬¦tÊvR+- ‘¨¥´|¹‘ÿ”͇p‰›©a{žÜ3D +•!Ö+û¬t]BPøL¹ÑZCL­T= +J“ºŠæ‚cø€qRL¯Ñ’'¶éRÓÏJêh”â¶²–kjXÙHMR£é×Fª0&+©Þ‡• ©µ!ë©Q ÚÂØ˜¾ä´—ÛÕ:ùb3J²Õ[+v6ÊltÝüú–:ù-ôÊŠSöµYueˆzs è™”5•ëV–#e«®Fª¹#5š+\bt'÷`Kª~¹–îfGrH Dh4¿„ÎŽÔCè»@/yœ•”I')$)ôˆ7xé”[é̃¡È¸ ×VÖJõ2³ë” êYJèRmÞȧ&$N#å,Ê›ÌÍgn!zÃ}ùëRoG-e-WÚ5EIÉL£³R£Äp£†h_óô·ÖJ„H®’„oG¤I£ÑËmÖ¶JýK¼{ÆÜš°z;ÒN­ð$k©ú˜Ÿ0¬¬_ !OЮ%ž&¼Ó‚¼œž- åFµbö>•f§ú(%ílɰá¤'ùÙàóNB\ŒFº^Ù4edñU +v¨á)ÅKˆ7EË=CµHåŽr"4*©þøP5¥[e„ZRËr€ý”)•]Ò|ʺ¢F$ G’Y[wŽò÷mºhC\Ã`¹Òn&0:µ¼½Ô–ÄkÕJÀ•ÀœÌäžmIæÚ¼KÒV*¢'ÝN§Qº5N­Ù ªm >R+Å»pu"iJ98B@Žâ©%ÅHz0/X¿—ßÎNò,K2¤#{zmÙ—«tÂVašŸlÌ3§ïâ­T +çÀ)ÔÄg-×À€íÊRˆÒÊ\Á¼Y-iåJ»ì¥3 'UA±R6y«Í$¡Ë}M7‚µ•´–4°ÍXy6TR öÜk‰_¯?¹sÕeµ‘/¶SxµìÀ›ü‰g[lá4o-¡}3¥2æ0·Ä=p£ù!èÈU5)ù)µ«µ +`Ð(, GMVZ¹›’r –JzžíÌólM­CJ¥+(J¡3«R¹þ™]—2›8õFîÙ®‹ R-PGCgnTjk˜ËÌÚ˜n'Šg9ʦ—2Ñ¥W±– +®h`k»2ÉRE+kðÒØ$k]ªd©»îχó •SKa\dÄ\0[Þn À]ñ ™;ÐŽ+ËÈZ—óÀ§@*èd0ŒO”Ö˜çNºRòvJ´'É=› 3­ml”‹uŠßK+—X³Ö˜‚ø¤¡Õ\µ×Zyë.±/µ\I 3'Acœç$÷`Ý%ÃZ-Ák-)¬– +6JÊ.^™É=h»˜E\³s¹ÒnvÓÙéå3ÐHH­\vD%¡_|¼”9GG/¿¸HX¨KÑ$R-F-N‘m5 +U+ãmÓ%–Ö%A;!“ +f‡³§Ì1¹Â 4MÒu|mIÆ5ñÿH՜Ȯ‘yÒdÎñÑbíć©—Y˜µyà ¯V©IeETÆ ¤s‘Plú¥F-©—ªµSºµ¶2£Z».Ï`nWÀ tk­à¼É®$ NӥĒ-©L¤–X»üÀzâÏ–w²C],5A¦V„¢B»5qÛY‘"ZZ‚L•êQvD à´$ó÷5Jo’]®´› †NŠ8àF¢=‰Î²#¥_8鵿žm­µ3Û*+ªPrFã¸1—̓Jb$ê¢(tk=m¸X®Ôd.O‹÷óÊßDzÒp`QjTrÀåÐÆ{èRSÚmÉZ5ßMM¼T6jå©”c&ä’è¤ AŽvZrñbì¸ÉZÁf]u#´+¸Q© ZsªŽ¹KÂ>ÒƒRr£ËÅv]à¾RSf _;MWñГè½RÌV®yRÝ æF ‡v­C¦'{ 5R¹Fymö¦´èÈîMlÉ×ÍFJN,‚št]TR…[\ꎜ¡Óª»ѳ%ƒc£Ô#ìêÊ’ãÒÐhKŽîèRMJ ’ ;­Z¹XOòâß4šS9ÌåÙ¡³wS^8p;;³à‘"…¶æù5u­†”3 |˜¢s›ÕmHù¾u—´L+[ÉTヿÈãÊJT‹7©’)'šàœ2³ ×M¡ÅÅfb*eùãúÆ$Q¯Ô.í’ÛAê$@»²c•øµq£NqÓáÄW¹Ñ|‡™j@qX[^¹ž¡­ä]ÑJ9¹ªcWRbN%v3j²“µ 4êµäÁäBzÉ;-®Ž8€ Ý*!ÙõÉ?”•¹ÝV§xo]‹D2urá'IĉG˜KhW&™p#eíÉ(Eªæ$¥x)Ï`# »ä¼4ûîaÇnyeîdW¾4„$¿Mk­t‹¬âç#!1ÉË­l8Ã*?T©Ð+.o-E:ë.㌀|¼“„Dˆ4BÐY“]›jÉM>_éAoÛ…vKkÉF- ©± +Å<4ŠjÈÎ}RpFÆ#Ä%¼÷¦RÓI©£)½' úü§³¬­Ia[Ùâ¢FÒ›KÑEü +¤Vš‰™K[®”"M]èÞ'Cªí…%í¶¤à.ße•âqr™8èÃ\Nâøx¯)†ª&ÄKÙÌ']+—ûÔY“SÌ…–ñ^9eƒœÞÆ|²l£T*dá= +Ë•v[ò†¶V’gL>)e‡°RÆ®4—S%ù’ *ÅKää܃¹©\;Ïæ ÉæÒq8L«ìEÃAnÔ“ÊÞ2gÆqsGÂÆ±8)•@°çPn$%0ì¬m”n­ÉÞ2sü^Þʆ/9ŸH2¤x¼¬Ú°FPvfÁ‰çf #»éñöNY§Í:¹ø¥î?œ~BŠl)ðWg%è¥W–Êp@£¹*ÞÀ1_ÑkzYSh•}÷ÐØ¥©ì#€F¹›V*2aÖ¤6¤®¢Å­U65ëm Å,«f{§ƒ*›%à'‰’:« +¦†Fkeç°™²kÍ™´Ö¸iæ’j¶|Hd“8±%¸TW³VN ÕÎKÔܨ,a®½h-§ÐãHù…®¤‚„ú_zø×G[Þõ`¬-£GÆR¶dC»NIÕ5ƒr%í×Å#•Ÿm‘RuWz0W®}ORª.)j¥W‹ÿ\ÊO~¼?UäòWÚmÉ›*ûóì¬ÉVk)+Yn$eH +|ßV©·¤‘r8ðÍH!œ.ó—O0¿ëAFò +ÔJ9Ã]Î÷R*UʽX>ôä?Õ´T‚0Zs¦ªìÔý?<úË'3O¸¶KY\ T}!gËZ‘£*dkŒwØ‚ÑÊ^Þ;¢z¥–lúq§Å*UUþüæ5„ñ) ¨&Gðau¥Û#Õð¥vr¼©²i×)…/¬»1Lñwìz0ó¾b~RK³FóÃ’Z¹+4Ú ¥ÔNù«‡!75<‡ Êÿ}S[BËÉ™^Ö¤F9ðOýÎïrÞ˜²ë´ƒºËyc6„œáªfæ#GuJE.¬O•NÅ/ï=þsÇæ{ÚHE¨¤?Ùszm ü?9ñÖŽœ¬hGh­\èwN^¨KEÚÿðÔæZ]ÊÅ6]O”ú‹g3?¶´4$›ke~l[“>©Ä ·&û}å]ö¸Bñ™É•#¡-ñ³[©»ÔQ°6o ”O¥…¢ ²‡T.±ôçgëjšlÌ9sZr8#”=ЫIUJÍÆ›ý×:¥f‘9 ך!–Å–¤•Êé5¸‘¤–éµv–ùfk­—´€–8=ýI»š„u +-WÚ­Í9ŽJí,=Ùºn~ê?÷l6,j)V2•6æS¬¡îŸž,Më.[<íH1 9>æ/ú1kZM—Äù½ ¢Ì ÕR¡uRHÑœj€éÂòÓÏò.0š‘,®J˜3o4ï|2ÐÖæH»Z9UQm¥$›ál¢¿ì˜€KHø´%)d:r/$ˆê”¤F%’)Ÿ$øk#‡t¬`‰ÚþË›£Ø¶rqsTcC–Q­ÒížÁŒ}mºÄ‹ð,¥Ý|ä2Þ>G]ÌÞj5Öjsûú‘Fñ)½å´é– ý§ß§Ì]bç²píêyÁ¡ë¼ÜBB<‚×Ê­ó<¼|Öþkû4ãÚµnþ«-q³%jŸ>ÐÊr.Ð5&\9/|sá¿jK+ü‰„ÿ-E¿ù¢¶pKµ•å +K^´²\¾Î8¡‡‡’ýPòRciµtàýÑ/°Å!6Ü´üMpT®4 ]¿û×­Ò××â' į§sYäãçñ±ü;~U'·uè-ÑKNGÏÈ,Øoö0wù+Øe–ÌÊýxK|ƼÐLüÛLܳrSÑR6‘ÅG¯äýÿãjø‹ü ùZ_èÖj;œU ç,A?Tެ—íÛÛ ®ë¾|¹+¾Æ‘õéFyFöÖ& £òGš¢ F›ëÞe*Ç2>Ὗ°Þœ_Ra]Ê`amÂa]ÞP!¹z‚˜Tû®WùŽ)¹ÎRL­(Ä”Žü’P«‚zðèZ.¦f,ïÓóŽì#$ +÷Z‰IM–BPò Î?®ëÝ~ò¾Q}ùÀøþ|léh1©y¢[6†‡ë#ŠF +Þ}8Ïu½LkÓ‰Áèþ¡¹Ã¸ì!t`\.(cíÕË™ZÝÍ@™ºyw fÕš¼GhozuPOÆ+¨çÚ›õîe4­¶p2²*£›_w6¸h(·.kåÚ‹ò +îI{†ô¤Ðزkbû +iƒ .žÎ×nÎܪnÌê°^ÌôþQý„ØÂÑBÎÖébâú‰ŒodGÁ§íÚ“÷O€ß=só1º| çúAãÀÃxgåCs†Šñø”Íï±ñuïСƒ˜BÔ^2œ,A{%öq×vwr èÎ& `£+FqqÕc…„Šw¸ÈÜá|xúP<&ñ%c¸Äêw˜Ü!ÌêÐ^BPú`>0qÌ岦;źZ8𞢗…=ãdQPÙ;zvsprë¶ÌAPQºÎhÞ¬Ÿ…ƒÉér^µb© Zö¥AåÀz[8óþÝ è}(w4¦èÿËXÕÂËUΫº}ûÐ>éýŒ>™ý «"z:q~öÏnöön*ƒÉ·»“iÅÒ•Î*gÁׂYW8ÔÑ=¨ûÒœjÞb{Õ +'4Žn‘½¸µƒÙ¢¡ŒÚ`áÈûY8šBº/A×-™o¯r0º"9ŒéÏaä|,œ]ÂzÐb`Ú3¢—à›Ø_ôOÀ‡f q‰/™›ÈÇ”Œb×&0 ÷EÏ`ÁGâƉI-–B|Õ81<’çQblÍ812gÈëÞ—ò ï%D×½ƒÆw¿&º¯_=^¨8¡çKŽhÅø‚±p ‹d‡]Ñ—õ ë#e6¥4¾'¦·¼oJkxî 2ïU:Ö;P Žè/FäŽcòFÁ}¸uɃŒî=h·u=«{MÞÝ)Ÿî´ûÚžœ?’õ5 ý˜àx$3Å£MqUãÅØ²±\HÊ Þ3­ƒŒABbå81¡é]!¢`ç×ö^׋õîÃ…d Ù§¼Öö`<‚zŠiƒø$aCŨ’ÑbÎŽù‚½³ÄðÊQœ|& ®ȹÜð®Øø.ŸÕ:EÈhŸ*D–â×e áüR€l +‰-ùôÍﳕßÛqµ?eò¶ÀÆWŒáCó‡ÑA)œE4Hï8ô Hž“šßåÓ7Lk&paiCص±ýÿȾ|TÚ01©q"š9„õ ïÇç ç‘ü¼Ѯ~=xO¿žlló8Ö?¥¿ça±è‹¥HG.R9Ñh½‰a=œ¸Àîn šËFôqâ|-V¬äT+—1*Gƒ[7ƒimwÆ?º/åŽÖ¼{7£IåÄÃw}, «‚{0«ã{Ý#{Òþè5iý ãênŽ´W7GΣ¼ç×— +Îz%÷uƒ»Ã=þ³@: ¿&©?ç×Ïo|_£ÐdßÞ°ª›Aèά‰ìÃû¦õ7ݤG]zð¾Éý…ˆâ‘bpÞ0Á?¶¿°&²¯Q0ÒU0ŠuïE­ŽêÅúÅöcc‹Fq9;>à³7M5!yCóÓOˆéóÀ§#òF!9ß޴oXo>¬|$ž§ØŠ1\ÁW³…‚#j1¥æ]12o$‰Æ5ªp$è^Ú2¶M‹iÄìmÓ$£bFëT1¶d 謑þ út&4äŠ JsŬ‰êà } 2#†§"Y*#¤·Mr·NRZ' quãnFò1ËÒËbXÞp!$s(œ8ôô%„ ÇsS0dŽËÚ<½ï1mËXkBz+ú?zÖÔFK>µí}øpië' + õh Ô7%o~ßkmt?>(a—X7^LE} ½Êgl˜„~NæS7¼ÇÇ—å¢KF²éé ÔŒ_|?&ÍCBíx>©~S:š‹+͇&†õÍ¢q½Ê‡ç ƒg¥Lh.AÑû‚Îùä¼Âz3^þ=¹¸úw˜à´ WKÙ«–.wRÑn= ’Å/)ÕŠå&•CßG:‰rîi=-@ÿ µÝƒõŠè òºÙàæÛòðïapõï¾ÌÞ rdV[ÐѽhŸ„¾LHÎ`¸·Á„l9’1Ê5¢'ëŸ:Ö^:‚¨Å¤ gÎÌÀû¤ àÃò‡s¾Iýhˆ^\Pö`>¤`˜½AP-Y°Xeü,ø€ÌA‚WR?£kP£€ô8ïa¶ì4èBК¨~ÈöáƒSƒnä|cú2¾±}ùˆüáBfóûBÖ®é @¶¸5H>Ñ|"{3ŽO¨'$ÕL@ºbëÓ‡õè#„àãkÆ™Ò7OÒ·O…ybªÆJ¸ i¢±q2¤#„¬S„¼=n²¶O]$†g Cº°ãØt,¬ÀœÏºÞlpÒ@!:w$¿.w(Y2Rˆ(zl3è´&Æ +YmSùŒ-SÄ$Kñ5ïð…xýp!iƒYСð, Qe£¸°ÜaðN°–„´“ø¼½qù»g°e'¬éò¯¬øÔõ¨Ò1€gàw!¡aôÍœÉ%7N`‚’€ ñ Hî2Û&cYÌjÌž-f´Oc›&˜’׿‡î5ÖíÞ‹ LÄFçЇ]—9˜]—>ÛôȊѰVèµhì¢û1~±}±NEº– L`t DóçÝÝèâu~n˜ôÎ3´7ŒíÙÛ™1us¢Ýº1>È.øÆ÷£ŒÒ.!=ØUQh½Gõá|"ûPH/ À/Hþû³h¾9XÞ!½™5èþèƒ±Ž Éo`Æá5.®b ž3”Eý0zDô¤×fà“6Nd³÷|ÀgìÆ‡—¤ÝCz²H—Âz5é¸7–ßÐêQ<’'õÍxXv=ɸõ¤Dî°žà]À. Y¦€¾ü"0üú á9Ã¥÷.…1 èÈdËã&L¬åÉüæô ¾6¼b`!60iÖQQÕcùˆ¢`¿ÛÁŠ1ec„8„ã"KF ‘ÙÃÅд!BXÎp°Á  £°ý F2ƒtÖ±°†â*Ç‚-…yà#3‡‰)Íï )M–  ¿a½ÂºäÂs‡ èYaÝiHW¥¯OH®žÆ–®r(&mšÄeî˜Ê'ÕŒ‡gÙ€qD6b›³k›·oSòÕl&wï46¶n,[…0qí8ø :®ã³¶La“ÖOàÖå]²&$·Ld‘lÓåßh„ÌmSù¤ËÑX ùºŸñEú'8u [>šÍØò>—Ù>™‹® Øô˜< ËŠe ÉlXþ0Л¸-$e Ñ7®íŽtÂË€C¹d´Æ>Ý DâRÒ€E‘þ£×¬ë cÐ%hL‡šÖ"{ì+Ö>·&¢/;x†‚£³ñÚBt#^oèo  Ûpy_Í¢kÎë™âc³éªÓ:&ÿà >²h5ˆ®ÃfžÁÔÝúŒ-ùAËú ²w=½¦;U:Š/Ü3“+90›/<0 ]Z+Z«µc¯ðÞ”kpÀë¼?—¡h^C‘ýBëQˆ©~Ç”²i2è*Ð;Œ«wwÎÙeÀK™Û?`*Ž[óHÇl"Ùí+Ddç36Mær÷Ì€yÄ#»ó 2ÂE£5ŒÆÖ/¹?´>`> qkû IùðìaXGÁ|ç ±äAç¡{rH¿Ã:b#d ¸É–™üC3¹\¤W‘œ_À󀞅ÏÞú`HÙͶù`û#r†Ïb +ö}H—žMíÿˆÍnCº´ÙdTˆ,ƺÂó†±1yÃÙI²èÿˆ²¹»?`²vMa’›Æ3aHVÒá÷ ÊŒísÚ–Il&²ïHÐ~q}Þ½ŒžA˜cñ)MÙƒññ ã™`4^ñ}`àùØàÌAl@ö &¦t$‡ÖÖþ>˜3t*í‹ì+ºÈ.—c[6š½‰8È-‹Æ‡öIìëìÐÝàÞt%Ø +­,Ÿßwd<»9![n/ Ÿˆ«À¿…â_}\Æ\ÜÛS°Yg0egutýù¹¬=ÓØuYƒéPXç¥#Øp„ñïEùÌíS˜‚ò©íï1q5c˜¸ÊÑLtéH&²l“Ðð|¨¸¦±T@Î@ÃêðžŒ7£~”oZ?6¼d8”9ÐèÙËÉ`˜(ÄÉLH{F÷ ¬+ƇÇr€lØGñ ¬/CÓ‡ðkúsÑ…#Œ —?fš:çbþíÕÛD4¿Æ†ë:?¡Š|Ä'5MùÄ: ­Åtàj4–ý[!Nð.èd·ƒ|NÄóÞáÙ¾€ù7ˆñµã4|ldg‘}á}=Œ1’ex&®tpXál‡†ûÏù!Þ°&ºÆ"Èv²r;Â(H÷ »ˆÖ/È$è!=‡òX/°¦@?sé-ïñ©HvÑßð³e´N2ÖßÔšn~Bìúì7ãÚ Ö;ÜÖQ2‚KÛôƒd Û9·ôêО°Î`\àžtp:š+Ä™]üºgd½£ÐшûK:´n,pY£Kæz°¶`}Âøñ‘YÃ@Ÿ²ÈƲ>ˆs ›D¯AëÀ#²…ì1€ð’Ov]þ:Í'g>4w˜ƒqʵø’³Ñ.ÀÛý,œX/ÄC|‘MG\,Ýü€Ï`ž‘ΛŒ°p_>gï X_`›Ù$§Á¹h3‚î|H»­éaô ìaXÔÛƒu9ƒ>‘½ !=´/wæƒ6 í¾ zmjÊ5´‡ðu~mw{zµð1àS0n—Àî¬7Z›èÀÓYŸØ>œgdoðû \7˜OB7Íà´Œ­S膛Ÿï|Š×è±ø¢1ÆækŸ2m/—¶þ}¡sãC=“Þ†®¯~Ë`TùHƒGpGVèÆ w¡+¾Ó²Å'5lhÁ0ãêàžàÃáâúÃà‚â€ÞÄ|8¾|(ˆKW#nQ9ÁŽ0A`ì! ¢àO!:k8ð.,u0ãŸÐÖæ +ˆk#ŒÔ‹FØ” H †#l•?éE„1Ðïaˆ÷Då!œ^6ëZd³}±È=ÒÙÈ@kn2[|p6‡¸5¬A>=è£ÒZ¦õÉ—ìÖûŽÔ¦{ó¹œÝÓ9›ÀŒÁ€¯„!×¥ d ‡á±G²r ¸ t'ØkjMtà´ºt%ø…‚²QÞѽ1LZ:Œ ΂qA\#Ââ­–€q¸ ÀÌHGÃuW³ñ“ŒeBÒÓk“úÁZÙÄ:­ø>üDvaÉ¢e*˜wƒkdOàψ YHë' ýßá½UÖÓ‚]“Øô6‹t +ø? ¼·ÆŒHp u㸔 ¹ÈªQh-õ¦=âzÓÞq}ŒˆW;"Nãàì¢räÜ»EÄéQ;è>ÆÉ®GL/$o=¯;‰HöøàîF­MϨ^° ®ëzà5†t,ø-Aw"¾×Û?lçÓ +!yÃÀx²ÕïFú*¥é]¶ü„Ž-?®Œ9#â¸tÕ7Öô¶û+˜Ý¯œ;ÿ¶œ*»¤eãËÆÀ:gï ¾/ 6©~¼±åúçtÑá˜ÌÁ`‹¨ÕèÞ?aÜ +ò˜Ôb)‚Ù[ð=™ë'ýÍzc¾Þ[Bx`]Ú`Œû‘L>[Žu(²± ËxÌ×3† ‰ ïò9;§ó9Û¦aþ›P?AHi˜8|†Btá(1 +ñ´&„¸’±/gmxŸjºüUwÎŽ Ï +þLe1£ö=>gótŵñþ|ªõÑ<æ's©ÚìØâ¤3'qk2€­¥|¢{}b{óQU£¯ÒÕ?ز%ßkÙØš1€iŸ˜>|Ê&Kºæ‚žj¹û9àY.yûl|Ó8&®QÂÙ‡f0Uõlí/¸¦ó¹†ËsÑØkA7`»’T7x)SqÔa«éØ.%Խån´Äø}øÜ²…Gg1•gm–®4¨À—r±b™AâëH®`M/§ƒ +ðœñ'ð¬M$÷àç˜5ˆC¼…›èÕp¯qÒŸîѽ€Óq1ÛEVŽbCË0¶æó‡€^¼>aêÐ “ŒoJ?.¨`ZÝw Ö'¾/œ=„_ßd“rñï8T\—Ž}ublù;àÛÅþÎØÒ1Bή|öŽið@„áÂR‡ÖããëÆñ!)ƒ…À¸\Zã»Æú³¶Æío–R»~\iØüò :¶d$ÈŸƒ°Æü²”gLoÀq0V0öx#=ñy ðߊñا>¤ìmÓ±? û*ßCR‡€_†ñ éů/|)o ¾Î­K¾q1ÙTÀÑU £ƒø@„_‘žÄ +ñu.k'â0çž‚ùz@BéF1uÓûlñþYðž|ÆúIújºô)›·k]<‚Dü%<{(øW™ðô!l0¤—ØÜ½ÓÙÔ–‰˜?¡ï²E‡f1)m–\tË;€a¾ÀN°y?¤›}ÁT^µcRZß»ÈÅÔeÊ[[nÏ1Ôµa36¾Ç„£|‘Í E8'}ƒ%¬¾îÊ\ºáƧTÓÏØŠS¶ð>€“€sñ Åc¸’ݳ˜’ƒ³¸‚=rÉëßlÏ"¹Å®àØ,oCÕ­¡¥ãàÕüšø~ôª€žÀ×àë`'n>p'X×KE–ŽÄëÍ `-Ð!€ 3A¹ƒùèZ‰¯‡å Á>F¤sÁ^0aîþ€.>6‹Ë90ƒ ¯ÅxFô†¿sÑÕc`M™¢kÁ§7ÆF«Å¡{Vô+çäé[𑇇õÂ{E÷…˜˜µQæë±ýÁ_ƒ}…H—±mïc!p7¯ÐÞ|H Müxˆ³ åc¨Š£Vôö‡ËùýwLTÛóÅlRÃxX+ϤެgBÚ a÷u=€Óq늆ÝcŽ. übS’C!,{˜Wþð1¥å=Ùyq]Þ0ì+€ñJn˜\û˃RñQˆ×!üú|ƒ2_ ž | hL&pYíSwžŽys<š?øâÍØÇœtMÞŽÀé¹üN¤jÏÚ2ÅßÎfòûƒL§¡`¼£zƒï|€OX¯°Þ.)M“¨êÓ6Æú‹z&gït`Á °ià»æ×"î¼õ=.q«%ØiÌ%‘M27O¦ëNÙÑEˆW"›Íøÿ9Ù”°žH—Nê®ÎãoÍç3÷MŒzÄ€Ö<Ò[ýðºFv)C¶«æ;¦ò¤ ø½0¾® sFUÒ7<œcØôfžSëÃO¾˜Ç„Æø:øŒø5hÍûG÷üÃ!}Ë•²âS›,…俉ˆ¿Ï%W Ê®é‡ý5©mïÓå'¬™‚¯>¢Ë¾Ó0?ļ q%6iÓ»lá׳èÆ[Ÿ#¾®cŠcÿ>@ø:[¼oŸ·÷Cð¿N‡µ +Hâë°^_OŠãkhAN\’6N«Çc¾î†ø:²ïÀ‘±ß9£m2æËÐ7ˆËÝ2ËÜô>ö3Í=×re!ß~ÓÛÕad6?Ybh<£§óvLe}И¯FXÜá>°;%wü€¹?Òa°6á„€dÌ×S2̇çc¾ŽýIH¸‚Ã3ùÜíÓ…äªñ<æë…˜¯sY[¦Â3b¾>DàÀó@‡"=Ì”šMWÐÒÅGfoü”˜«!\йzBÍ8ˆ‰qÉu㙼XR—?f×w,¤š;ç L2ôðÕ”Òh)¦ÙlðbªÎØ2M—ç0u?|:¿'²©lùakĉfòéM–  ¸æ› „¶ÛŽ06tÕ·Z,Ÿ9;>€ ›½ }¶Oe +¾™É&µ[Ré!>jô±ý*$o°„y›~ Ú7¶ã—ÜßèÕb ¬â>hp¼»à°?øBGºK@ºô"øçAþØÒ#jì7 +Íx”-Ú÷»¾s‘¡ù´›ÕdɧֽËç#‘»uš é^Ì™Àþƒ~‰©Çü ©Á". +ØÜq¥ c °3°Á60ˆ{ +k‘F²†õdXÁp§nï×ö¡'ÖŽg3¶OfóöÏôº?GŒc +FñáiC ~€94âF€ ðOÐ)ÈþÁšÅºt'ØÀˆ—›¶¿ü ø9¾Çë'0G4lá7³±?Â?¡?ày°“BPÖ“ZÞk{bÞ‘1ŒË(ŸÀ´ß^ŽíGDè厢ÊÁAPa™‚xzÆ?¦/àÞ/¢/Ø!À¼¦ôæÉðn¦uÅ#hÄ8ÏØ>cå‹¿ÖŠiÛ?àva£ÀGŠ8ø_.¦U >^¦š÷Ù—ªe+øZ}‹ªÅä"}Q0bXÐ``˜Ì_‘Í¡3çmü û—#Á'Ö› ˜ìp^> ñw4.Lé+cë½ù†/— 5¥£ÿî_~:_e¿Ä^E3.ÝàãL³*Ê3âÿ<Â|»]¾”V-_F©XïØ>¦ˆÒQ ¯±Ò;¢Ì7Žk¸¯í‰zö„±âýýA: ˆíOy…a=„±EÙW:¾öÛO±^Ì ¾N„‘Ù²£¦ê„ àL6°'²ƒH7ÐU_i°Ï>®h Ž£¦Ö[Bô0[vPÍn¾½Ôˆx4èmˆ¡˜"‘.Ïj™Ìo¸ò¥¸ù޳°é¡=Ýúx‘±þªÚ6Ö ›³}ª±î$Â~ßhéÚ z¦þæçÀŸ!ßbÙJÕJ>À‚IlÀ=üPbö–ibzý{ˆN‚5dJ®B|44àZS\ÁXà‡.©ƒ/4ž¡½hWŸîïkñ.Ä„‘§k/~ÂVŸÕ³wbŸAîöi G0献-¤ïú€iy¸€Ýôl)µþõ\ðKó)ÛÞçâÆÑmQëï|9o²À— ? } n‰ôÅœU:x9ø€«ÿeKZþšàÑG ÈB8?²Ä>¹ôM“èòó:6~Óx£F:¼tR<äÓIð±X¼Ð^5wþbÕ’ÅŽ*{ÖÇCwÒÍ×çPˆ‡FTŒ–3…lWP/Ì' +i ç d”öíÅ". ï.´\\Ì”}¯mþ÷¨‚8þ¹‰Õã€W›¯}Æn|¸„n{²˜)>ðÈŒ‘[eÁ­ì)øGö¼{‹¾!}ĸú BñÎY\éW!$k(øÖœÑz¢ ÷aM1®fœ¹P€½"zƒ¯ÍÉ(ª˜U~=„ðâ‘äK@ÎEZëdÐU ¯X¡uÃW×se'mMI-–0Ÿàç!ç é!£iÂ!3 5G¬˜íöܦŽe0¿Œ›¬kë.ÎÛ/;qÍW°UÇm@70í·–²yÛ?ß%Ή,9$À€CÌŽIÛlÉdîœÌ”£¡šn~ε>]Ê·Ý·§Ú_-6nºû›Ù6b<”w|oƒwd/£oj_:ëÀTcó­Oéú»Ÿ +ˆ—ž³×O +wÎSJÆcûŽlW¼ã#®ô˜VÈÝõ!ÆÁ€íÀ¹=HßÃ\Ñ g?å¯Ìg[.Χ[.}ó ¾gºì{ Änøø¦ñ|úΩƆ۟P¥§¬˜ÌSéÂca•·o:SòšÉÝ60Ææ‡¼drUØš‹Ÿ² W¿ÎCGWÞñzà=x}–‡¼=$\Õ7v|ó/™öËĽ×ÝÄ]pôC:ªa4Z2Ìœ7bÎî=×nŽHNƒ0 õ2 ô‡Ö7ø¢ ^d¿”RÁu Š9ûg™Ò7MÁxf]îPÈ× -o¼4Ÿ+>ió f‡ô«ëåëDZˆ;Àük¾×1å_©…¬Ó„¨jìƒä™ÒjÞ37Ló̆œ Ó4OÀ¾wð…e Å>ö¸ªw€cFhÎP´¦ãOdÖ0ðƒƒoE¬»¶¯9÷™ÄÙ‘ýކüŽÝ3ÄŒSÀgÏÅö—âÐyÃÀÀFe e ·Ng¶ÝXÁ}smµéÈÅ5lÎþéË/W98 *œË¶þ±õÆJnÓõ¥Æ¦“v S˜Í‹éг6\rëD.½øÜc+ÆFÿ?ŽÇ¢9EœjÄE5ˆ›".l¿C7=˜kh¹ð1]´}“¶a¢ŸØ8ZW4„ލÁä|=ƒËüjZëÃ1Êß< |^BjýD°™S€¶ê° Sõ½Ø0ð牡ˆ$·XžÊ•VÃßÙæ«sÙõ7b~ÒÒ1b&LÉ×VLÖî©TÙÁ¨ºz&çÈ 6¾e<èocõY-³áÉBÈûYéD«ÀVJyyÈk€û˜Å×^þ‚_w1]rJ 㲃cB¾ˆSC,8:øÒÀ"ŽÄï¼A¹ù6@<|mµÓÖçsa-ÐEÇg1‘M£™u©k_ÂqàuC°.Nlœ`l8iG¯¿7ä})ƒK,WÙD•ì;²óÂÚ¸þ&°#§3kB{ƒ~ƒóq^1ŸZ6lŽAnäü »ÈåïÿÏ=ø¡˜ÔúÄ„ÿ¦á F ñ4—+:ð)ÙÇ ÔÁØ×ïß—-G0ø„¡î‚-—¼Å’òOígôËìdd<“¾{ +W°÷#à ljâ*Õ•/BkìäãïšIW£›-¦·Oì§øW1§ÍÙ<•i8?Gh¼ºˆoºº€ÞxǯÀ¿:ÔØòð nk‡#½éñ"¸?ø"a­0Í·æò»î2‡‰×ø,"ÜöW°m:ðnÈÝ…¼C¶ô¨š)Ø;ƒMßþ>äpaEÃÙØŠÑXþ ŽÍââšÇ\€>nÆ´v.fó¶}À%4ŽgÒ¶Ob’ѺŒ¬AÅ•_ äÂÐÑ•#=B{BÌŒC¶p¿ñî2aEð=9/ ȇÜòÉ";G¹­Eœ(°'ø3Ù5{€?d2TÊUÃ>ð˜ò1lÑ¡™ØOô—¾s +_&å|OÌŽxÎÑ…\Æü3Ùü]Óq~Ä ޲*¼'Ä© ¾±!ðQ@®‚Úl‰óÊÄ9·9;aœ¦O‰öésd=^zëàŒð‰«'"ü +¾Z1¹b‚»mä÷2•Ç´3ƒ¬n¼¶”Ûu—2´>œƒsÖ¦€CÈQÁ~Çú+ƒÏ„KkµÄº81¬¯Ìíàœ?ÐûÀg‘Laî¹+‰5ãñZE˜|âLñÁ™|Êzé’7¾Ç”îeÜpíscý[:{Ç:ªr$äD°áå#ØLôÿšÓv8þ“\ÿ.äp +)ßÃ}#Ý 21 ªæ„ÎXu\ý&™í“!_üÈ '\Þþ˜úï?s¶ÏÀ9}¹‹°v²vM¡6>[Àm~¹‚KßÿίAŒË²Ú§ ΠæÓ[,áþX#^Ö¢ð ^GN ¼;¦z4|pN)Â7€u‘~âÆAÜb~ŒW4¶û0Ç´_DœÛß<b´À}¨´8”9ÐÉumwàIN.^F_„¥“Ú,¹¢sZÀ\܆ñØ6¤ Äñxѯ;Æakcú È‚¾’ò%R±¿ßx+øR³v~€ùFÁ!ï Ö3è>ˆMãAˆ AÜ|Æé-1~BöŒj¹ô9]óÇ­2‰‘%£ ÎÏí þ4¦ô¸5Uûƒ-Ø~ªö” ]sÊ–)?`z™ªCzÛ:d³ÛÍÞ>cZd³!ç“ËÝ=ÛþÍ¿4´ÞÃdn~®ÿ¡¡©óSˆIÑŧÔÀ_Œõ×ôÜæ{+éÍϾ¤ï|Šå¾èÐ,ºúŒ Õxùd³l@Cñc-ø¼ùô-“Aÿ€Írö}È–š} ëïÏg·Ýq .Lgožyw¡|×öÄöqljÓyÔúg_0¥t0Ž !‡•)=cMGTŽ`bǰÛÞ§×?˜Ç·v¬ ¯}‚ý°¯ 8Ä<ƒ¿ e“%ÄïÔ~x¯JÒöIBÂÆ‰CqwdÛgáœdÐÁ…Ž8f…1GÊvK6uÇ$&ÿÀtcº/`Ö¨ÚQÆÐÒ¡T\Ó:yëDcÅEkã¶Ÿ¾¤w¼\é¼í×…†ÿ\I}û› uòÍ*úà+–ÞòÓ2cÛO ¨Í¯²»ž: G;¼Äoo ßÝ]Ë~,0­Ï³5?|â’Ù4ÅäÓü8w·É$ú³b[îÎ7m¹E¹µ_æWm¸lt[щ¯=;dP -aŠoÀc ¼’j¼þ)øgø¢o¬!/ƒjºþ)’e[Ì9¶gÛ-gÚŸ/c6¼\È4?˜qøÐ —?ÅznCçºõñBÃúŽÏ5±_š-új6èOjóÃ… [˜¦Î/¯XÀ·ÝZ r&äìœ}©8_tÏtÐcð“ÍØ>….=:›®:ocl}4ÚÐ1ÞÜñ%ßÞaÏm¾³œ^ß9ÏØ|û3xFðßÀ³®~ rrM­øäŽÐ[ž/evv:qûïpÌÞGFç />7ÔßÿØØþû"æØ3þì£uìéÇþ±N/fÿ}†Û‰>èZqÏ vw‡ßݾwßȸëÊîÂP%ÔTÉVÆš;vNí?Ï¡>aÅc7Öˆ¯»–·Þ0Ò›Ÿ/1´ÝŸ \‰ÌžÜ2‘©:«®,àößçØÝÏ LíÕq>LfÛT¦ùÞÈ–žµŠqHÕ;>çÈLÈ1m¸åÀox¶|PL澩ˆ?¡“Ú&Ð)[&ÓNr¨»¥vØ÷v¡áØ? Ô‰ßDãéÿr£¿ÿÍÓpþV9_~ëNßÿ%–{ö(‹¹÷S<}åy{ꥌéòÅáÊxô‘×<}ì• |sÛÏtô¦¿ËÞëî¦ÖNbýµ…bÓ­/™–ŽH÷|óJýˆiºÿ…°©ÓÑuÓ-Šoz°ˆÏ;: ¸¢kJÃ$1®h¬ëºŒa.©›§pe;>®l†äísˆÓ}d¶?´gv¼rd<`Ù÷8öØÃUüÑ[^Üñžü¶‡ÕözÕxûCë“/ØíؽÍ¡qïk{ãž_W2;Þ8R{^;²{ÒôÞ§Îìá{<¿¯SÞXízüÜ:þÐUWfãÃE†–›Ÿ7>‹>_€Ì1ÅßY\‚ŒÑ›ž,âZï/…x-×þds¥iË Ê´ã +Ç´ÞXD­ïøt»鿦Ž9³0nx4Ǹùù<ç­?. ·¼\BïxºÂ¸ûõrjç›Ôî7öÌW¯Lì±Hsá¼0 ;òbû}JÜr›æ6t.åÛž­d7?[Êæ~õ!]5ŠÍÞû]qÎü?èž:À/|Zç%çtüƇKù –ÐëŸÍwnÿe®¡þ•ÞiãoŸ9µÿsŽÃé·F§Ž·k Ïÿ;Bxu³€{õ$Ûxã—ªó—Hæå›TúåoÉâçŠV?ßWáû`GðúV!ÿìQžéñí"×'—*¼oo]MGã(ÐßýºŠ;ùÌW8w;ÚtâN0¿çžhÚ}ÃÕíà%ÿU'NFº>$ì»n2¶ý²ÐÐxÿcnÛgÓÁÞìÎFªöºüà3æÚî­DzÈÁ´éºÁm×U—×MÀ7é ² ­Ó»ï9 :\ùã7}Åãwü {þ±Üxø}ô•‰;ý ˆ;ùÔ—9öÂD~Ér_?tg¿àËœüɃ>ýÊ‹¹ð,ˆ9ÿ"9ó³uêÔw¿¹NüÂQ§~rc.= \ÌžÏá¯^Še¾~äFïyn Û\bl~ð™±õ§°˜}iöÐCA8ØáÆî»Ã2í÷—7?žÏµÝ·7¾âòm:zi ·ûCïzêHo{¼‚Ûý€ößuãŽ=p£vüºÔ¸çÍ +vç#uࡳñðSŠ:þÒDŸüÕƒýáY {éñ:æüÓæÊ£æêã`ê›×sð)¶‰úæOí{d0~iàöurô÷«™Û÷B¹'.¯Î— ?Þ)4t¾ tºñÖ“ºóssûq4óÝ jëOKèRdCcªÇ/ƒ˜&Öå—‚}•Séõ™NÛþw>wà±(ž¾îùÕñp±þæ"¦èðGÎ;_lÜõÛ2ÉŸã‘×´sûßçj^Ø87þö1ßüãSÛ=£ÛÞk¾¦Óg£\.žM^uþtªëÉ 1Â77üÄ]<ßþÐc•M/O£‘c7¾Z‚0¡»i‚¡î†­áàߌç~s§_üœ(üt¾@øñB÷Ó£\öoOs¸Ÿî䲿¾Ìb^¿L^_,ò½ß^й¡*ãrA]Ù¥ÌïÇ;«¨×ÿ•$¼ì(òz´¿ÖõÙù +áù½ñaG}óq8Ï@æ»=Ù?zÚ~ŸgÜðú ñøÝ@×S—L_Ýóå¾}îEïÿ‘bŽ>„ów#]ï+.vÆrßuúóçî¯Ï^/\‹w½ö}&¾3TüWÝ{~_a<ôÚ‰Aö—=qßS¸r%–¿y=ÉÔq5ÛíéÙrßG{ýïokô~²¿Îãå‰þõõáÞ• þâHúÛ—®ìùûAlçõ$×ggÊW¿8^½æÁΆÀÎ u¡·ëÂnÖUßm®]s¿½ÊåõÉbæÇçi†ós:ôàÿÖ• ç7O¤ZÍ¡·¼^ÊnzµtØ.CÒ×ZÞØ0§~ôv}x¦ØýÁÉ +·›§ò<«^ýøÛjîZGŒáìïn+÷¿ëœþõ$§Õ1½V,uQÑ´§Ÿ°ã=áÀ-w÷ÇßVù?ØÕzwãFŸ{‡]nŸË»Æîê¤ø-wùhœ¾;æzëd®éÛ+ëØmâ®{<èöáÝ¿í5HæjΧWå^È«ôx¶·ÒåÇïKÅŸN»??T{«Ëdû…¤Ê½+7žO­ +ìl©‘Üz<=Péó`gøêj‘ðª3õ“UÌ×QNß.§Ú_lh|ú “vd*½é—/]Þ<ö1nþïÆ¢ó³œÊ¯Í2|ýcº-×óñ×uÞÔ»¼¸VÆÝ»“"<¹½êÙ•â“kù̹Çþ†S?¹8õñgóÃ}?æÊýPÃß¼™§·’`NV?9RÅ_¿ëxàï‹í[¯[;´½Ö¯Ü÷Ï9+O¾]æÔñ_ÿ{›k×_N©i¸’Z—#»!õFQcHgK£çÓý5â/WJ…Ÿïr?=È统¿úÙ¡Êuw[ê}ïo­r{ùU™óõz;ìþÇ|fû/öÂûÈο^Ìåú->k Ø•i¶ ÛÜ}÷Dn;ÂÛî]6ß2ˆÍ–² W>§ª°¡¶¼Y,œ¸ïïråbŠxñJwä¹›¡íïó åçf‹NÏtª8?ÛxôG£xóbª÷£c ^O¿®7=¾XÀ?º‘áòãÅò°»é7 šÒn46_K®Í¸Y°^¼w.‹¾õ ÄíÕÉwJZ²ngW—ÝI©Þ|-±¢ýF|ÙŽ+ åè}+³.çVåŸÏ­Ì¿’]q»¦zÕóCåìóçiô…WÌׯÝÄcwüÄwÅÓ×Ã…cw|ؽ4»½Ó‘s7×ùÇ·Qì¯O²ü;·ÖwnjìÜÒäß¹³Y||=—>÷ó§ ÿ#nüÓÇxõ}íϼuXqüí"û Ou›Þ|Ìÿp?lÕósU«Ÿ¯bî=eÎ=YË\x„ð³ÐÚáÀl}´œßÃÄýp9ØõÎw¹>v×­~x¤Ò÷ÁþÆÐŽ cîVÔf\Ï«Œ»]T^x5£|ó夊Ý7ãÊOÞŒ,¹x7¼èìµèÒSWbJ/܈,¾z=²ø"úÿå«Q¥.Ä–¼_¾ùbreáÅœÚÀ;j\^}[Ì¿¾‘çþôH…ñÖ9yëDíÿÎÌîßœ™C/xþðãUÜ–7L˯ …-Ohfßo4wñq˜ø¢£{r/ƒ}ò(M|u³Døér ýúy +÷óÃ\Ó« ¥®/®V0÷žÄ9ý_ÎÆcŒü÷7üLç³ÄW׊]_©H¹QÔœ;{}HgÛ¦ÕO¾®_œÍñxöu÷Ó=u^OwVGÝ+¯)¾žVµ÷Z\ÅÙ›Q¥§îD–|{7²ä4úyòVTÉÉ›Q%ǮŖ@ënýÕ䪗’«š/§Te\ͯ1ýô}‘ýÅ·œCé…éÎ[ÞÎåö½æ…ƒ¯V‰ûžº §;ƒ]/œKu½s¶Àíá¹rþÌÝ CûëùÆÖ—ó…öƒpø‡xún˜p +Ù俸‹7n¦ç_É[Ÿx½b½Ûý³ÜÉûkŒÛÿk©sãm[Ö_1G^ð\ÇݔлÍ-~÷w6¹¾8‹táÉj×—çÊ…_o¯~v *º£ª±áfRmÍÍÔÆÀ{mÍâ«óÅìã[É>÷Ô§v4¤ÝΫ­»™T±ãZ\|ö\+ÿ +ÍÓ‰K±ÇÏ%Ö;—PµçBBEíÅ´J߇[+ù7÷ò¹‡¦ë×2¹ïø nFòçïD +—¯ÇÂÚ¨8—‰ä:¯*÷rnuêå’Ú¤k%µMçÒjò/ç5ÒOž'9~÷ÖÙéî[_o¤Ÿ +/åÔמͨÞx6­*îV%’¯¦¦’+ÙM¾èÙ¨×?&®8óv…ýwoW:‚¾ýïî^_|­`kÁõ­÷w¶z>9PÍÞ¹Í]¾’z³d3Ì|N\)ßq=¾|ãå¤ò½7bËÏÞ‰,]'¾ÚëÙžêoÏ’ž¿õq|ùÿü~nüý§D×WGŠâ¯•׿_Í®©¿Z¹ùlZeìÕÊê ÛÍ•Á·[ª};Û+LÏO¹?;V!>¿[,>º[ vÞÏåÿm5µã—q_ÿÍýãbepGÛú€Îö¯G{jV½ø¦rõócÕÜ›‡ÙÆçb^wûn{ëa ëj²øâNQðÖ¦ÄkåÑWkvœJ­:|&±<òvÒÙ_ך^].svªÚó隰Φõy·r×'Ý(kô{ÐVÃü×ÓLúñãxîÙ]¤;/—y>;Xãÿ ½.¬³¶¶ævJmÆ­¼î§Î\êéϱÔãßbœn¾u_yöíÊeû~Ô//©³¬hëø%çÞÎuzòûZþoW ³®äÕl8—Rì^ÅŽ³)óËý;ZË=o/g^½Nco?f¾ýÉÙq/öî㟇{êÓ®6î=Tqâ|\ùÓÉU»Ï$£ï&W=“X±ñ‡´j'ÈÆ¾<[ö5÷J^íÑ*¾?WÚŽtÖ…«QÅ?v„¾AŸ³H×¥ÝÊ«1üãMâ’{oêõdgÕ¦; 5g;"JŽÜ‰©8p'¦²¨#£™ÿýRÿûÕ|°‡n?ž®p~õ÷°e_¿ýbe\ÑàÅÞݸ†X|æ,¨ìæ-Ui?þ\e£Ÿ§ÒØÌUYi?SÍ´ùBeec¯šcŒï¶0öÈÐ…mÿ3}Ñ­·‹¨_&&\,-ßx"«jÇwi•e§r«jOæTm8•VQò}~u&ÂwÛj¹Ïs\ž^)ó~°§á¢ú’‹9 ëÏdÔn<ŸRµá†êËéµ€óœïþï—7'K7^Iª:ôÛ±»‘¥»ïG–ì~YÆþóNöŠ­?éì#+†Ì_Æ«>o©šÔc”j¢j”j¼j¸êô±D¿ÏèóŽjö;STóæñª%B¬ÅbSJ÷?¥US‡ŽWSEWU ì>J5ÄâÕ˜–ªñ}¦ª,‡ÏRM¯UMŸ>G¥sTÍ˾2òËoÞ~²âÚ[Îðä¿C©3oWsg~t}üCEû™´šSgâËΜ‹/ûþbLéÑâË›.§TW_̨ͺšß˜rµ¸¡éLFÍ.<§)u?d֔Ϫ^õâh…ññß"è—/’cï–ÖÜèˆ(¾}/¼­¡zã?_¦,½óÖþË­›õeüöaK£Z‡¬HØ;jYÁÿ{ïUÒæýQ‰JDDQ 0¢(&r¦»éî»› Š$E$IÎ(” *‚Ù1Œ:æPÌÙÑÑ1ÍŒ3ó„™g÷¼uÎîløíûìu½¿ÿ<\MhèæÔ©ª;Ô©ûû±öéû4Ëûð¿Ìó9*8ú4=˜ä$B¬g¢ñ#mµÙ܆Èé!}¤ƒtñcþÉ™"kh‚‰5šé€–Wk8¥œÔwnýhåñDð”|â¤Ò‚ÞŸÚ¬xûºŒü±@ñäM±òÍ·åQ/÷6•Ü©hi½\\ßu¡°n×¥‚:lëw\,j8v-»îÜõÌší×òë±=®;y)§îÜÅœš‹×³j:oæ7Ô·<}šT!¼^UõéEZû_Þ­)yÕQ#ú›ívI˜çZxÎd‰2Mm¶£+š<ÉM·³Eî!«Õ½‹zÍ| +v˜ºG­Ó˜8Ö G†h(‚´&ùÐÂíÒÀjHýóÏšø}Üj]üWÚø' òœ>þc0Íš£@‹è2u·ýÂ4þÝ•‚ºÓåuÍ'Ëêë.”Ö5^(­o¼ZRß|q}C÷Å¢úí +ëžÏ¯?u!·îÈ…ÜÚcgój๹ÿZnÝ¡+9õ—û3j6Ü.oå~~UÊÿô°”úËyÉÏ›Î>Å>øyrU㓜F¯×‚hIÐJdka‹Ç¡1>8·!ø¬ÔI+ oôðÎT ýû¿ÿχ:i ü%\4DÍ5DÚê†ø§h¤Ñt4c^8r+¾c&ý€ýÆG!ۨ廧åÑÏv5ï<_XñBNÍŽËõ;¯æ×cSsúJVuá@esÈ÷Ç«Šnnj±ùõ¥ìÚWsꚯÕG¿è©çÿò¬œûÛãÙ7µÜy¹vSÍÓœZñß„X·†s£ç.ñCÖú#p†’óׯgßà6™âgŒ¿ƒïÕþKkþó¡FZ÷çv«áè;]ü~#ð\œ¶49m|>Â}0UôAXÁ½ú¾8ðÛÛ•aÏNÖF=ëkH¹×Üœz¿¡éìYËâ1 }Ø|i}ôãá³… g.æ~[zìBný£kÙ¯nfÖ*¸V†ß/Òï•ÀIÞ 1²_…4ï낇£(áú}@Õ?_ø¬õùš™ ™ˆÆ¡)hiÞaî¯/úÇ›éko´oÚrfcÃþs…'.ä6?ŸßtüJNË¡«9§/ä5^:“ßxö|^ýæ«¥uyUM›úK+o­oØ1€ó®[Yu{úsjÛû ¤? k=Î +óÝ‹÷™:G®SŸ9c>©>ŒŒArÿqÌ©“ë¯AÆ)|ýÏm‰Úø÷CÈÜœ‡jä{xn(þÐÃVÕDFZ¥¹²]æ‡t©{<<¨Ÿ¾Ë +yóuEß•¼ÚÊkbží¨‡|xÕ£ÎˆË ¯Ä±W})þºî^}cÔ‹¾:x¾ïzní-³?¼—Z=ë¦VµÝÏk{w¸ÇJ甪!V#ÿ?¯½&~ü¹­<íÕøü»Ávk“+£‹¯.þFfï E´AŸÛªCæŸÙð9hêÂhä¸rŸ–ÇÁNþFHxöUUÂíîÆºËÈ8ŒÔYï|þ–ësà>|x%wË“Kù[Ÿ\ÏÙrïfVãÙ˹x|6¿˜×°åJqƒïGA5{™ +00!s뿳 ÿÛãvþw´IçsŸj㡤ýÃðö‰ÆöhÜd9šâ”Œæ*ÛÔ–ì¬ü"#í]ß~ª´aß颯Óçò›/_ÈÛróB~Gÿµœö“óš\Ì­ï¸XT—u«¶ù•õØ¿×5Þ.¨ ½o³O¿à;mòœÿu;­¡9g?õ©Úçßéâßêá#µ‘h„†¦f†ûÉÛ$KìãÇ"­‰h˜æd¨aƒŒt¦£‘f^hê²\ä¸âœ–óa&÷öB6Ž[ê°?ŸPŸ{«ªQùCyЇӕ1O¶ÕaSÛÊìFÀÖ@L¾ÛÖ‹×2ëž>I©ÝƒsÎÔ§µ þ¿ +]/'-òQ¡‘†ÿ—¾AÿÅVÂÏø ˜§Ø*A›Ì‡ND# ç¢Q¦ŽÈÂd2á€ÌŒç!SƒYÈtÈLd¬7Ã÷º³‘™>þ;3g4aN8rÚ©áÖ'ØŠ_ Q‘÷UÄÞÙ^±ÙÁSEõ[°ï{~© ûé…¢mß^Íë|{µpû÷7󶽿Ûýö^vÇÓÛ™[úû³Û ïr¹%̦ñÿÆ>þa¡}§@™kY##MsüÓ0Ü‹àù±ÿT·Ä¶d,¡i‹L†LG&:vÈT9Ú ³Å±ŸGšÃmU›Çwª/*cäÿIãßœËn>³±þ«oJZ®žÏk¾y1·ùÖ¥¼-·nd7_½˜Ó|éRnóÁ«¹õ°==s5»žo¸^TçúBpž:ÓùÝ–?ì&Ø]bÙ‡|þ~(±#:Ÿ¿ŽûÑ\k<…ûÉÒÄ6³G£—"ˉîÈÊF‚,ldÈb‚™[º£ã¼ÑèÉ,²ó­B‹²ž8]f*_žÊ®9UYOâ–Kê]̭ñYCÓµÂ:g6Bî±ÿŽ_p,výzVýýK9õ—®d×ã6Öùý"„.ŒÞ¤n3×ûÖáÿt»ÀN%–A“|?hç .‰F†¡ê#‘…®-²0š‰,G.EíThò‚84Þ>?¢‘åT²O£‘“(4r¬0wG£Fy‘ßÍ”6¢ÅÙ÷ Ü_ +ž¢wBDØãƒ%«nuVlù¦¬þÆÉ–‡ç +¶\»¿ûøæsW²ê^ÞÈnú0Ùôþ^zó‡û™m÷ndo˜Ôç7Ae3/àÕgpþÃHŒ6ìsô8èó`î þÎÿÖ™i[ K½‰ÈB*27žmódfd‡çßBda¼™›,F¦&KIÛFÛ£Ñ6J4~f,šâSŠìÃj,ÜôÚÈé°`ërM˜/úAX¾üAo)Ä 'O6ß½×ô÷ÓÝþÌúýÙ­0ç¾½ŸÕõâNvÇ‹‡[/÷gã\¢´Úõ¾°dâ4ïÿõØl+"ýþÌXÝkà Ï+<çL5ÆâçÆ"C܇ÃðÃdˆ ¡?·m2³˜Ç§3“"4jN0²š¿ +sÉBEeh +׊¦ÐíhvØ õÅ›ÿ:bY¿0›y{-%ùâÖÍ…—jj6^ª¨½Žc¯;¸mG¯g7Ã>®ÿZVËþ¬¦×·²š_ d6Ÿ¿”Ó˜x·µÖý²°Èbبºßþ˜o`ïÁS™j˜#síq¸M£ðx4ÅÏ`m8ø;õÑÈ\ÇÛCÜwz3±Ý´G–fKÑØñ²™&-ME<òÐD×\4vY²r_‡Æ¸§#[i-š´M}aéóaNÇ…)â÷ +þõ¥ì5×¶Vœ¯­þæè†¶;'‹¶>8WÔ}þ|nä ›n–6¯}ÜÚ|ç ofuHÅgJœö -,fþÓ¾\“ÄZ#b雷}™ž5¶ý6È\s<¶ócñˆAƦ þ0U7Ãí‡FêÙ ½qØ6âÇð©ÈÌÛdm‚¬gD¢q³cЄ%9h‚¨ó)Gv‘ûÔŠïë-Ý'Œw}$8á88Võí©¢ø»]›ªÎVÔï;UX7p6¯á!nÛó95'ndÖ¾¼“VõãýôÖ÷OÓ·Þ¼›ÙÖ~£ 6à·7IvŠÔÿkŸ ÆÀÿþó¶d0ÖÁ½¥‡çš)îC ò0Ճ̇Í$}enåŠÇ /…Çá˜9*4f‹mŠYNðA棜‘ù8d>+uÄs. ͉> 1oó#Ç^ÁbÙ€0Çy@püü{LäãÞ ¥WÊjZ/”4`ÛÙtÇÒxŒ6>½“µå»{™íodnýéAFû›Û9¯²`-©Îû™ ¶±^ðOõ›ÆŸìã ý0ÄmÁчþd=ƳöÆípBc]±­X†ÌFbû1ÒÛL<Ïð\m±YŽZЬÌÐèñbd5™AãçD![÷<4CÞf®8¢>'ÿæÐÙUOu cwý6Êå¢0Çóµ –ÿô4=èÅÑâ¢s55›NWÖÝ:_Ô}åbNãñsù ²þ_CÅ'Ÿ€C8¿¸øk(÷íóü€WB¬Ç a©Óú+&æãÿÇv ú6‚•Ô%QxèQÈ÷“Ù°éÈû㉳#ÑTT4Ñ! Mœ"EãÇ.AVØ^ZÛáø¼¹hô¨8¦£qÓ4n–MrN@3DhÓŒìW|£1§ê•þ‚¯…QÎï…e®/ÑG!RüVˆæ¾W´üéÞêØ=áߪ}¼³¹óìúæösšãžôn ùþZ}îýÚΛ7×m~7VÕz­°Þë@Ïö[ý?¶M›´Ç€øæáÈœØ=ó둯ƒ€½4Õ²Â1Èh<Í‘±<¬‘©¡²ç‹l–áøxõ)Í%UïF,Ù%Œ]ö` ñä²cÂäÅ[ÿaáX÷ÖdÁæ×F soê/L96tÉÆ[FÎG„)n÷瀅ÉB<ÿéJqÈ»¯7%Ä6šÆOóEvž«‘-†&GV£é™G4íJ/kÏÙx]gnáå¡3SŽkÎÌ:­5¯ø¦î¼²§úóJêÏ˺:t~êù!Ž….Ç;—ûÂâe{§Ê§f®}ÂdÏû‚§ïCAî÷BPø=xÙG!%ùnS-Ä,Ю8vι]Ý$f$ÈÛßž†j÷ž>üI..Ü7jŸ¬f3yÉÿ0.ÕIŸ]aŽãá‘NÈl¬;2·• É.«Ñ ªM§JÐLEš½Káòžáâ^ÁjÙiÜ?·…y.·……`ÿ•?0šÕ£1SQ†ìëÕÆîÒZ’Ûo¸´ô™‰sÓϣݎ sp|âåû!XúÛÇ$îÓ•ß7ïU~Ãʯþ‰­dó[úàïþÆ›DÅÉ_VÐû~É»ÿáÌõýk€âè¯!܉ŸBøÃoUÇîF)/7úÅî–å¯ö7'>îÚýíþ6‘ıáÑZlõ©Ùʾ‡4{â­RÒõã<µmz¦,"yÚwâ~cî€&ÙÉpœ»9ÄžÕZ°ñ[CÇÁ½^? ´ß_…p¿ß„Ÿ_¥ËÁÑù¦0×ýàîÿwaEÚýÚº¾›9µÍùu¹w+kÏäÊ{gÏ£‚½×MÁCüD‘¾VË?üž¡üån%÷éåzÿ£‚“((ZÝyîäãᎠŽö1R]˜š³³éÛF+ãªøœ#6ÌοûòG>Ñ=?y2{ÇÉÒ{Ì}#+†LŸ#A–þËZпM gák˜-š0GöAíê‹+_˜€ýsû‰Ì—PɯB¬ä/Â*ÑB„ï#l î ”è¦@ù]ü%…0ù!=à;!F|SàD§/IÝ ;Iá+qç{ÙÀß#˜wßçÊ~R¥/„h¿¾ßçKJ[K·ÜŸG÷þäÅ|ý‘“5ݘMUšNµžÏ¼ 8rU©ºy%#äá…rþøw!\ûG7¶fÀ­¸4“=ò„ yr¦\õæf…¸_`g/¢ÿÛvéb»8Lc4>Ô +ŽÃyô<4nª/šéŸ†böj:¬¿¥¿xᅩq½-,ÂóIìuFXâUtÊÜ+¶S×/÷¹ßYÁƒ}r+=úåîÖÀ6±Èß½]'º(ˆÅëÍÅñ+4ÅkÖj‹sŠ ýŽØø]|ø×‹¸ÇÏ2%%ÆxKHšª)Ùõ¥Ô®ß¼å«* å¡éZl̓üÁïʳOb¹Ó/¸+Oc”×û“v~X*ßõ‹;ÕóÊ•Þþƒ;üe(}þS¨ï)ÁÉmÍN½q“—’<ûχ1öÓgÊÑBn£šsÖéan·'ß„À€Ÿ„¿÷B¶×J ö»ô§_òé_>øaÛ཮×h“'š¿p6­JÔ +8ôÖKñøjÎêg=©Oš·†¿=Ò@ÿð!O< ð>;~˜á[zÎÊÿkÁI|V‰:_͑Ԝ˜$ùú7/ú›oYê«wòýó¦’›LdA ¾rDÆh$ÐßÏí°bZ-bwý" +<÷89ðâ½dYÇÇEòøõz©-Æ~ õú‹ýÐ8 {â£5ÈzºÚçq©…†k`¿6r.šì G Ë՜ތr>%Lw}(,õù«(ÿíeýû‹îo7†|8] ÷þ¸÷Ï +™ûï’éË¿DPgÿ¦d¯|ŒSÞ\ êšÃù ¤Öµ›ù:û"oÇ…ˆ•±ö¿K[ûí%ÇÿÕSÒzu¦4e£!ÔAË›ÎÏ¡v¾÷`¾“É›îΓg·ŒäжŽQnìšÄ5÷/êyÀ^º‘Ü¥(ðÔý8þð·J¾ï¹”êùÎj¾1OV¶g¼ob½>Üo3Õ4 k> /͆OAc¦º¢é¾«ÐâU{‡¸}%Lóþ^`p~¹Öè|>œßk—Ü‚ý÷ýÃÑ/"KËÛ/y¹ÊP€4qT°zhtº~X^Ç$¾ñÆ®ü¨ÈOŠÆBŽ,ÑbxL…<\Õ|Þ^qöÁJæÄ+NÖxa6X6Œì?ï{çGöDGgé0a©Ú %Ëo}åÎw¼ö`«OÏa:_»*÷<áØ;¯×*®k';ø³}ñcóðm’ø;!Üc@p^¶á†ñÂåÝ VìÔ\¼b§–stß”£ÃÜóŽ›xíüÙŽùø!öâäÜ­ÞB½ý9Ãÿ°LÒôz–¤ûÓñ!Á= ÷·¥É-F‹;¡™Ö£ÐKK$÷òD¡q«u#×eÏ,ub?¹3—_D)2e_ÿE*;øÙž¿ºËËM’g–SU;&Ñû‹ÉÍS߇ìÿÝ]Vvf½®{¤<,K[–¤%JÐ"u/;_‹ƒßZtþA2uê+m¸>KZ~l¢¸ëã|QÛ»Y>¹GÌ\”9곜Ñ$ì›GM[†Æ;‡ ûÐj5çM÷Ì=vžç„¥žçñã¶ûßOò(Økâ™X¯+ÊÛn°¹w\@y§•¤vßq×}{qï÷޲ÊÓS¨ôΑtR“ —Ö>’ÉÚeŤïÍÄ•x¹z#÷ÅK‘Ôû+©)U!êòÀu&¿ÅRÖtq¶¬ùÂÙ– ötÓ×så[ÎÍ£v¼ue½àè“ßòd_å†ÖqlÞV+º÷ƒ§êÄÝ•Aýya·Î•ݸ–£:w­l×Gw¨« 2jMÅIëõ| +zFxl8m±4¬Xcú" +0°F&Cq>€óPÛYbäœsq¸ûÁÍç{¥?ýO¿ÿkŽôœÀìœ%Ù-¦+ðµL*2WŸ˜JvXa; ÉÄ郦 ¿“;ò˜ç€DËÜÏF“Z!¢—¿Ó&8µf$/–!/üûl7˜‚ÖÑTsÿ<ªòˆ-³ñÀdvýÁÉŠî§>a=wT\c¿#—±iÔ`0å{'Ó]¯\˜Ö{‹éª3ä;~pUõ}Ë(¿¿[øäfYÀžq–çwXÊZûçR'>²AO®•¸\Çýúh£ì7!MúW! û³8ïWå}XXàÒ7ÜIŠ<•+Ôü[Mg¿YÇß|•Ìÿ…“'6¹-óFi"5¥ßØReÇm}d*´`â4´tê\$rqFÁÊ0ð¤lãÈÄl“ÐÕ9ÃÓ+GÒí—Á>_þØÃ`êÈ·Rªï'OéÎ×Kå%]VTYŸ ³÷•öÕÊwÿâ!mz1WÞòƒ½û_ü¤³éuíæT\†“^;BÖùh³ûƒÕ÷ÁCÚ>0OZ}nЏëÍ|ÉÁCrPpõý¶Ðo÷¿Ì÷Û%Ø{\=ß "Ÿ¿JÏ‚¿ÏCÁÏïªà+:#ø\8ñiÁ×oÓ kÿømQØ*€Ðx oO´pêXäâà€|Ä"D‡'k³ 9ú ¡ à‹HC5Á^°™–¾¶té¶qD¤´k’*«ÌœÏ×gSGÈ;î/¢¶>[Âo·frZ,˜Ü 9¶…ªÓ·bBoœ*¦O}§”—ì/KßlLš <þ,\uûV>ìƒ ¼z5Ùÿ^&ëxº)Þ=žY[c,/?i+¹(H©Ÿ² .ò>!,öÈÓjÑØí¼ƒö\S’:Ü‚NkÐÀo{² æU¾k"¸ÁJÛdÌTž +õ'ªÎG"¨=àú‹UßÜ\®8òX¥:ü ”ÛñÞ‡i}±DÞþíb¶ë£;ìùT\½Ÿ(Ý÷7i× Gjóñ©òš¯§ÉÿâpñwÊÿ6Ž©¾BE¯„ÜoþÞû„¹þ›Nð Ë×Z¶LŒ<%*$R¥hH“ꇻû*ÐWäë¥BžNÞÈiº=ò\â6È¢áãÕ=òžh~>W’Ñd"_·e„<¹ÊHÂG¨9Í_ˆ&Ú¢%³æ#?<ïè¨ì¡PËZzªäRÐb§jNͤû^{+¾º§àÝç¹O~ïc³ó7UsÔŽÉmµäÒjFpY–LF+¶·­Ôúî±0¥»Þ»R^+.Ý‹§Žþ$•îúÅUÖóÃ2Yï'æè÷ wåùjþüóÙ®_]ä‰ ™µE†Tî¶ÑÒ¶‡Ì©ïUOï”D}wt ÷݃<ÉiA,úFp5¼›îŸ}ÄÜE…|˜Õꢔöá‡OYʼnI"åjuiXº–<8ESB¯TwvtÆóo&Z†ã:iãpyÏwÎ0oD\hf€n1ºJ30©ÜTYùÍ\¾kÀ‹îìw’wÝYÊn{æûî¨d}o\é’ÖLvãH¶°{,ÔzA}<·a› èó„]:•÷¨·uõãí¡×Îç+v¼±å'§3NM¡¶pf޽âeÏË÷üäIxãOW˜LgV™R9Í#¥™í#$¥ûÇŠ«¯N§î0ñLQ÷ âÔ|•éb:IÝO®&Oj0–®©2t^&B㇘ 8oši<¹.rC®Ž‹‘¿¯˜è‹åÁj”*ZƒpqV¯®ˆˆÑ¢q[ÿWlº[ª„Ô s=wýTG”ûŸRÕçfÈÓÛͨºË³¥=ïè¢}ãÕ%QƨSx¬*޼Ux¦¢·ÿèבª9?“Éï²¢Ó6›°ëû&€v uô}€øÈ_ÜüìpðW·€¾OKeeûÆK ÷XÉ2ZGÈã‹õ _|?&Q ¨ÍÇcÝŒ.=2‰Z[fãž*Þ?êJe+Öiûâ8ÌG¬BrE²“Û5šnyèȶ>uÝlÐ3"zBžÐòÝï= ¶‹iXDmìLõ`¾z.‡¾eξ +a/< ½f°Ot¤ +vZÉb +tÄt´º§ƒ<œÄH :÷Q¹Cé„ÍÃéÌîQ EGf3QØvÄ©ÓkjŒðXÃàGå…P·Âô~ðeKL¦b²u¨„B}&·ûóý8l0cÒêmdåáiTûÍELÇSf÷+_vÏK1½ó;ÑÛÞ÷ZÄ|õFuòŽ'‹åµ§ì¤}ï rYØóÍœ|(Ûöq‰´ö²´ëçEpþtjÑ0y|¦Svp²¼çƒ3µý£ èfRåû'Q¥_M”×]%ízã(Ùýë2Yr³±§(Í< Ù™ŽGf¢E³æ 777äí'Bn^Ø·áøØ'€C>"yyˆ‘—IÂâ5ä©5Æ =öj´Ak´þX:L’bÛCE¨~\ã¹ù\ç7ºë©3hvS«rõ˜²Ø]ODª½ +»li —Ó< +4±øÝ÷åŠ#TüágJfï÷bªçwjç'O¨ £[î.„kÈçUYÐeÛmd[®Ú3ûÞð'^„ËöþÍSZqÆV^Ñ?]ÒùÖ! ó£¬x÷XIx¦–„_­î#W“„¦hR«6JWfh/œí€fŽ™„ÍsAžËü°Ý”!`D‚6¼rý.[UûUEÓÍ¥À]:Ð+”ÊQ€˜A„‡™Scµþ ûÂoÜ6 êH±ÃdÕ™3mVòö'‹è=}©¾<èªoìØu-æ ~€^<›\nLjò²šG‘ø¦öÒl¢+Xvx +Uj]sbSÜ7Ž.Ý7A¶ýÕRêÀ÷"æÀ µí“+µþ  èeH4ÄÌ +uipš&]ªÜÛçUz ©' NÓ=ФWä e³¶Z²¥‡m©Æûóa|æ/Ž+Æ0 åÃèÕ¥†tlŽ.“1´#Ù½6ò-’䪯íä[o,„ÚJìÿ‚TGn‡ó‡©OÄó笠| oº>—ž_¾éë)P›õk̹oä}?;˲ÚÍe‰5ÃåùÝ£e=¿8Ézß»@¼ƒÇ¦‹lç'Г/OЂ5 ±2\è´4÷Ï•vÜw ³»F§jº,öE‹§/Dn‹¼ð¸”"‘ŒF2e˜º<ç–«òôéUéºÒå šÀ $/áÉZtj­)Wv|:hú€®k`r™ryêРåi: +.\]µrb×÷ذ9µ#©ªƒSå{?z“Úåco”ò¿ã¼ãÞYr•\kLu¾_*ï~·Œ®¿j/ßxp"Ýf!+94^žÒdâì,B3ì‘Ç?O`}Édø+ö=²Àu¢ùQ´ƒht21ÉC@3•ŒKl7ÙšvLÏ·žTWÿ>¹p8·*]/l²¢kOÌd7ŸA×áÿ×ûƒ»lÇw˸ÜfKf]•)W´o°6èôjS6½Áü$›ÓdA4uÖá|0ÇâÛDzÙMDK2­vŸ®CÇè½_Û’¯I›¨åC@k^uø Q%[‘® uÒ ·Çm<2…/ÿf½ª@?€ +WÉ‚Œg*._Ën·„ù"ëûÁU¶÷½'µã ÕóÁ]Þñt ·~ß$Ðv¦û…+h¬öÝ4¨aMõ¾òäzžû³žÉÙcÏUÌ×Ï8ÙŽ÷Î̦¯§îø yÓ¥¹ÔþwþÔÞ½åõ׿PY°®&Om0¡Ë±Íì|ºbªõîB¨=ÐŽ”)ñ\ Õ Öm6µy׋%tÝ•¹Ôò‚¡>ž<΃<Ÿ/¸ÄùõÝãA›’+苯¥—Rk +×X“9T´VS§ÌºuÀX=  ¤(ïÊU}3´u@ï“h\çvíQ¢¥}…¬åâ\Y×ãÅx>:2 Çf³ÍÐmý‹ømw}T½÷e\÷MOfÛmwfç÷^ô¾ïDÜñoƒø;wÓŸ]+ ¼¹êïCΟNåŽöÕ…¨È£§C^àºy= +Ü×Ü¡'ŒòâÃUª7Ö‡¼8_µr U¢Üw—…º|à1Èë¾™!Ç9ˆ|ËuY×÷Käå''KW uu– ÅÓ oœ€¦ñ›« õý€G¬ŠW—„&júŠÃ°Ý ClXª6hO…7Ÿó j9ïF´Ó¢ ô@+ +¸% ¡Ï¦V™Ò+“†€ßV}u+0ôÐõh®úØ,Ð¥M%ªùì\æÀ)sð“L²ý“#StÀ4ì™rSÖ|3‹Mª2 PF¨A¬Çï±? yµ,4N´ý©5ë @#Z[9\—mf¾‹m]òFcô&ÓšGÊ—'kùûc(çè$ÆOÀ±‚µG +´„°dœ¶ŒŽ—œ?Œ_WjºŒÐ.à ‚7_º{2èÕaæ<¨‘µ}„Íj¶ “J‡I‚b CZK®0Ï‚WªüN+ð£ˆ$<¢CWk¿ç)f|Nµ0±ÀŸ‡•ŽÍÐu2 ­Žc5yxº6³¶ÂˆYž>DÆE"´ò³j̹ÒípÞ¾ tÙm÷½˜Ž[N\ÍÑÙDónÓWvÀìvŸr×=yèÉsk#N}“´g hCÖž sTÞ|Î|9òi(åY<ÔéA:®Lp¶e+5˜äì·Žf*†ÁZÞd9‚Ÿ±¤ÂálžKÙ-–À#í"ŦvD—ÇÐlè*-¢WUyx¦²bŸèr³ŠŠ×:¶ùòB¾bÏ4Ð7äfë+Ö^7ð5è¶kŽl×mWˆÍ@3”p³s-AS±ÿ‘"ðø•Š}Xºåê˜ÃÀ& ðµn*h¦2i5¦Ll±ž<|­°2¸¤ÂØ„1óRÂ…ªQ+Sµ K¨°ÃšYSl( Æñ ¶w ýËà\øòä*ÐzWæ÷ÚÞLAóhà>¦+´ç- •¬.öÀÛbÖlƤԘ†An»•²d¯-Ñ“‚uÎÚ#3ù®åŽ{ÅÖ»l݉90.yü€{æàÏ™¦ó Ø­7œ!Tô<Q]—q™-ø:Õ˜SFÞöh!µó'Мµ?]H¯ïÇg·Z¹y»yàùÄ"&ºHZ™« ˆS§"Sµ©¸ÉZÞbç<®ÈaÒ<´Ðn>rw]ÎP5IHŒ\mÌlØ3Iª0xÐR%áäRcef°ûŒ€g.)è>>èSaû +ûQÀç¶×qÇ´˜‰mJÈÔ—·ßt$ú?§Þ†0Ç~TP­/9Ƭ*3ÄsCÝç^þ4‚1Hw?s•מ™vÒÓS޼¼ÄxW¤’+M;E8NÀd Q½ãJ‰d|¨:hyèø }nUвV‹hÊc{ȵ^\¬j;ëÂoþz&Œk&2Q ôÁØÆ+ ÙökË@÷‹Ëª4#±VÓÅtÇõÅÀaPåV[* ·Ž€ªìÀtÐ:¤[..Tî¼+¥{¾ódÖ”ÊCc4 ç¼xËxŦÞiÀd{Þú0½o}‰¯ï~âL´˜ŠwM`£ŠuÙèl] +Ï?)îЕæ*ŽÛÑ­óÕý 5è3XKm"vÇKOÂ<Åö†ÍlÅfwX’x½òä nË3'¾ã…§ªã‰Ÿªã³õÖR`!*R+L¹‚α e:z°Ÿô™Ün+sl<2•­¿6ŸoéÆw½ðQuÝwß–*¶ÝñýD<—g(ò[ƨrªF)ªÏa;®¹ðmý®xl:˜ Ç6LñöqØ×M!zzq¥†ÀĤÛ-a{Þûr½oýaÝÖIAš)îKü~¶ÓëwM„õ&»oŒ[bsX{à +¶Yƒæ3øÐc +ûƱëºFÉ#×icûŒá ËGw~ïÌ6Ü[ˆÇ5ä~|z»%Ñ®ë~à*ßzÛr^`fÁºY‡+êc^Õvß´ÞØÎ§.lë­¥À>àWd ®°f˜­7—É»ï/PX!ö®sÉ.¦íéRÕÖ‡ÞLçK7üzWÐ}\WaÎ…­Ñ‚ykNÊ͇g3ÎÊž;’ ž»Œ¢ý¶;Ýr}!0[¹êƒv uÇî¶!Ü«’¯¦(º¿óå{_J˜m?ºS/–rÅû'’õã’^¢o×÷\xøV„ò«ÇAôæó3È}Œ„ªáÔªõúëà¸ëbn…è rkëLxüþDG˜1xÜIÙåê~^2¢w lÐ/T•žX´}·¶ÌH±jãpEF³Ûvo™²ãŽ[}Ù^™¾Ùœh!ƒ½ë5y†À8ã>³³¨F—í{!Q}N4Õò¶ZýÁ΂8ŠV®Áö0Vƒ[š¢-æÐ^UVûUJµ9h f5Z,øZÂÜÀþtñ /­Øˆ¯¹ì ÜrÏ#¨õŽ¢¹ß‰°¼W¦×Rm<<_A‰ÀØHÑ!l|^ªÔA-nvsïnï}‰âì@Tàékñ ÅííìƒD~ô wW¿‡jÇ­Åö{þTç•ED‹rÊŽ'Ëp=4!Q®É5¤Bql…ã_Â^Äyý hÓ« +»&€¯½@fÃÁItìF}YX²ä=À/Qä÷SäîG—%»&C¬šE$ŽØtp*\C[2.N¸|0þ•[=öV–™ñ¯œ‹P  CÔðÀ¼VöËLõa’÷ð‰›ŒAã_omà*ÛðõÚòØWYz|è¨Ã=$ðc¥Î†¬ÖR& #œ 'æ©Úïyu ˆ@stžwDuc{VÍžp2Û-A;˜n{¾„®¾<›)>4‰©<ƒsª¶ìƃS¨íœTÇû#ÃNJRè_!ÝýÑ•®:5ƒÙtq&»®ØX`ÎÁ}:6¯Ý +Öõ€úwÀî`»ž»÷ÄÛÝyºc»*åp¬öoNµ*߉Œ×¿H¸Y«Ë€•ëï„a•¡óN™˜;Œ¯À~4VA—›°³°ýê¼ã©è½' >¶ç¥¼Ç1ÀÎZQ + KÒ¶¬œ‹Ñ³Ñê Ç­Š/4TEåêã„hʆ&ksDÓ6WŸh*oè™Àƒ>70 ’‹‡‡83[ïûc…°WnaÁŽ AIå#‚ã² ©¢ØÐ5á-nEéŽITïsÏÀcW—_;›ÅzÎÀ˜ñq“ ANSÓHà-î{'6ØmO=ù¾Ç’ íe\çKwûhÂÎÂ>›p†2šG;K® +'ì,åŸØYò¾\!?„û["?ŠÄJƒì¬" + l›Äl`S6<Ñ¥íúÏ0öþ`g)[ºñ[Ÿº‘qŒç¸”U—㱬yxX ë*G@<­Èï çÄ-ÏÖá"2†_^ÕrÏïxîÜz9¼>F]Ɔ«~ 0ÃKwNCt+ú¦qµ'ìíwÜAW—ëzî LÛãeØçÝyªú?èÎ[þ›î|÷wªÃOÃÂ.žÉQîx f+öN!ë†Ày(Ü1–Nª6&늇§3 gçÁZ¸4b­&hó8.¿®êz †>‡ýVs^1pp‰¨ŒT—)ÃI¬G´¹W¬Ö.áÕ:¼ûÃaƒ¯Ï|}f§hVÃøfãñXM)1RmèžÔÞï²åŽˆäM]wþMwžþCw~×éÕèºóÇ`ïÅsø4`h*3·ŒVäv•/Oц5 ùÊuC¸µ•Æàã›%¢BÕÄt°š8j»løê› ÎåÓ;Fÿ¶¾N[Æ«I¥ +„lj&á°®)FXìÉEFÊœ&+UrÕ ¯ æü†ƒS™®ÇnÀ%‚õEŽ{€-œs±¯ù¹{v–ŒSªÉ™cgƒ5"ð‰bQ ¹K±‰Tÿ¤ŠHªZž®£ŠJÕQD¬ÂG¦  ,n§ή¥Ìm²ûÉÆ§é€¿'¼ |m¹Æ3Àø!úôk7Cܪı>¶S•uÇ›öÙ)ÊöN%̶¢–±Ìö;°÷ÖJA‹›Kª4fð{ߌk»ã 1)¬*¢rt•1Ùz°o„°± +»ÆÁz aÿfwY1k7 £Ââ5 Ë ûLâ#ÿ`gm½ãÂwÝõ‚µ”?ØYàok7›ÀxæÓËMWì,à%Cnöïì¬üAvV Î÷ƒc4Á¿&UŽàÓ´a¿rM…1Ä@`sUùMcÏl]E`æf lG‚ïàÃÒ†ö~}Pò&3x=è­ÿùõÇ+‹¶ŽÍmÂìƒX£îÜBUû9× ’]Sf û ¼g‚]¿o³ýßó½td l<òzì;a €iþÆ^±aû¤Aîz‚&°?ëpÏ˟⑘P÷—)„‹TƒÜÖ³E2%&6‡m[u~6Ä’||‰A€$ùû1ÈO$ELàr Uz™Y`á–qÀA‡¼œ°MÁï”ìµ…µ‚-Ù34ìaOä¬Ôîï½¹š3s7ì,ì•ä‚Ô%g8Ä; q°O„åÿ~û]µ¶ÌD™”?<(&U/8ªÀ|ø*m6<^K‡ý'°»°MæK»'jdí¸f­K¹ÖkK€ïªH©5 Ìé´FßqÓâ|¸Ï1hs>ᆶñLÇ€3øÂH(ÁqGî–Ñ\ +n#p9ºnáx«ß%0«n´*:G/8µÖ"(çõ{lU=·ä»î);žIhÐNn¹í@ØY„ß¾kÕr°³ØæŽ„•Õ ì, _˜‹Êxu.g»hu6õ†„¥~2°³òÙYª?³³âÿ`g% a‚¢4(ç–J·CÌ ìøœ-V ï ü ˆI€¦J.Áó³ÖØ +äõ8ïà—ãׯԠèp5àRAÌ@¸?ðúòÃÓȘ8.Ô9Þ1A‰¯¥"6GðÉ¢Öæ·"£É‚®¿0—í{í+ßúxð©àå°¿œÆÈÕHž»v(¦áç­@Rçä™CàoD +ÉCÕùu¦°Žþò7x_XÃî4ŽãŸÌF ®â«©À«6·¯‡ùzËÄÛlT2¶ÇÕÊ;måKâJì·y°'ë±ÍŹ ŸZE˜°ßŠÚöÄ™ßþÔ°³@#=&UGöo쬔Ï쬵:„µg†¢ê„½2±d¸L¢ç¼m¸WªJ¯©¬Ü5=¨°cBPb>á[“|<½~$Ñco¹âHxØ—†hÙ¯€°ÉkGòë6ãØ«oøA¶åêb~ë€;Óvu)Ý|v>0àÉZìÏ!¹ÌVkhWóÍÐ’‡}ÊÒCÓKªÜ~OÄ×}3/(¹È„ ‹Ñ \™®‹óµÑ\ӵŃq8—äK²³Âκ·”ßöÊWÑû4ö C~@X«rõéȬ!Òå)ZTTþÐ?ØY°¾ÌÂWZß1QY±×N™·Ù’ø÷¼knóîiŠš“öªÒÓ]©X•¥{Å`ŽÃº‰*·Ýš­?:gÏqÒžpcŠ[­áoÁw(€ÇUqx–jÃþ©ÊìÍ`‹ðúÐ(Màoçžk>áÀ¶ßw‚õ5rÏX‚¹UØöÖT&V™†sLaÝæµYó¥6pÿ‚ÜeßC +®)[ÜiÍF§ëÈØuyP¸:øNÿ‚¦Z…©¯‹¤¡jlØ:mUl‰!ä·ªôÍ#y6™Û´š²ë¾?ÑA†{+2‡‚ÍçJ ÁRªx ‰,TM{~°ïX +ü˜*«m ñ‘دÎ.¬yâ¼ ö§Ázé ¿¤Ç†Ù| ´õ çbjÍ*­~$áƒe·Xß *n!öAY~h¦çªÀÀõÍA¦p…ñ ‡ +ûPˆS«Ûû âÂDŽ%À>@¬ ûN€ ã j,€ ×u‡°u‡gñõB¬÷U€\àü°ÕGg’± l™ â‹&ñ­7`|r]¯½à~²ëžoHÏmžÃö¸tbà'FªtáÖ±üš’apOú„‰ÏÔ…ûRLÍÉÙtÓµùÀÎRõ=bäÛž;;‹Ý´g +Ô|pE;ÇsÙ£AËš!kΧ¦v°B`=« Ï’.Ü&Ü^`g ²³øú¯ç±Íç€ ë­Øç«²›­H¬‰í>0[ fOØóU¸Ý%ãø¢Îq„5_Ô3QY{|×xváÚÂ=—Äb£Àlœï´×–kïwæ;n»ÓýKè-ø½*Ožp>€÷¤Üxt†*­É‚‰ŒÕâ+÷Lƒ5 åî»4ÄEdm£û‰Õza>á;á‹äMç[®.å.:Bœ$–† :0I“ Iц5åêK—_£qaÀ౤(ß7 îgÆ{\žžBâ}ˆÁÅ&³WaMDQÔ5˜ßà¿Ylã€-×òQbóG³šÔ¹T_œGxAi優J-A̸o 嫱߯9Äû„cqQQ‡5‹¯=É€‡›†Û‰Çég¦»·éàtXÓPx¨Td;o»pAqšr)àþaÔäÔŒ"Œ/à¼A[ OÖþÄÎbkOÏ%y[^óh¾êèlˆÇåmwBþ.LÓ–ãŸMi1Vš¢ä3‹ç}xåþ`g¶¶sªéa¬+ ¶Û ¾oç$uùÎÉ\ÕA;¶ùŒc ¹ÚÓ$f!kVå½Sà=®{üÿ  ¶ ¸Sx޲8—ï¼³L±÷Mï}éKµ÷;Â;¸ç®,;:ƒì›LÍÆï½+ 9zeeä‘ã«Âö]Ž Ü1ÀtßrÁù3œ3Ø"eV›îKÜ|í×wM„½nÜò졊⽓HÎÜ|ÆQ‘Vc& \©Îà˜š0¬óº­»Åâñc\ÎF©ËåA86”!™41‘iC >†v1—æÁºÎ'‡È(•ayâÿ¥Xße|+Ø¿D˜DåÇgÐ ×çs˜r¤Îç²°Å.ÑÖ\OEå×3ÙŠ¯¦ÁZ>øh6*K‡R­ÖŽ2ÜCWï›Lø(ä^/0©ZÇg Ö¶¡–Œ¯:m÷¬óÖ0a\”ª,Ü58Ԫܭְÿ†«;3[’yÔ3IUö•Œ{Ò×°Þ<®ü–1°vÍwÝóÁö{—kÀG¥ë°¡ ZŠäê°¯‡ÝýB¤Ú÷P¡ØþPÌ6,"ÌXC ÜéóضëK¸ÖëK•ëwN&Ls`Þâ˜Ä¬åû¦ÀþB°ŠÜFK``±õ'æÒÛŸ¸RÍ—çÁý]¸ßLjc +õˆO*Û3ì<ÄRŠÔB#§dÖR´Y“{BؾÓÍgæQõÇfÂõÎ:äó2E¬:ð+SûbóŠÛ`Ëd ‚vãø‘ø<ïÙŠ=¶,ŽÏqÞ2â )‡íŽC™åCà¼aï»ã©0iX·Þrk1[wv.Ìð_ìÆnvë#Øë©Üóa«ÏÙ[±Ù bVx_bcp_ÂÞKà=Á¾â÷`í +òþ¶+Î`Sɽé È{ÁÇÂû3ñZ°'ÖÂSįђIƒ™ˆé #©m‚{cLäJMoÓ*¿ ¸Çœ²Édgþõ EÙî)°† +÷ !fT$ä&öÑ#Á¹©Š{'+jO͇õE1øü”%§p©5#`O›¥«HŽ%~°_™­£ÀO*€eŸ©ë—|ÍÉyÀ<"ü `m.½q$äÙä>rî_`/¯j¿Ä#„[ Ìö¢m68G!|¸w¶œ°xÚ®9»^Cò=ÈUñ¸…tû“¥ô–;‹Àæ)Êp,\%ðµ›ØÑ•;ïÈ€÷ê ë+©Ô˜ì=µFØTºÇ–+Æq-ðág°OÀ]î¼³DÞv}]wf¹§“‚}Œ<ÇùÆ-–ä> ¬GÀÞáŒz‹Á¹e ì# Ú.“؉/é™@…¥jÉUk4 —nÄÀ„cÓ7c?SgÎãø“‡ýV¥;'*óê,ɽ²º#³ÙökK¹º³pŸž ËÔs+ըؗn³¦Z.;Àû“û5™x<ä´YÂ㊺­éÍ{l©ö«ŽTóÅùTãy{¨Eec2t€ÉƦê(Öo›Høp°‡$oçx~%ö¡±yzÊÔs`*€¥ãQ®|¶¡{§Á˜Ä9—>Ü{û¼)Ū4=vM‰¡"¹Ü„ÏïÂ6ªm4YçÃ9É7ðëà_Zì+E2 +A ¹ ä»pÝ!N‚û­³\\šÛÀ˜Æ×L‘ß>öòðqºJðçµÇæA¼<-ÈaÏ–²¨ÛönÀ¼‚ó€ûÅŠ”F3ÈÁ~CI¸ék7“=GÀ‚OÙdŠý˜)ñóÀ{Å6…K«5¦3á Ã~ŬÂìVBìœ[X£]WjBXMÄ=›p^aÍÇ¡0ǹÍGí°O±#œ+`ÅÂ:;žcŠd|íòñ8Ãù ÄE0q4—©=9úbB¦åä|¾¿n'á‰?øÃ°Îëä)%Fä^)މ€Ï¦ØöÀêè˜oÃ^Úb|Ý6ôMá•Á}ºô¦'»æ6¹`6šFöoÜ=ö»7„°_æ‰ðµ{¥ÊiCüRù;ÂÇmæ6lOÆiézÓñitùÑ)lJ­)Äs¤m°ï¥õº#Ì'ÂØZ¾J 8áÒÞo—Ê¿z)âz_ús=Ï|éÊ=“™åÉÚPñÀéÁ~` +™ÀŒ/1$çMæõ‘™Â—ãËñåør|9¾_Ž/Ç—ãËñåør|9¾_Ž/Ç—ãËñåør|9¾_Ž/Ç—ãËñåør|9¾_Ž/Ç—ãËñåør|9¾_Ž/ÇÿÏÇĉîqán!‰!º¬—îDgïyAøiȚĈ]~*h¦sB¢[TXbT|\HBªµ#yŽõ÷£¼Ý¬­mýBR#‚fÙM±^dmëì={V~þíëéð·³f̱·ž)‰±¶|ckü{kqBÔò¨8ü¤,,$&âóß.‚Oº9•p*. k׬„$â—Å}~Ö%¿ð?>oKÅÅ…ÄF„[“§­ñóÖó¦̲v6ÐeÍ&ÃgçݵðÍlëYäƒM…Ÿ|ðw+ñsÉÖ³gYû[+T³¬Ãñ Y©®Ý‚Ùs¬É§XøiÖ‚ù3æ/|ÂïÏO|þê÷o/ù/O|~IÜ8øfõç‹îáøù{Ò¾?ºÀv +>9ÖÓ@w¦[DRTX„«?çkÍâŽQXÛ‘+KßüégÛϘ;ËÁÁZe=ÿ<´vÅ?ûøíç—}þ²ÀÚŸÄìäÒÙ[“7Àç:‘œ(ŒGkûÙóç/ÀƒÈ[×Ë›Aî®þÈÛŸAþ²p5 ³\þ|¨º˜ +Q„©ù‹#Õ¼|yäá&E>¾ +$•¯P“EdkCi¥<2S[™¡- OÒ’(W«»;‹Ñ²Å^ÈÛƒC":ZM¸Z]$V÷ða‘›sòò ]“¨V¨K#Öh„¬Ò bótå+‹tÅiZ¾Ò ä/E 5% KÔ”G ‘§hú‘ÿí Âï!Cî˼ñW) +à–«C©l‹÷ó &ÀE©Ñ‘©Ú Ÿ¢J+2I9-c |Êk‰4pL®”Y“rš5eFPÒ +%ɰÝJ@UÍc¡¼J0éÐÕš +(É™•˜t]£%e•gA)(”­ñ±™ºDöU¬LÓQ¬Y”js°"r(ð÷Pö´"e(¹F;0®ÐP•€ÿÿÚÆ ƒÂ¬ÊÔ#r iÚ2(c¦Õ(E˜:H œ¾Z Ê¡T™‹HÐyn)Å!*$FƒKØd%A•\n +’DB+µÔÆ“¬CG%k+×µŒÂ××RRY£•ug*ªŽÛ«²*,ào8ØFz )ƒç›*ISʯÒóѸ/5)üò+ÕýE<ù²ƒØœÀ8 "S‘Œç|˜š„ +D ñ +ç±lxÖ(ùab‹õAöÞGB…«0ËÕˆt3n”IsI5&Üò<™*AþHa@Ù³":W¤(Hÿ¬„òÀÁrn¸Ä:T±²PO®\¥!Sb;¯©X™§§LÙbÛ$U”áçèˆíç`©0¶ÉØfByŒ+R +‹ûŠN +¥î0fTÉFP.KJž¡œ%Ûx('"%±k‹ÈxÃvY•Tf¢L,1R$䀃÷"R\Ðçé¤\•”–oØ>QUØ;æš²hÛÕ,)ì±!%i…c•Ù­£AÞ'0o‡ ù_ ¥°:[ŸÏi åm¤Äº¸k¼Ê¡%«Ö‚_W5‚HƒdxL–.AÕyãÖÿÃÚ{€EµlÛÂK0çÆ-æœsº{¥€ DAE%ç 9Ó49# æ€YQErÎA‚ ˜wpŸsÖ_³pŸ{Þ½÷¿ïÜï{ðõºÙÒkÕ¬1ÇœU5Æ<8Ç:…+ +mÜ'Áü)YÀUƒ÷JJÐXB<Â!„Ÿ ‰AµÇë@ŠâJSMÐÔ6$@6ŠO£Xƒåy\çÁ¿ ’åpÌ•¶†ã†®ã….(îàˆÄ¢oæbƒûä,;&σ#þèo)Â\‚cU¬•÷D¬ÇÇìAî÷¬÷DœÓm¥Š0W¨SèÞŸ¶ Ç1¦"¬©‰¿cXа¿oôÿÀÑt¸ ¹Î£%ÃÀÖ>ŽòÂ ç± iKζ RN ÃG"\ˆŽËã’ ÅÒO s ’ ðÀ\G‚â×Êg<–p’Τ/øOãÖÄG.Ž N]rWŒßíeBŸ;˱Ԝé¹ ÂR|ÍI#àu ûñk£Gæ Az>"‡å NÒÆÖ#Hñ‘!)pt-—áè8– 8yó@‘¥Ë8|4_w¤怀‘Q.wFœÐ5v.Žg£A¯ÃØâß½ U.2&£ìbfác‡(·ƒ1IJ-NˆÇÙ†+`(¯É¢óþÓ°äŠ À(œÏ ˜£ˆ€±0‡œ¢gácß ye{iªØ#eÈ#Y Ž ã£“h¾Â¼iK8*ó$_„XB"áxŸXš$±Q‚Ä>.é‹FBlüóX¬ÿÍå Õ ²WtÀå Å r#pô¾fâcœpüÑ-mmÅG6Q¬\È•ƒÌËŒÂrt/P|MìÙYúŒçlÃáseȾÀLà€{¬•û8Òˆcà ŠÙóAS±L#1x¥*†¯y9àV¨&ø°å­IŸÀñøƒÊYÀù7€dŒÈÖá<‹ò ‹ò à0æ(–±-ŠS„>>Žx ÎCˆC`ùÍ“¨n°°‹¹ÊÌÏç±” È3¡ù 1 8„)ÿü`¾Àœ|f½S`‰,ô~o>™ Áú¤ÔÉà›Ë ƒìÌwø;0w@¤yhk8ÏD·™Í˜gX¾ýM°à›¡šÙè¤<ÔŒ4Êw$X¹Àq~Œ¡ñ³ –YãZ{GóîŸÐÖw*¶F@9–9Žj”“( 4ŽØŽ$Q>+/ˆOælÐd°«€û Çåõù¨V!‡A/ x!¼7Êêö“r†ÌQT‡œI=°Â}àg0γ '#.úŠÝ##A®êu—Ïȃ È’æv#aòÏÇs a,ô-;Q½7ç?œç½&€Mô€#CÝrõ/ÀÑ0VüEÔ‹-XZ dE fD5.È>PWÛuè[x‚¿j“‘›ÁÊæ1Ôqz< ¶N š£B®¦Ï]š¹ˆ4CdY€·B<º¥*Ý•å[è=I\æüybT¯Y#>/ÀûAÖá!ärŒ¡ '²»¸^÷™ +ò¸Ø¾Àÿêr\ÿº$Ìy$Î =C‘}ˆ‚Ø.bHÊÑ)|æË¾é‹ÈäÊ=ØnéBÀègbÉ Ÿ¸Bÿ¬e”ôÍ2£ý™ùn?¶”Œ{» {±dY ŸñkÁVGpÜqX!_¥bÞnc 73ޱ3RÇFƒ +endstream endobj 131 0 obj <>stream +Ô9[¶ƒLmÞ‹e\ÁÖË9yí”4Äü¬¤eå;˜Äe6¹î›X©)C2‰(¯¸ÅÏ…ºËL&ä%°]ñÌPÂü=„y«˜'kéèâ­šº|z:Zü¡zÅÌ)lýê~,[âÂhàB¨9Qýrkxn¢¸‡>ô+߉,ª[@ +úvÀ{‡~šÚ„šd¤@öˆ±‰ÄÜšµ +š ¸ |z 1 Òñ¬uðd°[çѦrÌqç1ì¿ÉB3çÑ› ) 2•YO]ëÔÞk’ÙïÕAf÷/ +ÆÜe4e‚8ˆéÙáPÓ±gC§BÞ;Æ€Ž"Ôç°6%Bqˆe³@ÊðÓ#uȾbùOèÀýrOÄ’ž?åþ& +íP]‡øà-–Ϊ×'@ï ËFºÅÏc}s– Úy®›Ñø É^MÃ=¨ùk¯¯„šž Ê[ ˜HÆo£Ã^®£ƒ€ûCL{N&Qý@³…¥"½Ò?aŽže䑼Œy½¬lhÿ;Ë(«à‰Ó w-<…jo÷ܬk®äi\K¢œÒi`±F…¢ºålk㋬åÁ– +¬«DñÕû…I Àž8àX€œ:ž×(¯Ñ‘(wžÚJG`yAÌoíãaÌÀzì/ù—?î7ÌìÜýW½œG‚î)ÔëØÎÂÍyKû±Xºá-þ`½Ð3YIäž2ÕÁ‹@Î8(HÀã~ X!E½ØD?Z VŒ`%ë6T+<"ØQI {Q½¾…9: ÷÷…§ÿY¯3awׂ­ô߀§Ã\4T¯Ã|q’øx} #ĉ‘[ÆB‘kÌ\\¯› z¬(ÐØâ¾³Oöb\/Ãsçœ&²W–cI%è3aŠœ%lj•ª0§^Ÿ½Ù" ³º5øIov`Šãèž›!.nŽxŽÐJž‘’[Eµ?Â0˜›ðÀVêuàTP?BÀ²L ‘ý è'¡x`ƒ®\[!r—Íâz=×ë 3 ï×ëÐC„zê<ÀP„Ã`½HÉ^lË4è­CŸ×jˆ—âZdü ×à?—›%„…dRåN°³#SZ÷!N2dC8ÌSܳ=é:N 9‚m(„ÿbC6ìŒëå_ ¨VÖ”‰õO +Ÿ B„ÃaŠ`C!´²s[œ¸¦ÿœ˜4\²¡&Ô©°É-àú@–r(mŽþ¾MàT:Ù-ÀU°4!ãQ|÷\±l_îRARÍnAvÿA°+jp"¸g^×–J<’”ÄVž!6Û`YDÙ›mtrå>:þí.,} × Ò™Q71Ø‚2Y ˇ¦Ôe7À½¡d/7ãøô¿¾ Öh¿›Ë°¼[ðó5Œ[ŽyÚ{¼¬ +ŽË¾ŠÜÓ•`!'A_ƒ:á8dl&v#`maÈ$\¯w?Ü€ßôÎ!ްK„°p˽¡øÃ6‹Ð7‰=S`ò·Ø†Â7YéŸ6`CÔüôi¿ ¸ÿߣz˜äâ=žù0MU +zžr`ÃMwV°€‡æ.…æ<ØEB? ö,ÛH°D€šz èù‘ ' 5^ã€þ%âTt|ÕnaàãµØòÝ3*¡l— ³UEP±ƒ—Þ²xô.õßÖU×À6|T«óÈÚP(6ÀÚ•®ž˜0Ðâø„¿…í¤ /i~÷f`íb×Õ Áyìü(èa ¡¾Gx}çƒ:$oÅ~9Ë@ª¯•[õºÄ—2—b‰ì‹a3†¤ÏÆ|Í1°%‚þ§ð4Š_—âÓ>qÿ rkÈ]l¿‚ûög†öV0€S`¡‚r=ô±ÕúÅ ©3«á°7ÛTœõøŠÔšÂôZ Ê!Vñ/ +¾äœ<ŽèC:Ï~60"×µ¡ð²¡@9ÛH ¸‘Ø¢è¨ýhúÈ™‘¸¿à–2jGlu€æôß1ÿõº¾ÇÝiÿ‰€#`Ï*HíQ¦R»T¨ˆ—p¿ßÆgy¹û ÌSÆÆm¬?ÁüaŠTÄ–8(·ÒçGè©Áþ ìµ@’œL¯UÆ²ë £ +µyLNO_ÐÕÖ'PÝ? êX€zj?Ò:p"à"X–R§ˆƒ;µˆý{`Û +½VÞq°‹U«`è›Áü;À±œ-Ô¯(gB¿¬ò°íô¡.«P°@989ä ¨yA"î –Íl;À¿Ñ¯æÔ°á += 7Å`ûõ?È^c +MŠÐÖ" æ˜ãh Ø} ¼ÆýÉcGÃxãu ÓS#ðWs«p¯„'QþëÜÓŽãÈ£ç1anùh‹0îånŒ‹À9¡× ¶`‘O6Ò²[g‚4#Œ)`%{´qHâ4t&^GõLP‚uT, y“Õ¨ Òÿ€Û°†"±EXX˜^uHœÕÄ]îÔ£2»Ô ÕÛ± š'Œÿµ¥‚ølCAÅ•íÀ6¨~†ýZºF„®ð´X15!ô¡°·w°wÁ6îC6¢µ¡°úˆÂf$e|\žžÃ|Ö„Qž§âÊw11Å;Ä;qÏ àÚrÀ\sÚG+мo.£S;2—{5É´èK =®.bçPÙ]j`ñ†k^Û†z ö‡¡¶ç<ã5ï‹°‹˜u9ô V‡úlCÿAMd~q´ø´ï$°É‚µO´¥¢J·0Ηç +,}ÆtCïï Õ€ÜP@ý kvÙPÐØ†¢~/›Ù£)Ìn×#s>¨ .7+3—²ÃyÌyÿ˜íHÁ Ï1ÙPP Í»E¨.œƒeDȵbð¹8¿£\Ɔ]_ÍF<Ý, +¸¹ +ó`à(wà½=ïa¬¨ÄâÝlRÕ&µü•Z¡ ã ½g*²p#¬ÝÁRÛûÆRAbã.2¢h=})o)òt5ƨÀ»+Àæ’¸º8ææ°|,<³3±å»™Äje¨y({™Ô °^užÀåaߊ Vö|»0¥îÓ¡%¾Sk"¾ÞÊRÁOVQv‰Š”MøTÁ™À‰°Á3µn@3@q +5xš/ ×X4¿¡ëEzš$¿‡­\/ûß[+ñ¾¼ó™³S`¿XW“*°a›ð~X³kÓŸk½`ç ­0>‚ØÂ-tÔ£ `C!²‹Á=èÀž#‰Wìñ¥ô%â ¼u°§cˆÓ¤Ìýwè÷‚{ìN²ÙPãÈòžóž„×xl}§Bz+âøUalÉž¡šåo{Øßqk¥Ø'c ôì±¥%^‡œ +=°dBrWÐWëtØç5f’Çå`©¥®M€í0ÞË–VvPœY§Ë^®Õ$lǶ‘`Ó--Þ +rü ×#ÀÒ +qèÿYg šÍ>\ÖE±¨6E<\t­‰\îP +°>§½Òç­OdÌ#φN{vÚÿÙJlCa< ×QAYË¡ç%òL˜m(¼†l(„²‡[ÁjËô#î/¶Aõ€{ª¶|Cu*–1F¯3)Õ*LZ*®OR[T`ͬ‚ÀJŒü?¬ôæþÓJ/½[öýèRCråxŸAÒ|!ìk€¿rìq•Ê´fu*¼h܈¼&v>°– +5:ôÒ ¢Ix£Ž4yüò´øa™aî{˜ ThþZÚ6Yäö¡Ö„z ¯Ÿ žŒ±Ø5iÈ·Sim Þ5Ô<¨-M …(¿£úRÖø]èò“[wÚV´êABÍ6«M—Êê=D&5íÆqúlæ¶’I•»PÎÚ +8 먨>Þ =o¡÷•Å€?sDþwW1Öá(X[_mÒ'+wR~Y ±½ôªNœóØÆ¤wï'Óz•鈲-pa+ñfu1z:í4“ñ¹ºˆJëØ/ÌlÑKvÜo„s]PƒÀš'ðaèx\V‚u@ú˜çX|VÅíÚB‘KÆ|ØC†í†Àö$‡ä!ñt=æ×”Ïë é ¼ú»ÀYíâ6SH§ä™”{î|´|“àê§CÔõ~]ÞÕ¯ªü¼ºäËoFdÁÇÃÔý uå“– ûÓA2k@•¹ÙÃ=i9*~Ù`-zÕ|Š~Ø%¢3{ՙط»Œ.%/‘X:Œƒ¾Þ»ŠîØL¢yºŒ yºžIm> ¹Ò@šäT +§W +LÒÊ …qÅû°%²Mèt‰s"¾ÇPW’Iµ»¡?# }¾ öeɵ»ÁnלˆÛ3Ùï´éœ÷Ztz¿*Ò±ÖMàIçÒ[÷Q`CšÖ²W[ŽûÒLè£u€ŸdV§*` ܪ Ö’`Íq&ò¿±÷Rñ~ÑÛ+Çà+ãsm ñd%+Ý*È|·ŸLoÙOeµæ´è±YMÚ`-)HiÜïú7ðÞ‰Õ;!N ®É´NeØ;B]y¯Ißh5{júÎ;/½o/?¡}§ ç»ý´×HXüî,óºËRô´õ(}¯fo ú]ñí:#æV _x«ýía^³1s¯›&ÃË6áo× b›¶æ|ÞGÝïfÄOë,Ä÷kMˈsëTÖ{ ~v» +ÔJ`¿{ hYñQbÕAö^;ËÜêåÓqÕ;‡¬M³—Ò)mûùÒ7ëIk¿ PwS)­ûŒîV›Ý®=Be~U£Â^¯ë]aÀ³µØö-±a^Óò{´ò1îw± õ Q¼r(æ!²²íBÿÇk`ÿ‹$½A_˜Þ«=(úÒÝ¥¨~šI¹eÏ£<®Ìxß_¨ß°Aÿ.§ÊúƒO¾ø&¼þÝ„*üfÎ/ýÛa^%gJµqd{ßùÒmŸœ©ª÷ÖLQÿI¸w’ÊrQU3û¼Ïœz< ¤ž~‰ž7ž”<©·4ºSk*ɬ3'Ô¨Š“Ñ©-öì‚q%Þ¬¦“Û•E—[ Œ/7Âä5aà“µP+{$.;…Î2>ë3ÕÈ3k  kÇùØ" +¬Caò#}­S¾þÁ€Éë`˜¼6–yÚyXø¤á(›ßa.¼ÚI’ÙjdRã.~f·2s­Ó¹ÓAÓh wô·¿êÒ×?· ˜Ûu§‡ÇAÖûý¼ÜÁƒÔ•~ êzŽàÖ€6yã£yë£ý胄yÚ‡p —!Ÿ3/ßÞï>,¼‰®ñvÉÞo”ˆ´f´‰¨;݆ÐcæÝûªÃÏûª+xü™b +>å¿þ»±àùW–-o·•W;¿|{ÞøÉÛSâÛÕúJ«ý^ÞY°rÎ+ˆ‘ùÅl^¯˜Iû Æ ,8|µÄ˜Iî8`xØRÞÀÔf8Ø^ÂZ¨Qák[ɳJ+á^#6¯O"ºÑ)ç´“â+›Þª)ÌîÕe²z5™€G«ÀF‹ñ»³Œ’–lÅÖ¥‘[€¿}Ñ</Ù"ÌèÔ¦¿Ó Òzðr¾¨ð>ì0Ìø¶Ç0çÇ>ýלÀ°…³à¿ÿó¢èC}0û¡ÛOP÷å4ÙúÅ–îÿèIõs–„š½¿+=Ñq=V4Ð"ì}(éj 5î®ëÈO7T{£û(¢^}=Ìôž•4ÚK^4ÞnKn՛ܯ°<ü¢ÀÖäa‰µèn­DýE•ŸÔ¾“½Ú͓ܯ;ÆÜèqµ; ÿ=c6»Má¾är-ßäfõ£ëµ¨7©ôNUb!³KºÕf(Êk1æ×Ÿç7Yòoÿ¡-xø…O=ù a_wX³='è§}êa?Ã>ë4e +;NПŽP¯?¥Ëz­éÒ>+úÍçãdÑGÈWߌø/¾°dÑ'º¢ÇJÜQî'î,õVW8ÒÏÞ™P·ßó©œA AJÇA槃0è»]ó S$ºßbÂÜmbèœv-AV×6»]Oò°ê(Ä·äI…{«¦nöPW»tØ[”è^³ û´Ã„¼þUSpû£s£C@æuò{H2¿_B|=¼íµb*ºÎÒ¥=§éªwçèê®3äó}¿‡†ÜD>ï’wßñûùìÝV–*l1£ÛlØî£¥‘¢Á¦~+geXÇ™“MŸÏÓ]öô«¾#dî' *åP‡˜™P—Áš&ÆrÄK!?@¿Ê0¢váÕ¿`óºÄâוÌå_'Ô«Ñ¡Wón|WÜü¦Åñ™< x9¿©ðcû¶ò’¾í¦ jH²Û&wjNH^Û•».}íi\Pæ z^wR|³E(Ìé4À\årŸ:ÔiÊsLÆ Ä ·Š/ÏãÇ×mãßÿU_PòÍ”êûì*úT,, f?½ `~íñg?50_û}é~/Ñ@yè‰öééÖt™Oep|dÅ¥Øc]7däÀïn¢þ–УïîÅ÷–JEïÛ‚Å-T}×t?­èWƒæÌ‹Á#üìïûéÊâüf+㢠+É£¶ìË÷G©{ƒ$ý¤G$*m¶5n+ •·:²¯Z-…%ígÅÅÕvâ²gãšÂKÂÒVñ‹z+á›z+QAóæE—9õªû°(¿Åc•¥¸°ÌZTTm0ÏÈ ³g'/ðÞøº†·þ¡jø„3 ‹û +;}$=a’þš0aO³Ûßê'êm¢Úß9ðÊþfÂ+ûÓXPö«9¿êËqêÝGGv°É_ü©&ܼçA¬èSKUõî õ¢WB_ëÓD¼YO…½\GF×o%¯~Ô‚ç„ÏšÌ^Tž—äWXIòªŽˆo7Iî՘ݮ1¡vˆ˜Çï$‚§= ó¢Í\XØtZ”ßpJô¸ý¸ðQ§©àöwÁƒCå_æE»¹¨ªÊQX_ë&i©ö3é)Ž:ñîv’eûÕ¤cÝ÷âô¿ˆÔú‹Úª|„åu¶ÔË~c¦´Ýši­u3î}eÖ—cÑq#Ѫ5=Þ¦1)þ|}¼ìLsJœE{ŽÌh  Œ|ïůûõ¤áƒ?t ÿ#:>Mèš5ŸL}·º2 É\þ  ع‹ïöl¾~êÇ­tÑà1ãÎ7a¦R“ú¢À#]Oc̺^ư5-üâï&º÷8ž÷³…†f#u4Š2—º\_ Êk05íz)³ì¸™lÓœ‘q¼íA’Qc‰?ä5æf+)¼Òl ÌC÷éUéyㆂÉ˪³ÌÕ}ñÍ6!à ÓÙìq²#'Å\lb©·, ,0bðHïh£ÁÂñ§×a¦ïH¤8&sÊܢFg”zʬZScÄ(nôäEï¸+þP*úÐdÖýBF7 ØÞç´Éœïêü¤ž]´×ã¥Ôå/‡ŒŸÔ?î:.Èúó  ´t­aTÍZþ³o´¤½&À¼ëYü±ÎÇ F}5‘l[“‡¨»ÑïpïÛhqwM]ÒeÉ/údÄ{ô‡>ÿi/I¿m?IWµÛðë¾£{Ü`L̺Ë„µåŽy¿©ëeÖnÒÏØ¡{÷Ç>ÝN˰å–mYqi•±‰UžñAu~‰žu¡IçZS“Ì{îÅŠ¿TEˆ>·‡°Ÿ:‚„ßÚƒÌzDŸmNM8Ñž+3éÉ«ýqLÿÖèk_ôDyí(Ϩ³þV1aÅ›€»Ò9½Z8çÞm³×ÿ»Ú&0Êjà‹S:4™Äª½dÌÛ­ä•ê¢í–FUåâò*öñ{~öoûùQ%롯×JK× ž +ÄõåžÇÞ=M<Úó,AÒU,|Wçc4Xu¾9)É»>8Ù«>8)¥Æ=Χ>8MÜVâK5tœ3ùðVêÞžêÛèÙä“Uã*Í©s޼^å…®7Ú·2@TTå'»Øsøýƒ(æý{/ªìÃiúÙ€‰øiÓIñ‹&+ñëÚ ¢§MÇ™;­s­Õ@ø±9€7ÈÙ1_»}-[sδ^N±j½’lÙz#EÜU@•|¶0,û›˜_÷㸠úï'ôÞpú:ùœš^zÏýËw +ß¶Ÿ?ü¾DfÖ›/£ÛÞ;Ò%ݧè²NkÄŸ‹2[ôéÜwÚÂ{uömåã¦WÇ;nÅ›u>Ž>Ñq/ɦ%=áYçSíÔRí•Ué&½UïUPo^Þ|!´¸Æ>¢¨Ê!¢¬Î6¬ºÖ6¬ý\YmQVæy¿Ü9*«Ü=:¤Ü?Ϊ)=ÖèÃË0á@] iÏc© áOkÞcμ÷}ë~Ð'>ì:Ì^ù¨O§~U]é¦è»ß(¶¼ë¼¸¯%„ínóaºßy‰?Ô‡‹>U†Sï=ØÏ’eÆ}ÕRº­Û‰÷ìwžàé;°°î¤¤¥ÔWü¡&ÌøÃ©G]hJP£_Ú¹ÖìËfÝÏdâ¾bÿ#½ÏbõÜŽ?Ús#Æ®-*6¬ÖKv§ÆIZ\oQÔdþ²Ù6ü5úZÐ`^Poþ´Æ1*Í»´jwYF…»,¥ÒCæS+ùTªWαúe+xW8öî€PtÿÃañÝSÑëÖ3Æe%žÆMÅÁ&%QÂ7ÍÖüœ‚Ìþ¢œ¾èaÇñëæó¢"”“_|1×Õ{U¦¹ÖJÓLÚ‹¥lA»…àÚïš¼¤Æmü+_ÔèÇ}B¶¥Ùæ9%õdûdã¾b„…1Æý%Q¢¯af½y2ûYRb½[\l½g’U[vŠøCiÓÕà~¼ëv‚gKp¢Wc`\|½›ôzS$< Æ /ª¢®×:GeTºEÝ©sŒ*n²HkrŽ9Ú{;–üµ×]ÿ=wÜ ÿ–†ß¹ ‚ïŸ\?<u®‰Š ªö‹M(óŒÎ*öŠv¬ŽŽ±nL‰>Ó˜s¢5G*yÿ:Ô´÷©Tü¾9Lü®9XÜÚÀ>üÕŒ¼þw-öÙ¯GL[ʣϴd§nÍI<úîvìá¾çÑfïŸÆ°;ýï³£ûz=„ßjBŽvÝ”™ö?”tr­ƒG©wµG»îƹ7F]1j(¸¤÷’ÓÒÍþ¶E7ðñ|]»ä©zÎÉÓuSZ6Tþ!$ûº-º¯Ä…7{ÆÅ×zÈÌ{nH ~ãÎétsFÚï9‘ÖN¬Õϱš8Zg35øÊ1øÁÙ0ßj¼™ï5Þ‚/_\tÚ8‘vtË2ý{œ:ù懙¨¤ÕÞ¸¶ÆÿDÛ$çÚèÔèJߤ¬ +8ûæ¸4qouÛØìÆ4t:ªÝÅ}M¡gš2“]k¢’ì«ã¯yʾq²mŒG˜ý,Nò¡2Ò´·(Ƽ'/ö|krZ`C@š[]dÒÉŽìXú÷žKTW—3ÛÛŒ°³2Ò¼÷~¬eGNüùÖ¸¸ØF8Ÿ†ÀDöSkÙóÙ‘ìúæ`XÏ™êsºZwwh‡ÇÍÔ +Í«Q©v?%üµ:Ä·*06½ÄCŠòžôz±‡Ô§<(ʲ%3ʼëZýaÀ‹i|oO¿ütåñ£Ls—ËñÎÛ ^µ!Iw^»I_”:Eå½v—ÝzãŽþ_wé“7®ÒŒ·^1GºQŽí/Ž„üP÷ä­‹´°Ä)"aVYµ]Ø`Ë…èQŒ°Î«!0–ÿÇGW6ÎÐà;gs´û†ìr“KlqËÅðÇMÒ¼&‡èПá÷Š`á÷ê ȇ&ƒ¯¥¼¿×zÆ)ë:…NR?f%ÐøœÜžˆØ¾_“ؼs/±uÇ~bãVbýæ=Äš­ÊÄú­zÄ>ó0UÇÇST³ÿ¶B­S#¿tºº”GDe¼ð•]åY ‹+ð—¥yIà ƒb.!îpº9;Ží{ïoÔSy¬ãvâE áåþ‰io|â2J=d¹ˆ7ÄTzÇÏã5ÿÝÂècADF•›ì·§Í¶·ÚmÃouÚF2?šütr?mѳ•N> %$VÍU"W æ +Ä\b1=”Ð÷+GÏ&ÖÍ^Bìß/$4DŽrêù»)b锹Äbú­YÄyb²Ülbæp%bî襄ҴµÄ¹›‰+ö[ô­ˆý~U3=çvéÔp,¿ûOò gƾùleÜõVšóÆ+¶èsä›çÈÂr‡ˆ'o£’+=bbÊ}â|«ƒ’<ªÃ“ßøÄÞÄcê!{)6²Ô7æpß© ë׋TŸ»csDl]ËŰƶ ¡h%~ô{h6qz‡r]{ÈùÚTM»ÌÉ:.w´‚ß*iæ~Y¯‘÷÷-š¸š± K• ‹•Ö g."”£k˜AL Æã‰1ÄXô˜„~R$¦Jò3ˆÅÓ”ˆuÛ ˆ½ÆòÊŸWIœ§Ö©ëáNþÊÙ}x&ìë d›=…-½>¢ÞΠãïnÄ^ª ŽOxã^è%½úÚSŠp1:«È[ö¨ÄEúªÔ)òr‰G4Âcé³×®ÒWE®‘E¥Î‘i²è*ŸøÖÖóÁ\Uø—»ä_ûÏìJÔý³8øšÛrÀëÕ´="»av –-U"V¯YN¨šXËix_QÐôÌš®zÜ^~É|%b21‘MŒ"FÃñçt]òès!÷óçáè™ñèªÇ¢ß‰~’ÇÏGŸ¿LXA¬ß($v‘roq«ØþbOi~4îY`´´Ð_SèóöRt\‘¯,£È;úr¡Wôèç…nÒû…nQ^ºGÝFsóV‰›ô^±kô›rÇH¿ê æk—?û¹Ñ_ðë'÷ m1±/[Qn¿Óâs¨‡ÓÝct‚X>k9ŠÃ©èýÃ{…Þ•¾ +›qèïtñðúþÃW¿ w`1jØôu"1Rn"úi1sÊjbí3â O‚áʃœ ¨#¢þÖ ‹¶«q9^ÑE…®‘Yo<£sÞzD#Œ‰Ì/vŽðª +‰3yÿ8Ü»"4bóák—¨Ûo]¥q%ÞÑÙÑì¯mAÌïÍ.Í¡ñ5ïlB#[]£ô~ç,Ê^ÍÝ´G›P?]ÃhüþG¢wßO@×4EÜTô|?ì¿\Íþ†¯î_¯{ú„±‹þ½h.®Ú{’PhŸ¡z[©;ÀcºÞûH:«CLÛžEoË•]¬‹‹³­—ž|‰¸,ŠIø׾2Ǽ—^²E®xÜKºE7•¸ÄtU8E‰>–¢Ï\»‹côû¹“¼ïœF)§¶Sל˜‚Fèÿõ\£ÜÏ;ÿñóž)ŒZB,\¨K¬U»Hìu¯™¤ÚÃ"?U8Ø”%‡&¾Ýzåó¤ÐMö¸À#öq±kü½·®1ù…î1¯_xļ,p{ë/u¯ + -÷ ©ô•eU¡º«ÒYz½Ü5*¹ÜKfø•³Q{ÉmUõ¹9]ÅÜ^nÝÚ­ÄL¹I8ÇàwñÆœ¾ÿò8Ná뾆¡H‰^…çÞÐ<†¿‡çF£ÏqU'3‰)#sËwY[MÒåÔ95Áçng“Þ‡Á¹ÅîQ!%²“mYÑP[5¥É€—A]‰¸W´?új_s¼#W +Ïç–ºEU"ÎÞXg1ÄumÓêÝãLûó¤ˆ_ˆT.†š7kæÿnÿz­=×+ÿóµ¡ë‰ïÌXt‡Æ¢ÏIxö!êÉÿ¼Ö1xþ)LÞH¬ÜaAìàšÆüÓ‘ès4¾þIèåÄ©›‰ËøÄ +å Ä&QÒ°=YÜ<Ïœù‘¦¾ÉÏýe7ó½cò_yĽ)tO¬(ôH-/qM~Väw¿È-:µÈ[ê\ ªh”ߥ1ÕžR³ž›ašåœÖªeÿ××1„†òø=Ëÿ˘ûùÚXôê8ô9eØLb†ü1mÄbÒðÅÄDùEÄ”1«‰™ +‡ˆ•û܈Ç^P)äÖ1}….ˆ·HQ>€œíV#úXd4r²%SŠ0&ú ÂÊT”Fk€“_FØZTâ$mm¹uÕœ¶­Q2ïܵôwKwiЉ™òÿ/cCü¬„ŸÿÊ0O' T‚kR½„˜9q1{úNbÖ´í„âŒm„ÂÔ-Äô ë‰é£ÖSÇ­%¦Â÷c7 +ãÑï)¨‹7šÛŒräærËõº¸ãæÍ7ƒ-k.‡7»óÜ;:å¾öמ­…Þ™oÝÓúÞz]~_ážù¡Ú-£¯Î%µµÚ)±¼Ü% ê®ý•ÜÖIòÿoðñ/„ëžã¥8B‰˜2\ý4 "d~”?åæ ,™O̾œ˜6j51mÌbúøÄ̹‰Ë÷Ss%62)ö°ir»‚z§è|áLÙÞW.q/¢ï>½ÿ¶À=®¢È-®òµ{be™KÜÛ"׸ׯÝâî¼u‹.Dxúâ­‹ ž—•zKtp*+שü¯¯å/ÜŒ‹‘}ÔÏïGcóóûÉhG,$f£qš3m31Wa31kî^bÎUbÞ"}bÖ"1k±>¡8G•˜±@ƒ˜»Œ&Öh…»œÛ&(¿áÖ‰Þ=w‰|yËk¿èGEnRÄÍd±%^RÄ3c ö¸Uˆø âb¥¥ÎÑõ¯]£_»D£k”jãï°•[´i'Ê­“ÿí뜑a8þ~‡æàXÌF&3äf³Æ.'fMYGÌ™¹—X²FL,Û~ŠX¸Ù=,ˆ9+…Äœ…$1s©€˜9_˜¡¨JÌž}¿¶Î0†ØíR?Aõ§®ÛÏ1m¾sɪ2-8ñi`tÙ3¯øÆWž‰%…‰(Çǽ*v–¾+s‰¨rŠýPç7Pï”TWæ’œTó'^´Åà5fðþ'aŽ6é'{Êy0÷†^›€^B(ŒœEÌ·„˜5~%¡8u-Âæ„”5hþí fMÝM(NÛMLŸ¶_ÛÜåÆÄÜE"bá:Kb…¦?±ÙìŽüŽÐž)ÊyÜòý%ÜVÝÜÑ£ Wüƒ>Ë÷Š«-tmDãT[îÝQî’s®³Þ9½£Æ%µ£Ñ1åM¹ ª%ü#Ôs{–¬Òø_ÇæÐµxü ŸM•›EL•GšWÓМ›.?=7Ÿ˜ˆÆpzLµˆ˜1~5º¶„¬­(>UPLê³7ó¶Z ö;Kt‰L±‚L&6˜>‘ÛöÛŒ}åܪ¯äâ…¢”0¯×‘‘¯ƒ£J÷ªA×ö ÔEöå¸ògYG¹slO¥s\G•S\Ákטsµ Qªo¸]³&Íþ·Çí¯ùx™jº¼"¡8rº¦Ù(§£ç' Œ=qè5¹¹„â˜åÑØ[‡ps31Ga/1¡€X´É‚Xº×–X¬æN,9àFÌßgGÌSµ'~Qu –Fë2åvø·OR~Ì­ÐûÀc{^»œ-I ö,ˆŠxúÀ/©æ™wJÃ+7Ô ¡þq6Í qE¨Nh¬pÄ}HáÇ—”oqKfÍZ÷oçòá˜kGDÙk8Êeã”ö/"‡/D8?Eä ›ÓÐçt9t} ˆ™ãÓÆ-@؈“W +Óþ/Ò$”Ö˜Jk͉N‹÷¸‹u£ˆšAÄó›rÛ|êÇí½É-<ÐÄ)#l)î|î}º6=4üepôÍç^Òª—î²Ftme®‘OÊœ¢ÞÕØ…ªwHøÐêRQë””\æeð£÷ü¡íÿŭ8ðüü– qá1h´Æ¡¹6á,ü˜.ÿ ¡8i+ÅyP j³Qþ²QLü²žF˜¢KÌY¬I(ÎV!¨Šë‰ù;Ñœ3&6ZÜ–ßÖ4açnÖ¾*n£J·MÿëŸ'Í›¯øùF&^’!ìŒ}‰¸4ŠÑ˜ÖçÄî:§ä¾§”Ï ŽÉ½Õ®©]UÎÐK’j´qz‹”¶ÿ[ã&ÿ/ø8„ѵ ö1~¡ô‹ +±@I]‡21kþ„û…™?fnC˜‰æšksgí&æÌÞKÌST&æ.Ô#æ-£ˆ…ËU݉µüTbݱûr=*Foo»ó÷Ëîô³÷qÕ{8=þçV£Ž>Þ¯"#CóC¤•ÞÅE®1_yÈxåßë=ã4 î¡ú¢èûa¦³Ýà‹³T+ãö*ûOSœ°ð¼®¡Ü6³C@ɱ˜eA†žMLAã¤0i51åã%̉•j¶Ä’m¦Ä’†ÄÂù{ˆy/çL]ƒó6sgoGœRX°š"¬KUÎkuƒ‰µT±ùØSùá]ã·?äf«|àöxÇí×äÌõú8 æ}¿÷ÑÖ– Ù1fÝ÷¢,›sâÒ^úÆ%¿ò‹;Õr%Ñä}I´[}TZE…}X•]xB‰Wô¡~ŽÜ mý?^ÛH|=pnžL(bü‡9ÿ8ü8àåôó™‹æ£"1u<”ˆé׳h‹ö!~lý|øžðþ{®ró÷=å–ŸÜ÷ˆ[¶;åo³vJû¦m뙲íbüŽ‹Fï ¨œ¢rŸ[q°žS1øÄÑÿÄf¿û˜ô? =Óœ …zjràš v-r“={ëU^æÙRê=Påš\Wê/øÒâtÀµt`àû¿›c~ærˆO`ÆŠ£æs§¬%®Ò"Ö¨[ËI;b™y±Úéþð5þoFn (³ÉëÍèu_çœ?b‹OÅØ-­ã·ø7ŽßâüvôVÛ‚Q;½ª&ìÄ­Ù_ÏíÞw[¤Òªp —[¦^Ï©k5r|íN¨Ý±¼Aîâ…ÚØ(à,p]9ˆ;»VGÄêQú„†Î~ô4Ä×ZX2ï _Ïëæì}ì…a‹–íùâRàú Ećg* +óU ÅåúIJýÖÄZ±Zp‰X' '6Y\•ßR7q÷nÞ¾|4>ÕÜ–ýÕÜÀ¿]A S¶Ï–_' $6K¢‡í°¼:b[ùĽþmÓTb¿Î=øˆÛˆøÉ!­_9cÃç™/ÅžZ½{(¨lžvtËrý°âåä?õÙ²ÞsÂgߎ‘7ÿÔågüM…Éý‡ðÁwæÉg6¯O,yT{\TØvö;ésÊ¢ ùéòÿsÞƒ~Ì´©£ ®¿‘øEÉX°Ê˜X´í$±TÍŽXcèM¬>dC¬ÝsœXµ™$–­V%–/W#Voe‰­‚ aÛÏ=µÃ¾xìþô¿/T«áh6p:}œ‰àËwóÎëÂÏo/ñ¾}³åþá ÕÆ1‡²[­™Ò³Zë·Y§œÓ×+ã(Ã*΄ß4pši®wbÞÕº›õ=1íy!~ì ¢êl K91¿úÇ ¦»Ý˳&,©ªÜ>Ì«*$æ@òà‚…J[ÿ¸”ƒª q4ÏÐuN·˜˜3g+±d“±QÝ’Ø&ð"vNÄ®“IÃwD¾²ï5·Ríg¨Ï ž~zâ&ø­ÊÁà_Ïòÿ¨µ3ü³ÅV÷î„ÚwNOý3g¨õkåÌèO=^:=œñ¡à¹Z–QcÔÍCFjqš¼ +ÎL7÷Ïíú®WgòpT×7‹ŽkñG»nÅkNO±è¼•¤«¯CÐf#èˆçD¹$ý¤O¤Ÿþi‹šMÒ¸Å+vá:í¿û˜ˆÆíÅmÄÒ5<Äs}‰m–/Gl蜸3•SD±·ýÐgŽÔþ3ÓþÁÑüΉö·p;U*¸Mª½œªÎÜ1»ú(in…kT\•‡Ô­6$J8øÂz(š(öÔ^pÛÔp›Upjz-œ‰agÍøÓQô­6„ùòÎW秬kd!§²i;¡©¦JÀ9JØÇ(HoV¦"_n:dΊ˜ÂºÞ_Dåü¡ÅÞ0"³?«Sž7ð²µÌƒG­Þ¨OÌ™°ø¿ô‚þ#6åÏBkÒrbñ–Øl”,·;¤càßÁÏx¾ÖÿÎYêÿÊYé~âŽh5!,¨çºœ@»”ÓÑoäLùœƒA7wR¯‚ctŸs‡ô¥kô½nÏÓKëÝÌ«úãÕÿÞ÷‘³5ìà,´sÿܪd˜X¿…¼òùõpáÅ–m„?_-HÊßJÝ©3Þ+W;š4±»M˜äÁƒtdÕ6:øõ:ú~ mÒò"HÜ[¬WÎÑv‘ÿíuE¸8I~.1yôj4Üï4ä~V7ÌéÙË¿”>O˜»ˆºÑ¥ûjù×¾©ÆvlâÇÜF^û»¶aLÕÒ>YQpÊq å5ƒ—Ö´‹º6 -ÈP3L®Úbñj…^zïVýûœšþî nîÚ×þ¾Uû*·Y­Û©þÓÕü•©r:šœ¶ö[NK÷§ePÂ1zùœ–vè%Ó®#uM­ä Ÿ–×ÔP'v¬œOìß¶ÐÔÓ%H³ #é3®ãAC|DÀ_Äðð¹á€´SÚº·¤æ¬⟾Tì¨HŸöOÛÆÌà§Ö老í¡|.+Q®ñ³(7Ù,>ÂBq~åÉÃeÏ}ÈçÝ"þ¥[ yaSIï{‹EÛÌÄÕ•°Ròö­uë—Úºƒò¹¶²‰œÊz¶\¿ˆ3 ~q^¤ñ„Û­æôxŠªUÎXõ y“ÔÎåŒ×¸Çm1üÈ]„½|†Õœ©®[¶Â!-#BUY]“*q`Ç>bÿŽ]ßÊa }µC—ÍmÒ'3Z”ùÖ®cõyΤ’,!9í4΢ї4Œ®—ˆð9\Ï4%ÐÀàg¶ìƒ9'ºº„<ç7Q`:• +É[ùÿ±÷žQQ¥ë¾oUPTDÌŠ9çœET$CUÍ%S|òŽMðíÿ·Íüµ_y¿–—k}³NL0f´O4¦Ô÷•CÌvmجÛ8‘nûª :O¶îøðÜ‘˜eƒ–ž–R1Zì\ã­•üé?º)oiƒÜL©æû¸35Ó‡O6÷ô 63&³×ª·sÞé­›3b‚n"«›VÚÏÔ¹lÝ£sÙ²MçåáC:Ä>Æ3N‹´ .N|ù8%$ÊŠgïüSL©t·´„;9>{4f†¥¡‡žÚµ{AêÅ&®áýÆÌNG®ùãÕú¡_wñ%æ€Õå«F™sÌV•kßP/½Ðø¿îÅuä?X)öÎàÓë&ˆå§çA;»þ«ŸÏµÿØëwé{ý.ÿû¿Óßa¨º0G_|n†!«m¢1¶Ô÷Åü1_E‡Ù|fëŽ|ŵ\R•ìž+½8s¥†ƒÖ,s÷ÑtF%ÅBÈïη~½El{¾ ºÙÐ3"=¡KÏxãÙ_÷a¶Kh»·•xêÌ =wÁ¼8Ï|Šß9]L­›À§ÖŽç3šŒGYœ?ù§]†Î‡›üÎüºËxåW_î½?š„wþ¨ñ·>ø6Œ»ö«Aá?÷ñ7UôgÿÇn.ºÄÖK +4ó ˆ·ÀüòonÚÍÇþw?.0}~'Gx÷gÍ÷êÿ½Ïðæ?½}j>žçjÓ-›4O·tÌ,öyºnŸ§¨Ó‡gX"2¬ý‚â-¹Tkƒ)Ér×ÌîØ°…xl\b•—g« 5G¬cSlÔä2{bF…§’‚b-åè”QÐJO=ñU/>Q…K?øq¥­Óù´{Cßã-ÂÀ]¡k(¤V—³ë& }]´Ÿ†}r³ üÁ·î$ +¿ºbM*¼0Gh~´Q¨¹²X,ëqân¯j/.fyÂbý©¿ïÒûl¥_æQ{}ÁàTßêwç[Æ»ìeõº­ºm\tÎ[öë¼ôÁf˜³ÔG•ŽZ·`¹n®ƒnÞ˜ ºeã¦ë¶³üù•~×l¥îòJÌäi‡¯/—Zîo÷/=½XˆµÔehŠ´$-B°0KÆ)…Ó¤£×× +Ýï0vßÛÊréå¸ÿ†Öûë —þæ&]ü‰7 ¼ØŽ‚P9Ü¾áæ +®ýñV®óñV±ÿçý´Ök/.ÊûgsÇï¬Ï¿ôÞxiĽÞû>PüðeÿÖ·pE'g¢ŠFùð‘æ®ûݾ]>:è܇çäêÆñÙ}S¡ŇæŽð™ïˆ1ç5Žg¶0S(bµ®ÀÜŠpêObÅ¥…\Tî(.¡x´ßÃâùE–sÒ›‡}díÕ¥\ç—[…îç»…³ß{ˆç¾óáOþ¸—ô¶/üÑ[xãGæ4ŒÝ϶›n-ןþuæ€PËâÌ·ðί&CÿŸ·ë›>^®ïýÇV¼~>­d¬16{”Puy¡qèOÎÜÀŸwC7“«¾¸€«xc¾±ùÓUúÞ·øžý÷†”{Wï@ÝÚ…«tËæè6Î[©ÛºjnÏž=:7OoÝžý,¶±üØÝOÒ¹{ ºýû|tûÝ}u¾A±Æ´F{h¿`FZ‹Ðúù sNÏ|bNü¸ãïozžíá{Ÿ;C³›‹Ë·ªNÎÏ<óÖÎßS`»bÅÐ\)¯e*4±ä³_•k5ùê U8ÿ“7ô—½ÜÉ¿»b&Œo}¸×P.¨ŸÂW Ì5´ºN¸ð³Ÿ|ó›`Ãùÿ骯¹½ÈXsg™oÏÏýz~Ùb(=;Ë78ÛÊWŽ7w7›ùHµäâêìôYÖ›WoÔ­œ¹@·uýnëNOæ7 :0"¡ ¯–ŸY¤u~ºO9ñåp× C½B½Ñ¤óótÄÃÌkœ‚Yè¾È•ý 0GÊâÀL!§y’PÔ1ÃØùl+îÏÜé¿ìãëß^.f´NØôâÅ”j{šÉËi™JùMÓV“®`ÕÕÅÜÑ[«øÆ›+„ÒÓ³ùŠ ó ßïà.ýä-\úÑ—ëÿ» W~y.ô2ô¦ á ¹> Ý’‹¬°õ·Afþ9®Èšz†€t+èìAÿ‘?X0RÌéš&V\]Äÿjì š¿,¯˜)$Tåã+ìøè<.*k$´#ÅâósíO6Ó rý›Ë]_lÆl%‹þÚµûÁòÕ'šéÝ{±òûò—~ò3žø|­Èb¿ñÈ›‹1›ˆù5áýoƒô§ÿálÈéœdHlg,ì›nú·]†S¿îF¾Ãls·áäßwC Ì–`…ž†lN:--wÖ껿ÚÈçöNõ H³Ü½ÍC·mÙfÝž­û™]êuÞ^gPƒÌ!¬¶Œ+ÍÇeÚèÃ,Á $—à+>­ÉAªº± š>Ðu5¥4:ªai#ýÃÒG)R°¹–6ÊTÐ;Gl½³ZOÐÆàsNLâ+NÎázŸìºíO¾pÇœ«T}fôùÞ§ÎÊÙGáâ3½áäÏÎúsÛÍ¿õ‹ |ô4F¹õì xö>†“Ov‰åCsż¦É\ýå%Æóv£Ùå·~T—þ‹ÕÖRÇs)Mö\ϯ;Œ}¿ìä~ºÎXyy>ŸÛ1ÅPveŽ1õÄggoÝÆëtû¶{êÀñëË``ŸYì1˜BÌIó£d4:…¨”ÐL%»d~Sl¼´\úÖ•ë½³]N)'ÅeÚÊÅ'fðM7WŠu7VðÍìïúË^Ãà;¥ü–iBF½ƒTraX|fƒƒ˜yl⤘wb +iêd°z0•åâE³ÄÜSHK2½i"›9Š-²%½Ê7Ñçäºñ\XÖhÍã9˜Ã‡F•á`¦5椡·'U^[,W¿½‚+íÇ›yüu°g.¦ÐVÊ휆õb8ýÃù_]¹ÁwsCÚkì~¾]*¿°ÚîÐ)ú¾qÆ´‡øÃÖÜ©ï]¥¡—^â¥Fñ­—šðæ É0ø«³päÍ¥ÐCÜ0žøÃZîâ/^Üù¿º~¶†Ë陂¾š1íØ¾šùÌžçÛ‘Cpm7c~zþÐŽ4¨l­ˆ¶à2ê& 7`ìýf;ßüÉZ.¬h¤»«Ìê }:OY'%VŽ“Êûæ@›R*ê›Å®¥£”Úä€klˆÊiðO²ÔÅX€ÙÁ·ÝÛV4”êSK¤ú·×@[zŸ¤qß; Ú£¤¥Íb…¡õ£µ†Þ§ÛØzÜ"{kµØòá&¾ãÎV¹ÿ¡»vê+ƒÔ÷¥«Ð¯pò§ýü…¼¥ßúËfš^|VeúêãbÌß~ðnšt퉟+ä›ÌÖî:áìÏž˜ÅåÏý§‡!çÔ”½®¼nÇÆ:ctÕh¡û‡ÝâÐnÐãò{¦+®Î3&·G.ºo7˜­þ:èÛndéÉÄc É!ÇW#ÖCF³#4åÁU±ÎtíÓ0ùü#ta„aìë¥ã ‰ÎŸùÅÝ0ø³3´Í¸7âþB‹Ì!ŠÕ•ñevB~×4¡ÅYV_ˆÌWYÍŽRú!ë¨#—Ïê£ä#ã…ä:{!©~¼S8š/ó ..¸!ÄUcÌÅ´Ì·r}¿:s}ß삎‡TØ5“XEµ¬Îiùt#øbàãË 64†Ääâ±ÐpÎ}ë)_ªª—¿Ö¤s_P#@3½Òª:»H,ër‚ÖßüÞhÏ€ ³:‰?ý'7îôŸ] =/¶bÍ@ÃL&!o´TØ6y 7ðã±äü\pwýX-ƒš ±bpl\LÎ(o½Ÿ`ÍwcDе12w$_pz&[Û»¤òË ½}ƒt{w¸ê<ýd”l%µÏ„Ž8t€„˜|[0° O(Ä•1„&[¹zH:/1ÜŒ]‹Ð‚¦+˜` -‘ô³ç’– +>—ŸZ WôÍ—«/.%­”Ê‹ ¹£ï®&¦Hÿ÷®êÙ¯¸ 7> ½~+1ðòç!Rß7Ò£`÷ZºòLP?ú:Nûæ‹òÀo>¨Ç¬´JÔ EÌåƒÇ`l~{…‘Õ ÆöÏ7zÚn¬~g¡>¢d¤‹³¯nÛÒM:7V@Ó‰âf|ñhOðˆµXs߉–>AÌoéÄ 4khO·¼ïîßúÁÒN‹,²…V¸%ÐÐÓêøˆäˆÛÚwM®|)5¼µ +ºtÐTâZÞ[+\ú“^¸üwƒïÀß·%—æBÃ^¨f9eãÛ«Ääú ~jˆr=±ôÜ\ÄYÔÕ†1–Ðöç•F —T;ΓË|f¡­Í|]J¥½ ½Éô–ÉÆ°+//’:ÉÄXcöŽz´„Xfœ¶NÇ@J)+gTL€.#Þ8¨Ðâ–+Î.„^‹aÎÃYs uniF%×8@ÇZÆÞ¯w€/@,XðT›n¯EÞ%]~A÷O(m ·à¢†¹ÐXf±ÒØ~o“˜rÜÁG‰6÷™oBÌÄÐôˆ!bNË>¹b¬¯41¤ ÁÑtÀ<ó ˆ0'žˆÈQ¼}e Þ +ü"V§8Êy SÀÄB<‡•Î…>™¯iÎr3cp¦µT3^Ëa"I§H‚V~Nã$©b`«ÛwB7Qìÿj¿Ð}w—Ôx}5iÞyc9˜`÷©g¼ó~RÈ­·ÓüÏÝ3‘6dÓ{k±F-ï¯C,—ßy~@þäE,æôPÃCÇUd¾,ÂBHidñ±kºP3½*>ó„#jOcÙ®mžºÍ 7éöîôÒéƒS­ Zœ…«]]öû²\šåJ8ñ·}fÐä†þ4ôK¡ýÏ%Zø0sþÀ!+9­ÖA¨:¿>ºMüÑÏÖkç¾’µ3Ϲæe¤]XÜ6‹?ó½‡üÖKþæH~ÿ¹/¿2Ÿâød™-“¹ƒ‰Vž¾z¸³˜«N–iíê¦×Á/§ŒåbV=‹é¹6`sò!Q–ÐÅ$^%³/hBùdp ÒRN`6–\uð‘¯ÒõpŸØ|s ìRfØ3G<N|°IìúÂõ 2ôÒ›ë}ºSÊneשÑLcÇ“ÍÜÉ¿íƒæ„¡óùf¾üÔl9·m^›Ûž}l=‰:!²Ä–‹Èå§Ä˜s¡iÖ\®EŠ•›ÄjÝÆëu›—oÐíu†.ç3ßÀ( >¥Á^8|nž\3:ñÐR%ŽpJ…½š]vßxðÌ}¼tŸˆÏ}*æ_q1ÚBR÷h1“oJÈmìür éÿÜú9Pxë¯ +×öÍ0Ç„¸*;¶6Ì=XíååÇë`ƒ|ß cÓíð“®®FÝþý>:ð®è¤Ô:€;E'0™MæÐ;öãTA>`-oÒˆŽÍ-Å¥Žâ“¬HSžùC©í£mZÇ{»åº7W®…ÐD+胉Ç?Ù,v~¶º_RN­#åZ'>ÚÄw¾ -¿ašZÜ5­êÒ2hò­mVO>ÔóC?¸ +‡Ê쌢,‰s^Ú>G9rj)¸ƒâÐÏ=(Ö÷=s&-¦Ò3óÄðR12׆cëOÏît¥¥šËù¶'Ûä†;¡ŽîziÐ&¿s%æ)ó7bvÇT1·{åëµï¬Ú_ì’»¿qÕºŸyjÝ=…®»;ÀBTÒj¤¢žYÐ2„ŽÎ3@ßXÈï›A9Gåµ%âÑÏ6Èßí‘{¿q×zúôÝ×+ý< ŸÈÖò +¥°u¦–W?Ui¸ºFìþl·ÜqÇ…ÙæFÊÉXn#”Ìf±n1ééÅT؉Éw>Ù.ýê!úÙ } ôI¡-”öÌ¢¸ŸÀütù™ùèϹ§gcÊmùäF{.®z w0ÝÚG 4sÞ¾G·mëNö„¼¹03°Ü¡&t=Ý_ºF¬®õÕ‹:>$Ú +Œ +µáÝÄ@Kª¶'6-[ç¸jß=OñØÇ›ä¼cS¡#/%ÛQ¿³¨å]ùvJlº û÷LÒë»ø‹påg^æo.Bf4}”Û†9‡BRõ8褋å—Â7€]z)4ÆÊ?çètS^§“)ïØ Ô`üøq3O/Q +0ƒ#â&ô¶ Å ½a>$ÞŠô'ËOÍWŽ¿¿Ujùl¸¬Ð%<´_Y>(UtÏ…–¦¡ã½õÒŧœ:ôÈW†·)Ò‚˜6쾜úBTúî»3¿ºEè{¼G:û•¯xäÚR>¹h 4üÅÄ";°ŽñYŒÍµEnŽÞƒTÔïÍgÄèŒ Å§g‹½S¡Ö`챘1º||ÏOÎâ±G›™ 9¡ö“3;§‘v]ßcc×ý-¨yÁÌB_Œúp%C³aóZÇWû õ&ö<ß-¶ÝÝö|0k$¸~`Í]_î4ö}µ:¡è‰ÿÅu.;3Wèx¾CëúÚMèùn{¾ tL5“¤ CVX÷è9©uWW =÷œÕ¡¾þC¥óþ^¾õóÍ`¶J ——CëN*>;—¸Weo,Vú~ðO}ç+ôÿu/×óÍ©ôâ|ê—šKúv§_ú˜®Þ QßxêÏ×}°‚ö1êÇqqå£Qëú±Üué t¥¤æ 2ûý¤# f ³;½fî¹ß@zÇ`«@¿P«¾ºÊT2°@Jª¯ÄUŽS²Z¦ˆvªÝö‹ ¯S3ë&‘2â+ô®Øq&ýÆÎ⎳¼ìÂ7¾êõÇÁ¤©VÐ5ã; y¯bþ0ÚBŠƒ¦hë$¼_-§s¦–Ú0 ¨¦œã3 ‹XKÌ o¡‹O,¼ôÒñrãÇÕöGûüÛ¸+-wvË;¾ÔΔytªVyu_þ‰`l¤Ž"6{]ZÚ°·Xwj±tþ+_å½{á¦w?‹…·›³»ÎÛ“Öâî½³O¼ë§ <òâz>ÙJZܨ)»Ÿíd5ôh¢QåÛqXnÅò_b/²:ƒgñÚôZqï<Äzè +‡//à£+G‚R¬P÷€_¢žž­äŸ™MŒË²3 ‘+@³ˆòˆ#——à¶ RŒ9¸|°µýá^SÇS7µâÚ2ä¿F)ÄÌ47À¼«Åe¡á*Õ=râ{h\²ëm ®¡ÚÁ®WûSµâÆ +è¨c qŒ“ÃÍÅÀx+5±h,ip»¹^ë|äæß}Ïš»Ðyïˆëcþìèg눋Ý9 ÚÁ|ÇËí|ÃÇ«…Ò+ „ÚÛ¬¦º´H¬¼¼˜x²K»q'4èÖ­díæƒú³váëo­Ž|´RÌè  æöéÄ‚Îèëý;°;ÄÞ—{À=qÛë®sÝËüª^byh€Ù+ÞœWh'„ÆZ!.7+¾zo .ñjÀƒN´V¢™Ý¤Ö:@û\|îEì¬vm_±³ªÀÎbù]\þµàøthÆj™,îýÆÎ£Jlõ,öÚcÔñR°¹¨±¿åÀB +ж‚Ö²hb¶{­¶'>‹cÔI,Ë…GX‚ÏMoÒ½>öîzÒâg‹Åi|øÇ–¯Î?«~ªzøÔ"¹éƒM´¸+O-ÿJ|èƒ{YBË™bŠmåða-nâµÞÛB:³`>C篻öârhÖâ<ñ{£3F ÷Ó‰ñaŠÌ v”›e;ÌÎjœ!ž|ìþ ”v–IçëžIÊpº°ï^âjó;k2ØY¤WúŠ’5Ò”Ý5S©¿µÎTxzÊâéðGØ·+³u*13+À±Ôò›g@K_Ëb¾ÝW%¼È–ì»þÝ x>‹‡c‡ŸŸ?üüìžЬ†}‹±ÌVSËÆk‡ûøwÞqlàMuSïƒßuçùWºógžéÿOÝù¯wCwÞôÎ^¼TÓÀÐT³Û§+ù}³Œa©ÖèI#2FHIµöˆñàfysÌ|ø3#8jEgæÊ _nBž+gvOEüÛΰ6fz½¢cvbIÖCÅc‰ÅžR2^Í;1CK©æµa;¼Dè}º\"ô ,ï[œs£Îsï~bg$ÕÌ(üÎΚb¢·Iç½WÏâK¨9â“’>R Ë¥…§RB’FÈ¡é#á£Áâ&>unÓT5ÿÄ øO16}â=ñ.ص•ŽßÞÆéÓ'UÚ#oUY®ÏüÀµùÆFåÈ…åJÕù%Äl+i% <؇³7è•B‹[J®µØïßLêxàŒœ=@%<ÏFʵŹbc÷ÎF¿…Ø¿¹½3„¤Ãc¹ XKb9±˜I1ò;«ëÁn¹÷á~ôR^±³o•¤º °g9³Ú¼2°³ÀKFmößì¬Âav–‰ÕûQ–ˆ/¦äÚ‰rp²5Ö.4üÕC5öÈàsµÂ3‰g–Ñ<Å”]7…ùÀɈrPúbo±çû§qÄó¡·þ¯ÏG¯–tÍæ61ûk4¿¿Yë|ßÅ¿ìÌ%«ÆºÏà= ¶üÂaà—}òÐO>Б;l‹è-o¯S,æ®'X‚•þúØóòâdbîePt¾R¨jGô³½ ªLl‰ù ±þƒÕÈ%娲1~¾:/OAçé­× ¦0 -³ÊÑTÜ>tÔåÄ6EÜ);¿½bÁ–› {œ)@ÍÊýÉMj¼½¼y°³¼qVRò7;Ë(H:ì,fãðOÄÎrc}€ý®%UMP“ ÇùG¥Ù„£Q޳ƒc­”?Áîb>Y®è›"jÔ;׬íÞ©í³íà»*©Mަ¼'0*äî/÷"ÏÇ>r*hsŸðpÇ¡ûž3b 1ÊXÞ‘ß>]Jeï\ŽÞ»,ߺ³Û”Ó<]‹Ì³ HkšâŸÅêúÊ¡EÚÐ]£éÌ#E|áËC;¹õþFbg¿ýÌ®õCbg‰-_l!vVN ØYX‹j¬¹”70ZÝĦ>|’ØYøÉ`g³³´egžbg%üÃ-8‘Õ–*ËÛ‘ó‚Ÿ×>úÞào ' LK)cë³iØ +ô|VwÈaìùl.râþàùÕW—Ò˜,/Ö9œ§²k©DçÙŸ,Û†Lbµì0_r˜%;ëѹÿ{åÔs?œAF}@,Œ¸üÑ|hÎ}Xª^8ò; ý%0ˆ¯TÞ=_­9¿\-¨›Fñ½ ÕIª;»Ti|gVqiØ•J\ÎhœÃGßDËït^_3ÌçxgqcJۜ𳈠+x\5WWi‡/.Qsë¦À+xþpKð·À¹—Znn;¿Ú…þí¹ƒ%˜_Ï|oód5±ÞÎQĺ7t8É=s±! v¹ð5‡k*–ö8‰‘™£ bˆ¹Ñ?ر“ò_hú§×8xìu~úfbP†µ]f‡úVˬ› æ |²täâRµ÷+/ÒAÆ^ÅÁì‘ðùRB™b!§ÅZø˜ùâÌ‹=ȥǴœŽ™#Y\#Î.zž¬nÃù4ôK‡ù%Cs…º· ­¿5—ÐôÖ*p´ô£“‰–Û:qÇ¿´•üƒZ}e¥ÂjU0pÐßf +רs¨X EžÚpcØoȈ‰Ë%àkâÜ XÀ°/ÌX€Œë Fò±ùê*ùèG›‘+b_ìxpQÀù®¯$Û[&‹bѹíË]°O©÷û±_§ö>òº/KÌ‚Kçã~b¨9q ‹»fÉ‡ÊÆbO÷DˆÍ¶Á¾”ÐøÎjþÄgÀÎÒN?Œý/w%9·3RÉÉ9RnÏthY Ôs¾µ˜ØY`… ŸUÅ쳬—½'ö~ÁÎ*fgÉGß\/¶¼¿ 1‚ú­,æk¹-3(×d~ÌäÃÂñ›ëäzö¾ËºgË%=³‰5_24_mº±^:þÞ&âÚbÏ%±t¼)—Õ`øUœZ$uÞq–»ïïå»ïlçÛÙ諾º<;p>À{R+¯¯ÐÒOLB£­äÚsKÑÓPÏ>ä‘Qo£ïÙ.®íà Äwb5Õ•W–É­Ÿî}´y’>PÇ›’-¥ÀTkô|Ôø;pPÕÈ4-¥ÒAêúÂÅ¿ç®/±d2ê‘ ð¬òóeõº‘Ù¶ éÀ0Bß<ô5(#Îi––Ó2ì.Ô|r^ç 07ä’Á9˜1¡>S᩹"ìýËØ9>o4ò0bÀ0[Rª/,Å~1Þc +ƈÁ©”ï#SJ/-º=¥¤w˜ßˆß"óq` Ả%¿Xx|:˜Õ4çÒðÑzâ¥WUK«šH fvo‡Ê ,n³ ù>ql•t;‰ìÚSmn:{ŸÌNcº‘Ž\^†ž†zékU»tÏ$öÜß-ùÇXõ²ûWĨÉkœJŒ/pÞ‡E¦~¿°³Ä¦w×RÝVÐ2]®¿¾ù¸±ãÁfÔïÆÐtk#ËñÅÔVG°Ò”²ßXœ¬îcëx–ôŠUÜ9l# kêÄ-b¬«Es‡oÏLØÕ‚àPWŸ\(Õ_^.¶ÜÞÈll³Ôô.å,Ô³ª>µ¿ƒØp¥ÌîÙßC.@¾ Ü)¶FÅVË÷<Ø©œÀóç¿óà:ïlÁ;칫U×Wйɴ¼±òù‡†ÀëŸD„^»táãPÓà=?¡ïînV9ã5é93ؽdï]ûòÞù8ë&…åŽTJÏ/ š¹åö%½ÑÑ`Š0XNM ë‚>'p·Df?°q£nn4ú³ÜР3èM:!4}òc¼/áøÖ£/ÁêÉN3#–'û[Jyï\ð­p~‰˜DÕ7VðÇ>_æ˜r4çÀjYô¢Ä°(+°¶p=•Ú7WŠ5o,E/1Z ÏÅiñ–à(c])½°ø(´× &UÛ,pÖÐÛÆ,™\ÿî:ìYó=LØEÙõ%jñ™ùàPkù]N8#5ßÎ-i -ЪÞX»§{~x\…­3Ñ»–{¹3ÿ½BJÈ#‡gŽ$X)) q®G<û·vákEøÚGl¹·•˜=è!wúê*±ãóíRÛç;Ôò“ ‰iæ-Ëù(g­¾°ç á”üãÓÀÀÞ\Ë^ý]ì7Ó¬cT±-ŤªsKàç‘K)iÅã)OÉ>:U+êp¢=!æßù–Ûë¹£o­Äõgõ¼A‰6¿‚˜*,®Ï+íÀ–…Ä Âûfù#ŶîÅšs‹D–Ÿ³ºe-ò ½ÄüËC…°¬xÝ8{&>ß ¾uûÝmbó{k±¿Äʾ¹bדÝ8멞ûZÞ_G¾:«Î9+~/ùv/qö¼'œ  ¸‡ÞêþŽOœáSio:0Äu/b,~¿k…3è…ƒS$²2èý‡™ˆ™Ç&ƒ©‚÷„½1!4ÂÒËÝå´ŠN>Äì{Ì©G& óÌß\¡T]Œ*ö ‘3* …vÄÄb19^›Vzj¡Òtkú3J)³?öúԲˋ¥´Æ‰8!FçØ(iàX²ßÿ•Ý6qRË>6ÛýK¹ñõ`?¬-°á2OFMûÈ9ìþ‚A^^ýÅåÈGˆ[ f{Iÿ\V£Ÿ{çðåÄâéøl ØExÕ{¨U™Ý"‚ï|¶ƒo°>O©b¹¸JˆµG.-ç{ž:«'À‰Á^=±¾’+ìéì z8Tqn‘TÊòZðñÿðOà.÷<Ønìø|ß|{ í餲ØÛakl˜oÜ:öÑÀÙᬣS†säÖ™8GÀu|L¹“\64 J³2j‡,PK€[…œL81³ŽÅ™æI2Ë?eœ·ª89_-hžF{eÍ×V‹ŸíšßÛˆ}z!(ÛÚGŠ0ã²XVÜïĵ~¼¿Ÿök²™=äuLÓJúœøºs‹¸ÎO·p-màŽ°³¨bTÖ(ð1Åè´QJyÿ|âÃá IÁÉ9r‹¡Ñ¶jÚ±I`*`i³|Tªîg>ôüRØ$«¹Fcï þ¼)%.ÝVV3Q½Áž‡k¾´‡^çgàtÈ£Q› ÞÅuGž„ýV‰Ù¬“>ŠlŒivÍ”ÂΙ8Ë#ÇdÙ¨ˆçMo­G¾žêAœÙRKúæâìÖ^ö‹•Ô㎨ῑG7=©ÒžÎŸzÄÅ1Šóà½2Ÿ"¥79‚éL8=,,¦õö`l™½nZ××VþóõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãõãÿçÇüù{c‚÷&ޱ÷±™ïì¶ÞŸ}Ex(1$aŒ7û’ÿJç„Ä=áA‰á±1 iN[èk¢—'ç¶Çi‹Ó"ÏÀ´ÿUþ«Wù/vÚê´ÈÙý‹=…}{±Ó2üðªkÖ9­Ô‡F9-þÍNìûN> áaá1싆 À¨ß~v+þ3Æfù¦U›6®X³zÕz§M«6o^±nÍÆNÑøúêÕëV¬]µqÿ|=Š~~øÿØ×û‰W_ÿý÷ü¿}ý_ÏÁ16›˜16~cl6;-Zì$²ÿ]åä2Æ&þ·Ë³/<*dËoÿÞÂÞÁ«‹Å~zµ“è:Æfåžäð /ÉÃId—PqZåD×`ø?NËÿûO²—±aņMNšÓjöß kØwŃÿŸÁ~äÕ³~û´Éi{ «7±ÿ¬bÿÄ3W±W:Ÿ^&îò§u«7lØÄn¶›Í~7A·×ÅKçæ%è¼ Áf¾B˜9>¼äæ>\ ™·_™—O¨Ù~Y·o^çî¡èôƃf†\kŒ@C³­¡YÖúàd+_5Þ|¯³nç¶ý:·}’Λ4ó6Å›{#Í÷¹‹º=Î~ºýû|uGóÕšëCYùÆYpÑ6ƈŸt+½¿ÎË瀒P† DKcHÑ}@ª¥‡Ÿ?ýmw?ýƒnïN7öY¯ó“ÂÌ1ãëžžô3~R¸šf ™-½z"äŒLy­31f1X’ðÊ·Å84½ªÑSŒãX2F5µ¢–YCÁ¨$ ÞRÁè4äP¢2m Kã—µ—Wadãert¶ ÉS°ÏJDú(%ò% “ 5E²%øyŒ'L)‡²6ÅÛi ìï'UÚC®DˆË¶%Ù„tkÆy“§™Cª²Bp¼Æ 1R,…$XCF[ÏI:.0ÊBJ82£6|x’5–@ò2ç’"³Fa”òªc€™A>`&bT?’½ÿØt5«v’Zqz±–×3 cÊ~j¸™”dÙzïeƒó5Œàd¿#£¸ž ‡Ç“¼QNÇ ¥pp¶”Ó:UH*µkÙ×ë'HiõBXÞH?-Æ’®R\îh’ÓÈ>>…Žˆ“œMÉxº&+È;>cN8ZOGÙ!ãÀþïiÁKæNôÕÂÌ!± ‰f¿P3_} ™‡¯ªƒ“c RI=zy*:/ öu-5(ÑFö~ø vMÙÿC&sïOFO!ù*„—Øpáe6Æ©Võö´©O Îhа€,¦»·A‡ÑjñPíx¿ x w/Y·ÛÕGç…Ñ×À4k9¦f¬”xd¼]<Ú(ÆšßàgJ´pc?çæÙÞ3Èáu@®ÈàŸl)hq–Bhªµ‘g«EçŽV’JÇùçÔÃæf)™õŽ8Šndï—½s%µÎAÍnŸ¦åw;Aæ@K©v€t#I]¥U8À~¤¨”Q|xеšÑ:•]ßi +$+rŽOW›ooVêo¬Órj¦àg$f;RLê(ŒlIaÐ˴΂Íû§7L1ÅgÑRmµÔJÈ\á;ÈI‡¬ M‰Þ?ÜBб"ÉÈÈ\1!g4F-MÙǦcXN,´SB³G‘|PÞÑiÇRSkä¨láà!kHvј³}>,ÆR ‰·‚„’Êl#¹t<ÆéµŠsK•šË+´”£ŽrtŽ­›m;Lj¤Š0&B#|iMŽ4U4¶©æuÏ"I¬£n’[îlÈ£”3,#!ÄŽ6hì^0{ ±äDfÏÍ-é™B½ÅdÙÐJz±½–ß1KJ*'E¤Œ¤1ŒÄ²ûF£z¡QVRV×4)ºÐÖW1ß·ËùÈ}:½ÀÖ›–l©—ã,Œr$»—‰–ûÐËæ^Þ²ÎÛCÆÛ˜b,HN&$…­ù 3_Τƒ+^¤\ÅàœÍ¢KGCž¿Ç— 6óÂÌHb™½Œ3Kɤ°‚Q-Á’OV"óm!A÷'c|Ãc×¢ +IŒL©DÛÕ8 ƒÊü¨¬¥Q`«¦ÖMÔªìÕè,[52mÆTMé5ŽRÆ Ò­1+e¡12Èi`ŒžÝÂf°û@Ò=©Ujb…=ÆIf/¹i"ݧ¬æÉrÍ[+1‰1mŒ©*iìºBž‚ù^Œ’h¥giG®¯ÑŸY¬’ÌCÿ- ãòy£É2ÿ9<ÒË|2ó™£]ÑÈ*»WbdúHŒ¤Ãf´”¢ñk¥ÑdŒöÏÁØ®&•Ž'{c~YK®š &–WòÆÀÏáw‘dîyf •ÒøáùZñ©ùXkjIÿ<È_ þ ͥѱâžYjnÛtÈð˜ +çÒß‚äA|îh9¯u:ÆÐhº´wŽ‚q?ŒŒä4M‘3ê'’40¤½£rl)C2Äm30Æ&g×OR’ +Æb}Cò~²`x­¼‰ÝKØ#Fy˜Ï€}BºB ‹¶Â$#`Wîû|tîžzäŒ"³Åý¼ÎËÓ¤3ÊìùÌ'ñA VF-Ôþ‡$ ÂRGÀ~à›|H´%Æ¢=|Œ:?1Ø\ɰÂsGAòÒó°1> Õ +cÀX[Ÿ¢‘§ØBöš«ÆŠx±Å£•äê "‚ää0”Ä{Hþ¹íqÕqj”¹‚‘š°|. ÞÒ$‘Êb/ID0_¡F¦Û@>AI( ßR1"kÆÕ²®¹i†€mÉ‘Ì>Ùý¤‘¨ÜÓ ÙƒQ[),s$I‹¥ÔÑøŸ©dpQ³û¦f›2œtÎRKûæ±ü`ä†Ôò¾ùjÕ¥eðMjùÙEðEZJ¹=d²ÄÐ8+ébë¹…~hÆVՌʉʡÊñrZýDH„Dd³š1’¶cZ!³%ŒÌbä­’…# 6öZ`éŽ{Â{ÂZÂȪRuyã6Þ^‹Q-Œ–a +ù Éèä¶ÏÀ8ÆQÅxŒæVr™Ýa” ¶XÞ?²ÍZéÉùZVç Œâ³¿5 k ãOr\‰¤åi²¼‡Jì(¦§5OÂZbصͰÁùTæk!éÀƱûw$ƒáëèuã~°ç`„×ÒèÑdü‚ÎâBDŽ ¤gÿDKé@º5$— —Ç3¿È©áæÈ_0ÖÉ H4AŽÒø \ÇÄì7®t4Id7OS*Æc,šc¹’j%Ä”†,•tøÒB¥ôò"’„ J´’˜/¥±Q¶&ý‘×Ažö›tÜ£ízH¤‰!æ$;Àü¤oÅk!Ã’Ýì½ .cÄ›Æú£R)T£smi„”Þw£#å€ð‘©,–ç°œ0ïÄt²gÈÆ°ïãÞÃÒϦ4;"‚Üù¨ôãSh<Åoäv¸‡$¯’Íò¸´zG’kJ*§&WL i$fðQ˜Í`d>k(ûèφ4UZ™½VØ5[-ìtÂh/8²õŠu JŒôaÝ@šE!©‡¶™x$!éjf‡Â£±Æü4ÂÛø}|µâÂ"H*CžJ¬¼¼’ÙÁˆ">ÃgÒ¸%Æó{f`•F+™­AV²âc–;c¾œ] f_àû!+&!\F驹gÁ¨$r ø=9®` FɘÍ&WÛ“œ"¾–X8†‹È)1ß9[ŒÛ°5Æü1áCN,¶h äñxæÿ„ÈC#pmð_®éxS ‹,¾*È‹L5<Ê^CÍÍ•´¶X ßHë}¾¹\õÖ +áÄç›Åº·W’ìpõµ%4Ú[n'e´N–¿¹Dl}¼]ªÿt]c磇ŸŽ´PÒ•ÚKËåú«+16N×®¸6Fó!1G2ˆ@SF³ü2‰Ý×$¿ØzT3O5̃¯‚ßZ@‰ò¥2H@¼»Va>¶©Bò5õðH"ÒX&»Èƒh<•ÝoØä'hÔ#µ¸&l}¤ +Ë…ä˜<[Œ¦’L|îWBÅ8\K>¤ÈËì°Ž¤Ôßb,ò~ŒŽÂf ›i&f§¯FöñZh¬™å‹ÿ»_óûS+ìQgA¶€¤%\YÉlge6ª¦Õ‘¯¤”*{)³jpð£C! @åÅ…ÀˆÓIº#¡ØŽÞ_|éXŠÏŧæ@zþ’°sæBã©ÆR +;gIµ×–a4YL`÷/,g$î^$o0¶ + dCÕâ“s¥¸ +;øTHäáoÐ8z®mã$ ~“Õ°[Èp áy£ ÀN„¦XÁW"VÈlý“}–öÍõCÍô,–û¨ì3«Uðo?)Ú\Ïê/£:Œ!¹„W#ªå×–@¶—F_Ë/-Òrq4æœÂòcú÷‘ rÙÙùbÍ›K!g-fŸ˜ ä5bZ£ƒ˜Û>|vç`’ yì€Õa@„AÎ]Œ/œ‡ÞkŽœ”>xV“™˜ÿÍ2 ¸Û >y5dà[±š`&| ‹[caŸÈéþUÁbr~ä vQÙ}€¼ÅY_d_à‡)ç`¶Lø’ìGófy Å!–CLf«"3l(a±Súíë$¹%¶~a“ðC4NüÛs°^°¦àŸå’îÙ$ežG¯­´<çk.,Dü†<Ö;þÖä ¡#2[£8)íà$+¬3’Y`’ýÆ`V3ûGY fY¼ã\ÁØ=ùÐÖ)¨e9ÿxªõh<­O\?%­Üž,ÆJá¬æ`1Iˆdë $ÍšgñÈ-اt¨z°¸Îk÷5²Z…0C/ y!^›àº=Ê\/…±:$ÂÒw@QŸùî3óYˆÉ,¥T\^‚õ…Ø yX)¡r,I—2ßüPŒ´äBã,Áñ–UŒåÂÓ¬!‡ ‰C=«Ë‡%ÿ’,Ñ›bŠlù€$K_ÔëJŒ…lŽz õ®›Ñ?ÎòŽ$'Ëêt)–­õ>>³¸à¶ÏC‡ûn H³Bý äìðúI¶"rÓF)Ô\ŠÌ³ß–˜OAÿr€”32ÿ!CâiÇÙZÙ>á`öHŽÕÕ~¬¦ñ5øëüä 3’œd_‡ï2Û É´†¬$êuÈÀsJ‚dû ïLJ¦[cYÒc>}KøNVïYRü£8_<8=ô#£î`±z&r4òU©hº½ž$ ÿš‘Õ¸gμô/þjàÎÿ‡'ßøå: 7°ŽQÇùL„8ª’p‘7—‰‰ec‹ø`ö·!Ÿ‚¼ö˜ßí,•Êâ-zO¦¼¶YÈEá¿!#Ìêõj<Ë Å‚¼òÓÌ"–“…ì äq©^/µ‡Œ-a*Î,¢ú7·m†ZØ> y,z†jF­£–Þ0,¹˜]?…òåòÞ¹|çÝí„EJ©~&IC”¶ÌV* +ͯçû^ºðýßí&ôc˧›¤ºÛk w(G–ŽF¬þ† ÏdòUáø§¥ú×IY'&#?Â3GB’\8ñÅf¾ûé’[~+§sš˜Ý1œ#¾¾DzH‡Ï,¦~õŽN…\(ú2a–ÑëKB/…å¬^‡DzãZ‹©È3ŽM–"bù+ó“TC•CðüB xï“üêõØ\[òEsIºŒäŠzæ@ÊÒê73ê¤4V¿¤þª˜R2ᄾ©¼¼¨cªŸ E}äú +àøäŒî©Èq¿'¤ªkK…®ïv‰Gïo ûg".Ê™mSĦ7WqÝ_ïÚK*í›-&×Úó,æ%±<§¤× ë@i½ç,´?ÚÆw>Ú.5´‘¤Xb`%c”ܺÉrýÅ@a@rˆ¤Õ ë‰}Ôp5o¯Àõ6ûb±ûÙV’‹Ì±ÄZ¡^Q¯#N²¼ =üWÒ÷”K¥5L¤uÀî r-øäÀÈ…ÅøÊ±JFËp½ž\1ŽzŒÌç"^@fZ.»¸P¨{{…\qu‰œrÌQ Mïr‚½6SF˰¼.»6jòqGÈÜ_cé ™ù[ôÈŒ¬†ÇzQÂ2FaOH+ïû­^ϲE¿†z…Ì—I¥Cs©GˆÚ-,idºa›2úx¿á"øæ›«„³ßz*Wž˜ø¡Ÿ\!‡û +!…æŽYtÈ5|èˆ=â––u’5“PŸcoJevHòV\†ÿ,ìž yV’éD¯×« ¤7“å³SÒY]Çòø[’¸®×Ç ÆÂk#yÇüÖrùÉù¬v^Lus»ÃòT¨Ç€š¾¦êÜÔôrõÕeð‰|Ë'ź÷VŠÕÈýaÓEãxV?ˆÓG¤cqïlä'RXòÿÂÎ9üñ?lrF¬¸¼Pˆ«±CLCïZ‰aµwÁéÙrÞi'Äiª%YL‡ÄPhÂVW²˜ Y5£o|SjëýÝJÇc`DcÀ%ÙsZ×,®‰,vxƒxô’¤ü6£eî!ÀTþ²[ßÿí¶Wõ:r»¦¨× ;ÉÖ|t† Il2+×__¥u:©]³X<²‹ÈA!ÕNý ‹šn¯kÞZd"ÏT·±Z 2†À w°z}½{d,õ÷•Øßëu©îÀ¡ÿ†<k9Ðp½Žõ’k ézÚ_c÷vâŸß7GÍ;>êõ@V¯Áî-õK‡æQ½Œ¯%fÛÉ•§‘ôúL„‹89_î¾·W9ù•¯|á'þàfìøx3á"ÂÙ5f¹x(Ës”8 ^M°–Eeµ?óaX›x ÿG½Žœ +õ#bÉ'AÊ +ý ô“˜=È5o.W*Ï.V ŽMW¨^¯¥zr°xT¯£‡ˆzu|(óÃ@$ +Çn¯Ú ½uô)©Vcy)ÕêÛC¯¡ uºó…|ÇÝ-ÀÎñ]Ïw²œdÁr2¬SêÙFåÙr¦ÂE(ÿ‚‹.]ʘéDZZÙ‡Ó ñ¿á"JÇ(IÌgÖM.B‰Ë°ÅÚ!I^ïLäÄ|üÚ0.Bi{ä,w>sÁûƒ|8b¨Êþ~R•=$É ¿ +ôßÊjìš+Ôs%y¹Ã§p¶qC¿ìÂÈh9®YñÙ¦Â'-®È¶‰Ü†ä }¼Qì¼»Slýt+ITâ}Bâ²é͵¡";Hæ³ë«=êÐ×~¸6±÷Ö‘}Vœ[ˆ=éð……$ÃVsk¹”Ò‰-í‡ýQ.ÜþU-èuÂ}DLB_CˆÈ ¹Y.0Ý +{ ÃzGÚï®ys5½6ôYÎ|—Ê|;ü"ɲ1û#"úFÂc6Ädj QÞéô;.¢¸ˆšaé~Äø—Ì6ªÿ€‹X-ŠÜÜÏÛD9â Ö#bƒÈjOH§ÂÖÈO&×L }:Ôö´ž¨‡ž×2]*=;Oªº²dر¿™=䌙5Ž=ÃþÕЬ6BN@ŸIšðÒR¬Yò¥ðˆÿÈX]nb¹ Éö³ï¡>§Ÿ§½Ä¶S•jo­¤~Dt®-òyB.Ä—3E±5p0ÆŠê6ÂE4ÍO~íIñ#¸Mçë«êȦ°Ÿ YðÌQÈS€bú 1¸¼7Ó+\DhÖÈaÉËwÖiÅg*,w‘ÒÑ#e5zžECsÕR}z 0eBû[ņk+3ÁÏBYª¼¾„;ñ`#RÃRØ3Я¢=äÝ,_Çž|”VÂÖ7ó™èÍ’LÉi´ç<ˆÜÿÄïùÎYdµ-I˲|’žð)Àeà¬úD¨ùÅØÃc¨ÿ€³zØ’jåc5sß+ çi\6ž9Èœ0°µ+°5¬#úI8³€< +xG  P¡ÇÀ¾n Ù_Ô@´Çþ%Ë©ÄÖ{Û”ª+MÀ®™ÐöÅV®ÿ¹3×öåfCï³íÈÓлôeù¶·«á"Œ¬V7ð¿ã"œà°wåí£éü<²Oü-Â>¡/šL½ìÃ6©®†TæÁäèa)¨ï™¿A2z¨C M«>¹’ª´W=ÜëÒÊú”ujÝÄa âä‘”°5|úŸJ,³_f—Zl©õÏ[kß L +õí†ÏVHðS@°X¾3!ÑS«í¹à8Kœ !œÄ¡ÂÿÆEt?pQzº ™'&½ÂEM‰d3èCfÖLD~\îš÷¯¸ˆ¢a\‹q„{`vcJc5PXÆH1$Ášú ù]³P;’€­#ôß)ÿ->7ì.¶Â~U®û»„îï…†÷VS¿?©t,?ðìS)) öŸ°~UòC“]Ãb«™<gxPSÓ ¤ÃùÞ‡»Hr§¨…øƒæ>¾>:oO_«ûÍPç`õ0j?>¾Ê~hÑý®‚nÏÝîíûuÀ«¢×jæë„#¾è›a ¿90É΢~e1ýB íÏ^ êr =k`199âj^HYâºägÿ ãù_ÜØšZ\6p>n +÷7ÇAtÀ3¢þ‡<5á"ܧ¯“f4ËÁü5õ'¦ŽÄý¦} +úg…k¥D±øÄml–-–L~ˆr‹Æ·Ö+-ïm#¿ˆœ½Nà»o®ÝÞ€<Џ§ð ±·Ö K‘™Lû¨EmNØG%鯯k«¥Á¯Ý!Ñ¿=SóååÝó”Þ{ûµÁ'uà[¡ÿû}\ÛýM„‹`ëDª8»€ký€pBË› Áêgœ·ððö×y+±æ@&!ˆ>!³KÚfÃB¸ˆ‚a\„ú¯¸ˆ¸W¸ˆ$k! Ü‚W"Ì)ßÅž0‹óBË­ÒñO6K,爛AåÙEð#Tsf¤–\X(v»GøÑïù“3úÒJᙹrvû4aèû}@±QÍ YlÔK8Æ>£™P<ŽÎE¤7LD]ŽþjuÔ¿À{"ÿCM M©Å–Î +{Ÿžš>_/å Lç¢Km!ñÎ'Öƒ}êÕps×½>:gW›«ŸÎGŠ ýPäB×â…´9zXh¢xkª'j¯¯Á™/بp0ÉZbµ4Þ»Ú}ÇUlüp½ÊbõÞÓkhÿg9ò éÚëÄu=Ø.õ}ëF¸ˆº«Ë`3Ü︈´ßp‰#5ÂEœ_¹}5±|Àbíaþ÷Jhÿd›ÜqÏEê¾ã"t¹ ÷½g¡ñÃ5Ø»Q€¾.9¿€kÿz+ßðÑ*±ìê¡öíe䣪ÞX ¥Xyfr:Êͱ|(…¢ÁyÒ‰;Û¤öû»PóÇQ7`¿u­äò8·ÇlB>vk“Òõh¿xòíòÃ@íÜsY¨¹¹THoŸ$$ÕÛs Uv؃0ÅYú‰f~ÌNQƒˆ,`ëeüšÌÖ7zQØ/òqçuø9B®°¼P«¸²ÂT20Ÿò™C•ãq^ˆ ¥ãK¹îƒµtž{v@þ¶× ì&Pª¸?܉׋Mo­.BM?N=ôpæÈT|b¶VÖ;_«¾ºg:†sš®Ô{G(¹|<õسME=N= Èç&–Œ¥=ž´r{ôÁÑ[ÑZìUN|¶}¸fgñ;ç;..ÑJûæ£gOèIÚ‡®²GxG©öôbñÌ#/ùÖƒ`Ó;‘À;z¸zꀦ³l=_ìÑúyËݹÎ6Þ8íæO6@62Ö´ôËÐÿF\°š-£Þû¢Ü V›²<\=û„ç¾q.ˆr±¸wÖðþDß þБqÀ¨‹ï,!\Dzͪ£ª¡ç¥µÍ"\Dñ0.B9öæ !HNŸåþZ« +ºÍÆêT’fß—ºî;K=öR}ÒýÌ{&@úyÇ7þoÈ»é¿#ïzØ‹s?ÞzaXVœÎtÌRp®²é-ww)=O]…úVã:ÀvhOØ쥢FG/ ñÕHÊùG|à÷bµ7ëOÿ䌵 yw…˜Ö9 ²ø¨5Q/Ñ>ð¡šqä‹ó:f@f]èyá{wgù ûOBêßYœWc²mMˆ#À‹F&€×ªé\±RÔ8¤’±w„³e8óÃ⢠™åÊkKµüþÙØBþKˆ6ìQb…ÝKœƒÏA~´ž_4–zýsF)IM¬Ž>3O©»±þ0 À•g'Æê×ê«$ã Û•Ò+©¯Ž¾‰©ýëý@×Ë9íÓP“ …ó>þ©u“âóǪ™UŽ$ÿÞ÷–z¶Çtý‹€ÿ.^~aÄ>•—»Q‡ØDõz;À;Ö¼±ÈZ¡÷›½@p +]OvJMnP_Z¬” Í%Ü.öü3'¡G'Æ¡=ØÁEð¬~¥}¡âŽY@›£ž0¶~±È9>ºÈ†‹*³e62],¹8¨hÂε³ZåøLù.qçñê.,ŽßZ˜­•œœÜïU•jÚŠÁbûç;ÕŽûû”Îû{„¾¯~GÞ ¯w§ŸùýŸÈ»ÇÎ@Þá&­1ô˜-’t|͙ń…bñç'"„RÉÙ¹8#´ ”Õ<‰ì¿æírv×4Øüj3±ÿ¹«Tuf!á‹ÏÎJšO;êÀg7ND¯ga„Œ£ !IVØ3“Y,G¥ô=õY®ˆÞ'‡™ã<,ò>Â9²8Ô°ÇègJ‘,÷@?6™4|VzàÀ‚¹¾œúÌ_—*ç4Ÿù@‚œÕtFg«¯.Ž€Îa¿û(R¬°O…ý=ì ¡G³ +jQ—+Ú{pÀˆU°<*µv‚8‚ÎȰxˆº†$ÌáCP3â#»u°pèÕjÍ3ÔÊ3Kp¾WÞ93lµï;ШÆþowÒ…˜¢Ñ8cˆ3*Ôwl»·=ÈÓ“oGMŒõUvv!ùƒßG=[¬«=pv%ïÄtZ«@NÖ_[„²RØ3üž +úf‹ —Wp½vpm_lŸ›/¤ˆ3è"öÿ„rzwa…²ë'AVŸ~7P;èÏT^ZÌŸ¸½ž;öîjê›/{Ø}dBPV]YT¸Vqv éÃ9pœ]ÄÚ)¿0Ÿïûq<ø‹—\re!¯Z yYùÉù¬fX Ä Ié󺂭ÅõÈ_hm`5%êîÌã“ðAgúX~ƒ\xœÜöiØ÷ÄžŸ–Aq÷XˆJIg[sº¦cµŸ,ò1G!¾l °Þ¨“€å"X.?ä$ùlò9»w:ÅæØÂ1´¯EYP“i«²xHRñt^¢ˆú½ôwP·¢—Z~~!Õ5W—Ö¤çÀÙý?Œ³V,΢¾f‡Ù‡Z{mµRuu9î-ö¬±WOX ô1±‰~!Îø¢Ï_48‡úBØ3e¾—öòÑÃÂóXž!¥–'? +|öša£u×WJýtìs÷Ì%tüuýuJÕըã†û‰­³€ˆO~çÎõ>Û ¼£œ\k/ÆæØâ5³èŒzx¾ ΢ fô>Sk‰Þ’Á?Ö=c.&dž K·b)¿{†XÿÁáø—±€&cu½¹ùXäÅ8›Kx:ì—eqö çR¤ºwW_ƒ£SSé5ã RõÍBóÝÀÊR=Ï|+ìçDý‹ºæR]ŠüHV+‡¯-Åžâp?``pYjåµåRÓG(gE–Þ8‰>èœÜ•¥”¡/Ìâ%ù…üΙ°©þݵÀtQÿ’Ù=»®‹€r¸àÇ„¦kh×»ºo>õ±'„}GôŒKºgQþÄâßýåáÄ­õ´o[j öù•#—W¢Ÿ&6¼»¸UÂÕ·|´Ð~MWWÁ/ó­ÌOS¬c1ðð‹ÙgSN PB•Sìü~¿±ÿéN±lp6~ýCcçómØ“ê>Zú…k{°Y|á- þ¸Ÿïx²ìþÈuàà6ðw·²˜µ~û¨¬>^‡ž·RrjübŽZñÆR©áúJêA}æ‰/ß~w‹pxpa Ð«Šˆ±¢x¼Kï»ùžw‰ _¬Çu„ÄV±áãµBêQ1³c²Tzf®ÐóÍn¥ÿ™ÐéÔoÄ\jìy"F¿ pÀ û€âÁ"šUÉ?;GÍí›…3d„¾g’áƒk¯²<âíU”sžu’ŠÎÍ«¯.掱¿‹œ5½Å‘KjÏgwN +NÏâšï¬åÎüu¿pîoÙì5^ýOoþ½óç?øËáÚ¯’pê¯ÜÐ_÷ðƒÚ+]ø£A½ù,L{ïq¼úþÓñÍïU±ÿGWéħ[ýË:盢3mÑ— ³«ìšÉÖéB¹öíUR÷SÓ©Ç|àÉ»ÊÞ»\`ϽÒòÉNB'q0å´Ó5F]Éw<܆þŒòÿ°ö`q%ë¾w!î$!î:÷Á]ºéîem8QbÜ“àÚHã’`1 ¸"ÁÝÝ->’Ù³×­Z™ùξçžïÜ}žçv?kºé†Ìªª·^©µê÷yµÝ—'5A²@LÍ s{*³Ï€ÌÖ'ÓF5Éä5tÝHʈñsiÊ’ Mí8†ÅV3ëÒTÈÓÈ⽚ȷI*HIè ;úÝÿ‰YKeîÍÛ‚üz¥|ïn ÂŸï ¢+÷c·úÔð´5"£CGÕÁâg´ H,¹õ(:G´~ƒÎK¨WBv‚ìOíUA÷ŽÙÃzäýN’‘&óû0nÚÈ1^|·–õM‹|1d"(ë»H•öÛ_t'u“üûð€¿+Êk2¡r;x‚Üøwݘ  Ý”z4@âaU»ð°òXlÛANÖ'e¢p€½h:-*l´@¹Œ(§ #2†uy™Ýª¨VB2Iè^2ºì0¡Nƒÿ¨›OåñHi½Ò ÒÌdr—Oò~'~þæ,TwÉÊ&ë-Mò­ˆ[_´ˆÐÒH"Wàÿr;#ϖТÌ\Óºùt+ŠÇÌz§ÕÕɨ¤ÂËö£Êä!ÑU~϶¡û_Äi-lAÚ.Zƒ"¯?Üë§Å„{æ +Â3{æS¸–ײ‹ýÖä½øÎÃß|a¥¿™Å_­y•ÿ0çÖÒD÷g'þPß ²ë£ Q7|ž*=ƒúN\[í)¬kr῱&ž ˆcBá«Ö3âçÍ6&ùâ[MQ|ƒ¦(©E‡LéЀ¾ç0W<ôùV2©[Ex»ÓØôv .HêÑ<ߎjESÏ„µ"ç%¦}ç›xelàG kǯ)'$ñ‰®Ó¡øHÞíe‘÷ÆŒ©‚Š*èâS/zÍÏ[Žó_÷X îôâx渞Øz˜wk@…ºÛË¡ò{HŽ!–?ÎÂò¾‘÷>ãyãÆT^/Aär©']ÁÃN¡¨°ÉÒôuÅEÁãzS2½W‹—Ò|KT…‡ +²92ôÝNd—ÈÆˆÛZü[Ýzèz-?«Ù¦‘8» ߫㓷š´ðÔäû¨4èÿ’:”Ñ5 ,­OËVãæLhÙ£ºÄ½AC,wÜ¿ÿÁÏýÀ"ŸŽ‰©#Ð Qø«"êíð A္àlc^Î/l wšS»„Dþ­1s}1ä|1ž}"¨¢Çy¥šb¯¾ðùÕÝ—…ÕõN¦oËíLŸ—ŸåÕ‹ÉìNC2sXQ´Å&®ÀüýAÄ/Q©cZôæw*L©¤u޹œ±ÅåIHž] 5).u¿¬µä™ð FÄÂû½QV7.Ên%øiz‚Ì!#*cHòú3’»¢næo"$û‰Ñˆ¢}(Ü€ó<¬bŸ ½WOÖ§K¤©s³>«òâÇqÒ¿åd}Wf—Ò§ƒ>ÍþãŠp¬9ˆ?6pkú|ïüì@Ž~ð"F¿zˆ&*B,‡JNõ܋޷ †úÄý­!¦5’=¯D-õ>°…Ä»/æü¢¡SŠÖkâ7my]"qn“©Yaù›"³'ç…ÅXægM^b·ÿÎW\Øt‚º?‚áÒÆChý­ó3»Œ b‹o7òÌÔ[™Ük£z“HëÕ¤-Üê×&r»8‚SÁëæS¢×m6¼¼ß °'ŸyÄó11¿´ç<¿hðùbDL<¥ø/{-¨âžSdÑG+¢tì8Y5tž¬±%ß:‰—ün…¿ûjÂ{ó™—|4#kmE=Õ7E½•~‚ú'òeŸ‘7Ì#²&t±äž£Ø­h>û êq¯PXØaF=l£È¬n},£_ŸÙÍ?©;Žì[ü¼æ4?·‹$ wú ù¹=„ðQ»ÿE~ï‹–÷Áºßƒá½\ìÉ Ž¿E_¬¨ò![ª¦ÿ"Y9xެë»DÖ÷_À_ ÉÂAÅ&üÕˆØÇÞŒòø;ùDq‡%ÙÚu™?Ðák2V!œh æuÒ¶œ&ÚoûdG¶ö_#ßXá9u‰pCc£º ]Ód|9ÌKQ|@ëUœðÆmœ;ªó úE¢ÒZ{맯íEñÍZdÈ“­Üûß´±_õyo>‘سq‚›õ«*/vd?7ñ«’ yBWœÙ…™å7œ—–]5©.ó0¯,õ2-ªr¾j:#zÐ!dõ3¹ÊímT§0ÎQécº0'Ü/tº½‚×t€Wø «øjAŒ|r~¬ NTñ?öùS¿ úñ?¶ùS_Foã£ÞÂñêSÝY’siѾµAq5×cOô߯ÇsŽv„ï{$5ª”‡»‚D½Ds¿=ìO[òÝ„5õfŠ—ùM KW½n·5-©q?í:Å;|œx4“Ï…ÂÊvÓ®Š`au§ÿ]§ ¢û¢¨¬þª¨ªÁÅ´¡øº ²ó²èM³­à}³­°¨ýõ¦ßšx7`.|Ý +í±ÎFT\u^XRú<ã[ƒJÜ€G8ҦݜÜjržÓÆxÙèqAO«¯x°&T<Ú*l¿Éí¼)j$ºû¹Uÿ0ãVýaŠUýbÍ«û|’èûàÄŸhó}l³|+üØLÔõ] Þ ‰É»#,,üýN"ôí<ªy?~çƒ>úLð²ÍÚäM­øu­¸ ÎJ”×f"~Ô`a’×`F>éRÏúÄØ‹AŠzÓe-(n;'|ÝrVø¬û¤ài¯–÷Í{<Î!aü¥Þt[ ëêœÍîâŽú›fƒe‘§úòmºï$žxg5ú&V0Þè'ìªóT79oGM©ÊîóTg£»éÐûHË‘×1§{î'Øv¦Å]nMŒ³kŽ‹¾Ðž,=Ým2^JN {óš~9Ãyü»!Zÿ^ S¸e¬ÂSú”‰ìq=êö˜òm(vñÜ_®b§|ØO–Lœ0í}jÑS$1k. °êcÙÿ6†ßÐáÈ+ûffôˆVåú¼\˱tœl¨gÂZVàzo° Å¢ÿm´Mσ¤Ëíéé'»'š´Vø¡¸F=èÄÙíÆ‚ØOï*íL[ŠüÅoë.Rw:Ø¢]äg¨ÞvÏ3=Y±Ðæb*}¢ý«b Z åG™L‡‹>–†Z ?–8µH›Ìªrʯr‹J¯ôжíL‰A»µ,ˆ:Ùs?V4V"ë ´xM¶_åÒxÖ7m^âàaÒûÙFâögÓçM—DÏúObh`!•Û9‘ Ûy/¿’âîëþ—q'zŸÅ›Œ4Dð»Ú<…­7͇ʣD dE¿ ¯ä£ ÷éïlÞ‹!œ,ï>CÖu_æ5}=A¶¸£1±x-h¬v2.øU›u«q;süÑÃïÊFE´>§ã÷S6]ÒÔZÏØ„:¯¸À¦› ^M!‰—:S­ÅŠ>×… ?uó?ö +¾vZ=ŽºØžª;'Úlôi·ñû vîïêäÝÏ,aA7ŒóãÚ|¿Ç?S¡e{PîJf é31÷a—ˆæwº0“Œž(¹GJ¨;†Ç”ïdz?h ßtÛ˜ÔU{Šªë\ùφÍx™¿ªñ"+v`!¥Û8’ÊØó LÔ\íu¢ïEÂñÁ—ñâþê A_“¯ÉDu¤]{b¢OsP’wsPbrƒ‡Ô·9(UÔUqƒhé¹d6V.ñh K¹Ñz3&¢Í3&£ÁM’Õäq¯Î5¶7êF­t`¥T`ÝÍè+­±1æÃ#©áao¢jìùrÜLô¢íŒèM›­¨´Ñ^ø¢í$•ßIPw;Úý¹ôUêËÀ ›Îœø ·“m;³“l:ï'‹úý‰ŠO§9Uÿñš¾ŸÄêÿ<ÅzO³ _ÓZ¬´Á}ìÛ”åÝvæÃÑ–C¯£É®a'²bà,YÕ{æÏ'…·:ØdNŸàQ“˜_^{Á´íÿÉžÜ8ËÞgQ§z%^îHKwl—H}¢œ[C"ƒë}#3jÝ%¹ÍΑEÍaÕíö!e ×ÂKêëšBëB«áϵõW몜" +«]"3ª=¢‚«ý¤¶mi±&coCãMƒÏ$XËç¹ÏhþèŸ\2÷+—|<"<é7çg`“)_4…Ùùð+Á¯î·tóº|©>oÑXs˜ðcm1>ìÉÿÔë/« +7©—]ÎÜ—¿q±}˜ ¸éŒ¸£ò†h¬!Ôtì½Ä³)$9°õfê¥ÎÌÛ–/£E#e~VC/cO æÅ¼sµ+26´Ñ;:¿ÁYRÖ|5¼¤Í!ìm»CX)|-j¹VÔ|5ìEƒSdœw©õÑé5ÑɵžÑ¾õ±âÅ!¬jšÏ¯ÚÂͦUùÇÂÂ1sÑÃA aiçÓª +/Ó¶² ³ÞŠHÁûöó¼¬quìÖ¨º0«ƒ'|Òc%*m·–À˜üæ³…¨©Ù'°. Õ­Q’jÖ]&áuŸÆîþ¦ÇMl=ÀËþ¬E>ð;Ú=/·'§œé¾Ÿd:R}aQŒéhE¤ðKk¨åPAôµŽèÄ„fwil³W¢mWf²h¬2”êoñ8ÙŸïÕ”àÝ kv—ÜkpŽ@G^½säS8Nojœ$¯+ܤ/*\£óª\%Òjï¨S½9Q‚]üÞ_qcÃu~q°ªÙAPÙæ ¬mtBsCRqÚu@´­ŒWm˜Ô½!LšTáXH »¿£¹œvúÔ èŸ‚küâ¥e¾1éeÞÑÎ-Qо’’Âên&‚ç†O¸¾§ YïhC^ç·óèß¶iÏM mÊ j αí¾Ëz  †j«½Æ¯­¹äÕ–Æ oê#ï5ºD¦×ºGæ79E–µ9„§¶¹ÄÊ‹Åò`Ó'GÿiÃùFÛcß>º™Ž= qiˆ”Öߌ¯òŠÊ(óŽrªŠ9ßšu¡5%æTg–D<\b1ôB"nõµ‰:»ýùO~±Äïý©Ïù‹•EGuÔ…ŽÌÔsY ÇûòbÍG^EY¿ˆá轉 ÿz•ò|m>Þÿ Úbô‰Ä¸—>mÜ9qœèkt<ÞÿPêÑ™mÒRtõ–Ö7ÊüºÏ(àÙ*£«IóY.I Œ’;v×þ.ÀG\NdKÃÚ½¤qžÑÖƒ÷%ƿҗ hƒaZ¨?F‹ôGi¾ÞMNÐÆ_è ÆßéËÔ×ê[ƒöù³«a-4ˆêØÄ~Dkãï¿[ ++:¯™66øêÊOtiŒJ‰ª½‘˜Qã)½Ö.M Õò[ÛÝ©–^GAK½‡h¤-äBÛ­$·†ÈÄkõÒ„{%^ÑOÞ»E:´ÆAŸýR*«°*‰±,ˆµëLJ hñOuoŠH<Ó“Kþ6xèïwáµCßYa=TkÓ“g×)•ƶzJ}[ø;ýñÁONxÿWGN3maTFé?œ8d&]¬’³\·‚Vå |;+ø¥>øF]@lZ…§Æ=ɽ2O‰ou`¤MÇ­Hëþ»‘䨏7Õ:||ûÑ +ÆñãT{¿ëÉÞ¼xïÆàÄüRwÉ›JçÈ‚RèÜ÷ðo=$Ïß»IÒ˽c¬`Œ-‹@ñÕ¿.@ú¼ÜUR\áž}VUýÕЉûàð(ƒ¾Î»% –÷û7Ý.šcü¾||à~ôí6ר²Ž+aÏÚ%mŽQ!¾É‚o5A‚oõ(šM”J¸c¿Ú鿤UŒœCæhŸ°•Ó0½${”+ÕôÀ^¥c`ÿ!5°{¿*ع÷(ض_ìÜÏʘ‹Œ¦Ó³yš™ÿØ¢ÕBkáŸ{Ý\«Ã#Óß܈¾÷Î;*¢Ä?ZZäVâ- +Œ¹s‡sí™RþȰŸÉ`]ĉž<)Ì‹âêýRßûJÓ+=£s`ÞSë#Ey·ýÏÓ&ŠÂÓëÜ£ß@ÿö¢Ý!<·Û!,·×!‚úÞvÓ0çã>–ƒd®º¾ü¼|5X;iXå@,…Çjøþ§©KÁŽ¥€ššè +dµÅžrJG°qÞr° ,¿µÌ’[æÊ.‹'­˧n«¶ƒµË÷‚-[”Á>¶-P»Y·Pç}ذæóþ¸Œ¿§-ùï?Ùšö—K²Þ{Ç–¼w‰x_áQ\íþ¼Ü%2©Ö3&¦ÚWz£>0ѳ>4!é½oìfL=%qå×c#*oĘ<—`ý¿\!FG<œÚÃc›:®„¶vÙ‡À9}õÔk£Y:9¿l×q¹;_ïê­¹†®ù‹ôƒÊWëå|Þ©[ðç>½Ç´’^lËFÎI°~õ°vñ:°zÑz؆…`˜f‚i`:<æÀŸÁ°Zn!X¯°ì8` Ž™†Ë©\y9S5~b…V­ÍþLŸåüB_5{* à·Ox :†|…C½'ûîÇ^oŠ‹ï•Vì-¹Sê%~1*£Ä'úi…«ä]¥sÄí +Ï(è%/KÝ$ïJÜ"J*]"Rk<££ê|ã:;í‚èAÛ°Ï=W“~½x¦?%Âè7ú´F)½OÝûÂQáU™]Jê`ÓÆÕ`ë¶Í@Ó켬®Oö"=¯Œš'¯ÉmXµÌ³ÁT0ȃIÌS¶K>e€ì_?O‚ŸÌ„­žk2üIŽùl&|®œµìÜ-‡ñY\úgþh™—äu Dú2 JRì'‰)ö‹Š)¿%-¹^âu»Ø;*¿È3êU±»¤°Ø=òé[È<87s+Ü%ÊÜ¢ÞW;EܬŒ§¾ôûñ?µúa¿|ô°ïЉ}Û cp·}XL‡[ŒÎ mtÔäؼd3´ÃùðüѹMg%Ë´Í x 3•ÿñ@ßÿç‡,Óô›¨f)2óàël0Yv6üi!X5!qÈ6Ÿ”ºFæ•»I¤>Q§{2£ø¿tR¿µû»¶‡Ä5ô]‰èt‹dýFÛhD¿[¾ç¨X=s!lÃTæü'Ã3DïgÁ6-€7¾CïeþÖüç‡ Óºm· |¢±›ÿ½…p.þ|ì Pñï^¨yþÉhœ>AõûŠ{ëƒ-º^Fžìʉ¾Ò$•:4GǾ} sYh“h ¥¥7¢Ñ8¼õŽ~SâÆŒò¥O‹Ý£Ú*\cúkœ#…*à¿gmÐOSìQú ÷}U·’ÖR2²óàý¿~ 6ÊþÕ#è¿òõÙ¢)ÀÚµF`»ÖpÌ£aŽæ ­ƒ¬q¼\•’ðÆ?:÷wÌób÷ègEž±ÏÊÜ╻ż.öˆ)}ãó¶È#*´ÜOâQRí\{#:£Ö]µ.’{Õn‘IÕÞÑœ/ôe­·ô~Mß T­¯ÉîØ¾,–ÃØà4æ,þw›“eú_ޱSôúŸÛðÃ'Ãï§0sïÇ<”aޣϦÂç èUgÅ`žüz°LQl>|ì7K“Õj¥µ°O.fCO‚rÊ<"ƒ+ü£ÏteD¡zض-5åe¨®„¹W”|½Ös²'G‚>Ï©t¬…9{k“Cø\×!,±ÙCj1Z ù…PõJØ”Kÿÿöý$xük[ÿþ µWî¯ï~´{2Ó3ÓaM‡Ï9ÌìýáQø ¹¿Ú:™‹æî?: ”N=׺Goã ÑV]Ã.Ô§ÇHÞßdìð\[jTS‘gBe‰{L ÃÖ2÷„ŽRÏäŽJ·„¦—˜·ïÝc }F?+ñˆN(óÖŸ E»”E`á,fnýW~áúø»ÿÕµiÚ_c:>§2ퟟ0&Îß Ölâ-*ö`0Qæh½ÂðmmÕvÿFÒ+¿è¯}b^¿ó”¾/öH¨)öL©®pKzYâ!-,qJ)ñ‘¸ÔFF¡Ã³.8 +ÆwIL½—ÄrðA¨^5­ÿó¦Ýÿãvüð†rÌ9Ëý˘ÊüõÝtøí øœ'³,”[æÈ,‚ã¤}Ò2ãWù `Τõ`¶Ü:0oÚV°x‘øIÙ(x'¯ZLï FŠ]aÞ"ñÅ„(÷Ú°á‡ê@“ñ×Ág:nI ‰z}e + #È× œü6ô­%Î’ÎŽ+‘÷`ÍéÐmø¶ÒJëÛxXOËÍþ¿Œ ø?|%úùïxæé,è•P›§n‹gïK(% +âÂ`Ñü}`Á¬`Á”`þŒí`>z?}X4þÞ"U°~·%8`’%§‘CofõÓ'­ÛÙ4ÜC¹Yþ+Ÿ¨ûºK½Ò;‹}nõ–{¤Ž”{ß®ñ¸5Vïž>ÒäšÒYïœP]횈ê.µZzÿ¹ÿ7þño?ˆÚ‡ò4^Šò«Á¼IŠð§9pQä‡ñSvô%«ÀÂI›Â”­@aÚ6°`æn°x¹X³æ~Zn`7•,³Ÿ*{8phžágÚ‚?ôÎUúÆ?êá‹ëqåEÒšwim©GBm•«´¼ÄMZZê.Í/w*†þôM¹k4ú<ºÒG¢ÞC«þ´CõÜ–¿ý&òÓÏ>å¯÷S?2í¯÷sá8*ʯKá8-SØ –/Ú –,?–mÐ+Ö±Á’u\°d=(.Ó ×è‚å›H°M? v隥òžÞ!ì{åñ*8ŠÉ[JoF=-q—ÀÜ,:¶Â[óÌT{äÃüæb••.QÍ¥nQ¥e®Q°ƒ¯´ù¡Ó!²ëö(ÁØ:÷ßnò“SÏ0‰yÿÃþ˜ƒÓ™ldX(»,™¾,™·,[| lØ&›žk÷ZÃã4Xö“,[‹ƒÅ1°x ,TÔK—ê0ßíàÄ€#®Í³4ûhm£QÚÊ¢=ÿºmmjP‹€¨ª—Þq­ï¼*Š=`Œ—¾+s‘ôU¹ÆŽ×9ÇŽ59JÇ››ª\PNª÷­Ûgü?3tþs˜mÎ_Ù㘇æÞïfÁoçE“—€e36€%3Šó·Cß¼,š· οC`Éü#@QáX pŒiÛòͦ`ù:!X»ÃlÑó{-óå… ÎS) 7«UÐû>ÐÇ·dû¡ôåkoic±Gl+§Æj稞j×x4çz›]Òz\SzZ’ßW»ÂZÂ/\½™>ºágÝÿ±mþh+`Æųù²KÀ|9X!Áy¥çܹUð³U`6Ã9ðP˜²,œ¹¶m7X´d?´OUh“F`énS°b¿-X£æ6€-T<Ø‚']Ïe„þºP¹šÞEŒT\±/Iõ.ˆð/ Ь„¹WlÛãJ×è§0ÆUW¸D÷T»ÄÖºH{ꜥE¥n1—ã#5ßÓ‡—ÌYúoÛßó ù{©È)ÅÉk`›–B{\?Ÿ#öìßÉ.ŠÓ6CÇnÆè7÷‚e‹ŽUk1°nÏi°ñ˜X¯å6¨»ƒUÊWÁ +Ík`¥¦#ØÌ‰;MnÉò랣òŒÞ£OðK]/V$yE†¿x|3±á¥OrË;Ÿô¢"÷hT3„ÔøI/·ÇKK`ÐZãĬC +>¼¹®’KoX²dÇ¿Ë'1¹ÊaôšcÙŒÕÐ÷¯Š“ÖB?¿ +ZäBÆ6àsì"ؾ5`ñŒu@aÆèá1÷'°hôÿëôÀêmf`õvk°f×°þ¨Xo Öè‚mÖdø6Ï8ö€^«ÞF«À<ØFÔûÊç\cZHØÛ ¨¯¼%uo=¢[aÛªŠÜ"žW9Gö5\ ûØì?Öé˜\Ó蜘Tåiü}Èn›Àáÿ:f?ràÿøùo_ò#žGkœk à.aŽr+âœÌX)®P‡6¨–B;\¹[Vî$¡O1ËÖëÅ¥ª@qPÜi +V)Á9gvŸÎ“ÛÚ6K)›^¢\GïV­£°¿üqƺ=û¦_Y@D|ñõhè;cßÂ\ÚhLgƒKÂ@“sÒH‹sò§§¤¡z·”þ:´–$Ñí¢YëVü·ÆMî_üãÿ1¶f3·€Õ+UÁšÕº°*`É*uè+”Á¢ÅÐ,>}&œgp®-_r,[z ¬PTËײÀŠMX»û$جé¶óRÀŽ…²»=k¦î +뜮ô”^y$íûRµz·ö Íâ}êt4éyìëó.""äu°¤¶È'½¬Ä-æÙ;Ïhnõ7sÖKZÏø¬/J¾™S½ÝžÆý´V}LåF™‚⬵ÿm»~ĶiLvˆ¼ät&ËBz)˜ÇiÑœ­`ŒÇvYƒŸ´À†`ÃX»ê(Xýå²ùÛàbÞ°|éA˜S²Àš­X³S6ª^Û‚ÀvB +öžx!·;¬æÁ'ôRÕ1ZY½V3š ­Y#ôijxÔçxçýp›–ÌËG‘6íYÒÔ·7¤IïnJÏvd'˜ WD¹7G¦ÖÔ\ ­»_á¥3Jã» Îÿ·m›Ì´g›çEÆÌ`rþÌ+ÊA¿\ ¿æ Ëá|Tóåѱ,˜½ ,Y£Ö)Ãüøü«IGÃF½C¯R~AoFù¤òSzÓ‘ä,Q’Œ( œwȽfæ¡+O§õ¯§ZHoÑh¦U?ÒØésüÏe¾f£OB.´ÇKP=‡jr”k>Eµk‰{ôËr—Èê*§ˆŽJç¨ñ:·¤¦J×8ìs‡³º[¥òÈ¿ÿ;¶9í¯XŽìeÆŠS–å󶃵?ëƒmÚçÁfü*Ød¶:NÚæ÷~ònÿÊi{¼ßOÝqåÙ¤.¯å÷ùÖLßÐ9sŸ_ëÌ}.åS÷;MQò®›¥ö”Þ¦ÖLQ¾G¯S î\¤žCoÒn¦µõ[ižA-0è ùÜ úŠ}cl$ÊYP»²`îìVË"Ø@×P ž†èn/øÌcy?XªÌ·—Y·éèc—²Ì˜!¿¾PæÃ‹UÀ¢Uš@q3lR;¶c¾`+vì„=§ïÈnš}$›^¡üŽO=½O­ž>„üßáÀ–yûOfÊ퀽â(™C6wäºWÏ>æ×¥ ûe¹ÆSz7ÌOtô¡M9ß'ì¨Ïe^úC4_'°j…ATÇfvhÙf<ÿ6¿jè’àå×øƒ?ŒxéÿP¥rþi,xüÍŒzþÉŒ_0"?m<),îw2*£U„r äþû¸‡ÖCÐL›?u Ìõwƒ•«9`ÍϦ`Ý3`£ÖU°ã¶ê\Ûž?ïÅÁ¦­š`óf-°u?ìÇe^z:åе²éji®Õj ÕõZhcÃÚ ûüÍÕº÷^¸àSùuîׯ¼Oßõ»hJ'ó×­zɃ[õïÒ{ «i6«Š&8u´¯müÕÞìLõ5zX޼ˆ±|-øÐH4;p*i¯þû)j ÛÛ«!4±®úZ¨w]pŒzÒÄšµ«÷ÿv)‹ª6˜{ÀyÛ©0c=X¶l?ذÇìÖ¶0opw‡Ï$N:Q>O¹”þIë;ÍaÓŸ»c¿Ö9ÿóËEÞïW9t8ýNŸÒúF³´?Ñýo´Èà mI~ô6¤Mu‚Š—ëÛDNÓ¶žlPBëqkhK£œ?²Ýî,æ>¦‰þ1÷Ó=wãŽ÷çJ/µ§%ŸîÍM4bÒò´<þj—0§'ŸÙi÷i]Nœ±~Ëa¦Nû¯³á¸­T<6nãÂ<÷8`óVþ ïl¥ZÚÞAO4nð+mið¶ÒûF Õ:h%Õzæ­iø;}âjs¤$§Æ-RZç)qo ŽL¼ñDk(zÐö´ÞдÓ{ujh-VmƤÏóÆÿp~m ¦>÷Ý0|L«™œ–UÝsèii´ÝLj¥µ«ow o-ž ŸÇw+\Gdý®Ï/7Á3?i^÷×p3õ­ƒ¦lÝÍËf­ÿ?Ö‚þÃ6å`žs¬9›Áú}|°×$IöHpòŸ˜ùbÎþFÛ°¡m>ÒVúmÐ4Ó˜Q TÒ†ìVÚ‚7N;ÐgX54eôŠÖaKz¶±½óV°R‡örë~·"F‡Ý¹hN}Ú çýl¿‚Õœ„æ}xö'âÉÅ­Ú……½ÚŠ%¾ÞOä7 +Ë…¢š2'³Öâ@þ³3*iBƒŒ¨;@•î ;H³Ž7¢¡š V5Mî:Œÿ—íšýâ¹å`îÔ`þì5°ŽÞÖü¤v^ÎÜŸtàFíÌ#÷ÿ\©^O†ó‰¥ó†>ªãóJQÇ&uºû#Eƒ·´ÙQëxºïn¼x¢8„o÷âŽ\3*¡Y,ÿ(EÖ¹“X/Of¹ùÌ6ˆ.\gPFëñÛ}¨ö.göõ¼•º02w˜Ä¾ócØïº<ÛàÙ¡UXoi#£ÔþÝìˆçÙO¾ëà/zIìá¨1/÷7]Ì>VkrANߘ0ñ9†“„øûî)+ˆø¶Ãä¯Fâwíöâ’&{nÊÄaÞ¹3Œâæ\ˆšyÄðX³d/£å˜õt™¿ìRÌ•ƒqmñ°éʨD-U}EoUo¥éýJ‹yßûœð?z¼¨ßZýÍÆ_G¢kÔX—7ÑÐU:H. Ðýïœøê½ìgÿÔfÇ—ïà\ñŸöAób‹vcYcZDþ(—۸緘òI^)ôOÛHI«˜d¶âÒª«¦Õe>âWÍgù½B~N7ËÐÀ¤Uû¸÷Öê_Šš‰®·-˜4‹Y;ø×ËEs·€•?©ƒ­ú¶àˆíý)éŸu‡iÖ—'ÐÞ8M Ò|vmjøàJV.òº¦@G Œ9¦€ÂLeÍO;δðHÙÈ©:J>ÞfdÀÖ,Jë—#èØ²h©˜´h¯àmË)ây?Å)Þ…_ +˜ÃÜž3jÀÜ}Úeaá0±dùÉýšü”A-2üõn"uP]x¯ƒ"/ Ê:.`¿i`áo·qó¿èá%VDëˆk€¶Ôª£U•oVÍ?t<]îà‰¬IGNdÉ«žÎ™¢uåñMg +:Y_¶ãžè^·Æðlä‹“á#Z™;¸“þù ë­iœýý˜±}ܼ#GTÀŽÕKÁîeËOG˜Ÿ=?ÝúšËBKçëKÑ>1ãüÏšÄûž“º:gî“_8Üü_ô¸÷~Õä>ÚÈs˜…elÄsÛYÌ=š¯†-ŒsÿÐä¼Ùˆ_K_̳p™Ìµ°“ç¼ Ïì{Éd™>«=oRÔb½'9Ñ•;9O7°Ò&ö%ŽîÔs/\¤&t“Ý©"al^ú³2X«jöš‡Ë¨†4)jåÑÛ´ßÑÇ´‹àñúýÔáZ^÷´/EM7ò¸½È84{q`ê +väƒõ¬´æ½¬ìa%nðë-˜cêbÜ.Vºš´˜p¹³‚p¼»œ80KG]h98z0^qØ@(2“å‰Íd ϸeÜØ’]\iñnnBñ^<öÉ^»}Xƈ:ù¨‡Â_öò™û*oƯ!=’WàÙãÚ¢ç§Lªë<,jßšTU¸‰Š/sïLh¢}˜Sä–Ýz^™ µn¾^rÌÂWnëa ,œµ(L…õ¬C7ïdU·’¹š´†Þ0MâŸ?xâc¿ºqÞѤñ]Z•í·ÀøìK;ŸY¼ðç?áÞ)+ ˜Dœõ™‰˜‚†*š@kß`¤¬ øäif¯ÃŽóÌZg걘Ïâø½1ô„WürLZ½ .ÜLøçm"oäo¤wêYd6ˆ¨˜j%Ê)d!ÚƒAÞß„§õ«ñMGð°çÛyÔE9½„p¸1PÜQ`|ïOUžgÊ2n|õìùiÒQág:þ^B}kóç~§¯r~¥í`<;«ÛOcºôAÝ+9sUXæ@[xBÆ0¾m+Ù>t_ÓoO<ûJñ.ÅÌÓPÖlŽ`öhø½ØŒ<۬ǃ~Ç~ÚŒÔT©ÐBÎÒÎu¾õ%WóónsÅŽÁ‹ñ¤ÒÃè>_þÓVS¬°—ƒå|Òæd ã]O[ä¬#î÷³Ð}µ¼»_µ8±={xqàwÿ4àÄÔí¯%)bg¦Ž‘ ¹©m‡‰»ãXθ'©n'üÝVÚÐ~v!­ÅΧ5Œr¾2¸ûç~ƒ;ô^­bZI{Œ6Òû…jOІz­´A9­oô†Ö7® )ÖkZß äùjÃsn“,låŒÍÏÉééjƒC?­j=–À-í'“Üf"†&ÒAú"óK“¿ S—a°oq¿[kˆ_ÚF‘K€"yÎs&é³—Ò|Kî:JøÞ^M¸Å-!Ü£—ð /½®=c^õÊ5 ä]Ï]Ëu û/ðåfv ÍÁ&>» ¼H÷9}DËùÙŸsž…ö¢‘·[tMîU™}¸^©«ƒw«CÍ9,ðÎüÒÍÙØÕùDpÁOhÿ‰(µÍí= rÚY¢5Ç…í"QA‹9•1¦GÄ÷å%õ!Ó&4Ñ=Ÿ‚òæKœ¿iqÒz”°Ðg?ñ"žüÌ-øj`\òfXsª^ÚܨŸ6ƒãf¨û€ÞcÒºÞÀÂS^Y™´Ù"`$º"DZ‹š«©/G¨}ÐVÑ*[÷í£?´høçdµ´€ê5 «i¸,Ärfg›z¦®7óÎÞ‚ö‰<×£=ŽTvY^ý A~Ÿ›ýIç³÷¾½’—þA…'©Ø…ÙÇ(pÏÎäÝþCETÔy‰Ì!˜½.×Ñ~fìæÝµ˜gÂRÜ#e9Ï/o;¥e/;ﻺñ/ÊÆqÕ;Y·Æ÷e9dTsÙ2še\÷‘qÙ?HƒG¿fùÜ^Âr‹V`ßúz/Ã¥Ý{ØN± +¼k yöaóØ|+•ý‡À ›ÁÑûœwøIשh/bé‰ìý‹‹xµÏÔ»÷IË2ăò6áÎa 07ébŽsÒB¶_î*Vxù&–C†‚®øŠ¬vVF_è(ÇÂíd Ø–2<»èùœ‹a³U•ÀÚ) +`!¬›vÌ_ Ôku¥#ÀPŸÅpˆY銞·œ2©}ï!®¬v!^ˆØÿÔâ>¡XAï×ksƒ­ŠëÁϳVÁ×å@Ë€œ“×&sO]›llq~fue2W|y’Šš&8ýç±ýJŒv)`6aë6ƒcf-‹bÿœýt¡ÝõùŒfÔÉ«Ó(‹s“ø6öÓ+ŸÝÆæ¶ ‰¼cÌ7n9î4Ÿ›Þ¢DÜÔF\CâJà<¾s¨"‘Þ¢.zVnmQöÜãdÃÃÓWÕ—ˆÛcÚhåù`-!i:@=ÚB^O]‡¿ÙIçnyÂNögNtÅcǨùŒ¥ìÀ×븗¤óÔ5a½°÷08²_¨*éCŽ¥ ÚgÉ9ã;mïÆm`Ýô`ý,°uîrpæ(¿2qO^#Íßöä‰n>ÞFIëšøælᛞ›Äáñ)>=‰a"-ŒK>sž˨¨Ç{ˆ”÷Çx)u‡a.½ ?7®~/7ï“.•;ŒsowE: +Äÿ9Hw¾Kh9Œ%µ&oè0s=8w3qãÖ,¦zy¿Û˜xØÍCcK¼í7#‹»­ð§ƒŒ‰J˜WÖ +î¯i,ü´¬¶´TX€…8÷'ݧâBçâÎéK7 +·vÂ"NBßqV¿1ÚÂJ ÁÅÛѾ"{\ŸôËÛ„q†]ðžI¸§Âxž óÁèEÄUÉ\ð3–Ts˜HéT#îöë“÷úXxÖ&ÃÛ~0hD<â¢}¼”Ž#¼ÈWÛ89c*hªeÑ=ßÄË11÷ÖÄQNäûmœ´/‡Ñùã>sx眧ù›x™ãªØí 5ÄÍÄs7b~7ð$å;9iCJì»ß”¹öÒùÚFf`Ϧ`Û‚µàÀúàðÎÝ@CCè Û`~¬gL=#èh±€Ž°-ÎÉñ"æ#ö ò/h6b-"Ö‰[Èbè{0+YF?.æÝ~*µCOëTEÌnÌÖ}µž¼Óa$º_'@¶Kúe®£Ü¤K‹·™'(lñ º„Äýa–ùAËú¬ö„áq‡Pò=–à·×qÊ÷FŒùÏ{,¹÷Óæ½ÙÌ ªÞÊN9`œ:ªÄõ½»Šmé,ÏæŸ—ÕãYʰͯLÂlCgsN9M>´ëرr#8¼O h+@¿ÉH#±á…7îl%•k bkŽ!Ý5Ä¡C¼BO ŒY`ô0Ý"– ½þˆûÂ÷¿µí#…q`%á"Q$¼Wð’:ã÷&ô±œZxØ‹mäµ8EˆOÚÎgöä¹H—2ùMdé.†+P°‹zµx¾ðÍYƒû=XϽÝ Ë6"ò†ØØ­ÏêØüuˆ—Á_c'd9¦W'a§ýf#Ý>ô϶^3SkzUqöÿ?á1•tI^FúlÆbš÷#ûBÌ_˜W¬$.ÎÁÏûÍÆmܦcgœ¦"v$é}/¡í³9ìÉ6^rÕ!´·Æ?Qa½%¿ M$~]wŽÿ®åž7lÌ‹­ÜCÂØÏ y²íMDû׈w½œœ/ª\—$E¹<ÏôåÜ̯*Üì15”ï@ÛTãf}VC,0Þñ òhMƒ%´”e8-Òê=œ”æ¸kÚRcS‡IjGôÁ‘­‡€Æah—`ÄÅWh!˳‚µ¥­ÇLÜÖq:çø…IHƒ’a¼XÚËã‘ ¨€g[Óq]Åö‹„Ǧš¿:M@YÊŠŽ;L{¤­%ãª#Öbcà.±Š¸_ÖZ,­í‘Ò¤Bfué¡}®Tà͈'ˆ§µ« +î6q‰Ü7kD•sï“þt””´Ÿ¼ê8AÞdq³ÚTÈ™ëH·ÈÅXXþO¼ûºÌÞå§CB^Þ°îhÚ͵˜‡ÙGÎÇRÇŽñÒG•ñ¨ò½<ÿü ¸kâîõGkyWbTUÀí{ÖQ€t<‘Ö— _aìክdæ‡OÃè$ÎØOAÌTÆ.¡ß$#ò¶™½ÚXZõQ¾½÷\ÊÖqß;vù|úl;.ÿ¿ìšÜŒeÊ]ºŒ¸¶€òy°imàŽá HÇhE'I·Ø% S笯À\Üëö*Ò5v Ã’¼¹?ç8 ?ç5ƒáíø?Ù̼څÎÃŽ;MA¬yô7h>bTqO8NFû¤oò/ÜÂ|±·õšiŒYÊqM²gì¬ç Ê5iš/ÜœêÜûcÚXÆ–9®ÉK鬃´€>P—üçR7Ò×"6%啾 +öå"êJäÔÇÜ3ÎS¹&—'q,ÎÊ!Í<¾N iõ & 0û'*ìÅnÄÖA¼O†qíž¶ +±G–6Œܸ’=Ü´ö#p>*ÑOw‘Òâƒxbõaþ­F=Qv3—J¯Ñ&nÕkYÃ:øƒ#êY¯ ¿¡ÑQÜU n~ïöß›½v  +ÛÈç.Ñ‹áÜÝKÜ1@{qñ{ßõ¹.ÙK4µqpì€2àÙÌ$RÔÈÌ]ÄÃÜS—òü +Öóìbæ£\TK i¶šÄ·a¸‘¾Y=F+ç)üós­‡k’Eˆ)t•ŠuâÂòãüûM\Ä…!ÌÃÏ}ç"&:~gT›1¢ŠØfXlË4¾ˆE‡4 ˆ3°®<}6áž¼Œð„qÖ$ô„“du5dáµs‡õ‘]È<Â.t>q9lÿ¬çLü¼Ï,Æ`¤‹‹tCPáYYÒ!|Úߊ¥©bé=*ˆãAy&¯d´Š‚a#-?€ôÅ>ÒåEÚLˆ1DÚyÏA â^¯ÿq»P˜ß*¢î5sQ€˜Ñhí„aÜÝL^O^XO¸äínÄžAÚ 8¬“ðœq],gB››ÚuÍÄ0£þÌ·™”gü +”·`·‡4HŸûëî®1¬ePM†4€H¿ŒµÈFC;ë2͈#B>A1ßy§ì'óN»NÅ=rV¹­BÝÈßdĶšÇ´1`vò|¯„•ˆ#Ž8@ÄY÷H ñ Û본ÖvòÚú0$OÊÀ¾XØCˆéŠ›]˜„X2$ÃÏÎXǰTÐëì|¿ô üÀÜŸVŠî&,êõ.FSäV¿¶ðn3fñ°ø¤õãW—Ìò+­¨ô6]†GÇšzÔAKZmE=U7ÌzŠÂÐ^9Ä*>h$Ѿ|¤ÇÀ“¼ØÎƒ5/¡ò7mø(/ðå&Î)Ÿ©êªlpäçƒ@ÖˆéÄÄÍóÞ3 ±èœ,ÛüÒ$}–ô›€´p˜ŒØS–Òwz&qE ;í´× ÄŠBº%ˆ¡O:„-ÀOÙMAq[ô°Vlþ¨ò4þt'âÒ!¦&}»‡ÈçùŸ¹ìÛŸ•Ÿ¼uˆaOœ2âÅNÒ.LÁXh%ƒr=Ò÷Þ:gQ]Í5?; ±ý±‹7f!F v9x.÷¬+ô™ž3Hèëìýçóoòªt1︽¼¡!Œ< + N2£±í éX¡µG ±„`ú¡q·éPöžsø×ü—µ é "7ßïî&Ä«ƒ1Lõ#ëöZĺCºE 3Ê.hâ"Ö/­õÒ`´`‘žjä›=(ï¢ò»˜qÀ/xÌ䙞”ÃLÏüÐmDŒe+y uIû˜,¬1 }#a%CZ_‚bé"]‚ÛùÍa›Ø0Ò\K¦æ™±é)Y†³á™ºÅ”£±ù7?/ô‹`²ˆï¾ib¡xŽtXq§ihŒÍ?- sž¥ãdârÐ<â¸ã.ušáQˆ•ï¡HùÝ^ëveÄM$o5ë)µ*TÄã] ó.äá6¤Ù‰´û„wšxæ/ß]¶zõÂÁä^˜aCF¾Ýƒæ(Oún/Šåü—æü²®shŸªáÇ•05ƒ¾ì”aãcòrâBдV…;Æ.B5‚ÏBFåˆ8´é ÐT6Ë+ò\‘­œ.¬]ÕuØ0—†9¤à$£¿Íæ™É &7âO#~)bÿã—ä¹øqYÜü¢<ß!xpòˆÛ„GUìÝkæ‹îtü ‡[v¡wü*üN¿>ÿi· þüÊ8—ÖÂo<ÚÀĤOæ(]Œ¸$oÀæ¤;‹öÕ# 8ÎqÇÉÚº€ü"£SóÒ) Æt×éH›·:3 q1½Jh_ˆ Åâòa~zÿ´1;ï¹ä8—\ã–!=Ä.„ämc¸Ì0‡&Ímå^UpÁaЃmˆË…4«È“ç&#N)}ˆtïgÄ7ü¡oè:SxáÆ\¤×ô5ðÄ +%2­^åfˆÊèf»Å,CLAn›@ü¬á”àA ‰Ç•Dsi`°/‘n*b¦W#6¾3x–—å‘VeÁhl"Có’M™Ë`§&3ZBÞ)«‰‹¾³9¦0?þ± Xë1±Ü>L±Þ…žÙë½/ér¤ûÄhº¢öú±Ò‘VƤ·E\¼9‡¸¡Àh¸'­^¿¿™áI¡uÎÈÂü´:-aF[ܨEJžïFvɇºfŽâ9[tL®REõ  ³ÛKkW¦œã`?E,@š2¼Ä¶CXÖ'-Äœà&uÂod¯á»Æ/C禫¡ç ˆÓ>3°SîÓŒge1k‡ÉØÔöòº, +Ö<êàÀÆ}àжý@Sq9ÍeØfgäpûðùÄÍ{ë » yˆXªŒŽ°½ß|¡sÒôÌYF€¸OŒ>âSAÿŠîGA1±…¨”uÄbf|Ó發¤%†ÿójÄŒxúQ€Å÷(!Í1Â6`6œ²ú°ö24ƲA<½Kùf;ò“ÚÚ< £ÃHïŠûàHwŠÑqBšÌb3YÄ;6Æ„€Ë7—E,o†}Îi&e{efvYžaÊCHÅ—%¾Uã‡>Ùìš°¾$ø`dLÙ!2©Bq¿(—àEL®[rO©<‚tDîáË„ÞÉk€( o+bâq%‡„YC¸æ¬ä½1·‹˜ÙÎÂN\Ì"ÍdTj€#‡•º&d„—AZîˆF$·« Ž/ÓG°®esH€[ÙÈ# +aøëŒÚåÀùŒ6-œç¨/„éudôûƒ|·è¥ˆ#O]òžÍ¬wz%À¼Ë}¶àÜÕéðýJ†×—;Ê"àœ;ŸÔ ÇЈÉÈœ‚±í‡Î!q9p.⤓7ò6!߀´—ž²>+oâµ\ì–´Zì½Õ`¸9òã&2ú†€G™Ê #Š›ˆ·…X܈7Œ[—gø“7²7bÞ¦¤G.+bŽ2ðˆý +óAÊ/ebirßî£rÛ1af›XÜâÓrŒ¦ Óì*R^¯ýª‘Þ¢AÝmf“!…?ãv^³ß¼ä5i£Wòœë ”›£µÊëÖjÄ|FñqÆïœ5äµ´¥<ëk“‘ÆŒs—OV%£›AZj?¾cÒ2†]—Þ¢ÎK®WB5/ÒÌBëbÌ:œOædó¢Äf-Äz#S;ÕÈøÚcHû€Âi*ÒõCZ3Dr2/½ù(â„¢5Æÿ¢~¾~g‘ØyL”ܪK¤öiÀ¿WGÜñµ EÊâ¢<š÷hÍIZ°‹H­Sf6°M2 AR½&Wyi¶RáùÛëŽò¾»ŽÑ½ºþp‹ }@ŸŸÝÇ&n}ÔÄR{ŽQ¾¹˜õãëÙë¾]N7K\Pk%|Øn‚‡mg®c\›‹ÙÞ˜‰j]cX"ÝuuBq©Ë>ü÷Ž$ÒŒvÇ!ËèpÞ1ÒVAüBQ`ÁN±ÏíÔå€y[ÿ¹'é2±IY˜Ò C†¿ß+t UdXÈ(¾"ÞõEÙHãŒúK; ‹yÙƒ¶ðq‹%ÃTóH^ñ·vÊ£páEèmä([ÄSDí¹$­] WD T±KÌ +ăE±–ÑÜ€ñqñ-¼«¾óøïš´LâôÒjFËû¼ïl±cÔR‘Áv¤ñer il\™Æè`Ãó9ü`q“¡Ù[¨ûÍlÁÛº“â×ç‹[WUà?XÜiÕZ¢ŒZcÁí&C,µì0ÃâF5eJ‡2¬¡w#æ ªG„Ýgcæ0·‚ù/£½ë ÆĦy§­G±ñ‰›ùqÿ™\ {yT÷ ýgÎû5ŒÆåõ;›P®€˜EL’ÿêCd[\ê¬,ÒåCö/LhÔ'¶ë +ý +·¢ü—GYÉãf2ŠHó +i5À¸L„0uÿRÈ|ĸ„ý=é +a%´ë ýžmGut Å1ŒR–4;//¼ä5‡apF?ß'JjÒ5I©3BÌ]ÄyFzGX:ôgQ{]ç¤eˆŒ'vÅÃßï"|m$‚ßÀš*o3響»Ý¦"zVmmñê•èyõ ÎÝ u<ìÕv"¤dy-‘ñ±Hs]§#=’V u=¤€øwH»ƒLëÖ@º'ºšz@[úUóPS™¿õæD¶ž³ ësò(.2ºYçç!­´þÎhœtš†æð’û~Œƒˆ±Š¸ÜŒvô_© Ú‚ì&bð‘™}z¼˜Ç í¬^Ó¹v“¶,:#Ç#OË"·èœ÷lÑI÷Hã„aÊšÛO¦¦­ûL†©|3s=ñ¹‘„½ï\¤ÃtfÄÉ͆Hc…Ñ6¶õÍèze¬7± \hzÖu6ÒTÜL[ÿ7‹[à—±ËîÖ?-?nZñÖ…zÔM ›ÑÓ`ƒ:M±‹‘.Ãâö¿¿‰ÑÃF~àV§6?§mr»•K¥öi’0F3ÚY0f3:CNÒ¥H;‹'²d´³„ÿ¢ÅËù ŽêCt}ËÈcr¥ÚY>ŒV£msÉuÒ¦`´á.múJÄF¶÷·v–0¾UƒŸÜ©ÁØ1œãÒF–m iÍ£¿"­†kÁ Q>-ðLY…Ή:î:²rš‚ôåEqMü”n-¤{€GF–KZÊ0ú-H3Ü/k#ò1 1(çg*òù^ARƒ&âêRiÝÚˆñH$¶+ØÇpç±ðÿ;¿ìÿãΧh‰ +:-,JÞ¸ 3ZXdÐý-̺!ÒyðÎX…Û…ÏgÖƒ +¶Ño÷¡µpŽÕåIˆu̇y9Šë¢´st¿Ê9½b¤ƒ‹4…Ö²\¡%“ë1lîç'#]$F¯éA[^š,°vs%xbŸ 2: í,Ø·kg í,˜ßÙºÏzÄ,GÌX‘#Œ{ig‘g|fp`l¨Á8e)KŠàÿËÄ\޲°‘G¬eR mó²×ÀùŒ>ŒcÌšÈ%ß9ØÉS“>bz3Üëè×û7ÒÙ‚q&ç®ÏEzu&NaK…7³7ó#‹RˆÅ퟽ é_ 3Y(GFײ'˜3õžÁ?ùƒÅÍèÅÕ)1œY¤ùŒ8×較s·!f-ºÑïµ¹6íÇ:ðUFãC|Úm&ÒŽžsšñC;+b™Õ¢Ö){¤%lÒ3±Ÿ‚tºÐu7¤†âÐæÊô¿´³þ{oÕ¶m‹V‚·kÁ" ·…Ë‚%¸âUÓg%!FŒ„¸»{Rq’àîî"ˆá.K·ÉmöÙûœ{¿÷î÷½÷ÉW$©TU朣Þ[ïcôÖFB;‹ò•~Öβ ì­*ûFÌ87_±k’Dâåáw +×£º]…_Q Å€Äaб”Ã4cÀ¥/_HÆUtŒìKí;ãüB¼ŸÄÃÝïë~PÅpVþ97b«>±ƒåøªI–¥õ†ÖÅÍÆ4oªlþï<ó™w~w»ùÿ丼óê“Ø{ñHDLƒ†¦TÉv~½e‡€>²£oÑΫ—`ï×>ZÜTŸ:$û+), ü'çæ×ñžê]{Ëç]XÊOï•8¸U"XŸøi’æÔ"1mÿwbÒ¾iT³-ºp,»£y öÞ V +.n~{ê–|&ôÍø’æåÀ¤¨ŠŽ¡z’KH_ì¡ÚXQ•ߢÞBµC*ǰ^ñU6n=¨–‰™4F~ÖÎ*k^!TÞ[‡ZÊgí,Ä[Ñ+}(ìYH½2hgA/¹ÙigEtkg©I¾oåÒñE½=u¸`»½'æ.8ü¥­)C€àsåˆüo¨ž™¿f”:(}ñ#;¿^T{‹¼ßÒ;Mïßú?¿y¼]6œÛT³XCsi±\zi¥eìîib`Š>xŸ¡÷Lµ`ãöObw¼Y#Ô¾2,´c¡GßOb'jlÁ™ùbüŽIݺëž= •ýÔ±æe¤&‚¶‘…¨0åíµ;¢žml!) ‰ÍŸÁe\ž,)¸Åö73µVmdͬÚAGHÒWG täåTÛq'vßÔ¨lìÞ‰à°Çž䬪=¯ÖóYæAoÚYÆØ+É[jC;KÉò +ÚYÄÆáŸ¨vÖzò÷ÈÚï²WÒPi{Ä Kß¾VŽ‘ý¡Ñ(غ÷älÝtÅ-$~B»‹ød!¡j4¡¡FkçÐ5+jü™/ºõô]EŸl}uh…4*„ò»«ó±ÎLnnªO_2Ž-o\ŽØB5b î+Íûk„.GeÁ[õ+ÔÁšÑ²sh_+ßìQ–$¯O¬"×6(Õ»[D±¦Ó”wraÓ"ªEõÛwOR^¡ÚY\Á%T;+¸ÚY:0%7m>tÇpuSmêø:ª%C?ÚYÝÚYò?kg¹}ÖÎÚÞ‹µtÔQq$·”næ…v|hñð{C˜Z`²w,™ŸÙ_C[¾Ÿä‚y¿•“ŽŠ±Õ‚.0ÕýÁû“N§hj\ÒÍs\3A"÷Rt íKõɽzAó[ ÌÅä\™Çíz±AYÖöôUV:Ø_Îr5š'¸zõf¬mt6®æ ÉÉí‚zá5Ʀ*……z“¶àŸ2 uDÄäoø\Ô0 ;­²%ø'(oŸrxô* Í½aR±a½R¼Í9zœ9JJ¬›-_Š+IÜàOâˆÏ%¹Œà›A5ÿ°ßJUݾ\ØÑ±‘jg#ÝÅ·Å?´³|>igyõQSí¬½3ÅŒÓó¥m±ƒ,”ÖZ8wèmc­TÈ)¥îžaU>Ár[Õ·¦ùx@ÎHÊÇ^xc Õ+ qº4”ËzT›<{¤àŸN°×® ˆƒ\áÍ…²ÆÕlÉÍŸ™‚‹ ¡OkaØŸCs™2\Ÿuf.¸ä±ïQJ82º¤ÒŽcAsf¥wôPÎÆ¥‡Ú)@äk£ùü[?ƒñ$—íÖ—ìÖÎb©vVËÏBõ³ âÎ3ìAF~@µ0ÜÃú1öÁ½Ì|tU޽?kg¡¾Íª¯W>QJÙ÷žþ5ïá…|úžébÖÙùrÂÁЮ݃ûa¯æ8ê&rX©—s|n·>ÇÙùT7&¦È¯Eì¡Ç•rt¶`š’> +¾XÄû79ö€þtîù‚Ó‹¸ÒûËP_£kîÐ Ë ¾W3RÚ–1Œj8»„S­{ux‰P1ë,r—ýU¸§\L…çÐÇ‚³ÓVZÚj#vRü N¿”aÖp +3óMZœOÙ5vò[9 }$4Oà“ù´Ó¥ÊûF”k›ƒzÃçóž± U²›Ž©Å&-Sìù!±X +qL.ù†ÆHרÎ.jž$oÃþ4ÔK»õKjdzé'Á­¿9›}r6td¿œ‘T,¤p âŽeL!õRò‘Y"ÉU¡ƒúf·¦pÊn*CS3O͇öpÕDÁðÀšØw-`Øz, Œû :àNst¶su1°"ÖU ]èüp™ÇgQÛ„¶L E“„¢»Ë`Ÿ|å‹uX¯“*[6X×6 <ñŸÐ¥31‚~¢½6ÕŽ*+lˆ5}Œ 뤇u)6ëì&ÿÖBhgÉ»ZYeõ£eÐÎâÒöNEÏ]7Ž© .k–ÖœÏM¥ÚYÐ +A=+‰Øgl%¹&r½ÐΊìÖÎrN,à +.}Aë­$æË!c(Ö$~š-ÀÃlÞéùB¹îØòo…èŠo©Ö|tíD)ûÔ>ïâ÷T×k.Ûb«CH~ ¿„SøÒúåByÓj¦¼þ'¦˜|VêÑéгƒÎôž¤Äã3e¿üQ¬½«®ºw:jÒž{ p­mTµ/S]YHõHŽEsÄ#3„›? ¹W—'™˜[+õö¼µOOÔ|$ðÐA•œ}õdïÄa|Ù•– ¦TKÆ?CX€!ù™)ÉוĶYY #Ô¡GƒºÅ`Tç4PO. í.ä|BhéhnÑ5ãÐcBëL;Çs°WÔ/Ý‚õÐ~ÀaT†Ø’˜¼:Ö3¨Æû–ðþœ­ÅûÀ`bÌÁÉ\ÞÍ%¨‰ˆÑ•ã ùøÍm!ÜWä£Ô/Fä†f5ísɼº€êù%S TÙ7i8Õ`&c*d’¸Mr4à}ªc\]nÀ‘{Os#èáú‘ë$vúIÓ½?ŸvhjÒÁ‡’|°QÍU4­à-·ôPš +¬_QšÐ¬¯¨ÆtÞ€Ã\#ûÑzÂ?igqÙççѼ-¼`´q|𸲤y1òw¥½_O%ÁøœO¡>´ÒÄØOZœ$ï#óx,ÿY;+ªô[hñ˜Sùç¨Æº¹c|÷çV|{ ¹ t¨“ë&ó‡¾ã +.,"6¶˜Ï>O1 ­Y%ϠÚp1ÄîÉß ¾ ºSdŽr)$—¯h^*îkf˜}O7¨Jë—`ÖÜ¥¤ã3é¾Ißо{ÖÇo8Ù;ån³ÿº½º¦ÑŒ­jXAò¡å8gø")¸d Kr äÞÇUNÄ^7Þ!¤·³oÍ™ .,ý²ô-ÔNÚ,ÁÔTÃ:¼Êº[±ظ’sÔV*- 6´PX˜«¬½_/àc\›wmê$Ÿìe¡’µ¨–'ù[b\åxè[aÿÕ$J>5“ɽ½š#Д£}$—E-ŠspÑ…Özb—rx:jùˆÑœcp•ìÑ:ÊXCcöO¦ú(t­šTEc¡³†Ú6zÉ„Œóó±fE5QÄ]ÄŸ&Eížj9¬ÌûoxÍ…nlIçQí$9éðw°{:Ö¨7A+¢ðÔ®…ÊCâ¿gòžaýÇ€>Ü&O]Ñ;s8öõp{ËûŠâއ&\AãT³5ª;}t6Wrû'¾èöÏR\ÝdªiÍ[‚ù(fMÞ?û áݼ¯¡Å圞Çìh_©*¸¾ë»Xo¦½Ž.Q}iLJÚ; ~XJôLqJPÎWrd‰]"þ)¸°@•srîtÖ‘Ï[ˆ®ÚЯ š*$®PŸS‚=,“©n®›àG#ȼçRöNá>'yË<à sžø'‚CY‡À^8oì=ãj:ÖAAݺ¸áGNsqæâ—X5ž+k]½žÒÞ‡,—yi>õÕéúÀ¬ø\êcÈXbï%ôž°/€Æ=Ô®÷—ÜXŸJצ­ít÷"ÆâóY;7]ìÉ@-:EœÕV] sËnMĀܑÐTÁ5amŒµwêad¸ž`ZQ!l%v5fŸ´¡Ýzæ'fŠI{¦¢†Š5H`FÑ3bÕÄ"1 ç&Çìœ,fŸ[ˆúŒC윟{h*ï›5{"8×`=Ñ:–äóá¿‚Š¾Bœ¡eïÔõK!ëìhQý hmA. o$òlºŽLÆdÐËË8ððÕ­†f{tõx’£P}¬Ã—S-ž’[K ]„÷Ð|¹*±[` h@0¥í?3ÅÍ?Àç‰IK@W ±6íàwLEÛr©®Ù:1X«§Z_ۆн'¨5bPÂÞ)| ÁµÐ7ÆÏðOÐ]®hþIYrû{Fsa.]Óñ!±¶CæX·¾qá×tõìÌÕ‘ ¿Á>UÉuŠ„ØÚ *_]¥¼U¹t«€9  Ǥ“8£!ü)`¿UBÝD)\ó5]+ӛÕÞú™×\\„uzÖ&¨§ 拉ÚLbYTµªðú"|>]¯ "öZò5æ]eÀ¤ï¢*½¹DUpu¡*ïò|ô¢r.} É¹úöãª'R}8ì! ¯'8‘êÞWòÍ­BZÚòÉÕćî››$9W?¬½Á¿@oJt÷ëËm z'"*‰*Më|$g¢ùyîô¥M6˜+Ì,T +àhä&Èwqß“°ÞÊ›å·øõ¡¶ irÏĈÒo°—Gب'!žgŸ\¼=-äƒØ³%EWÇÞ Ì+œÖ‹EŸ<}äÎðßÀ‘T7Ý+qÝs-xŸ´a$Ž £qz¯Ä§ð~ÙúÐt¦zÂØ¯\H5»%`èÜ¢FëŸ0”j5Q|bÕyEÍ„àPÌq>ýx·?‚ö)ñqTç +Z±¨³“9&z“{AìŒä'ÀE°A’Íc³ÏÎÁ8²…g +©ä3ÈuR=1è‡BuÔÉ}bÓµR‚‰ Ï&V?0BëCð6öÒÆû¿k´è¨^Öé‡!O‚væ6½ðiG¦ÓýÀ‰{&`¿+t¡Aˆý‚˜_#{ %‡–|CãRòÁï¨&8¹f>¾lµÓ„šñLÚ©éLòñ©œOö0à9zmØ÷Rt{ æÕØrp×…N¸ùÎ'?+?5æw>5âk;70©{'³Þ=ÑüGÆn"tzH˜Jç#´ÝbÐó¦óúج®/Ç—ãËñåør|9¾_Ž/Ç—ãËñåør|9¾_Ž/Ç—ãËñåør|9¾_Ž/Ç—ãËñåør|9¾_Ž/Ç—ãËñåør|9¾_ŽÿŸ‰Wo±]e½Íº¿·®¿ÞÄåëX’gÌ­·n³óì¯gLž²œµÜsÛ*G›mŽn[¬=} –Ðç8£ªõ« –LÙhíkçi9Ûr±åTƒ ¦,_?g¶%yùíTƒxíì™sçÌ2·³v1˜ÒýÁä÷&žŽŽ[È“6Ö.vŸ^ûþë¯÷Ý÷sæÌŸ9oö¢…ßÏ™»p悹ó¸þëó³/ž9î¢E.xþÓOx}÷+þçóŸ?ÇåÿðùäùÍýõØþz[úë™õ×[l0eªG~Týë÷ä}{´ÂÓkëfSëmäz¶|zv…¹¢}~ŠjËkW;[ú´yÞ`áÔþ³ –÷×›mÀyãÿåvýõ¼ð̓Ùô狟 ÉwNä9oƒ9³ Œ Dy¶-y#gNOî"ú½)³¿_8sá÷ÝOlüç'>}Ýø·ü'>½eË¿œ¾ñød k]ì–|úž^ßgÛ wdŽ·¶¿Þ¬UvÛmìVñ 8b1"9ñïè wÿO~¢·{óºÿ l0‡œÄ¹¸ÖÍÿïÞ€ûòéMŸ¾|o0ŸœÀœïém›o€·Í&ç9‘ž$Lz‰Áü9 ~O,{½Þºõ¬bõJ#Åz#Vada«eÊ:hãa$lÒ6QYk›Ùh™Øk­Û (Ö¬2WnæÊÍZv!=Ñï©´ê©´ìin»]×TòÐ^½ÜD±ôÇuŠõkx…1ã¬e¬öÐ6V:k¯1ä«–›)Ö­1U€ ÎTÞ¬mn·U×ÌÚ]Gå®§tŠÖ3±óÓÝ`n©02Ù¤ÿ•…ͶJ»È^æV>=6˜YÒ¿mh&“ϰP¬^ºž|5W˜ñÚèÿÀ^ý­èkÌxG-ÆÞ·'8]d¿äáànR‡~NôüR¾b—°¾èý¦=>[“£Ï}ÒØƒ¾T9²`,znÐÊlòè!¢OÜ/.zàÈ¥½¦©‡f£?½t‚kåâ _E'¿>¢;¸Z2G€W‹r´àõèÅÚìÓ[°ßÚS½%j€ìIþ¾Wâp³°îA})G„_O ôV3j-•h£ ^&p,°¶ºè­Dÿ4oçÙœáæ*^¡²vÑá=Ó£¯ˆqôêÉ8xR.p‘ñÎ}Ð7 +.Y ¥•–…°I‹/3¹~7?=)0u„”°kªZ1=Ùf’£kã¥ Ž zí±5eôo&ŸƒþXÜOÏøÁ”Ë)¸dŒQó-\øë3€Û–JžÏÊûf cB{›É[tÀ_Ë»‡ô£Ü!Ay£è~xÊÝ=˜ÞôP„æ}…ž.ôÐ}ûଠ‡±tÖax+mðDšÊÚ൉™½–©¹µÖSIî) ôhð.”×Òh£¨0‚®Ã:¥}´¢«Ž’\cCî)ùœ «WmT Ïü¶¬c´žÊ1VO¹ÉGæ&àq5±V(ÕN:à54¶P œÛš:ØÌÆCÇÐHP¬Xk¢0BŸ¯µoOaKÊ@~[Ú`Î5ªŸ’sÓ†V…™z›Îzòºõ+ÁQl¥Î&œ¸™,,·÷`e÷¬½OOÉ)´¯ìÒOôŠdœ›+dècß½’\/9mÑ'}˜TüµVnNÙ;yx*)¯—oÂ0Øïâ݇qôî)ù~Eîï×"ø9‚óFKš ‹ÅŒSóåà”Qx Ol‡ßâÓ½”£%¢„òts3Ž…Í[úeŽR{ö—=}úÊ>‰ÃÀÝ@¹)¶†wk½U<ŒàÃa,uX›-º”Ó9Dó RuPîhô; Û"ˆöA}(WRhÎ×è=“|R† .Azìæ­=ÁOF{’ˆí3[zpvºà¾}ˆml î9aït1åÐLÙ;G_p î˹éÁÎÑÏ^&ôÄÐ~Eßl}ÚïáÙ¶)…–¥ü_9W¾ +êD?'ÜÍ™ÁzDô³ÉX{ =ØÛˆ=£9ºr8%¨®Ý–@=Úsã5D+Ë{Åâ¼{Óžôÿ’q£}‰ö.º|`Ù×¼kD_SÁN{Í2Câ#×(ÌY2ßäí=Ìw¥àLÆr[y˜ NÚFÆ‚Âx×­å£Þ¢C¹sì¼Éœ·Ñ2U©àÅù·–³ î…>$Ö5¦¸ñ9¦*[-3ÖA‹òI“k@ï6¿=k(ïÞÇBöÔÁß?z±Eç°¾àÇ ãㄞÅîsðnB÷‰söí-:EõUJî:ñ£–n=D§ð¾’OúpÙ3iˆäØWrö탞\µ_Š>oƒž¿žè÷åÓhϸCÀ@ÆGj„q Iäm CЃI9·g§ã¨)¤œœ…žOô¤£'Wô%÷\Ä÷¢oFŽÙ=EN;>WŽß=U¢œÕ“ä@p„ö£>øÏîþeⓉÏDÏìŠöç’±âœýz£ÿ6#{GF/íÃFMDõ8ô8Ñ>]¯˜ÁÔÞˆ_–·' •¶Å=CûÃÏá³(?Æ< …öÐÒ~÷øå¨1פèê àúêîs¬Oûä¢*ÆJ!E£Á9¤¯Oÿøå¦òŠ$mOJy ˆmÀGÑøëIlý‘ð±˜CA9£h/:x¸|c‡ÈeßJ¥èc¦ýœd¾b^‚oý‹˜7à¡)¯EÑ78OÊ—žnb‡àý£=œaù´_¶ñ^Ý„ýSÀ ...ñÐðƒƒý˜ø +ŸI{KÑ“V1ý¶´”Ø84À¡î™nn7âËɽ ö5¾\¸œgdª ³s<¸hÐ +l¿'¸‡÷GŸ%µOb³Û“‡PîH<·-¢¿Ê)¨7kC|¸{Á-NæñÇ”sÜin‘ýÁÈÿÇ:oí…{ƒ| ¹§ƒÕ[H¼ ñU ³OŸî^Xr)§gѹErøF:ßÈïà €m„¤“3ÙüÛ‹¹ô3³(Çrò±i´Ó-nï_8’?1+|ðŸqs>ïš2ÀÄ~ÚYGôËÔS~'d…yz¿øô(ç#t8] ¾ô"ãêEâ™R@ÞWêˆà«àw8«Í:à‚¢x)|çç‰ÄÇÁ6%ðÛúÄÿ#íA%ãD{qÉxÃFÀµAûÊÑ?Œ{Bæå!XHØÚ}¸”> +ãå™0÷R„Ï£¼ë±0xŸO1¸}²°pD‚‡ŠØég~œ íá&’'ñŸ%ãEc>b¿OÂäYàh <šiGf€œöî•|Ó©¯¤ï¤!|@ÒPh{À‚û…j$˜ M.¼t4å)ñŒ@¯Ï#f ÏQ;Çgþü·èéVÙ{ÐKŒ(˧›>lΓŒŸCpoŒÎü>èÑ…î +8R¥¨ºñ¼{ÂøTðâoÐÞûPÜÛ¬<ü&É`·àgCûX@cÃÞ[¾±B óŸÚgLÕx3Î^ËœÄr‰|%¹ +¾7ã]µÍIþ¥”ºõO(7Äç~ܸcÓÀQLû|ãN~¸ñhO·7ÁÇôû´¡B잉\ʉéàîæ‚òGBß z<œoÖ0.¤ø+<˜ ÒQЄ¿;4,H=4p×s±ý¡]b®vÓ&¥†ädjâ¿íý{€sHÜ–>”Ú‰ˆÉ7¨¿—á–¾‚ê0ÊiQÚ±œæßŽ~}hL$ã«*¾·šLú©໇}RUn\ Î;`+’|_CâÖ@Ø'p"èr˜Ì܉Œ¸ôhœ%ñE ñ~˜bbËT«%(SŸö´ÜBãÁ”Ô…ä Îþz‹ØÉzžòË€3ŠÌ_Ø$üíþôÌÌ)øg!ºü[ÊÛE~GÏ-¦zô8ÀïΤ쟌ø .6ÌwüÌp5€/ˆ#¶FãxÃm½t1Ï(§ù›Ð'PÚ’œÙÒE9#Gâ}p PZ8 +¹¬ÊÒƒæz´ŸÌOÜ?Ñ7nÕk 1–w$9‰I¬3™v¾=¡/ûä·&‚†î3zøM•$Wa¬´PK.ű–ÈÛ]´Íy’‡8iƒçzG´N|†q&> 1™`á>b¡i˜_ˆÍàÂå=RžVâûYkç*{÷J[4lM¨rôí î_ð9𓼼›ßЫjì–ȾŒ•WSäëâÖVùò)Ü7¥¥»¸,)w.ÉÓyÇÀÞà¤ÚHàà #9n$#à´˜]¡ ¡*iý‘Î/ø±à´‘ª²æ¹Ú7†Ê]YmQòd18A©nlÐ/{¸Òγ‡/iAËŽÕ\šÏ§_žË{¥ QÙzꢆ~ÌÁ#¸ü&͇ƒ3QC!¹tÞhð)ª½ &pì'¹ùèJþqC‘Ï@;<ï˜S4W ¹6ÁH=ÁëþmÙ›`Kp"ù¦ëƒO ú,”·Ó'k8õµ$fA«…bØ=ñÙݼ„µøôc³ÊI5r$Àe^˜ÏU?_ÇïzdÆìè¤ü¨”ãÆ=f ð5åÓ +endstream endobj 132 0 obj <>stream +ÝÑZôÞÛƒ]wÁw"^C£¹ëB^_‰ºGÜf³/ŠC€ ¼2‡@ç‚â‚ ’1”s›`pÆP×\ ÊK»-z »%Ls ¶I},™ ò}|%qaýš +Œ»ÒÊWù3ôu»çÏv]è!€[[ÉÛkóΡzðÛ<ñ)¨€ûbFâ?ðY€OÃ7WŸÌ¥^à(d7õV‘¼ÚŒä4¦– +3ÁF‹òk’çáû¸ÍÄvíz‚Cù:8ïU¢§8 +ÁeÈØûõÄôE0‘Ç™X¨©ž+tiÀǦ˜Ám‹ˆXÄØ’¿ ®àVØcX¹4¸$oQ{R‡…ÿg2É×{I€w¸\ÛÄ"–S +ŽpÓ|=f8{©¦BÂî)4ÿ )#EŽEÍPòOÕ—ý2»ù%ƒ2FQ¼W9ž)mø‰j@y'F=“ò`Ä|+&ÔLf5×0UV2ÕOWPË‚›ßóéæ‚ÛQpŽé‡X ­•c`/è3¯²y7ñWæóù#YÇ€Þà_góï,fÊÛ~¦Ü²Ð .ýš *éÆñǧq¹õ‹ùâ˄Җ•BqÃrð¶ts7’¸V8y)å0w'â´`"« (>&1ñèt>õôL.çÆBCc¥µ Ø…Ñew¾Nì +sŠê‘¼Ÿré;y÷Þ‘s’ü ptn»GõÞ=n€@òð³£nÜ«ÚDü§Oätà¶ï•E±µàž<~x5að×Ã&Ág/x¤ ‚¼g£Í;÷<㉶Á½a›à¹•·FÓZ8«QÛ¥õÎÀÌ‘RÂþn^ä®Ãm¬G9\¶E ¤|ÆQ%ߨŠn,Ríù`Èìo¬¬y³Œ Ìû3•œµQ—79pîå²Ç<'~‚âsðe…iFÓš>jHñ»§Òz­ÿä|nTÔeÀ9- Öç…Z +Á$_j㲉©Àþ¹#»y—~%~’æPqà?Ü7ºCÀû”ëùº[H_\—‘;ÆSž6ÊÍT1¼•à‘—3çŸ>Œ÷%ù‹wü`ÔW9ïèAàC§:?‰‡¦B×™æOàÝN;>Úƒ‚ùWÀ‚/Ä >éØt¶ìé2.§é{.¢úÄE! h—}b¶ªüáRè˜ñ1UßrÛS‡0N$æyœ]i€y 6.g‹[~dJ[~â5WQÞ™-°èþbHúH!ãÀLè~€_‰òÈÃzÈáRÎÌÄýVæÞ™¯,oÿr«9ë±›Üt‘¯sÈ×' nB ÿ3Ï?ÅR¾™Ãé< c¬ ,Ìy$ý ºóõí ƒh‘ø\Ä pj ±&³égf + G§ Þ¹úœ½O/üžêksSûts “{#mÏÓ§¯r´z¶è€'I þ52%Éá1_Dÿ>X’ãª>åë}Q¯¡µBâËø˜Úñ´FˆÜÍÁ«8Éa›êxŸ´1ÍéÙìž'Å#­j¦öÕZpÿ~ÖÆàíCz³ÖƒØlíœNØš6qKÌ?ÏäçX›’ˆR./ðKÃF” .ZÊIŠZîWx1åýÄA8@ô#yÁð·”Ï«;_ï çF¹,à +ÇquIî<•æÍÁdüº¹¸†Òr>øš¤½ÓÓ ÉGgÀ'27qégqÉÀþ°éÈA ɸÍ~½(eTå·À'¼Ãö^–¥ã˜¼k ¡¯Ã%šÌº§ @LCíZÜBrïð]ß +¡» §i.Ib:øÜ ûƦ‘¼’ÄlpÈ)%heAOK*lZ!–$ô­iÞFr%p6B‰-yð3É×ðnii}_tûG¾Î§ž ­'Ô߀Ó1WºóuÌ—¾àé§ëkda'–aUã¤Ð¼Ñ4_·&ù:ô1ÈØÒºsLíš/ã¹mA„ÄS(ÏêLT£n¢PÞ¸Z¬»o*ìoWq5Ï×+K®/¦ÚŽäžÛ,nOpŽè®ÃHž:ݰ$÷'> sç­äëÀTÈ(Wx»PÏ@=‰Øƒrâ;1qÏT)icÄô½ˆHm ÑÝ¿/æÕ] ­ü˜˜±‚_ëÖÆ‹Z– ¥í+q}àJG åìÉß÷Jþ5pÁ¯Bg…)$9vÊZs¥\zñ»&©JšTÕ¾Y½bècKÀD¸gQ{&©#J d÷ȰM`ÊÕ˜{}WÚ°”+¼ùåãÄu‚Ï3ûÄ<žêb–PNÓ²û«¤Ú‡f¸7lîÅùÔ>öNÆ ¿2åœK9÷VgÀ¸E÷3Ãú¨ÊQþU +¯4À8"&¡®Á:ö·®ÊÚOk Ýz%út½;åÄzn¨?l#8œø.‰øvøEÊAGìj?¢nÞ?bSÐ3'/ÕÆˆ+5ø‡6F"´1Rºu +ÿá_Šhþm žä¢ÀæfÆjŠg08’{‚'¶Fýäö”¡t¹½“?O´†Z0šÙ3O:2­Û‘¿NA`Æ€}p¼aý€æÐ$7& _)ãÁ阳ԗÂw"þ#¼\M° Õ( ¿C~N_O׋ƀ;–O=7‹Ö#\CúÏS} ¸Aj26oÑ¥yÕÆÈÃÕ=ÜHㇴ1d…©©¤ 6…õgp ôNîÔ'mŒQÐÆÀµ©?kcØöîæ÷<;_ŽÚ3Y$Ø…÷C”äD¨yFÖŽ£º4É»¦A“-¾ó—yl´[ðZð@ó‰Ç§©ò›A?«›÷»t êUt¸›àu¬™ÁGÉÑd~Ÿ‰Ú,å䃴µ/]sƒŠPݺž©xºœ#¹-åÑ%xü¥ð)ÐÁ^ Ô‰ósnñýiýß“|Xiç£kba¯e¸šEÍSÚàŒc@/èc`€™»,™óаD= {€£ e äD¨1ç{‚ã9]ã@ý’`*®°ñG1éÔLªÃ@î[tçUuÇrUÑÝÅ•í?§¡viJð¶ñÚõTCIru æÚð X»26‘fEjŸø[Tã +uIûí´6ƒµsØ&Í«Á ºy{/Ô°Dä÷Äß ŽÎ@ä!àá•ãë&ƒ?–®•»v׺äØêI”·Û'}x7ßòöÞ9­$Ô?E7b¿Ä.e·˜´~†Øšz˜jÂк½g÷Þ +~ +º.$Ö£îLõß}’‡¨lÝ{`oÕÎØñ_ÚåÍ+ÅÊ{ëÙ€üŸµ1”êm:ÔfP‡ H|m ŒúÏÚ‘ÝÚ$ÆQm b7j_’9ø÷æì<{ÒúBXÙXäŽTÌ#Ôß)þÚ;Ú[ÂøhƪÊ_,cËŸ-g3/Ρõ~¯˜ÌŽç«0Oy¯°þXÂü•¨ÊAuzHl圷÷ÆäÔФƒæxÒ™Ê{Ë(<¸]‘ 1›µMLMÆM$ï×BžƒõäÃÈý¤ð‹ÐQ]·–U¬Z²A±â§u +hÉ¢ÖjáM³|}è£n†5,|00åØEþJb&ê…Ðï£Z$¨"/‡~)´)HÌ&GÜ@Î ÞNÜÊoZݹR¹ïÍz2§@Ú&ëÁ‹n©…‡Ë+ E‰ü\ÜTÃUlÜÀ(øÍ½ÕÐ !þšÖ'7ûôÆxÓu ›-ºô«½».î•èBâô|Ýû2Û©¢Ø"ëä±àâÔ/s¢Ö ­²¬Ós¹Ü 3Á‰1…o`sOÎíæ]MI×Q#‹ °ŽJy*³ŽÍákB~k(j_âËãÊ'ˆ•ëäšV iǶúÙUQÓ÷TƒÌ>aÏ$UáeªÁÜYLµ1HþŒýŒ-Æ¢›6ô¡ —ˆ:Õ.úš3T#¼[Cúgm ÷ÏÚ^=Y+GFtÒ¦xkÂ$γõ?ðy7ówÒšAâž)ð#4çôÏ!EïŸÌ•?YÅïxiÈT¼[Žº´±{¼Tü5[ûl tçhÎ päKØFT3Ô3jÝá—9y9êGÈÕ‘ÿBËø54ÉÞ§·ì7Ú]XûÏ.›}{¼c´Ê5¦/øì™méƒ`Ÿæ’£öÚÕ&Šå+×*Ö¯5S˜ðNt=¸“-»·¼»àqG Ë‚“GOšO¤Ÿ‹=_°Qv³WOžäÒ¸v©¼~-—ueDb­½û¥ £ëØË +þÚJUYóO|Õ“õT#ýè ØŒêÚ¾Ÿ´1¶õ–©6ƾ™Ð¶Å FmÍ‚Ì'{OÖ”ƒò¿–± +¸ÑÁ§jmæ*YÁmré!y§§œüØsU=¾ +öJýx`óÎ/²./R‡•`2aêÞ®Uíh[ÆÇÖNÀ³9¸—r³oO•SdŸÏÚlQÛÉËà§dèX¤î›)GdŒ¦ñÄ2!}ï !óÌ|)qÿtŠƒHì {{ˆ¿ÇX±Å7~JWòåõ+Ùò»Ë0¾¨=³YWæbíF„Îwô¾Iªâ‡?0™Wgs±G'±©gfP•tx*´7¹ÄÝ“€é(6Ç:ð>t#"k&ðùõ?òÅMËó°þ¹úȰ^¼‡Î`yìÛ#6!äžû^,kYÇÕ=Þ ºg-ïíØ”ÓÓY¿â¬WÆ•gÒ¬AXظ÷0㬴̈"á óeüš@æ7jQX/21dxÕ—!¸PN82S½c"Å3[c¿ô4Ä’»+…ôËóè~¬ÙAoõÓZ/4F¡‹ñQå_YÀeŸœm É/Ö PÀž#uTþ·rlåD9ùè,ìéèÆ4echíu íqƒi=(÷+äã´†®àmÑéoÜÔÁQ[‘ ›W‹ù·~êÎÙIüöÇþŽÓ䘪‰¨ÙSMº45hYò©»¦r»[Œ„sͶêSõÎвܰv£ZÈt/[ÅUru‹±°ãž¡ªôò÷TËÚáš ¡Înº-‚PÿïÖó 9›†>ÖEUù$7%8\ÚÓʨv<^m è±sQ•c»×'ªÆ0[ÓA3žK8;jcø¥ ¥yTrÍÔ¼¤È¢±T#ª[CÌ=±úT;€`Ù‹äáåT‡Žä©”[™üž/kZÎW´¬¦ùIyûr¬™@¿ú~LÖ¿èûþ‡¾_åóÕØ÷clÎvs¨Ó}%cEìkÀßG|AÃ2±¢m-›quîl‡® Ack©ÈÑQKC<$9’¸¯…±>uÑM>Ñlk¾ëÕrÌ6íüLηt4k"_¢ëÀ[SQ_Z2œòlEçJØ»!Áƒ†«6RUs‘Äwç¥-A}Õˆ#ÐRuöêÿ.{&Ó}ÅbdÖhÊ µ#ì-ÞpJ'›.‡U‹5!à_ªG‡5J¬¯±Ä^1øàèJ‘i­spÑ+›äÑ»'ˆé§æÁÿQÍ h³A;ä¯ÉG)g5l—÷K¤uuÔMÔÅ×qd<„à⯑“ …ý>–>é#¬<ÂJIúT à“–%ÆVUÛ¾J}üŽÕ•k~Ü¡N%Ö©Œ • +Ä&𝡶-Ë”ÃÓ ÏËV>^ ½Q¶¬u)Ÿ}e¡pª];žj cÍß?kjtœ[TºûOÚ É_éºPTÉXè¸#ŸPÞY}=Æ5ROåÛ—ØÈh.úÀDèb#w·•÷ðYqûñÒ÷Çæ[€˜-G×Möû\_¥9mBÍ$®øöR©¤iXÚ´Š­ºÿ}?ö³¾ß®v³ÿ©ï÷`9ôý°“Î1Ôˆ-Ržü”ÝS©‰ÿØw-&ª½g<ö@G‘ÔŒ öŸrf¦Tö5ìþ¹Wݱ–OÚ=™jYFíÝlÆ7g”5µì…aýs†[ØyébÍL ±8J¬jÛ ¬ˆÚ“JpÐÆ~Xà>ª]IâtÝ ñŒz&ïL°êñ°I¯î½j´ Ô´ãßÑ:ñІ‚³º÷| Of'yÝ£‹½ŒÉG¿ƒöÝ„õ¬£lòÖÅ:Ö÷°6„ö*H‘et_9t,°Í´‚£|R‡²®ÛzÑ=2$"¯¡|íð!Èñ*üx¨ÕÊáš1RâîiØßËA˘¶ZÕlXeõ“¥t–È~Øcˆ=*´îXÔ¸5pñSߎœó+vÏdºç~ùl +4˜äd..~¡së¨È)‘wäÀƒîéÏ$øXZ@!Å_cÝk~œƒ?ûcÖŧ7ÝÛ\6k´È}˜mЀÎÕg=bûCÃy´VUNK‡Õi·æwA•£ilv‹èO×ãeŠÃ¶ô•H<¤¼øt¿D$­÷Ò¿ƒ¼µÔ¸}“i¾‘rt:Õp Ç>p2þñØkEâ,òh +ûRÍ“Ž~‡±Åš5Öꩆê˜X¿D½{|Qç¬GëBX3%¾—®å£†…÷œÁûĦ~ZQXk†¦ŸMuPOÇ:WTÅxªÓqj¾˜ydò¸îzbáX¦²eW÷ÔPUÙ¾Z–ÂöÔ!œ[p_œ3Á1?AÿV@LÛž1Œ^+®‡ä°]øÔ¶âOUåMKQW¡×JÎ-iÿ>ØOÖ¹ùT<õÈ òÜTälضºs•ª¶s%j¡\ÔŽ±|d•öY¡Ö£*¾»XH¹0‡Ö¥ÉÜÀ~=äÛç&bªS_|s1|lýØ/B>c†·—î—ÅúÖyQÓÀ~6çê|¶îåzeIËba[Ê`ÆÆ‘î•DMkטïBÜ)b`É×T£Æ?{$jEdL¤ë@A™´o„®ýûd£šÖÄ¿I ;§ÒØOó¢Ñô÷Α}y§hú {ÔÃô°u4¥¥S÷žz·¨-YXºé f¬Ú¬§rðë =uèµðaåc¸ŒËsÙ¼»‹0 ÃFòzm âc‹±7—jña½,0MWؗ§ŸŸÓ}rF!¦ÒsƤäÓ3YMÃ"hèÒ|žøVØ5ö‰ZF–§y)ð?ôOHN,Æ›Ž5ÅîzÀŽ Ð“}Çg_]H1+p˜_Öú ûäŽL§8ua/©_+ýöÂgœŸM2Z¿$vOîëè¤B_Ú,ÐZc³OÍ¥k(¸ßÉUiMkBXwDÍ8º|,ÅO$ž1åwfóÏ- ëVn1 ù†u~1íÐ,ÔÓ¸Ìóó -‹ØÏ\]Hu ³Î†_f +‰Ÿ¦±ŽÄÀøZ³÷L¥˜zÐMJ<0•Æþšgë”ÕmK¹ØšoñZÔ•¥?bMŠM¿:ù‹ª¨y±PÓiÌÖ¼\Ç”´þHí>í8´ï2% ?˜µ~ë¨$?žš·½sübŽ”px:Ÿy|­Bo{w«)Sܰ„¯G5/P«rÚ¢Kã´l*Ÿ¯`*^.ã2ï,À}„ÄV.óú<Ö'gP2’Ù=ž­x¼B¬n7‚N<­7¢¯ 9Ö<‡Q/ˆØa€u@ns¤íU Û3N +©‹=dT Z%Ø“ œz”àˆ3³)æˆØcÀGîÇ%ªÊ%˜Õ¯@_å•9˜ *Ɇï«ÒÔÏSíþ¸ŽÝûÆØb÷o«•GÿnÌ\üÝ’¹üa{ì-Ïîü¸AUûqSón5¿ÿ……tºÝA¾øÀCºÔ¶…;ñLâª_®åóoþ`[:QíÐu ºw•Ü3h_’y:YH=3›/o[©Þù€±®k7U6¨¬+êÍÅ‚K©N³WÚ0up1½ÇÈ+™’{?¢>#¦›‡}L齡DsN‚íùÚ§¹ºW¸Ê7«¹²Ç+°n‚t›¨Ÿ«ìXÊBµ¢ýgU~=­Kói'gÁ25OV÷p¥Ë w ½ Ø™”°o­¥Òý¢§Âá+³g"›yz›{{¡ªúé +¦²}[Ó¾N¬k7jZ7BïRUöð'œ#ê78wUqÓØ ìš©x² {Gد ¹}æÐÌæ=UYT¾þYYôh‰ªî5Ü™—–â§[ùkÏ\¥3Ü‘Gœ°<Èkåƒ-–üv¥x ¼ï‘J<ÚfÅyÎ1wæ07g«ò[¿7¯ûe){ì9/Ÿiq–ݳ–‘wµ¨ØšW땵–#W‚&öp¹7KÅ«„#þÀK%Wд¤[oµvWÖ¹B©¹>›ñˆï¼›-ëXjy¸ÉÖòà=;¶ú·5lúµÙÐÏΤZtÅ–Ò5­ø“3i½Óί'òA>óÆBÄPŠCrï|/&œúû_Ô•LÅÊ—ëQƒâbO"ùÓH6¬v ±s¬*úØ8ÓÂsLw­Vžù»’¹ð»¬ºöWköÊïöÊÛÿ¾É¢¡Ë†}ôk ðòi×ù1˜m|åÁ_}ã‚{§n¨[‚…s¯íÙSïDöÌ[I:÷ÐE}ú¾«å¡{6êês¹¨yµ\ú`WÞ¾Šøž0®Lúé\é£eÒŽ3«±ôñ1éôLäŠVÅãä ´QV[c†XFÖL²°v|žêVAÏëtˆÜž'&ÜÞ·füÑÇ<´SàÏ<Ù$ž~à œl/î~Â0µïÖ0%PV?_ÆïybÎzÌqd U‡Þ™¨þfÌíý`Æ|gÆ|²‡^Xð':Eñp‡$k±µ:k«x¼ÉŠ«z²FY~ÿGUÕ‹åä± 6Ç¥_š »„±;ž¯ªb½V¨{Û4VïlaÔ{®ºe SѾ ¾¯$þ¯´})Ö,T•O—ªj^­°Øõ~»óÍzvï #Õw™}Œ˜L¸“oÕü™×ļä™sdþâ«Íâ±ç›Äýä>f„cÕÒñŽMüñN‰=ôÜ5f‹#¿)þf¬:õ Ë_þà ¼öVªs¿ Bý#/©¾)ÐêâÍíV§on‘6©¹F\í«õ87>ëò|ÄW>bÎ…£/e¾âížø‚M»oYñ¥WšorÕ1³ñê-N¬…Z^¹æ«>Ûà.zi)}­–ö=åºGŒ¼ó!+Tvе/ùš—†|âÉéÐöâãMf5·R=Õ¬Ë €_Ä82Ï3n-«žŠ•O׳/WZÔýº\Yôv±yÕï?™×ý}©éµ.•y{—³òÕ¿ùHoï§oŸÇ«Z~uc:~õåÞ|ˆdßü.¿¿•fûê°ÆéñÞ|é݃TñåÓ$õ³‡iVÏïj6?>_,?hŠ&÷Qb/ý¶I¸üÒIºõÐ_}¡ÕS<Ø)«´XY»ëºéÂe_ë·<¤Ã÷ÔªÚ_W+K-v?·PkÙÌï{­b +î-Fý5c¡¶Ó˜ø!SõŽ{JëýMv–{ï©‘o²•OVó°…êgkÙæÒÑv+ñü}'ù|««òàß6ªNüªdO¿U ×{—_8qg^«ÙoxáìþÊc'îòG;öÚ[îÎKîökwîú/ŽÌÕ¿Ù1—~·T^øU`®~´æî¾p—×ÇËOn'ˆMw¹³O­Ùƒ¯”lÝûõª²Ç?©ª?®Â|à?cùãO$éX»5¸•çêmPÕ<[)Ô>2QŸht€}«OßutrìþfìîgFÂǬt¤ÍZ8óØšÙû›¡êà#~ßcsô‰…êÄ †9ÿFÍ^þÍŽ¿ùÒ¿ûl+wû…×øt×ôÌ“9÷N⎽à›˜s¯EæðS¥êÄ¥p¸C`¯´Ûr;½„çí1–oogIï[S•]îæ-]öLë/Û¹‡Ïü¹K¯í˜]׳™$†äD^†5MêË .E|@½Ê<óÞwæ»ÿc¥pô™,_kð¶?yÞ[.º¿†K;1ÃbßkUûß ¼ð §:õ޵¨ûËreþë…%¿/ËÞ¯W×vª¬5;©¯Ý𳬿¾éöµH«Ëw¤s-.òþvQ¬{bF±ÊŽ×k‘§±$ÎñUo×L¸P +Ü1FYزHyìOSÕ­ßmØ×¿„Jo§Hï蘭&ò¾H>¶&ò¿½‰ãÞ½‰’ÞÕ§9=ªÓ¸uTæÆ4¤fÝÍßül_.óî¯aÒ›ö4‡§G +¬^ÞÖH¯:Sä'íIìýgÞä~ºs—ÞÛóÞÛ)kÿX¡ª|·L>ßænuõnˆúd§“pñ•{ä=Ã~!I·Û|­:o¥JõÂ¥WñÖ£­ò&?ùNs°Uó•Xñv‡—|á¾»xý¾»t¹Í“¿ðÌž½ô|“tþ!±ÇFWùÊéj“ñy–fÕ/–X$™h^Ð2×üÀ®6?ÝeÆÜxã >~£~q7]ý¦9]|Ñ/¼éˆ—^¶%³žXÜùwk‹;ÿf¥ºó§½²ñWGöé‡@á}k‚ü±9ÃþÅñ|éc{*ÛøÔ“½ðRÍíym¢Ê¼>›M¿8‹É¹¿Ùýaž϶Ú[^hØ®>×]}´ÑN>Øj©>Òlcy°Ùš;ñXâO=U«Î¼àù öâ•V7éüƒ-Ò©GŽâÉ'6ªƒ©Ž¿3çHüå/<²—Åû÷ÂÔíMñÖ/nd;==XâúhwÉæçG +íÞ\ÈßÝK:cÄú_öâ+þö#¾ã^˜ÕËëÙ¶¯Ïç9?ÞWìÞQYèõ°¤pûýÂ\϶²çGu¹–ï.§sï_E)[þt1?þ7#Ô¤­CÅК±LùÓ¥ìÎw†üŽ·†ðmˆ]ʰ³cMË?,䮾ßlõäzºÍãËëûW“ìžÉ³}v1OhnPÞøÃÚøH×r‹è³ãÌmzZ*XÖ^[ Ùû­tôͳ‹¹®÷—zµUU9v/±|x+qßßÁˆ;ÛÌÄ£ä>]º½ÝêÁåDõÅÆ­üîvSy§?Ã?i‹py\—Ol.¿øvtnâ¤<Ø ÝËC9–ï¯dʯ¥Û¼:® | ¡6Yw',çÐМªÛ‘¹îåy2±[»GsïË—ß6¥Io;’mŸ_ÈåZßù™ëÚÈÔý±VYòâ.êÔ$vǯë¬N·l“O=sTÕüÛ*UÚí™æÙÍ3•gçÔšíŸ-ÜüäT‘åëæ,¡³5Bzþ0~ÓË›9òóædîÖ3WåÕ–'ÿfª<ó’án>ráy)[~ß̽x†1±}~*W¼Whvô/kMªïÍ3­}·Øøðß—_îÚ`Þþ7'×Κ‚ІˆüâÆÈÂä–øâÈ–´’må%ö/ŽäË¿6fJ¿>N”lûòxÎÖ¶ò"§G»r­ßœÌ²¸÷÷ͦþ¶’Ûó«‰tô‰óïÖ + ǧóé7æ»ru/7И{¸Söü·»SeYó@)—=6ä‹fòn.dv~X+]xäjÙX!×7†§^Y+kÿ²B™}k–*íÚwæšÛ³T§ß«äûõ‘›Ÿž)vxq¶Hý¬>E|Úcù¾>{{[IIôý”Ò¨û)%eÍá1÷S*äÎ[qìƒÇÛ¬ßÞÔ„·f”Ç=ŒÏËjÈ«iÕÔµgím É&×›ט›|;1'¹1>×ça~Þ¦WdzùW¯¢Ø;oݸ³ï¬å3­.ò…VwùÚ=oéL«#¨ƒå÷t˜‰Ú-Þwùñ¿=síØUäÙ±£Ì½cg©kǾ2ùÙ½DöÖ/Îæwþ]V¶üÝQÕôN&×»LÎw­1©|±ÀtLJ%âÍGÛ7½º•kûò|.×ù*»õ| wç‰ÁÏŽRu»)·ëéFñH‹Z¸ÙàiÕz)ÑññBÛ'§rœ)ñj¯¬ +hÓÄÜKÊ z˜–Ú“]Ó¦9p?(ûò}ߌú6ï´Íþ™W2ï´ø¦7ÝóM¯'?74ùeÞ¹˜u¬>8»¦><'µ>¡À½µ2ßòíÅtñ]K’Í‹SÕƒó°8ÕeÎùO îÀïÜñ×¢xâÙ&açS®ü·ÕÒÎç,wøwV¨¶]~Ýž*<ïŒáŸ?’ßÞÏ>6d°ï^E¿²8ûW Õ™§*ñJ‹‹ºývœü¶9ÝêíuMDKZYòÃøŠmµ;lŸŸÍ•_ßH°{y6󋃅/öåùufç§ß‹Ê=Ô¤¹qß/ój«oÆÅ6ߌkäëå~—ïûeœiÌ>Jæ]ESxnÕÝðܲ†ˆÜ˜¦ä|õÇ+i&õ]‚iæ©;»– ‡ß‰Ò±·›äÃ/l¤kžVwnEZµÞH±~r+[¼Þ桬{·RUýf¥T×®”N<¶“¯µm—®’˜|áW¹å~trcREè=M…õ£áò#gÕž¿Z”<\¤ÜùëîÔkQho‹ðj++wy´¯Ôêõ â /çY½¹•-ýö0ÝöåÑ\ÿöÜ’âûaù÷#KÜ;kËä··ÓùgŸ,ŠlO)Žz˜TPx?L³·9( ƒMAÙ'É8]¸¨9+´à̭܃wB4õQ9NOvåˆ:“…'í1ê{ͱ•ǮÒû¾âíV_©á^ æ†æV,±ë¤ÜĆļȆŒ‚°æŒ‚Ò[QùÉ I%ìóWaf—º,ÌÛºœ6ÿ”z7¡¨àFL^ըܠ9ľJK3ãKȹ1ïÞ‡]ï22¹Ôe¤ìøÃŸíÚv "½9eWʽÔ]îöUÛ??šÇ·6ø w·EÞϨÁ8áq¡) {ï½à쪆°ìC-Ù7Z}3+Zƒó^Ìgþ|núªËÑìͺšÿÑå­úãc¨ÕÛSiÁÍÙÉMñùEw"sjnDå6åäy<,Ëñ|XžçÔQ§Q¿º–fóòŒF~Õ–.?mK‘;% +'þ´eöþÇáìŸv6íõ9žíµnuÅOæoz}.ÇöÕ™<áÓxÕ«¿øq¯_Fˆ¿7§:<ÛŸk󿄯ìI—³YÇ{ö齇g‡ Âfï´|p9Öäb×ãÚß'kìW:Ä$¸t˜qYû³†¿‰ÌëçÁÎÏwd´Eދȵ±Ocö—®mFÏ»,7¾ê’6¼í’7¼é ßvqFï»lÌ~ëò4û{—ÿ{s4ÿGs´ê×_CŒ:»¤9í“Mt­e®ÿÝVºÕáou¯9Á©óPIð½œòœ†¸’š»þmò˦dáa[ÿàI€ø )\~ÝšæÙZ]Úœ]âßTP¼÷jdî‰ë¡Ù¾ ‰Ï>[ ~Ûeóòjžý‹£ùÛ;J+’$V„µd•¸<®Íçþú"–}ö,XxÙF|gC–ýËcù®ë +·wä?Œ(ˆyT,|ìHd^üÈ<û=Àü~—ñ.ã ‡ß/Þ˜Q0rCÚ®Ñëou-7þÇñϦԸƤüÊ[÷4{oDhbꓳ]Û«³íŸíÉæÞ¾‹â¾òç.~´#qÜo{âøä`QÔ½Ô’C×Â4ne½ž{àz8yo¸æôõPMÕͨ<»ç$ƾ¹‘…øšØ˜TpúfˆæÊ­ Ì:â³î4ù¥¿o÷Ný@7ˆ¯‹z”¯üÛ‡Ðõ]æfty9<ß—»£5$ÿF»OÆ©ÖÍÑÖ€œ´ö˜2ñ»)âMɈ‡Öï¯i,Þþeû†³]ËŒƒÒ®Ý쮳Êj›öO’âû†ŠùK~V,\¼B1wárÅìù?)¾[¸L1{¡‰b©*Xkuà©Á«kÿ}êš]k˜_Ÿ„†ÔgfW]ˆËÝ{)*'ëjbnÁå„ÜÊ«QšŒ+Éy±;¸µÕ¯_%X¾hÌÚüø`ÁEEõ Å×c +ªnGäî"¸!¯!º8Ï¢í?œ-?\άj ˽@üÛ™6ßÌ|3<ñÍâÿÞo´ëã_Í •DÅôÑŠq=ôcúŠÑСНÈÀ|?­÷WŠY_MT¬X!*ÖKÚkÕ:K~d“V|­E^5JÑ_G_1Hû+ÅȊѽ') †ÎTŒ=_1uêRÅSwÅŠøÆáëÎuý`ÔÜ%(Ÿÿ›s½ËV¸þ‹»Õ³›šºëQùW¯g]¿œu¥> óôÍàìÒ†ˆ¼¼ú˜‚¸¦ä’ˆ¦ôâÒë1ùûé˜Fh +oÆægÝŽËÛôú´FõìOöÍëðÀ¶Ìü–vŸô‡Þid©þþ&°µËdÝ®?g® Þ3ÄЯzQÈ!ý )7 wý:{ýÑÿX`x¼k‰aþƒIËÌ f)Ư0П@®a¸¢¿¢¯¢Ÿ¢B<’ŸF(†) t†+& 5PÌZd¦øÙ*Sg™ÏÙ~Ë‹ÞYÓÞµÖô×®-ævùY¾=—.¾~‘$´½Û_ÆH/Ÿ$;>Ý—ÛœRXt=&§òJ”f÷µH ñ‹95W£sOÞ +Ñ\º”µãVDñÇš³×B5—®†f]½œUq7"7§1¦°£c{J× ÷Œ_û•þùfk²Ë³ò,ã¿v9¯ºÖµ`eÔ¥¡?I~Zs–¬TLžd ˜ñÝÅjkíõÑ;õ #k†­vô×™8Ö@1H1@Ñ[ÑK¡«èAÿé’ëÒ!ÿ´ÚŸ~îAžéG®Z¼ª'ùI‡>×üû¦ÿTÅì¹¢â&I{ծ雑šóÉš‚³I9š+ š¼+ 9y7cs +®ÆåV]ÎÙq%*çÐ刜sWÂ4Ç®„eŸ¼ž}ÌÍ·Â4Gn„æ\¯ÌŠoJ.â{– üò0AõçÇpïμü‹$?òÎÈkÍ[÷¢Ëø'K'Å”QSˆ!çsëEÎJ›^Ʀ/yàLµÿuà÷ÿýЦWƒWâôWôÒL¾PôÔ@~®9x†bæ[Ū˜f}ów$n¼ï +!>ÊNzÓ‘ìܹ» îrTÎÕ+¡Y5×#sênFä“uþFpfTcjõ«SÑwÓ +a›'®…d¼ª)¸ãü¸6Gø³3™ÿk[bH[ZaóS¯´¬ŽÐl“¿v¹®Ê½4zÞOý†“kèMÏ¿'9C|ߟ\Ó0bqCÈwø^ë\Í?´èÕýóuk‘;=òyÃÉ\œþ³‹bYâ£á«÷vM3~×µ™ö*Fý¤)Õ¦ól¶cç®\Ÿ–‚ßû¹ù/,KlcXp-.ãxôbTî…«¡tÜàKO^ Ëi½’÷ìnP¶ôáVù<ûϺxÓ7].tù­¿Ýµf‰±½b0¡ÿ¯\£ö§;‚ÿu?Ý3ý^ãÆ+f®ñQüÞ4»´>*×ü·.¯5»®ŽÙ?l¹½¿ö¬™ #µRìCÏâ_mN›Þj§øú߯¡Û{’ß÷¢s¯{jÑïñ\oò¯/ñªý#ƒu'(¾±J1ågÅBëJí5»Ö¨~ylýòDÊ®áÙ©·s]:kr»·Vä—!¯$Ø+'|õoÉÉs|¼KƒçwÝËn ˜ýa‹of7ÖõÍ(¹^`󿍆à i¹OF¯1£Fþï}òøçkýü®WçÓﺯ»'½3zäé‘éìíö¨Ý>HçÓµö¡óOÐ\Å´ÅΊ%Nûu×ìíúNù²Ë×®óp†gSUžæz<µC·ÖŠœ–ËÅ·¯†å= cøðFXqûµˆ²öÛ¡Å-wƒó.^Ë#ö™{êjxnñ˜Ü ï»ä9KeÅðþCéÜúßù…ÿÛãóuþï\SŸOcÚ“üëM¯ ùGbâùŠo'+S—y+æI%Z?Õt1ú¥ËÞ®u_\鹄Üýç£óÎ_Š(¸~%¼øî•ˆòú[¡¥g¯†»–S~5Z܃GDcj‰ïš¼¦Hí‹ýé†õ]¦Ožû}ÝÞP‡ž³Î?©Ö§ßé‘ßö%ÿkT ×£¨¥OÆi(ñI_“?V1Tw¢b` Š:ãƒûÌPŒÔ_§˜¶4L±dó%ÝåWºfñ¯¯„Ü¢!ñ1!'¬!#OúPŸlùî|ªK{µ†ø˜œÓÄW–“0_L¾ƒøÖ«·‚4í>Ù{IÎéÛ‘kôG—ݚʧ“~0”#uü?ŒâøJüü9^`žö'^ ×4¢÷DÅÈó_ [¢5ô{ňá‹úC(†õŸ­Ök–bHß™Š!ø^oŽB¿yþrÅ„¹¶ŠE–u:«vuM1yÖåhß¶?ŵyG°Ù¡sÑ9Å$ö=ºYÕq%ºúÉÍðŠ×7£v¼º^ý¶)¬êuKHyGSPq}}H ò®ÿÅÞ{ÇUu­{¿ƒªQŠ ŠbÁ‚E°Q¤—Õf_…"é½¥JWé*b×X¢&Ö{ï51&¶ô]’}ÎzÇ3HöÙ÷ž÷ž»ßÏçÞÿœù¬€ ÖbÍ9žñ”1ÇóûºßR/«õÿüÓÂùAžãe¡c‹Œµ-ð¿ÆâQ„È㧦ö%“Ñxm{d:j.2Õs@f†‹Ðë5hŠ=Îý¼ŠÐ"¾Wc‰Ð¯¹¼î[ãÀŸÔá·ç ;ÎÖ´òYUç• %7/wÜú²dÛ­ë…W.u|ùeqÇá+Åí_`zöJáfx~óµŠ6—j·ÙóÝþÏåO¿ >BŸxöQ|?šø½?¾‡ÇÑBg*šˆÇÉÊÔY›;"KëUÈjº'²±#K;²œ&FVžhü_d=“CþMhyÁó1®—Ôó_Ÿ.l9ÝÐNò–/7¶Ÿ¸X܆s³Í[¯–·áãùµÚ;è­:2üÉ᪤[ýõÛ>«m¿þyyç£óeÛ®~Qº ÇøŽó— Ú¾¾^¸õýíü­ïîçv¼ß}ÿzá6ÈIý~S+í–HþÆ >ÿX’£ý#{‰y0÷F~6ÿÔ™ëZ"+ƒéÈÒp6²0™‡}ó,dnì€çŸ3²4Y,LW 3ÓUäܬíCµMfùU#LjÃZΛ^»UÛ»_U/ ú^ýp¸rÐÏÏ”wÜû¢dë#·ã× +7ŸÀ1îÆÕ‚Í/ol}}« ãåíüŽ _mI½×ÕêyI½ÜrìÄ{Üþœoàï!R™iY Ý)øœ&b{4ÃÏÁÛhägšÖÈBÏûC<_1xáBñf¨6ݬîH{ÒÕq× næ‘uHù÷g«\ª§[ZÎÿ·c¹6ɵ GÄÑKÇ2[ìûí…öTìç'c‹OlÓÿg¦iŽÏo +š``‡L ¦`߈ãf#s3ìÿíü­C(²…¦,ŒCÓV¡iA­hŠ_rˆ: éTùÀ`ÕõTÇjWœÇ+¿:]‘xo`SÓ¹úö§ËÛnŸ+ÙüŸÛõ E-§®ç·~}7»é‡¹]ïžåöÞ¼—ßÝs½¬UòÛ·éò¬ÿ×1Éÿëßú’‘\X–žkfx -ÉÃLk²;ŸŒ•…¶A4Ûá¤EJ4i‡}J²šæ‡,&º!‹)^ÈbAšì‚眤-Š=¤µ¤ññ—aµåêÛêEn·ÕN⟋z2¼±úrmK×U›±ïÜzçÒØF·<»[°í›ûù=oæ÷þø0¯çÛ;E}¯nÀZR›ïsµÈÎvÙ¿5nZÿâGü‡>œ}ÎB¶“ÜÐ[_|®Èr²ö«‘ùì?&8aŸ‰çžkÖ–+ÕÄUÈÆÂYO!›™,šº(Ù{– yTš¿ö˜æ¢Ò›£6=Ów9¡ž´bà·‰îÕ‹¼_«EÔÏrƒ_¯¬8ßÒ²éLCÛ­ ƒ—/m9y¾t³ìƯa¢ÏÕ~’#¸¾¸økÿÕ‹RÉ+u¼×uõ*× —M-ÆLýÏk$¶é‘켤>ɲ BODÆxœÌÇÎEV8O_…f{e¡éNáhú,)š:y%²ÁþÒÊÄ? æ-FÖ—áœR„¦ÌeÑ”r4Ã-Í ªGóØä¸ö3­EM¯ —}ªžèöN½Úãkµ{Ðu”è:–ÿîmEô³ýÍñ‡¶D|s¤5þÉ®Žþs:zÎoìHx:¼-ô»«íÅZûoÞÌi|{;»©ëjy»Ï[5³0 ù<7]r>cHl‡,ˆÿ0 9¿ù +9øK3œƒXãùhLtàa‹ÌŒåd·çÇɧµW6½¿rzòêÏÔöO®>¡ž¹¢÷–.moL—5¾6v.¾ièœybôÊš[ÆnÇÔ³Ö˜£?Q¢òW v3Wþv©IÆ üúx œOpEæ“=‘…½ÍtOFóèJ4—®BóåMhqì-§†ûF+†Õ6«Ïàñ¹£^â~Gí þoyÝCã¥1CZóåµÈQÕ®á¿Ggeñ £UÕÏMݶþl½æ„zÎO|üÿ¢‘þö!ÿér™ÿ·jÁ§îºM@ûS{qãe{æðïbáú·©òÏYËø=ˆü‡¿û?%ò㿆ò§~ ޾QªNÜ‹Q|ñ<ö;]VK\uZfZÿs܃õ˜i&£§à\šd+ESæ„ ;§84Ã+9H+Ð\Ÿ44oe šãÈ ™s=‘½½š»T@Ké:e©'F9ç\Öwø©^wÕ~Õ’À7êPú§_ £¾Ú×,ÿñJ•ì—_²¨Ëõ®æ}†þ:ׯ÷õ\ÿ½jÇÀj±èºš•ÞV‡Rß'òOäó_ß+‰xóÙ–ð×g7Ë¿ÿªŽ}ð>KzM­¤îü¶ŽÿæEyÙÝÆîÛ7rËo7lñèù0eªíÒÃ.5¡jùžgø½P±ûÃz£ü°Ä+­Û`Ú¬å¤NûßFxÜ&Y8¡2œçn@Nñçt–Õ|eäÒ§¶À¶·ÌçG5ðWuDÀoêH¿_Õ +÷§j·›êŞߪ=ÿ®^›ý µm÷Í¢ÖŽÛ¥mÅ÷ZåΖŠ¶=¯³j'ïãjGŸ›j/ÑSu¨ôµ:™zÿ{žâ—{ üO_o<®v +ŽÕt[¼ ùyy"裄}ŒôÀW¶åÜByîvkEB³±PtÌŽÝõwáØû`fèGo¶lÿYî…Tý¨¹‹ÄÈjÌ´ÿ¶ô_¶©…ó,œcµGÓ–È1¸GsEÃKSðk~$ó%Lü«:^üuRÐêHÿÇØâ¶—âòC6¢þoe·ÿɾý®Xö½:KúR°û÷¥âꣶÒm–0Ã?ú°Ÿ~àe[¯/¤›NÏ¥»Ï,eß—È]Q(o^Î }ôEpò›P¾çîå¶Wÿå|îØS.ôéÙ:å·7ëE7ÔÜÂåÌÿö¼ô±_«eƶA&FSp½M™íæf#§¸ýÚNn®Øÿ“<ãù$ò9«^éSqÚÂ'¾_? øˆEÀ9µ÷ôVnì×{»T¾ØÄ½RF½}“tQ-Õ´[ˆ×j‹Ö§éŠŠ*Œ6³ ¸¬ö^?©àŸ<ÏWšä+•£ °,mñž¬¢÷üæK%5Qa¹:\ËÃeÂáoäŠsOãù3/ÃùËÏâ×ndHv½_EíùÅ“zåÁìøÞS8ùusá§0ÿÓj×5ëwL™¹ŠÔÙÿz˜à˜1w>…œù ·‚3c×ÜQ»ú¯VI~T§¼Sc­ã¸ËüôK)óˇ²ì|s†—¹z£¥Î QPRªŽäÈù“+EÉχú³žvôF¼9¶™ùþ}‰è¶ZðÛùý<ÿêó6Ÿª]EçÔAAý¯‰[NÍú›óÙWýÉ[ uðo¾tÆVSYpŠ–¿„B´*N‹è$þ~qŸ Ûõx9·ç— Õù'ª‹÷3d}–S‰ $Y&)í†+SÐKG£µÈzºÆv©ƒÆiá¸6a1šéD¡eª: ×ÍßNt;­žëñH½Êï¯jõÛ×yÌï/Ëø¿=ª }¦îýñïž—³Þf0—~‰¤ÏýMÁ]þ xð¤LyãY콂Îé1÷wóG¾.Έ“qö¿K»n8ŠOþ§·¸ëÊ|ifôAS[/,¢w½ób¿•Q[ï-¡ +;'ð½“53øŽ+‚‡²ª/¯g‡Ü¸\¡:ý A8ú•BØýBJ}³†î¸¾DV»oªj»!Üo3ÓCÖþõ€±47 Mšíæú'¡IûG­ùD=Ç÷;5‹ë˵°Fç÷^ͼV âûêÀÿp ˆ,Ðñ A>2$‘† žÑ ‹Í5 /é›!l¹¾’¯;î ENS&"—iVh"¿j"ô‰IÿäÉ^z£¸};_öé_¤²Ãñ“íû«'Uwd•_kB7íœÁ|""{4O.9ø»§¬öì &gp^ + OסbRtHßË®×¢“·’ƒ/<Ì O¿ç¤›¯-Ö˜.ø°4¨ûí¿âcæîŠ"Í®*4Çæ‰sV£©n¡È1¬YÃmÓ} ¯CjïóêUÞðãöûýßÍð*ÛoêÚ®T²Ã\Ò8øÌ/|è®’ßrÃ…ÏÛ4z0غý3™Wîl×ýLÓ©yÔÎï=”»¿bßÝ«S=½Y+Ù÷nTiŸ•¬ëÆbúÔ.øéÕê÷—Úø_×È~SgKÿªNÇñ,Á÷•šö=ª^曹{œ«( y+Öjv=žË=ù6G¸ù*ƒ=ù O¥n1^³Ú‰¥¡ˆôhTfOמ´÷“)ѲésЪًQ» +Q„kE¤šD¥š†%Så6L`z¾\û|…Bèc_IéÝ?zKw½^EU ØÐµ»íØý¯D°¯–Úû‹—tëËÅTç÷NÌÞÿn¹½Éé± òôØÜÖñ²þÇËÙ½ïèÝ、=·—H›ÏÏ |»T|Lí%>¬^´û7瀽ÿ±4`ÚÑë µ‹÷;uß_Ô +ïê@¿Gꀀ+jÿ ³jÉU5/:£öØtÊ60±H7(…èTÌPÔZp‰¥†\Ö–ñT߃åtïó•lå[¶¨Ó’-ÞlIa_¨·_TKé?@^ä{J½Â+ÿ¤±gÒ.}c½RwúQ/‘~¯Î„½|Ò;êð â!sÿ`äéˆÏÉy8¯FîÎË•”«Çíy$ì~,fŸºRÉEúb™ +AOº”*1 ô¢q;úﻪ }¸eý¶ Amºæ]·g:“ºÑˆÎÞdÂ6 ý'ÊþÇAÐ{Àï~"R~v3Z~ì‰Ryôa¿óÛõr%ÕóÕ +nàƒ'ìù”_y*=ð7/éÀKºñälªåÓ9²£¿H.þNÞÁ9ÕWê° WêP< zƒ”¥ÍÖÐãÈ¿ =tg­üð× +ÙðTÁs¦|Ç$jð{WªíêB:c‹©,±ÎÚñ»«ò³TîЖôºäl³€~fzãÞ©t鶉LIŸ5U}ÈNÜ÷ÐQ|è7ÉžŸWK:o,m¿4høgç £8—½¬InÿC)¹ü.àÈß—‹*vXŠŠ6›Š·ÿâÌ{ÇH:^,çm5¥r¶§2šŒÅB¤†ëRgä4Ý­\°àyÇÄކ^6ÐÒSfT›‚;Ýrz>³ûµ¯ü“ûráÈ?ôŒö?‘±»ÞúÒ-ÇØâ.+>»e<_ÐgÅæuaÛeIoœ óPºçýÅ«ù—÷éã?J¥{~ñ }¿Z6ü“;{ü;–¿ü"Y¸ð"N¶çWw*µÆˆM«0¢‹·[K»9±§¿S)ŸÝ­Šùæø6þ›‡%â3jQÐgjÏ Íoç³pŠA~l²fPfÏ8ÉQµ·¬þÔŒ E²¦4 ¡:pW)Ûý­SµË–-Ü2+œ ½^ÐÏoÜnú<á_žÎOx<Ü•üdgOØÕ ¥òoƒ¸ºÏç²OÏ¢w¼wcO¼dý/VPû~ô¦}ÈÔšÉä7™ÑE¤ù=ãÅÕ'‹š¯Ìeí4õUejzÑ þŠ\-“® ŽÐ Ò7›H×7¹­BSG™¢ñ¸nšo2 y,_ƒ<\V @Ñ!Q!´2V‹pq’7Œ“GÆé0ø\ÿ¢J¨4Ý-eJ‰‘œo=Ãüнå±ÛኃÏUtóùyTn9Ývi¡tè+Sq`*°ºÄŠ8MÛªüØË0Å¡çJfÇžpé– óÙÒ&»Ñ”Û°{hÒÇßIDÇþâ)9ô³§äð¯k$»Z%«=0UZ¾ÏF–×5žJ¬4€qñþ˜XŽ 7Ûº9S}lVkvOWœ +}¥²µ9ºþ8ó)%ÏÐb‹¬™ÎG.\×3WÐÍ=#¢'tè)Cí}ç½]l×íåôŽ'nôÐ3èg°Oa‹{¬¹ÌFS&³Á˜Éi3£ÚqœßõÞUÖso™dÏ;WêÈ;1}ýüµ’9û&„¿ðU4}ìLzà7/æÔ;¹tï_Ýéø +ƒ@>TC’¬ý[Ì®}•§® ¾u©DuíF{æR|ô?½dŸªƒDõ—¦yË¢Ñ\‹ihÎ˜Éø«5ò +à4&GW¶.GWž¬MGfêÊTiÚ®îžhöŸ«–ºZkÄ&HC£4!V‰úŠô*ÂŒŠÉÖãõ…ø =ÐJ†‹+ØCßHèÊNk&«ÞD6øÐ…ÝñÚt ÙÌ:c!¿Ñ‚|è¡»€m88 ç ³¤Ã?¹J7_/Ém7‘–ìœ(®;c'Kí0öðÄõ‚ãr´b©rsñAÒ è³”ÆUê9Îp@vúfhÚS4wœ5Z‰óȯ‚‹{§Èχž<åÆã|Ç•Á•»g !‰ÚRJ@œ*V›h #µbœ¼´ÅŠo?¾˜í»´Šê»½çÒ0þ²Î;޲C?úò¿cd;ž¯Ž›R3¸ Ló©yô¶‡Ë鞇˹ío|È\o8hÏnØ>…Þrc ·ÿ…„ýäcËž{Ê}ñ"’9ñšÅ1Ñ….Ûe#‹+Ó1±šÞ^,òr!èÜÇfRÇ1ùƒA7Љ*%bc°ïHÐdÖ·c[˜Ä–áGÃó o…~ïÏUšIÇêÑ)å†lq?Žçq>¸ÙœÍnñ‘ GçÐ=7—³}ÏÜÙ½¯ü¹}_‹˜]ßz½í¯ƒØO¾•AŸÕ÷tÕzÚAºû+ôA- {¾ÙÏß©dÛ?¬”¶^rü¼>?“U1–JÌ×ckϤ†Þ»Ñ;>¸ƒn&]wp]ýÉtªíÊéÀ·.⽿®–et˜x…¢Å3 ³©ÈiÚ|´|Á"´fÍä„ÖøàØ†óc? ü‚Xäã%B>~b$OÔ¢²ZL@{ü ôhƒÖ"hýqL¸&-ž‡ŽÔ$ü¸-ç—òýO×0ÏÜ@³›N*6`kwMãö< Rî¿-Ûåª‡ìø¢Ž‰ ‰%ì}@É=T +GŸ+Øý߉è¡ï=é]?yCOÓyÏ®¡PÒdÉÔî°“m»âÈx#N½Œíÿ›·´þ¬=Uc®¸ÿ“¤ÿ­‹¬rïdqD¾ŽXHÖô£"4Äa™ÚtR£‘t]ž®óB'4Ò ´|‰;ò^€ý¦ #´áöØ+{®xÉ·Þ\Ü5С½B)¥B‹³¨ÅzýA÷E¨Ù>úHq˜Ä´Y°eÝ6TÏÓå̾þôîx¦Ï¸œN ?@/žË¨3!=yI~ÓúåB¢+X{tÝ~zÓrj[¹{ +S}`šlÇ«Uô¡ï‚ØCߊéí?yÐÛ^†T•¢%b×jJC²µéØj pìŸ“Ê @SO’­:{ ÿȬ-ÍôZqÕGíé-–‚}æ/Î+&±)uc™äj#&¾HŸŽË Ú‘\ù~;jÛcgÒƒÜô©Õ{Ýz+qü V»!}¬T¹(œ¸–9ô„Úzm1‡c?µéÓYЛýkìù¯Â¥»v“ôXÈR[ÆQ¥ƒÖ²¡_\eÃïÜ!ßÁ¶é.Ûõ“;hQÑ):°¦!RDh–Ž‹¥}œ˜Â‰’,m÷þhÅ\g´f¹¶K) +’1H¦פ"qm™TbÈ$åêK£S´AI4^"2t˜¬V3¾öä\Ðô]WUF‹¹":ktpt¶žœÐTFgé©J¦r7–ƒÖhc0[-˜ê]Séǫؾû®Ü®ç~ÐçÊ×í±=Afà‰›|ï}{ð©T¶ë›tßî̉·¬üâ“ùé§k¹½¯E²]]¹ Cv\Qëºéðljÿ_Ò»|â[uèw\wÜ_$Ëh1¦3ZMèþw«¨Á·«™ö+ŽTÍáéLa·¥¬êÈT*s«©›[ršçˆ¼V àxëK&Ã_qì‘©"5‰æGÅN¢ÑÉÆeŒÍTb—Øor-‡Ø¡¯¼é+…Œòq|R®P¾Õ†i=5Ÿk<9iÃoø{OÙÎoVóÅVlN“_q`°6˜Üf3.w³ÄI®h«%ÑÔÉÁõ`&ÎÅËvLæ +·Z-ÉìÖñLb®“Xf@ôvj>µ'_Óéè¼Q 5¯>|Ш’­ÍÕ…>iÐÛãkŽÍê>›Ç$•Jè Y0{¦J øÂ+˜/²Ýß{Èö¿ó¦w~ëN½÷¤úž­ä7˜Úî SÀ¾ô5Ðb¶ŽhXÓï¼ù¡Ü¡çwâ…’ýô9/ÛùÎÝôéЃ¸Amýr1}ðm ½ÿ_ªýê"º ßÖÕ¨¬Í¦Lö™ýÏVBAwÝs†þqÐóíH™ϵ°x-:§ÑÖ¨—+™¶Ë‹éè²Ñ~Þ®ƒ¼P€¿€øÔšqü†Á© MÉ— NÆ×ÒœÏl5ƒk,‹Ë- NÓ–†'h³ƒéºí¬Ð’× Ïæ›>[Ú: ÷I4®‹&ƒö(ÑÒÆ±BÖyq±làÉ +<]ØÍ'r_,cºo,¶ßóS?ñƒ7½Ùíw<Ù]ßù0¾ âO~,ܽ—«z~µVõàR9ô߇^8“Å{,ŸËlž€ç®#»÷Môâ2û~ó— [zz3h•ÓjDÅײ}߸sCßø‚¾]Ü?‘ª>:Jßb¹¨—;0[ƒèÛÝÈÊ]312”\7ްrÚÌAS¸JÀÃX§:v%ZØ_º0lX4~¾rh¢3{ÞúÉv¾qm3zëC'_Тf‡ëÊä*#¶¸×Š-Åq×öl^›9Ÿ½ÉŒÍk7§‹q}”¾É˜Mo4aÓšŒ…„RC&¹b ƒc0pqB8 ŠM.«Ù ú[éÁwnôàKWÐñàK{'VQ®s:®8_ øxÀå6h qéåcAÃ…Ý÷U€pü‰Bqø‘’ß÷@5hFÃÚ ÑªÝkÏUõÚ‚ÖÓvnhÏ„Áu³û½/½ûƒ·¬ÿùr˜3 aÆ&¥È/í²¼…Þñí®b¿pw%¸–š @\õΩ`£ ¡A'èI•à4AóZ—¡KÅŽfJvOÂsÛ•ßpxf8y®òFÑáé:BÙ¶I #:@lB±0°@ŸMª#‹J×ñöçQ £¯… h¦+š¢ Z2ÑÏÞiG´Tàë†áBõàt¡î࢕Rsp&Ý~f!aŠlå­Øû€ÿ䋘¨ã§SC_‹äû= +<Öü‘§¬ââ£$åËëB_^h‚^9Ð*Q¸ÇA_>ð¨¶ÏæQ¸¡¶]s’ |·’ªû|¦t]Åh71Z1gòÅ5h:‘¸™\n;ˆ³PWË´AÛŸ^¿a hÒi ãd …Øg–pñØ×eÔ˜ 7™Ý1ŠÎÐ Ä1âè$ƶ'àXÁÚ# ZB80N;­cÀg”ŽrªMA—Î 8¨ Å-Tï zu8†¹hdí˜ +ZwÀ-"šQéõf cZÔÀ£UÀ ,Xà©¶ž] yø9&¥Ä +‰Ñ¢CâF¸ ±Œc%µíö2.c‹™H¯)á°od#5¸¨ìQC¸‚K&½z¬88ž0¤eñä:óL²N“èl”öÛ@Œ€%H, &,YøE¸N1Šš-‰ñ8¬L|ž¬“‰…XMœ#hP¹ºlZ½1;JÆÇ"´ò Z,øêÓpݾt¹í|ؾ[®|Ëñ…DónÓ'ÀìvŸbÏ}*ìóói‘§?Ë +Þw[E´![Ï-†9Juœw„X.|þ,L¸ü<úô †W6$û²uZlF ޽ÖlJýXX«br·šC@…k¸®@Î3—!ÏÕH‘©#S&iùâÚÕÃGŒsiœCÊc[L…j€&7èOƒ~)hÿ3á©:2&Z“ [¯#d5˜±µûg‚Ý&¦ýê徂rÏ3V¨ÿd.Ñ.,ïšÌìyå/œxÌœú /9¨öb6™NâðÉr;&ÐkSuÄRÜY諜4:W×ÛWŠÀ/Nθ¼&Ó õÍÉDÆiƒ.&áUbûM(‘L@lX¬¶‚m,½|—‚çRa§ð@»H¾éÑeÆ94–¤CôªŽÎWÔp].`Vq1‰º SÇu\rê÷Í}þa¡¡"eÃ8àu_ƒé¾ê Üñ€Ü 4C 7»h‹è`Ê>–«NÞ]'?ðc:¯,ƒ9 l_Kংf*›ÝbÆÆWPi:ÀÊàÓ[cl 楘Ó ×eé–PyŸ-»¾ÒH‚óìï@û—ŵ‰åM¦ õ®(¶#¼™²kà>¦+œ?®[@+X]2#€·Å®ß8–Íl1% ƒâEÕ~{¢'ëœ­Çæ ·½;ï‹å½÷¼¸¶S‹À.ü€{æÏÙ­–q½×Ý ”½¢ž¬æó;ñuj1¦ ÕýØ™Þõ£hNÈzž93†§…]VðÙ|×xáùÄ!6¶Â€^W¬'‘'hÒQYºt\‹ _kä4c rvXŠ<Ý@—3LC§Åd4›°÷McÓëA'´T G8£ÚD‘ßì>cà™‹‚ätŸŸ ô©°…ý(ó@[ˆï»ëZÌÄ7¥äR=7]ˆþÏé7¡ì‰ät×K`ޱIµFxnhúãÚ+P °Afð¹ÕzvøIoo +ùøˆð®Èd4˜wŠpœ€É¬ +Õ½c ­@2!L´¼‰Ftbž!Ÿ”©G‡¦éMyìù®‹+”ÝçÜ…ÆOçƒ]³Q©: Æm¹ìÌõ\] º_|Aƒ9ɵ¶^\Æô][eq³•¢¼w +p”µ‡æ‚Ö!ÓyÑY±ëž”úÆ›]_eD…ÅiÎyå¶©òMÃs€;È ½ñc‡ßø“X?øÔh1Uî™ÆÅTês±…ú4žR< +Íןt`º¯šo8VpÔ`Ì`- ´‰¸_{æ)ö7\~÷D®°ÏŠäë ŸÏã·=wú^z+ûž(û°½·V QžUoÆ—õO-CÐуý  oÌÚœ£æØl®ýêR¡çë5ÂÀK?åÀ=QÈà©|û]ÐOÄsyž¼´s’²¨i¢¼ùè"®ïª»Ð}ÃÛ¦ÉÉpnÃVcÝ,¢§—PmLL¦çñJnè??ü&Ö-`ô ÙÊþÉ$î§`?½aÏtXŸa wO¢60é-&tRÝzm¶®ˆ Õp[¹­X¾Á=¡ :ZXî Æö>q_rp]+–rˆ‰Œ×F…¢ùŒa ¥Õ™6-žçp-ƒ·¸Í—– E›'‚Ž<ŸZnDÖ;˶ἫØHž˜­¿ŸDôú¾±GÞ0Ò=?z°¹f É(’¯Ã±m„sȦÕtná™à€ºô|T‚NpA»µª¨ÇVU´Ùj0& üx°†@ ¢ø Ðc„¸ z[ Å zÃLd²ÑŸÜ0<]¾åür¾ãê +ಂæ(aÀƒö+Îùê>;ÐÒ”uŸ[Â|B+†î‹ÐâVÅj¦ —áëœ|ðŽö«.ìàÃ5üÞbnÓ±9LzÙÐðçRËŒ€u _¹ÄBÈÍaí/Ûn šÏO@gŒ-ß=…˘HEåècÇŒq ËÇôçÆm¾ïŒmÈj?!·ÇŠh× >ô zï¸@Í Ì,X#ëpCSÀæ•ݼ@ëëæÎuÝZìamÞhàúk†í½¹š|°tBaM„ø_¸ÎU{ìØîg«”½|Ùþ¯×à×{€îƒ*§Þ‚_¯óÖœG²ý·ÝCwÅÁC÷XyÏO¦óš30[ùæÃ uÇ—ïµ#Ü«ªOfÉ¿ñ†¿³Ûð¤û_®â+N'ëÇUÃvDßn÷ ‘êè­HÅ'O‚™Æ óÈ}Œ”¦qtÒC¨u%¸_«:ˆ|Z›©€ßŸèH3Û”‹Ö ð‘½c`«€~¡²îèUÅŽ|Z­±<©fœ<¯Ã’뾿ZÑwׇk¾ä¨Èm´ ZÈ_Aïz}‰0Îø?ØYôœ—x)VA4ÕJzmþdgAÅ(Öc¯Å'¦h§œ¯² g’2³Ù4PU[l@b-anàx ºø„…—]i,´\rRl»ïÜu×OÞqÕ°¼“+T¹í•5Gçã+8™z„ƒ?—2kD‹›kžÅï –Ÿ»£:s5´¸}ÝüPP3¢Å=pÃK¹ó–D¾ã~ Ýy9Ñ↚²ïéj\C/ÍA¨Gë‹è0œ[áü—°qÁàxÚôÊòiëA/Ýxx_c( Ïкø%òÒÝSäÅ{¦ÆeÕž™+€fÉ#6ž ×lKÆ'h—ì_±íž§ªû‰¯¢úØ\È)>RC„j°7€y¬—Ùæ£¤îR7™€Æ%¾ÞºÀ5Ttãëµí‰¿¢úä<ÐQ‡{HÇh!F“ MÖQ¤–%œ›O-QöÜ÷ » ó ¼#zû³ö«Ž„‹ßcÚÁL÷‹•Ló¥…lå‘lÃY\S²çjÏ¢wœÇ;km™¾,<]ز§Eq±š Ç­L,7RÆã„hʆeèòDÓ¶Øh*oš&€>70 2*LJ83ªÞÀX!lã¤J#Â-,Û9-8½n|HB¡0Uä¦ý©Å-¯Þ9ƒ~á­:q%:äê¹þÈ lÆopš¶N.Ñâ®Ù?“ð°Álæ-ì~"ÞñHÆ÷íÉáMØY8fÎP^ÇD`gQÊÂÎRü ;‹Úý½Ô‡p+(€&¹Ò;«‚°Û&µp °)žèÒNýg°½?ÙYŠ®Gk„Þgkˆã9.åâ5)l[Àš‡×(€ÕÓ0òiyißdøL|t¡™7 +øòÊÎûk„¾^À=`¢áõqš2.Bƒð[€^½kø¢ƒX¿{ßzÊQÞs×tuùÞ ñÈv?Ycѧ›ÿ/ºóVÿÔüÆKyôYxøÅ³EŠE\ýþYdÝ8å;'3éÍ&d]±þè\vó¹%°.LÓ­cçåוE0æ°ß +rNÂ+.0Qš2EÉõˆ6÷Úd]à"^ ð #RuåñØn2Ì@û\¾óY agUàkû';«ØY8¿K*£(Ùb š±Ê\÷þ`gqqRœ®¡ÃGhrJü·‚ôøðxÐZæTØ6×½Ö™>ŽcdM$µr,³NøL éMt¯7ŸYB´¸³…ã4<‚«Æ¯.8¯i¢bã°½ÐzaZÜ5Ã3¥ØyO92ÜËbópΔPn ÄŒhqþPçm¢3 Ìgй†ÏÝpÐ4ka?á÷Æçè¬gƇ*¶ÈØQŠÄ<ƒvV‹ ·ë¡?¬òÀÎR!±x&£€Ó÷Ý€qHŸ©ÿ;k°³ˆ^éŸì¬È¼ÑªüÞIò¦ÓŽªÒÝ38žþu%ú„Û•Û9‘0skÌ€c©,n³-}eö…x\å1eľ›Î,…×ãx8väõÅ#¯Ïï·Íj°o.Ûjf•±rãàŒàž~¡Ûiàî?uç™?uç÷<•þwÝùGî ;¯:{/^È!¦CS‘¿ÍZ^<8™ŠÎÔ…5 j]Î(>­ÁbXÜ„O]Ø:QQ¼Õü'—˜­ñžð.ðµå·œuÆѧO«1¼Us}ìf+ÚN:É7p×îŸM˜m“Ùw½`ï ¬•‚7ŸÞ`Ââ÷¾ß}× rRX”Çé+â + `ßac•LõÂþ-°aÓ6Ž¥Ãµ Ë ÇL#ÿdgõÞuîùÀZÊŸì,ˆ·ò´FS°g!·Î xeÀÎ^2ÔfÿÅÎ*ag©p½§ ñE•Þ0^ˆH×…¹ þŠõõ&ÏU–nDxf9m–ªüFKì'@ì³Gö~}pÆ&sx=è­ÿë롎WTôNÍmÂìƒ\£í¼³²ç¼GpÕžÙò¼zsÐ}Þ3aÁn80ƒÝñÖKúN:²ÀŽ6y=ްÀv|æ(߸cÆw=EX‰À€õ@¸çH H$DjÊäHÌGi@íëÙA2&6}×ta!ä’BbÕ‰8°( HŠXU´–2·Ö\U¾m +pС.'lSˆ;Uûía퀰`«öM {ØS5+½÷;_¾åìbàÍ;+öJòÁšÀ΢X±ÀÎÂ6þ‰°³|ñßÃ`¿+ÓjMé¥ã‚ã² BbÊÆ£QˆHÒå"uä 8~» ûd¡zp0¡FÖÎkÖu{ßuu%ð]噭檢~[`T}7=!χûS67ánìžÊöÝvƒØB U8ï(ÞfÍgâs.ÇÀ-œoÝpW´Y+c‹ B²Z-ƒóp]_3d¯ºE©öÜ—Ëw>3 Üylj°³¿}Ï ºó ÂÎâ:®»vVA°³´üa.*5ù¢6 ÕMØÔwv–øÉÀÎ*ag)ÿ••ø';+}£Es¸¶Tà¼r^`Çm³}oào@N,0eFžŸ­VÀV ¯Çu‡_²N‹f"4€K9áþÀëëŽÎ!`jà¼dDçxç4¾–òø"Â'‹IÌoyÞVK¦ý‹ÅÜî×þTï“åÀ?¤C¢µ`9ƒP«‘:!>m4®à+GR×ä‘ù£àw‚Ä4’©Â4…œz3XG„øõ¼/¬awšŽÀùOþK¾þ“ÙÀ«6·¿…ü})ù6“ýq³¥¢f—=°|I^‰ã¶þdö¹¸–²šóö[ÑÛŸº ;žvh¤ÇeéÉþÉÎÊüƒ•¦§"ì¬}óäM§©UãdT¨|vàmýRenËEÞ¹Áå}Ó‚SK ßšÔã¹íˆ{çeÂ+Àq¸4DËx„MÞ:AÈiĹ×îi¹Î++„ÞÛžl÷•ULǹ¥À€'ka°?‡Ô2½¶p^|Ëg‹@Kö=*ªÌ.©bÇý ¡í³%Á¦\xœ¶j]®>®×¬ù­WW@ÆãZv„/9ÂÎb ;ëþ*aû+ùð3 ìA†ú€°0’Š ™¨‚QÒèL:¦tôŸì,X_æá+mè›®¨ßï (i´"ñ½¤Ó–oÜ;GÞò¹£²úÐ\`WÊ“ + a¯ÌqX7Q÷ØríÇð9>w$ܘÊ.[ø]ˆràqÕ] Üxp¶¢°Ñ|±^£ ü-àÜ󧜸ž®°¾Fî¹K°¸ ûÞ¶ ŠÔ&3ÂpŽ+!¬{UI·­PÝo÷/X¨]<¢ášr•ý¶\l®žŒ‹Ô¤‚#4!v’ü4ý³ëÍü½8$‘†ipá9ºÊø*#¨o•¹€y>™ßtpŽbàA ÑA†{kóGƒÏçSªŒ ÒÊD-±,LC {~pì\ +☲ {‰‘8®Î.¬y⺠ö§Ázé¿dÈŽm<ÚúNPs±­'‡@™Ý>ðÁ +;m îWvÿ ¨;2_ŽkU`àÀúæS¸Þd„C…c(ä©Í'ýya¢ƒçà ׄ}'Àû‚ `ÃõFä!\ÛÑBûEgÈá¾ +°ã‹œ®ùø|b›À–É#±h†ÐuÓì“xí÷ë÷ýC‡î<öŸÀ¥?1J“p Ë{' ë«ÆÂ=}61_îK±-Ÿ/d¶^] +ì,åîÇ,µý…+°³¸MûfAÏ_±k*_Øo ZÖ,Ys>=‹°³€ëYµØ>«ð9áóvVÙ;Khÿt ×q~IJފc¾²°Ã†äšØï³òavË)G¡ ŸwUß¡¢ +aÍW MW´ž\Âo9·ŒpmážKj¥±ª×Àð«¶ç{n¸ }w<™¾+™mø½ŽÎžp>€÷¤¨9>O™½Õ’Š×öÍ5 ÅÞ{ äEdmcð©+ÝõÅRÂwÂ5©5jŽÌ:¯¬6_t +¹× Lª®ÉÀYƒµmè%šÎ8Â=+Â<„5L°‹ªã³å{¦‡ZYÜk ûoø¶³#¹%™GC3”µŸ8€Ý“±†õ&àq•vN‚µkaà¾ößóø”â1BL®–¢#Ïhûz¸½/ƒ”Éå;‰¸ŽÛË ³Öwúè®ûÚJ¾ëÚ*ņ]3 Ó˜·8ç#9kÝY°¿|€¼x‹0°¸öS‹™O=èŽKKàþ.Üo&½Žqå$&Õî› ~r)yV¹1ÉSòÛ'*˺mÉ=!ìߙ޳Kèöóáúgêy™<^ø„©‚ã +ñy•ݰ‡e&áÁyãü‘Ä<ï¹ú}öÎÏqݲò )ýÎCÙè¼Qð¹aï·ó™0X·Þvk×vn1̈_\Í ×ûØöz*ö=b¹æóŽÄWç5šCÎ +ïK| KØ{ ¼'Ø@â¬]AÝß}Ù |*¹7©u/ÄXx62QödÀZ8pЏõ:2ið1wó`ªÀ9Á½16jv Ÿ/ÎiåHXíî1gn2á™:O^»w¬¡Â=HÈå)¥F„‰…c4äHðÙ”•Ã3å­§—ÂúŒ¼Ûþ|ŠªÃ³ø¬–ñ°'‚‹/ЗgÇ¿?ø¯ü®‰'åÀ²OÌ7€õK¡åó%À<"ü `m.w˨³É}ä<¾À ^^ÓAÈG·˜íÛípBøpï|9añt_uv¼†Ô{P«b»…LÏÓU̶»ËÁçÉkq.\%ˆµ›90ýOÜ»îÊ€÷ê ë+½Ú„ì=µFØT½Ïž¯Äy-ðáßàŸ€»Üw%Õ}mÓvv¹§“‰cØžc#|ãN+rÖ#`ïp^»åHŽÜ9 öÐÝ—Hî$T M£Ã³t(åz-¨%€[90á¸ÜFgÚ,œ +°ßªz×tEI›¹WÖvl!×sußvÎ îÓ³áùº"~½Dzòí¶tç%'xr¿&ÛCQ·Ì1¾bЖiÜgO÷\q¡;..¥·\p„^T..Oø˜\|–ž|Ãöé„{HJvMÖá_b ÈÚl¬B9°´q>Ê×mÇ>tÿ°I\s½7ð/À›’'ep뫌äu¦BéöQÝÖd×L¤ÞÀ¯ƒk|i‘¿Id4‚<j¨wáºCž÷[yl³|B¶±m`Lãk&/í™{y„„<}ÄóÖK _žÔƒ°gKQ1h{7`^Áç€ûÅòÌ-æP;ƒÿ†<’pÓÓjLÈž#`Ágn2ÃqÌŒÄyà½bŸÂg·šÓ™ð„a¿bA'av+ ÷Î-¬ÑæT›VñÁŸ.$œWX3Áy(Ìq¾ñøˆ?ö)öq„s¬XXgÇsLž¯])¶3\Ÿ@^6ˆk Ålëç a!'d;?_*4à÷ÀçIxbÀþ0¬óÀ:yf•1¹WŠs"à³É·? „>:6çÛ°—¶_·»g‹ŽðÊà>]nÔIÀ®ƒ¹M®ø‡MGæýÀ5{§Á~Wà&ƒö Âü"9¾¶à¯”EÝ“H\ª;ä@˜àøœù½S‰Vï´c6œÃÔŸÅe¶šA>GÎ ö½t]sùD[ÑI:À —µŠúäë ~øë@~è¹?Ó°o&¡ ý!ÿá±›œf‘ùìÁÄ*#ò¹É¼>6_ýñøx|<>ÇÇããññøx|<>ÇÇããññøx|<>ÇÇããññøx|<>ÇÇããññøx|<>ÇÇããñÿó1}ºgBÄšÐÔÐ1úœÏýén¾K‚ñ3ÒÐõ©‘)côƒðSÁóÝRR×Ä„§Æ$&„¦dÙºç¸ÀÚw­‹­}@hVdJð‚àeÁ³l—ÛÚ»ù.\Œ_:Ëv.üî‚y‹mçK#CãlíGÞØÿÜV”“€Ÿ”…‡ÆEþñ»Ëácô–-pvž·ØiÑÛe -ç¸Ôy¡müÿíù…Žó-Y´Ð6žÿã_øù?~ã¿=ÿÏ÷‰ûxüüÚ1úìý„1ú’1úζö³l9ü϶n‘cô“ÿ¸:^1q‘.|ï‰ÏàÏk…{¡-ç=FþšÈô˜ðH@Þß–ÃWPnK®ÀüŸùªENÿü ‹m•¶ —.³]ºÿ·ößú}øÙ¯ùãË2[Güç.Ãÿ[€¿%/ÇŸr:ùˆ0À.¶Ž —.]†ÇÙWßÇ—EžÈ7E² 1­ @!LSD‡jIÂ5EQ>þòZ#E~þr$¥ÖjÈ" u¡û‘ŠÊ×¥¢òt¥é:bE²¦§›­^áƒ|½xÄÄj©’5ƒ¨XM/?­q“ /1e4±r­¦4r½Ž$4I‹Ž/ѧÖUè‹"³uü¥Á(P†@ JžªME–’†djûK‚Éßö“(ñ{Èçj_üUŠ$|´&tCÀÎõ€€ò;>Fƒ‰ÊÒ…evÝxP2RuN‚{è€%ê½qÅÐ M:^Ö×C×)t ÃŽdèÒT–uL†è’dÂ’µåÐ5 J(q¹ú K://€nMè,âóõ‰2þ*_—­'Oå’f P™"Š%ðûЙ´6s´µ^W•Pn¤LÁ?­Æ”Jؤ|¢˜™­+ƒNcF¥AËÃ5A¥؈dè4„nb>2E´¥4èÐ8->e“1tÙ01iºLt +Q–e.>6Oº(AYUF…hÈ„0 ºôcñù'fë+ò,Õ»g)‹ú'C‡²D£Á†§é€â9÷ªÓ•Ð}»¿t‹ÂõLÙhL” +ºmä¥;§ðÙ´J#.µ?ßdÊg5™±ÑE£%Ê-Pså“ + ‰’FþK²;œ(ÙT“kE[&B‡ìª'»ØAÁÿ&8V‹áC4A5Q¬ŒÖumPgI¢4ÄÒP ±“ :ø8¢ò G@9ð¡t•ÊäñZ>&_SüoPÈô\€ ëÔ^Ù˜ +}:¦JŸ +ËÔEo¨šŠB¥Z§Š˜~A2]ÕÜúcIx²–_ €Ü½E(º^C³t…„ú±|ê&c.¾Üâ5Ü Q¥jùâßóõÅÞ P0‚ÏJE²àtmV™¤ÍFeê*Ö(ã åi•ã‚ šÀæ&Ës›Ìa:…ÏMyf£™"›•²¸Ï”uf ÚHT®²ªÍÀ~ø¸ =&&CW‘Ó9__+9¨Ul±V´u–7tTÔ[ÂïðØvø„L=è4 Š%¥Ý¤{~D© s2Ø|pv³¥*9oŒ2%Ó@™YcJD©a}‰(I°¡ëu@•Ôa˜à-6Ø9t÷Jtˆî½¬VsÒýWf¶©(ê›LÔ°Ú¿X&tÜXÝ|Áˆ‚›\j(Sâ±Àö@:’S±=CWnÅÀTPX ”·„<}Ò’]n¢,îžÌ§Uã×eŒ&&Ð ‹ÇtéEÅéðy½V||©XˆÔôrõÃ>Ò IY<ß”éÚR!I‹bñX¦jÓø!Öi (ÈŸ!Û¨´ˆ’LdžóábZ…@…>¨¸r£ +‡¯4e>x1¡!a£5ˆº2>èdæÓ[Lùè=™2E þ¨U@g²<¶ØÔ"Èø¬ƒ¾‘ŽkP¡ +›5Z¾®Ü€R$iÉØ'jËו(2Ç+SjMñyŠØ,=èPUe×›óáБ­ ݯ|Þ&ÒAJÐAÇGŸ3ð8ÕžÌZ3Ejµ t$…½ôÖñdœòÚ&õ'æC$thC‡ª< _WP¦À¾ºH”•{ì•›Ž/RnÜ3KA¶ÏPæA§|‘!ñØŽtóbŸŒ}&tЀ]‘nU1G:øˆOžÔèÐ$<~k‰Z0ø:ò¹a<ðk {®¨¢Ë8•¸Öèƒê,œªÍ‡eë‚Ú(å1Ø/ÒŠMÈ_ £Ô2@ ”hA$×QaûMª4$êùm¸Œjc舦q.@Gfê° U† HÅo<4S^yØž¨Á…§êðØ—’ŽQ<'ƒ!¯eF°ß´-æÐÕ.u4.R“(`?É…$ë0Êȵn|.—¡»›tôÇe’P²…Nû<ǰ?&ø $–X6”ñìÿØØõ£àÚÀ| ¾¦Æª/p|•ƒ:^l¦ÞHg(þ õ§æ“¹…kðd¾áŸ/€ÜF¨=1ÝzÍ™kül>Q®;6›t5&n0âs:'ð?Íu>\É7]qäãëDRðÓ±ZòìfsyÃ!¡éè|è'×®|ûèÊu9¢€TÊxœ_¦áqMÃñ ÏGEî–‰ªÒÓÀWßáBÖj2É—ª@ýáÌb9öq`› +P{ÍÜh +jˆ¤##äA¤37Ø(O.k覅k‚çQSÁ¹Pd]©D!|ŒWJõ8¸–rðyD…¼ÊæŸùGŒ…¼ºFÁf@1T™°þÙ­Ÿ…t4ã’ÇñŸÅãEb>ÄþÌj¨³@±€¨Jn:2Ô²I'+¶QEV#ñ•ä‘QkÂçÖšéü((¡@ÍÁ™@8àJz¬‰jGJ¹9¿äʱ$>—OÕð  ÎtT2©±ä¥=“ù†cs¡+™KÁã]0Æ>¨Ý@Ç*PH@1TQ¾ËŽOª6Ÿ +êxð7H'z\Û ü&®ÀnA›)Ò“q"*C|%Ä +ÏbŸ•ƒv.JCŠc¹H¿âZ¾—ðñšR\QŠQJø³;uñ٠ØKº^7²š(Å‘ç œ“ï7™ +U{§sõŸÎ%k.ë }†Ëj1ã +·M„“ßc „$P;†×a@%w.¹j <¤ªDMÈIɃÁ5™ +û靖Q€<µÑ”ØŽ¸Þ þ”ý + „œ3¢ðÐóÌÔß1Ùz$&âñ¥·Ýs…}¦ñä\Pû$> ¼Ï|äÕ ¹® &¯Áqk,Ø'ä‰düRcäü7€ª‹(Ë‘8‹ã‹€ã øa’s`[&ä’üfsÒáó‡pA2ãpÝ›£Or;ù?ž'j+  „ç/Ø$ø!ÒIüÇk`¾Àœÿ,TôM!*Vøgä³UnŸ +t +P;gêÌ„ø Êd0ßáïÀÜåPÏá°­‘8*Úi:0ψÂþ› ÖOEàš98N jFÇ;h+ÐqO|h§%Ô²tp2©õHg:žŸpýäYL½ÇX>×8&±±xDfé28m ì“__7ˆp¡£]LáZ… Ñ€µ$È á³±ÁP·ÇiJùh\‡¬ÓÕ; ÿuÈÏ`œ±Ï‚˜Œsa=yõáÙ0¿ 6ƒ2,ŸR3–¨–bßù!«MG%iSÉÚ$¬¯KÇdé‚.¨Jq]>¢ö—¦ klB™’¦-†z]ž %b#4¡ƒz +®œ¤ÊŽDI×é|LÞhPÚ#¤ P‡)Æ5n#ÈÓ*wORÝýx™_àÇ +6M {ï®à†ÞúQ»ÿê)ëþÊ2‰Š?Ø`vëx*2E[Â+4€ìƶwä/,âÓêMèˆXõ +˜Br!øMR4à +®¥·ü/ÖÞ,ªd[.Áœ31笘D@2t÷NQÌqLäDrÎ9 ˆ9€9ŠHÎ ÌNpÎ9û¯UÌœ{¾{ï¿sŸçƒ§èf¤kWÕZï»Ví÷UuAù9Œ NØ–??ð§ÔÖ{ðpRÕsØS„+`®1ÒPP95jÙ9Œ-A!È:x*¨K[ Q±<6…ÄZœ³À¹„`X÷8f¨ôeÍç‚óV‰‰B³Ç8¢ñ(ôùz6£s7—ÓjJ_j!j¡Dñå„×8À×D]ög·1àÜ@®=^{°®wAì„| ŽÀ-˜#ø÷!VB]è¤÷Xú€í0‚Cœ ®8$Î" +Ô。 +‰Ñð{WƒãQi=í9Ž9æ2ö¬Mcñ^߇¯8/èjë#˜w‘¹õàÏà6;°ÎwPšqV +Üaç‘·9S þJ€3âø!uP—°ŽšŠ÷Ò0Pìc8 §0¯6ÅœÆDh†LÅ–ƒˆÚ$~b{¯Ý}vCAQø:(ÀS’SŠ ØÊ~´•ÍP؇"óŸ“=†c,Ô-!vb¾7˜ä?’ç=Æ€“Ô#ïÀ¹ú'Àh$VBEøó Dý”?€3bŽ Ê Ì•VCöfŸºþ‹V¶Ü6`3ʉ»)¸´€t9{úÂ8ÈEô^ü·A9p+¬G—p¤’â| µ'¹sülÀ¢¿AAóõaÒ“€ + à~PžÆñr9‰¡ øʸ„¯{M[â0àse1á¿Nñ³¤n ³ÇBÍPj8Uf: ¶è2àeï´ytRùvâˆtÎwÔ3‰*„Wì‰Oæ"&âõ:½U“Îx·“¸>ƾÙÄ?_ J‡âÃ^£!ׂó uÐ~¸^e¢ßläB +Ösö1Ó2톃9S²™NiÜA”VÁyË1i&ë8€.Þ[ÊF•næêÔÅI5šâ„r P1P2ÄyÅ%Nx)Qô%KÈKàŒâž®Bð1~H|s—qV²‘EªzF"µ X†ú¢¾Ž×ì)âÎy?Q–?tn8à pNÌŸ@ìM¼î¡Îõî„÷X1æ- Vu;À½Ô?-m‡§¥'P&â΄l->á?â2ਠƒš;¬IPwŸ ŽèBÖR;è8B|êâxÉ^Çá°6Aõp¨ìgOR«g¨í’z§}è4©Ï•àG1†;ë>°Q49í6ލûz$þDÅm¤®~Ô£o|0eöª3ö!S`ý™H+@]”ºÇÁµ"Êî°Ïqœ øÔ£\"”IMjH¯,!õ$Rÿ‰œJ¡P—f1ÔúÎ@-ã Ì×Ajã²38§~´š6 B„ñ+Ž“„CyƒàõEàÂxŸ(ß_?î4JÊî—æÕ2¢T”:TAU”YÛàÉœ5æ/ç.N€ú*{Îs<¨ƒ×ßÛKÀå˜ð'P¡º·œøÄ¶)3 Â|Ažàüò–1ÉïÔÙÈÊM¬[ÆOÅvñÓÙðû«©”z5põâ¼Òç°g'Ò‡pÎ;ƒqŽgš +ìI\…“P³NªÙÎEn$*,Ç`}xŽ‘8O‡Ü\ . 6DTÕ@Ñ ÔõÃ<^ ×[U²^”Ò´•(vÉì9>ø: |ò$ÆMPÃÿKõž`)ëÐ)d๬100`aö¤ï8‰mì_?ë3žÔqÌ…| +Óâ 71ÁWŠ}r—ŠÏEMe­Îƒ×‰Û~orÛØe]|m¤g£§‚­h8×SÕ 1Ž·P#aûE²ßvô„dÞéòuûQP¯!µBË8¯¬y¤FÜmÿ™a Ð kS u¼?"èˆG«™«í’» r:ë½(áþåÁY9 g,0±üy0p:ñÏA!oÉì£A­F ø9ô¦¤xe+P[†øé–2”Y‰B'Ô +àz¹&ÕÍ?ùÆJl0¯Ãøâ-Q·àëc€cÁ{#ÊŽ.q³ÄÞÙ 0w^Bx³#ž¿eªI¤Æœbßµ¥ÀéÅþ¹Ë!&Ò±EÙà«XÀþ°¦ÝÇÓ˜?°l†5G´9€O¸ýg‡™¹%Í¥£_©‚Û ës{s"`,ä4¨]KŽaîíš3G윣yšpIœÓAÝ \И Ì+qÎE5‘ô¤"8G»”4®r§$±NDc@P<'ûç56 箘—ªld>Q$øÖ6V æ ÜAÀ¡RtéãNAFû¶¿ø:`9¾¦À׉ãÄa¼çÚŽ$êš8ÞŠCî­–¸'©H]“gc<ƒ‚J;©×€[QøóulÀƒåà–nÏ„·a® +†àÄ$ÖíÀ|}w×A†»xcQ` xº‚sÉV¡{Ž6…þ(uPâ«Ô5MærÔ5˜CöÃAi–²°½…÷Ž©¤ßp yoP8q8Ž]RÛ!.E6¼þˆ"Ô@¯)p÷…Zâá¤òO§_pŠPí‡üñÅ.žð?pŠà0lnj$'ò ìGÈ ,æž š +kÄɳ“HŸ¸ý![²ŸH Ý9V™óº:Ÿó»»t ~á¿ +{€í¦‚âô‡ÆÜ0ùJT o-ƒ=Kb)ÄNÈÿ€0/—clCûñkÀÏÉï“^bü,PR埮"õˆ£N£Ï·…“ÞãåGð8plámÄ)"|›]o@òÇypŠ!)"k +ú9‡AÜnàpaúÓ)b:8EÀØä9EXÙP»|²^æqu‘cÎj¤˜AÍÓ=k.qiñÏY +eLBÉV64o8™Àï‚*2ç{o)SµܤT°“fA½Šôwc¼=3ˆQ2O¼¿qÌ„Ú,Q¨wd kÒsgqFƒ.úNƒÅÜ–¨Êb<jžSÀ)ÎJ@8?{üâR€ï1í;?ÄXh5HO‹š§8eÓí†[œâ½Ëà=ŽŽPO‚3 €£ÀÙ\ €A??‘Ô/1¦bã*¶Iü®$®øš1ñ%[©Œf *¾l³0­i;à4¨]š`¼m¤£Kœ"D˜« é:E¨@l€Þ•‘± ™HÈú„¿EŸ .iu–Ôf wk“ðjPÉ Ü>é7â"¸ŠîÖaЮ-úhçöÝœU¡Ö*<_1SÁÍêfÐÂ00QœþŠs&Ô ÁÍŽ8s@-x9¸y‚SΙ€É!oçK¸.Dí3£ESt½Wï© à” Nƺ n6B†CàÌü”©‰S„ƒ ôiİ.G¯I}òÀùá0ߤ¯aylùjub\+ÉœÀÝö¸ý(zÿY‡¶{°Aûb‰‹€9¡Ö Î]aÖ²QÏUg‚z"Ì)Ä&êÁÚÒ i¤ê¯}T¢Ú–·†Ë¬×u~ˆÛÐC‘[ãXî2_’V±[–Ù ”^j7f2:´©øÊMÄ)ïÎçêB*.Ÿ8E0±%›‰SæÏpÞBßÈ IŽ+€[¸BЏe{ÆÏâá:à!ýW§ˆ9EœʘT¤%‡Þ…ž0ÎóLléV.ºh3‡q'©ø^] q„pNÛH%©çElJû.îR·Ú¯ui‰Û•yb‡„™LV‡6¸°Î ŠØÀ—à|~ÍSãɹ›Ð)ÀË¡~\ø/8{þƒšÔêüpÙqïqàd½OPeÂßnà/)SG½Fº;}:x<¬Oô ‚Ž–1ÒÐÔAº:¦È˜;Dú¡€;™äj5P¡Us¨a ip%:9”ð‰À{ká̬QæÀ™¡æÒ0viJ©V°AŠs©½ÛL&ý?8Ëá j®i*TrÕv.½]—8Eç.‡5CýÓ)ÂúO§ˆÓÃeÄ)âúJPÚ—žöžµ5!ÞO4œ=ÁXSæ3Sg¡7î?? jmJ†Ø=GKÏO! +õpæÂ#c>Ä*X¯$*jô³Íâ°ür—˜O¨¿ƒ£Ä©WÒ\P:Å<\Í^m6_jÒ‡ùÇ)kãJÕdÙåqrÅ..ê™*Ä6»N”™¡vI΃€Ê©oÎàÀ¿¡g÷—SKœ"jwˆ3ºô$Y­ÆtvŸu©Q»5z<ôÇa¢ÖC©Cî#þrŠ`â·I1/ƒ8%W‡Àë+en!Ê$¿ã\&¾¶\úx½Ô÷Æ2‚ƒàÜAÎöàxsÅ$m'Vhr)¥šLJ™:Ì/Ôž™°‚µÐ»‘€ëµçõ…TBýV:´p5{!w!øx9‰Q~w–€%ë{e!`:‚Í¡x\Ü3çs1¥Û¸„Juà<ŒmÔTà ЯÞCö`y8·‡×„8êé&IrÍn6»M_v»ÚBv­YÌȯSà ,Æx¿Ì…¸&ÆûjQÐ/2Ö£üq[Á¸Pæsw¥ÜóÒ‚g~öç5À]B’X¦)Î_GÎ3@ÏÜGÿìõ‚ã&¸¨ÂüP1ØðkÀ)BjMjP€3Gr˜9² i dþ¹«àLǦIžEjïP:ë=ÔØ¢f'5 PÎ=í9Žôx¬½'Bj+²¸*-ILñöÎŽó·-œï¸¹T敾jöÄu’ô¡ý&B œ¹Àœ%ì•CñÓª½ò‡¥‡ÁÙQ_Ç309Ë–Z²K–Qc$¾T­G%åo"ÎŽà¤Q¤ +Šù `Múà:…1ÔÿÜ-0g³ ™ +}Q*sSŒÃ¥WhêR›8E€;9ë‘6{ ?‘>‹þ9h<8¨³>O–§›€I„Gùg.†š—Ô=~6qŠðpŠDÝW7¢¤±¿ì æ®)*Ä• óT¢4Œ_ç’+5¸Ô-ÂORš4 gn>àvG‡ýnwÊÿt»KëÔ‚s?Ff@Qœœ3Hœ-s ð÷A1=¶\]’ڨÄ®ëk‡ô„Àqz©ÀÑ¡–ùs$ÉõÚâá‹ã²ûU{9ï5`/0AÏV²ÖIJ ˆ\øéÿ0žÄbçÄY °Î¤¶hÂz×ÃxPo—qHp~Çy^zÌa”ò8‹>3 â»ì”?9W,qS&*ÉÐ;‚³epæçE1(,ûæ-“¹dÌžà_âÎ=Jè¯à¹„³bs€«žô¤û8Rë?à8Br&óè+ó%Á×Aü# àTîNb˜¿úçgX»œ/©«CÝDžP¿\ëÅŽ 3“@- +Îû˜V2?é2Njç7•(ãÿéìsKe5í’ß+Ùg^ðʆ½Ý"‚>•¡žAn"| j;àìpg)¸Õ2imZà¾É$7¨q᪒‹·–H<³æ§]èùÛ†)AŽ=î1†ô`ÿÅ)‚Æü•ô…<gƒ«9ð Q\ÉFp›£º¤Ž\…׈2ëys¸DÇy÷ÌU¢ÿåyÎãßXÁD?Ý9[晽°ß_õUÂi}2² oÕ¤‰•Ú’¤Ê]Lzí?ÝÜîršLÿ«Û]¸ÝÁ9L²Ç ~„×"Q¸²„8BáüçÁ™ˆ¸'y^gÀU³P"ë?àñJ±CòLX€›±Í:œß•EÄÙÑãê\p‘¦­#'ÓaS ÖgaÛÈ)Â}g†@ÏLŒs9à(Iz£¾cE¨=Qâý +ppqrÄy\ÎÀñê™ÜaŒ= kòÌÀY5RGР{+HÇ pJ;† œùž˜ó rFÎ2úç®'r>ú ÐGÙsnô© ¿½!¨QÀY©{² +9W®Ѓ1Œ£ÎNbŽžFÎÈà|¼†¨—C ·¸™àµZ™kÄ,©ï•¥p¾—gGÀ̰VÓ«ôÀU”Ñ®FÎ(s g ጠ+©;ÆWlš (Ó“Øœö×…«‹È™?ˆûÀgÀÑs8»â£Lö*¸M†ä­÷d‰[êÀ˜\Óç°¡·WRiU;¨ø’ÌÅk ›È)p&bÀ¥ÿL\œž­'ŽB!J ¨OþmpÙúŒï­%tÌó TÔ³5¤nÎRÇ/Ž…:2qŸô»»\Âe>W—’3}pÎ.ÂÞñ¾±€NïÞ%Îì5{Þ]DÎ×€«à2ïì˜3¬w¢¢1ó +¼7~!{ú¨À)wÛE+ÁƒœéÅø°.8ã8%Ì„¾'ôüØý¶$ïÃ3GÎ'g[“•¡G ܇> ŽÈQS™“Æ€£7ð$p¥a,í’¥"*^¸Cì¦Lróq·1¤/;¢HpØ1»QRœ‰J<9/áNê½äïo…Zª÷õE„oä.#Ž&®pÏÿE8k…ó,ðpØÁëC˜·Fâ—»æzÖЫ'ŽPÇ„þ%Ô áŒ/ÔùÝ3ç’ºôLqì%½|¨aÁÿ‡qwþÂGÁ9 zͰFƒï­&.PO‡>—Gê<âZñ:äázIèÝ5Àãê‰q³ÁžÍ~§G¥5©³£ølàDö¸ã(xÏÇl7X1ä´³!“ÉXa<˜ÀÚ…øµmÇS*¥R ê*dLÎø½+|^?aO×wìÀ»ËñsK€³Áù0p­a2ZvQY-šP e=.ÍæÜÓUàœÔz¨„²Íâ€çkH]ï 8¯|›à\ÿk‹¡WL\ÛÞl†Økî÷€ó"øßX.ö¾FÎËBú¼PÓ€ó8Ldáz&»[W”X³Y|:`myœ•„š"ô®a¿‹½o.–Ø'Î$Ž-¶áÓ V„÷ÀÒr%÷ÞÿùÐÉÄáÇ7©Ïå%$÷þ¯L^?ì>Š;äIäŒúA—‘pêh"³Cgê-†Ú’Ðì¸"ÔŒ©cŽ#©ý6CÁ]ÜK8—”YlHþZ&ºl#ìp%ü^Aˆc,àb8›Kœé _f4Ÿà\ +ülÍÀ5ˆœ9•¼g8ƒäÿh%Q¾e ŸÇ±Ö5œ5sOžGx)àpÁœXr1oôê—æƒS–Ô7o^¨J0+à0›0%ò çäî.#8êÂ8_’¸à’ô¬.äÙ:pè"õK¼îñu] ®¡à¶N%à<Æ„?\Kz(p½ýÓš ô„ ï5cÏ”Ù?á|F§”í`bžn }«ã^cÁ úü’ Û« žÆ†>[N«Ä©>¶P•¸ú…箆¸LÇá8Mrγpξº„`ZpŸ!ß›KHîÏìØ-ÊhTc/dÎß…ú¡(©yô¤˜àÂ5À_¨øªÍâÌ#&³{7ذ¬û {à§J'–oÅ9Kâ0ôQ1?^5o‰çåù çH}î,ãBï­"5PpŸ¾Ò`B'”oa.fÎ%P«:tlÉwàì’Ö¹“NíVgCK6Àu„øgXÙÐ×ë˜ó‘“Y»Äiœ×•yLjÛNIF“!¸¦“z#Ü×zž€‡¡^àvIú€ì÷‘ä^—«s¥Né³á qç8“ 180ãˆÇ« æp»ªÂ¹_›Ëúç.¡¢ðßÌj;•::vHšÆ¸æÌ¦"J×QW>íf®õ ¯|Õåþ0¢_|3£ó?îaòú8æò'}*ëÓ.:³_‹»Ñ%”>jÚ/{QwRú²ñ{¿CÊftëp1o¶š]HZ ?j7 +êäì*¾fà‰÷é"qàãÕ\J£¦ürm‘].Ù“VNY¤– +$±EjĵøLÐd¹c¹ÆÀ+éÄêmPŸ‘=]ç2è¤êmàD8'Æö\Ö;6û½>›Ö«Å&·í„¾ <ÀňĹ´f5œBS›vP1¥¤.Í=Xñ“ÎlׂØÂ&5«ƒû#¸çÀ:“ú\_Jj©ä¼è­%Çà+çuuúhõV•Êx·“NkÚÉd6í–d7‹3 Àý‘J®ßïê7ðÞ©„Ê-°N`]Ó©íêpv„¹ü^½Þ,iöö;J˜Ö³Cߺ…Êþ®Í>î6“½û™{ÕqTú¸y?{·•_Çü»²[5fÜÍ&‘äfþÿZ)In£9w·“¥CJÖÐ!oVS1 ›ÙŸÕ˜¼NNö¸æ°,¯Ú°Œ,§†b2ß늲Z5€+Cœ5`£Š6K*v‰ï¶Š¹›Ý"6¶rË€ûhÖB6¹e§(âõjúäÅ1À»™äf5³;•{ÍnUïc2¾j3Á¯Vƒ;®Ä÷ÉJâÌ–P§FzZ,‡|Lêûl†äB‹T!‡U²Iâópœ‘§Õ™HÒºu¡Å^¸³ó§iŒKÖ,ÆíòlÊ3o®I\Ý“;¼–èñýü›Œzõ›SðÍJôöo{„å¼%ÓúÅ^ÜýΛmùäÈT¼?Éök'//u“VÔ8ŠŸöX1û%Ìã>©ôiýù£Ú£f·«-å5Y|•–,©n7›Ò´ Çž­0¯tð£ålR«ºôR³©ù¥:Z’Ô¦-ñ{´¸¢¹[Â\™CÐtóŸ½&š¹g.‡AïøqqwOèÓA~d¯¶³×úL¹Ü6ŽËmsÛ÷HÕí?k³’\i§é¬~m:±~«(£S»Ú.àn·±,žCêv¿1uë«{í£)}«ß”»ÕÎ0·»„Üý‰äN³T–W³×üYñÏ’{•ælz»¶(¥v•Þ¥ê°æØà—«a]Âc.uj‹3Zõ _+În‡µi$¿\C˯UˆÙŒm:µIb—†ã_R“ô,¨´wjTæûœ»˜Ë½ºÌµ.Cêf¿}ý£!}ó£1û OÎ=îÁq ›£Ÿ~”q/Þäuî‘ÜÀc¼ÕF‹óêåÒ{Í{¸{-Ræv§jÌ»_ E¹_¨‡Ÿ.ÿã~Ñ«¿›SO¿ŠÅ¥­g¤¥•öæ/Þœ5ôæ˜ìV¥œ½ÜlÈf½×…÷ƅ寇\@ò +ÆGô³2qn·ŒKíÓæp,Øs¥ØœKjÓì9ªhjyf08SB/Ô¬à•µüIù Éín3qn\z½]"Ën¥e—ëqZ³ž$«ÛˆËìÖã|,§+îâíELD±*q ËßøEâ÷yHñIz»ž$í.“Ú­)Ìþ¢!ŠïÛ,Hÿ¶]ýCÍäO šøÃ¢÷œ—öÕˆû:/R5_ŽÓÍ_¬ÙÞîLï7Wه⠽ïïDj»#í¯ ”t¿ó“wÔ™w–Eh{– ««ôÄ×QʼüºGœß}HZ\o+ÞpJr«E&¿Ycn‘WvtÏó|k‹ûÅ'¥wªåTÖ-Qbëñ•N¡<¯æw½‡¢c«7CýjÆâ¬#‡Lä—ªE7*÷™]«–ßdÒÚµ8X :ÌÍ4·É\ò¬öìYÃQÑ­ß ¨û_DÌ£>¹øUÛIq~×!öqœ¹ßˉŸ´[rm‡ØüOû˜W}ûÙ’î“ìÛžìëÏéÂß÷Ñ/¿™‰žÓ…Ÿ,ز®²¶Ò‹²ö·>’Ê2{öÉ; æÖ{“ýA—JnÛNe|Úû½ÓÁp÷Ú¥Ò¼& îNÇf·êS™šâ¬VcùýŠý°¾åÊ‹o¶°Ì.SæJ‡¡øf#½Ûh!~ÜfA_ûªGÝúhÈ]o£èÜv!u¿‹¦ŸõÊ™ü¯û¸7Ý'¸²ŽŸÙ·]ÇÙŠw§ÙÊŽSôÓ~)›×ÅBn¢ŸöHè;ïDÔý^‘øN³˜)hÚËÖ·œw6y™õ½ “~h5ó'5¼Ýðù,[ßa˾ìÙGç|ÒeBqµ‹ž¼ zš$–c\ +ùêU‚Ðê‚+×çvÈd¯ÊÏY=xvN_«ÍÝ_.¼þ]‡ºñM_ôü3K=ìg„Ù¿jˆbzT…‰ß¶H’?èʳZ(‹ÛU‡ä¯ŠlÌJ‹\÷¼}ånž_b'}ZsDv£I"Én7%XåRð4ç9.½OcBU©ý¥Y¢¸š¢¼_L¨âo–LÏggé§·Ò%âOï|¹_º|ÄŸ|¹¯½Þl¯‡´¿4èPkvÄñæ´(¯ò€¸°² 1:®GÑý¿¹H{›‚ö¿»kÞý6Bú¾%@ÖÞäÇÔvœÃ×óûòƒ÷üÃ>QÖ÷TZ¿ºìYã óÂ2'ùƒ–Câï÷3w?Ðì£.©ôm£µyKq ´´Ù^ü²ù¨¤¸õgYQ¥¬¤ÊѼªà‚ämóÙóÚ’×µ'¤ù§¸çVÌËÎ=Ògõx=V•”œ”VžÄ1ÏÌ4£k‹ÐïîAlÍZÁÍh ñ¦tQï~I[½—¼«,XÞ[,éj¼(îm¾(ínôgZßÙ Kþf!,ùÜ*ùÅJTñå óøCƒìSUˆU×½駦@¦âÝ)æy·œ½ÚcL…¾^Í¿XEGÖªÒW>êÃs’' VfÏËÏÊŸ•çVì“Ýj0“ß­²4»UeÁÞo“rßÉ©Ç]÷¼ÅJRÐp\ú¬î˜ôaëAɃvKêÖwCê^¿€Åù—{Þj%­¨°—ÔV»È›*/Zt…zw+ñhë•Äwãöõ>‘ôWûH[*¼$¥5ÖÌ‹^sîmëI®¹ÚżûuøÞžgчۮ'œhN‹;SŸw¶6.êTcrìáÖì(³þü`öÃ{QÍ/G÷~7„úôçIçÌÙtÊ;5ær¿w©Obä.‘Ë“Ù&)UÙÂÌÛ_[¶åGXÔúíëx½·ãE´¸ªÉNTôÝÂè.¯!ô|2W°×n¨¡žb+‰Óµ9ÒÜ:KËŽQGÛn$iLO?Ør/Ѭ¾Øòw£™–\n4•äâëôòíYóº|_ù‹ŠŸ¹+M&²-ˆ3\{£Û‘¶ì¼æbÞzFù–øEÃÜ×};ÒìCA¨ìÓ«`Ë÷÷"ìë"ÈšÌ.q‰¼]â™þÖ=êDsJ´ ¯Û}]¹‘Û®ÇÈú*ƒ¤}Íþ{;ŸG± ý6‚<Þ€Îþ®#JìÚÊz<\È\ú²ÛüQÍiÙÃŽƒT滨 ·+áU+EO¾±òÖ*_«Ž'qÚÆ›õT…‰[ܤõ÷t¿‰”uVù³ÅGE…ŸÌ„~7=î¦Ù7­GØŠÖ3¢šoØ®:˜“½£$Õ¥ö¦¹¿êgT¯3Éêßlt燚Q>¯/húýÐÑ–ÌØÔr·˜„ +÷8ÿš‹ î5A‰§›S­ºîÆÈ¾T„J?·Š?µùK¾µúïí¾ùscJü¡Öœ(‹ÞaÂêLnþ®É^ýb,ÍmÅy¾_Gìso\´°+›Ý­Orî™ø*ÆWZ(³Ì:‘,¹MK¨ØAG¿Q¥/Ô‘>o=jVQê&+­p?|o!Êúu§(¼xôj… âí*êÑJV[ê~àÝã„ý]Oâ奒w5^fJÃÏ6&&zÖ$yÔ$&W¹ÆzÕ¤ÊZн™º¶Ó}o"\BR¼ë/F‡5¸EgV9Gd×8†]«p +Çãô.÷òëé_q1ê|}Lôž÷÷¹÷ï=˜’¾ãì“~ Ùã†#²ç 'd¯ªÏI7än73ÜÕfSÉÇF_áÞ†ûÚé}´9'þTó¥äÍ—“Ž6_O–uTû2ÅŸ Jþ&Õü8HUþýñkÞÄð¯mœÖµÁäÒÇ-’7­g÷¼/ŽÚÛý,ŠmyoÏwcKÚObü|PšÑdÂæ¼3Ü­‘‹ß”Ÿ2oxé{°ífÜÞö‡‘‡Úî&žiJK·kŒˆõªö‹t¨ +¬ô +Ï,w‰¸Yëž_kRÚx.¨¨Ê6´°Â.´¤Æ:¸²Ú:¸ÿ\^iZRb–WêžYêXê{¢!-ƬïE°¤¿ÆÏ²ëaU÷ÇIáC^@ßý‡½ùMÈÞë‘Hîwì_þh¦|Õ’^îdØ;ßqiÇYYOS ¸³Å‹ë|ç!ë« ‘~*aúß»‰?·ûÊûJBÍ{*#Ø–Ná“ß„Ôãw”¤ æˆ¼é­·¬¯*ؼïu„[MP²ýÅÔÓÍY—öv>‰’õùìë~s ëVÜþ®ëÑ6-á1ÁÕQ·«"ŠjmB ¬C^4Z‡¼Â_óëlBòkmBWÙ‡çâ}—Zé•^æ•\îåUé#ÿTd\Ê‹MBK–/óâ;ýi^ßÙ.K髿Sæ%Åîæ EíÅá’×'EÙýšTF¯¦4»I$½ß¶Oöªñ¬´çäç_,e5µžþ~©ÎÕ©­EâüÖÃÔÕßô„‰õE—¿h³{$â¦F·3É)GZ¯'™÷áX˜mÞ[.ýZ¼·;7ʶ)*1¡Ö%6¦Ö=ñDKV²¬ïm0×Qçz°ãV¼{S@‚G½_l\­Kĵ*‡0xܪt€çéy™}ijbçØÇÅNQ·Jœ"bK="µçDJ>¶ø‹Û›¼äÕUÄmG¥%µÖ’· ÖÒòj{ØÅðºö‹ò-÷v/‰u© +‰M*öˆñ/÷Kd:ß»˜¾ä…‚FþПË|âc‹¼¢Ó‹<¢ê"ñúJJ +©¸˜t¿7ºÿƒ³ákÞÐø%o(jþ~þí£7Sƒ«rªsN´^ϰêÌæÊmÅåe§ÝkC2ažàñ¼Ò.üZµcxz¹Køíûð¢ëÐÔÇèýÝ·bè_º]MÞóM{ÿqTð?G}ÿälÞ÷0ȱ*<Ö¿òbL|‰{df‘G¤}edôÉúäÈSõ)чš³#äï_Yv?޽o –½k 5·úŠïÿ²—¾öw}ñ“_öY6•FžjÊJ=Þœ°ÿÝ­˜==O#÷¾-þØ~‘zÿ« ÛÓí&ùV¸¿ãF”eïýÓvþ°ió‡ýÌ»j»ýwb]ëÃ/›Õå_0~Áëe}Û`ä÷p¶‘MÒDcǤÉFÉMkLË—Ð=އ;/dž4ºÇÆU»EYu]0ý•?mØÉ›¼ç¥ú}¼L¿—ëõñ¬áÞÒô+Êô†ûVåÉ}¯ò¤¾|q2lᥑM‹Lîò:ôë{¥ÅͶæÕU>‡Zn':VG¦D–{'f–¹ÅÚ6Ʀʺ+ýÅõ.\]»¤®ÒUÖÓtª!#ɹ*<Ѷ26áZ¡{Ôý×ÎáÖõq8f?‰•÷•‡YvF[uåÆœmNJõ«óMu© K<Ò–ÃþÖuéèpw7âØYfÕs´-;îlsllL½[¬W_‚øS³/ÝõÙžîøf'¨å-Šx#ý;6„ÄNÓÊQÖ-æ5ßI~© ô®ð‹I+v‹Ày/âZ‘[„W©øÑ¦Œp«Ž«ál_¿WÿÞ–}ñiÎãû¹Æ§ƒí·â=ªo¿r‰xþÖ!<÷•kÔÍ×®øÿuxôÚ9"ýGô¾Nœc{‹Â ¿úVøÅ>zãQPìšcVI¥Mð‡¦sñ£Ç::¿Ñïu[xéwþÌþÎëQ—œbŠšÎ‡¤Ô'!õµWlú[·¨Œ¢Ë=cç ÿ~Øìc~hz…KÔsß7Z‡Þlµ¹ÙnÆýh¸h˜óiƒ±uÄxM} Z¦¬‚枊f£©HMB3ðC¿tø ´jÆ´s§éJítänŠ[¶1háe4MÇ¿5QœŠÆ+Ì@Ó« åá ‘Ê¤•h®òz´d‰Ú`rí¼X1e÷S~«a/uþq†~Íï¿þ|¼ãMDök˜Â׎a¯‹à +JíB½q O*w‹Ž.õŠõ®ôOt« NHzísƒÌ©[DÜ› 1ao½£÷ô<Š :~9Ïôö¸Ú7†ÆÔ4®o9„÷P<õ£×M¯7ÞóËÊÝŽW'êÙdŒ7tº=U?àŠ^Ηպ¹ß wߢS·P]pÍWY…æN›‡T¦ÎÇc˜‚Æ Qh4FâÇ8ü“šŒT§ ù“TЪ¦h‡y¨¢úù'£5â?ÌÒnâuL¾ðÇ¿ð6f}Oƒ%=]~âÆî’¦n/iw»ÿÁw×c.TÄÅ¿öŠL+ðˆ¸òÊ=ÇÅÈÌBϨÅN/ß:„]*v‹Äñ8âÉ+爗…Îa…oÃRËÜ¢"+¼âš›Ïð]'B¾´Ù$ýÒû³ÿ‘Ž”0£ßøÃ»^ñ4=^NÚ.µ´f‹&Z´P-_±iYœTÐõ¼Ø–Ïç¼u /ǘ½¾Æ:tëZ‡$ÖºÆZöæF`|!Õ82lÖôiÿ¿×~0~üëXÿzÆ«øçkãJ®ÌH|…FâÏqd÷DÔ¤øçXGý7uüZ´tóa´åÐ!Ú×ø¢nÞz_ËS•éѯ/’ux¼!5²&ß-ám¡KtžÃú"—„¦WnÉMojÊ£_¼v‰Æë3êa¡kTB‘W”þ^¶FM†¦Œ™DöÖþ·ó¿û€1øsN‡âÏádüãð'Ή×£9‹Dh‰ú9´Nš8h{&?Ëð3oµ¯áºwÒSŸ¨Ï<£Ÿ½t‹}]àšPVà–RZìœô¤Ð56¯Ð%2¥Ð3±<<n‘8¿GDWºGìíº¬WÊë/[´ö=Žh¨HÞ³â¿Ìé ?_‰_…?' š†¦(ÎBãMÅó4 Ǥ™8ÇÏF“†,@ãÏGcç¡ #–£iSw£¥j.hË—C4 +øU\OÆ-8@Nˆt)‰–~,õ7ëx¤)#ǘÈG8V¦à4±0ù%[ ‹"š›Î‡_ÜӺ9<Êð;¿O;íÝ­z24MqìÿenЉ•ðó_ùöé•`LJàicס“· é“6!¥)ÑÔ‰Ðä1«Ñäa«ÐÄQ+ÑDø~ä4u4þ½©hþÚ½h£Y¶â®~±qЪñFÀѪK!€Ín?õŒLÀ¹¯õ•{zsgFû×Ôž7—Þ—¹fôUº¤÷Ô8¥4W:$”–:%ïÚYΫŽSüÿŠƒ0>À)0_JCTЄÁJø§qx!óãü©0Ç’ÙhÊàÅhÒ°åhÒˆhòèµhšò.4g1Æ~ÚÎh-—ß)ÍÔBSæè"åE,Z¡‚¶:¶ŒQͯ’¾{êö40’à–W#ºD`lSìqf4p›¿`,öö­cdí+çÈWEN‘xŒßø=›)Ì[·çÖñÿö¸ N'‘a0ù~ ìÁ‘ŒCS¦¡é#£éV¡™Óv +dhѦchîz+ü8Œf.• ™si4m!…¦Í6FS”´ÐŒ»Ék«Ñh›Sí­w¼ŽQ/¿Ï²ñö…å© ý"KžxÄÕ¿tO(.pKÀ9>öe‘cÄ»§˜þ +‡˜¾»ØþZ‡Äš§À¤z?xÙ¼ ¦ÿ«9ƒ÷?Ž`´q¢Çœ{oàµ1øÕ hêÐéhæ¨húè¥HiâJ›— ©Vàý·MŸ¸ )MÚ†&OÚAƦ¼Ø)Ï“¢¹«Ž¢%z>hýÞÛŠ›ƒº&¨çò‹wóªFùýûë.û}òÌ#¶ºÀ5¦ÏSu©Cd[©S<ì¹öZÇ´¶*§”¶zûä×¥N˜Kø„jÖòÛ,Óý_¯Í±"2Ï&*LG1CÂûjÞs“gãçf£±xÇáǤaóДÑËñØÖ¢©ÓUñúÔÀkÒÍXkŽf©ž@sv:¢F~h –ÐIhå#…mÁ¿NQ+å×0=ÅçÏ&{¼ + ó}þc¯*<¶{o¢àWZìÕVêÓUîÛVá›ÿÊ9útu|¸Ök~ëôq3þíyûk¿A¼‡L5YQ ) ƒÇ4¯ÇÉøù18cxMA)XŒã!ž»Q«pÜ\fNÝfϥмu‡ÑÂÖh¾¶+Z é‚f«Ù YZ¶è'-;´XŽV›e(löi§þ_bÜÇw½rú¹89À=?<ôñ½‹‰UO<“ë^z¦çç»Dg*ó‰=Ó[ˆyB}™=©CJ>>¿ ~“_0}úª;—&X 0"Î^ƒq.¥‚cÿ<¤4x.Žó³ñŠœBÖæ$ü9Ya*ß4mÔ<4iÔñcüR4u2ŽÿóôÊ + ¤²Ò +ÍYsÍßîŒæ…£9zþh…Õ …^µ£vÜàçj6ðꕵ?õ<^ò" òÆSˆŠ®Qõxl%ùÎaJÂßUÙ„|ªµ‹ïk¶K.«vHL*q7ýÑ}v…Äúÿ:gø?~þ+– `áx¶Fá½6Ïátò˜¬øR·ŠÌ•Ò,M¼õÑ ¼Z+C?­fqL1B3çë!¥HiŽ6RZmŽfoÁ{Î4­=|KqCpØ-—ùéjüZ +~£É×?ŽX5^¾èSä_p! +ÇΘKã5Ý\å˜ÐYãÔSçü¹Î>©»Ò9¥£ÂjIº-¼ñ<•MÿÖ¼)þK|ˆcñX0ú½©ü¤æ¨èâq¨£é³5q¬PCS§áø1m#Ž™xŸá½¦<}š9cš¥¤Ž”ç£Y‹4wíA´XË­¥ UòÖº• _ÒîZèõäcxi‰}XÓ[‡Èþ +礚·NqÔ—&Mç·“ F@|ÿwÖæˆ?s9¬O@ÆJÃf"å +ÑÜeúh…ÎI´˜¶A‹¬BÑr‡¼Á+|^]ëûvÄ:×ÃW8x•ã³!¼ÊFnðk½Á§~ôÇ7ÃU­ó‡mñ¨³ó¿bg-¿Mí?O=°yªf¿H§–×ѯçEm¼Ä ‰ ?ðçÏUÇ„fqecìì\c̘ ]Ãô4dW›ÄtÇjâsƒæ-Úþ?¬K2g×§(a<(-h9猊xSu©¿âdÅÿ9ïA=vÚÄás0Ö_‹~R 9ËÌѼGÐBm´Bà‰–ï>ƒVn?ˆ–­§Ñ¢åZhñbm´\UŒT)ÿA›N?¶Ù¶häδ¿ÏÕ®â5õêxSÃÞ‚úòÝɪýZ¨äó› Âo߬EŸØé·ðÜî¬_—ë%w-׿ʯ7,åMŒKxFPÁ[ˆúsµÜ»j×½=£-»žGI>¶û3µýÖ‚·¼LTùã×Ùêá^œXQjìQ­™ôaÎ\Õc]*kÃØï3<ÎI£æ£™3UÑ‚u¦h­ÎQ´‘ò@›i´õHâàÍao&¨½â—jÿà&ü‡Ÿ%Ÿ¹P¿VØ™þãëϢ߫m4YýÎÒþÎë|æúßy™ÁW~/û©Ëð‹7ßP ¬4|„ŽUàPƒB^OXÆï5Êùc“‰ó•iÂ{¼)ÓÑçr¸íjÜþŽ›±§Ó’·ßL421DìÞÃCØÐ§k¤9õ4û¨Gj’öiƒö™ÄQó—l%<í¿û‹çí'¥há +!ƹÞhãÑC6ù¶Ý’Â+áµ·i÷gž6ø•ßkðƒß§÷—îlâ·h”ñë´ºy-Ãßù6µá9eÎá±n.Õá’ÏÝ †¢‡×žös~£Î=~ýî2^Û¸‰·tñ'EýØK¿Ur_ÞyÞãÕÌ+h¬Û„ô´µÜG ç©´Fu&ìʼn]†²ôXè±sÞ<&ûw}q^¿õY‡q¿>Gh—¥¤o0lùZ4sÌüÿR úµ©ˆqÆXã£ùÄh½Y’¶À¶Iÿv}&ûeÉwþ¨É/ü £Oü>ý jyʨŒ§ Þò†&õ¼¥¨Ÿ·3íä—ñœÑS~·IDÛ +[³ŒS»× +~ßÇô¾w~ä­müaƒœ?TM|rU µèËŸw3÷?p˜’5TÈÓåTâ3Uæv©$ïTVVdoQ_à/~ØiÁ%}ØÅ†Uld^­bóšX‹¦çþ²î²ãRž]³•þoÇ5ÇÅqŠÊhüðYhâØ9˜Go@s–ê£U†6hã‘ëƒ7z—Þvýï?iVò[ñ~2Þýœß¾Ûó©Ò# \î*¼àµÙ¦r»Ãï®ÆË?±ýî¢Þ[£BÞØØ7RÉøøÁÆ?Ÿjìì9Ö *ožA¯'îjôä[L.ÜúIW AF{¬›\ùÛêÊ]щÀ±¢=vCذºMâÛ鋦£Ü³6K®¨ùˆômé9Óìþ¢+ß´¨¬MúÒG-ñÃw{èü/{ôŸòê»~Î5gѳÿõc"ÎËW‰ÐfÎw†ã³q»*yuý¼Üô3Ê 7ÃñZj‚ó.ýå›ý탻Ž º¶—'lR×Aª›× £§‡˜ÞíÙ-i|ã|²%+Õº)6yoO^ý±ßÕ¸‚ëe~\©ïór–á}^Ýøod”Ú±Ö$ìÑB“û?vÓÛYêN¯©èæoºÔ¹˜IB³SŠú¦"DÉ($ÐßwI™ÅÄ7le¯|3’¿l<'/¬9'Lù°UtÜ{”©uÜDƒS‘£·žBs¦¯'9Z‘ÔÓý¹.‡ ñŠ8¯M[‡m¡MrÿAêQÝ34žòË5ëùz¿òrÑwöômîÜoõ¾ýÏ¡÷Çõµx0µ½çè×ßöQ/~“²EŽIkÝe¥ÍÎ\^¿”²Mšª¯¡t·lF¬Epþ]_ºÞäá?tLâ߬œ÷ ÷A‹bò×RÙ}ÚÌí^¡(¦zƒÈ)nç™ü“Ô7m![ºÍ,«Ž‘¿*±1/-ò”?­=&Îm—ŠsZTVç.*¶dƒÐïÚ\ýÓ‘£¡ß6yðR;ø×˜Ë©ã— Ÿ–j¢åú'жׇíºÃ/Ó}Ï3˜_€^?Ïtñb“ÞÜðÆß¶ìs¢k`Žvk +‘©Àq”¹ÂžÃv£-]SŠ£K¶sþ÷VÐÆ93Жù3Ñ6x,™´wnDTlþzÉ‹ºCÌ£N]°†>í7Žœ?Ïé5 g¢;Ž`,­‡‚–¬8¹CKœÒ¥Í†>[ˤviJ¯5qlU×IQÓ)*ó·]Tè‹ÂÛ_õèÂû˜úž³Æü^í +^CíbÉÄÍûÓ7ȼí@öÃ9ôÏß§åúpÒîì¯+˜ýnpǹ:4êùjox—W3‰éZm’þe“ñ]^Ëôò¦çâ&lÛ¦ŽV©Ì@kgÎD¢Ý:hϱ“#­l§ìu¸0î3½ýE‹yÝvPZQá ¼ÿ‹@xû=áµ_µDþwŠü&R!™ é›ÆäŒæÓ÷–¦7ÿÐú=_HÛ¦OY:Zž":xj¹ï%»ËØüaùI³üºsÔÓ~VõvµÀÿÁã´ªF‰½«õ\ò¦î”:+¬V—£…87ÏX¦†æjX õ{BiÕ(ißâWè¼äwèäãÇ]÷Sß/Ôv¿>IçtäH#×KSMƒ/Ï1õOe~c¾qZízãËï·Ÿ-¡ìR§Ñgc&q6IÓÇ+³»«ÊÌ1¿1»5u‘Ö¶H ‡ó•ÀIe +"¹…ã7SS¸F[°V˜P°žŽ¹¿N”ðr•Ù£ÉÞmãè'íbr®òbüÖ5y}¹_Gö¨úYi…«eùK³’bgY~õá•Zp_e>Ùø¬÷(=÷¬)ÚŸMßa饸|+…¦ŒQA“†c>€yèâÕÆHùp¼V¿Kï=ÏÒ_>ºÑ}¿: ^ò¬éU^ÃÄ)n²é|-ÏzŽ…>ZJ{¤ÌÂq`0sÌs4h +ªk!í ‘‘š³‡É½BD;Î-{ž¹uØ4±±íƯ›â¸Á¸Ç+S±¥¨À¼ÅŒï­E¬÷íE’ôf=ˬ*]º…³š÷`0þ×Ñi;™øšmtÈ£•¢Ìš²œvFú¾Ú_ÞTægzíï"·”™ÂøÒuÔ£¬YS±yÿëî{ƒ¯ðo#ø•?‹óÙ1ÝžÒÍå7éžÏ¯n¼éH 2ŒoXÎ6vÛŠË:Î1¿q¢ÓÑv©é""÷hø<^Lù=\¬'”¡M –¡K×!£È\j©¸÷¬ÓD«ÓN“öœt/· œF'½Ú +ç|ÅêÍ©¼v•óYGݵCt!må—3¹Þa çjEW¿i bÚÖ‰â>n¤¯þÝ@]±†¶MR¢ŽÙ`ì§S¶2Wû ¨œ~mARÅAèË%Æiݪ&y¼¶Ém~—QÎÍWÿ®jp…_¯]ÀoÑéãô~á¥:xC½zÞÀà ¯oôœ×7-æ9ãg¼¾AÐ#ÃãÎC,O(šî9®¨§«ƒ6/vn܈ôŒ½÷ÜPö”óhÐÐðì9=âë:“Â×–öɘCô@|ÒÊý”Øãn£Yëè)¢”Ú­TrËvÆë’ +ã7q‰š.±Pö¬üÈž’§^ôÓN©èÂ͹B»à‰´çÝùÒ‡-{e•ånpRþæs³O(LiÞÌx]Ëœ ›(ò²Ø¤P¾8.Ò}ÄoÓvx8AëDöHs¹ã´OgÖ½Ëo|äÏÃY>A%oiä’5u·¾ÒR7ÄcÒBš›ÕÐÎÍ[‘è„ÝöJ›‘8§Á„NoRti"”#¸']@‹‘ü¸Ã¸½T§kv­XJîÃuOU QF“ì9ÊÿÊúôű”MÐD&0w)Ü"Km0‚{¸œFcÙã²ý’¼F™,·n—Ù§ÇÄ·m%µocÓ>hÁ™OÉ›ÚÓ‚¿i ÒÚ¶PÁ—ŠÂî/æ~30-üƒ2¬Ä˜ªßcÔÁ[ày3Ô½Á¯3 ªŸo`é6DMÍé˜È‘ì¼¢àläx-} Ú¾Qéï–!u]¤¾|=ÒÙ¾kÀ‹F|\A[ÇilÛ‰tµŒÐ˜F¹¥¢Å)»±æn©ó-<./{ƒdn¡Êp#w¹ÍÀâVåÉíwRáåÏš"Çè©´Ç¥ŸDéÕEÅk¨sÑ“„ÇýG‹.ý¡.Ëo>ÍÞêaȽ.¶ Jp?3uñê\Ê-a횢,ò¹5Ï$¥n½É­š¦W¾ª™Æ•®6ÎèW5ºüu³Q.ƲE¼±iÅßd¦Ec îþ¾ÕØóÒtcç¨I&ß6Óy}´ilë:û˜I"Û„)¢s!LÄû©«nF,FÛW«"¼ïèƒNÃá^6ÐÒ“ó™ZìTØÓUtN—®äND|·VÌÝjfÄ×…Lv¯.voã?“³ ›Â9¦Ìdìãq¼ŸNy§Ï†}(¸Ò§It˜K^Õ§î}®|Óf}T^þ²“¹÷žáŠZOŠó[¯|ß):í;–9ã9–rÉP$Öodž¾—Ëš«.ì¼—ÀuÖ¹š<ãóZFQ½Ë ò”vDzÌI£óIãMsyaÀ£…FÒ“ +K»!"óóƒMèC +[4ðþ[…Ô0¡ÏúŽeujÀ¾1âÌfè³{N –ŸõŸ, |¼NœV±›N-U¥Uí`3Zvƒ„üF•L˜Ó­I_ÈVaœ¢§±é³á^/¸?ž»˜1ôy,_=u8Öp9þdcfÒžâ|7If¯ëÿd9sñéêR¿ó C,LmÝ&ºöY‡ºÕmHÜZD;„L¦œc§ ’¦˜øÜœmúf‘±uæ$]ùymêØ }©¢1}VÁÀdï ÑÙ¨‰‚ŸCÆj¨¡¹Ã&¡)˜7­šøÒܺ inÙ† õ‰±±È|%;¬H|qNz—ì;2„Æcÿù1¯± »%;å:V|Òa4Ü3ÌeUÈò*,¥7[äTèË•"»¤©TÄë5‚¬>uÚóÆ\ðê2‘Q ðZ•äµí‘Þj‘Ñ—>iÁu¤ÂòW1ni³h›àI¬wÎ|Фîõ™çý¢ezë«–éíï»Ls¾ìúݘ+ð¸6Kh?EtÜkÌ‹>ø™HÜ›×úTÚ'o!uÆo,¬{Êëæ\¸¯TxÀv¨>ÆazÆ2$’œSd\Ò”é¸ú-l|³:èfƒžÑºÕD‹®öiý]L|ÅVêR£•Õ¬ ÷‹Ó8¦0.IÊìùàIôùÀ ´mÄdQ$ÎóÙýê¤êM¦WúÔEwûL¨]ræI—Œ~ÞcÎå·ï§òú„‚?´éG}ÁÕ_wRG=GrƒLÌO*Âý[tög]Ù£ºCfå¯]åoK™g=2“Üh ïóFƯçë÷£åJóѲ1³ñWe¤mÀ"ÁAÛ¡ÂC¶CM-O¦ö*”Ÿ¬¾S íÀñs‡êâÇFöËœp%°°R€\!>~n¤ôì…‰Ä3ê ÍÎòø`ñÑs#@+A|¹ÁDz³AÊÜê4¥¼â”i뀉Âôº-Ì¥.Ð5dÎûO;+1éuš²‡o¬,‹¹¬ºfþ´ô4s©OîAãÜnÌe"j62w—°RUèÐç«™À›K0NX"¸üE]U¼ÊÔ.r¢À5s†‰ÿ³yÂÓ±4µ0_X¿mSÕD[v#CÁÞApŸ¥àˆ×ˆõ W y#'£ùc&¡åã•ÑvŒ?_™¹$Ï‘ß^÷äÉ.Þ[ÁÅVn7óÊY"6?>X #V~x0Ñ"/ŒÓžã%na3¹È{똔×;D)[1–^ó/Œ«\/¼õY—»ùž^jÙ> +Ì)ßqà»@‡>ZI%Ôm¥’ê¶²=»É^¼¹˜ñΘCE—nøÿØ{ïø¨ªô<  €`cíè(¢ f¸½€- E$é%‰“d“™8™‚téÒ”j¥«€Ûª«îºº»~vu×]×Þ·|¶}öS¾ßßïû{ý~ìïyÎ-s'3IæŽÀdÂKæ>sϹçyÎ9O9çÜçí=ñílÏËß:±o=ïü)äýÅ·a÷ëÿî›8ѵúØhGtõÐ*÷üÓ¦zJ¦ÞQUR…yî#+Ïq'¶ï^zärÌån^~v•'º#6Ðݶó WyVÃüÂŽï­xŽÿÇ ïÆopE—u%ÖœëYyìù à>|±gÑnEG>ðÊM®ý¿ä9øu¹çÙ?Íð>÷Ç*÷±¿L!ù¶Ÿÿ÷Yž—ÿâÀ÷4œ¿ºÅ¹ë­Òš§ÿq¾„±,žùöüäuŽ'þykÍ®_–Öþ_“°ýîεç9ãK‡z6¿tƒó蔹žüg9æÍtmyázׯ—Ç:w¿GÕþËÄêgÿ¯Û{.œ6+TÂÞ@•”Žº¶D¼nBÉ$Š)™v÷™¯fÕžø0€c×»ñèߊ=—cN,ÿ³Ÿ:¯~Vëå› çÄ_«\GÿsŠëØÿLÃwÂÜ{?–Q†þû¶_æÞüäÇãïqžçÿ6ÛÿæwMŽÿÏ´š­osnýàæêCgúûDǺg¯®nZ:¸ÚÏÀ»œMªrµnY3oÉ™K&\u}É$¾¼dÚí• 7%ˆ‰¹áƒžW»ÿ½©G{â®a:ÌWXã¬+™]å)!x˜+v^†ïúcÞÿ¦'®Ç÷HÁ\åY¶ûÏê}£û¿šä~îŸ3\OÿçT÷ö—zïÝ{‰þÃ|ñÞŽ-’wò–í¹œø7»þ&y7¿2ÞõÐ[”{ç›vϺ§¯qo|þ:Ç“ºÍõâ_gy^üKµë‰ÿ©pmxi æË¨©KœUå™;°æîEƒ\ó7Ÿ¸ ~ÐÏ­«‡cN=ÇÝ‹cž=Ìÿèž{ß9Þe®ðn|eœë‘O_˜óüŠ«<‰-ç¹ïÙ8Òݲb˜+ºäÌé]sbŒóñ/dòòö•:üFÆw+ÁþÕ×¾úû&ÿ+_ÔÖýôøÿgŸÍu¿ø×ÙÎGÍzÁö;üÑx|7ß_óüì5Oÿ¯2Dzý—8’;Ïw®:r¥ãèÿ¾ÃqüåèïÀØ,wûŸrÌ朓ŒkUÁ¦$O˞ؚƒŸŠîå‡/Ÿ}wç ò[f”Ür³\2yÒ0.kJf9Ü%Ž`ã@gbËÖûÎu·.V3'11(IŽ—¦ŽÁîÎ]£|›ß¸sú`^׺ŽçtžS?gÑЀ¯i`íœÎ¡u÷¾Ö»÷ƒI˜ë sc¸—=z‰{ã±k]‡¿¸Ísð“;¼Ç¾¹ ßsõmyfætþ²,ðì'Ï _Õ8Žý­¬æ¹ÿ.w¿þwOàÝ/c·¾šë}öß«Ǿ¸Ã»áèïŠ]—º¶¿t£óÄ?§“w—_ÿKÐùâÿqÇ'Œ£c箎]ºýã6ç‘¿ßî~è=ι饱îåû.s¬ÿáµÎ…^TV6«D´s%So­,AOÄúr8à/ØG]x Éù±ö)’£Óí8s¦’q zÓ»óÅRÏÑ?LsþàVÇšó}­‹‡û×<:Ú½ëÍ ÞmoØÝ»áyÇÿsŠã©?ßî[¹ç +ϽÛGùÖ>bm¸ïå]üð%h'½+½ŒäÔ¹âÁ…à‹¯~òjïòG/#¹$íú;¾x¨;¾z8É·³éGãÈßÛ.pÍYr6æšÇ2ø>æ¨rÌ]<ß“Æ|{¾M¯Ž÷où±ÝݺúÜÙ®¦³õ%8ž]±UÃ}Ë÷_óÅñôV8Nücšë©¿”»ŽþÇçÁ¯oõmxþzÌíŽy +u`Œ€9£qí„äÚüì8ïú6ÌõäÞýƒ¹gÄ q’ûéÿ˜îzúŸÓ‡¾™„ss˜ù&±â\ߪÇF£ßâzò/“½kOŒAÜÝÙË`L†@ÞO]‹csh¸bˆΪ©E0s¾;çu qÎ_~Žû¾§¯‚¹}‡oÃK7̪n,™rÛ´’ÊÙþWã‚ÁþÕ_…yÄ1'¶r8b`a~BOëúŽæƒ§Íð•ÌôF€,Fcî!Ìéê%a./ÉŸýÔ’Kÿn8~½㑱þ-/ÜDr¥lzá×C?¥ ¦Èš|öSWãË¿ˆ4¿öV2ôүþ#_L'ù( ¯}?üÊ|÷óÖÚï~³!ôÝÏ·ã»r˜«$øüÇ^|/ñœ»lwB â|ü×¢ãð_ounùÉ 5óÖžSQV]rËMRÉtˆ 0§±›÷¬9·ñˆkã«’ƒfT5‚Þl,ñ6vÁÜSM{~vWýÞŸO&¹Óæ¯޹¢·sè{;·rÏ[p6ÚíÚ—W×ðÃ_Ï÷íx¼t˜SɵçÖóâÔx^úGõ“ÿ3ѳöÅ1˜ÃÞ³|Ê?¦¼ ¶_4;€¾žwÝscÐÎb\íhˆ ÂÜþ®¶ #0G «ýó±å 3W ÷¶€®ëØt¡óM.Ús©sNÇà™3Á:}%˜'™`¬ÁxB+\{ta.!°C +ÆéÞ+ÇÀ×±ê<ÿ½/¼ŒÈâ b.nÿÆgoÀ|u`ÃÊ”YO^‹¹î·ˆäŒZ°uæ1Ä\Îß߆ø ñTw½Í¢ßå{éÒîÄ}ç:åº;ªà6bŽe°•ÎÇ?”¼Œª +´ œíÝè ð6/:mˆwÙžËÜ 6žW]ßB0¤M-Dˆy6ûîyIžU‡F£@eVµ¿ÄÝpÏ`Ä/‚8åbÿŠ—!&ÚsÄau·,ŠëdÕþùÁGàlZ<ÄÓ¾õÏœÅg;|óIž"æÊ_¶ó߯'¯ƒ¸ývÌ›è}âÓ;=w‡oçk4Éy÷àË¥ˆÙ‰Ø}Ág>q6üägíá·~ÜYÿ܇u$7ä®wXœ£Î=?ãЖûòuƒÿWßÄñ==Œá1«çîè²ygy:v‚}_ûܧþÚg¾öø·¾|3É]¸æ±«ÝÏüi†ÿõoëÝoþß¾Ù/ükª{ÃÇ»ƒød‹÷\êš›\Y]S‚¸³ø^=bÀÕÌY´·¡u0ÉWõÀ+‚[Ÿ/ż\ˆYåć`ž:ïž_Êþ­ÏÝ„ù |ÃåçÎG¼nÄ×pï{¢÷ðï+Ð7Ü¡7{Å#W`ÌÀ _êÞøh^àùϼî½ïI8‡›À²DÜTÌ™êY´s”§eÝpgSû`ÄÊð-ØI06qŒá¼¬ö5 pÍëB°„Ö´yÚÖ¬¹üÐw˜û×±±åÛ/Â\ïÁUÇǼ™Õ{®DÜ'‚éŠüCÜ‚¹Ò«Ë6ñ¶)\çÜõêÿá§Ÿú¤:pàã©ÞÝo28.ýð=÷<úsÉ{à7eŽ~;ËuøËÛ}K÷‚œvŽBLç¾/d×±ÿžŠ9'û¿–ÝŽ_ã_þØض铧Â|ò–xæ¯îš·rèì@l «¹sˆ+вè<½Ê1OE‰x=_"— +%SÊ0/gÀêPô,wÇŽ =÷?wgÁÖ 0O<æR%8Â/ .ÝŽØ} žyÕ¬@ æ}"øl˜Ÿ +ô+žGA›‡¹…|?ªÀ\ÌD7%–žëÜÿÛ‰$ÿÏ[ y^ÿ¯€ë±ï&"昧uóH˜g@ì5s¶»Ç ûÈ7Î]oÛQON›æ,¹óΪÄ»"}ÐñÀ(Ä"8NˆÉ\ˆùŽg»‚%Ã@ÌåMrDÇ—œëk]8ÔjLrʃ>ô=öî-µûÞ)÷oûÑמæä`Ìæ}äW²wÿû·cÞ/ß².&¾Ö£ïJ¾qjWî¸"¸æÀ5ˆP»ùÅ›1ס{ï»rðØÇ5æi[?ÒÙDpÎ×=~màÁã7!î ÷èßîòÿÛ bë|UFr1­{æ:odÝ0ïüåÃ\0ÿj ?0¯´oë¥îǾ¸Å¿ãsÅ!Žö®¥an"ïSœF0OAßx—î»Ü»üàÄ_à'vßãßÜá?øÝ´Úƒ_UÖü¬Òsàw·!b së(ßêCWc.CÌ£‡ç0¿±gå‘ÑÄçØôêÞ‡Þüûÿ8Ùø»»j\u÷‘ßמøhæO„¹l¬Ú{UíŠí—v¼Âx¾_îß÷AŒM‘ødàÛxÖ=y غñ$Ÿ^lãHÄÄtïÿâVïÑÌðÿÛL\·ÀuRÌíYwèjb÷ §7<3×g<ËŸ¾ÊÛ0ܽ`ç…®Ö-#\s ©ò†”Ý:¹ä–I·—àžÐ,לˆå޹À<¾¼óøA\[]ã-q‡[#FEpÇOE‚Ö¾åB‚M óe<òa¥÷á_Jþ_Žyä}É5#ÉzçêÇÁïZ92_4 ¾_Eòõ½ð÷*Ïÿæ®yæ¿+<‹·ÂœŒUy`ÛœCOû–ó1OºwË7 n@ìDÌKïkŽ ®_öЕu+öÛêV<<c0wêñú3*g–8}wÀ|Œh71ßæâÆ|Ãîð=ƒIþÉ ÇÇùÙ$ßž÷oA\VÌ9J0à1÷+øƒ¾Ç`.MǾwxß _º‚G?©öc.îºùgLè—»ÿÆ8òû»@¯Nôùl²ïÙO«½¾z“{Áê˜Ãß›\=±Žñ¯7¾|8úæ¸öà[ý„ s>£=ÁŠ¹Þ¼‡¾.÷>ö»ÛûÀ?wÉ9ˆë‡X3ž¿½ÝyäÓ[1O(®‰ý‹r^ÿÌϾ¯o«=ðùtÏ¡?N†ò˜÷¡îÞ­—øÛã¼Ç5§à¶Whϡ˂G?ª®?ú±'°ÿ÷SÜ{-#f«oÇK¥˜ëηæÙ1÷jýËãGþ<ÃüÕž'þkŠëÐw·ùÖ½0–¬¯?>†ä·{úÛªºW~¾üe½{ÛÏíd#±ý|Wë†s1Ö 1 â®WùæÀ<ˆ¾öÝù¡~’G1c`ÜÕxç ¬¼ÓAò#¶ +æ/¬Ýò +U·öÉë}í›/´n:?°dÏeÞ}ŸÜ<øÑÞ¿ä‚‹·]Br!£}Å|×m÷DŒ3ŸŠåzü²ç¿«¾öYÉ©vßÑvúQî`èÖ³|­˜Stï%Èoí²ýWÕ.Üq æ@­[öÈhÌ‹¶–`n€½Å¼ø oѺ ü;)ÿdjýcÝØóÁËûžu#ë?tyí¦WìˆñUŸDŒ…C 6´«¶SÉÅíÝv|¼ïħÕw>ŒÔýôý8æâž^vWɬJ·’‹ûðSkŸúÝìÀ“ŸÌtúÕ$’‹cʃ_Ý14ƒ91 ¶­éjß +ü_‚½q†ì 榯]sø:´õ˜/ÐsÿK×»[6ëhìŒqâ—V=}M`å3׌ËõÏÜ€¾æ,"~ă/݈2ıåðÅ".ŽÿàãO©Û÷åôàÆWoFÿ×é ˜í ð Ý@Ì+Äj»ìÙñ +‰{üÉ/Ä— ï!ˆkÜòzüËÁoØ1:î!¡sù#½¡{“«Ï#98~“¯ÝÿÉôúƒΜ»˜çñŽ\G@Ÿ=ô>Gp–î¿s»÷}{«{Ç/iϺ^ïyàmˆ©^çÝôÒxד_ÜQûÆÍo½µ öÍæÖ<ûÏ +÷ö·ìžßà½wѱˆ9‡ûtÞûöÆu=ÄGÀüwˆÝá=üídÄ=™>å®’iS@¯ÖøÀ½{€†7WÛºj¤§9>í"Áͺgˈ•‚ëïà ²d(λ`råyþ­`1Ç*æå&ØY ¿}4-pü“ÌÁç=úÇ»œÁA쬹«‡9 BlY§/z–Ó; æã®¯YY91NHNÙ†Ž!>’Óvå¹$§òýG¯óc~nÄ€èXw>âp#ÎLÝOg"Æ +Á6n]7’à®~êºú[~pwlùHÄT Üø:-w`ãS×»Ž;­îõ÷æÜýþ;Ë|?üÖƒcæ®ÉÕ% +NÓ£—".ÉŽéÄ õÀ_Oó?ýeuý“Ÿ;|‡þ8Å 6š`gÍ&8CKö\ŽØYÎÚ&‚4`g9ŸþÏ +ŒqkV¥‹øJ +vÖZ‚@°m’ËG 6Á†'yi\…ùŸqìiØYÁÇ>Ÿì?ðõd2ŽaŽ×x[:al!Ö<– "VýüýéÀªƒWc›|s–õ…—œøòµ{?™ì?øíTÄ=pÏÁòÑoÓ‚ß‚˜á]:†äAÜúôM¾]orýMÁ¼º¾ÃßNÞ}_Þ6äwíHË;…žwþÈŸ§Ö¾òucã»o¯>õY•wë‰ñdÝqÖæô&y¯þ)Orq#ÎØiü¯>¾þ|Ä««_²ýòàýÇÇùwý\òa.îMÇo@ü«àSW¡Œ{Yž%à3ÅÖ ÷G”\Ühï‡IžYÄ|Æ<רî^(Åœµxà÷¶Ü;TY^D0>êæ¯8±£‚ñ%Ã쬣½Ç>›ëƒ¾ÄΪ+©®B<“޳§ ÷Ý/ íP°eá0;ëRÄÎ"ùJ5ì¬ð’sê–¸*°ý-®nÕÓ×Áž‘<üóîFp»|`(.Þ4 +q,kWî¹ôk—€.„~ DV'ã{ûO,öð<¥üJ¥üÒC£1g5ŽooÆêÂõÔÞäúúýÜzü£Y$n:ü‘žwÞ­å櫚̼óŸ—cÞùº×ñìÅ·´iˆ¡\úø••G®vÎY8×$œóî=Û×þÀ…hã7k–«a@•ûîNÄQ[ýÌÿŽßJèçú¼íbû¹›îâðÜ= ¦&PãdÁam[sÁbïX{ApÅ££k;¶+xm8çïéFÏá/'#.®/:ÀïAlÄ9¯šá,©œr'ÁÎrø‚œ;ë\#B›X5«®dÖ”°/ÍÑ>Õ†S;gñÐÚHçÐ@¸ýló¢sPG#7Á§^¾ëòàÊGG£þôÆ E{Oð.@¶¾GÞã‡ä§oßt!ú­AðõAÜÜý†xðùÒÀæ7̶µ{¯ö<ùÑT<{ƒk¥˜‹Û·à =P'â›ùö}T†>)®"+†£Ë‡ã¹‚µæð5¸ÞB°—íi¿ÿ žú¦Ú¹“÷þ^$ØY¿ý™ë]{A°³¼{~3‘`g-ÛƒØYgÍÀ¹Œô­xr4æê&ØÔ÷#ØYµˆŸŒØY«ì¬Z#vV\ÃÎZp¶§>r–Ë ±eüvôy;~Åã£1¿7âo O‚X`µëa~Hyˆ;üs üÝóÎr¹› .ú ÷Ëoyå&òbj€_¢ä9~êº È2вb8Á'‹´Ÿ˜ß%^æ~è¬÷éŸá<ðå$Ä?tÝ=ç,<_î†ÿ0V#qBKû9îPãY•Ó%5nˆÉÃKÏÆ{fU»Ju ý÷n…ëˆh0~Ãzq q§]Màÿ,}ä2ßÖ—oD¼ +Äæž1ÕY2cº³ýmo¤ôñŽË‚›ŽC,_âW‚Ýö£>Ù:bçv‚ù‡ç­\O|UæòëJ‚…9Ò£C:vÖB;«}hÁÎzÎØþ&L®?ßá À¶#Þ6î•Ö.Þyiðgn®_sðºúä*‚oMâñÅ]Jò±ïýÕD‚WvqiH.{Ä+ Øä».õß» |¯§¯C;èÝûÞ-þNñì{ï6÷žwÄ€'kax>‡Ä2lÈ—oçÌ%çƒx3â’Ÿüd–÷ùú޵y£ƒêæ-ñÚ•¾Gß¿}0IJ +¾¤‚å!ØYŸÜæâO3Ç¿žg1> X­+Ïu7/;»fÎÂÁ®Èªs4ì,\_BÌ‚¯´áàØàÖ¥Áû¶]Aìû}{m¾mÏÞØù®vã‹7#ve uÙ¹xV ç8®›Ô®Üoó>ô£àsü„#¸1ë³á½h;ˆÇµõªöþn .ßvêâ–oˆ Bü-Ĺ÷íySôîÿô\_#{îˆ%¸r;èÞÝ—“ÛG çè}ë¾î¾}6ÿÆCcpÿƒ±ËóŸ»P¦Þu‡lÞù‹‡:¼áÎú¦h;‰ÿ‹9ým5cª·dvMÃoã½Cj[ÖÄø¶vñ¶Kóu²ïÁn +þt&ɃŒ{s—žƒ:ß—X?m¡«6~Vµ£a@5žùÛƒ¾Ú±Úeû®"6ìÁÙÅ5OˆÛð|®—*ø%GÇx¶½Ž¹õEŒ¹<»^§‡ vÑC—|°å{G£Ý©_·—è‡à–N@¬Š8¸¾©` +o½PÁ¡Š~êŽ78Ä~C?€`¢ ø¨Ð×Äs'ˆŒã ß±@Ì`”7bÔ¡âÝý +åè]}EÜWAìxÄEAœïŽ×&±‰Ø2Kˆ-ºÞÿØoïÀñé;üïwâ~]ðð'3BGï÷þD\ºª™ˆŸØ<à@¯9pµ¿mýy¸§}â‰/†ûRž?¡Ý¾/ vVíÓ_xœO|{bgy|n<¾óá[{ìZßòCWb.kYs~k<ÁÎB¬\ÏÚ ãsýaà øEì¬Õ +v–ÿ¡ñÞ=?“ÐFõV°ùµË÷Œ&¾&è}ÄlAØóÈ›œ;ð½þà5þµ‡®!XókŽ îzƒ÷=òŽDpmqÏ%¹î‚ºå †ßÆãã|û?(óüý÷Ánu?u=ðÊMˆg‡8ˆ÷Üôš½vÑ£—yš[ûxî&\Ó>û±ý"²¶qä«;\ýB øNc‘XcÓoöï}ï6ÿÃïND?©ª&Tâ®[0ÈZ8×|‚÷Ü7qPƒó;‡Õvlå;ð›ŠúC¿«&X2÷n¿}7ÄC³«!^wÂØöÔ– †®# ®kŒàœ.V»lÏ•ˆÝ…1ŸÅþш¹á_ûÔµøŽ YgZu|ŒÇ+®_Æ— óß³â\ôà Œ¥À–çoÂý ‚ñ»o„·i!ñ÷Ñ ¬{ñï#ïMÄ5‘ÀÚÃ×"æ7Úo/è8ÄB¹bë Øpë`ÜÃóÐ º q§`Žz·B,è£Û'>r»Oüq†kÿñŒî¹7¿f'ç&;Wœç?ñ±#ôÚ¯æ5¿úFkãó¿l®{êÃÙž#¿+‡x¨ ÛŒº(¸lßhèKàd¿áðX<ëæ›³üœÀºד˜yÏÛ‹v^쨛7Ð>5Á°¾ïˆ q·¼0~pŒ;½‘Ng=ø†ŽGM]‰§yÑÙè#_žGþÇu ˆ'Ïv¸j,OxV`Ãá1ˆo…ç—&Ñ–7ìî‡Í#æbÊ‘÷ –ŵ(ïœè`ÄÚByøÑïÖ—oµ|´ÑÞȲ¡®Ú{!Ž2î¡Ö=ÁG!{½ˆIõØÕˆ³†kÛø.™ûO9ܳ"˜‡¸†‰ãbýk7×<3q¨kW°áùßî·ß’Ì££××n~¹Ç=ék\oB<®U{¯ÂµkÿáOîým÷%VŽðGõ6$:vüÏõxŸýnVíóŸO~^åÝóá$‚ÙƒkwúÊ»ï×·úûõmÁ Çn ˜æˆy >ñY·ô&ë~ò« +מ_ò¸¿‹ûÍä]ÇèšáÄ&m~îFÔóèK:×\@ü”¥]^»zŸì ~wïy›w=ôú”â¬c<ï´ Dü +‚©v…è¼uûð Ë 7ùÿ‘ؘ÷Þ­Ïó‚q ‹þDôø¡ž9KÎÆvãÙ3ïS_߉€n\·~üw·xw¿Ãâ\@ûåÝtdŒ÷ÀåxÖ3øÜçqDW/Ùv1ú¬X/Ñ1Зxöñžð\±{¸v…qÿ¾_•¡N%{Ó¡ðY÷¢Åú=áø`<“káˆSä½»m°£¦^ÁD\ü𥈩‚<áÞ˜§yÞ ™wMŸ6Pâoƒq{Ì ¼HÁ3ÿ‘=°ùÙñ¸†Š{è3«FL,°Ñè#aÛj׿!°ë-×gë`üAû‚ë_ïëÜù<ámY6,Љ8–P?ꯥ]Žv2€Xöñ¥ÃqýÒ¿ó'ôeYðØGĉÁ½z‚õµ`ã…äì ®5â Ïó­¿ññõâ.úèVç¾_KîÝo3dOg!Ø;0Ç|ã½W}@\À³ÃKºLñ‘÷^…ç\û~I|'ÿú£×¹;;kÛÎÂXq«Ðç@L8ïâm`gv_âÿÓç­6¼o÷d¯l÷«´wÿû·ùv¿#â>½§qé*ß¼®¹`ËÖr1ÆÎ¨¿Ñ$¸éí›.$gŽ ~უÀŽ"vñ^A§øíº1 ž0žW\¶—`vÑ÷Aœ[\£½wãE«‰èàÑç×LÀÅ9îÛöš¢ûtÁ¹B¬X\g‡9èÙ­‚qñ úE8!b=»~Bc?¢OèÙûÁÿÔ|<1ÄEüa\çÁuò…ë/ {¥à!>[à‰Ïfâ{tž…àoãYÚu ·ûŸ¾±è^îÓ-Þ4 +ã$ĮùMä€úáÁÞDÎozö:<‰ˆAˆçq~d‹úªvž«ˆ]Úòb)Áž}÷¸–ŒÓOq?øÆMî-¯÷.Ü5 +ý9ž{yì×q>Œ­9­ƒ'¼æøns¾üÇY¾ãœé;úÍ ÷ÏÝà™Ó1ßAÿún,âô€Oæ#bÆ×$í&óúÕ ÿ²>ÖÇúXëc}¬õ±>ÖÇúXëc}¬õ±>ÖÇúXëc}¬õ±>ÖÇúXëc}¬õ±>ÖÇúXëc}¬õ9ÅŸ±c§Äš&‡’¡üwŽ6¶l:_”šP[2œ1lê'”%’“#ÉH<JtÚ&šwf¥kúdÛDÛ¸ÊPg8QOÕóõãm“lãʦÓT=”€_ÇÛnÆ{);ÃÙ&Ô„CQÛ8¥bün«JDæDb@t4†¢aõÞIø¿ÃJ%Jí4Ïs6‰¦9;Ã3´­…ÐeÙΊ o G‘®^]½C¥§êéŽn¬gîˆažÃb#†Í1L¶oóÂ¥+ý;ÈHB•'ÚÛæV‡’ÀO,%¹úYñXu"KFbsJKUzy85þ’m%¿¬È÷´©‘(‘ùý;Š=+Þ&ßÓ{¡‡Ÿ ¶Dcðc)40ihO†Ûˆˆ¡3¡®÷4ÎD›á¹ƒ±M˜K¦~Äÿ%;[•Go›àŠEꀚcsÒï\ж«·.ìùÎX¨E¹¢´­3Ô™;C…cˆ¦L°47™37™;_ÚýEÁ\G¤)97wÞÔÛ ÅZ¼a^¸1Yo5A3Ëã½LŸÍD[À½É¶Ü¹M+T(žË¦×—E[ç†ê霙4Á­½1‡7Ýœ[Ãûœ‚µS|ÎÂhµ…§&Â÷´‡c&´S—b…êýd{¢¡= +mç̰R8W>õG„½XÜ‘Œ${Ñ@æÚÈíÎH4lb§*«LÎ<ÆÚ[ª“¡fX4–)äXÍ™ÉD¸­=jªj÷稲ºã€î‰ƒìJÓhEÂÎ磡é=wGAzÊoO4†§%B­s#¹›•Xî݉nöÖNKñÖp"”Œ'rg,U¢(¦Y$Ö‹ÞIï4¦à¬"ÞÒo‹$MͯSÔâþåÜŽ “ÃͶIVpÚw²‚S+8µ‚ÓSœrVpª§¹êÅ›6'BrDgÅ#mVtZäÑiîó׊N­èÔŠN­èÔŠN­èô¤žR¦ßŧ¦X*’•ëϪæŠ+B…h­<¼ uÌ 5Å;¬ Å.‰dû¿‘»gß–lš^ a³Ì„/ÆR…â²!ÚÞ‹-,~ï~Z¨½­-Š•÷Êkßöïs‘M&ìaS ¢ ŽL8-MôZLͧbQ…ñææ¶p²÷éSüª¢ŠpZÌJ"w礭5ÜØ %*â±¶d(f¢³2KÌé¤L³;eak<·ÝTÉB±›ûé­¶öDs¨1¬žΙӴR…â2Š žqnŒG㉉s{]7HsÆ:Mq¬Ün™‹“ÈΗªö^&Øé³}MC—2|r–΢ܳ¨€«5¼žŠdŠ6ÕQ¦×  +éèTÇ#±d¥©¦›O]kª…­T51;`fµ_±hõ~¾ÿ’ßRVÛ0E1(‹4|Ëk›©¯)Ü#¸ùlî=„÷jôånCç÷Â|GtQpÔËWG\#éÜ92¡ôæPçõïã¡D$9·%œ4ÁZ1šeóÞT±˜äh$YŠô¶eÙä|z¤¯™ô<ÐóÐC…ìå™áÄœ0ʵ˜=/ÓSòLè¤SÚ˜>Ð~yŒÛßÖâÌœ.²Nƒþ4ÝoOƒ¡ï+UÄãÑòD8¼(÷½¸þ~ü¶çžœ jŠ´›èvíþÂFÏýóh_S$2±¥\Œqsîö=ÂÊ>ÎQ?¹ÇܵÐ)sˆã‰Ö¹ñh|NîîKŒ¡ú³N´4ajÂÓòòbçÌÒ„ YûÝym3o(‡lÈ}ß«èÔƒÉ÷”ŠG?ÿ)m3}S$3‰2áøYù;záÔÊßÑçNÔkþŽñX±Y¸ÜY+2 ×?’Ôä¾ U17‹…£Žp4Üh*ÀÌ,Y¨ÑX–ûþTÞÜf–,·½=4“ï öå£~è™™Q“Es|ª!÷Xtf-w֊̬MŽ´µFCá–p,93ÔZ̶²iÿØ2¾Òi_sîLòÕ„w©Ý_ ã´HTeKªË}C¿˜‚º†Ü—#‹NašÌ¢Z< +³߀ž™Ã ìÛÊÒL‰¦0‘g¡˜Óå¾>RtJ#wÖN‘Òèk³”êÅ÷0.à"°œ‰…[åöBuu(ÚêÌ9™ÉPÂÜPV +ŠA>wæšLäÀRn.SÑH,Êý…‰ÆP´qfÜÄÙvC‰B±Ølî-Ö³Ký÷ì’ ÖŠÌÆYg—¬³KÙ¸í;g—roŠëìR?ôĮ́ɢ9»ÔØÏ.™`­ÈÌZ>»DŸqg—ÌŒÓ"Q•ýøìRcÿ=»d‚µ"S˜ýäì’™*Mqfœ]jì¿g—L°VdJãl¡ãQ,3l^鲃ûE¢P3g­î9íÝsJóô]ïœÒÆô†ôÇ®eÓë'“ÔLõ&×Súññd‹fE–W¬#œÞcUÏyå­²ÔbjQ°Ô¢Ê_î’°Ô¢¥-µØ?Õâ”P,gÑr‹\+†q[JÑRŠ'O)Z®¢å*ZJÑRŠ–R$JѸÃVoòðA?Ö¹Kâ$í‰ã.«5Óòži¢5ÓTþr—„5Ó¬™Öûxâ)ŸûAUE5fΪŠÊKîV¢=Ñ n¹É>M/UŠ´H ¼ªú­õ3Ëß‚än­*Z«Š}}UѬ·V­UÅŒÐÜQki±˜–•¨dÒœD8›Þlx¸‘9ñI "ñh89)nšO„b½]°Ö î¿ ¹/ ‡£penUÎP¤`Ö_ÊÃТHK{²Dߴɨ(ðòÕäY‹©DÛN A{H°T©Z€bž &°ÛZà™æ×Ô2KÎY6Íî”…­`ôòa7U²p~X/az?Z\3ÓµÖêZßZ]ÓfLz ª¯)jk%ÊZ‰²V¢¬•¨Sã&X+QÖJ”µÕçV¢Ôu'e%J]–" RÖJT±ÚÖJÔÉZ‰*œŽ-ôîø™²¾æPÃÁþ°À +endstream endobj 133 0 obj <>stream +–Oh[,aû‘{¦¿¾ÞÞ×\N•>é‰gL$5)’Ä3&’šX‰gú>GE’x¦#!™gLW-³$«C‘Þ¶-›Ü'l²• βÉ}zÔ‰M6­ô,sܧÌq~‹Åf’­$p&mr1ž³0ßÙV¸ïÙ˜>Ðþ˜î MŽæ˜jŠwX8ggDÞÜóßYy7ú¶ïÑ_RTäÜ”;67¹·P£ÏG½˜˜4ŽÉ|*Uonn 'qú$ÂMæ´}‘ªŒ*Âñ«|.?‚–¾Ö]§mç©èzÊ +/‹/¼,¥ù±9bŽAýS,™ðÞ +è¼Ñ,•;KsæNê÷Œ9Îs‘&3'NÕÛ æÍÑ‹7VZû3añF°oúI$Ö_o¤~·xc‚#kñÆZ¼±oŠ¡ËÏ„%¾Ö]ÖâµxÓoÎÔð22s¯¿—§ôSaNûÚsOÕj OM„ïiÇM¸ó]ŠŠÓæD¨1ŠÎŠGL¼¡Ï•SýaÊðàHF’½¬Ù¥­àíÎHÔL~ƒ´B…bÕD¾X{Kôû3<ËŠÅÆÜ×ôŠ-w¾ Ö¬´ùÝwz1&+ë÷9½¬”^VJ¯lÒëÔ.ræîšö›Œ^”=w½dÜ„/Žp¤9o11ÉÝ…óÍOoöµÂ-Šå‘zìT-ˆ9Û íQÐE½jÆ[.’E+R–®ËãíÎB.}çõ✻%ÛÏ š`¨HŽ +Rýù¨ 欣‚E°—“ò†ê{É­ríèPvêLÙÿHæè [»}}÷#÷3jźùcµ¿èêÑ©©ž²âS+>µâS+>µâÓ>ÂYñ©Ÿö™ø4÷¬ÿǧ¹g)îðÔ:ž×ÔÜǬ Zjê)+@µT+@íj)ÝïBTS,IÊ÷ç Õ sVZAª'oš“™°¿ý=Bíßð@¹G2Vʕޣ™¾Ï\‘‘ö—<2Và9²òÈô™¤"Ŧã9$)^MxRÓãf< +¾eic<OLlˆ†çO²)¤xk¨1’ìœhf/ -Ù5±2®Þ^¨¡I˜î·ÏwE6ï¦â-æig²wŠÄ®õóâï• ¬X`ÔΠߤ¤±­èÏŠò ÃoU‡+â±¶d¨7 Ê´§kÁBI³è…ŽÆ—+­P¡xì˜k&åHWÓá†Òl¦‘Õ®å +ÅmîÇŠÚÚ͡ưÉ.M/eÅé'‘)³øåÅfM㳟y‘„Üó|…£penñÝP¤`F†Í])…EZÚÍlê +ÅQüOöuª<ºÉâ¡TšÚ“¾ùT¶‡èJÕÚž~¦†¤mÞÑÌ,Y0%»–Ó=eak<·ÝTIËé´œNËéìiUB2Uí¹o›œâ³¾}MQ[Zñ;h–vzü3‡ªNúƒƒ–j,µßÏ÷NNÛáú¢˜Eú~N¿ØQÈݘßKÖ"cá½ór稗[Ó8¢ Ç‘‰>êå„JG\QpdBñÍ/ ÞëßǰC‰HrnKØ M1šfÓ»Ec–£‘du(ÒÛz•e“û„M6aÁŠÄ&›Ð÷–Mîû£®Hl²i¥g™ã>eŽó[ä°Lrÿ6ÉŸLoaç•v: GÑuÒ)mL1–üt‹ÃÓ8sÒs[ùϺ2W¼ùÏÎxÒ\“ƒ¿ÿØ?Ò Ñ6Jý'Û7’sg’¯&Ƭv×b±‘-!¨.÷ü;Åd3¦Aé¶ÞÏÿ’!¯¾ÍÌ¡#û¶–éϮ虑 +èt¿nZÈI×_²ç”æ#KúœÒþ—?çt­¾„¹ª‚¼«^HåQü gÌ;WÅ2ûù Îï1ÙŠg{ +·mEçi½_œɫÊE£Ð&pé‹Ùý7vbî/îé´ë/þÿ5ä8½ÍáÄÔH¢Ï,õµÞgl¹ï6$C ѰÛäÒmZ¡BÒˆS½ÆYHe4µ=ÖXSÌZÈ.Ú(›5ûÇHœVÔ#‘¶Tbˆå}ሉÏ0i†3е5›€Ê郳#/ŸªXÆ~¾ò“ï[^Å´è£ðØ—<~kÙ§‡.#Ç'ˢѾÒY}M>yiëDï÷lLhH~¨zc˦ÓTý”X“Ž®Gh<’êgÅcÕP IlUªÒËÃs"1ã/#†ÍjUêá”- ñ(4©¬©É65´ ž@¥3‚²•FÙ¼øÿ²ðˆaíi_ªàvAiY–9JhŽ—l”æD‰—eZ dJxåä˜.E‰ciVdxN‚ R¼$1,ÏÈMcAI‘ã)Y¢X™alÞ>E;„æíÄ«»àÛ< uØhÊ6Ó¨¥lMÐNo͈a¥”ãF’m m—xŽ·µ‘ì´Lqp»æiÎVÊpv^f%ÞÎВȉǒ¬­T¶ ´D ¶ +(¨iÆ.H”h«D"gy +3”¢€üÂð<~aí”$ÀhÑÎ + K(¬ Ó¶F¥¼¨Õjy»ÄŒBæ +Íq|ŠB +RvYb8Ãm²á@¶@aì m+…z( [@KvšæXÒz]¥4m‡ Ø|ν§n’dg±N¥*xô›zÍsƇC‹€&³ø\ý&úRbR¬¯œ 3i eøŠR×Ä%AS’Ä~áY&%o`C§iS©Ð8™t/ÐEcA$´ˆÏ±ƒy›a@@_ 4« šÄIÚmȤLÁäKU””†Çáh&’6ÜM i1ÕndŒ1#s8}XšáS"(EÉ Ÿ’R)ˤæ¡`;u¢&tœŒPVAÐv†(¥ +: %DË(!g­™8ànžmŒ…g8 F#À,¹ 0E8ž·Áì§XŽÁ: ¡Xòhh4ÌÖH‚i +z´Ð$jD½À`Í0€Xcc4íU7æB­ +¬ d7Þæõ€f®ÏªË€œ¯6ƒ¢Ùô’óÔhJcòÒiX4/­f”‹Q¯­Ï¢ÙÆÖ›×mcëóÓnP./ý6¶>›†S¨æu)—¡å€šEÏ­ÏOÓA¹,ºŽÔ–‡¶¹å¥ïÆÖç«ñ`å§ó”ñžÖS&Y^zŠfÓ|HÎG÷ÁP0­ýÆÖgÑÐo™pl}^:pl} éqe±xÌ&3‚¢»¸™P“ óR(š(˜ 4ñ ßýDò' 'A’‰ºÔHÐá2Ç*š”L=:+M+Z©¸µ0œØ¬4Ô²¢c´¢YHD¤¢âg¨ ÉB2$=˜I2´¢+Ÿ•=‘,2I€îÌ"—Õð0ìäLÙ¨†æ§*ÈJ4ˆ#Õ¬¬Ä´âYä”"¦µ)‹¬ŒƒM“ ‰ÿ&Óã}(­Æv%±Õ/‡1LœH:µ¸¶M(Ç£é7ÅpÙ}Z{¤I ®ÇÖó™UÕ@ØÕ–LÓ† +AÅÀ$—mÌO9ǃ¾ ¼2#’Ñ>¡&Š*o`‰´ZeG4¢¤ú…(oZ"Ò4#ܩ֌cýˆa²><ô(Rý²…ƒåíÉdѾ•vóÕØ«iý­wT©ÖSiÃ%c,)ìÂ8à²}цh45D”¢Žgmê£Ð8xŒƒÊÀrc÷£ˆ1?Šànph»é{SÌ:Šˆ‡ß[YêvåòÜl£(§ç‚G™6о—¢O¶âl ƒÓnŽ*á¦HÒVJ4™0G}h‰’ˆÂuIõ«:­™„àŒbÒh@.ÍÀaÈË*—r W,ܦ^+Á#ù¦W¨~ÁŠá ñè•/ŠÖ×~5RjRžáé P[¦}Ój2p¢2h°‡à×@‘å‹Ê¼7FýKËXþ_¡È¾Ѥ~.5”*Uª"÷Êi­Ì¼TZ٬ݪpТ] +jXN­[ûB*¿ŠØJ•Vo0–T+¬P[‘ê¬ôËfÅ,ô5Ç|Nt4}Ú§õäP2<5Ž6õèh’©ÌÓ-‹ÇR”Ä1`r,· ýÍH’˜B‰<'Ò0ƒ)™áA1C=-§f»E™ë rí¢âþ• +ªE†D†›¨ÿÕñ•Šœ$ò2hˆ»aÚÀãA 8 +,(/±¬¨½‚qަ¡°}Ð[v1u‰ÍÍ¢” ²'-mÊxUs-èµI.úôrÔ†+ Å/$|âS…žÜA¾CÓWY2m º4W —kˆÝÆ”ïõfî!¦:·šËs¯™I7ÅD-‘àN• g”Q¾®r.0fd#˜‘ cF6tºlôÉŠ2!Ñ\)®‘)aÌ¢‰KÿB÷$'AN ŠË.( ‡!EÚ#c{¨î\=ô—wr”&‘Ì*ºñÚºVÁtð#£²Ì¨S*ŸÚ_¦7vÁrñ'‹c¶ ǬyŽÙ^9æUŽy•c­gµ¿=NÂ1{²øºð+˜çWè…_VÕ´6ªim0³†/'qT žQU§ÿ faQ0°˜Q" GŒÊ£òC©\hOî˜rž¥Bw³TÈy–vñz,@³´Më7íïɳ½ðËvá7Ûí…_¶g~)uÈ2ê°dÔqJ¥þžÄáʦ W®Ë\îØ´áÚ¥D&3ŒÂ‹½(c”ÒþœÜ‘Êv7óØîfÛÝÌËΊ²E¡Œ6Ʀv†úçdA6ç)Çv7åØœ§\6V‰jl!iÕ?Òþ*›êß“3©îúê®ß¨îúÊÊ ‚¼2Úxeì±ÚŸ“;©îfÕÝl¢º›MÙYáVT^í õÏÉ‚§¸O\†x3cˆ²Ë ͉"G¢$H,¯íâ6)Í úzŽMÙG¤•£d\ÊMŸš)w–Öb7|± -)‹©[PZÿËbÚVÖª´Ž³¥¢4 µ³l¢±¥GjZ×]׈½…^ÙmîaguôiYlݺ]$Lè±4OiHžÏîÖ_ëýÙ }WROú¢ Дö?Ö®,DžÖ¥—D¼µ)ÞÑû_Úâ*E†¯¹?:µãGv!xÜVæÉɘ–LReŠT*Ø9òÅH“È!ŽìCð"9é¨wh\#ÄÃ"äh“œªJߦЉx( îãSµ§(‚¡6hhk4½6퉲z“Þ. 6#’SiMU;Îæx¢EËN§ŒF¶Mñ†p}Ùt¹âHvFÃõ©§«·C‹(R¢,ŒO—.//kllo©‰'SÉôñ-Äs¨™|–WP ){1Ù0>¤Ô€Ä1@ñ² Ó`˜(7‰vü  r×iÆA›"bQ2”ªá‹:òô*¥Æ™ëzUX’QF(§ŽY««–ºÎ™ +,“1µ4’ÆŠV­Æ« °g]e”ë +W#Jéå€|dòå¬ú<“„Ûh¸U¦µ‹¦y•i/YÝgñ!4­Ô*eÙoë¾VJfíÇš µ–7žŠ¶–ß¶âÚ§¢fÒ›ª›ˆ>–Œµ}|ÒÛZþ}ÛŠû-™µZ +¹÷Ó=éj&-ª''=Yˆü%‘e)÷t–a9™Y ÂzzßY^’xl¡B¼ÏS"O3¸ñ‹Š‹ÑÿËvrC ý5@«‡kWšn¢SZ‚€ÜÍVª²/|œ>xr•m;d—Dš«(\ÅQÿœîvj$Ú’SàÚ](Ûcüš±§OXšÅ)€uôÛ”#-¥ð‘ðü³J«4Ðð yµ¢2U6ÍP¶Y¯ñmЍ ÙÎŒr @£¡ àh¥ +Ú.á+:YHZÉ{þ½·ùõý>¨À÷A­@4ÛºújJyÍêN»¼>Ù6µ}Ñ¢NêÛt_kl=ÑÎ)—«Þ{“ê²%’]ÝÇÊHl¾®i'‘Šë3«TÔƒ*µwgªË;k®L_,ã­¶4å®]ÜØ®´÷%Z¥ü™C¨™Þ¾Ì™é¯¨Fï,UCvjZ ÍJ5™N›jðÑ”·áº8n)¢Áu[ÎòhÚ}ƒ(á´:p œV_Q=N¾}|ݸ“)Î\¹±õS•Ù£,V(+£Ý;qzê p¤Ê¦ÛÊÚ“q›¢ž"‹Â©ø6sí¡ª¡-œXnª‡°^¹«-]•¤Þ +–3Þ +îfS’2¼÷A±¸~ÁÑøêY! |û˜•Y‰ç³ð¸@ê 5KâÙ(fÕи|¯éÃèxõDšHá«ðW¢%"qy‘ŠV~Ñj,H±\ŠX©šãŒE;ŒÉP»@Ú V¦; E«L'²"ÙÕª‡/<'*µ)­Ð(¤6Z¡©›¢ +S©¢:ßzõ +iEE6™iA²¾]*Ú¡;.U®¥ Q©WPiÞØÑ.‘·ó) ’”Þz\ð$#㲴Ȫ7RôÖ§ˆ©Ö§Õ~U«×»Mo…±Ëµæ{\gJ/šb\­ÝHÐ{U·È +Í{2Kó°ôRª¦×ª^„¥“RÂ2”…yµVoíÁÆy¨6Ï -½”Æ´VkêZ“VW¹Töžäãôì}Sê†ÈIÝ'ËÔŒ­ó°T7{àúMHRnTþŸË¸$rß{ \ݦÓþýWêúûþX’þ¯öÍúXý“e •œœÑ×ýù~NÂF3ž÷³SîµÁ-¶ªDf3 +ìd×sˆýrGZلκ»Ó…œûþŽºmÜu‡G!ç³Ç£”ÌØåéB6³ÏƒE3wzŽóÚëÉ&CRcL‘¶¶)(i íûgÝêB6±%³í9ß} R4s'¨ ÙÄ^a.c7ˆPóÚÊ&ÃEŸu£¨ ÙÌVͶYDÈùl‘‚FéT[F„³ÌM#BÎkÛ(›{x¶ý¤.d3;J˜<Ëž!ç·«DŠfî+u!›ØY"Üeî-r^»K٤أгm;¥SsßxÂ\ÙY¶žH +íü6Ÿ°h–í§.dP˜Þ=s +Îc*‹ôz”u¶Ý©tjîûSøªBæ¾xŸÏ–ËÜ¥J§æ¼O…,eîT!5½ª,RëQÆÙ6±Ò©¹ocái¨Œ,ÐÇVåÊÜÌJ§æº… enh!5-­,2ëÙ%ɲוNÍ}· ÊeÙï"Ô»rYä–“—œ&ä<6ì rš„óÛ´3¸ÁiÎoã.å§ 8Í»Lyåä§ 7}½”Kœ&Û<ööRŽoš\óØßKùÂiBÍc/SN9ùÁiBÍcûO÷ÓdšÇ`ÊÓM“©ùmÀ”ó›&Ò<¶3¥”“ã›&Ò”ù [@I8{çí­tÏð¼9<»€ÞÞJwÑkôÙŒ=Ñ’ÞIÆÎ3ô©¡§ CÀЋZ'jCFU†Ý¥—ýohÐIõÊлéÎù©È;;„.b ”¸ÞÊ‹t÷9>¿›þÎíù]átSÊ¡Å0óKõ©oP)©‰Všši]„Qu¨Ã "MÓP©q0u×ôIBϲ·~Äêµ¼ õÜ9<¿»~Ìéù]ûñôxÖŒDÆÑÊp#S•V&$C°±%®§$¡Ô*hò†Ê+æR£°­Bn1|Uïh6 ),L +Óé£.s6÷µl²¬]9Á]á4wú½;pþ“¦]º¾´ÈNñ¼@>¼äí8§Œlg)šDø"m  ÌÚ÷ +2¨AL‘*S$ܼÀÍP# #,š±!\‚#”Ò¼]ÂeHu +Ê.T…>"Á¿²ª*Ù)YÍI% ¢º8MnʤhõJ×G•vmLiדW\3ù*5²®®—§Ë¦Ô(¹R£TG(€ÛYòd1²y;+r6Ÿò°*ã¤Z­˜Bœ´¯ƒêµÎ°AY¯S÷§*S–ãO24"Õº +e8hí6ò´ ådƒÀEžœêÏœXåHŠ#§+UReŠÄˆÊÎUe–’•ê¨ú„“–‰t®šAÔ{ÛH0öQw­âÊÌg©:o3<¾4 WDcŽs:õð®×é•",¹@äª)]õRë)KkÛ1Y ©¥©Ú”+;ϱ²F*Å\Ü—dí»>†p†g8Ž&¦'ãŠ×›”ª¢Kí©GWôÕ GÎøyZaCbOÿ6GÑÝ0h&¾Ym†¹Mr1£ºþ§Ð@9phgAÅ/D¶Ì%²yˆË¿2MÎz(„F²ó&p´ºGVOqèµhíQ$}…Bƒ'pœòÊ +©› ÑtêI¡‘$nPš£ß¤5X¯¥+W=\ygVº¦O¶M´kŒ$£áz¶~¼¼ý àÇ®o‡a_‚Z$‹È2ô +Ç*X~”•h‰tb%!r Ѳ¢¡xŠl‘rF œ]wP`àü‹G±I/H2z¨x3ô­" +–EœyŽ/–œ³xü‰Â™ Ωš%D!¢ÞAÝÁ…öÐYÒ•ñˆ’ ÿŠ"®Ý +ÄJvå¦"“AE¥AÑ›a`t1o¼T´ Søö$þ+EåÍ øMXrÌRàpË»5 ÍKZó" FÉdJƒÆX2¦Dí´’bÊá–ÅÆ¤7ª"³'Á=ù: Q"Xæ[Ä¥i;…,[Ê2ª…Ó¬¼áP¢qnÐ}M©%Fµ‚‚e¢æÏ“ÀkÉá™gâk’=}£_Œ€Š22±¼ 1É]‚5§ÄÓ<ò„°’¥H¬LÉxÖQ r +‚çNRË0¸ekïáxÉa$|C Æ¿áºBI„Þ‹FbìŽÈع™`ùEìzh9ÃÐZ’/Ô\üêHì-šSh‚¢ƒQùÑ©žÉ轊,=ZÙ{Ø‹çX\\–s=!ÀôîLcÛ—\Tˆ©Ð†Àš•a€qø*¯,1<}ú}Ô¹q’ÙÈVJä°Û'W_i»rX·A´•&ŠVP™)F_k¢hãj#*'xiÜŒ ”täAF’âa\—‚(tFðu*¤Hd•l8‘™¥ÓÐ ªiÚ€$’COð<è\FV¯ÑBìÏfI$h9A•j¤J#IPðe5Â"à2'qÊú ÌãA9xªú?KDQªí½3"$D¶Á`K¸&«Ó€!HP%KªÔäQñáu´ +uUªÜ QêQ¦]«ëÁ +/\ª* —ü´kåMUNËvzX79–ðŠœk*«Âyí%¯¶E¥¨mEX^¨Ú%Kž Ìhh¾Ÿ¨—VÆRÚÀªÐò!Ê K¬¥8Eä\¡CÛ&”—xõ ¬B"ý%1ÊQ.µh’^›¢ueB»µ…h}Q’icé üm‰R“«%)×É3iÄTY²–jWr€nçÐÍÀ§Hj•`ßEQ9Ž­Ó íÖŠf!iµUê9s‰14°¢ÓpêAÕÆ±ÎsäisÖðŒÚRV¤TRç1ñÎu>å9¢º?AЙm0+E˜>õš#3Ž„p*EÒ£Ö@fñ”‡¨×ʲ’ˆø0Ú4Æx^^¯B#ž¢‘´†¨uhí슲ØåEÞÈ”–YJ/…at˜V§v©?U#¨íÒJ«íVkOñ…ª¸¯RXš¯ÈB2jVÅfy”V²%£n¼”2ëÍB2ꃇ– ¦"–šüÅE2<߯Û^˜,K„CõÍñÆö¶ni²g]CâgIdð½NVb(ܪÄHYä9ÜÈ‘CL­ÆÏx(N0ÆÇ´@Bf-€K¤mÞ²î<¦2Í‚ÊËtDTЯz©«JíªT»Ìr¥]´)CP0< …$p¶Ž"Ëã4Ÿ#uU©]•j—Y®´‹¶¾6òh<ÒaCÜEü+cüO‘LsuÊOH”°õ³â1rhª(-Uéd<1lV+ùMR~«Ž¶Ãÿ«æ…“0bÉ{è¶òD{Û\ÛÌP,4'œ°U%šÐÙìåG›òkE(€½jiTou‚œ'ØX[kÒn«‰·Çš&dÞ;Þ-—^‚¦z,’~3okUê€S£¡d¯œñöƹ?+u´ÍÕŠÃ誊A'ÍM+[17”hŒ‡¢¶R[u8Ö‰j·7á]J]J„’7´Á÷Øœö°v³Ú÷Yê¯ +uDì‡Z&Œ·ÙÕnƒ®Nï´S0š”Ö¤Ú„=lä¯1Q8:ÌÊ,óÅ•<*g+›^_ž€i “:*# 0;ë+p§PýS¯pXÇSž§•·l]JØëÚ©HUbÓ¼0q‚MûæóâuM°©'‰Sz–Ö¿Q +èµN»WÈOe85¦ºò§ÜYs'ƒdã³þE&¬5È„êN&§[Ý(dÞ¨`È5ªò¯ò_ʽ¦znsžÏg»>D˜öpê>œ'Ç©¨<›·)‹ó2ù÷T>9»æm›«´ƒ‚P>ML.MÉgÔÈÊo ÉÎh<Š 3bñ޹BOb\Y´³­-T?Í1Þ6aŒ}´ÈÊÀÙXÖošPoiÅ.œ‰bšõ‰Š*‰ÄlÊ- +Y‰Û&¨÷ÜŒAÆw¤-þ©4K%Žd¨q¾©JÊCm‘Æ´ñùa3U0ä§hUB-е½+CqJbUú@Ÿ¡+)[€ÆÅSåòM ÀÅdDÓÌð ooŸ«µµšÚÃ[»È^o“ ÉJ\èlP-I<'ó´D^¢Ie†áX^–%Bá!\ç(¢uQ‰ñЦ/ñ‚šf™|Ó")r–R  ÈŽ$gvã1?Ùö,èòh8Ötò$=Ô—Çœ5𔪢G¦ Ì”…áÆvlŒò#©"‹ªá¾}1hÙ“Ò’®=¬MUëV57·…“ãI¿t[ŸéÑh;‰Cã {x!æS¬"â ib—V£­Dj›ÒÜ VnwF’yj}}ª*”Ú§ÇÚ p&£a\U{R¹ÐhLŽ´µFCÊåø>b:Šw^{xJ†vÁ¬YåbI hV X†6Æi§E«÷Ë×_94eªl2#XæÊ2W–¹²ÌÕÉ +júÎáIËÚYÖ®‹µO¹µËncÈꨭ"žˆ…m'ÅÆt©1eWzîÚNãÉISd´·õ0¬½3vAïûHÌZ*ÊY#IÅá[s¸ç0qÈ(V¤Dß4å(’³Šb8‘(pÉXDÉ$à’'S´¬»h9QúÀ³bmè¿'ÁÔNUv›s7²øþx¾:pq/FöÌU~²¥ü,å×/˜¾¢ˆ$|YÖRDÝ*¢òh{Ø6+\,»v}A‘#¾¸ÁѬÀÐÿ?{ïÙ<’4€ÞÏï9Ï0`rRBLÆ$ƒãlLM˜Ý™÷·ßê €Âfvgöγg¼¶Ôêê®®ÜUÝXÈ 9šÄ§öp<ËñëµÕIïåäÜ^ïÑÛªÞIø%:Hœðˆt’}ÉS‰¼ÿ:C`™¡‹ËBISø”& +^IJ4%y„`‚ )Šà(’ ‘ŒTNêÜU¨#pý¼RC¶2÷øM¢Z ½tê vÉÿUì²,¨ä…Ã3ÆR%ZY m"’´—4ÎÕÆ(9AýÄ™èLÔÿE\r|ˆ ñ$l œŽè’AGoñ$ O9ŠÝ0>©NãGÈT†w9, +XU€w6Ñy5ÿ“èä9B'š àtð0Iü€æ¤NæsD”{ÐÇœwJ˜ô¿'hÀfüc _ËKšFÄÍLcÉ«½’°ÐÐ.:A–@ãHòfEïŸJܲ¸øó ¹ÿYº ±4O³è9š<.=jÐÉC:ƒj£”5 ¡³”J +'ÿ)-Áî!3öoMfTè:;šÎ°x(°c˜˜7؆¡h¬M0ÚD6: í?,§T9èK>¤ŒøíS8Üß›Ðþ#töO¼åŸ £cBÉþ|:Ï®ýü·ü{F,þj‰2ûë|D픟á¯ÐGÖ`¦¿Ó)úaB®êÅ©q±H‰3 ¹EY::ŽØÆý6ï­ù@>Znóyjãƒù|½y­þ8˜-·?«@¨á3e ÖÙ!|•5Oèäì5ã‰O>F¢Á`ð»ih¦¹Û[U„ÁƒÔ§ø î? iç+åÔ)ç¼› :Ó®xDv]õä'0ì)†'Ài°TúÛjÞÿç Ú¿¢ûë"Bˆ–Ž©{ \QA`Ðyî¼ÀKO€t86D‘‹„H†R¢P†j²ô;üd%¡³ËNIG¢ä^'Ù¢"á“챨ú3»Ï‚NóD‡ô¯EÈ´·Xº×T‚…Ðçd9ØM“ñh0>‚ñþÑRÿh©5öÿ$-µ–ë ÅöÈš¥xöï«e°¸þ#Zæ+±ûøÄtü¥wüA8 `õWNÛ¦4‡³ýCDÿy"Z_Gú·¦¡Ð§Zå`ýiþäËÿÿûSj>Õú­îô_ÏàÒ?‰yBh AðHÌSQú ¼F5瘭Åa7Ö?“T"z–þ÷¬‚&!ö¦sñ¬!΂\7o&^·çoâ|¹i"­À¬5|ƒÐÖ‹è¶æCÃ$ñÓŸú“<ðEg4WÏgµ+µbb´š«gÞŸÎÿPÇïÚ›6ø·G>kuT8ì,濊!ð×þyñÿœõàÿs-@Lfº'D¡“¡ÐíÇø'qF‡H6ÂZ <Åá{¹þw@A²‚€vÝŠF·& “—ñn>-Ðèâz\…#p AsÎÚ=Ã9Ÿ¬òw¡ü}Xˆ–Wh"ÙÑô_è(׿éí?Âôï LÿV´Lí§ÙzQt÷gÙДֆþ0†Mš¾ÿXºk!ý Ï[«Ñòõï)žÿ^§‘‡N-Úü~Ì¡EÿÁ´ +]â<ÙV×ß] •wvÿ13ÿ †yNOºŠCžŸ]iÄåR”V¨Ò>5˸ž•WH¼º1jþ@òUýâ×ÿU:zdâºï–âæõÉ•. $­ ýÀ)Š®j6qV»Ûñ,ÉSB(â8ð  „à)VàyT­³vb·<Š#d¾lú`)TE +8r,AÉ{Šo²sQœl? ‘<“ƒ¡†(’Õ\>Ž¦Ð™ZÍÓ[N ¿{¸¢,“¨`“ŨÃ"ƒÈ!XZ`AÂ1R¹1 š ±4…ÄŽ$@ÑyåÀ£OI²6Ú9†ÛYvJù7¹ ÉùBK+ô £™Iè¢bIrƒ#€@Ô¯O¬ +1$@ÅI‘”¦ +Ýk¬äHÄ”†.Ö aòãIÇÈb”e€ÑX +„ü– ¬)Åð,!t- óP­ ƒ”2¤*ËÄä§9Úp ÏŸAÄÇÊÄ' …ñ®½ñ'$(ÚG 4"h‰ðB0'ôGcñJ!ì…³h ¡¥ JsL¼r¢ˆ,)¡­Àdx'-J;%(–EáE^zDîPü.Þµ¥«k°°º¼“¤0Ò° Rºè= ŽÁÈ“MHY²€cS -HŠ”Îɹ…H°„NËÇcÛ=|€Ýƒ© +2ÄÉÚûÏ=Éà2’øA©"“Ç€àšYÒA3†xšÞdé¥ùî+fHÒh† ŒjTŒéi,êIu¥+z"¨hM‡+6(`ad F=³Á6ªHÒSð="q’3Å0 z@ 3äNEùÅÓšql¤ ‚Hõ¡d4Yô€DI.ƒ•I²7„´€É’ÒáYРŢÛy¼$‹Àd†¶¥±N +0:V ÊõÖT»¯Å 4 a@æà<0â€Íiàrlù€¥âPÁ ™Ñ•×h{”ªŒðÒöð* ä4Œ®Þ±4§lÅ3·±ŸÆv\ “A+£>(¤ŒpÁ4G¢4v@ÃI&IÀi]B’ _óG*ONØ”P«Ã0°Z6‚ÖFP(F ( M˜0È|V‚ Â(Ä¢2y‘‰D™èÒmÅ‚È +I‡_¨¿‰h²U”Ô†F¥Q"p`ÿ#ó&Kc¨(ÝÊ F#ÝW©g jŒœØ¯*°Tˆ4&NŠ”r +ðA¡ !Á„•ŽAà Ï4öàoP0rÐQ+ An‡7Y•¥ŠŸÈF³€%E¡bÕ{,ºÅ‘e$ëFêð « R˨R‚0mÁ,^ÐÚ@*ˆdÀN¥1 ÜNi4`i®dãLÈ‚Iƒ§°U@p !$勺¤AUÃÄ!d… Êj0'Q-Vþà÷Ö†BsÑSK0̓N{&ÈfhdÙΈ9xÅÀ8˜Œ ¡–P  —d@3ñX…°4.jä‹ vT´# [ÑÁ¨°¦w0Díhrm)®4.a ë6¤ •‘ ƒ 0Ƀõ † ¶^`F ð H6DJÂT3X!¨Pl@]Ën·QjÜ'ÓâiÀ3–¸²±‚ +-Љ€ülÌÔ$ƒnofe±ÙRÈ —Épx¨Ð;¬-he±´{£Ñ·øÀ"=€D Œ [Ã<% l+„ +¼+ÉQL gžâqq>:VðB#vD·œb<\žE‹²›ÕµŽégEk¸ª¬cl+LPÓ,Œt/^8t«*‡”3èl’YÜf3³>íK36B:‡lc­P0pIì@`—Iá6™GR°N<à"È»!”EI®6L„Õ‡±¯ëÝŦw½­æ ®+7´”…Én=r¡K¤ $„f@ºd {N ¿`Î$˜˜¼4dï!µÂDéj_Z÷ +yš+iX˜Âhlym„ù:§Ç¿|gRœJÓÏeU7WuTþnâ{ÔJõYyÞéº&¾\7”?Þ} þj<ÞDY÷AjhØQv:ꊓ³*üìMÙZêÒ8»DÑ Î"‘Z®¿Úwo™ö»uÛ¡êÊÎ[¿ã½+JS2Ý‘1 °S÷Qb˃7†™ eyðè*1è„°²~8ðØððÙA'!—.„Ÿ†À4!l$€æ ….DÂ8)É•ßþ·qБ›BZ-$ÛCàq ¡è_#‡:d¢á!/ÝB»@ÛøŒ¶„ 6~ÅzA5AÖÔ“õ°8,QÔŠSØèDù‹j)xÆàMÒ°Â-!t¨˜!N:íy† +|JÑ fûŸÊO@?‘ +•uhkpâÀDžv‹@u,§tÏé?„3hœÛ Òå˜,š¿µæ‹ E†£²ío +!Œ_, N”ë³iéû_BÕd:Í`i4í A›@Ó¦é) ÷ûl&]0if’@35qÍ”&&ªl~J¢ø9RÈýH1‡ŠA«=Mq†™•þ¯ÂñB!ü›y±€Úþ5Íìñåtü*‰†­ñl$"cøÐ<¥þ'ø¦† +þZãùßbåEï_úþHòÅhÐùßã[[Úp¾íédòµ7Ά‰µßýè/!Ì¥¤KéK4»ñwŒÉÝ©ÿEæ¶ÿ˜ƒÓûÝÔôNì5}ŸX•³ãùƒ³ë‹ë3¦OqÓô/1OZ ,%åɳ(OêÐDÿ5èâ£>ÏsÝò/ct`iZ›®æ1ª ÿV(ÿÄ8Æâ²Õsìƒ~<[wœ5EhŠÖ>].â6LÐ ÚPYk4XhŸ-fÓMg²àžµº;q¶1¾«?c6GåL×õÇRD(w_-§gÕÖb)ΈÚâ9’<ÛLàl°˜ŽZKñ¬*à6õœö&JNà7•Û9ᬵ‰±uðöu6ßzí,Ê*4nJB×[<ìö×Z©Il·¡YÈÊÞ6–gD)š-ç­ÉbÖZëüý ºg ]œ +g³ÖLœÃÛñj$+kbÊ +ô¬Ñp2í §«%ÀÇ»¦jã·­ÌÅ…8ÿM«Š@«uáà–#0¨í6¸ «>Ôv)N`êx Ë3eÈU>Ü +M½$.ú[ºÄ8RÀÙP?¡ú¤¼ZÎ`â>ÚžÒ«3¾bkò±j}ˆg•él‹¼]SU­jâ躵„ž [qžK-TñUƒ¶Åi§5B³WµV¶¨#ï +Þ¡p’jÖ@àÍñÒ´«Ýõ©ˆóÅLÄ[>Y Áf]iä’;ásmó LAcŠm¦¶e•M„È»É`©`%ƒVÈ*®î³a‚ÜYm5›‰,Îp¢ÜÚÊ›á=¶5£ðOîé6!çž4ÍŒ¦Ó¹<J&AmËë)PÔtr­´ŽÈQë¤8%A‹o‡kØ/AyÖêÈìÇ(ÀšaCÝ®ZˆGÏŠâoâHgÄYoË]Àÿ£ÁD<[à:öq‘L ã¹Ìj4ÚpÁúl x«#cXEÿ­ÉrpÃi-¶œ¸5}Í¢7â%ˆ¤ƒHÃî”g†KQE –iuDùÜmÞ•Ö\:}{QIeÐ 7TâpáÞ³:zHÕqzÜ»•ù´7‰ñ÷ƒóýª'¨?b4\Ä% +‘xˆÚ»ÛĪ.ß:ýݱò{#ýï¥là <+x¥’Õm+3æ𸥠+>cܸ1ÿ„Ÿ,–­Ig3UKñ cB6.[Ûmº YŠdöH"%qS)j©%R”uhÔ3^Je×Ìú`5)Õ&­,÷HD"_6çvß—¦¿Áë&pFaØ(5oýËD' ñ‰ã~Öí`}úÓ9Æô¦íÖÏÝfK€v Þ l‘Lïf5– –¤ŒÏQÓâ¶©,»TMqŸÉ>X¢ªgÿ†Å³èôâ.2êÓÙY½¿·Ïr“®øoøy–­h‚ÜZR£†ìšl‘H’Z´ +Ú¼öIhŸÐ +!ABÇ|¹‘ ½8ãv7Ñ_àE±"=r¦§¹£`èû#¦Ž1õß1süˆ™ãGüŸ¦œÐñ³ +ýõgÅ?+ö¿K]:i0‡F¬è\%0ÓÿžMçKäµàï°Œ,¤õ*£ÖDÄç÷`› iØCÞVi{¾ãYô9Rê‡ô96­É`ч©+Õº¡#'aÑÌ›oÌÛ.ž¤ ”9!½ ƒõ²E²±U&ù‘lû؈YÔÄÎtÒUBFùãGàÔ§ +irù¤¼GÕ3?Šíü5ƒ åЂÊ<®­Ú@Û™)X%Ud *,Ïf¶‰¶L7>ìÖžAå ¦VZÆÕÎRsrœJvŽ£ þß —éü¬Ý) ^£¡vFƒÙYgŠö¾ÿ}6?@úÈÁGˆ t}ëfÑãk;E}¦VRÖ6ÕF +e7×HlÒãÎjK°È$ÓJ%…Á XoM$Cñr-±ÈÍëìh +¸¬Š³ÕHáu©vnƒÍácñZ2—ãC)‰WÜò?"³ÈÂgAÿþߨ4þ­¤ž/Ïîîr©3¥´ *O/Ó(…ÓÍÀ–]c·«¿I÷Ë¥t–:‹çÎ’h½“ëõ®jÖ[éù£81rùãÈå—üÃ@ foÔOKWjr¤g±Û÷¶ÓÀLõ|`Š)Ç: QS…PÔhAíôð¢èM8›LeÎ?L0¡tO½ˆˆ4Á5äº +Q2¹4<)ÈlHì0do©õž…VvÁ›íY5V5–QéFåݶàìc< tæÓMÔÕµk˜ì4ÿœ¶—è,K-ï4l#¦žöz¹"|g8ŠÅöl?sÃ’¢PÀäPÏsÅYz›¶è&t£qwÅB¯r¯ÒÄ$—[$#ÅŽÛ­ùâPÃYëCLzÓ}Ð;ón`:ÿü¶§3Ôæ2Û^ñ`ÜlÑ™:;B[`_#"v{êLû–5Z”±ÂàÅÅý=½90›O´@íkØ^ïôîí²+.%Íp”Ñd¦s¤[:Ûª–³Ù<€7«ö5Ícywaï„[‹ö`9ní#;ÔÝV¶¥*ù½Á¨D7¡ ÍÎ…9fDÃQì½²†œ2n͇ Ä)#°þöBTªŒžr +f¿MHI¯ÑÀÉ¡{£;$¬z“e ;šÍ{S…¶@…‰û-  $Åø‰ +¤€kÍ tÏ^⓲ÌESjoŠ4d.éÓ¹yWÙÂô )Ó1ÇXRgZÉ|È2:Ä„ ¤u–¸rÅX7—~ºìo‰\OÏCSDÖŠ¨Âþþ:ãß·…j to.Dg­±~*@ KÔ‹Òî0¥²²‹¤l3ïÎjix€¸ñ­Édª˜äî:àV›HÃbŸÝ!µ\M:‡Ú¨¥¥þÿ=¡%åü ¥ÈÎ…¾Ë¸g–Е‚ûôÆ-¦³îêP‹ÎôP‹ÅN¢†F ZchÒú¶jÛouŹx ÇÙÁÛãZÏQ3u¬ Õk6Ÿk3sp^Ó¦ ×6£"‰@ ä†R~Ħ£Á>»Z lˆ–:`(]´ûõFfµdOëÍûŒSÉzVžª½®¥ê~µSÓŽ’)jÖye(Äß|y¦H^úND¡i[9hÂþßdÌÍѾíÏÁŸ/D4Œù¦‹á`NËd¸O²74í±¸!(Låu¸™—>ÎóÓvœt%Æ Ãˆ–"®¤Ê¹“":Û`*ºsGJÂÛ›v'}UD£&ú +§î|¥†% éh`Òg& åG“Œœx“Ú~³Î…9S$1í ñZ,–ôJ¨äMËc4J§‚åká"Ó²Ï#‰Z¯d+Ò7Ëüž°8˜ëj,\Ž-…A¦ôò_~\õ3ŽlqöÇX,î÷”ÅâqZ-WÞ +Ýò¡bºü‡üE©Øü6GÂ/çsôg=ν~Œàû-ü°òÙDLÌJ#rôQƒP¬ñúå†_œNügú½“Ë£?/🠚¿¸B–¥Æõ§NýÙÁÆù[z¿¸¬¨óË8_ùìÁoîú³`²Î@E¶=¨•µšµohøÍwƒ>O'‹zý‰‡Jªþüâ'ñÛLRœ¡?ïПþô{ôË…~iÁ!” úí9þSšccCc¹A&Ù{üÁ>±³~º]'¬™ËÔ* ‹W:ôWâõ¯…=“Nx(À·ë5Ý>?§zÎk{ª°¢ß0Ö0>i诀7n³ô©TŽ.Q©óç0ñÞ «üá˜Ïc,›|°uÿã•¶øÁþ8êݬÉ/àÿã¼Ðh ïzë%ô Ÿ¤‡Š·çsÀŽÍŠpímâ‡èsxž‡©: oð|8Ø4¶†Ñ•›ð&W•Ìa¢IÜÖ®xúå&@fOÕxµ{åH¤ƒ6Èøøzó¦¢ÃHÚ1}ðd/ì{bîúb_ƒ„‚¢änˈÞPÏ +tïøxú±Ê\fre–-tÉAä:ìM—ŠdìëªÃyÓÅÌ KŸ¯:üæ ot9çÖXšäÃñš/6I>ºhD)qqÅ¥Ÿz™D,|ó9 z^†?“wšñ”.r‹ërºMøVñ£­ëùéMø…ÛçT®›sBw‰QlD'F!{›ã‚‹Ÿwr¤w(¼"F±Þævq¯­,}o"Mõ²qrî÷Æ’Îvœ÷¬©žÿ…N%J¥¨va×+ú&æ?,67é·ØÀ޶X»×ŸKêžâ'-–«üÔº^0·çÕjqß<|YV¢-B†¹¶„ï,o–‹N-“%â¸ç,Ñh¾l¹jD>,± éµ$ž”%ùlkZÒŽù¹%SùŠY®í³K®<³Y +þUÜRlÙ›–›+¯ÛRq°9Ëm;>°Ôr%ÆrG<ÜY«O«åaêK[žš‘>óòpÇYÞnG/–÷zÈgi7ª5K÷avnéu£EKÚZZ†âÚ2?~Y¦å@ÖòÕ¹ÿ²,}ÔµÕ’k­¬¶Y¢du$l««ÿpgõ&¯«a·¥Ö…•&Kcc }†óVþÆé²^„'/Ö¨³uiÍ¿¬É~µfͼkî57²_®ËÖr·ÄX«£Û‰õnÙ¨[ èè%>²Z›5KÓÚèÞE޲î ƒ±möjUø³tÞ±6km~ns0W}›{о·ùk쵤y[ÈA{mü¸µ°]¾_ôl±êç“-u“/Û®kDÆV¼Fl•—[ÆVÿŒøm6·Óö*̬¶V¥5·‰µ±í“*|Û¤šìÛŽøÇ¹µ|Õ;wú’çÞ·lÿœ¸(|ž‡,wãsá¥ùu-Ì,çÉé<¿¦ãþó’÷>t^õ-"ç÷pöü%بœ·Â¶çó^©Ð?¾/Vç³e6`·\¬"Æîx¸)Ú½+狼iMìì2îµ_Þ8¢öѫٳýÛ¾½Tˆ¸í5.³?Z—ö·ÑðËÞý°öÏæ{Å>ëuÆK·Å8œÃî­#àÏ g½p„+ä³#6ˆ»Œ#Ë6 +ŽÒÃpâ¨;|ÇÓm¶íhÆñ!†ž“Ô}À±ò»ïŽÅ½ßéƒN¦ñp^Ü^¼8…)ãÌ•k]gå%z弸fηU¿äì±^縘k:—ÃØ’†ÎhÄâ +ô„+°aWä“_ºÒ™‹W d¤«>©9\//­Ž«›Ÿ]£Áº–‰‚ÕíLˆw0é­¸¹b1ê¾z[ÜÙ¯ÔÂ] »î‡|òÞý>µ܃hqøÇžúòzŽg›‡}M}y®®™¡çš>=·ŽiËó8ß<`T¾x†ƒ×gÏrÚ|öºÝ¯^ŠŸ6½×Ö¶7õNô¼7¾ÔÈ{_z˜{[Ö…ÝûYâÞ¥µÊŸ«iKø¨LîÆwéŸ>ûÒ‹ÌÀWî,l¾Ç× +íë¼Ói߸=¼÷['õ¡ßozý\Ø÷Ço¾îý…Qoêo„^hÿûË}É? TûþÕÇð&žKÖÑbý(4\÷Fñò<Ð*Ü]FùÉ(hÍÓ—AµÚò][(˜\]¿Ëá%|ºË¿CÁ¯Ê[›p¹â—}gW¡V†È/+6¢ñ‘º'Ú·tˆ˜`Òžs IÞ¸ƒd¤æî“¹Q"ï¦E¶É䔜\W”ýk§¨ˆÓKE§éUH¾=Rž@–o€£¾Š6'íNÕ&4˸ßédèýŽ®p‰<ý*œÇèÏâÏXïË€a‚ˤ—‰\r&ÿèµ2žó%#>ž/˜}¾y‡žeH¸ç¬¡l2iÝËîPÇÿA„¾|ŽõxW,O¾_³™D°ÆÖ«µ&Û¹Fì—ðèàï¼X¶ˆûKÂe ]Æ’ŸƒËJ¿“»lñ/î˯ÞÓ{Äõ˜ŒD=]wä¦ÕïDšóBd–ÑQ_¶0FRí×èMÁ“‹6ŸJˆ¢³ÁÌqå÷'‡WÑ›ùëUyV¬\µ2¾ÔÕ|ÖbÁr6‹s´3VsÙ-±îx8‹[Þ^‡qºõ<ˆ§»ñûû^üÓÙê'œ—ÃÏ„p»' +3bžxKdm‰Ù¼ã0ÉÀ‡NÆ©b4Y[.óÉ^;ÛH?¬º)®|³HåË@êõ¾OÍÞKµtФ¼Ç¾{±ÄÓÏø1ã¼ÿ\d.‚}!s#ï2íòr‘µ„Ý‘lÈÏ¿esî&ûj_^÷üš +ÉëTe>¼~è§£×cÏè#ç«¢¹¸Ûý™»{î$sŸBvžw¯¨›|T´yóµzÿ5ßoˆÑ‚«ü¼(DžÞpPžƒeÑÅÏ‹‘&…Nþ+ÖœqO±ßxþ,¹IK£$’¥úÝ€*}&.,7^î£gÓÏ7÷!ÛÍÍøò%U”2åÔA•Ÿ­+_ù+=tV¨~ËVÉ]½¬*ÍåÛòÖòÚ[Ýò™©õ¶,¸ìæ¶çeÝUW°BT¯èO®ÚàƒWÕñÍ]¾wµl°Ú®½•ݳºÅúâ­óõ«Ëz%ì*×?–½ö§Ó°Ý%ž á»§Zìön^¿6Bo²QêGKž#ýyïNÔsÿèÝÝ?ñvëý¼M?°×¯Ÿe¯ëâácXꓽ…ç¹@¼=wßÚÑw¤cyIÚO//íYôÕòp˜×‹›pûõî¶V|ÖGÜÓbmoeËSïmÀyîš»»t3ç"¹fç¡ï}w3¹Õ{rBßßž—Öy®ýÒºŠ5î[O±J­µÊUnÛÕJ¥Ýè6*í¹§]íð7Ë€éÔäsgZȵº¬ïã³{Û!æÝqãÙ-2y"$V"O q”¼¨öèë¯N¯|ÿ°ê {1úƒ¦èÜG¹æh~ SKŸ¾\ô+Áq£?ÎçæÅ}1¸½ ?&7Ed˜~²•Nî³öâÎ>r‘¡àu‡Tœ.>g­Ñeú–=®Hql}GDZËÚxüFeò§KpNÒNòeÒ ‘© ,§ùkú~ÚoG/gQ¶Í*µæûlêµäÌÿ }ÝçZÖ¹…ˆóXàµ1oz¸ìÂmï ›L#Ï6… kw˜ +Ѫ֪ª¬!ÜK0R´8>ß·iµi]?ÐA‡ ÓÃH(¿‡›×÷fmšVZbN•/dØ´>Œ•#Þ‡ŠMɲ‚*Òé$[3©zy iz:"=ÖÝ¥cx $¾–ŸHVU¦@v¿+C–†S)M'Ó>‘7d&4µ,Ý3,G’xc‹Ñ uãý[¡‚wK3(ê_ÓùP! „Ö7°×—Áþn~ï[Á(°\­#„»â ÕM”V +ÝÉ<0‘n§%Ê{å4£»1¥\Py)sh+<Þžþv`вJ¿- ¶yôŠh¹úCs•ñÇopn5ĶâXÊ’½Q%T퟉¢U;ÃÑ•Ç3‚ɬõï‘J•é zƒí®Ðq\e^¼«Q¶.ðÞìgSRLk;4ǘ’?ËeB Ç;ói»µ,¶~·æÌqH’µÉþ‰j8dg¦G­ðŽØ6!…Ö­s“h­(2Aú¥øq "ž +dÁ:*ç•wªŽ[”Ä¡­`%ùR®Ašù:öAÖÓž¦e†˜v÷cÚ“¡Hˆ{­¹¾—™ZxJ³îû<°Ëñ®q]™ø¼×ih²®8ÝÆ ·–"®sž´£… 5¢!,Ú ¸÷Tн†ª”qˆt½â€ð‘ᥤù’[oÔ̶/sUv<{/ï#΋փ/O;ÊþDlž÷ÃK>cñ¹œÉA+°8gï®Ó¬-»ËFKÌU¸øâ,Åæ«—IS%ÞN2Œ ©ÏÔ‡8]¼<±Kßl[¨ €‰]-óM«ü2ñq}[Œ]2b-9ˆD;©@Àù±«Ø}€\*csOÙeêó5Á<ù}ññ´¸ˆçj˾7ÊÚV™s~Ÿø9ïLªGäÛº½sBkÜ>¿ÄëÉ@ê²]ø5v9̼ÆÂ‹ÀØ›òÙWW¶Û0_™wÏ©Þë=‡vñ½D™ìsO¤ +#ïŽT‡,~Å.¯œ÷RG0èEòíãm +¿9¾ÐN %áç?Ïã5¿m" â¡Õ]áÓåí¤;¡[W²Ï4/.ãvÚáMÜøÞÑà]&)®<ÑFÞÖ¿ètZCôÛÀ›îûh’¶¸ùàü=ͽxýà&†h[s þÃÍ\®»¼O¤öI_ú]êz¤r@Á„7Mû¨ÔÕGdÝÑ}äò¢ûyó†Ws;b诜mÀ@«D~;„Wy¤+RE­D? Y©&F7Ú5fØ'ö³¯§>½©^°ð•nµœç ¶}w{yjFãõ~g¯œwJñ:E#ˆs¯6ø¨û”~x¿Zm±$¯ŠZ߆roü(0¿Þ,Úã4Õ«¥»¥ÐoËíÚ.î¥UB=˜t“ô6ÌC>›ÏûwL¸t…W‰ æ,¬ ÇçML…7-6ÕSW¢~ƒ*iqQW(èï¬\™ÔˆLùP~d‰ÔQ”mOcõ¥5^Ï/W»ØÔ¬¦õ›Õ˜[Ð3”ÑÁ|q-ªVUA̸3w²ÏVŸÒmâÒ“çs!V"Û‘HÙ¢£˜7ó$¦¹Kÿ{±l!Ê}r­µV•¯} ñò[¢”Iöò +`pfý¯7 +“LŒ$‡(ÀžmZB.Va±¬ní—™æ²î‰]‹7Ýx¸Þè6ÿ¹ÂÆPX +Z7JÙ4ò$£´²Wἑ84…ë›ÐýlènqOÅLœžç±— ž’»†Ÿæ .í÷õ˜Táê‹Q‚I4ÅxuR»‹×–¹qÚ[ ºÔoG™˜`Ÿm|Žª[vÏ$¹çúW¼œLT°e³¶ºÆ*Ü€›Š¬3õ\wѹ«Æ¹—|5•Ÿ{Þõ:ˆ‡®_sñÂý-²¡×c»³³‹²8_Û„E6ªü%°u-û]‹ý~696®êãî^ÅBªw»¨•g0©Ó_Iɧ)ëó~oÉÐU0JoI&T49Ɉ—3©ÏûfrðÉ/zcû˜¾Ð}ç¸jwŠFç—ͦµ…[½Ê]!‚^÷ö¿åx°žmà šúð»¯$·tô ¸²3Ù÷>&ƒƒh$¼^/5ªT®Ê¨?‘½e$Ó”ëP¹ÆKPiŠ2%Ú_Ó¨b$F>‡#*‘»Ì•ërê‹tsF¶cw΀"¨F…FÖ‹Þªò¯ßµBxDd^b4 çÚ¿•ÕÚPЧ2ÓžÝÛ¦õ +{3ÉÆ´*¹Ÿ“ Š;RmF¬dcÅH ‚θ+£‹L*ôDy£¯žÝ.MDýlœ(6û¥hm¢l~• +T»~\ì°ÕYuÖš™$×ÑD Aÿìk:H.b”:Å`_|{G(]¬G—MEÖâô>BšŸJŒËQ¤ÖTæÈ “(¯è'@wu‘özØžB…ÉÔ‡Š=·}ñ±ðý×à¢wÝþˆ…2Ê®$ù-¹øBÅ¡‘¿ô=²×¸s…>_7%\àÎ/;°†O)qV.bƒµzF¥ +õ’U†Ï5FÅ:h¾«ót“˜¼¦zõ +§}ÓÒ*ŠÅŸÓÊÈ­±¢ÖÑÌû¤«`åÁ›F¼^Œ!~ü»Ã¿tÅæ~a¯Tƒ¯áÁ߃U¿÷ µQX=’~ŠnŠ0[^î2Í‹~P •Š~a¥?,¨öE”_ õZÅùöì#@^7|ëg°ÌÈN«Ÿù3®©àÖ¼#ÛÅ%÷±U¹hÐ7þÄhLô€h†Ol4\~Œ]Ìrwrëvxm )ÇßN=†­p“p·ÛþÚmòäO“3“Ùa¼žj‘‰oã Ê÷5ˆ…Ë·#¼hJa³CKxw#ÒyxæI•âÕzìk—@l‹ä RZÄÂ{‹½b²É›dãjk6²}Ã]:Ï©\§ZI0÷ÔrgõßlP&ÄmÆ•¿* +×/™åÚ@^/dÈ­À^Îã½Ô‡í•á³@Œ¤GîJ2Qo=qŠhïùÒ}no""¿L·ƒO3µY.¯;Îk™¦ÍQƒz_ÒoŸË[î¢4»L·Tæ.yéçx½î°¨Hæ*·í·¸j­i£(‰äÍŸ/TrmË$ã¯`;Ær(:˜Iùê¡m˜Q¯0Œ§ëqN¨~Ì{b ÓL†M^h!_ÊíŸøê[³ ü´zãj»ŒÎÐ6Qb4!:}ˆ‰¡s™O0Ö»ëÈ ã45×µý§êÅxÁ`†¹pOÒS%²±)Òy\ÉœLÛÀƒxä>Â$o¹É¸+Ëxá‘ì* F +7ÝTw,øT;06ýòðC–Æ’Hž¾÷C +–Ýî}Hâ×{3ýLõ„ü(Õö ìBñ}~™‰&VCÕ "´!¾I_R…ÂeP²á¨Ûš?“&{®L8^µnVõÞŠ d#™x4ÁÚg¡T®5²ïˆ¢QÅ Øy­"ÁHrVèÒpÒ¥oUyÌĈe~ÒÎX<>üÜ;ô‘@ÑïÀW¼¢_ÚãrK(WçÞ6Û_1»f o‡‹Œ+7Ž ý—[&U)Õ2öræ^üˆÑ‰'Ffʵu¿ÉvÞŒs5[2ÿ]Ç.ý·>ÔÊ‘EAæh•¦w™Í6Œ3®Ä]Úµh¿"™BjñE,|Ox€ƒýÆ`jÅåîÕuû ù.r¬ ñi¿ìQºVûXSÿÖ)ÜËÛ¸ý3ÞA@ëE¥ZµìKÖž}åh†+Eãe1ó +$;Çö ÞêÄ64+¥åþ¥‚x£¬ošñ¸},XGŒ<ØïY^ˆB§±ÞÇcówʹ*cWTæÂg•ýü]JSªòY·—q²‚r¥1ÉÞ¾ØÐ‹Q¼Öžõ$‡’b­‰±•ÿTP±ëÙ×–=e}ƒÁÜÓ—-îâ¶\‰×VwÔ®‚ ÍS¹ñ`z,1†!ŽØÌ{É.[åð% +t%KÝ¢MÍ7†/Lƒt{zí?Юî¸M·ÞsÖÄØëPèì-¥)l’«›Xî"@Ó›‚wæŠL¯ yíùs`E.üæ­¡%¯vmh÷„#iŧs*÷…`œÏ.–( ½\ë!¶p?XS…üëWJ¼|³Ê‹&yï ¨íÞ $ÉK ·Ë³Ÿ£o𾮯3Íå«?sŠuõŽ‹ùe-l6~C´uÌßç /›}âë/év=~Ÿú9I¶bùµUÜ’ÈZ/K/Ê~@[™ÉþóåW&^‰ÍÂ¥ÅjªŽ&²ì)TSdk˜ò ‚î’N‹é§^.½ iâ&5àýZéªÖ¦<û9‹%˜„´ÊW¿fR«8ÞÞ¼3ÄéOe&ñhÔº;1¼¸ô¯ÍM— ìj«zWN‘$ãºÓ[k"äΠ<›t7œúPˆÎuƒºmé5úîâÕiñ~¹‡JÇ¡9á¼,¦}¯ |Kå.Æhã—BZôË“OµÄ*°]ô:ûØœ½c¹e#ìohYŒ€8÷glìüöú + ¢+Ø…¯Ó6¤Jݺ–ˆª.Ù»J7,{çËØIx×·U_*oéÊ9Hg$Ûøêű†ÈØ‹\XÓù¶1¢´Œãéc’êM_½8Фø^Kþ¢Êõì*0{‹žÜ¼L(¥À™î¬¬o|ùš® ´/‘iúaíl¶ÕÓS*WwôžüègœhW zÛÁŒÍƧ_‹ J)§^6ÕÖ·, +ÂùV£$£@ålß‚m\Ê8³öÌõxë7uHå½¶ôhyžî´}]œ–pO]­­´úMdÈ]ªbä¯\ìâÍ¿Š×“\<Ó.8âA+>‹ytR/´+~»x½Kp“\L½~¼R(.PÅ‚›Þ@tTºÀˆƒK˜³ÊJMãó/äT§€Å!4vμ˜t[çÂÇý{NÌNÉåÕ»¥½žÎWŠ8÷O°ÊY’\†±œ»v…[í$­.HËOÛge\B³Ð­EÛ¹…g²=i”ãÅI/ê®”WÕÉõIRn::x*µÓX­ìB‘#üŒ“áh± t7mÎíÉM†gÅÁbipdO­õ›XZ–ƒÙHŒkŽþQ4£ˆ½5zÊK5gàÌZ“íQ¤„!¢ûÓ]¶ƹtΠ3jU}üÒúŠŸF¯¾önÖÚ©·÷(ñUJ]î»Kè¿xaÑ¡EŠF›cèwz†ù¯–Ó‚8מRoRõÍ1í”ü0=\«Æ¨DºCP]x¶…Sùèé<­‹ã™â8-Mwª{·o€_:ƒ…>”‡-Òò5tzv]çbm<€/Ë“Jk{¤r®è’4)3|Ë+»lvDYNh¦'Ýíå# 2ðS’l&ÄÁAÙ¼üõ8ãWùH?× ½sÞ«F;H½%?OKýF1—·azûâvû~qA_Õ— pþ³Ãk[5ÒÁýݾ¥¼‘*Û·¸éëˆÅt"ï¬á¥Å}ó$X|ý¼{ï,ÞU¸fñ•R?Q¢ˆ`äÑ…áƒôtß2 jQ‚Ñ¥† Qߣt‚§y°zÆO8‘o Ëo‰ë¦ˆœÿù<iÇ}³›|¬ ,¢üõå} 3}béùË‘zÊ<Ö3‘x¤CzâÜ„–Å;û¦ˆ|¥š$®ßCAêÝr]&}Î~C9ÆWE¿%à³—¸„´Ô0*\Ÿj†°°¼:S”3jMiš‚ >K]Ù®ßàÏìˆè:S”óùÅ¢1ñ"ÈÔ$$ü¹՛~ù¬ýŽÝº\ð%9Aƒ)˘ž¿&=±]äWÞhÖâ1‡¡2Ójmbõ !íµÙ¯É€UP#ï¡/όЅúÆ>UŒ ^ÛFíà“ û±2àKËóÂÖx¬èC½8£áäs^ª÷¢Ã\@ !Ós~Å”ô§Ë<>ÂSÒ…jÍtÙs®ê¾ÑƒJdê÷)*Z%`Öf¯Ôâq#¨ïDÖöt§5ë9síÀƒT´6/Ÿ-v ¸âtj––¾XŽº*Pf;­^ÚÇù+•¿APÝ»ëxf"¥¤ 2hu‡ Þ.3†PC£²uiµ5sØzP |œé°'KcÀZ¨‹ø+mõš™>?Nõ¡^Z] 'ç˜c¨RÄD x¾z'ín×Õó«TïåEÕh®¬Íöµzâô baÃ<>™ÂeEÉÖÌX°37©[=¨Df:ÈBu”ÊbCE©AÚé2"‘½µ=é/íÍ=a5€ÊÍ4PÎlsƒáG¿K† +`0àÐ×°V•¦›~fTPŸ¢D1'Ъgg®×Ã/ŽI\1zP‰â¸'b¨Xtªc¨|)ýÖ6‚úF”Gåš>Ô‚ó©Lç¨ \+ÑœÞt1Ôb–)0PŸ¢ž«¹  ®–µbö£;ݱB­‹7Á¾ÔÑxsF5P pQp6\–›+]¨÷þ†Ãê}Üua3‚: ž|¤ô§{“?-KêkÛZ2„: œy T FürE¼½Å}¨e¯uæi¯ õ~pBµ>¾y‚’’Ö™î¥Å2Ÿg*Cջä.=8oÑ"y>O{7ж2Ö¼µPB®gü–îäüòÛ]µæF¦#ÃÏA;æ†o‰ôe×·y[›è›bìúyÓ ±#ï‹ÕzsÏÛî{ÇømÉ2úI@¯s0~[^ ?ßÖ‚ ¿ÝEQë§Ɵ׫ӲáÛùÒGm´\öQOB7Mƒ-ÇäÊøíýyå|Ï[öÅ¥@šNƒë~ÊøíSèÙküöuè*ËouöæbŒ?ûx ß‚¾FõÞnF2 ËøóH wgü6!0ŒñÛ›(=݇4²ü¾0|v̦M÷‡7Ú¼mÎw‘f9/E‡›m­ ´PDj¬~;ÓøhHâT·ŽªcãFEgîËȪÒd-ˆZÕÄú·÷üÕÖy¸ŽÔSC2™æïS61_K]ykuÞoq¬à·l%\:“™‡—LWöï ›S¡Ön²-8ˆ´Ý°–Ö4ø«ªJέ”3RñK6òƒsÚh'tžc9‹ü G•,ñ'øÊ+¤V‘õ.õ ‚€“†P±d•EQ`ä +½Ê€UP_ ¡‚Õ;£¡"?HMÐjÀÈúØ@ÍŽ”P/-n%T¦v®Äp%D) v› 9È=ئUPC}äŒô¡2îWc¨ÖL+ ¶ÓÔ€±o`\Fð Þ  >6 ¡¢ÙX³ç¬át±o`Ì04ZFP«2Ôµ9¨BòM¡a j‚:Go}Ûßük+Ê î€AS:I˜è’x÷„ãûÛmD'6ÂdÑBNŒôÑn Ë‰$‡p¢Bö!I9¯ˆB ­E}i)žÿ/ýHú=É­[‹NÙ¼EϪ2W^Cnobº¸‘¿¥P€!AkdÀ¿«ÀŸ»ä¬<’¼† QÅ1Û4©Å”‘*€D>d·Ë?¢3W·¾¶¦q/ª´‡¡Æ¾¤VªH t"ØSvôöEG/”sxN‘­sçõ‡”"4„MÛ×?|¥©Þ°TcÊ,öŽÉFúîHúñ¼ñÖñ™õØÊ +Ä_¹Ò…ýˆ_ÿh=¤dß[3C¤oÐ$éó‹BQž¤þ ÑCkè´ê­!&Õ2"F½Wú<:3DvíQk¸ ¦è-#!~ŠcðeLh6âbx¨7S4?%Ó¯‹¬ê1 G_¤A½ijì7ç§á ¢— l úøÒH¡ôKÔ£–BiY +m¥ÀG®È£o®ÂávÄ*b¨’±¶‹¾4rºsŠÏµÃi®œ êK¾-út÷$ö|KS¯«DA_Žë²§ÀÓ™œßª7¹]ö<0¹«ðmiÏä$^r;0/É#шÎGßlËlûæ•-8Ö$ Cóé—”_3%•"0=%äñ)É}Ë*rw Õ¾Ù%ö·4Ñ#­ÇãFƒYq¯£jÝp­‰'R +nf/E€ô{K< y3`Ý€1îMÀ-kÖ«fÀŒÖ 0â>D°M­ö3`p` ûðµ<Ä+*ÚØ4 µi=¼ªviUqóÉìÈCympƒ!.ï‚;ckÓn]ºmYK”á4ƒý©7"›f +¤íYɆT-Köu¦’BkZWAûn–ô$>3úFÂÖŠ44%ÕjmÈ/÷k*‹ŒÃðßVzj +ѱ«öUY­ÔÞÅ—G©ˆ7{kºÃ­FÚ3¶Ž©1!CÏX{–«[Qp@™à5Üoèö퇂ý›k¨Ùô’ðÕðŸŒ"’$¹¸?ï-¸`(ÊqDoÄI‘FžiÔI‘FÿikM½&7ß®wûqMt­ô~§E"èC–3•xèê +=[×P¦-¯,¦­o}öü¸V;ì?bÏåÕù‘î4ÞÙÕ§´ÄÃÒþ¡á84Ã1°Óö#ˆ[Í;“ŽDÕx6Í͆äú·o”óÞ÷üy9Ÿ&zW…o3ï=ñÈì°s¬4øŒëÀýY͘4jíà°6cJî/i²©„=73JKˆV‹Ó$ÞꈣÊÀNi-õòmÃv¦PU۟ǦE•Ñ;*qS+ÿݬ%޹zÀÚD³Søª:”å%ÍÐDÅʾ">³3\G R;®#¯“^¡fcÅ4âºöóÍ1õ{F&µ.Ñî¦öBç9m•αq·´FÎjú˜ÔKªÅìßV +…›ar&ª™LÀ•bbTvw ‘`“py°ìîP¤ÙL€•Ýý8²õè›í÷ÌãÆx·b¿—¢KÐ)ãL>:Á˳1nU–E+sÈu7%(2ÏX/˜bÎ9Æc2[ôªÐFu¯mêkŸíd*Ц09_{2 ÌÚÔqŒ"ð/Kè!??ózÐÊoe<íÈz4sÌp…¬)TŸ®ðM9‹×f(¨¿Aì2Q#§Î§ÔfÞQêˆÆd3“¼|š54ʼ×F=÷q` QÔó×ÞŠ|ÓŒÚÍî¯ÉY[Gô¶ÿ ƒ®tó¡Qoûj8f`HÅœi{+vŽFÚž”o M#ÝŽ›¦&^¼Œ~IĪòÄÃÛq&¥>-£Šbñ„6d{ƒ>Õíi:ÐÛ[[^éž{¢ì£ò@âduâáë\³½úmðz¿?¸ÝŠØx½Öî…‡Œ:ÐIKس܆åi*|ð*mv +¨e±§†]mèèsª´3!cÄ”“·o›HS°wXßmh|\#ö<Èñ“¦Îžég›—êÔÞý¦q­Ñ!ãCAÐJ ê©ÐŽe¹µÓ®\icœöº´k¹Di§Åû9¼¯Ù¿1DÕÒëü ªä +¶M‚ÿ è`_ôf2bzXÇEo¶cRˆ×Ã:*z³gL;'ÀüU¦¢7Fn”:zCŸ à:z“?*zók{¨¶ní™õ§Žq^éx|£@H¹dÁa2Êa¢@èÅúq¶ËðLÍŒºi æøñ˜,‰Íž´Ù7N“ +»Â`NÅ ½Tè£Mu„óo:Û*SivßÏùõ¢aÆo¹¸RGÇÔe©5ÜÑOäÀ½˜ˆÙ˜3ü¥ÞŒ6p ÌØÐvêœwŒ*ÍŠÌì_š• ‹d_¾NS$KZùb¾H–´j]Ë_?(’%­ŒYGõ×¾"Ù–U4Qõ³ß„¸?U‘ìý©ŠdïOU${’"Ù{½ƒ®•N¡‰J:õ¢iºV¥@èä/í–’høQç kTv·_£™Ní=mQÞz6×jíTEy¿¾qÚõ7Šò~mï÷ÔííTEyR¬ó°—ÿâ<}ßóäEyºá‡Óå­µ§Úh<\”gÎb”OH–Måúwú=²—œ~¯Nµ:\­öÍ#át×z;Ñ}¨ŒÈxË&àÌíF™Ë(}àÀAF†g +v£P5ä5xœ®@cR…&Éâ˜tW™Ñ=zºT½^„õÕÈÔâÃâŸÜ6-¾Æ[ÚâÓo^H£{à“è·G‹¯ÿYG?bo'·øRÕ$úîηKêÐŒxý[sn•ÌÁM}Ñ‚´Ï•ü«ª’b¬TXÐ/€»´:ö]¡ðk2ˆUpÞKêãÖ*k³ÝÍFÏFewOûŠýÖÌç¾b¿ÞMͪƒÌ7;FP»¿ÔÅ~Ú¢°DMUSvg닲„ÔÖ¡E¿ÎÇÛ¹îû1îGC¨€äˆq±‘ˆ¨Ò=…Õ1õfT··ØoÁCÍúÞ2Ô_»÷Š.®otOa`Ô¢Ó*â›Å]Ôb8]KìÕ_W-­(làãßÖ‹áN>udží$)°iú¶OvÉÚ¾ÞÒåƒíBý5õÉg£Â§—¸ÆJÝì¹vOg̬Œo‹ÒËïýµsœÚ¸ÕÙezNºç`W…+c6ªBžŠ3£å÷ï@Ã&ò1]ÆÅEjëøpF×)®×Ó3Œ•»Q'º^/ªs·Þ·Ãv)ó™˜òlÐMqC§L'wðÀ]x'»YÏ0[[6ÕM×/^¼Ofw†ºùÐè»ý·+˜SP»'ýmÄ›ÈØ4Í7o‘ÑÉ ÞnÉmÌÁöi‡ˆâÕ?Ùìöéy [Çãt…}zñ1U<í4…}z¡êmÌé +ûô²Jv2!^اWÕ§â›ÓöîþIaŸNW¤"áòT…}zU}2!¿Sا·Ï³wŸ²°OÏ»ÖhÏSö)𵕩º»¸?+ìÓ«ê3¬Xù~aŸì{«ÎO;uaŸÞ ++â§*ìÓ«êÛÝŠøqaŸ^UŸ$lNZا·†ßœ´°ïu¢Â>½®Œ7‹¿]ا×Õ¯Ã70[Øw:¤4BÚ÷ +ûŒvâÂ>½ª¾_¦+½LöéÉÈuê”…}zU}Z%}‚¾=+§,ìÓ+ASº¸'*ì;tœî‰ +ûôVI6nOVØgÖ÷üaaß¾üöé±»BI*ìS¯Rè¨UÚÚÐêÌMêuѨ}ÄÜ‘gN»QÐùÄr„ì1¬¾Jk‹y™߸ÅOÏ Úkr|ï?#“ãà-~fQå4“r7Ê ª[ºt Ùñè o:¢q`L[¡ “Àä©“®VÆìÖ!«àÀ˜¶Â†eš±©È¼˜6Jù©v™"K­Ë„J»î{š ›ýìò¿ ÒößÿwŒ½®{ùŸi¦#ÍG^þgåÐÜÿ÷ÍL™—}Ìåûò¡åûÿ~P*%]þ÷ó ¤©Ëÿ~ýŸ©ì–Ÿ^þ'gÛ­?Ò½ÿïÇ$ks°  0|ƒ"·Æ1³ck<è«;ÎDA®Ö×ß[+f39÷¾ì‡#júÔfù÷²»aáÅc¯Ð+èÛÙ)üæµ}fªr(+&7•¤&y¨èñˆûÆ•4µšN;ýKº=νâæ4ªU4à¾ãRâ+ãS¦ZAo§JµªŒÍ¦Zí¯1i5ÍÜœyˆÒ’RÍè•NR*%q{~ܯ{:$:Mväûæp”ᇤtÁÆ1•ö†‰c¨«€9Ñi²Ú×½«ê§<Þz3YíòëÿL¼ÔM +6¥2ScS½6]eêª …³¹·„b{Ô´ + <ïß$4,Ì64ð~³0ôÝYLçQ÷fê^“—;.†Æ)³¦/oÒëüýBÌ#lŒ=é£w§Ø'ƽœâÜÑ‘%º)#¸#ý«Æ¾QBá‰_ìÜ|q¨Šâ?î¦j ¢Àäìc’Ýû÷Ë\½çOïýû¥­Â3ÅAGßû÷mSý¸{ÿŒMõõÕ?e£Æ¦êû*iúeöÁŸ•4ý’/4æÇŸßû§/lLÞúmþÞ?M:Éjß–µjâƒ2íþtÕ¾÷ØøQóÍ÷«}ï÷ûÞ¿ÌÞŽýòõ“£µ6ÑA´ÿë?Aµ/ô¢ü:6£Kêèè¨çnT]êèçÕ¾ÐËþ³íŽ«¾G·oj¯SvÖ 0&k©šó]~„g‡Ã`ë8ô¡Z*gäÙðŽz3…Tµv™< ÞD!Us¾³6ß>=÷vØ»ßÚ‡üæÜT|Û8Ö©F{ßV³á?Æ÷4bGRmÀìÖÏï PºQN*ñðè×ÖÝjÏqþ–Åøk}àéênõŠnŽÇ±u·‰‡áþ]ÅŽÏfmŒënµ© ß:UkUG½-MXl&,›G½¢[½Ý(sš½ sÿèž¾“\†¹-’=EÝ­lÍ£\ÞâB?3ema¢j)‹§pAâ‚ATbX³øšÝºÅS³è·ÊºÎ°Ð Á‡!·VD‘éP9ºM,J.ßú…J/-.ã ñøJP¢T}ùŸó|:Sj>ÕÕt®öyu¨rØÕ5r/û®á{óÿí}iW*ɲè÷½ÿ‹¬¬ÙÑóˆ3 +[Ý*(Â9÷|y¿ýEdÖLUY }ï]ë½îÕ6U$™‘‘‘1fd„ŽJªeõ hT†×ÿëHË÷a)w£n§”ðQ··{ ·£ËŸ8û¥nÂrä"2óô£õcרvŽ"%].¿Ÿ…¥*/Ùõ‹ìgX>`x"`ø™xÅš?ñ¶–þ¨ÎοÏÃFmš`‰ÿ Éd)hºfZëóîl訩›Yõ, Ãy6ª#oüÓÝYð--îÑŸ}²RB­í`˜oý`¶§Ë™ƒÕTŒv½ÁýÛ¼ËÕbôFjmbøy>í¦QöÕÁq€øóqð)²‡ ¾ˆÒÃu’²nŸ#žF +Ï?r_çe£ù~¬˜cÅÊÌ0Qx~ÕH·B•`Æ:~8Ë×ï¨: <à|à2U‹?¬ˆŸ7ÚÁ­ˆ<´Üéq#PÕr>z†±O a²]ÈÙÐ3ô–0:âƒaò#Iø. ñdjû&è˜ÍÄ΂ÏáúøV#Ïn¸ô±.tOOÁ7ÝÈåߌá¹ÝÉ–ˆ®‚u·5 x‚§üÎÄ0l˜\äå;qýiüç$n0ËŸ†¹rqâÄ? öH»Yg¼”ın×õIOÀÍ´îŸÄ®ì3`A>›¸…ÌíÃ÷ÝU}g´ƒCß±˜Msær0-Kº:#yŒÓÿÂææ0¨]üïŽÄqóycv¹á ­í ›!ü1‚¸yvzxEãx7Y¸;û=œã'´%†ïO› *T©s’ž˜JD®dm7LÊÅQÕ½`yØÿy‰‘I‰s1îˆ[Úù!‘ËòªÇÊ- IŠA rùvÎ[ z¢„IÛëêæÐôÖˆ®z>"Ò~Ê& i?D@G™¦Éݦ„´v(·X÷ÄoxoášcHJb\‹—ï›±Sãæ#FoÏSãæ#ÚüñRGôC›’høC>¢}$~¼”ĸùˆ˜3AJbÜ|Äį‰R㢔 é±Sãæ#YÒ£¥$Fh‘á!¼è”DœáyÅ(V˜ð—=øgŠúú‡ä±±‹z ¬Xa°ÛnêÅ +žö+dHKoö½öëÔ‹†»í¦Z¬08ceêÅ +Ý'ïÿÁb… ß½êQ`EèÕœŸoµš¸àatµÃÉOÛ™£2ñnµú¹àá·ZMRðЙÜ4nµ +-xíBÒ¡Ç-x]í0È™2VÁÃh÷ZH„}ô‚‡ÑÕct¬ƒ‘‘ÕÝ‘ÂqüÀvÁÉʦq&2a&”M)*¬Ú¡}DqÒ‚‡£ø:'(xè]ø¸%)F.x8ÆaØq +%GÆ8m7jÁà z:£%Ÿ£§MXð0NzÜ +ZidÁÕ‡bã<ƒÒÆ)x”9•Œ|oÁÃè^?×)œ´è¯]§p£Óò ×„£ÏÑ%‚¯Í½àa´-pº{¼‚‡Á[Ûªvè¶&*xMW@r²‚‡ÑG¼½>›è”‹È‚‡#¥ÇM+åÂ_í0\ë±àáD\ ~ÁÃȬ͜5ÌÄEß7℉&,x8BÂÉS.ÚCÕý‘ FW;4¹Àä£} +#˜JÁÃ0šçÕ½GFÆßçѱë`ž6FÁÑŽ%Œ_ðÐ}d{¸Ú¡o˜ñ ŽeâŽ^ð0¼ÜŒ1ÄZ¼‚‡î2—¼‰Vüc<ñ q F›Ý³™°à¡F˜Þâ1qãú²ƒ +F+?ü\ç +FW;œÜ;h<œB.nœ‚‡±rq'/xhõœ<Ú‰®€‚‡ñRõƒ½êc<ŒNÕçîî)< æfµÃPž6jÁÃèj‡î@þD£­ûµ½àatµÃI|^¤ÅÍ&÷íJ¯·JË¥³ÛF:5ßÑäÔ⩦²Ý“£]:ÙË-¿/•s¥ÕË#8ûý²H¶ö?%R5¶ÖIõö¶F¶óƒcR×Êפ~}õDö²ß9Y^TÈÉýZ™œý}l‘óÅÎ 9¯‹_äüswŽ\¬=n’Ûƒ·ßä¶/\’ûB‡ßî¯ëlÉ6>ºõïßw¹Íüü š®í쀙úqS½Ï\ÿ†ÝÝPP ™CfvùÃl›V%åæ‹&_Vj‹ö'V’¢T¼£ïK Õ²<¤xóæcEðQ°YÌm_Öœiíü³\ymER,ÉéêÝCˆg8™:hô›ëËõT¿Ë¹æ¯çžì/ +î/î´¶ý…3à-Hžç kÀÑA W æßIq{5ë¼³qÙl¿]É»¾hÎUV­/vÌÕÌúnrˆ¯ °Ó¿øâXdÒÚY +×±ÞšÝÇ=’ðºÊpž…mÔ.3âAn¨#Ýè°zÐä ˆ÷ãåÙqLx›ÙŒ |b£^°G}°†yL«W…Íbseaé¹³xV]Ù’ÿ:bÂääÛ—Gn/“åjrB@Ýe§2.Yt±4³iõ—Ù…aô#Cß®®/¶O7wZf¶-ÌëR´Hæ”:«O3ï÷³[Oo_4iÊöÔ›0Lß0íñ €(Ê^µ<ž­@><\ñ±¾“O×"—ûÅÇ;Z2v(¬×cS²>µdÖ‡¹¾oǬËSÌàñ²hþöíšXŸîD7 <‚ŠV/™½µ$×w)éžoχ½¯ys6o*“%ç÷OXRì_ +ö¨O&½ô-®§áSS´>µ¨ÓXÆ1̰ÿW¶Tu7DJÿ¼šÍ”–µóÂÌ^õaoÞ`Ò[Z¸ÿÖÈîvNõºUÍMyIf]Ê„W{lV·­/¹cã1™hfÿ* \s˜è`‰]£PKå3k§LtέC/p&Ê×mµ‘f6ÏFší=‹|šMš_xT´¦Õ¡ŒøJ#Û»ï[ЬÏž·ÿ¶sœC×2<ÿúÏâfîÔàO£+`ç‹tq=uËVùgžY÷ ‚¯ì_/ûwX¼æ—rLOÛÚ ñ@ƒÝÿí#üî †Ñ€±”´Œ½ª·æV(­æ\ïš3; $KFÚiÔßÊï3ªÃbùl~ƒê§×*o-7[ß^Ê ìáòi@_ºÈ¹}–ÖqåÆÄ¸z·}' ÷ LtˆÛŸKxÛø~‘õ Ã`çm¡õÍx«ÃëµÆÃ +Áá7ØlG 8¥êg]VGL'Ì­žlµHk¾³ Jà“÷öT W~såž5¦•ÓGÙãèb¯ñN‰=«‡yƒÇÃ/—Ú¶pEw].{—Zm`Ñáã>–(?óÜ}aV.—‡î>”nÕ߇´síôqÂû°°¤ðÅà´Q½_¤™²FŠí4¬×3ÁÛHPë4_7¿²æë·™R‹b ß–GY‹KpÖƒ‡%1ç¹ì¢ÉôIVªœ)æì‹LzíúsGÃʧ͢åËÇö¥#·ŽÇ.Ö@Pg†*v[u”Ù"\¦ºÅ-~GC¯Ü0s +÷:ö'7° äm€H<æŽÐµ6Há¨)ŽMùûzQ•ÂQ/¹î8|ÏsB–AŽ˜xX—\x˜_I=Xx‹œ+W¸ß#aóûÄsóЉfyp}`ãáÒ‹‡|($HëGé´‰„æÚ Kß ¦}ãàÁ\–ñ€ç¿Í-PÎü¶‘P»fþžùˆÁÜ7œ1.DP‘}°+SG¡È„·x½X±á7EX˜k¿v×È[Ë-=ù¡èñW$í^is¤Ù}DvÚ½"î>â`Âi¡áY[zëX}d}Kšv0DÂ} P(2ú&µÍ“Gû&žŽ·]†iæõ>§e›|·Ã”æ4“ÒÜ xlJc¾¨‘ðRÚ„{?íÆÄ¸”æFF#íÀ¢4÷Þ¥Vwþ‰¸÷í06J‹BƘ+â ?5ô32¢úðqã ˜X‹ì#dïÇYÞ.‡…´ñH+ă°ÉH ¬תŽ5gIa˜1'ÆÄ0¹€Ž5µ¸ysdA¿}7¹e}Õ-¤ã"#ëÐf\ †Xg6T4ÅÂM›c²Î¬Ã-F’KnÖ™Kž¡@ÐrCÜq=Þö—vÝ<-+Í-U~; ÀP«×íÇ·ÇœG~ìÚzôºìsf Î~´#ìÖºXJ×\Ørlì‘Æ"`’¹ÇÒ傦ß/©Â®q•*è…+Ü7¹'¡–ÊdòÌVE»¼eyѹɽ¿uÕï?Å k²Í;ºÖt?Œæ‡Ý Ë<·£úaGw¢_`d?ìèNXFУúaGwÂÂ0c:MGršçlFóÃŽî„…aF÷ÃŽî„5ÝÝ£ùaGwÂ:³Á;º–+P#úaGwÂr.àñâ½ï„R1¼ÈuÙ Ù ‹ívMD^¾å,–u÷N¡ø:s¸ÀwI ßÒ–æŽSd®æÁVXÇÇ¥œX›û[â\ËæLð‹sÂYF¢1Q`§TÑYxÅÙX9¬:v°à¶}ÀkÁúâwš9cÅ<é<Øì‰³N1_™´ßåÍwg¢À8Cšåæ¤å«³5‹‰Õ QcÄø·èbŽÛå/ˆáù™YÛËS¿ÙÀw¢-:4ÛÕ‚IÐs}·ëE«ó}Â!ª©õ Ê}îOïæ ¦ësãÿ”¿t‘jIö§xñk9ñ«¸±#ŠgV·Úk·OÛÿÕßì> >Ú~r)YÜ8©ììèÊfû©Ûj'yj°ò ÙL¤`Ò­Iéî·ü2ª|åÍ?Æö[möxµ¹ù‡4J~§ýâçé:ík¦”ÇûޝSyZ=I¥kßy|lp·›fs.U·+-Á÷)¼µ§Šµõ•ݰ$?$0L80©¶ŠÑ‚c ¬¤æÛâo„í«Ÿóþî3Ö‚„û¶EæÏ*©ó•ÁæUµ}¹9ÛlUn·/ÕýJkf½Ø_Ù]/~·–«ÆìÛáÖźt·|Uï”¶ßÏ/o6jjêz9ÿ²öfúƒsoÚ"W‚w1ìuÙfo£‡\éð^ÞÒ(X ù¬¨074ìRë“È­ZÆ™Ù0ŠÆUp3( ¬æy´¢|y݃NJ`ý²Z´ÃÄ­),¾ÜÛ[+P·0c ãÄx]_|Vží/|›1Ëö!ãz}–¶wü~ÞýųlëxûcçÀ£Ö gеBU²v0îȵc|<Êz5 Ççâ÷Èä$OsÚ’)ò{]öx*¬¢ ü¨ÈâAâÓÚbîÈì÷éèŒõ+¹4ŠÚ}ÏÔ3¹À‘vZp ßµõe›ìËïÂsvãðéO}ó÷NêÄ!Kb]1\ñ2ÏyïqØ2ÍÔª+æ!¦©uyT_uv¦Ò?œkoß^éÏ=̽n]µ‘óŸŠÓÛÁݺÉqw’­wÈ®©o®i6½\ðHÝ<ª †Q´¨ÿ‚pïû-Vñ»-±vÁÎ;uñ“d’y[ËxæÊìòþ‰­þ•­“_û“è!ú@ï^-ˆ®$¨›os–FñW±fseÚ$3§ú~2¿•72°¿Éù\ÎuTØäÇvmc>5öÇ<†gžÜ)/8£J ™Äë-üi\`äV´?Qw»½gßÉ8È,ˆŽªçÊfNÏT«[{纥Ê|(¤ý¸¤"¡ +ÒÜÊÊ*PW?›1Ïn–ÁhËm%ìü6+Þæ«­i‹K ]*o]”¿Îuf7s†"¯XLôs ¾ØÛÝ4à‹Õµª1wܪÜîÎÖJ_suK©e18îQ0×m÷Ãä_1ßâÍ™]æRÍYMο¾DsÚe–ÙêŠVÖÉu›ìÆê§ŸužÈ¬s<>ûe©Fëv•9ÞŒ JMþ¼g)‹Ú +·Qÿœ-]´üs·~@øòÛb«Í°Øç®\Ûy^-nî®t ¨5UG1½EZ<þ[˜Ûq4ŒJ-‹Ûõn®s ¸¬çœà¯£ÞÄÐm`˜õÆ:"è=ß»à>íȈq(Û…ºÃ ˜;šùQ¾â_'FÚ3JÑ 1±wóòþæ‘®íå†C¾k'®vnò‚'a“…®Jg÷٭Ј-¾›ù’­•§ƒ#¿#™õ1ðôQ[¨9G)™^ÏÉ«ôù}Š)Xý| ½,%Á~W´ßÁÚäOÐÖH÷l•ôû+Ÿ¿Ã½äwÞ?¬ÒxÁÔ´6ÝO)Û_í‰#6Âãˆü6ûxqÄ ²ã˜ÏOšu!áº'=ZHX=AåLåªugáAðÂx¿l<ܹƒ©Ì?g"áÊÇTfwF㡹²ïàAº~uWPùçÀOÞw!FP9ŠÖNPy¬àº•ÀÍùCTÚƒN:uåˆÉ ÷™@˜á¤£ãf±±XqÖÆßÇã÷„yøÎ:Ø‘‘Ø+rxó9:i'<7,•ïC¶G\l¶¿ƒm íéžHvÎÕÇZå«ë飛úˆ@lÚ‰¥ÃÞŒÕGãÃéƒÔöOî±767\«ï­ÞBù…SÚIgrJk÷Gêc¸ƒ÷Ôä”vÞ™œÒÝI1tðØ êgãAÆUÔD^ÆÅ¦‹ÒÞ“­Hã>|ß2•#N_“ÁÄZ£ˆÐø+Òx Üû]¹—¡y›¾CÚDéù÷HÐ1¹@ƒ™É€¸š!¤é÷ÓGjñüåÄÝÇãcl‘à9¾àé£ýõ2~âÅEW>Öoß³ÎÇNÿÇU”K_þ¬CG‘çã å~|šñ<.ÌZçjk܇Žf¬a3oú:+£Óö2•ÿú¬§ò{—\;„¹œThìM‹dµ!»C& 4gœÈ_õþÞev-wÉÉ'¬Ï%nœs—&F!ðçv¢È-îvó>m~úÛfáÒŒuŽ`Ã#nO˜UÃ˨¦Õ~¶Ô·¬öâÇïTµ3ÏÑjôº²HJ'>xë -ìÝ6ø¨SW|t + ,¡Ó»[eZ ,¡S×0ÓÊ6 +œÂ0SL` œb´wz ,¡S&o¦–À8õf¶LšÀ8MüšfKhà†‰À2Aà4Án“ŽN1pй a±Ó)N]z(v:ÅÀiÂÌ@f<¿æ!)ädŒ¾þr?e­Py˜Æé܉ը90Å5ǰèýV§å‰ÂëyxuÒî>Yå¾Ü~~íÔ›ÿi÷¿Ä$ÿ—À¿øW3’"Õ“TQàAÁ·u@LšµNŠ™d½“øE’èæ¾/nôú›¯Oý×n§ÙûOr‰½»Ü«Ÿíl&—’ü7÷ð›åd #÷оʰ˜ì½”,·›ïÉt³×ßi™/q÷lüsùo„oã?à&|ñ|Ú…OáÝ¿“"Iî%¯oI²•€/¿¨J’‘j‚aý£hbòºSeXÿšâkeÈÉwh¤(‚¨J²,"É¢ìo¤IIQÖ~d•b"è’ª( +4 г· U¡‰(º¥äŒånEXGªëg:tôîoElÍP„É©I7ÐT#z²@ÜJä$ÌÞûšj²ÊÀ Šá€F¨èiFTìá ªnORUtêmF5ª+Iª)®YJºVjPY“}M`e†'0¹[ØÑßý­X_®•Pu˜¶j @ð“tL0Dùi0}Öé4?Ú­äs¯ÙzŃª”a“§z6A†d¨@É4]Q ª¶Òafª&ÂÜ5ÝÐeÕµÙðoù † ɺ¢KU4 ÑM”eø!U¯8w*E$¢!)DU x#É‚¢¨¢h€––˜¸¬•O@M¢RÑÐ4]V4À‹Kت¤h%U4üdA¡ì +‘@+ IŠ5XAUeÍP±ø•")’@%B%Å "‘’å§ÿÆ©•§75I"‚ÓRÌ24í'²ªëª +k«ªlj •Ë¡œðÇéýnï£ùžIÏ:¯xZå¤ß{í<K|]Z:n?õ›ç÷öÒR¥Ûë´{§ÿù„ÏÔä”éÇïîû ßþñ×ÇÝA§_ø~?ÆØ’úw` ø›ît^û¯Í÷£A³Õkvúfcbóyoë üŸÙÆ»ñD1ä'¯­þKðOhÈOjí×ç ]4º®Àžn÷VçÉb¹Û hõÞ}zû÷ëw{$ I2"¹œp¥­D7DÙ2(ƒñØÛàÛùñ83­½<]5°8ᬃ×ãÍZ +D™òIw¦5ø2oWýWû䥉ß6{Ío«{O'Ác¸~[kvZïíÞ>H¯þ­9‹Q +™lP£"0màƒ ú“DP5C4@ƒ1 ˺ÌÞø¤ž¢‹6à pTà¼ÀXAXƒµÔ·&ÈdÃ.Õ!L]óhkF º¦y”5¤®yT!Ð"ä}mX/ +Tؼz‘!©~åEg@ ëEÃ*›æVØ4Ió©l NQ ÑØ<°hljŽneHÑå mHòjl°¾É¡Åž4öÞÅ T؆gXaó¬ 5ü+Š Æ .¢ÿ¿pþÎa?ù_,œæΡƒþÃÂY UEþ· g`ÿg%ÚYÂ<$Ä4(ñ_”°*X5ºbS5UD9\•ª`„gûÞ€„SGã^jº¨´©·A N1ÀRÒTèœjØF6"K”P`Ù2˜cC4•ʺHuQ§  5Ò)g¨ ð,‰|4MA© ”J†´!¤®Q4 0낺RAf’´,ƒ9¢&°@Ôª`«Ëh‚*ª8(nu•M~¨(ìWBD]TôàVšb &Š‘ÁíÏ¡Vš`N@ºS€P&ÌlÆ*õ &† bŒP”lÃÐôUÝTR±š†fAtƒ€hûܾ<<­¡&•Ä/èÔwIÕAÑ€5•Z!%(ê„c@+ lt…h@I²¦U1DQeP+]Àr' É`†öe ŠTFß‚$ÈŒ@kR PÀ‚WZàq¸‘DY5tYBR$Ð9‡Ú$1öZ%B‘£·w;ñ+;@7Ôfâ¥Èþ$XeX ذ  ’5 +T, Î¡Þ¬ƒ–4*‹ÀÚ®€VuÔ® AF·ÑI&H +è_l5¸€4UT×uEÓÂZièiªh¨DÕÁ -è0¡J’¢é`1Àhvƒ Jh¶°ÂvtP+I4Ô +lÆ’ZQ𠪞ªÜV„¨P¡l!+@—@Ñð{09 ™»6ùwÔ `:¬!ü§êIXuTq4e Z-G1µ¬"‰\W¶š@&°(:Ã$ +(: ª€0­4W“æé¦D% U€_©°ó«„r,ƒ•†´§¡Ý Ì,P¯nP¾bèSÀ¨…Í+*¼/èIUÆ8)ša( x Q9 bö– +6Â[i‚ +«J«š°$Qn®I‘EdÙÖêÞDþJQ"@_v˜Œ& fÊ[ÿ–`_R Ø%…õ©„%ĬƒÌèRY@!k,é-& V•1X ^JœQ؉ˆ"ÀŠÐS\fìSMÄz,Ü×#׈XÛìYدôwúmGx6,¬¡‹È½E´¤I€dÀèbEk¬]À ˆ ÀÞ€ù-â…ÿ²á 4 +º+,£+ºa©à{9àö™Ät E.jg@2Eã’ÂæÛßt€˜#Ó4P tÔ[EÄžE¯îV(ÏU\"4 ‰[~]“`­5cJ[€¦À$ªˆ¬R;°CóAƒº‰*šÅ2Š2hò +h–ˆ*ð(Š;]ÂàˆRàñDG“Å/à‚÷€ß*DJÂö £Áˆ’7½Ô©ÃWˆnè@؈Ýg2Bvšl,l» ÌUU׿(9¾ÝJJ6­ö¿Ê䦜<ê4'Ø$è TV±"ðËoè€Ê£¸ù`<àw2L‘·—@®¸eayÙö‘ä_ܰV2·ß`oÁºQàÿ¢=Asq72L 6Û)¸Aƒå’‘«bPØŠFP¸ÐO© 9èë_Ðð*˜N¤¬Ä9- +0 +ØõFRÒy”³rµæ \MÆ Zέ‘þ0Èd Ûƒ–¸Sªqx¬fjÓÀ¨€ÏKöÁ¨Iž Ã÷‹!ÇZ¤(•$Î.k ™+k¨ *¬€xI…. X9AeÞ!ÀÒ¸ÆXµ(Ø0:a>hEnQÁF€†ð5œÃmêœæ³ršC@“‘8ð†µ¡ÐFÔA›U`“ñVÀY1<¨ÂteÐoMÑ„ÒIBéÁDÒ€aX+ƒ&(¢.[”jÒ8ç¿èÍ’dI“BZÞ Àâ 7= •¤”0mK°>D¦K®ånà[/ÜàÃmTßrhèÍ /(2ÐªŽ +0/6 +ÒlI‡”ˆM’|Ån=غÕÝpÚºÒ +aDËôTàÀVÊÑÃDHüö™r/#™Î$//¿êeóÌÀV§ÅâùÌØœ?l>·O{Í×w>stream +H‰\RAN1 ¼çþÀzãĉãkKÅ ¡ŠÜW@ÛJ¥ÿ—°“–ªÛÛ3vv~ÞÂü´°yØB8ª@©Á1RÍÝvFlYÜ£Kvu[»Éãì`´¬nÖà©ÝÞ›XÓ{{K³Üá¬ÃéÍ»w­¹Ûqëv 7o ‡ð +'S??¾Dø¼X­bæVšÀDQPˆ¹ªþ~ee$Îj¤¨LBJ°Ãæ æ—C„Ëvo°{£#øòãë½ÓÏ[#_.@ý—åô£çl@ôÉA¦¨P9f'pü&"db˜ì¢ú"Ìa6‘‹ n±¯ÀVf¸Z¡T±*CÖ´Ç KbH‚¥’]eCÒâaÆ(Rè¾3¶P¿–Ü×=øoô‡PPCV—MµÞ6¢ãÄŠµu"ëYKýƒ$llÓ$BMuˆ)Ò~¦žM× ÈŒ™¦jÓä[DÙŠØ^ú;dðæ)¹šKø°—Ù=Ù7¼ß šÏŽ% +endstream endobj 121 0 obj <> endobj 134 0 obj <> endobj 135 0 obj <> endobj 116 0 obj <>stream +H‰TRËNÄ0 ¼û+üñÆqžW +â´B+|@\ +Ò²ÿ/á<ÈU©Ç“L2Óôô²áé¼Y|xÜ®`‘]îô×Ï;¼á7œ¶W‹õ†¶?x«J=+õyƒ+r'™Öú­ýS¢Ö [OYZcÚ’De@ŽXa û„ÎöåK×Í”Që4¸CÖ¹4ÌÆ¥iP·¨Àï­ŽóÆòá¿Â\€›å‘åž!z +9d›(‰÷‡8âɉ‘&69‘Èp(ø€&eò%™È”´*ãÔŠjL,ÿT>Ré©îŒ#kÑᤫtJŽD"çÓêY(ZÆ1•"÷¶¨1iŸfûü{¦ìôZæÞ³ÕÛ‰”lYD;ÝRP ™Jní³Ï‹§¹F¾”yµËËÁŽœzšêã-=õ·¼À¯ÇC‚Ù +endstream endobj 75 0 obj <>stream +8;Ue`+:,,;!BU6A*^5P$`CJL0b<,tCo2+7qT24*8Du^GW!2*pm[K~> +endstream endobj 76 0 obj [/Indexed/DeviceRGB 255 77 0 R] endobj 77 0 obj <>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> +endstream endobj 5 0 obj <> endobj 27 0 obj <> endobj 48 0 obj <> endobj 69 0 obj <> endobj 90 0 obj <> endobj 102 0 obj [/View/Design] endobj 103 0 obj <>>> endobj 78 0 obj [/View/Design] endobj 79 0 obj <>>> endobj 57 0 obj [/View/Design] endobj 58 0 obj <>>> endobj 36 0 obj [/View/Design] endobj 37 0 obj <>>> endobj 15 0 obj [/View/Design] endobj 16 0 obj <>>> endobj 114 0 obj [113 0 R] endobj 136 0 obj <> endobj xref +0 137 +0000000004 65535 f +0000000016 00000 n +0000000218 00000 n +0000042000 00000 n +0000000006 00000 f +0000364731 00000 n +0000000008 00000 f +0000042066 00000 n +0000000009 00000 f +0000000010 00000 f +0000000011 00000 f +0000000012 00000 f +0000000013 00000 f +0000000014 00000 f +0000000017 00000 f +0000365553 00000 n +0000365584 00000 n +0000000018 00000 f +0000000019 00000 f +0000000020 00000 f +0000000021 00000 f +0000000022 00000 f +0000000023 00000 f +0000000024 00000 f +0000000025 00000 f +0000000026 00000 f +0000000028 00000 f +0000364801 00000 n +0000000029 00000 f +0000000030 00000 f +0000000031 00000 f +0000000032 00000 f +0000000033 00000 f +0000000034 00000 f +0000000035 00000 f +0000000038 00000 f +0000365437 00000 n +0000365468 00000 n +0000000039 00000 f +0000000040 00000 f +0000000041 00000 f +0000000042 00000 f +0000000043 00000 f +0000000044 00000 f +0000000045 00000 f +0000000046 00000 f +0000000047 00000 f +0000000049 00000 f +0000364872 00000 n +0000000050 00000 f +0000000051 00000 f +0000000052 00000 f +0000000053 00000 f +0000000054 00000 f +0000000055 00000 f +0000000056 00000 f +0000000059 00000 f +0000365321 00000 n +0000365352 00000 n +0000000060 00000 f +0000000061 00000 f +0000000062 00000 f +0000000063 00000 f +0000000064 00000 f +0000000065 00000 f +0000000066 00000 f +0000000067 00000 f +0000000068 00000 f +0000000070 00000 f +0000364943 00000 n +0000000071 00000 f +0000000072 00000 f +0000000073 00000 f +0000000074 00000 f +0000000080 00000 f +0000363974 00000 n +0000364169 00000 n +0000364217 00000 n +0000365205 00000 n +0000365236 00000 n +0000000081 00000 f +0000000082 00000 f +0000000083 00000 f +0000000084 00000 f +0000000085 00000 f +0000000086 00000 f +0000000087 00000 f +0000000088 00000 f +0000000089 00000 f +0000000000 00000 f +0000365014 00000 n +0000000000 00000 f +0000042451 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000365087 00000 n +0000365119 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000043666 00000 n +0000365669 00000 n +0000042848 00000 n +0000363590 00000 n +0000046659 00000 n +0000043972 00000 n +0000043858 00000 n +0000362798 00000 n +0000363240 00000 n +0000043229 00000 n +0000043740 00000 n +0000043772 00000 n +0000044009 00000 n +0000046735 00000 n +0000047005 00000 n +0000048244 00000 n +0000056080 00000 n +0000121670 00000 n +0000187260 00000 n +0000252850 00000 n +0000318440 00000 n +0000363386 00000 n +0000363483 00000 n +0000365696 00000 n +trailer +<]>> +startxref +365881 +%%EOF diff --git a/new.html b/new.html new file mode 100644 index 0000000..4fae6fc --- /dev/null +++ b/new.html @@ -0,0 +1,389 @@ + + + + + RanchiMall Pay + + + + + + + + + + + +

+

+
+ Cancel + OK +
+
+
+ + + +
+

+ + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/old_index.html b/old_index.html new file mode 100644 index 0000000..84cbc1b --- /dev/null +++ b/old_index.html @@ -0,0 +1,14749 @@ + + + + + + + RanchiMall Pay + + + + + + + + +

+
+ Cancel + OK +
+
+ +

Some input required

+ +
+ Cancel + OK +
+
+ +
+ + close + + + +

+

+
+ Back +
+ Next +
+
+ +
+ + Loader + + +

Loading RanchiMall Pay

+ Sign Out +
+ +
+
+

RanchiMall Pay

+

Send & request money
using
UPI on Blockchain

+
+ +
+ + + + +
+

Point your camera towards QR Code.
+ *Only works with RanchiMall Pay. +

+
+ +
+

Show this QR Code to receive money using RanchiMall Pay

+ + Download my QR code + +
+
+
+ + +

+ Send wallet money to any FLO address. +

+
+ + How to send rupee? + +
Step 1
+

Enter receiver's FLO address.

+
Step 2
+

Enter the amount you want to send.

+
Step 3
+

Press Send button.

+
+ + + rupee-symbol + + + + +
+ + +

+ Add balance to your RanchiMall pay wallet. +

+
+ + How to deposit money? + +
Step 1
+

Copy UPI address shown below.

+
Step 2
+

Open any UPI app of your preference and send money to copied UPI address. (Do not close this + browser)

+
Step 3
+

Copy the UPI transaction ID shown after transaction was successful.

+
Step 4
+

Enter the amount you sent to copied address

+
Step 5
+

Then enter the UPI transaction ID you copied when was transaction completed.

+
Step 6
+

Press Deposit button

+
+

Send money to UPI ID below.

+
+

Loading cashier UPI...

+ + Copy + + + +
+ + + rupee-symbol + + + + +
+ + +

+ Transfer wallet balance to your bank account using specified UPI address. +

+
+ + How to withdraw rupee? + +
Step 1
+

Enter amount you want to withdraw

+
Step 2
+

Select UPI address you want to withdraw rupee to. If you haven't added UPI address, add one using + 'Add UPI address' button.

+
Step 3
+

Press Withdraw button

+
+ + + rupee-symbol + + + + +
Withdraw To
+
+ + Add UPI + address +
+ + +

+ Request money from others using their FLO address. +

+
+ + How to request rupee? + +
Step 1
+

Enter amount you want to request

+
Step 2
+

Enter the FLO address of person you want to request rupee from.

+
Step 3
+

Press Request button

+
+ + + rupee-symbol + + + + +
+ + +
+ + What is this? + +

+ Don't have enough wallet balance? Pay to our cashier through UPI and our cashier will complete that + transaction on your behalf. +

+
+
+ + How to pay through cashier? + +
Step 1
+

Copy UPI address shown below.

+
Step 2
+

Open any UPI app of your preference and send money to copied UPI address. (Do not close this + browser)

+
Step 3
+

Enter the amount you sent to copied address

+
Step 4
+

Then enter the FLO address of person you want send rupee to.

+
Step 5
+

Select UPI address that you used when sending money copied UPI address. If you haven't added UPI + address, add one using 'Add UPI address' button.

+
Step 6
+

Press Pay button

+
+

Send money to UPI ID below.

+
+

Loading cashier UPI...

+ + Copy + + + +
+ + + rupee-symbol + + + + + +
+ + + +
+ + + + + success-art + + + + + + + + + + + + + + + + + + + + + +
+
+ + failure + + + + +
+

+

+
+
Transaction ID
+

+ + Copy + + + +
+ Done +
+ + + + + + + + + + + + + + + + + +
+

+

+
+ + + + + remove + + + + +
+
+
FLO ID
+
+

+ + Copy + + + +
+
+
+ + + +

Send rupee

+
+
+ + request + + + + +

Request rupee

+
+
+
+ + + + + + + +
+ +
+ + qr scanner + + + + + + +
+
+ +
+
+
+

Rupee actions

+
+
+ + + +

Send

+
+
+ + deposit + + + + + + +

deposit

+
+
+ + withdraw + + + + + + + +

Withdraw

+
+
+ + request + + + + +

Request

+
+
+ + + + +

pay through cashier

+ +
+
+
+

Contacts

+
+
+
+

S

+

Sairaj Mote

+
+
+
+
+
+

My Balances

+ +
+
+
+
+
?
+

Your wallet balance

+
+
Wallet
+

0

+
+
+
+
?
+

Money that is in-process after deposit.

+
+
In-process
+

0

+
+
+
+
?
+

Your FLO balance. This is required for every transaction.

+
+
FLO
+

0

+
+
+
+
+
+
+

Requests

+ + Deposits + Withdrawals + Pay Through Cashier + Unconfirmed + + + +
+ Load pending +
+
+
+ + + + + Empty icon + + + + + + + + + +

No deposit requests.

+
+
+ +
+ Load pending +
+
+
+ + + + + Empty icon + + + + + + + + + +

No withdraw requests.

+
+
+ +
+ Load pending + +
+
+
+ + + + + Empty icon + + + + + + + + + +

No pay requests.

+
+
+ +
+ Load pending + +
+
+
+ + + + + Empty icon + + + + + + + + + +

No unconfirmed requests.

+
+
+
+
+
+
+

My Balances

+ +
+
+
+
+
?
+

Your wallet balance

+
+
Wallet
+

0

+
+
+
+
?
+

Your FLO balance. This is required for every transaction.

+
+
FLO
+

0

+
+
+
+
+
+

Requests

+ + Pending + Paid + Declined + + + +
+

You don't have any pending requests.

+
+ + +

No paid requests.

+
+ +
+

No declined requests.

+
+
+
+
+
+

Activity

+ Refresh +
+ + Sent + Received + Deposits + Withdrawals + Paid through cashier + System Notifications + + + +
+

You haven't sent any rupee yet.

+
+ +
+

You haven't sent any rupee yet.

+
+ +
+

You haven't deposited rupee yet.

+
+ +
+

You haven't withdrawn rupee yet.

+
+ +
+

You haven't paid through cashier yet.

+
+ +
+

No messages from cashier.

+
+
+
+
+
+

Complaints

+

+
Select Cashier
+ + + Deposit + Withdraw + Pay through cashier + + + +
+

No deposit complaints.

+
+ +
+

No withdraw complaints.

+
+ +
+

No pay through cashier complaints.

+
+
+
+
+

Settings

+
+

My FLO address

+
+

+ + Copy + + + +
+
+ Sign out +

Theme

+
+

Toggle dark theme

+ +
+

Haptic feedback

+
+

Toggle haptic feedback. This will turn vibration feedback on/off.

+ +
+
+

My UPI ID

+
+

Add your UPI addresses for withdrawing money from wallet back to your bank account.

+ + Add UPI address + +
+
+
+
+ + Go to activity page + + +

+
+
+

+ Report +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/components.js b/scripts/components.js new file mode 100644 index 0000000..85d5d80 --- /dev/null +++ b/scripts/components.js @@ -0,0 +1,3079 @@ +/*jshint esversion: 6 */ +const smButton = document.createElement('template') +smButton.innerHTML = ` + +
+ +
`; +customElements.define('sm-button', + class extends HTMLElement { + constructor() { + super(); + this.attachShadow({ + mode: 'open' + }).append(smButton.content.cloneNode(true)); + } + static get observedAttributes() { + return ['disabled']; + } + + get disabled() { + return this.hasAttribute('disabled'); + } + + set disabled(value) { + if (value) { + this.setAttribute('disabled', ''); + } else { + this.removeAttribute('disabled'); + } + } + focusIn() { + this.focus(); + } + + handleKeyDown(e) { + if (!this.hasAttribute('disabled') && (e.key === 'Enter' || e.key === ' ')) { + e.preventDefault(); + this.click(); + } + } + + connectedCallback() { + if (!this.hasAttribute('disabled')) { + this.setAttribute('tabindex', '0'); + } + this.setAttribute('role', 'button'); + this.addEventListener('keydown', this.handleKeyDown); + } + attributeChangedCallback(name) { + if (name === 'disabled') { + if (this.hasAttribute('disabled')) { + this.removeAttribute('tabindex'); + } else { + this.setAttribute('tabindex', '0'); + } + this.setAttribute('aria-disabled', this.hasAttribute('disabled')); + } + } + }) +const smForm = document.createElement('template'); +smForm.innerHTML = ` + +
+ +
+`; + +customElements.define('sm-form', class extends HTMLElement { + constructor() { + super() + this.attachShadow({ + mode: 'open' + }).append(smForm.content.cloneNode(true)) + + this.form = this.shadowRoot.querySelector('form'); + this.formElements + this.requiredElements + this.submitButton + this.resetButton + this.allRequiredValid = false; + + this.debounce = this.debounce.bind(this) + this._checkValidity = this._checkValidity.bind(this) + this.handleKeydown = this.handleKeydown.bind(this) + this.reset = this.reset.bind(this) + this.elementsChanged = this.elementsChanged.bind(this) + } + debounce(callback, wait) { + let timeoutId = null; + return (...args) => { + window.clearTimeout(timeoutId); + timeoutId = window.setTimeout(() => { + callback.apply(null, args); + }, wait); + }; + } + _checkValidity() { + this.allRequiredValid = this.requiredElements.every(elem => elem.isValid) + if (!this.submitButton) return; + if (this.allRequiredValid) { + this.submitButton.disabled = false; + } + else { + this.submitButton.disabled = true; + } + } + handleKeydown(e) { + if (e.key === 'Enter' && !e.target.tagName.includes('TEXTAREA')) { + if (this.allRequiredValid) { + if (this.submitButton) { + this.submitButton.click() + } + this.dispatchEvent(new CustomEvent('submit', { + bubbles: true, + composed: true, + })) + } + else { + this.requiredElements.find(elem => !elem.isValid).vibrate() + } + } + } + reset() { + this.formElements.forEach(elem => elem.reset()) + } + elementsChanged() { + this.formElements = [...this.querySelectorAll('sm-input, sm-textarea, sm-checkbox, tags-input, file-input, sm-switch, sm-radio')] + this.requiredElements = this.formElements.filter(elem => elem.hasAttribute('required')); + this.submitButton = this.querySelector('[variant="primary"], [type="submit"]'); + this.resetButton = this.querySelector('[type="reset"]'); + if (this.resetButton) { + this.resetButton.addEventListener('click', this.reset); + } + this._checkValidity() + } + connectedCallback() { + const slot = this.shadowRoot.querySelector('slot') + slot.addEventListener('slotchange', this.elementsChanged) + this.addEventListener('input', this.debounce(this._checkValidity, 100)); + this.addEventListener('keydown', this.debounce(this.handleKeydown, 100)); + } + disconnectedCallback() { + this.removeEventListener('input', this.debounce(this._checkValidity, 100)); + this.removeEventListener('keydown', this.debounce(this.handleKeydown, 100)); + } +}) + +const smInput = document.createElement('template') +smInput.innerHTML = ` + +
+ + +
+`; +customElements.define('sm-input', + class extends HTMLElement { + + constructor() { + super(); + this.attachShadow({ + mode: 'open' + }).append(smInput.content.cloneNode(true)); + + this.inputParent = this.shadowRoot.querySelector('.input'); + this.input = this.shadowRoot.querySelector('input'); + this.clearBtn = this.shadowRoot.querySelector('.clear'); + this.label = this.shadowRoot.querySelector('.label'); + this.feedbackText = this.shadowRoot.querySelector('.feedback-text'); + this.outerContainer = this.shadowRoot.querySelector('.outer-container'); + this._helperText = ''; + this._errorText = ''; + this.isRequired = false; + this.validationFunction = undefined; + this.reflectedAttributes = ['value', 'required', 'disabled', 'type', 'inputmode', 'readonly', 'min', 'max', 'pattern', 'minlength', 'maxlength', 'step']; + + this.reset = this.reset.bind(this); + this.clear = this.clear.bind(this); + this.focusIn = this.focusIn.bind(this); + this.focusOut = this.focusOut.bind(this); + this.fireEvent = this.fireEvent.bind(this); + this.checkInput = this.checkInput.bind(this); + this.vibrate = this.vibrate.bind(this); + } + + static get observedAttributes() { + return ['value', 'placeholder', 'required', 'disabled', 'type', 'inputmode', 'readonly', 'min', 'max', 'pattern', 'minlength', 'maxlength', 'step', 'helper-text', 'error-text', 'hiderequired']; + } + + get value() { + return this.input.value; + } + + set value(val) { + this.input.value = val; + this.checkInput(); + this.fireEvent(); + } + + get placeholder() { + return this.getAttribute('placeholder'); + } + + set placeholder(val) { + this.setAttribute('placeholder', val); + } + + get type() { + return this.getAttribute('type'); + } + + set type(val) { + this.setAttribute('type', val); + } + + get validity() { + return this.input.validity; + } + + get disabled() { + return this.hasAttribute('disabled'); + } + set disabled(value) { + if (value) + this.inputParent.classList.add('disabled'); + else + this.inputParent.classList.remove('disabled'); + } + get readOnly() { + return this.hasAttribute('readonly'); + } + set readOnly(value) { + if (value) { + this.setAttribute('readonly', ''); + } else { + this.removeAttribute('readonly'); + } + } + set customValidation(val) { + this.validationFunction = val; + } + set errorText(val) { + this._errorText = val; + } + set helperText(val) { + this._helperText = val; + } + get isValid() { + if (this.input.value !== '') { + const _isValid = this.input.checkValidity(); + let _customValid = true; + if (this.validationFunction) { + _customValid = Boolean(this.validationFunction(this.input.value)); + } + if (_isValid && _customValid) { + this.feedbackText.classList.remove('error'); + this.feedbackText.classList.add('success'); + this.feedbackText.textContent = ''; + } else { + if (this._errorText) { + this.feedbackText.classList.add('error'); + this.feedbackText.classList.remove('success'); + this.feedbackText.innerHTML = ` + + ${this._errorText} + `; + } + } + return (_isValid && _customValid); + } + } + reset() { + this.value = ''; + } + clear() { + this.value = ''; + this.input.focus(); + } + + focusIn() { + this.input.focus(); + } + + focusOut() { + this.input.blur(); + } + + fireEvent() { + let event = new Event('input', { + bubbles: true, + cancelable: true, + composed: true + }); + this.dispatchEvent(event); + } + + checkInput(e) { + if (!this.hasAttribute('readonly')) { + if (this.input.value.trim() !== '') { + this.clearBtn.classList.remove('hide'); + } else { + this.clearBtn.classList.add('hide'); + } + } + if (!this.hasAttribute('placeholder') || this.getAttribute('placeholder').trim() === '') return; + if (this.input.value !== '') { + if (this.animate) + this.inputParent.classList.add('animate-placeholder'); + else + this.label.classList.add('hide'); + } else { + if (this.animate) + this.inputParent.classList.remove('animate-placeholder'); + else + this.label.classList.remove('hide'); + this.feedbackText.textContent = ''; + } + } + vibrate() { + this.outerContainer.animate([ + { transform: 'translateX(-1rem)' }, + { transform: 'translateX(1rem)' }, + { transform: 'translateX(-0.5rem)' }, + { transform: 'translateX(0.5rem)' }, + { transform: 'translateX(0)' }, + ], { + duration: 300, + easing: 'ease' + }); + } + + + connectedCallback() { + this.animate = this.hasAttribute('animate'); + this.setAttribute('role', 'textbox'); + this.input.addEventListener('input', this.checkInput); + this.clearBtn.addEventListener('click', this.clear); + } + + attributeChangedCallback(name, oldValue, newValue) { + if (oldValue !== newValue) { + if (this.reflectedAttributes.includes(name)) { + if (this.hasAttribute(name)) { + this.input.setAttribute(name, this.getAttribute(name) ? this.getAttribute(name) : ''); + } + else { + this.input.removeAttribute(name); + } + } + if (name === 'placeholder') { + this.label.textContent = newValue; + this.setAttribute('aria-label', newValue); + } + else if (this.hasAttribute('value')) { + this.checkInput(); + } + else if (name === 'type') { + if (this.hasAttribute('type') && this.getAttribute('type') === 'number') { + this.input.setAttribute('inputmode', 'numeric'); + } + } + else if (name === 'helper-text') { + this._helperText = this.getAttribute('helper-text'); + } + else if (name === 'error-text') { + this._errorText = this.getAttribute('error-text'); + } + else if (name === 'required') { + this.isRequired = this.hasAttribute('required'); + if (this.isRequired) { + this.setAttribute('aria-required', 'true'); + } + else { + this.setAttribute('aria-required', 'false'); + } + } + else if (name === 'readonly') { + if (this.hasAttribute('readonly')) { + this.inputParent.classList.add('readonly'); + } else { + this.inputParent.classList.remove('readonly'); + } + } + else if (name === 'disabled') { + if (this.hasAttribute('disabled')) { + this.inputParent.classList.add('disabled'); + } + else { + this.inputParent.classList.remove('disabled'); + } + } + } + } + disconnectedCallback() { + this.input.removeEventListener('input', this.checkInput); + this.clearBtn.removeEventListener('click', this.clear); + } + }) +const smNotifications = document.createElement('template') +smNotifications.innerHTML = ` + +
+`; + + +customElements.define('sm-notifications', class extends HTMLElement { + constructor() { + super(); + this.shadow = this.attachShadow({ + mode: 'open' + }).append(smNotifications.content.cloneNode(true)) + + this.notificationPanel = this.shadowRoot.querySelector('.notification-panel') + this.animationOptions = { + duration: 300, + fill: "forwards", + easing: "cubic-bezier(0.175, 0.885, 0.32, 1.275)" + } + + this.push = this.push.bind(this) + this.createNotification = this.createNotification.bind(this) + this.removeNotification = this.removeNotification.bind(this) + this.clearAll = this.clearAll.bind(this) + + } + + randString(length) { + let result = ''; + const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + for (let i = 0; i < length; i++) + result += characters.charAt(Math.floor(Math.random() * characters.length)); + return result; + } + + createNotification(message, options = {}) { + const { pinned = false, icon = '' } = options; + const notification = document.createElement('output') + notification.id = this.randString(8) + notification.classList.add('notification'); + let composition = ``; + composition += ` +
${icon}
+

${message}

+ `; + if (pinned) { + notification.classList.add('pinned'); + composition += ` + + `; + } + notification.innerHTML = composition; + return notification; + } + + push(message, options = {}) { + const notification = this.createNotification(message, options); + this.notificationPanel.append(notification); + notification.animate([ + { + transform: `translateY(1rem)`, + opacity: '0' + }, + { + transform: `none`, + opacity: '1' + }, + ], this.animationOptions); + return notification.id; + } + + removeNotification(notification) { + notification.animate([ + { + transform: `none`, + opacity: '1' + }, + { + transform: `translateY(0.5rem)`, + opacity: '0' + } + ], this.animationOptions).onfinish = () => { + notification.remove(); + }; + } + + clearAll() { + Array.from(this.notificationPanel.children).forEach(child => { + this.removeNotification(child); + }); + } + + connectedCallback() { + this.notificationPanel.addEventListener('click', e => { + if (e.target.closest('.close')) { + this.removeNotification(e.target.closest('.notification')); + } + }); + + const observer = new MutationObserver(mutationList => { + mutationList.forEach(mutation => { + if (mutation.type === 'childList') { + if (mutation.addedNodes.length && !mutation.addedNodes[0].classList.contains('pinned')) { + setTimeout(() => { + this.removeNotification(mutation.addedNodes[0]); + }, 5000); + } + } + }); + }); + observer.observe(this.notificationPanel, { + childList: true, + }); + } +}); + +class Stack { + constructor() { + this.items = []; + } + push(element) { + this.items.push(element); + } + pop() { + if (this.items.length == 0) + return "Underflow"; + return this.items.pop(); + } + peek() { + return this.items[this.items.length - 1]; + } +} +const popupStack = new Stack(); + +const smPopup = document.createElement('template'); +smPopup.innerHTML = ` + + +`; +customElements.define('sm-popup', class extends HTMLElement { + constructor() { + super(); + this.attachShadow({ + mode: 'open' + }).append(smPopup.content.cloneNode(true)); + + this.allowClosing = false; + this.isOpen = false; + this.pinned = false; + this.offset = 0; + this.touchStartY = 0; + this.touchEndY = 0; + this.touchStartTime = 0; + this.touchEndTime = 0; + this.touchEndAnimation = undefined; + this.focusable + this.autoFocus + this.mutationObserver + + this.popupContainer = this.shadowRoot.querySelector('.popup-container'); + this.backdrop = this.shadowRoot.querySelector('.background'); + this.popup = this.shadowRoot.querySelector('.popup'); + this.popupBodySlot = this.shadowRoot.querySelector('.popup-body slot'); + this.popupHeader = this.shadowRoot.querySelector('.popup-top'); + + this.resumeScrolling = this.resumeScrolling.bind(this); + this.setStateOpen = this.setStateOpen.bind(this); + this.show = this.show.bind(this); + this.hide = this.hide.bind(this); + this.handleTouchStart = this.handleTouchStart.bind(this); + this.handleTouchMove = this.handleTouchMove.bind(this); + this.handleTouchEnd = this.handleTouchEnd.bind(this); + this.detectFocus = this.detectFocus.bind(this); + } + + static get observedAttributes() { + return ['open']; + } + + get open() { + return this.isOpen; + } + + animateTo(element, keyframes, options) { + const anime = element.animate(keyframes, { ...options, fill: 'both' }) + anime.finished.then(() => { + anime.commitStyles() + anime.cancel() + }) + return anime + } + + resumeScrolling() { + const scrollY = document.body.style.top; + window.scrollTo(0, parseInt(scrollY || '0') * -1); + document.body.style.overflow = ''; + document.body.style.top = 'initial'; + } + + setStateOpen() { + if (!this.isOpen || this.offset) { + const animOptions = { + duration: 300, + easing: 'ease' + } + const initialAnimation = (window.innerWidth > 640) ? 'scale(1.1)' : `translateY(${this.offset ? `${this.offset}px` : '100%'})` + this.animateTo(this.popup, [ + { + opacity: this.offset ? 1 : 0, + transform: initialAnimation + }, + { + opacity: 1, + transform: 'none' + }, + ], animOptions) + + } + } + + show(options = {}) { + const { pinned = false } = options; + if (!this.isOpen) { + const animOptions = { + duration: 300, + easing: 'ease' + } + popupStack.push({ + popup: this, + permission: pinned + }); + if (popupStack.items.length > 1) { + this.animateTo(popupStack.items[popupStack.items.length - 2].popup.shadowRoot.querySelector('.popup'), [ + { transform: 'none' }, + { transform: (window.innerWidth > 640) ? 'scale(0.95)' : 'translateY(-1.5rem)' }, + ], animOptions) + } + this.popupContainer.classList.remove('hide'); + if (!this.offset) + this.backdrop.animate([ + { opacity: 0 }, + { opacity: 1 }, + ], animOptions) + this.setStateOpen() + this.dispatchEvent( + new CustomEvent("popupopened", { + bubbles: true, + detail: { + popup: this, + } + }) + ); + this.pinned = pinned; + this.isOpen = true; + document.body.style.overflow = 'hidden'; + document.body.style.top = `-${window.scrollY}px`; + const elementToFocus = this.autoFocus || this.focusable[0]; + elementToFocus.tagName.includes('SM-') ? elementToFocus.focusIn() : elementToFocus.focus(); + if (!this.hasAttribute('open')) + this.setAttribute('open', ''); + } + } + hide() { + const animOptions = { + duration: 150, + easing: 'ease' + } + this.backdrop.animate([ + { opacity: 1 }, + { opacity: 0 } + ], animOptions) + this.animateTo(this.popup, [ + { + opacity: 1, + transform: (window.innerWidth > 640) ? 'none' : `translateY(${this.offset ? `${this.offset}px` : '0'})` + }, + { + opacity: 0, + transform: (window.innerWidth > 640) ? 'scale(1.1)' : 'translateY(100%)' + }, + ], animOptions).finished + .finally(() => { + this.popupContainer.classList.add('hide'); + this.popup.style = '' + this.removeAttribute('open'); + + if (this.forms.length) { + this.forms.forEach(form => form.reset()); + } + this.dispatchEvent( + new CustomEvent("popupclosed", { + bubbles: true, + detail: { + popup: this, + } + }) + ); + this.isOpen = false; + }) + popupStack.pop(); + if (popupStack.items.length) { + this.animateTo(popupStack.items[popupStack.items.length - 1].popup.shadowRoot.querySelector('.popup'), [ + { transform: (window.innerWidth > 640) ? 'scale(0.95)' : 'translateY(-1.5rem)' }, + { transform: 'none' }, + ], animOptions) + + } else { + this.resumeScrolling(); + } + } + + handleTouchStart(e) { + this.offset = 0 + this.popupHeader.addEventListener('touchmove', this.handleTouchMove, { passive: true }); + this.popupHeader.addEventListener('touchend', this.handleTouchEnd, { passive: true }); + this.touchStartY = e.changedTouches[0].clientY; + this.touchStartTime = e.timeStamp; + } + + handleTouchMove(e) { + if (this.touchStartY < e.changedTouches[0].clientY) { + this.offset = e.changedTouches[0].clientY - this.touchStartY; + this.touchEndAnimation = window.requestAnimationFrame(() => { + this.popup.style.transform = `translateY(${this.offset}px)`; + }); + } + } + + handleTouchEnd(e) { + this.touchEndTime = e.timeStamp; + cancelAnimationFrame(this.touchEndAnimation); + this.touchEndY = e.changedTouches[0].clientY; + this.threshold = this.popup.getBoundingClientRect().height * 0.3; + if (this.touchEndTime - this.touchStartTime > 200) { + if (this.touchEndY - this.touchStartY > this.threshold) { + if (this.pinned) { + this.setStateOpen(); + return; + } else + this.hide(); + } else { + this.setStateOpen(); + } + } else { + if (this.touchEndY > this.touchStartY) + if (this.pinned) { + this.setStateOpen(); + return; + } + else + this.hide(); + } + this.popupHeader.removeEventListener('touchmove', this.handleTouchMove, { passive: true }); + this.popupHeader.removeEventListener('touchend', this.handleTouchEnd, { passive: true }); + } + + + detectFocus(e) { + if (e.key === 'Tab') { + const lastElement = this.focusable[this.focusable.length - 1]; + const firstElement = this.focusable[0]; + if (e.shiftKey && document.activeElement === firstElement) { + e.preventDefault(); + lastElement.tagName.includes('SM-') ? lastElement.focusIn() : lastElement.focus(); + } else if (!e.shiftKey && document.activeElement === lastElement) { + e.preventDefault(); + firstElement.tagName.includes('SM-') ? firstElement.focusIn() : firstElement.focus(); + } + } + } + + updateFocusableList() { + this.focusable = this.querySelectorAll('sm-button:not([disabled]), button:not([disabled]), [href], sm-input, input:not([readonly]), sm-select, select, sm-checkbox, sm-textarea, textarea, [tabindex]:not([tabindex="-1"])') + this.autoFocus = this.querySelector('[autofocus]') + } + + connectedCallback() { + this.popupBodySlot.addEventListener('slotchange', () => { + this.forms = this.querySelectorAll('sm-form'); + this.updateFocusableList() + }); + this.popupContainer.addEventListener('mousedown', e => { + if (e.target === this.popupContainer && !this.pinned) { + if (this.pinned) { + this.setStateOpen(); + } else + this.hide(); + } + }); + + const resizeObserver = new ResizeObserver(entries => { + for (let entry of entries) { + if (entry.contentBoxSize) { + // Firefox implements `contentBoxSize` as a single content rect, rather than an array + const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize; + this.threshold = contentBoxSize.blockSize.height * 0.3; + } else { + this.threshold = entry.contentRect.height * 0.3; + } + } + }); + resizeObserver.observe(this); + + this.mutationObserver = new MutationObserver(entries => { + this.updateFocusableList() + }) + this.mutationObserver.observe(this, { attributes: true, childList: true, subtree: true }) + + this.addEventListener('keydown', this.detectFocus); + this.popupHeader.addEventListener('touchstart', this.handleTouchStart, { passive: true }); + } + disconnectedCallback() { + this.removeEventListener('keydown', this.detectFocus); + resizeObserver.unobserve(); + this.mutationObserver.disconnect() + this.popupHeader.removeEventListener('touchstart', this.handleTouchStart, { passive: true }); + } + attributeChangedCallback(name) { + if (name === 'open') { + if (this.hasAttribute('open')) { + this.show(); + } + } + } +}); +const smSwitch = document.createElement('template') +smSwitch.innerHTML = ` + +` + +customElements.define('sm-switch', class extends HTMLElement { + constructor() { + super() + this.attachShadow({ + mode: 'open' + }).append(smSwitch.content.cloneNode(true)) + this.switch = this.shadowRoot.querySelector('.switch'); + this.input = this.shadowRoot.querySelector('input') + this.isChecked = false + this.isDisabled = false + + this.dispatch = this.dispatch.bind(this) + } + + static get observedAttributes() { + return ['disabled', 'checked'] + } + + get disabled() { + return this.isDisabled + } + + set disabled(val) { + if (val) { + this.setAttribute('disabled', '') + } else { + this.removeAttribute('disabled') + } + } + + get checked() { + return this.isChecked + } + + set checked(value) { + if (value) { + this.setAttribute('checked', '') + } else { + this.removeAttribute('checked') + } + } + + reset() { + + } + + dispatch() { + this.dispatchEvent(new CustomEvent('change', { + bubbles: true, + composed: true, + detail: { + value: this.isChecked + } + })) + } + + connectedCallback() { + this.addEventListener('keydown', e => { + if (e.key === ' ' && !this.isDisabled) { + e.preventDefault() + this.input.click() + } + }) + this.input.addEventListener('click', e => { + if (this.input.checked) + this.checked = true + else + this.checked = false + this.dispatch() + }) + } + attributeChangedCallback(name, oldValue, newValue) { + if (oldValue !== newValue) { + if (name === 'disabled') { + if (this.hasAttribute('disabled')) { + this.disabled = true + } + else { + this.disabled = false + } + } + else if (name === 'checked') { + if (this.hasAttribute('checked')) { + this.isChecked = true + this.input.checked = true + } + else { + this.isChecked = false + this.input.checked = false + } + } + } + } + +}) +const themeToggle = document.createElement('template'); +themeToggle.innerHTML = ` + + +`; + +class ThemeToggle extends HTMLElement { + constructor() { + super(); + + this.attachShadow({ + mode: 'open' + }).append(themeToggle.content.cloneNode(true)); + + this.isChecked = false; + this.hasTheme = 'light'; + + this.toggleState = this.toggleState.bind(this); + this.fireEvent = this.fireEvent.bind(this); + this.handleThemeChange = this.handleThemeChange.bind(this); + } + static get observedAttributes() { + return ['checked']; + } + + daylight() { + this.hasTheme = 'light'; + document.body.dataset.theme = 'light'; + this.setAttribute('aria-checked', 'false'); + } + + nightlight() { + this.hasTheme = 'dark'; + document.body.dataset.theme = 'dark'; + this.setAttribute('aria-checked', 'true'); + } + + toggleState() { + this.toggleAttribute('checked'); + this.fireEvent(); + } + handleKeyDown(e) { + if (e.key === ' ') { + this.toggleState(); + } + } + handleThemeChange(e) { + if (e.detail.theme !== this.hasTheme) { + if (e.detail.theme === 'dark') { + this.setAttribute('checked', ''); + } + else { + this.removeAttribute('checked'); + } + } + } + + fireEvent() { + this.dispatchEvent( + new CustomEvent('themechange', { + bubbles: true, + composed: true, + detail: { + theme: this.hasTheme + } + }) + ); + } + + connectedCallback() { + this.setAttribute('role', 'switch'); + this.setAttribute('aria-label', 'theme toggle'); + if (localStorage.getItem(`${window.location.hostname}-theme`) === "dark") { + this.nightlight(); + this.setAttribute('checked', ''); + } else if (localStorage.getItem(`${window.location.hostname}-theme`) === "light") { + this.daylight(); + this.removeAttribute('checked'); + } + else { + if (window.matchMedia(`(prefers-color-scheme: dark)`).matches) { + this.nightlight(); + this.setAttribute('checked', ''); + } else { + this.daylight(); + this.removeAttribute('checked'); + } + } + this.addEventListener("click", this.toggleState); + this.addEventListener("keydown", this.handleKeyDown); + document.addEventListener('themechange', this.handleThemeChange); + } + + disconnectedCallback() { + this.removeEventListener("click", this.toggleState); + this.removeEventListener("keydown", this.handleKeyDown); + document.removeEventListener('themechange', this.handleThemeChange); + } + + attributeChangedCallback(name, oldVal, newVal) { + if (name === 'checked') { + if (this.hasAttribute('checked')) { + this.nightlight(); + localStorage.setItem(`${window.location.hostname}-theme`, "dark"); + } else { + this.daylight(); + localStorage.setItem(`${window.location.hostname}-theme`, "light"); + } + } + } +} + +window.customElements.define('theme-toggle', ThemeToggle); + +const smCopy = document.createElement('template'); +smCopy.innerHTML = ` + +
+

+ +
+`; +customElements.define('sm-copy', + class extends HTMLElement { + constructor() { + super(); + this.attachShadow({ + mode: 'open' + }).append(smCopy.content.cloneNode(true)); + + this.copyContent = this.shadowRoot.querySelector('.copy-content'); + this.copyButton = this.shadowRoot.querySelector('.copy-button'); + + this.copy = this.copy.bind(this); + } + static get observedAttributes() { + return ['value']; + } + set value(val) { + this.setAttribute('value', val); + } + get value() { + return this.getAttribute('value'); + } + fireEvent() { + this.dispatchEvent( + new CustomEvent('copy', { + composed: true, + bubbles: true, + cancelable: true, + }) + ); + } + copy() { + navigator.clipboard.writeText(this.copyContent.textContent) + .then(res => this.fireEvent()) + .catch(err => console.error(err)); + } + connectedCallback() { + this.copyButton.addEventListener('click', this.copy); + } + attributeChangedCallback(name, oldValue, newValue) { + if (name === 'value') { + this.copyContent.textContent = newValue; + } + } + disconnectedCallback() { + this.copyButton.removeEventListener('click', this.copy); + } + }); +const spinner = document.createElement('template'); +spinner.innerHTML = ` + + + +`; +class SpinnerLoader extends HTMLElement { + constructor() { + super(); + this.attachShadow({ + mode: 'open' + }).append(spinner.content.cloneNode(true)); + } +} +window.customElements.define('sm-spinner', SpinnerLoader); + +//Color Grid +const colorGrid = document.createElement('template'); +colorGrid.innerHTML = ` + +
+
`; + +customElements.define('color-grid', + class extends HTMLElement { + constructor() { + super() + this.attachShadow({ + mode: 'open' + }).append(colorGrid.content.cloneNode(true)) + + this.colorArray = [] + this.container = this.shadowRoot.querySelector('.color-tile-container') + this.handleChange = this.handleChange.bind(this) + this.setCheckMark = this.setCheckMark.bind(this) + } + + set colors(arr) { + this.colorArray = arr + this.renderTiles() + } + + set selectedColor(color) { + if (this.colorArray.includes(color) && this.container.querySelector(`[data-color="${color}"]`)) { + const selectedTile = this.container.querySelector(`[data-color="${color}"]`) + if (selectedTile) { + selectedTile.querySelector('input').checked = true + this.setCheckMark(selectedTile) + } + } + } + + randString(length) { + let result = ''; + let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + + for (let i = 0; i < length; i++) + result += characters.charAt(Math.floor(Math.random() * characters.length)); + return result; + } + + renderTiles() { + this.container.innerHTML = '' + const frag = document.createDocumentFragment() + const groupName = this.randString(6) + this.colorArray.forEach(color => { + const label = document.createElement('label') + label.classList.add('color-tile') + label.setAttribute('data-color', color) + if (color.includes('--')) + label.setAttribute('style', `background-color: var(${color})`) + else + label.setAttribute('style', `background-color: ${color}`) + label.innerHTML = ` + + ` + frag.append(label) + }) + this.container.append(frag) + } + setCheckMark(target) { + target.parentNode.querySelectorAll('.checkmark').forEach(checkmark => checkmark.remove()) + const checkMark = document.createElement('div') + checkMark.classList.add('checkmark') + checkMark.innerHTML = ` + + ` + target.append(checkMark) + } + + handleChange(e) { + const clickedTile = e.target.closest('.color-tile') + this.setCheckMark(clickedTile) + const clickedTileColor = clickedTile.dataset.color + const tileSelected = new CustomEvent('colorselected', { + bubbles: true, + composed: true, + detail: { + value: clickedTileColor, + } + }) + this.dispatchEvent(tileSelected) + } + + connectedCallback() { + this.container.addEventListener('change', this.handleChange) + } + + disconnectedCallback() { + this.container.removeEventListener('change', this.handleChange) + } + }) +const stripSelect = document.createElement('template'); +stripSelect.innerHTML = ` + +
+
+ +
+ +
+ +
+
+ +`; +customElements.define('strip-select', class extends HTMLElement { + constructor() { + super(); + this.attachShadow({ + mode: 'open' + }).append(stripSelect.content.cloneNode(true)); + this.stripSelect = this.shadowRoot.querySelector('.strip-select'); + this.slottedOptions = undefined; + this._value = undefined; + this.scrollDistance = 0; + + this.scrollLeft = this.scrollLeft.bind(this); + this.scrollRight = this.scrollRight.bind(this); + this.fireEvent = this.fireEvent.bind(this); + } + get value() { + return this._value; + } + scrollLeft() { + this.stripSelect.scrollBy({ + left: -this.scrollDistance, + behavior: 'smooth' + }); + } + + scrollRight() { + this.stripSelect.scrollBy({ + left: this.scrollDistance, + behavior: 'smooth' + }); + } + fireEvent() { + this.dispatchEvent( + new CustomEvent("change", { + bubbles: true, + composed: true, + detail: { + value: this._value + } + }) + ); + } + connectedCallback() { + this.setAttribute('role', 'listbox'); + + const slot = this.shadowRoot.querySelector('slot'); + const coverLeft = this.shadowRoot.querySelector('.cover--left'); + const coverRight = this.shadowRoot.querySelector('.cover--right'); + const navButtonLeft = this.shadowRoot.querySelector('.nav-button--left'); + const navButtonRight = this.shadowRoot.querySelector('.nav-button--right'); + slot.addEventListener('slotchange', e => { + const assignedElements = slot.assignedElements(); + assignedElements.forEach(elem => { + if (elem.hasAttribute('selected')) { + elem.setAttribute('active', ''); + this._value = elem.value; + } + }); + if (!this.hasAttribute('multiline')) { + if (assignedElements.length > 0) { + firstOptionObserver.observe(slot.assignedElements()[0]); + lastOptionObserver.observe(slot.assignedElements()[slot.assignedElements().length - 1]); + } + else { + navButtonLeft.classList.add('hide'); + navButtonRight.classList.add('hide'); + coverLeft.classList.add('hide'); + coverRight.classList.add('hide'); + firstOptionObserver.disconnect(); + lastOptionObserver.disconnect(); + } + } + }); + const resObs = new ResizeObserver(entries => { + entries.forEach(entry => { + if (entry.contentBoxSize) { + // Firefox implements `contentBoxSize` as a single content rect, rather than an array + const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize; + + this.scrollDistance = contentBoxSize.inlineSize * 0.6; + } else { + this.scrollDistance = entry.contentRect.width * 0.6; + } + }); + }); + resObs.observe(this); + this.stripSelect.addEventListener('option-clicked', e => { + if (this._value !== e.target.value) { + this._value = e.target.value; + slot.assignedElements().forEach(elem => elem.removeAttribute('active')); + e.target.setAttribute('active', ''); + e.target.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" }); + this.fireEvent(); + } + }); + const firstOptionObserver = new IntersectionObserver(entries => { + entries.forEach(entry => { + if (entry.isIntersecting) { + navButtonLeft.classList.add('hide'); + coverLeft.classList.add('hide'); + } + else { + navButtonLeft.classList.remove('hide'); + coverLeft.classList.remove('hide'); + } + }); + }, + { + threshold: 0.9, + root: this + }); + const lastOptionObserver = new IntersectionObserver(entries => { + entries.forEach(entry => { + if (entry.isIntersecting) { + navButtonRight.classList.add('hide'); + coverRight.classList.add('hide'); + } + else { + navButtonRight.classList.remove('hide'); + coverRight.classList.remove('hide'); + } + }); + }, + { + threshold: 0.9, + root: this + }); + navButtonLeft.addEventListener('click', this.scrollLeft); + navButtonRight.addEventListener('click', this.scrollRight); + } + disconnectedCallback() { + navButtonLeft.removeEventListener('click', this.scrollLeft); + navButtonRight.removeEventListener('click', this.scrollRight); + } +}); + +//Strip option +const stripOption = document.createElement('template'); +stripOption.innerHTML = ` + + +`; +customElements.define('strip-option', class extends HTMLElement { + constructor() { + super(); + this.attachShadow({ + mode: 'open' + }).append(stripOption.content.cloneNode(true)); + this._value = undefined; + this.radioButton = this.shadowRoot.querySelector('input'); + + this.fireEvent = this.fireEvent.bind(this); + this.handleKeyDown = this.handleKeyDown.bind(this); + } + get value() { + return this._value; + } + fireEvent() { + this.dispatchEvent( + new CustomEvent("option-clicked", { + bubbles: true, + composed: true, + detail: { + value: this._value + } + }) + ); + } + handleKeyDown(e) { + if (e.key === 'Enter' || e.key === 'Space') { + this.fireEvent(); + } + } + connectedCallback() { + this.setAttribute('role', 'option'); + this.setAttribute('tabindex', '0'); + this._value = this.getAttribute('value'); + this.addEventListener('click', this.fireEvent); + this.addEventListener('keydown', this.handleKeyDown); + } + disconnectedCallback() { + this.removeEventListener('click', this.fireEvent); + this.removeEventListener('keydown', this.handleKeyDown); + } +}); +const smTextarea = document.createElement('template') +smTextarea.innerHTML = ` + + +`; +customElements.define('sm-textarea', + class extends HTMLElement { + constructor() { + super() + this.attachShadow({ + mode: 'open' + }).append(smTextarea.content.cloneNode(true)) + + this.textarea = this.shadowRoot.querySelector('textarea') + this.textareaBox = this.shadowRoot.querySelector('.textarea') + this.placeholder = this.shadowRoot.querySelector('.placeholder') + this.reflectedAttributes = ['disabled', 'required', 'readonly', 'rows', 'minlength', 'maxlength'] + + this.reset = this.reset.bind(this) + this.focusIn = this.focusIn.bind(this) + this.fireEvent = this.fireEvent.bind(this) + this.checkInput = this.checkInput.bind(this) + } + static get observedAttributes() { + return ['disabled', 'value', 'placeholder', 'required', 'readonly', 'rows', 'minlength', 'maxlength'] + } + get value() { + return this.textarea.value + } + set value(val) { + this.setAttribute('value', val) + this.fireEvent() + } + get disabled() { + return this.hasAttribute('disabled') + } + set disabled(val) { + if (val) { + this.setAttribute('disabled', '') + } else { + this.removeAttribute('disabled') + } + } + get isValid() { + return this.textarea.checkValidity() + } + reset() { + this.setAttribute('value', '') + } + focusIn() { + this.textarea.focus() + } + fireEvent() { + let event = new Event('input', { + bubbles: true, + cancelable: true, + composed: true + }); + this.dispatchEvent(event); + } + checkInput() { + if (!this.hasAttribute('placeholder') || this.getAttribute('placeholder') === '') + return; + if (this.textarea.value !== '') { + if (this.hasAttribute('animate')) + this.textareaBox.classList.add('animate-placeholder') + else + this.placeholder.classList.add('hide') + + } else { + if (this.hasAttribute('animate')) + this.textareaBox.classList.remove('animate-placeholder') + else + this.placeholder.classList.remove('hide') + } + } + connectedCallback() { + this.textarea.addEventListener('input', e => { + this.textareaBox.dataset.value = this.textarea.value + this.checkInput() + }) + } + attributeChangedCallback(name, oldValue, newValue) { + if (this.reflectedAttributes.includes(name)) { + if (this.hasAttribute(name)) { + this.textarea.setAttribute(name, this.getAttribute(name) ? this.getAttribute(name) : '') + } + else { + this.textContent.removeAttribute(name) + } + } + else if (name === 'placeholder') { + this.placeholder.textContent = this.getAttribute('placeholder') + } + else if (name === 'value') { + this.textarea.value = newValue; + this.textareaBox.dataset.value = newValue + this.checkInput() + } + } + }) + +const smTabHeader = document.createElement('template') +smTabHeader.innerHTML = ` + +
+
+ +
+
+
+`; + +customElements.define('tab-header', class extends HTMLElement { + constructor() { + super() + this.attachShadow({ + mode: 'open' + }).append(smTabHeader.content.cloneNode(true)) + + this.prevTab + this.allTabs + this.activeTab + + this.indicator = this.shadowRoot.querySelector('.indicator'); + this.tabSlot = this.shadowRoot.querySelector('slot'); + this.tabHeader = this.shadowRoot.querySelector('.tab-header'); + + this.changeTab = this.changeTab.bind(this) + this.handleClick = this.handleClick.bind(this) + this.handlePanelChange = this.handlePanelChange.bind(this) + this.moveIndiactor = this.moveIndiactor.bind(this) + } + + fireEvent(index) { + this.dispatchEvent( + new CustomEvent(`switchedtab${this.target}`, { + bubbles: true, + detail: { + index: parseInt(index) + } + }) + ) + } + + moveIndiactor(tabDimensions) { + this.indicator.setAttribute('style', `width: ${tabDimensions.width}px; transform: translateX(${tabDimensions.left - this.tabHeader.getBoundingClientRect().left + this.tabHeader.scrollLeft}px)`) + } + + + changeTab(target) { + if (target === this.prevTab || !target.closest('sm-tab')) + return + if (this.prevTab) + this.prevTab.classList.remove('active') + target.classList.add('active') + + this.tabHeader.scrollTo({ + behavior: 'smooth', + left: target.getBoundingClientRect().left - this.tabHeader.getBoundingClientRect().left + this.tabHeader.scrollLeft + }) + this.moveIndiactor(target.getBoundingClientRect()) + this.prevTab = target; + this.activeTab = target; + } + handleClick(e) { + if (e.target.closest('sm-tab')) { + this.changeTab(e.target) + this.fireEvent(e.target.dataset.index) + } + } + + handlePanelChange(e) { + this.changeTab(this.allTabs[e.detail.index]) + } + + connectedCallback() { + if (!this.hasAttribute('target') || this.getAttribute('target').value === '') return; + this.target = this.getAttribute('target') + + this.tabSlot.addEventListener('slotchange', () => { + this.allTabs = this.tabSlot.assignedElements(); + this.allTabs.forEach((tab, index) => { + tab.dataset.index = index + }) + }) + + this.addEventListener('click', this.handleClick) + document.addEventListener(`switchedpanel${this.target}`, this.handlePanelChange) + + let resizeObserver = new ResizeObserver(entries => { + entries.forEach((entry) => { + if (this.prevTab) { + let tabDimensions = this.activeTab.getBoundingClientRect(); + this.moveIndiactor(tabDimensions) + } + }) + }) + resizeObserver.observe(this) + let observer = new IntersectionObserver((entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + this.indicator.style.transition = 'none' + if (this.activeTab) { + let tabDimensions = this.activeTab.getBoundingClientRect(); + this.moveIndiactor(tabDimensions) + } else { + this.allTabs[0].classList.add('active') + let tabDimensions = this.allTabs[0].getBoundingClientRect(); + this.moveIndiactor(tabDimensions) + this.fireEvent(0) + this.prevTab = this.tabSlot.assignedElements()[0]; + this.activeTab = this.prevTab; + } + } + }) + }, { + threshold: 1.0 + }) + observer.observe(this) + } + disconnectedCallback() { + this.removeEventListener('click', this.handleClick) + document.removeEventListener(`switchedpanel${this.target}`, this.handlePanelChange) + } +}) + +// tab +const smTab = document.createElement('template') +smTab.innerHTML = ` + +
+ +
+`; + +customElements.define('sm-tab', class extends HTMLElement { + constructor() { + super() + this.shadow = this.attachShadow({ + mode: 'open' + }).append(smTab.content.cloneNode(true)) + } +}) + +// tab-panels + +const smTabPanels = document.createElement('template') +smTabPanels.innerHTML = ` + +
+ Nothing to see here. +
+`; + +customElements.define('tab-panels', class extends HTMLElement { + constructor() { + super() + this.attachShadow({ + mode: 'open' + }).append(smTabPanels.content.cloneNode(true)) + + this.isTransitioning = false + + this.panelContainer = this.shadowRoot.querySelector('.panel-container'); + this.handleTabChange = this.handleTabChange.bind(this) + } + handleTabChange(e) { + this.isTransitioning = true + this.panelContainer.scrollTo({ + left: this.allPanels[e.detail.index].getBoundingClientRect().left - this.panelContainer.getBoundingClientRect().left + this.panelContainer.scrollLeft, + behavior: 'smooth' + }) + setTimeout(() => { + this.isTransitioning = false + }, 300); + } + fireEvent(index) { + this.dispatchEvent( + new CustomEvent(`switchedpanel${this.id}`, { + bubbles: true, + detail: { + index: parseInt(index) + } + }) + ) + } + connectedCallback() { + const slot = this.shadowRoot.querySelector('slot'); + slot.addEventListener('slotchange', (e) => { + this.allPanels = e.target.assignedElements() + this.allPanels.forEach((panel, index) => { + panel.dataset.index = index + intersectionObserver.observe(panel) + }) + }) + document.addEventListener(`switchedtab${this.id}`, this.handleTabChange) + + const intersectionObserver = new IntersectionObserver(entries => { + + entries.forEach(entry => { + if (!this.isTransitioning && entry.isIntersecting) { + this.fireEvent(entry.target.dataset.index) + } + }) + }, { + threshold: 0.6 + }) + } + disconnectedCallback() { + intersectionObserver.disconnect() + document.removeEventListener(`switchedtab${this.id}`, this.handleTabChange) + } +}) \ No newline at end of file diff --git a/scripts/fn_pay.js b/scripts/fn_pay.js new file mode 100644 index 0000000..c9f7c9c --- /dev/null +++ b/scripts/fn_pay.js @@ -0,0 +1,251 @@ +/*jshint esversion: 6 */ +const TYPE_MONEY_REQUEST = "MoneyRequests", + TYPE_CASHIER_REQUEST = "CashierRequests", + TYPE_CASHIER_UPI = "CashierUPI"; + +const cashierUPI = {}; + +//For regular users +const User = {}; +const cashierStatus = {}; + +User.init = function () { + return new Promise((resolve, reject) => { + let promises; + //Request cashier for token-cash exchange + promises = floGlobals.subAdmins.map(cashierID => floCloudAPI.requestGeneralData(TYPE_CASHIER_REQUEST, { + senderID: myFloID, + receiverID: cashierID, + group: "Cashiers", + callback: userUI.renderCashierRequests //UI_fn + })); + //Request received from other Users for token + promises.push(floCloudAPI.requestGeneralData(TYPE_MONEY_REQUEST, { + receiverID: myFloID, + callback: userUI.renderMoneyRequests //UI_fn + })); + //Check online status of cashiers + promises.push(floCloudAPI.requestStatus(Array.from(floGlobals.subAdmins), { + callback: (d, e) => { + if (e) return console.error(e); + for (let i in d) + cashierStatus[i] = d[i]; + //Add any UI_fn if any + } + })) + /* + promises.push(floCloudAPI.requestObjectData("UPI", { //Is this needed? + callback: UI_RENDER_FN + })); + */ + promises.push(User.getCashierUPI()); + Promise.all(promises) + .then(result => resolve(result)) + .catch(error => reject(error)) + }) +} + +User.getCashierUPI = function () { + return new Promise((resolve) => { + Promise.allSettled(floGlobals.subAdmins.map(cashierID => floCloudAPI.requestApplicationData(TYPE_CASHIER_UPI, { + senderID: cashierID, + mostRecent: true + }))).then(result => { + for (let r of result) + if (r.status === "fulfilled" && r.value.length) + cashierUPI[r.value[0].senderID] = floCloudAPI.util.decodeMessage(r.value[0].message).upi; + resolve(cashierUPI); + }) + }) +} + +Object.defineProperty(User, 'cashierRequests', { + get: function () { + let fk = floCloudAPI.util.filterKey(TYPE_CASHIER_REQUEST, { + senderID: myFloID, + group: "Cashiers", + }); + return floGlobals.generalData[fk]; + } +}); + +Object.defineProperty(User, 'moneyRequests', { + get: function () { + let fk = floCloudAPI.util.filterKey(TYPE_MONEY_REQUEST, { + receiverID: myFloID, + }); + return floGlobals.generalData[fk]; + } +}); + +User.findCashier = function () { + let online = []; + for (let c in cashierStatus) + if (cashierStatus[c] && cashierUPI[c]) + online.push(c); + if (!online.length) + return null; + else + return online[floCrypto.randInt(0, online.length)]; +} + +User.cashToToken = function (cashier, amount, upiTxID) { + return new Promise((resolve, reject) => { + if (!floGlobals.subAdmins.includes(cashier)) + return reject("Invalid cashier"); + floCloudAPI.sendGeneralData({ + mode: "cash-to-token", + amount: amount, + upi_txid: upiTxID + }, TYPE_CASHIER_REQUEST, { + receiverID: cashier + }).then(result => resolve(result)) + .catch(error => reject(error)) + }) +} + +User.tokenToCash = function (cashier, amount, blkTxID, upiID) { + return new Promise((resolve, reject) => { + if (!floGlobals.subAdmins.includes(cashier)) + return reject("Invalid cashier"); + floCloudAPI.sendGeneralData({ + mode: "token-to-cash", + amount: amount, + token_txid: blkTxID, + upi_id: upiID + }, TYPE_CASHIER_REQUEST, { + receiverID: cashier + }).then(result => resolve(result)) + .catch(error => reject(error)) + }) +} + +User.sendToken = function (receiverID, amount, remark = '') { + return new Promise((resolve, reject) => { + tokenAPI.sendToken(myPrivKey, amount, receiverID, remark) + .then(result => resolve(result)) + .catch(error => reject(error)) + }) +} + +User.requestToken = function (floID, amount, remark = '') { + return new Promise((resolve, reject) => { + floCloudAPI.sendGeneralData({ + amount: amount, + remark: remark + }, TYPE_MONEY_REQUEST, { + receiverID: floID + }).then(result => resolve(result)) + .catch(error => reject(error)) + }) +} + +User.decideRequest = function (request, note) { + return new Promise((resolve, reject) => { + floCloudAPI.noteApplicationData(request.vectorClock, note, { + receiverID: myFloID + }).then(result => resolve(result)) + .catch(error => reject(error)) + }) +} + +const Cashier = {}; + +Cashier.init = function () { + return new Promise((resolve, reject) => { + let promises = []; + //Requests from user to cashier(self) for token-cash exchange + promises.push(floCloudAPI.requestGeneralData(TYPE_CASHIER_REQUEST, { + receiverID: myFloID, + callback: cashierUI.renderRequests //UI_fn + })); + //Set online status of cashier(self) + promises.push(floCloudAPI.setStatus()); + /* + promises.push(floCloudAPI.requestObjectData("UPI", { //Is this needed? + callback: UI_RENDER_FN + })); + */ + Promise.all(promises) + .then(result => resolve(result)) + .catch(error => reject(error)) + }) +} + +Cashier.updateUPI = function (upi_id) { + return new Promise((resolve, reject) => { + floCloudAPI.sendApplicationData({ + upi: upi_id + }, TYPE_CASHIER_UPI) + .then(result => resolve(result)) + .catch(error => reject(error)) + }) +} + +Object.defineProperty(Cashier, 'Requests', { + get: function () { + let fk = floCloudAPI.util.filterKey(TYPE_CASHIER_REQUEST, { + receiverID: myFloID + }); + console.debug(fk, floGlobals.generalData[fk]); + return floGlobals.generalData[fk]; + } +}); + +Cashier.finishRequest = function (request, txid) { + return new Promise((resolve, reject) => { + floCloudAPI.tagApplicationData(request.vectorClock, 'COMPLETED', { + receiverID: myFloID + }).then(result => { + floCloudAPI.noteApplicationData(request.vectorClock, txid, { + receiverID: myFloID + }).then(result => resolve(result)) + .catch(error => reject(error)) + }).catch(error => reject(error)) + }) +} + +Cashier.rejectRequest = function (request, reason) { + return new Promise((resolve, reject) => { + floCloudAPI.noteApplicationData(request.vectorClock, "REJECTED:" + reason, { + receiverID: myFloID + }).then(result => resolve(result)) + .catch(error => reject(error)) + }) +} + +Cashier.checkIfUpiTxIsValid = function (upiTxID) { + return new Promise((resolve, reject) => { + let requests = Cashier.Requests; + for (let r in requests) + if (requests[r].message.mode === "cash-to-token" && requests[r].note) + if (requests[r].message.upi_txid === upiTxID) + return reject([true, "UPI transaction is already used for another request"]); + return resolve(true); + }) +} + +Cashier.checkIfTokenTxIsValid = function (tokenTxID, sender, amount) { + return new Promise((resolve, reject) => { + let requests = Cashier.Requests; + for (let r in requests) + if (requests[r].message.mode === "token-to-cash" && requests[r].note) + if (requests[r].message.token_txid === tokenTxID) + return reject([true, "Token transaction is already used for another request"]); + tokenAPI.getTx(tokenTxID).then(tx => { + let parsedTxData = tokenAPI.util.parseTxData(tx); + console.debug(parsedTxData); + if (parsedTxData.type !== "transfer" || parsedTxData.transferType !== "token") + reject([true, "Invalid token transfer type"]); + else if (parsedTxData.tokenAmount !== amount) + reject([true, "Incorrect token amount: " + parsedTxData.tokenAmount]); + else if (parsedTxData.tokenIdentification !== floGlobals.currency) + reject([true, "Incorrect token: " + parsedTxData.tokenIdentification]); + else if (parsedTxData.sender !== sender) + reject([true, "Incorrect senderID: " + parsedTxData.sender]); + else if (parsedTxData.receiver !== myFloID) + reject([true, "Incorrect receiverID: " + parsedTxData.receive]) + else resolve(true); + }).catch(error => reject([null, error])) + }) +} \ No newline at end of file diff --git a/scripts/fn_ui.js b/scripts/fn_ui.js new file mode 100644 index 0000000..0e4e671 --- /dev/null +++ b/scripts/fn_ui.js @@ -0,0 +1,296 @@ +/*jshint esversion: 6 */ +const userUI = {}; + +userUI.requestTokenFromCashier = function () { + let cashier = User.findCashier(); + if (!cashier) + return alert("No cashier online"); + let amount = parseFloat(getRef('request_cashier_amount').value.trim()); + //get UPI txid from user + let upiTxID = prompt(`Send Rs. ${amount} to ${cashierUPI[cashier]} and enter UPI txid`); + if (!upiTxID) + return alert("Cancelled"); + User.cashToToken(cashier, amount, upiTxID).then(result => { + console.log(result); + alert("Requested cashier. please wait!"); + }).catch(error => console.error(error)) +} + +userUI.withdrawCashFromCashier = function () { + let cashier = User.findCashier(); + if (!cashier) + return alert("No cashier online"); + let amount = parseFloat(getRef('request_cashier_amount').value.trim()); + //get confirmation from user + let upiID = prompt(`${amount} ${floGlobals.currency}# will be sent to ${cashier}. Enter UPI ID`); + if (!upiID) + return alert("Cancelled"); + User.sendToken(cashier, amount, 'for token-to-cash').then(txid => { + console.warn(`Withdraw ${amount} from cashier ${cashier}`, txid); + User.tokenToCash(cashier, amount, txid, upiID).then(result => { + console.log(result); + alert("Requested cashier. please wait!"); + }).catch(error => console.error(error)) + }).catch(error => console.error(error)) +} + +userUI.sendMoneyToUser = function (floID, amount, remark) { + getConfirmation('Confirm', { message: `Do you want to SEND ${amount} to ${floID}?` }).then(confirmation => { + if (confirmation) { + User.sendToken(floID, amount, "|" + remark).then(txid => { + console.warn(`Sent ${amount} to ${floID}`, txid); + notify(`Sent ${amount} to ${floID}. It may take a few mins to reflect in their wallet`, 'success'); + hidePopup() + }).catch(error => console.error(error)); + } + }) +} + +userUI.requestMoneyFromUser = function (floID, amount, remark) { + getConfirmation('Confirm', { message: `Do you want to REQUEST ${amount} from ${floID}?` }).then(confirmation => { + if (confirmation) { + User.requestToken(floID, amount, remark).then(result => { + console.log(`Requested ${amount} from ${floID}`, result); + notify(`Requested ${amount} from ${floID}`, 'success'); + hidePopup() + }).catch(error => console.error(error)); + } + }) +} + +userUI.renderCashierRequests = function (requests, error = null) { + if (error) + return console.error(error); + else if (typeof requests !== "object" || requests === null) + return; + const frag = document.createDocumentFragment() + for (let r in requests) { + let oldCard = document.getElementById(r); + if (oldCard) oldCard.remove(); + frag.append(render.walletRequestCard(requests[r])) + } + getRef('user-cashier-requests').append(frag) +} + +userUI.renderMoneyRequests = function (requests, error = null) { + if (error) + return console.error(error); + else if (typeof requests !== "object" || requests === null) + return; + const frag = document.createDocumentFragment() + for (let r in requests) { + let oldCard = document.getElementById(r); + if (oldCard) oldCard.remove(); + frag.append(render.paymentRequestCard(requests[r])) + } + getRef('user-money-requests').append(frag) +} + +userUI.payRequest = function (reqID) { + let request = User.moneyRequests[reqID]; + getConfirmation('Pay?', { message: `Do you want to pay ${request.message.amount} to ${request.senderID}?` }).then(confirmation => { + if (confirmation) { + User.sendToken(request.senderID, request.message.amount, "|" + request.message.remark).then(txid => { + console.warn(`Sent ${request.message.amount} to ${request.senderID}`, txid); + notify(`Sent ${request.message.amount} to ${request.senderID}. It may take a few mins to reflect in their wallet`, 'success'); + User.decideRequest(request, 'PAID: ' + txid) + .then(result => console.log(result)) + .catch(error => console.error(error)) + }).catch(error => console.error(error)); + } + }) +} + +userUI.declineRequest = function (reqID) { + let request = User.moneyRequests[reqID]; + getConfirmation('Decline payment?').then(confirmation => { + if (confirmation) { + User.decideRequest(request, "DECLINED").then(result => { + console.log(result); + notify("Request declined", 'success'); + }).catch(error => console.error(error)) + } + }) +} + +//Cashier +const cashierUI = {}; + +cashierUI.renderRequests = function (requests, error = null) { + if (error) + return console.error(error); + else if (typeof requests !== "object" || requests === null) + return; + const frag = document.createDocumentFragment(); + for (let r in requests) { + const oldCard = document.getElementById(r); + if (oldCard) oldCard.remove(); + frag.append(render.cashierRequestCard(requests[r])); + } + getRef('cashier_request_list').append(frag) +} + +cashierUI.completeRequest = function (reqID) { + let request = Cashier.Requests[reqID]; + if (request.message.mode === "cash-to-token") + completeCashToTokenRequest(request); + else if (request.message.mode === "token-to-cash") + completeTokenToCashRequest(request); +} + +function completeCashToTokenRequest(request) { + Cashier.checkIfUpiTxIsValid(request.message.upi_txid).then(_ => { + let confirmation = confirm(`Check if you have received UPI transfer\ntxid:${request.message.upi_txid}\namount:${request.message.amount}`); + if (!confirmation) + return alert("Cancelled"); + User.sendToken(request.senderID, request.message.amount, 'for cash-to-token').then(txid => { + console.warn(`${request.message.amount} cash-to-token for ${request.senderID}`, txid); + Cashier.finishRequest(request, txid).then(result => { + console.log(result); + console.info('Completed cash-to-token request:', request.vectorClock); + alert("Completed request"); + }).catch(error => console.error(error)) + }).catch(error => console.error(error)) + }).catch(error => { + console.error(error); + alert(error); + if (Array.isArray(error) && error[0] === true && typeof error[1] === 'string') + Cashier.rejectRequest(request, error[1]).then(result => { + console.log(result); + console.info('Rejected cash-to-token request:', request.vectorClock); + }).catch(error => console.error(error)) + }) +} + +function completeTokenToCashRequest(request) { + Cashier.checkIfTokenTxIsValid(request.message.token_txid, request.senderID, request.message.amount).then(result => { + let upiTxID = prompt(`Token transfer is verified!\n Send ${request.message.amount} to ${request.message.upi_id} and Enter UPI txid`); + if (!upiTxID) + return alert("Cancelled"); + Cashier.finishRequest(request, upiTxID).then(result => { + console.log(result); + console.info('Completed token-to-cash request:', request.vectorClock); + alert("Completed request"); + }).catch(error => console.error(error)) + }).catch(error => { + console.error(error); + alert(error); + if (Array.isArray(error) && error[0] === true && typeof error[1] === 'string') + Cashier.rejectRequest(request, error[1]).then(result => { + console.log(result); + console.info('Rejected token-to-cash request:', request.vectorClock); + }).catch(error => console.error(error)) + }) +} + +function renderAllTokenTransactions() { + tokenAPI.getAllTxs(myFloID).then(result => { + getRef('token_transactions').innerHTML = '' + const frag = document.createDocumentFragment(); + for (let txid in result.transactions) { + frag.append(render.transactionCard(txid, tokenAPI.util.parseTxData(result.transactions[txid]))) + } + getRef('token_transactions').append(frag) + }).catch(error => console.error(error)) +} + +const render = { + transactionCard(txid, transactionDetails) { + const { time, sender, receiver, tokenAmount } = transactionDetails + const clone = getRef('transaction_template').content.cloneNode(true).firstElementChild; + clone.dataset.txid = txid + clone.querySelector('.transaction__time').textContent = getFormattedTime(time * 1000) + clone.querySelector('.transaction__amount').textContent = tokenAmount + if (sender === myFloID) { + clone.querySelector('.transaction__amount').classList.add('sent') + clone.querySelector('.transaction__receiver').textContent = `Sent to ${receiver || 'Myself'}` + clone.querySelector('.transaction__icon').innerHTML = `` + } else if (receiver === myFloID) { + clone.querySelector('.transaction__amount').classList.add('received') + clone.querySelector('.transaction__receiver').textContent = `Received from ${sender}` + clone.querySelector('.transaction__icon').innerHTML = `` + } else { //This should not happen unless API returns transaction that does not involve myFloID + row.insertCell().textContent = tx.sender; + row.insertCell().textContent = tx.receiver; + } + return clone + }, + cashierRequestCard(details) { + const { time, senderID, message: { mode }, note, tag, vectorClock } = details; + const clone = getRef('cashier_request_template').content.cloneNode(true).firstElementChild; + clone.id = vectorClock + const status = tag || note; //status tag for completed, note for rejected + clone.querySelector('.cashier-request__requestor').textContent = senderID + clone.querySelector('.cashier-request__time').textContent = getFormattedTime(time) + clone.querySelector('.cashier-request__mode').textContent = mode + if (status) + clone.querySelector('.cashier-request__status').textContent = status + else + clone.querySelector('.cashier-request__status').innerHTML = `` + return clone + }, + walletRequestCard(details) { + const { time, receiverID, message: { mode }, note, tag, vectorClock } = details; + const clone = getRef('wallet_request_template').content.cloneNode(true).firstElementChild; + clone.id = vectorClock + clone.querySelector('.wallet-request__requestor').textContent = receiverID + clone.querySelector('.wallet-request__time').textContent = getFormattedTime(time) + clone.querySelector('.wallet-request__mode').textContent = mode === 'cash-to-token' ? 'Deposit' : 'Withdraw' + let status = tag ? (tag + ":" + note) : (note || "PENDING"); + clone.querySelector('.wallet-request__status').textContent = status + return clone + }, + paymentRequestCard(details) { + const { time, senderID, message: { amount, remark }, note, vectorClock } = details; + const clone = getRef('payment_request_template').content.cloneNode(true).firstElementChild; + clone.id = vectorClock + clone.querySelector('.payment-request__requestor').textContent = senderID + clone.querySelector('.payment-request__time').textContent = getFormattedTime(time) + clone.querySelector('.payment-request__amount').textContent = amount.toLocaleString(`en-IN`, { style: 'currency', currency: 'INR' }) + clone.querySelector('.payment-request__remark').textContent = remark + + let status = note; + if (status) + clone.querySelector('.payment-request__actions').textContent = note; + else + clone.querySelector('.payment-request__actions').innerHTML = + ` + `; + + return clone + }, +} + +let currentUserAction +function showTokenTransfer(type) { + getRef('tt_button').textContent = type; + currentUserAction = type + if (type === 'send') { + getRef('token_transfer__title').textContent = 'Send money to FLO ID'; + } else { + getRef('token_transfer__title').textContent = 'Request money from FLO ID'; + } + showPopup('token_transfer_popup') +} + +function executeUserAction() { + const floID = getRef('tt_flo_id').value.trim(), + amount = parseFloat(getRef('tt_amount').value), + remark = getRef('tt_remark').value.trim(); + if (currentUserAction === 'send') { + userUI.sendMoneyToUser(floID, amount, remark) + + } else { + userUI.requestMoneyFromUser(floID, amount, remark) + } +} + +function signOut() { + getConfirmation('Sign out?', 'You are about to sign out of the app, continue?', 'Stay', 'Leave') + .then(async (res) => { + if (res) { + await floDapps.clearCredentials() + location.reload() + } + }) +} \ No newline at end of file diff --git a/scripts/qrcode-scanner.min.js b/scripts/qrcode-scanner.min.js new file mode 100644 index 0000000..b275c07 --- /dev/null +++ b/scripts/qrcode-scanner.min.js @@ -0,0 +1,7 @@ +function getLazarSoftScanner(){var e={};function t(e,t){this.count=e,this.dataCodewords=t,this.__defineGetter__("Count",function(){return this.count}),this.__defineGetter__("DataCodewords",function(){return this.dataCodewords})}function n(e,t,n){this.ecCodewordsPerBlock=e,this.ecBlocks=n?new Array(t,n):new Array(t),this.__defineGetter__("ECCodewordsPerBlock",function(){return this.ecCodewordsPerBlock}),this.__defineGetter__("TotalECCodewords",function(){return this.ecCodewordsPerBlock*this.NumBlocks}),this.__defineGetter__("NumBlocks",function(){for(var e=0,t=0;t6&&(t.setRegion(e-11,0,3,6),t.setRegion(0,e-11,6,3)),t},this.getECBlocksForLevel=function(e){return this.ecBlocks[e.ordinal()]}}function i(e,t,n,r,a,o,s,h,w){this.a11=e,this.a12=r,this.a13=s,this.a21=t,this.a22=a,this.a23=h,this.a31=n,this.a32=o,this.a33=w,this.transformPoints1=function(e){for(var t=e.length,n=this.a11,r=this.a12,i=this.a13,a=this.a21,o=this.a22,s=this.a23,h=this.a31,w=this.a32,f=this.a33,u=0;uMath.abs(n-e);if(i){var a=e;e=t,t=a,a=n,n=r,r=a}for(var o=Math.abs(n-e),s=Math.abs(r-t),h=-o>>1,w=t0){if(l==r)break;l+=w,h-=o}}var b=n-e,y=r-t;return Math.sqrt(b*b+y*y)},this.sizeOfBlackWhiteBlackRunBothWays=function(e,t,n,r){var i=this.sizeOfBlackWhiteBlackRun(e,t,n,r),a=1,o=e-(n-e);o<0?(a=e/(e-o),o=0):o>=A.width&&(a=(A.width-1-e)/(o-e),o=A.width-1);var s=Math.floor(t-(r-t)*a);return a=1,s<0?(a=t/(t-s),s=0):s>=A.height&&(a=(A.height-1-t)/(s-t),s=A.height-1),o=Math.floor(e+(o-e)*a),(i+=this.sizeOfBlackWhiteBlackRun(e,t,o,s))-1},this.calculateModuleSizeOneWay=function(e,t){var n=this.sizeOfBlackWhiteBlackRunBothWays(Math.floor(e.X),Math.floor(e.Y),Math.floor(t.X),Math.floor(t.Y)),r=this.sizeOfBlackWhiteBlackRunBothWays(Math.floor(t.X),Math.floor(t.Y),Math.floor(e.X),Math.floor(e.Y));return isNaN(n)?r/7:isNaN(r)?n/7:(n+r)/14},this.calculateModuleSize=function(e,t,n){return(this.calculateModuleSizeOneWay(e,t)+this.calculateModuleSizeOneWay(e,n))/2},this.distance=function(e,t){var n=e.X-t.X,r=e.Y-t.Y;return Math.sqrt(n*n+r*r)},this.computeDimension=function(e,t,n,r){var i=7+(Math.round(this.distance(e,t)/r)+Math.round(this.distance(e,n)/r)>>1);switch(3&i){case 0:i++;break;case 2:i--;break;case 3:throw"Error"}return i},this.findAlignmentInRegion=function(e,t,n,r){var i=Math.floor(r*e),a=Math.max(0,t-i),o=Math.min(A.width-1,t+i);if(o-a<3*e)throw"Error";var s=Math.max(0,n-i),h=Math.min(A.height-1,n+i);return new F(this.image,a,s,o-a,h-s,e,this.resultPointCallback).find()},this.createTransform=function(e,t,n,r,a){var o,s,h,w,f=a-3.5;return null!=r?(o=r.X,s=r.Y,h=w=f-3):(o=t.X-e.X+n.X,s=t.Y-e.Y+n.Y,h=w=f),i.quadrilateralToQuadrilateral(3.5,3.5,f,3.5,h,w,3.5,f,e.X,e.Y,t.X,t.Y,o,s,n.X,n.Y)},this.sampleGrid=function(t,n,r){return e.sampleGrid3(t,r,n)},this.processFinderPatternInfo=function(e){var t=e.TopLeft,n=e.TopRight,i=e.BottomLeft,o=this.calculateModuleSize(t,n,i);if(o<1)throw"Error";var s=this.computeDimension(t,n,i,o),h=r.getProvisionalVersionForDimension(s),w=h.DimensionForVersion-7,f=null;if(h.AlignmentPatternCenters.length>0)for(var u=n.X-t.X+i.X,d=n.Y-t.Y+i.Y,l=1-3/w,c=Math.floor(t.X+l*(u-t.X)),g=Math.floor(t.Y+l*(d-t.Y)),v=4;v<=16;v<<=1){f=this.findAlignmentInRegion(o,c,g,v);break}var m=this.createTransform(t,n,i,f,s);return new a(this.sampleGrid(this.image,m,s),null==f?new Array(i,t,n):new Array(i,t,n,f))},this.detect=function(){var e=(new D).findFinderPattern(this.image);return this.processFinderPatternInfo(e)}}e.checkAndNudgePoints=function(e,t){for(var n=A.width,r=A.height,i=!0,a=0;an||s<-1||s>r)throw"Error.checkAndNudgePoints ";i=!1,-1==o?(t[a]=0,i=!0):o==n&&(t[a]=n-1,i=!0),-1==s?(t[a+1]=0,i=!0):s==r&&(t[a+1]=r-1,i=!0)}i=!0;for(a=t.length-2;a>=0&&i;a-=2){o=Math.floor(t[a]),s=Math.floor(t[a+1]);if(o<-1||o>n||s<-1||s>r)throw"Error.checkAndNudgePoints ";i=!1,-1==o?(t[a]=0,i=!0):o==n&&(t[a]=n-1,i=!0),-1==s?(t[a+1]=0,i=!0):s==r&&(t[a+1]=r-1,i=!0)}},e.sampleGrid3=function(t,n,r){for(var i=new v(n),a=new Array(n<<1),o=0;o>1),a[w+1]=h;r.transformPoints1(a),e.checkAndNudgePoints(t,a);try{for(w=0;w>1,o)}}catch(e){throw"Error.checkAndNudgePoints"}}return i},e.sampleGridx=function(t,n,r,a,o,s,h,w,f,u,d,l,c,g,v,m,b,y){var C=i.quadrilateralToQuadrilateral(r,a,o,s,h,w,f,u,d,l,c,g,v,m,b,y);return e.sampleGrid3(t,n,C)},r.VERSION_DECODE_INFO=new Array(31892,34236,39577,42195,48118,51042,55367,58893,63784,68472,70749,76311,79154,84390,87683,92361,96236,102084,102881,110507,110734,117786,119615,126325,127568,133589,136944,141498,145311,150283,152622,158308,161089,167017),r.VERSIONS=new Array(new r(1,new Array,new n(7,new t(1,19)),new n(10,new t(1,16)),new n(13,new t(1,13)),new n(17,new t(1,9))),new r(2,new Array(6,18),new n(10,new t(1,34)),new n(16,new t(1,28)),new n(22,new t(1,22)),new n(28,new t(1,16))),new r(3,new Array(6,22),new n(15,new t(1,55)),new n(26,new t(1,44)),new n(18,new t(2,17)),new n(22,new t(2,13))),new r(4,new Array(6,26),new n(20,new t(1,80)),new n(18,new t(2,32)),new n(26,new t(2,24)),new n(16,new t(4,9))),new r(5,new Array(6,30),new n(26,new t(1,108)),new n(24,new t(2,43)),new n(18,new t(2,15),new t(2,16)),new n(22,new t(2,11),new t(2,12))),new r(6,new Array(6,34),new n(18,new t(2,68)),new n(16,new t(4,27)),new n(24,new t(4,19)),new n(28,new t(4,15))),new r(7,new Array(6,22,38),new n(20,new t(2,78)),new n(18,new t(4,31)),new n(18,new t(2,14),new t(4,15)),new n(26,new t(4,13),new t(1,14))),new r(8,new Array(6,24,42),new n(24,new t(2,97)),new n(22,new t(2,38),new t(2,39)),new n(22,new t(4,18),new t(2,19)),new n(26,new t(4,14),new t(2,15))),new r(9,new Array(6,26,46),new n(30,new t(2,116)),new n(22,new t(3,36),new t(2,37)),new n(20,new t(4,16),new t(4,17)),new n(24,new t(4,12),new t(4,13))),new r(10,new Array(6,28,50),new n(18,new t(2,68),new t(2,69)),new n(26,new t(4,43),new t(1,44)),new n(24,new t(6,19),new t(2,20)),new n(28,new t(6,15),new t(2,16))),new r(11,new Array(6,30,54),new n(20,new t(4,81)),new n(30,new t(1,50),new t(4,51)),new n(28,new t(4,22),new t(4,23)),new n(24,new t(3,12),new t(8,13))),new r(12,new Array(6,32,58),new n(24,new t(2,92),new t(2,93)),new n(22,new t(6,36),new t(2,37)),new n(26,new t(4,20),new t(6,21)),new n(28,new t(7,14),new t(4,15))),new r(13,new Array(6,34,62),new n(26,new t(4,107)),new n(22,new t(8,37),new t(1,38)),new n(24,new t(8,20),new t(4,21)),new n(22,new t(12,11),new t(4,12))),new r(14,new Array(6,26,46,66),new n(30,new t(3,115),new t(1,116)),new n(24,new t(4,40),new t(5,41)),new n(20,new t(11,16),new t(5,17)),new n(24,new t(11,12),new t(5,13))),new r(15,new Array(6,26,48,70),new n(22,new t(5,87),new t(1,88)),new n(24,new t(5,41),new t(5,42)),new n(30,new t(5,24),new t(7,25)),new n(24,new t(11,12),new t(7,13))),new r(16,new Array(6,26,50,74),new n(24,new t(5,98),new t(1,99)),new n(28,new t(7,45),new t(3,46)),new n(24,new t(15,19),new t(2,20)),new n(30,new t(3,15),new t(13,16))),new r(17,new Array(6,30,54,78),new n(28,new t(1,107),new t(5,108)),new n(28,new t(10,46),new t(1,47)),new n(28,new t(1,22),new t(15,23)),new n(28,new t(2,14),new t(17,15))),new r(18,new Array(6,30,56,82),new n(30,new t(5,120),new t(1,121)),new n(26,new t(9,43),new t(4,44)),new n(28,new t(17,22),new t(1,23)),new n(28,new t(2,14),new t(19,15))),new r(19,new Array(6,30,58,86),new n(28,new t(3,113),new t(4,114)),new n(26,new t(3,44),new t(11,45)),new n(26,new t(17,21),new t(4,22)),new n(26,new t(9,13),new t(16,14))),new r(20,new Array(6,34,62,90),new n(28,new t(3,107),new t(5,108)),new n(26,new t(3,41),new t(13,42)),new n(30,new t(15,24),new t(5,25)),new n(28,new t(15,15),new t(10,16))),new r(21,new Array(6,28,50,72,94),new n(28,new t(4,116),new t(4,117)),new n(26,new t(17,42)),new n(28,new t(17,22),new t(6,23)),new n(30,new t(19,16),new t(6,17))),new r(22,new Array(6,26,50,74,98),new n(28,new t(2,111),new t(7,112)),new n(28,new t(17,46)),new n(30,new t(7,24),new t(16,25)),new n(24,new t(34,13))),new r(23,new Array(6,30,54,74,102),new n(30,new t(4,121),new t(5,122)),new n(28,new t(4,47),new t(14,48)),new n(30,new t(11,24),new t(14,25)),new n(30,new t(16,15),new t(14,16))),new r(24,new Array(6,28,54,80,106),new n(30,new t(6,117),new t(4,118)),new n(28,new t(6,45),new t(14,46)),new n(30,new t(11,24),new t(16,25)),new n(30,new t(30,16),new t(2,17))),new r(25,new Array(6,32,58,84,110),new n(26,new t(8,106),new t(4,107)),new n(28,new t(8,47),new t(13,48)),new n(30,new t(7,24),new t(22,25)),new n(30,new t(22,15),new t(13,16))),new r(26,new Array(6,30,58,86,114),new n(28,new t(10,114),new t(2,115)),new n(28,new t(19,46),new t(4,47)),new n(28,new t(28,22),new t(6,23)),new n(30,new t(33,16),new t(4,17))),new r(27,new Array(6,34,62,90,118),new n(30,new t(8,122),new t(4,123)),new n(28,new t(22,45),new t(3,46)),new n(30,new t(8,23),new t(26,24)),new n(30,new t(12,15),new t(28,16))),new r(28,new Array(6,26,50,74,98,122),new n(30,new t(3,117),new t(10,118)),new n(28,new t(3,45),new t(23,46)),new n(30,new t(4,24),new t(31,25)),new n(30,new t(11,15),new t(31,16))),new r(29,new Array(6,30,54,78,102,126),new n(30,new t(7,116),new t(7,117)),new n(28,new t(21,45),new t(7,46)),new n(30,new t(1,23),new t(37,24)),new n(30,new t(19,15),new t(26,16))),new r(30,new Array(6,26,52,78,104,130),new n(30,new t(5,115),new t(10,116)),new n(28,new t(19,47),new t(10,48)),new n(30,new t(15,24),new t(25,25)),new n(30,new t(23,15),new t(25,16))),new r(31,new Array(6,30,56,82,108,134),new n(30,new t(13,115),new t(3,116)),new n(28,new t(2,46),new t(29,47)),new n(30,new t(42,24),new t(1,25)),new n(30,new t(23,15),new t(28,16))),new r(32,new Array(6,34,60,86,112,138),new n(30,new t(17,115)),new n(28,new t(10,46),new t(23,47)),new n(30,new t(10,24),new t(35,25)),new n(30,new t(19,15),new t(35,16))),new r(33,new Array(6,30,58,86,114,142),new n(30,new t(17,115),new t(1,116)),new n(28,new t(14,46),new t(21,47)),new n(30,new t(29,24),new t(19,25)),new n(30,new t(11,15),new t(46,16))),new r(34,new Array(6,34,62,90,118,146),new n(30,new t(13,115),new t(6,116)),new n(28,new t(14,46),new t(23,47)),new n(30,new t(44,24),new t(7,25)),new n(30,new t(59,16),new t(1,17))),new r(35,new Array(6,30,54,78,102,126,150),new n(30,new t(12,121),new t(7,122)),new n(28,new t(12,47),new t(26,48)),new n(30,new t(39,24),new t(14,25)),new n(30,new t(22,15),new t(41,16))),new r(36,new Array(6,24,50,76,102,128,154),new n(30,new t(6,121),new t(14,122)),new n(28,new t(6,47),new t(34,48)),new n(30,new t(46,24),new t(10,25)),new n(30,new t(2,15),new t(64,16))),new r(37,new Array(6,28,54,80,106,132,158),new n(30,new t(17,122),new t(4,123)),new n(28,new t(29,46),new t(14,47)),new n(30,new t(49,24),new t(10,25)),new n(30,new t(24,15),new t(46,16))),new r(38,new Array(6,32,58,84,110,136,162),new n(30,new t(4,122),new t(18,123)),new n(28,new t(13,46),new t(32,47)),new n(30,new t(48,24),new t(14,25)),new n(30,new t(42,15),new t(32,16))),new r(39,new Array(6,26,54,82,110,138,166),new n(30,new t(20,117),new t(4,118)),new n(28,new t(40,47),new t(7,48)),new n(30,new t(43,24),new t(22,25)),new n(30,new t(10,15),new t(67,16))),new r(40,new Array(6,30,58,86,114,142,170),new n(30,new t(19,118),new t(6,119)),new n(28,new t(18,47),new t(31,48)),new n(30,new t(34,24),new t(34,25)),new n(30,new t(20,15),new t(61,16)))),r.getVersionForNumber=function(e){if(e<1||e>40)throw"ArgumentException";return r.VERSIONS[e-1]},r.getProvisionalVersionForDimension=function(e){if(e%4!=1)throw"Error getProvisionalVersionForDimension";try{return r.getVersionForNumber(e-17>>2)}catch(e){throw"Error getVersionForNumber"}},r.decodeVersionInformation=function(e){for(var t=4294967295,n=0,i=0;i>3&3),this.dataMask=7&e,this.__defineGetter__("ErrorCorrectionLevel",function(){return this.errorCorrectionLevel}),this.__defineGetter__("DataMask",function(){return this.dataMask}),this.GetHashCode=function(){return this.errorCorrectionLevel.ordinal()<<3|this.dataMask},this.Equals=function(e){var t=e;return this.errorCorrectionLevel==t.errorCorrectionLevel&&this.dataMask==t.dataMask}}function f(e,t,n){this.ordinal_Renamed_Field=e,this.bits=t,this.name=n,this.__defineGetter__("Bits",function(){return this.bits}),this.__defineGetter__("Name",function(){return this.name}),this.ordinal=function(){return this.ordinal_Renamed_Field}}w.numBitsDiffering=function(e,t){return h[15&(e^=t)]+h[15&M(e,4)]+h[15&M(e,8)]+h[15&M(e,12)]+h[15&M(e,16)]+h[15&M(e,20)]+h[15&M(e,24)]+h[15&M(e,28)]},w.decodeFormatInformation=function(e){var t=w.doDecodeFormatInformation(e);return null!=t?t:w.doDecodeFormatInformation(21522^e)},w.doDecodeFormatInformation=function(e){for(var t=4294967295,n=0,r=0;r=g.length)throw"ArgumentException";return g[e]};var u=new f(0,1,"L"),d=new f(1,0,"M"),l=new f(2,3,"Q"),c=new f(3,2,"H"),g=new Array(d,u,c,l);function v(e,t){if(t||(t=e),e<1||t<1)throw"Both dimensions must be greater than 0";this.width=e,this.height=t;var n=e>>5;0!=(31&e)&&n++,this.rowSize=n,this.bits=new Array(n*t);for(var r=0;r>5);return 0!=(1&M(this.bits[n],31&e))},this.set_Renamed=function(e,t){var n=t*this.rowSize+(e>>5);this.bits[n]|=1<<(31&e)},this.flip=function(e,t){var n=t*this.rowSize+(e>>5);this.bits[n]^=1<<(31&e)},this.clear=function(){for(var e=this.bits.length,t=0;tthis.height||i>this.width)throw"The region must fit inside the matrix";for(var o=t;o>5)]|=1<<(31&h)}}function m(e,t){this.numDataCodewords=e,this.codewords=t,this.__defineGetter__("NumDataCodewords",function(){return this.numDataCodewords}),this.__defineGetter__("Codewords",function(){return this.codewords})}function b(e){var t=e.Dimension;if(t<21||1!=(3&t))throw"Error BitMatrixParser";this.bitMatrix=e,this.parsedVersion=null,this.parsedFormatInfo=null,this.copyBit=function(e,t,n){return this.bitMatrix.get_Renamed(e,t)?n<<1|1:n<<1},this.readFormatInformation=function(){if(null!=this.parsedFormatInfo)return this.parsedFormatInfo;for(var e=0,t=0;t<6;t++)e=this.copyBit(t,8,e);e=this.copyBit(7,8,e),e=this.copyBit(8,8,e),e=this.copyBit(8,7,e);for(var n=5;n>=0;n--)e=this.copyBit(8,n,e);if(this.parsedFormatInfo=w.decodeFormatInformation(e),null!=this.parsedFormatInfo)return this.parsedFormatInfo;var r=this.bitMatrix.Dimension;e=0;var i=r-8;for(t=r-1;t>=i;t--)e=this.copyBit(t,8,e);for(n=r-7;n>2;if(t<=6)return r.getVersionForNumber(t);for(var n=0,i=e-11,a=5;a>=0;a--)for(var o=e-9;o>=i;o--)n=this.copyBit(o,a,n);if(this.parsedVersion=r.decodeVersionInformation(n),null!=this.parsedVersion&&this.parsedVersion.DimensionForVersion==e)return this.parsedVersion;n=0;for(o=5;o>=0;o--)for(a=e-9;a>=i;a--)n=this.copyBit(o,a,n);if(this.parsedVersion=r.decodeVersionInformation(n),null!=this.parsedVersion&&this.parsedVersion.DimensionForVersion==e)return this.parsedVersion;throw"Error readVersion"},this.readCodewords=function(){var e=this.readFormatInformation(),t=this.readVersion(),n=y.forReference(e.DataMask),r=this.bitMatrix.Dimension;n.unmaskBitMatrix(this.bitMatrix,r);for(var i=t.buildFunctionPattern(),a=!0,o=new Array(t.TotalCodewords),s=0,h=0,w=0,f=r-1;f>0;f-=2){6==f&&f--;for(var u=0;u=0;){if(s[c].codewords.length==l)break;c--}c++;var g=l-r.ECCodewordsPerBlock,v=0;for(o=0;o1&&0==t[0]){for(var r=1;rr.length){var i=n;n=r,r=i}for(var a=new Array(r.length),o=r.length-n.length,s=0;s=e.Degree&&!n.Zero;){var a=n.Degree-e.Degree,o=this.field.multiply(n.getCoefficient(n.Degree),i),s=e.multiplyByMonomial(a,o),h=this.field.buildMonomial(a,o);t=t.addOrSubtract(h),n=n.addOrSubtract(s)}return new Array(t,n)}}function _(e){this.expTable=new Array(256),this.logTable=new Array(256);for(var t=1,n=0;n<256;n++)this.expTable[n]=t,(t<<=1)>=256&&(t^=e);for(n=0;n<255;n++)this.logTable[this.expTable[n]]=n;var r=new Array(1);r[0]=0,this.zero=new C(this,new Array(r));var i=new Array(1);i[0]=1,this.one=new C(this,new Array(i)),this.__defineGetter__("Zero",function(){return this.zero}),this.__defineGetter__("One",function(){return this.one}),this.buildMonomial=function(e,t){if(e<0)throw"System.ArgumentException";if(0==t)return this.zero;for(var n=new Array(e+1),r=0;r7)throw"System.ArgumentException";return y.DATA_MASKS[e]},y.DATA_MASKS=new Array(new function(){this.unmaskBitMatrix=function(e,t){for(var n=0;n=Math.floor(n/2);){var f=i,u=o,d=h;if(o=s,h=w,(i=a).Zero)throw"r_{i-1} was zero";a=f;for(var l=this.field.Zero,c=i.getCoefficient(i.Degree),g=this.field.inverse(c);a.Degree>=i.Degree&&!a.Zero;){var v=a.Degree-i.Degree,m=this.field.multiply(a.getCoefficient(a.Degree),g);l=l.addOrSubtract(this.field.buildMonomial(v,m)),a=a.addOrSubtract(i.multiplyByMonomial(v,m))}s=l.multiply1(o).addOrSubtract(u),w=l.multiply1(h).addOrSubtract(d)}var b=w.getCoefficient(0);if(0==b)throw"ReedSolomonException sigmaTilde(0) was zero";var y=this.field.inverse(b),C=w.multiply2(y),_=a.multiply2(y);return new Array(C,_)},this.findErrorLocations=function(e){var t=e.Degree;if(1==t)return new Array(e.getCoefficient(1));for(var n=new Array(t),r=0,i=1;i<256&&r=0?e>>t:(e>>t)+(2<<~t)}A.imagedata=null,A.width=0,A.height=0,A.qrCodeSymbol=null,A.debug=!1,A.maxImgSize=1048576,A.sizeOfDataLengthInfo=[[10,9,8,8],[12,11,16,10],[14,13,16,12]],A.callback=null,A.vidSuccess=function(e){A.localstream=e,A.webkit?A.video.src=window.webkitURL.createObjectURL(e):A.moz?(A.video.mozSrcObject=e,A.video.play()):A.video.src=e,A.gUM=!0,A.canvas_qr2=document.createElement("canvas"),A.canvas_qr2.id="qr-canvas",A.qrcontext2=A.canvas_qr2.getContext("2d"),A.canvas_qr2.width=A.video.videoWidth,A.canvas_qr2.height=A.video.videoHeight,setTimeout(A.captureToCanvas,500)},A.vidError=function(e){A.gUM=!1},A.captureToCanvas=function(){if(A.gUM)try{if(0==A.video.videoWidth)return void setTimeout(A.captureToCanvas,500);A.canvas_qr2.width=A.video.videoWidth,A.canvas_qr2.height=A.video.videoHeight,A.qrcontext2.drawImage(A.video,0,0);try{A.decode()}catch(e){console.log(e),setTimeout(A.captureToCanvas,500)}}catch(e){console.log(e),setTimeout(A.captureToCanvas,500)}},A.setWebcam=function(e){var t=navigator;A.video=document.getElementById(e);var n=!0;if(navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices)try{navigator.mediaDevices.enumerateDevices().then(function(e){e.forEach(function(e){console.log("deb1"),"videoinput"===e.kind&&e.label.toLowerCase().search("back")>-1&&(n=[{sourceId:e.deviceId}]),console.log(e.kind+": "+e.label+" id = "+e.deviceId)})})}catch(e){console.log(e)}else console.log("no navigator.mediaDevices.enumerateDevices");t.getUserMedia?t.getUserMedia({video:n,audio:!1},A.vidSuccess,A.vidError):t.webkitGetUserMedia?(A.webkit=!0,t.webkitGetUserMedia({video:n,audio:!1},A.vidSuccess,A.vidError)):t.mozGetUserMedia&&(A.moz=!0,t.mozGetUserMedia({video:n,audio:!1},A.vidSuccess,A.vidError))},A.decode=function(e){if(0==arguments.length){if(A.canvas_qr2)var t=A.canvas_qr2,n=A.qrcontext2;else n=(t=document.getElementById("qr-canvas")).getContext("2d");return A.width=t.width,A.height=t.height,A.imagedata=n.getImageData(0,0,A.width,A.height),A.result=A.process(n),null!=A.callback&&A.callback(A.result),A.result}var r=new Image;r.crossOrigin="Anonymous",r.onload=function(){var e=document.getElementById("out-canvas");if(null!=e){var t=e.getContext("2d");t.clearRect(0,0,320,240),t.drawImage(r,0,0,320,240)}var n=document.createElement("canvas"),i=n.getContext("2d"),a=r.height,o=r.width;if(r.width*r.height>A.maxImgSize){var s=r.width/r.height;o=s*(a=Math.sqrt(A.maxImgSize/s))}n.width=o,n.height=a,i.drawImage(r,0,0,n.width,n.height),A.width=n.width,A.height=n.height;try{A.imagedata=i.getImageData(0,0,n.width,n.height)}catch(e){return A.result="Cross domain image reading not supported in your browser! Save it to your computer then drag and drop the file!",void(null!=A.callback&&A.callback(A.result))}try{A.result=A.process(i)}catch(e){console.log(e),A.result="error decoding QR Code"}null!=A.callback&&A.callback(A.result)},r.onerror=function(){null!=A.callback&&A.callback("Failed to load the image")},r.src=e},A.isUrl=function(e){return/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(e)},A.decode_url=function(e){var t="";try{t=escape(e)}catch(n){console.log(n),t=e}var n="";try{n=decodeURIComponent(t)}catch(e){console.log(e),n=t}return n},A.decode_utf8=function(e){return A.isUrl(e)?A.decode_url(e):e},A.process=function(e){var t=(new Date).getTime(),n=A.grayScaleToBitmap(A.grayscale());if(A.debug){for(var r=0;rr[s][o][1]&&(r[s][o][1]=f)}}for(var u=new Array(4),d=0;d<4;d++)u[d]=new Array(4);for(o=0;o<4;o++)for(s=0;s<4;s++)u[s][o]=Math.floor((r[s][o][0]+r[s][o][1])/2);return u},A.grayScaleToBitmap=function(e){for(var t=A.getMiddleBrightnessPerArea(e),n=t.length,r=Math.floor(A.width/n),i=Math.floor(A.height/n),a=new ArrayBuffer(A.width*A.height),o=new Uint8Array(a),s=0;s=0&&i[t+s*A.width];)o[2]++,s--;if(s<0)return NaN;for(;s>=0&&!i[t+s*A.width]&&o[1]<=n;)o[1]++,s--;if(s<0||o[1]>n)return NaN;for(;s>=0&&i[t+s*A.width]&&o[0]<=n;)o[0]++,s--;if(o[0]>n)return NaN;for(s=e+1;s=n)return NaN;for(;s=n)return NaN;var h=o[0]+o[1]+o[2]+o[3]+o[4];return 5*Math.abs(h-r)>=2*r?NaN:this.foundPatternCross(o)?this.centerFromEnd(o,s):NaN},this.crossCheckHorizontal=function(e,t,n,r){for(var i=this.image,a=A.width,o=this.CrossCheckStateCount,s=e;s>=0&&i[s+t*A.width];)o[2]++,s--;if(s<0)return NaN;for(;s>=0&&!i[s+t*A.width]&&o[1]<=n;)o[1]++,s--;if(s<0||o[1]>n)return NaN;for(;s>=0&&i[s+t*A.width]&&o[0]<=n;)o[0]++,s--;if(o[0]>n)return NaN;for(s=e+1;s=n)return NaN;for(;s=n)return NaN;var h=o[0]+o[1]+o[2]+o[3]+o[4];return 5*Math.abs(h-r)>=r?NaN:this.foundPatternCross(o)?this.centerFromEnd(o,s):NaN},this.handlePossibleCenter=function(e,t,n){var r=e[0]+e[1]+e[2]+e[3]+e[4],i=this.centerFromEnd(e,n),a=this.crossCheckVertical(t,Math.floor(i),e[2],r);if(!isNaN(a)&&(i=this.crossCheckHorizontal(Math.floor(i),Math.floor(a),e[2],r),!isNaN(i))){for(var o=r/7,s=!1,h=this.possibleCenters.length,w=0;w3){for(var t=0,n=0,r=0;r=0;r--){var h=this.possibleCenters[r];Math.abs(h.EstimatedModuleSize-a)>s&&this.possibleCenters.splice(r,1)}}return this.possibleCenters.length>3&&this.possibleCenters.sort(function(e,t){return e.count>t.count?-1:e.count=B){if(null!=t)return this.hasSkipped=!0,Math.floor((Math.abs(t.X-r.X)-Math.abs(t.Y-r.Y))/2);t=r}}return 0},this.haveMultiplyConfirmedCenters=function(){for(var e=0,t=0,n=this.possibleCenters.length,r=0;r=B&&(e++,t+=i.EstimatedModuleSize)}if(e<3)return!1;var a=t/n,o=0;for(r=0;ra[2]&&(o+=w-a[2]-r,h=n-1)}else{do{h++}while(h=n)return!1;return!0},this.crossCheckVertical=function(e,t,n,r){var i=this.image,a=A.height,o=this.crossCheckStateCount;o[0]=0,o[1]=0,o[2]=0;for(var s=e;s>=0&&i[t+s*A.width]&&o[1]<=n;)o[1]++,s--;if(s<0||o[1]>n)return NaN;for(;s>=0&&!i[t+s*A.width]&&o[0]<=n;)o[0]++,s--;if(o[0]>n)return NaN;for(s=e+1;sn)return NaN;for(;sn)return NaN;var h=o[0]+o[1]+o[2];return 5*Math.abs(h-r)>=2*r?NaN:this.foundPatternCross(o)?this.centerFromEnd(o,s):NaN},this.handlePossibleCenter=function(e,t,n){var r=e[0]+e[1]+e[2],i=this.centerFromEnd(e,n),a=this.crossCheckVertical(t,Math.floor(i),2*e[1],r);if(!isNaN(a)){for(var o=(e[0]+e[1]+e[2])/3,s=this.possibleCenters.length,h=0;h>1),s=new Array(0,0,0),h=0;h>1:-(h+1>>1));s[0]=0,s[1]=0,s[2]=0;for(var f=t;f=10&&t<=26?this.dataLengthMode=1:t>=27&&t<=40&&(this.dataLengthMode=2),this.getNextBits=function(e){var t=0;if(e>this.bitPointer-e+1,this.bitPointer-=e,t}if(e>8-(e-(this.bitPointer+1)),this.bitPointer=this.bitPointer-e%8,this.bitPointer<0&&(this.bitPointer=8+this.bitPointer),t}if(e>8-(e-(this.bitPointer+1+8))),this.bitPointer=this.bitPointer-(e-8)%8,this.bitPointer<0&&(this.bitPointer=8+this.bitPointer),t}return 0},this.NextMode=function(){return this.blockPointer>this.blocks.length-this.numErrorCorrectionCode-2?0:this.getNextBits(4)},this.getDataLength=function(e){for(var t=0;e>>t!=1;)t++;return this.getNextBits(A.sizeOfDataLengthInfo[this.dataLengthMode][t])},this.getRomanAndFigureString=function(e){var t=e,n=0,r="",i=new Array("0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"," ","$","%","*","+","-",".","/",":");do{if(t>1){var a=(n=this.getNextBits(11))%45;r+=i[Math.floor(n/45)],r+=i[a],t-=2}else 1==t&&(r+=i[n=this.getNextBits(6)],t-=1)}while(t>0);return r},this.getFigureString=function(e){var t=e,n=0,r="";do{t>=3?((n=this.getNextBits(10))<100&&(r+="0"),n<10&&(r+="0"),t-=3):2==t?((n=this.getNextBits(7))<10&&(r+="0"),t-=2):1==t&&(n=this.getNextBits(4),t-=1),r+=n}while(t>0);return r},this.get8bitByteArray=function(e){var t=e,n=0,r=new Array;do{n=this.getNextBits(8),r.push(n),t--}while(t>0);return r},this.getKanjiString=function(e){var t=e,n=0,r="";do{var i=((n=this.getNextBits(13))/192<<8)+n%192,a=0;a=i+33088<=40956?i+33088:i+49472,r+=String.fromCharCode(a),t--}while(t>0);return r},this.parseECIValue=function(){var e=0,t=this.getNextBits(8);(0==(128&t)&&(e=127&t),128==(192&t))&&(e=(63&t)<<8|this.getNextBits(8));192==(224&t)&&(e=(31&t)<<16|this.getNextBits(8));return e},this.__defineGetter__("DataByte",function(){for(var e=new Array;;){var t=this.NextMode();if(0==t){if(e.length>0)break;throw"Empty data block"}if(1!=t&&2!=t&&4!=t&&8!=t&&7!=t)throw"Invalid mode: "+t+" in (block:"+this.blockPointer+" bit:"+this.bitPointer+")";if(7==t)var n=this.parseECIValue();else{var r=this.getDataLength(t);if(r<1)throw"Invalid data length: "+r;switch(t){case 1:for(var i=this.getFigureString(r),a=new Array(i.length),o=0;o=a&&o>=s?(r=e[0],n=e[1],i=e[2]):s>=o&&s>=a?(r=e[1],n=e[0],i=e[2]):(r=e[2],n=e[0],i=e[1]),function(e,t,n){var r=t.x,i=t.y;return(n.x-r)*(e.y-i)-(n.y-i)*(e.x-r)}(n,r,i)<0){var h=n;n=i,i=h}e[0]=n,e[1]=r,e[2]=i},A} + +/** Html5Qrcode From here */ +"use strict";function _typeof(a){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},_typeof(a)}function _classCallCheck(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function _defineProperties(a,b){for(var c,d=0;dk)throw"'config.qrbox' should not be greater than the width of the HTML element."}var m=function(a,b){var c=h.qrbox;c>b&&console.warn("[Html5Qrcode] config.qrboxsize is greater than video height. Shading will be ignored");var d=i&&c<=b,e=d?f._getShadedRegionBounds(a,b,c):{x:0,y:0,width:a,height:b},k=f._createCanvasElement(e.width,e.height),l=k.getContext("2d");l.canvas.width=e.width,l.canvas.height=e.height,j.append(k),d&&f._possiblyInsertShadingElement(j,b,e),g._qrRegion=e,g._context=l,g._canvasElement=k},n=function(){try{return g.qrcode.decode(),f._possiblyUpdateShaders(!0),!0}catch(a){return f._possiblyUpdateShaders(!1),e("QR code parse error, error = ".concat(a)),!1}},o=function b(){if(g._shouldScan){if(g._localMediaStream){var c=g._videoElement,d=c.videoWidth/c.clientWidth,e=c.videoHeight/c.clientHeight,i=g._qrRegion.width*d,j=g._qrRegion.height*e,k=g._qrRegion.x*d,l=g._qrRegion.y*e;g._context.drawImage(g._videoElement,k,l,i,j,0,0,g._qrRegion.width,g._qrRegion.height),n()||!0===h.disableFlip||(f._context.translate(f._context.canvas.width,0),f._context.scale(-1,1),n())}g._foreverScanTimeout=setTimeout(b,a._getTimeoutFps(h.fps))}},p=function(a){return new Promise(function(b,c){var d=function(){var d=f._createVideoElement(k);g._element.append(d),d.onabort=c,d.onerror=c,d.onplaying=function(){var a=d.clientWidth,c=d.clientHeight;m(a,c),o(),b()},d.srcObject=a,d.play(),g._videoElement=d};if(g._localMediaStream=a,!h.aspectRatio)d();else{var e={aspectRatio:h.aspectRatio},i=a.getVideoTracks()[0];i.applyConstraints(e).then(function(){return d()})["catch"](function(a){console.log("[Warning] [Html5Qrcode] Constriants could not be satisfied, ignoring constraints",a),d()})}})};return new Promise(function(a,c){if(navigator.mediaDevices&&navigator.mediaDevices.getUserMedia){var d=g._createVideoConstraints(b);navigator.mediaDevices.getUserMedia({audio:!1,video:d}).then(function(b){p(b).then(function(){g._isScanning=!0,a()})["catch"](c)})["catch"](function(a){c("Error getting userMedia, error = ".concat(a))})}else if(navigator.getUserMedia){if("string"!=typeof b)throw"The device doesn't support navigator.mediaDevices, only supported cameraIdOrConfig in this case is deviceId parameter (string).";navigator.getUserMedia({video:{optional:[{sourceId:b}]}},function(b){p(b).then(function(){g._isScanning=!0,a()})["catch"](c)},function(a){c("Error getting userMedia, error = ".concat(a))})}else c("Web camera streaming not supported by the browser.")})}},{key:"stop",value:function(){this._shouldScan=!1,clearTimeout(this._foreverScanTimeout);var b=this;return new Promise(function(c){b.qrcode.callback=null;var d=b._localMediaStream.getVideoTracks().length,e=0,f=function(){for(;b._element.getElementsByClassName(a.SHADED_REGION_CLASSNAME).length;){var c=b._element.getElementsByClassName(a.SHADED_REGION_CLASSNAME)[0];b._element.removeChild(c)}},g=function(){b._localMediaStream=null,b._element.removeChild(b._videoElement),b._element.removeChild(b._canvasElement),f(),b._isScanning=!1,b._qrRegion&&(b._qrRegion=null),b._context&&(b._context=null),c(!0)};b._localMediaStream.getVideoTracks().forEach(function(a){a.stop(),++e,e>=d&&g()})})}},{key:"scanFile",value:function(b,c){var d=this;if(!b||!(b instanceof File))throw"imageFile argument is mandatory and should be instance of File. Use 'event.target.files[0]'";if(c=void 0===c||c,d._isScanning)throw"Close ongoing scan before scanning a file.";var e=function b(c,d,e,f){if(c<=e&&d<=f){var g=(e-c)/2,h=(f-d)/2;return{x:g,y:h,width:c,height:d}}var i=c,j=d;return c>e&&(d=e/c*d,c=e),d>f&&(c=f/d*c,d=f),a._log("Image downsampled from "+"".concat(i,"X").concat(j)+" to ".concat(c,"X").concat(d,".")),b(c,d,e,f)};return new Promise(function(f,g){d._possiblyCloseLastScanImageFile(),d._clearElement(),d._lastScanImageFile=b;var h=new Image;h.onload=function(){var b=Math.max,i=h.width,j=h.height,k=document.getElementById(d._elementId),l=k.clientWidth?k.clientWidth:a.DEFAULT_WIDTH,m=b(k.clientHeight?k.clientHeight:j,a.FILE_SCAN_MIN_HEIGHT),n=e(i,j,l,m);if(c){var o=d._createCanvasElement(l,m,"qr-canvas-visible");o.style.display="inline-block",k.appendChild(o);var p=o.getContext("2d");p.canvas.width=l,p.canvas.height=m,p.drawImage(h,0,0,i,j,n.x,n.y,n.width,n.height)}var q=d._createCanvasElement(n.width,n.height);k.appendChild(q);var r=q.getContext("2d");r.canvas.width=n.width,r.canvas.height=n.height,r.drawImage(h,0,0,i,j,0,0,n.width,n.height);try{f(d.qrcode.decode())}catch(a){g("QR code parse error, error = ".concat(a))}},h.onerror=g,h.onabort=g,h.onstalled=g,h.onsuspend=g,h.src=URL.createObjectURL(b)})}},{key:"clear",value:function(){this._clearElement()}},{key:"_clearElement",value:function(){if(this._isScanning)throw"Cannot clear while scan is ongoing, close it first.";var a=document.getElementById(this._elementId);a.innerHTML=""}},{key:"_createCanvasElement",value:function(a,b,c){var d=document.createElement("canvas");return d.style.width="".concat(a,"px"),d.style.height="".concat(b,"px"),d.style.display="none",d.id=null==c?"qr-canvas":c,d}},{key:"_createVideoElement",value:function(a){var b=document.createElement("video");return b.style.width="".concat(a,"px"),b.muted=!0,b.playsInline=!0,b}},{key:"_getShadedRegionBounds",value:function(a,b,c){if(c>a||c>b)throw"'config.qrbox' should not be greater than the width and height of the HTML element.";return{x:(a-c)/2,y:(b-c)/2,width:c,height:c}}},{key:"_possiblyInsertShadingElement",value:function(b,c,d){var e=this;if(0!=d.x||0!=d.y){var f={};f[a.SHADED_LEFT]=this._createShadedElement(c,d,a.SHADED_LEFT),f[a.SHADED_RIGHT]=this._createShadedElement(c,d,a.SHADED_RIGHT),f[a.SHADED_TOP]=this._createShadedElement(c,d,a.SHADED_TOP),f[a.SHADED_BOTTOM]=this._createShadedElement(c,d,a.SHADED_BOTTOM),Object.keys(f).forEach(function(a){return b.append(f[a])}),10>d.x||10>d.y?this.hasBorderShaders=!1:(Object.keys(f).forEach(function(a){return e._insertShaderBorders(f[a],d,a)}),this.hasBorderShaders=!0)}}},{key:"_createShadedElement",value:function(b,c,d){var e=document.createElement("div");switch(e.style.position="absolute",e.style.height="".concat(b,"px"),e.className=a.SHADED_REGION_CLASSNAME,e.id="".concat(a.SHADED_REGION_CLASSNAME,"_").concat(d),e.style.background="#0000007a",d){case a.SHADED_LEFT:e.style.top="0px",e.style.left="0px",e.style.width="".concat(c.x,"px"),e.style.height="".concat(b,"px");break;case a.SHADED_RIGHT:e.style.top="0px",e.style.right="0px",e.style.width="".concat(c.x,"px"),e.style.height="".concat(b,"px");break;case a.SHADED_TOP:e.style.top="0px",e.style.left="".concat(c.x,"px"),e.style.width="".concat(c.width,"px"),e.style.height="".concat(c.y,"px");break;case a.SHADED_BOTTOM:var f=c.y+c.height;e.style.top="".concat(f,"px"),e.style.left="".concat(c.x,"px"),e.style.width="".concat(c.width,"px"),e.style.height="".concat(c.y,"px");break;default:throw"Unsupported shadingPosition";}return e}},{key:"_insertShaderBorders",value:function(b,c,d){d=parseInt(d);var e=this,f=5,g=5,h=40,i=function(){var b=document.createElement("div");switch(b.style.position="absolute",b.style.backgroundColor=a.BORDER_SHADER_DEFAULT_COLOR,d){case a.SHADED_LEFT:case a.SHADED_RIGHT:b.style.width="".concat(g,"px"),b.style.height="".concat(h+f,"px");break;case a.SHADED_TOP:case a.SHADED_BOTTOM:b.style.width="".concat(h+f,"px"),b.style.height="".concat(g,"px");break;default:throw"Unsupported shadingPosition";}return b},j=function(a,c){if(null===a||null===c)throw"Shaders should have defined positions";var d=i();d.style.top="".concat(a,"px"),d.style.left="".concat(c,"px"),b.appendChild(d),e.borderShaders||(e.borderShaders=[]),e.borderShaders.push(d)},k=null,l=null,m=null,n=null;switch(d){case a.SHADED_LEFT:k=c.y-f,l=c.x-g,m=c.y+c.height-h,n=l;break;case a.SHADED_RIGHT:k=c.y-f,l=0,m=c.y+c.height-h,n=l;break;case a.SHADED_TOP:k=c.y-f,l=-g,m=k,n=c.width-h;break;case a.SHADED_BOTTOM:k=0,l=-g,m=k,n=c.width-h;break;default:throw"Unsupported shadingPosition";}j(k,l),j(m,n)}},{key:"_possiblyUpdateShaders",value:function(b){this.qrMatch===b||(this.hasBorderShaders&&this.borderShaders&&this.borderShaders.length&&this.borderShaders.forEach(function(c){c.style.backgroundColor=b?a.BORDER_SHADER_MATCH_COLOR:a.BORDER_SHADER_DEFAULT_COLOR}),this.qrMatch=b)}},{key:"_possiblyCloseLastScanImageFile",value:function(){this._lastScanImageFile&&(URL.revokeObjectURL(this._lastScanImageFile),this._lastScanImageFile=null)}},{key:"_createVideoConstraints",value:function(a){if("string"==typeof a)return{deviceId:{exact:a}};if("object"==_typeof(a)){var b={user:!0,environment:!0},c=function(a){if(a in b)return!0;throw"config has invalid 'facingMode' value = "+"'".concat(a,"'")},d=Object.keys(a);if(1!=d.length)throw"'cameraIdOrConfig' object should have exactly 1 key,"+" if passed as an object, found ".concat(d.length," keys");var e=Object.keys(a)[0];if("facingMode"!=e&&"deviceId"!=e)throw"Only '".concat("facingMode","' and '").concat("deviceId","' ")+" are supported for 'cameraIdOrConfig'";if("facingMode"==e){var f=a[e];if("string"==typeof f){if(c(f))return{facingMode:f};}else if("object"!=_typeof(f)){var g=_typeof(f);throw"Invalid type of 'facingMode' = ".concat(g)}else if(!("exact"in f))throw"'facingMode' should be string or object with"+" ".concat("exact"," as key.");else if(c(f.exact))return{facingMode:{exact:f.exact}}}else{var h=a[e];if("string"==typeof h)return{deviceId:h};if("object"==_typeof(h)){if("exact"in h)return{deviceId:{exact:h.exact}};throw"'deviceId' should be string or object with"+" ".concat("exact"," as key.")}else{var i=_typeof(h);throw"Invalid type of 'deviceId' = ".concat(i)}}}else{var j=_typeof(a);throw"Invalid type of 'cameraIdOrConfig' = ".concat(j)}}}],[{key:"getCameras",value:function(){var a=this;return new Promise(function(b,c){if(navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices&&navigator.mediaDevices.getUserMedia)a._log("navigator.mediaDevices used"),navigator.mediaDevices.getUserMedia({audio:!1,video:!0}).then(function(d){d.oninactive=function(){return a._log("All streams closed")};var e=function(a){for(var b,c=a.getVideoTracks(),d=0;d",c.appendChild(b.cameraScanImage)},this.cameraScanImage.width=64,this.cameraScanImage.style.opacity=.3,this.cameraScanImage.src=a.ASSET_CAMERA_SCAN)}},{key:"__insertFileScanImageToScanRegion",value:function(){var b=this,c=document.getElementById(this.__getScanRegionId());return this.fileScanImage?(c.innerHTML="
",void c.appendChild(this.fileScanImage)):void(this.fileScanImage=new Image,this.fileScanImage.onload=function(){c.innerHTML="
",c.appendChild(b.fileScanImage)},this.fileScanImage.width=64,this.fileScanImage.style.opacity=.3,this.fileScanImage.src=a.ASSET_FILE_SCAN)}},{key:"__clearScanRegion",value:function(){var a=document.getElementById(this.__getScanRegionId());a.innerHTML=""}},{key:"__getDashboardSectionId",value:function(){return"".concat(this.elementId,"__dashboard_section")}},{key:"__getDashboardSectionCameraScanRegionId",value:function(){return"".concat(this.elementId,"__dashboard_section_csr")}},{key:"__getDashboardSectionFileScanRegionId",value:function(){return"".concat(this.elementId,"__dashboard_section_fsr")}},{key:"__getDashboardSectionSwapLinkId",value:function(){return"".concat(this.elementId,"__dashboard_section_swaplink")}},{key:"__getScanRegionId",value:function(){return"".concat(this.elementId,"__scan_region")}},{key:"__getDashboardId",value:function(){return"".concat(this.elementId,"__dashboard")}},{key:"__getFileScanInputId",value:function(){return"".concat(this.elementId,"__filescan_input")}},{key:"__getStatusSpanId",value:function(){return"".concat(this.elementId,"__status_span")}},{key:"__getHeaderMessageContainerId",value:function(){return"".concat(this.elementId,"__header_message")}},{key:"__getCameraSelectionId",value:function(){return"".concat(this.elementId,"__camera_selection")}},{key:"__getCameraScanRegion",value:function(){return document.getElementById(this.__getDashboardSectionCameraScanRegionId())}},{key:"__getFileScanRegion",value:function(){return document.getElementById(this.__getDashboardSectionFileScanRegionId())}},{key:"__getFileScanInput",value:function(){return document.getElementById(this.__getFileScanInputId())}},{key:"__getDashboardSectionSwapLink",value:function(){return document.getElementById(this.__getDashboardSectionSwapLinkId())}}]),a}();_defineProperty(Html5QrcodeScanner,"SCAN_TYPE_CAMERA","SCAN_TYPE_CAMERA"),_defineProperty(Html5QrcodeScanner,"SCAN_TYPE_FILE","SCAN_TYPE_FILE"),_defineProperty(Html5QrcodeScanner,"STATUS_SUCCESS","STATUS_SUCCESS"),_defineProperty(Html5QrcodeScanner,"STATUS_WARNING","STATUS_WARNING"),_defineProperty(Html5QrcodeScanner,"STATUS_DEFAULT","STATUS_DEFAULT"),_defineProperty(Html5QrcodeScanner,"ASSET_FILE_SCAN","https://raw.githubusercontent.com/mebjas/html5-qrcode/master/assets/file-scan.gif"),_defineProperty(Html5QrcodeScanner,"ASSET_CAMERA_SCAN","https://raw.githubusercontent.com/mebjas/html5-qrcode/master/assets/camera-scan.gif"); \ No newline at end of file diff --git a/scripts/qrcode.min.js b/scripts/qrcode.min.js new file mode 100644 index 0000000..993e88f --- /dev/null +++ b/scripts/qrcode.min.js @@ -0,0 +1 @@ +var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j=0?p.get(q):0}}for(var r=0,m=0;mm;m++)for(var j=0;jm;m++)for(var j=0;j=0;)b^=f.G15<=0;)b^=f.G18<>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;cf;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=[''],h=0;d>h;h++){g.push("");for(var i=0;d>i;i++)g.push('');g.push("")}g.push("
"),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}(); \ No newline at end of file diff --git a/scripts/std_op.js b/scripts/std_op.js new file mode 100644 index 0000000..837cd19 --- /dev/null +++ b/scripts/std_op.js @@ -0,0 +1,9521 @@ +(typeof global !== "undefined" ? global : window).cryptocoin = floGlobals.blockchain; +/* Util Libraries required for Standard operations + All credits for these codes belong to their respective creators, moderators and owners. + For more info on licence for these codes, visit respective source. +*/ +'use strict'; +//Crypto.js +(function(GLOBAL) { + // Global Crypto object + var Crypto = GLOBAL.Crypto = {}; + /*! + * Crypto-JS v2.5.4 Crypto.js + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2009-2013, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ + (function() { + + var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + // Crypto utilities + var util = Crypto.util = { + + // Bit-wise rotate left + rotl: function(n, b) { + return (n << b) | (n >>> (32 - b)); + }, + + // Bit-wise rotate right + rotr: function(n, b) { + return (n << (32 - b)) | (n >>> b); + }, + + // Swap big-endian to little-endian and vice versa + endian: function(n) { + + // If number given, swap endian + if (n.constructor == Number) { + return util.rotl(n, 8) & 0x00FF00FF | + util.rotl(n, 24) & 0xFF00FF00; + } + + // Else, assume array and swap all items + for (var i = 0; i < n.length; i++) + n[i] = util.endian(n[i]); + return n; + + }, + + // Generate an array of any length of random bytes + randomBytes: function(n) { + for (var bytes = []; n > 0; n--) + bytes.push(Math.floor(Math.random() * 256)); + return bytes; + }, + + // Convert a byte array to big-endian 32-bit words + bytesToWords: function(bytes) { + for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8) + words[b >>> 5] |= (bytes[i] & 0xFF) << (24 - b % 32); + return words; + }, + + // Convert big-endian 32-bit words to a byte array + wordsToBytes: function(words) { + for (var bytes = [], b = 0; b < words.length * 32; b += 8) + bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF); + return bytes; + }, + + // Convert a byte array to a hex string + bytesToHex: function(bytes) { + for (var hex = [], i = 0; i < bytes.length; i++) { + hex.push((bytes[i] >>> 4).toString(16)); + hex.push((bytes[i] & 0xF).toString(16)); + } + return hex.join(""); + }, + + // Convert a hex string to a byte array + hexToBytes: function(hex) { + for (var bytes = [], c = 0; c < hex.length; c += 2) + bytes.push(parseInt(hex.substr(c, 2), 16)); + return bytes; + }, + + // Convert a byte array to a base-64 string + bytesToBase64: function(bytes) { + for (var base64 = [], i = 0; i < bytes.length; i += 3) { + var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]; + for (var j = 0; j < 4; j++) { + if (i * 8 + j * 6 <= bytes.length * 8) + base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F)); + else base64.push("="); + } + } + + return base64.join(""); + }, + + // Convert a base-64 string to a byte array + base64ToBytes: function(base64) { + // Remove non-base-64 characters + base64 = base64.replace(/[^A-Z0-9+\/]/ig, ""); + + for (var bytes = [], i = 0, imod4 = 0; i < base64.length; imod4 = ++i % 4) { + if (imod4 == 0) continue; + bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2)) | + (base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2))); + } + + return bytes; + } + + }; + + // Crypto character encodings + var charenc = Crypto.charenc = {}; + + // UTF-8 encoding + var UTF8 = charenc.UTF8 = { + + // Convert a string to a byte array + stringToBytes: function(str) { + return Binary.stringToBytes(unescape(encodeURIComponent(str))); + }, + + // Convert a byte array to a string + bytesToString: function(bytes) { + return decodeURIComponent(escape(Binary.bytesToString(bytes))); + } + + }; + + // Binary encoding + var Binary = charenc.Binary = { + + // Convert a string to a byte array + stringToBytes: function(str) { + for (var bytes = [], i = 0; i < str.length; i++) + bytes.push(str.charCodeAt(i) & 0xFF); + return bytes; + }, + + // Convert a byte array to a string + bytesToString: function(bytes) { + for (var str = [], i = 0; i < bytes.length; i++) + str.push(String.fromCharCode(bytes[i])); + return str.join(""); + } + + }; + + })(); + //Adding SHA1 to fix basic PKBDF2 + /* + * Crypto-JS v2.5.4 + * http://code.google.com/p/crypto-js/ + * (c) 2009-2012 by Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ + (function() { + + // Shortcuts + var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8, + Binary = charenc.Binary; + + // Public API + var SHA1 = C.SHA1 = function(message, options) { + var digestbytes = util.wordsToBytes(SHA1._sha1(message)); + return options && options.asBytes ? digestbytes : + options && options.asString ? Binary.bytesToString(digestbytes) : + util.bytesToHex(digestbytes); + }; + + // The core + SHA1._sha1 = function(message) { + + // Convert to byte array + if (message.constructor == String) message = UTF8.stringToBytes(message); + /* else, assume byte array already */ + + var m = util.bytesToWords(message), + l = message.length * 8, + w = [], + H0 = 1732584193, + H1 = -271733879, + H2 = -1732584194, + H3 = 271733878, + H4 = -1009589776; + + // Padding + m[l >> 5] |= 0x80 << (24 - l % 32); + m[((l + 64 >>> 9) << 4) + 15] = l; + + for (var i = 0; i < m.length; i += 16) { + + var a = H0, + b = H1, + c = H2, + d = H3, + e = H4; + + for (var j = 0; j < 80; j++) { + + if (j < 16) w[j] = m[i + j]; + else { + var n = w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16]; + w[j] = (n << 1) | (n >>> 31); + } + + var t = ((H0 << 5) | (H0 >>> 27)) + H4 + (w[j] >>> 0) + ( + j < 20 ? (H1 & H2 | ~H1 & H3) + 1518500249 : + j < 40 ? (H1 ^ H2 ^ H3) + 1859775393 : + j < 60 ? (H1 & H2 | H1 & H3 | H2 & H3) - 1894007588 : + (H1 ^ H2 ^ H3) - 899497514); + + H4 = H3; + H3 = H2; + H2 = (H1 << 30) | (H1 >>> 2); + H1 = H0; + H0 = t; + + } + + H0 += a; + H1 += b; + H2 += c; + H3 += d; + H4 += e; + + } + + return [H0, H1, H2, H3, H4]; + + }; + + // Package private blocksize + SHA1._blocksize = 16; + + SHA1._digestsize = 20; + + })(); + + //Added to make PKBDF2 work + /* + * Crypto-JS v2.5.4 + * http://code.google.com/p/crypto-js/ + * (c) 2009-2012 by Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ + (function() { + + // Shortcuts + var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8, + Binary = charenc.Binary; + + C.HMAC = function(hasher, message, key, options) { + + // Convert to byte arrays + if (message.constructor == String) message = UTF8.stringToBytes(message); + if (key.constructor == String) key = UTF8.stringToBytes(key); + /* else, assume byte arrays already */ + + // Allow arbitrary length keys + if (key.length > hasher._blocksize * 4) + key = hasher(key, { + asBytes: true + }); + + // XOR keys with pad constants + var okey = key.slice(0), + ikey = key.slice(0); + for (var i = 0; i < hasher._blocksize * 4; i++) { + okey[i] ^= 0x5C; + ikey[i] ^= 0x36; + } + + var hmacbytes = hasher(okey.concat(hasher(ikey.concat(message), { + asBytes: true + })), { + asBytes: true + }); + + return options && options.asBytes ? hmacbytes : + options && options.asString ? Binary.bytesToString(hmacbytes) : + util.bytesToHex(hmacbytes); + + }; + + })(); + + + //crypto-sha256-hmac.js + /* + * Crypto-JS v2.5.4 + * http://code.google.com/p/crypto-js/ + * (c) 2009-2012 by Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ + (function() { + var d = Crypto, + k = d.util, + g = d.charenc, + b = g.UTF8, + a = g.Binary, + c = [1116352408, 1899447441, 3049323471, 3921009573, 961987163, 1508970993, 2453635748, 2870763221, + 3624381080, 310598401, 607225278, 1426881987, 1925078388, 2162078206, 2614888103, 3248222580, + 3835390401, 4022224774, 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, + 2554220882, 2821834349, 2952996808, 3210313671, 3336571891, 3584528711, 113926993, 338241895, + 666307205, 773529912, 1294757372, 1396182291, 1695183700, 1986661051, 2177026350, 2456956037, + 2730485921, + 2820302411, 3259730800, 3345764771, 3516065817, 3600352804, 4094571909, 275423344, 430227734, + 506948616, 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779, 1955562222, + 2024104815, 2227730452, 2361852424, 2428436474, 2756734187, 3204031479, 3329325298 + ], + e = d.SHA256 = function(b, c) { + var f = k.wordsToBytes(e._sha256(b)); + return c && c.asBytes ? f : c && c.asString ? a.bytesToString(f) : k.bytesToHex(f) + }; + e._sha256 = function(a) { + a.constructor == String && (a = b.stringToBytes(a)); + var e = k.bytesToWords(a), + f = a.length * 8, + a = [1779033703, 3144134277, + 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225 + ], + d = [], + g, m, r, i, n, o, s, t, h, l, j; + e[f >> 5] |= 128 << 24 - f % 32; + e[(f + 64 >> 9 << 4) + 15] = f; + for (t = 0; t < e.length; t += 16) { + f = a[0]; + g = a[1]; + m = a[2]; + r = a[3]; + i = a[4]; + n = a[5]; + o = a[6]; + s = a[7]; + for (h = 0; h < 64; h++) { + h < 16 ? d[h] = e[h + t] : (l = d[h - 15], j = d[h - 2], d[h] = ((l << 25 | l >>> 7) ^ + (l << 14 | l >>> 18) ^ l >>> 3) + (d[h - 7] >>> 0) + ((j << 15 | j >>> 17) ^ + (j << 13 | j >>> 19) ^ j >>> 10) + (d[h - 16] >>> 0)); + j = f & g ^ f & m ^ g & m; + var u = (f << 30 | f >>> 2) ^ (f << 19 | f >>> 13) ^ (f << 10 | f >>> 22); + l = (s >>> 0) + ((i << 26 | i >>> 6) ^ (i << 21 | i >>> 11) ^ (i << 7 | i >>> 25)) + + (i & n ^ ~i & o) + c[h] + (d[h] >>> 0); + j = u + j; + s = o; + o = n; + n = i; + i = r + l >>> 0; + r = m; + m = g; + g = f; + f = l + j >>> 0 + } + a[0] += f; + a[1] += g; + a[2] += m; + a[3] += r; + a[4] += i; + a[5] += n; + a[6] += o; + a[7] += s + } + return a + }; + e._blocksize = 16; + e._digestsize = 32 + })(); + (function() { + var d = Crypto, + k = d.util, + g = d.charenc, + b = g.UTF8, + a = g.Binary; + d.HMAC = function(c, e, d, g) { + e.constructor == String && (e = b.stringToBytes(e)); + d.constructor == String && (d = b.stringToBytes(d)); + d.length > c._blocksize * 4 && (d = c(d, { + asBytes: !0 + })); + for (var f = d.slice(0), d = d.slice(0), q = 0; q < c._blocksize * 4; q++) f[q] ^= 92, d[q] ^= + 54; + c = c(f.concat(c(d.concat(e), { + asBytes: !0 + })), { + asBytes: !0 + }); + return g && g.asBytes ? c : g && g.asString ? a.bytesToString(c) : k.bytesToHex(c) + } + })(); +})(typeof global !== "undefined" ? global : window); + +//SecureRandom.js +(function(GLOBAL) { + + const getRandomValues = function(buf) { + if (typeof require === 'function') { + var bytes = require('crypto').randomBytes(buf.length); + buf.set(bytes) + return buf; + } else if (GLOBAL.crypto && GLOBAL.crypto.getRandomValues) + return GLOBAL.crypto.getRandomValues(buf); + else + return null; + } + + /*! + * Random number generator with ArcFour PRNG + * + * NOTE: For best results, put code like + * + * in your main HTML document. + * + * Copyright Tom Wu, bitaddress.org BSD License. + * http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE + */ + + // Constructor function of Global SecureRandom object + var sr = GLOBAL.SecureRandom = function() {}; + + // Properties + sr.state; + sr.pool; + sr.pptr; + sr.poolCopyOnInit; + + // Pool size must be a multiple of 4 and greater than 32. + // An array of bytes the size of the pool will be passed to init() + sr.poolSize = 256; + + // --- object methods --- + + // public method + // ba: byte array + sr.prototype.nextBytes = function(ba) { + var i; + if (getRandomValues && GLOBAL.Uint8Array) { + try { + var rvBytes = new Uint8Array(ba.length); + getRandomValues(rvBytes); + for (i = 0; i < ba.length; ++i) + ba[i] = sr.getByte() ^ rvBytes[i]; + return; + } catch (e) { + alert(e); + } + } + for (i = 0; i < ba.length; ++i) ba[i] = sr.getByte(); + }; + + + // --- static methods --- + + // Mix in the current time (w/milliseconds) into the pool + // NOTE: this method should be called from body click/keypress event handlers to increase entropy + sr.seedTime = function() { + sr.seedInt(new Date().getTime()); + } + + sr.getByte = function() { + if (sr.state == null) { + sr.seedTime(); + sr.state = sr.ArcFour(); // Plug in your RNG constructor here + sr.state.init(sr.pool); + sr.poolCopyOnInit = []; + for (sr.pptr = 0; sr.pptr < sr.pool.length; ++sr.pptr) + sr.poolCopyOnInit[sr.pptr] = sr.pool[sr.pptr]; + sr.pptr = 0; + } + // TODO: allow reseeding after first request + return sr.state.next(); + } + + // Mix in a 32-bit integer into the pool + sr.seedInt = function(x) { + sr.seedInt8(x); + sr.seedInt8((x >> 8)); + sr.seedInt8((x >> 16)); + sr.seedInt8((x >> 24)); + } + + // Mix in a 16-bit integer into the pool + sr.seedInt16 = function(x) { + sr.seedInt8(x); + sr.seedInt8((x >> 8)); + } + + // Mix in a 8-bit integer into the pool + sr.seedInt8 = function(x) { + sr.pool[sr.pptr++] ^= x & 255; + if (sr.pptr >= sr.poolSize) sr.pptr -= sr.poolSize; + } + + // Arcfour is a PRNG + sr.ArcFour = function() { + function Arcfour() { + this.i = 0; + this.j = 0; + this.S = new Array(); + } + + // Initialize arcfour context from key, an array of ints, each from [0..255] + function ARC4init(key) { + var i, j, t; + for (i = 0; i < 256; ++i) + this.S[i] = i; + j = 0; + for (i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; + } + + function ARC4next() { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; + } + + Arcfour.prototype.init = ARC4init; + Arcfour.prototype.next = ARC4next; + + return new Arcfour(); + }; + + + // Initialize the pool with junk if needed. + if (sr.pool == null) { + sr.pool = new Array(); + sr.pptr = 0; + var t; + if (getRandomValues && GLOBAL.Uint8Array) { + try { + // Use webcrypto if available + var ua = new Uint8Array(sr.poolSize); + getRandomValues(ua); + for (t = 0; t < sr.poolSize; ++t) + sr.pool[sr.pptr++] = ua[t]; + } catch (e) { + alert(e); + } + } + while (sr.pptr < sr.poolSize) { // extract some randomness from Math.random() + t = Math.floor(65536 * Math.random()); + sr.pool[sr.pptr++] = t >>> 8; + sr.pool[sr.pptr++] = t & 255; + } + sr.pptr = Math.floor(sr.poolSize * Math.random()); + sr.seedTime(); + // entropy + var entropyStr = ""; + // screen size and color depth: ~4.8 to ~5.4 bits + entropyStr += (GLOBAL.screen.height * GLOBAL.screen.width * GLOBAL.screen.colorDepth); + entropyStr += (GLOBAL.screen.availHeight * GLOBAL.screen.availWidth * GLOBAL.screen.pixelDepth); + // time zone offset: ~4 bits + var dateObj = new Date(); + var timeZoneOffset = dateObj.getTimezoneOffset(); + entropyStr += timeZoneOffset; + // user agent: ~8.3 to ~11.6 bits + entropyStr += navigator.userAgent; + // browser plugin details: ~16.2 to ~21.8 bits + var pluginsStr = ""; + for (var i = 0; i < navigator.plugins.length; i++) { + pluginsStr += navigator.plugins[i].name + " " + navigator.plugins[i].filename + " " + navigator.plugins[i].description + " " + navigator.plugins[i].version + ", "; + } + var mimeTypesStr = ""; + for (var i = 0; i < navigator.mimeTypes.length; i++) { + mimeTypesStr += navigator.mimeTypes[i].description + " " + navigator.mimeTypes[i].type + " " + navigator.mimeTypes[i].suffixes + ", "; + } + entropyStr += pluginsStr + mimeTypesStr; + // cookies and storage: 1 bit + entropyStr += navigator.cookieEnabled + typeof(sessionStorage) + typeof(localStorage); + // language: ~7 bit + entropyStr += navigator.language; + // history: ~2 bit + entropyStr += GLOBAL.history.length; + // location + entropyStr += GLOBAL.location; + + var entropyBytes = Crypto.SHA256(entropyStr, { + asBytes: true + }); + for (var i = 0; i < entropyBytes.length; i++) { + sr.seedInt8(entropyBytes[i]); + } + } +})(typeof global !== "undefined" ? global : window); + +//ripemd160.js +(function(GLOBAL) { + + /* + CryptoJS v3.1.2 + code.google.com/p/crypto-js + (c) 2009-2013 by Jeff Mott. All rights reserved. + code.google.com/p/crypto-js/wiki/License + */ + /** @preserve + (c) 2012 by Cédric Mesnil. All rights reserved. + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + // Constants table + var zl = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, + 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, + 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, + 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 + ]; + var zr = [ + 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, + 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, + 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, + 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, + 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 + ]; + var sl = [ + 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, + 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, + 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, + 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, + 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 + ]; + var sr = [ + 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, + 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, + 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, + 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, + 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 + ]; + + var hl = [0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E]; + var hr = [0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000]; + + var bytesToWords = function(bytes) { + var words = []; + for (var i = 0, b = 0; i < bytes.length; i++, b += 8) { + words[b >>> 5] |= bytes[i] << (24 - b % 32); + } + return words; + }; + + var wordsToBytes = function(words) { + var bytes = []; + for (var b = 0; b < words.length * 32; b += 8) { + bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF); + } + return bytes; + }; + + var processBlock = function(H, M, offset) { + + // Swap endian + for (var i = 0; i < 16; i++) { + var offset_i = offset + i; + var M_offset_i = M[offset_i]; + + // Swap + M[offset_i] = ( + (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | + (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00) + ); + } + + // Working variables + var al, bl, cl, dl, el; + var ar, br, cr, dr, er; + + ar = al = H[0]; + br = bl = H[1]; + cr = cl = H[2]; + dr = dl = H[3]; + er = el = H[4]; + // Computation + var t; + for (var i = 0; i < 80; i += 1) { + t = (al + M[offset + zl[i]]) | 0; + if (i < 16) { + t += f1(bl, cl, dl) + hl[0]; + } else if (i < 32) { + t += f2(bl, cl, dl) + hl[1]; + } else if (i < 48) { + t += f3(bl, cl, dl) + hl[2]; + } else if (i < 64) { + t += f4(bl, cl, dl) + hl[3]; + } else { // if (i<80) { + t += f5(bl, cl, dl) + hl[4]; + } + t = t | 0; + t = rotl(t, sl[i]); + t = (t + el) | 0; + al = el; + el = dl; + dl = rotl(cl, 10); + cl = bl; + bl = t; + + t = (ar + M[offset + zr[i]]) | 0; + if (i < 16) { + t += f5(br, cr, dr) + hr[0]; + } else if (i < 32) { + t += f4(br, cr, dr) + hr[1]; + } else if (i < 48) { + t += f3(br, cr, dr) + hr[2]; + } else if (i < 64) { + t += f2(br, cr, dr) + hr[3]; + } else { // if (i<80) { + t += f1(br, cr, dr) + hr[4]; + } + t = t | 0; + t = rotl(t, sr[i]); + t = (t + er) | 0; + ar = er; + er = dr; + dr = rotl(cr, 10); + cr = br; + br = t; + } + // Intermediate hash value + t = (H[1] + cl + dr) | 0; + H[1] = (H[2] + dl + er) | 0; + H[2] = (H[3] + el + ar) | 0; + H[3] = (H[4] + al + br) | 0; + H[4] = (H[0] + bl + cr) | 0; + H[0] = t; + }; + + function f1(x, y, z) { + return ((x) ^ (y) ^ (z)); + } + + function f2(x, y, z) { + return (((x) & (y)) | ((~x) & (z))); + } + + function f3(x, y, z) { + return (((x) | (~(y))) ^ (z)); + } + + function f4(x, y, z) { + return (((x) & (z)) | ((y) & (~(z)))); + } + + function f5(x, y, z) { + return ((x) ^ ((y) | (~(z)))); + } + + function rotl(x, n) { + return (x << n) | (x >>> (32 - n)); + } + + GLOBAL.ripemd160 = function ripemd160(message) { + var H = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]; + + var m = bytesToWords(message); + + var nBitsLeft = message.length * 8; + var nBitsTotal = message.length * 8; + + // Add padding + m[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); + m[(((nBitsLeft + 64) >>> 9) << 4) + 14] = ( + (((nBitsTotal << 8) | (nBitsTotal >>> 24)) & 0x00ff00ff) | + (((nBitsTotal << 24) | (nBitsTotal >>> 8)) & 0xff00ff00) + ); + + for (var i = 0; i < m.length; i += 16) { + processBlock(H, m, i); + } + + // Swap endian + for (var i = 0; i < 5; i++) { + // Shortcut + var H_i = H[i]; + + // Swap + H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | + (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00); + } + + var digestbytes = wordsToBytes(H); + return digestbytes; + } +})(typeof global !== "undefined" ? global : window); + +//BigInteger.js +(function(GLOBAL) { + // Upstream 'BigInteger' here: + // Original Author: http://www-cs-students.stanford.edu/~tjw/jsbn/ + // Follows 'jsbn' on Github: https://github.com/jasondavies/jsbn + // Review and Testing: https://github.com/cryptocoinjs/bigi/ + /*! + * Basic JavaScript BN library - subset useful for RSA encryption. v1.4 + * + * Copyright (c) 2005 Tom Wu + * All Rights Reserved. + * BSD License + * http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE + * + * Copyright Stephan Thomas + * Copyright pointbiz + */ + + // (public) Constructor function of Global BigInteger object + var BigInteger = GLOBAL.BigInteger = function BigInteger(a, b, c) { + if (!(this instanceof BigInteger)) + return new BigInteger(a, b, c); + + if (a != null) + if ("number" == typeof a) this.fromNumber(a, b, c); + else if (b == null && "string" != typeof a) this.fromString(a, 256); + else this.fromString(a, b); + }; + + // Bits per digit + var dbits; + + // JavaScript engine analysis + var canary = 0xdeadbeefcafe; + var j_lm = ((canary & 0xffffff) == 0xefcafe); + + // return new, unset BigInteger + function nbi() { + return new BigInteger(null); + } + + // am: Compute w_j += (x*this_i), propagate carries, + // c is initial carry, returns final carry. + // c < 3*dvalue, x < 2*dvalue, this_i < dvalue + // We need to select the fastest one that works in this environment. + + // am1: use a single mult and divide to get the high bits, + // max digit bits should be 26 because + // max internal value = 2*dvalue^2-2*dvalue (< 2^53) + function am1(i, x, w, j, c, n) { + while (--n >= 0) { + var v = x * this[i++] + w[j] + c; + c = Math.floor(v / 0x4000000); + w[j++] = v & 0x3ffffff; + } + return c; + } + // am2 avoids a big mult-and-extract completely. + // Max digit bits should be <= 30 because we do bitwise ops + // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) + function am2(i, x, w, j, c, n) { + var xl = x & 0x7fff, + xh = x >> 15; + while (--n >= 0) { + var l = this[i] & 0x7fff; + var h = this[i++] >> 15; + var m = xh * l + h * xl; + l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff); + c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30); + w[j++] = l & 0x3fffffff; + } + return c; + } + // Alternately, set max digit bits to 28 since some + // browsers slow down when dealing with 32-bit numbers. + function am3(i, x, w, j, c, n) { + var xl = x & 0x3fff, + xh = x >> 14; + while (--n >= 0) { + var l = this[i] & 0x3fff; + var h = this[i++] >> 14; + var m = xh * l + h * xl; + l = xl * l + ((m & 0x3fff) << 14) + w[j] + c; + c = (l >> 28) + (m >> 14) + xh * h; + w[j++] = l & 0xfffffff; + } + return c; + } + if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) { + BigInteger.prototype.am = am2; + dbits = 30; + } else if (j_lm && (navigator.appName != "Netscape")) { + BigInteger.prototype.am = am1; + dbits = 26; + } else { // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; + } + + BigInteger.prototype.DB = dbits; + BigInteger.prototype.DM = ((1 << dbits) - 1); + BigInteger.prototype.DV = (1 << dbits); + + var BI_FP = 52; + BigInteger.prototype.FV = Math.pow(2, BI_FP); + BigInteger.prototype.F1 = BI_FP - dbits; + BigInteger.prototype.F2 = 2 * dbits - BI_FP; + + // Digit conversions + var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; + var BI_RC = new Array(); + var rr, vv; + rr = "0".charCodeAt(0); + for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; + rr = "a".charCodeAt(0); + for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; + rr = "A".charCodeAt(0); + for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; + + function int2char(n) { + return BI_RM.charAt(n); + } + + function intAt(s, i) { + var c = BI_RC[s.charCodeAt(i)]; + return (c == null) ? -1 : c; + } + + + + // return bigint initialized to value + function nbv(i) { + var r = nbi(); + r.fromInt(i); + return r; + } + + + // returns bit length of the integer x + function nbits(x) { + var r = 1, + t; + if ((t = x >>> 16) != 0) { + x = t; + r += 16; + } + if ((t = x >> 8) != 0) { + x = t; + r += 8; + } + if ((t = x >> 4) != 0) { + x = t; + r += 4; + } + if ((t = x >> 2) != 0) { + x = t; + r += 2; + } + if ((t = x >> 1) != 0) { + x = t; + r += 1; + } + return r; + } + + + + + + + + // (protected) copy this to r + BigInteger.prototype.copyTo = function(r) { + for (var i = this.t - 1; i >= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; + }; + + + // (protected) set from integer value x, -DV <= x < DV + BigInteger.prototype.fromInt = function(x) { + this.t = 1; + this.s = (x < 0) ? -1 : 0; + if (x > 0) this[0] = x; + else if (x < -1) this[0] = x + this.DV; + else this.t = 0; + }; + + // (protected) set from string and radix + BigInteger.prototype.fromString = function(s, b) { + var k; + if (b == 16) k = 4; + else if (b == 8) k = 3; + else if (b == 256) k = 8; // byte array + else if (b == 2) k = 1; + else if (b == 32) k = 5; + else if (b == 4) k = 2; + else { + this.fromRadix(s, b); + return; + } + this.t = 0; + this.s = 0; + var i = s.length, + mi = false, + sh = 0; + while (--i >= 0) { + var x = (k == 8) ? s[i] & 0xff : intAt(s, i); + if (x < 0) { + if (s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if (sh == 0) + this[this.t++] = x; + else if (sh + k > this.DB) { + this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh; + this[this.t++] = (x >> (this.DB - sh)); + } else + this[this.t - 1] |= x << sh; + sh += k; + if (sh >= this.DB) sh -= this.DB; + } + if (k == 8 && (s[0] & 0x80) != 0) { + this.s = -1; + if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh; + } + this.clamp(); + if (mi) BigInteger.ZERO.subTo(this, this); + }; + + + // (protected) clamp off excess high words + BigInteger.prototype.clamp = function() { + var c = this.s & this.DM; + while (this.t > 0 && this[this.t - 1] == c) --this.t; + }; + + // (protected) r = this << n*DB + BigInteger.prototype.dlShiftTo = function(n, r) { + var i; + for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i]; + for (i = n - 1; i >= 0; --i) r[i] = 0; + r.t = this.t + n; + r.s = this.s; + }; + + // (protected) r = this >> n*DB + BigInteger.prototype.drShiftTo = function(n, r) { + for (var i = n; i < this.t; ++i) r[i - n] = this[i]; + r.t = Math.max(this.t - n, 0); + r.s = this.s; + }; + + + // (protected) r = this << n + BigInteger.prototype.lShiftTo = function(n, r) { + var bs = n % this.DB; + var cbs = this.DB - bs; + var bm = (1 << cbs) - 1; + var ds = Math.floor(n / this.DB), + c = (this.s << bs) & this.DM, + i; + for (i = this.t - 1; i >= 0; --i) { + r[i + ds + 1] = (this[i] >> cbs) | c; + c = (this[i] & bm) << bs; + } + for (i = ds - 1; i >= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t + ds + 1; + r.s = this.s; + r.clamp(); + }; + + + // (protected) r = this >> n + BigInteger.prototype.rShiftTo = function(n, r) { + r.s = this.s; + var ds = Math.floor(n / this.DB); + if (ds >= this.t) { + r.t = 0; + return; + } + var bs = n % this.DB; + var cbs = this.DB - bs; + var bm = (1 << bs) - 1; + r[0] = this[ds] >> bs; + for (var i = ds + 1; i < this.t; ++i) { + r[i - ds - 1] |= (this[i] & bm) << cbs; + r[i - ds] = this[i] >> bs; + } + if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs; + r.t = this.t - ds; + r.clamp(); + }; + + + // (protected) r = this - a + BigInteger.prototype.subTo = function(a, r) { + var i = 0, + c = 0, + m = Math.min(a.t, this.t); + while (i < m) { + c += this[i] - a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + if (a.t < this.t) { + c -= a.s; + while (i < this.t) { + c += this[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += this.s; + } else { + c += this.s; + while (i < a.t) { + c -= a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c < 0) ? -1 : 0; + if (c < -1) r[i++] = this.DV + c; + else if (c > 0) r[i++] = c; + r.t = i; + r.clamp(); + }; + + + // (protected) r = this * a, r != this,a (HAC 14.12) + // "this" should be the larger one if appropriate. + BigInteger.prototype.multiplyTo = function(a, r) { + var x = this.abs(), + y = a.abs(); + var i = x.t; + r.t = i + y.t; + while (--i >= 0) r[i] = 0; + for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t); + r.s = 0; + r.clamp(); + if (this.s != a.s) BigInteger.ZERO.subTo(r, r); + }; + + + // (protected) r = this^2, r != this (HAC 14.16) + BigInteger.prototype.squareTo = function(r) { + var x = this.abs(); + var i = r.t = 2 * x.t; + while (--i >= 0) r[i] = 0; + for (i = 0; i < x.t - 1; ++i) { + var c = x.am(i, x[i], r, 2 * i, 0, 1); + if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) { + r[i + x.t] -= x.DV; + r[i + x.t + 1] = 1; + } + } + if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1); + r.s = 0; + r.clamp(); + }; + + + + // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) + // r != q, this != m. q or r may be null. + BigInteger.prototype.divRemTo = function(m, q, r) { + var pm = m.abs(); + if (pm.t <= 0) return; + var pt = this.abs(); + if (pt.t < pm.t) { + if (q != null) q.fromInt(0); + if (r != null) this.copyTo(r); + return; + } + if (r == null) r = nbi(); + var y = nbi(), + ts = this.s, + ms = m.s; + var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus + if (nsh > 0) { + pm.lShiftTo(nsh, y); + pt.lShiftTo(nsh, r); + } else { + pm.copyTo(y); + pt.copyTo(r); + } + var ys = y.t; + var y0 = y[ys - 1]; + if (y0 == 0) return; + var yt = y0 * (1 << this.F1) + ((ys > 1) ? y[ys - 2] >> this.F2 : 0); + var d1 = this.FV / yt, + d2 = (1 << this.F1) / yt, + e = 1 << this.F2; + var i = r.t, + j = i - ys, + t = (q == null) ? nbi() : q; + y.dlShiftTo(j, t); + if (r.compareTo(t) >= 0) { + r[r.t++] = 1; + r.subTo(t, r); + } + BigInteger.ONE.dlShiftTo(ys, t); + t.subTo(y, y); // "negative" y so we can replace sub with am later + while (y.t < ys) y[y.t++] = 0; + while (--j >= 0) { + // Estimate quotient digit + var qd = (r[--i] == y0) ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2); + if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { // Try it out + y.dlShiftTo(j, t); + r.subTo(t, r); + while (r[i] < --qd) r.subTo(t, r); + } + } + if (q != null) { + r.drShiftTo(ys, q); + if (ts != ms) BigInteger.ZERO.subTo(q, q); + } + r.t = ys; + r.clamp(); + if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder + if (ts < 0) BigInteger.ZERO.subTo(r, r); + }; + + + // (protected) return "-1/this % 2^DB"; useful for Mont. reduction + // justification: + // xy == 1 (mod m) + // xy = 1+km + // xy(2-xy) = (1+km)(1-km) + // x[y(2-xy)] = 1-k^2m^2 + // x[y(2-xy)] == 1 (mod m^2) + // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 + // should reduce x and y(2-xy) by m^2 at each step to keep size bounded. + // JS multiply "overflows" differently from C/C++, so care is needed here. + BigInteger.prototype.invDigit = function() { + if (this.t < 1) return 0; + var x = this[0]; + if ((x & 1) == 0) return 0; + var y = x & 3; // y == 1/x mod 2^2 + y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 + y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 + y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y * (2 - x * y % this.DV)) % this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y > 0) ? this.DV - y : -y; + }; + + + // (protected) true iff this is even + BigInteger.prototype.isEven = function() { + return ((this.t > 0) ? (this[0] & 1) : this.s) == 0; + }; + + + // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) + BigInteger.prototype.exp = function(e, z) { + if (e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), + r2 = nbi(), + g = z.convert(this), + i = nbits(e) - 1; + g.copyTo(r); + while (--i >= 0) { + z.sqrTo(r, r2); + if ((e & (1 << i)) > 0) z.mulTo(r2, g, r); + else { + var t = r; + r = r2; + r2 = t; + } + } + return z.revert(r); + }; + + + // (public) return string representation in given radix + BigInteger.prototype.toString = function(b) { + if (this.s < 0) return "-" + this.negate().toString(b); + var k; + if (b == 16) k = 4; + else if (b == 8) k = 3; + else if (b == 2) k = 1; + else if (b == 32) k = 5; + else if (b == 4) k = 2; + else return this.toRadix(b); + var km = (1 << k) - 1, + d, m = false, + r = "", + i = this.t; + var p = this.DB - (i * this.DB) % k; + if (i-- > 0) { + if (p < this.DB && (d = this[i] >> p) > 0) { + m = true; + r = int2char(d); + } + while (i >= 0) { + if (p < k) { + d = (this[i] & ((1 << p) - 1)) << (k - p); + d |= this[--i] >> (p += this.DB - k); + } else { + d = (this[i] >> (p -= k)) & km; + if (p <= 0) { + p += this.DB; + --i; + } + } + if (d > 0) m = true; + if (m) r += int2char(d); + } + } + return m ? r : "0"; + }; + + + // (public) -this + BigInteger.prototype.negate = function() { + var r = nbi(); + BigInteger.ZERO.subTo(this, r); + return r; + }; + + // (public) |this| + BigInteger.prototype.abs = function() { + return (this.s < 0) ? this.negate() : this; + }; + + // (public) return + if this > a, - if this < a, 0 if equal + BigInteger.prototype.compareTo = function(a) { + var r = this.s - a.s; + if (r != 0) return r; + var i = this.t; + r = i - a.t; + if (r != 0) return (this.s < 0) ? -r : r; + while (--i >= 0) + if ((r = this[i] - a[i]) != 0) return r; + return 0; + } + + // (public) return the number of bits in "this" + BigInteger.prototype.bitLength = function() { + if (this.t <= 0) return 0; + return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)); + }; + + // (public) this mod a + BigInteger.prototype.mod = function(a) { + var r = nbi(); + this.abs().divRemTo(a, null, r); + if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r); + return r; + } + + // (public) this^e % m, 0 <= e < 2^32 + BigInteger.prototype.modPowInt = function(e, m) { + var z; + if (e < 256 || m.isEven()) z = new Classic(m); + else z = new Montgomery(m); + return this.exp(e, z); + }; + + // "constants" + BigInteger.ZERO = nbv(0); + BigInteger.ONE = nbv(1); + + + + + + + + // Copyright (c) 2005-2009 Tom Wu + // All Rights Reserved. + // See "LICENSE" for details. + // Extended JavaScript BN functions, required for RSA private ops. + // Version 1.1: new BigInteger("0", 10) returns "proper" zero + // Version 1.2: square() API, isProbablePrime fix + + + // return index of lowest 1-bit in x, x < 2^31 + function lbit(x) { + if (x == 0) return -1; + var r = 0; + if ((x & 0xffff) == 0) { + x >>= 16; + r += 16; + } + if ((x & 0xff) == 0) { + x >>= 8; + r += 8; + } + if ((x & 0xf) == 0) { + x >>= 4; + r += 4; + } + if ((x & 3) == 0) { + x >>= 2; + r += 2; + } + if ((x & 1) == 0) ++r; + return r; + } + + // return number of 1 bits in x + function cbit(x) { + var r = 0; + while (x != 0) { + x &= x - 1; + ++r; + } + return r; + } + + var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, + 89, + 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, + 193, + 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, + 311, + 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, + 433, + 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, + 569, + 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, + 683, + 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, + 827, + 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, + 971, + 977, 983, 991, 997 + ]; + var lplim = (1 << 26) / lowprimes[lowprimes.length - 1]; + + + + // (protected) return x s.t. r^x < DV + BigInteger.prototype.chunkSize = function(r) { + return Math.floor(Math.LN2 * this.DB / Math.log(r)); + }; + + // (protected) convert to radix string + BigInteger.prototype.toRadix = function(b) { + if (b == null) b = 10; + if (this.signum() == 0 || b < 2 || b > 36) return "0"; + var cs = this.chunkSize(b); + var a = Math.pow(b, cs); + var d = nbv(a), + y = nbi(), + z = nbi(), + r = ""; + this.divRemTo(d, y, z); + while (y.signum() > 0) { + r = (a + z.intValue()).toString(b).substr(1) + r; + y.divRemTo(d, y, z); + } + return z.intValue().toString(b) + r; + }; + + // (protected) convert from radix string + BigInteger.prototype.fromRadix = function(s, b) { + this.fromInt(0); + if (b == null) b = 10; + var cs = this.chunkSize(b); + var d = Math.pow(b, cs), + mi = false, + j = 0, + w = 0; + for (var i = 0; i < s.length; ++i) { + var x = intAt(s, i); + if (x < 0) { + if (s.charAt(i) == "-" && this.signum() == 0) mi = true; + continue; + } + w = b * w + x; + if (++j >= cs) { + this.dMultiply(d); + this.dAddOffset(w, 0); + j = 0; + w = 0; + } + } + if (j > 0) { + this.dMultiply(Math.pow(b, j)); + this.dAddOffset(w, 0); + } + if (mi) BigInteger.ZERO.subTo(this, this); + }; + + // (protected) alternate constructor + BigInteger.prototype.fromNumber = function(a, b, c) { + if ("number" == typeof b) { + // new BigInteger(int,int,RNG) + if (a < 2) this.fromInt(1); + else { + this.fromNumber(a, c); + if (!this.testBit(a - 1)) // force MSB set + this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this); + if (this.isEven()) this.dAddOffset(1, 0); // force odd + while (!this.isProbablePrime(b)) { + this.dAddOffset(2, 0); + if (this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a - 1), this); + } + } + } else { + // new BigInteger(int,RNG) + var x = new Array(), + t = a & 7; + x.length = (a >> 3) + 1; + b.nextBytes(x); + if (t > 0) x[0] &= ((1 << t) - 1); + else x[0] = 0; + this.fromString(x, 256); + } + }; + + // (protected) r = this op a (bitwise) + BigInteger.prototype.bitwiseTo = function(a, op, r) { + var i, f, m = Math.min(a.t, this.t); + for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]); + if (a.t < this.t) { + f = a.s & this.DM; + for (i = m; i < this.t; ++i) r[i] = op(this[i], f); + r.t = this.t; + } else { + f = this.s & this.DM; + for (i = m; i < a.t; ++i) r[i] = op(f, a[i]); + r.t = a.t; + } + r.s = op(this.s, a.s); + r.clamp(); + }; + + // (protected) this op (1<>= this.DB; + } + if (a.t < this.t) { + c += a.s; + while (i < this.t) { + c += this[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += this.s; + } else { + c += this.s; + while (i < a.t) { + c += a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += a.s; + } + r.s = (c < 0) ? -1 : 0; + if (c > 0) r[i++] = c; + else if (c < -1) r[i++] = this.DV + c; + r.t = i; + r.clamp(); + }; + + // (protected) this *= n, this >= 0, 1 < n < DV + BigInteger.prototype.dMultiply = function(n) { + this[this.t] = this.am(0, n - 1, this, 0, 0, this.t); + ++this.t; + this.clamp(); + }; + + // (protected) this += n << w words, this >= 0 + BigInteger.prototype.dAddOffset = function(n, w) { + if (n == 0) return; + while (this.t <= w) this[this.t++] = 0; + this[w] += n; + while (this[w] >= this.DV) { + this[w] -= this.DV; + if (++w >= this.t) this[this.t++] = 0; + ++this[w]; + } + }; + + // (protected) r = lower n words of "this * a", a.t <= n + // "this" should be the larger one if appropriate. + BigInteger.prototype.multiplyLowerTo = function(a, n, r) { + var i = Math.min(this.t + a.t, n); + r.s = 0; // assumes a,this >= 0 + r.t = i; + while (i > 0) r[--i] = 0; + var j; + for (j = r.t - this.t; i < j; ++i) r[i + this.t] = this.am(0, a[i], r, i, 0, this.t); + for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i); + r.clamp(); + }; + + + // (protected) r = "this * a" without lower n words, n > 0 + // "this" should be the larger one if appropriate. + BigInteger.prototype.multiplyUpperTo = function(a, n, r) { + --n; + var i = r.t = this.t + a.t - n; + r.s = 0; // assumes a,this >= 0 + while (--i >= 0) r[i] = 0; + for (i = Math.max(n - this.t, 0); i < a.t; ++i) + r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n); + r.clamp(); + r.drShiftTo(1, r); + }; + + // (protected) this % n, n < 2^26 + BigInteger.prototype.modInt = function(n) { + if (n <= 0) return 0; + var d = this.DV % n, + r = (this.s < 0) ? n - 1 : 0; + if (this.t > 0) + if (d == 0) r = this[0] % n; + else + for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n; + return r; + }; + + + // (protected) true if probably prime (HAC 4.24, Miller-Rabin) + BigInteger.prototype.millerRabin = function(t) { + var n1 = this.subtract(BigInteger.ONE); + var k = n1.getLowestSetBit(); + if (k <= 0) return false; + var r = n1.shiftRight(k); + t = (t + 1) >> 1; + if (t > lowprimes.length) t = lowprimes.length; + var a = nbi(); + for (var i = 0; i < t; ++i) { + //Pick bases at random, instead of starting at 2 + a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]); + var y = a.modPow(r, this); + if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + var j = 1; + while (j++ < k && y.compareTo(n1) != 0) { + y = y.modPowInt(2, this); + if (y.compareTo(BigInteger.ONE) == 0) return false; + } + if (y.compareTo(n1) != 0) return false; + } + } + return true; + }; + + + + // (public) + BigInteger.prototype.clone = function() { + var r = nbi(); + this.copyTo(r); + return r; + }; + + // (public) return value as integer + BigInteger.prototype.intValue = function() { + if (this.s < 0) { + if (this.t == 1) return this[0] - this.DV; + else if (this.t == 0) return -1; + } else if (this.t == 1) return this[0]; + else if (this.t == 0) return 0; + // assumes 16 < DB < 32 + return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0]; + }; + + + // (public) return value as byte + BigInteger.prototype.byteValue = function() { + return (this.t == 0) ? this.s : (this[0] << 24) >> 24; + }; + + // (public) return value as short (assumes DB>=16) + BigInteger.prototype.shortValue = function() { + return (this.t == 0) ? this.s : (this[0] << 16) >> 16; + }; + + // (public) 0 if this == 0, 1 if this > 0 + BigInteger.prototype.signum = function() { + if (this.s < 0) return -1; + else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; + else return 1; + }; + + + // (public) convert to bigendian byte array + BigInteger.prototype.toByteArray = function() { + var i = this.t, + r = new Array(); + r[0] = this.s; + var p = this.DB - (i * this.DB) % 8, + d, k = 0; + if (i-- > 0) { + if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) + r[k++] = d | (this.s << (this.DB - p)); + while (i >= 0) { + if (p < 8) { + d = (this[i] & ((1 << p) - 1)) << (8 - p); + d |= this[--i] >> (p += this.DB - 8); + } else { + d = (this[i] >> (p -= 8)) & 0xff; + if (p <= 0) { + p += this.DB; + --i; + } + } + if ((d & 0x80) != 0) d |= -256; + if (k == 0 && (this.s & 0x80) != (d & 0x80)) ++k; + if (k > 0 || d != this.s) r[k++] = d; + } + } + return r; + }; + + BigInteger.prototype.equals = function(a) { + return (this.compareTo(a) == 0); + }; + BigInteger.prototype.min = function(a) { + return (this.compareTo(a) < 0) ? this : a; + }; + BigInteger.prototype.max = function(a) { + return (this.compareTo(a) > 0) ? this : a; + }; + + // (public) this & a + function op_and(x, y) { + return x & y; + } + BigInteger.prototype.and = function(a) { + var r = nbi(); + this.bitwiseTo(a, op_and, r); + return r; + }; + + // (public) this | a + function op_or(x, y) { + return x | y; + } + BigInteger.prototype.or = function(a) { + var r = nbi(); + this.bitwiseTo(a, op_or, r); + return r; + }; + + // (public) this ^ a + function op_xor(x, y) { + return x ^ y; + } + BigInteger.prototype.xor = function(a) { + var r = nbi(); + this.bitwiseTo(a, op_xor, r); + return r; + }; + + // (public) this & ~a + function op_andnot(x, y) { + return x & ~y; + } + BigInteger.prototype.andNot = function(a) { + var r = nbi(); + this.bitwiseTo(a, op_andnot, r); + return r; + }; + + // (public) ~this + BigInteger.prototype.not = function() { + var r = nbi(); + for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i]; + r.t = this.t; + r.s = ~this.s; + return r; + }; + + // (public) this << n + BigInteger.prototype.shiftLeft = function(n) { + var r = nbi(); + if (n < 0) this.rShiftTo(-n, r); + else this.lShiftTo(n, r); + return r; + }; + + // (public) this >> n + BigInteger.prototype.shiftRight = function(n) { + var r = nbi(); + if (n < 0) this.lShiftTo(-n, r); + else this.rShiftTo(n, r); + return r; + }; + + // (public) returns index of lowest 1-bit (or -1 if none) + BigInteger.prototype.getLowestSetBit = function() { + for (var i = 0; i < this.t; ++i) + if (this[i] != 0) return i * this.DB + lbit(this[i]); + if (this.s < 0) return this.t * this.DB; + return -1; + }; + + // (public) return number of set bits + BigInteger.prototype.bitCount = function() { + var r = 0, + x = this.s & this.DM; + for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x); + return r; + }; + + // (public) true iff nth bit is set + BigInteger.prototype.testBit = function(n) { + var j = Math.floor(n / this.DB); + if (j >= this.t) return (this.s != 0); + return ((this[j] & (1 << (n % this.DB))) != 0); + }; + + // (public) this | (1< 1) { + var g2 = nbi(); + z.sqrTo(g[1], g2); + while (n <= km) { + g[n] = nbi(); + z.mulTo(g2, g[n - 2], g[n]); + n += 2; + } + } + + var j = e.t - 1, + w, is1 = true, + r2 = nbi(), + t; + i = nbits(e[j]) - 1; + while (j >= 0) { + if (i >= k1) w = (e[j] >> (i - k1)) & km; + else { + w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i); + if (j > 0) w |= e[j - 1] >> (this.DB + i - k1); + } + + n = k; + while ((w & 1) == 0) { + w >>= 1; + --n; + } + if ((i -= n) < 0) { + i += this.DB; + --j; + } + if (is1) { // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r); + is1 = false; + } else { + while (n > 1) { + z.sqrTo(r, r2); + z.sqrTo(r2, r); + n -= 2; + } + if (n > 0) z.sqrTo(r, r2); + else { + t = r; + r = r2; + r2 = t; + } + z.mulTo(r2, g[w], r); + } + + while (j >= 0 && (e[j] & (1 << i)) == 0) { + z.sqrTo(r, r2); + t = r; + r = r2; + r2 = t; + if (--i < 0) { + i = this.DB - 1; + --j; + } + } + } + return z.revert(r); + }; + + // (public) 1/this % m (HAC 14.61) + BigInteger.prototype.modInverse = function(m) { + var ac = m.isEven(); + if (this.signum() === 0) throw new Error('division by zero'); + if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; + var u = m.clone(), + v = this.clone(); + var a = nbv(1), + b = nbv(0), + c = nbv(0), + d = nbv(1); + while (u.signum() != 0) { + while (u.isEven()) { + u.rShiftTo(1, u); + if (ac) { + if (!a.isEven() || !b.isEven()) { + a.addTo(this, a); + b.subTo(m, b); + } + a.rShiftTo(1, a); + } else if (!b.isEven()) b.subTo(m, b); + b.rShiftTo(1, b); + } + while (v.isEven()) { + v.rShiftTo(1, v); + if (ac) { + if (!c.isEven() || !d.isEven()) { + c.addTo(this, c); + d.subTo(m, d); + } + c.rShiftTo(1, c); + } else if (!d.isEven()) d.subTo(m, d); + d.rShiftTo(1, d); + } + if (u.compareTo(v) >= 0) { + u.subTo(v, u); + if (ac) a.subTo(c, a); + b.subTo(d, b); + } else { + v.subTo(u, v); + if (ac) c.subTo(a, c); + d.subTo(b, d); + } + } + if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; + while (d.compareTo(m) >= 0) d.subTo(m, d); + while (d.signum() < 0) d.addTo(m, d); + return d; + }; + + + // (public) this^e + BigInteger.prototype.pow = function(e) { + return this.exp(e, new NullExp()); + }; + + // (public) gcd(this,a) (HAC 14.54) + BigInteger.prototype.gcd = function(a) { + var x = (this.s < 0) ? this.negate() : this.clone(); + var y = (a.s < 0) ? a.negate() : a.clone(); + if (x.compareTo(y) < 0) { + var t = x; + x = y; + y = t; + } + var i = x.getLowestSetBit(), + g = y.getLowestSetBit(); + if (g < 0) return x; + if (i < g) g = i; + if (g > 0) { + x.rShiftTo(g, x); + y.rShiftTo(g, y); + } + while (x.signum() > 0) { + if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x); + if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y); + if (x.compareTo(y) >= 0) { + x.subTo(y, x); + x.rShiftTo(1, x); + } else { + y.subTo(x, y); + y.rShiftTo(1, y); + } + } + if (g > 0) y.lShiftTo(g, y); + return y; + }; + + // (public) test primality with certainty >= 1-.5^t + BigInteger.prototype.isProbablePrime = function(t) { + var i, x = this.abs(); + if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) { + for (i = 0; i < lowprimes.length; ++i) + if (x[0] == lowprimes[i]) return true; + return false; + } + if (x.isEven()) return false; + i = 1; + while (i < lowprimes.length) { + var m = lowprimes[i], + j = i + 1; + while (j < lowprimes.length && m < lplim) m *= lowprimes[j++]; + m = x.modInt(m); + while (i < j) + if (m % lowprimes[i++] == 0) return false; + } + return x.millerRabin(t); + }; + + + // JSBN-specific extension + + // (public) this^2 + BigInteger.prototype.square = function() { + var r = nbi(); + this.squareTo(r); + return r; + }; + + + // NOTE: BigInteger interfaces not implemented in jsbn: + // BigInteger(int signum, byte[] magnitude) + // double doubleValue() + // float floatValue() + // int hashCode() + // long longValue() + // static BigInteger valueOf(long val) + + + + // Copyright Stephan Thomas (start) --- // + // https://raw.github.com/bitcoinjs/bitcoinjs-lib/07f9d55ccb6abd962efb6befdd37671f85ea4ff9/src/util.js + // BigInteger monkey patching + BigInteger.valueOf = nbv; + + /** + * Returns a byte array representation of the big integer. + * + * This returns the absolute of the contained value in big endian + * form. A value of zero results in an empty array. + */ + BigInteger.prototype.toByteArrayUnsigned = function() { + var ba = this.abs().toByteArray(); + if (ba.length) { + if (ba[0] == 0) { + ba = ba.slice(1); + } + return ba.map(function(v) { + return (v < 0) ? v + 256 : v; + }); + } else { + // Empty array, nothing to do + return ba; + } + }; + + /** + * Turns a byte array into a big integer. + * + * This function will interpret a byte array as a big integer in big + * endian notation and ignore leading zeros. + */ + BigInteger.fromByteArrayUnsigned = function(ba) { + if (!ba.length) { + return ba.valueOf(0); + } else if (ba[0] & 0x80) { + // Prepend a zero so the BigInteger class doesn't mistake this + // for a negative integer. + return new BigInteger([0].concat(ba)); + } else { + return new BigInteger(ba); + } + }; + + /** + * Converts big integer to signed byte representation. + * + * The format for this value uses a the most significant bit as a sign + * bit. If the most significant bit is already occupied by the + * absolute value, an extra byte is prepended and the sign bit is set + * there. + * + * Examples: + * + * 0 => 0x00 + * 1 => 0x01 + * -1 => 0x81 + * 127 => 0x7f + * -127 => 0xff + * 128 => 0x0080 + * -128 => 0x8080 + * 255 => 0x00ff + * -255 => 0x80ff + * 16300 => 0x3fac + * -16300 => 0xbfac + * 62300 => 0x00f35c + * -62300 => 0x80f35c + */ + BigInteger.prototype.toByteArraySigned = function() { + var val = this.abs().toByteArrayUnsigned(); + var neg = this.compareTo(BigInteger.ZERO) < 0; + + if (neg) { + if (val[0] & 0x80) { + val.unshift(0x80); + } else { + val[0] |= 0x80; + } + } else { + if (val[0] & 0x80) { + val.unshift(0x00); + } + } + + return val; + }; + + /** + * Parse a signed big integer byte representation. + * + * For details on the format please see BigInteger.toByteArraySigned. + */ + BigInteger.fromByteArraySigned = function(ba) { + // Check for negative value + if (ba[0] & 0x80) { + // Remove sign bit + ba[0] &= 0x7f; + + return BigInteger.fromByteArrayUnsigned(ba).negate(); + } else { + return BigInteger.fromByteArrayUnsigned(ba); + } + }; + // Copyright Stephan Thomas (end) --- // + + + + + // ****** REDUCTION ******* // + + // Modular reduction using "classic" algorithm + var Classic = GLOBAL.Classic = function Classic(m) { + this.m = m; + } + Classic.prototype.convert = function(x) { + if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; + }; + Classic.prototype.revert = function(x) { + return x; + }; + Classic.prototype.reduce = function(x) { + x.divRemTo(this.m, null, x); + }; + Classic.prototype.mulTo = function(x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); + }; + Classic.prototype.sqrTo = function(x, r) { + x.squareTo(r); + this.reduce(r); + }; + + + + + + // Montgomery reduction + var Montgomery = GLOBAL.Montgomery = function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp & 0x7fff; + this.mph = this.mp >> 15; + this.um = (1 << (m.DB - 15)) - 1; + this.mt2 = 2 * m.t; + } + // xR mod m + Montgomery.prototype.convert = function(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t, r); + r.divRemTo(this.m, null, r); + if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r); + return r; + } + // x/R mod m + Montgomery.prototype.revert = function(x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; + }; + // x = x/R mod m (HAC 14.32) + Montgomery.prototype.reduce = function(x) { + while (x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0; + for (var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i] & 0x7fff; + var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM; + // use am to combine the multiply-shift-add into one call + j = i + this.m.t; + x[j] += this.m.am(0, u0, x, i, 0, this.m.t); + // propagate carry + while (x[j] >= x.DV) { + x[j] -= x.DV; + x[++j]++; + } + } + x.clamp(); + x.drShiftTo(this.m.t, x); + if (x.compareTo(this.m) >= 0) x.subTo(this.m, x); + }; + // r = "xy/R mod m"; x,y != r + Montgomery.prototype.mulTo = function(x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); + }; + // r = "x^2/R mod m"; x != r + Montgomery.prototype.sqrTo = function(x, r) { + x.squareTo(r); + this.reduce(r); + }; + + + + + + // A "null" reducer + var NullExp = GLOBAL.NullExp = function NullExp() {} + NullExp.prototype.convert = function(x) { + return x; + }; + NullExp.prototype.revert = function(x) { + return x; + }; + NullExp.prototype.mulTo = function(x, y, r) { + x.multiplyTo(y, r); + }; + NullExp.prototype.sqrTo = function(x, r) { + x.squareTo(r); + }; + + + + + + // Barrett modular reduction + var Barrett = GLOBAL.Barrett = function Barrett(m) { + // setup Barrett + this.r2 = nbi(); + this.q3 = nbi(); + BigInteger.ONE.dlShiftTo(2 * m.t, this.r2); + this.mu = this.r2.divide(m); + this.m = m; + } + Barrett.prototype.convert = function(x) { + if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m); + else if (x.compareTo(this.m) < 0) return x; + else { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; + } + }; + Barrett.prototype.revert = function(x) { + return x; + }; + // x = x mod m (HAC 14.42) + Barrett.prototype.reduce = function(x) { + x.drShiftTo(this.m.t - 1, this.r2); + if (x.t > this.m.t + 1) { + x.t = this.m.t + 1; + x.clamp(); + } + this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3); + this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2); + while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1); + x.subTo(this.r2, x); + while (x.compareTo(this.m) >= 0) x.subTo(this.m, x); + }; + // r = x*y mod m; x,y != r + Barrett.prototype.mulTo = function(x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); + }; + // r = x^2 mod m; x != r + Barrett.prototype.sqrTo = function(x, r) { + x.squareTo(r); + this.reduce(r); + }; + + // BigInteger interfaces not implemented in jsbn: + + // BigInteger(int signum, byte[] magnitude) + // double doubleValue() + // float floatValue() + // int hashCode() + // long longValue() + // static BigInteger valueOf(long val) +})(typeof global !== "undefined" ? global : window); + +//ellipticcurve.js +(function(GLOBAL) { + /*! + * Basic Javascript Elliptic Curve implementation + * Ported loosely from BouncyCastle's Java EC code + * Only Fp curves implemented for now + * + * Copyright Tom Wu, bitaddress.org BSD License. + * http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE + */ + // Constructor function of Global EllipticCurve object + var ec = GLOBAL.EllipticCurve = function() {}; + + // ---------------- + // ECFieldElementFp constructor + // q instanceof BigInteger + // x instanceof BigInteger + ec.FieldElementFp = function(q, x) { + this.x = x; + // TODO if(x.compareTo(q) >= 0) error + this.q = q; + }; + + ec.FieldElementFp.prototype.equals = function(other) { + if (other == this) return true; + return (this.q.equals(other.q) && this.x.equals(other.x)); + }; + + ec.FieldElementFp.prototype.toBigInteger = function() { + return this.x; + }; + + ec.FieldElementFp.prototype.negate = function() { + return new ec.FieldElementFp(this.q, this.x.negate().mod(this.q)); + }; + + ec.FieldElementFp.prototype.add = function(b) { + return new ec.FieldElementFp(this.q, this.x.add(b.toBigInteger()).mod(this.q)); + }; + + ec.FieldElementFp.prototype.subtract = function(b) { + return new ec.FieldElementFp(this.q, this.x.subtract(b.toBigInteger()).mod(this.q)); + }; + + ec.FieldElementFp.prototype.multiply = function(b) { + return new ec.FieldElementFp(this.q, this.x.multiply(b.toBigInteger()).mod(this.q)); + }; + + ec.FieldElementFp.prototype.square = function() { + return new ec.FieldElementFp(this.q, this.x.square().mod(this.q)); + }; + + ec.FieldElementFp.prototype.divide = function(b) { + return new ec.FieldElementFp(this.q, this.x.multiply(b.toBigInteger().modInverse(this.q)).mod( + this.q)); + }; + + ec.FieldElementFp.prototype.getByteLength = function() { + return Math.floor((this.toBigInteger().bitLength() + 7) / 8); + }; + + // D.1.4 91 + /** + * return a sqrt root - the routine verifies that the calculation + * returns the right value - if none exists it returns null. + * + * Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) + * Ported to JavaScript by bitaddress.org + */ + ec.FieldElementFp.prototype.sqrt = function() { + if (!this.q.testBit(0)) throw new Error("even value of q"); + + // p mod 4 == 3 + if (this.q.testBit(1)) { + // z = g^(u+1) + p, p = 4u + 3 + var z = new ec.FieldElementFp(this.q, this.x.modPow(this.q.shiftRight(2).add(BigInteger.ONE), + this.q)); + return z.square().equals(this) ? z : null; + } + + // p mod 4 == 1 + var qMinusOne = this.q.subtract(BigInteger.ONE); + var legendreExponent = qMinusOne.shiftRight(1); + if (!(this.x.modPow(legendreExponent, this.q).equals(BigInteger.ONE))) return null; + var u = qMinusOne.shiftRight(2); + var k = u.shiftLeft(1).add(BigInteger.ONE); + var Q = this.x; + var fourQ = Q.shiftLeft(2).mod(this.q); + var U, V; + + do { + var rand = new SecureRandom(); + var P; + do { + P = new BigInteger(this.q.bitLength(), rand); + } + while (P.compareTo(this.q) >= 0 || !(P.multiply(P).subtract(fourQ).modPow(legendreExponent, + this.q).equals(qMinusOne))); + + var result = ec.FieldElementFp.fastLucasSequence(this.q, P, Q, k); + + U = result[0]; + V = result[1]; + if (V.multiply(V).mod(this.q).equals(fourQ)) { + // Integer division by 2, mod q + if (V.testBit(0)) { + V = V.add(this.q); + } + V = V.shiftRight(1); + return new ec.FieldElementFp(this.q, V); + } + } + while (U.equals(BigInteger.ONE) || U.equals(qMinusOne)); + + return null; + }; + /*! + * Crypto-JS 2.5.4 BlockModes.js + * contribution from Simon Greatrix + */ + + (function(C) { + + // Create pad namespace + var C_pad = C.pad = {}; + + // Calculate the number of padding bytes required. + function _requiredPadding(cipher, message) { + var blockSizeInBytes = cipher._blocksize * 4; + var reqd = blockSizeInBytes - message.length % blockSizeInBytes; + return reqd; + } + + // Remove padding when the final byte gives the number of padding bytes. + var _unpadLength = function(cipher, message, alg, padding) { + var pad = message.pop(); + if (pad == 0) { + throw new Error("Invalid zero-length padding specified for " + alg + + ". Wrong cipher specification or key used?"); + } + var maxPad = cipher._blocksize * 4; + if (pad > maxPad) { + throw new Error("Invalid padding length of " + pad + + " specified for " + alg + + ". Wrong cipher specification or key used?"); + } + for (var i = 1; i < pad; i++) { + var b = message.pop(); + if (padding != undefined && padding != b) { + throw new Error("Invalid padding byte of 0x" + b.toString(16) + + " specified for " + alg + + ". Wrong cipher specification or key used?"); + } + } + }; + + // No-operation padding, used for stream ciphers + C_pad.NoPadding = { + pad: function(cipher, message) {}, + unpad: function(cipher, message) {} + }; + + // Zero Padding. + // + // If the message is not an exact number of blocks, the final block is + // completed with 0x00 bytes. There is no unpadding. + C_pad.ZeroPadding = { + pad: function(cipher, message) { + var blockSizeInBytes = cipher._blocksize * 4; + var reqd = message.length % blockSizeInBytes; + if (reqd != 0) { + for (reqd = blockSizeInBytes - reqd; reqd > 0; reqd--) { + message.push(0x00); + } + } + }, + + unpad: function(cipher, message) { + while (message[message.length - 1] == 0) { + message.pop(); + } + } + }; + + // ISO/IEC 7816-4 padding. + // + // Pads the plain text with an 0x80 byte followed by as many 0x00 + // bytes are required to complete the block. + C_pad.iso7816 = { + pad: function(cipher, message) { + var reqd = _requiredPadding(cipher, message); + message.push(0x80); + for (; reqd > 1; reqd--) { + message.push(0x00); + } + }, + + unpad: function(cipher, message) { + var padLength; + for (padLength = cipher._blocksize * 4; padLength > 0; padLength--) { + var b = message.pop(); + if (b == 0x80) return; + if (b != 0x00) { + throw new Error("ISO-7816 padding byte must be 0, not 0x" + b.toString(16) + + ". Wrong cipher specification or key used?"); + } + } + throw new Error( + "ISO-7816 padded beyond cipher block size. Wrong cipher specification or key used?" + ); + } + }; + + // ANSI X.923 padding + // + // The final block is padded with zeros except for the last byte of the + // last block which contains the number of padding bytes. + C_pad.ansix923 = { + pad: function(cipher, message) { + var reqd = _requiredPadding(cipher, message); + for (var i = 1; i < reqd; i++) { + message.push(0x00); + } + message.push(reqd); + }, + + unpad: function(cipher, message) { + _unpadLength(cipher, message, "ANSI X.923", 0); + } + }; + + // ISO 10126 + // + // The final block is padded with random bytes except for the last + // byte of the last block which contains the number of padding bytes. + C_pad.iso10126 = { + pad: function(cipher, message) { + var reqd = _requiredPadding(cipher, message); + for (var i = 1; i < reqd; i++) { + message.push(Math.floor(Math.random() * 256)); + } + message.push(reqd); + }, + + unpad: function(cipher, message) { + _unpadLength(cipher, message, "ISO 10126", undefined); + } + }; + + // PKCS7 padding + // + // PKCS7 is described in RFC 5652. Padding is in whole bytes. The + // value of each added byte is the number of bytes that are added, + // i.e. N bytes, each of value N are added. + C_pad.pkcs7 = { + pad: function(cipher, message) { + var reqd = _requiredPadding(cipher, message); + for (var i = 0; i < reqd; i++) { + message.push(reqd); + } + }, + + unpad: function(cipher, message) { + _unpadLength(cipher, message, "PKCS 7", message[message.length - 1]); + } + }; + + // Create mode namespace + var C_mode = C.mode = {}; + + /** + * Mode base "class". + */ + var Mode = C_mode.Mode = function(padding) { + if (padding) { + this._padding = padding; + } + }; + + Mode.prototype = { + encrypt: function(cipher, m, iv) { + this._padding.pad(cipher, m); + this._doEncrypt(cipher, m, iv); + }, + + decrypt: function(cipher, m, iv) { + this._doDecrypt(cipher, m, iv); + this._padding.unpad(cipher, m); + }, + + // Default padding + _padding: C_pad.iso7816 + }; + + + /** + * Electronic Code Book mode. + * + * ECB applies the cipher directly against each block of the input. + * + * ECB does not require an initialization vector. + */ + var ECB = C_mode.ECB = function() { + // Call parent constructor + Mode.apply(this, arguments); + }; + + // Inherit from Mode + var ECB_prototype = ECB.prototype = new Mode; + + // Concrete steps for Mode template + ECB_prototype._doEncrypt = function(cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + // Encrypt each block + for (var offset = 0; offset < m.length; offset += blockSizeInBytes) { + cipher._encryptblock(m, offset); + } + }; + ECB_prototype._doDecrypt = function(cipher, c, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + // Decrypt each block + for (var offset = 0; offset < c.length; offset += blockSizeInBytes) { + cipher._decryptblock(c, offset); + } + }; + + // ECB never uses an IV + ECB_prototype.fixOptions = function(options) { + options.iv = []; + }; + + + /** + * Cipher block chaining + * + * The first block is XORed with the IV. Subsequent blocks are XOR with the + * previous cipher output. + */ + var CBC = C_mode.CBC = function() { + // Call parent constructor + Mode.apply(this, arguments); + }; + + // Inherit from Mode + var CBC_prototype = CBC.prototype = new Mode; + + // Concrete steps for Mode template + CBC_prototype._doEncrypt = function(cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + + // Encrypt each block + for (var offset = 0; offset < m.length; offset += blockSizeInBytes) { + if (offset == 0) { + // XOR first block using IV + for (var i = 0; i < blockSizeInBytes; i++) + m[i] ^= iv[i]; + } else { + // XOR this block using previous crypted block + for (var i = 0; i < blockSizeInBytes; i++) + m[offset + i] ^= m[offset + i - blockSizeInBytes]; + } + // Encrypt block + cipher._encryptblock(m, offset); + } + }; + CBC_prototype._doDecrypt = function(cipher, c, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + + // At the start, the previously crypted block is the IV + var prevCryptedBlock = iv; + + // Decrypt each block + for (var offset = 0; offset < c.length; offset += blockSizeInBytes) { + // Save this crypted block + var thisCryptedBlock = c.slice(offset, offset + blockSizeInBytes); + // Decrypt block + cipher._decryptblock(c, offset); + // XOR decrypted block using previous crypted block + for (var i = 0; i < blockSizeInBytes; i++) { + c[offset + i] ^= prevCryptedBlock[i]; + } + prevCryptedBlock = thisCryptedBlock; + } + }; + + + /** + * Cipher feed back + * + * The cipher output is XORed with the plain text to produce the cipher output, + * which is then fed back into the cipher to produce a bit pattern to XOR the + * next block with. + * + * This is a stream cipher mode and does not require padding. + */ + var CFB = C_mode.CFB = function() { + // Call parent constructor + Mode.apply(this, arguments); + }; + + // Inherit from Mode + var CFB_prototype = CFB.prototype = new Mode; + + // Override padding + CFB_prototype._padding = C_pad.NoPadding; + + // Concrete steps for Mode template + CFB_prototype._doEncrypt = function(cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4, + keystream = iv.slice(0); + + // Encrypt each byte + for (var i = 0; i < m.length; i++) { + + var j = i % blockSizeInBytes; + if (j == 0) cipher._encryptblock(keystream, 0); + + m[i] ^= keystream[j]; + keystream[j] = m[i]; + } + }; + CFB_prototype._doDecrypt = function(cipher, c, iv) { + var blockSizeInBytes = cipher._blocksize * 4, + keystream = iv.slice(0); + + // Encrypt each byte + for (var i = 0; i < c.length; i++) { + + var j = i % blockSizeInBytes; + if (j == 0) cipher._encryptblock(keystream, 0); + + var b = c[i]; + c[i] ^= keystream[j]; + keystream[j] = b; + } + }; + + + /** + * Output feed back + * + * The cipher repeatedly encrypts its own output. The output is XORed with the + * plain text to produce the cipher text. + * + * This is a stream cipher mode and does not require padding. + */ + var OFB = C_mode.OFB = function() { + // Call parent constructor + Mode.apply(this, arguments); + }; + + // Inherit from Mode + var OFB_prototype = OFB.prototype = new Mode; + + // Override padding + OFB_prototype._padding = C_pad.NoPadding; + + // Concrete steps for Mode template + OFB_prototype._doEncrypt = function(cipher, m, iv) { + + var blockSizeInBytes = cipher._blocksize * 4, + keystream = iv.slice(0); + + // Encrypt each byte + for (var i = 0; i < m.length; i++) { + + // Generate keystream + if (i % blockSizeInBytes == 0) + cipher._encryptblock(keystream, 0); + + // Encrypt byte + m[i] ^= keystream[i % blockSizeInBytes]; + + } + }; + OFB_prototype._doDecrypt = OFB_prototype._doEncrypt; + + /** + * Counter + * @author Gergely Risko + * + * After every block the last 4 bytes of the IV is increased by one + * with carry and that IV is used for the next block. + * + * This is a stream cipher mode and does not require padding. + */ + var CTR = C_mode.CTR = function() { + // Call parent constructor + Mode.apply(this, arguments); + }; + + // Inherit from Mode + var CTR_prototype = CTR.prototype = new Mode; + + // Override padding + CTR_prototype._padding = C_pad.NoPadding; + + CTR_prototype._doEncrypt = function(cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + var counter = iv.slice(0); + + for (var i = 0; i < m.length;) { + // do not lose iv + var keystream = counter.slice(0); + + // Generate keystream for next block + cipher._encryptblock(keystream, 0); + + // XOR keystream with block + for (var j = 0; i < m.length && j < blockSizeInBytes; j++, i++) { + m[i] ^= keystream[j]; + } + + // Increase counter + if (++(counter[blockSizeInBytes - 1]) == 256) { + counter[blockSizeInBytes - 1] = 0; + if (++(counter[blockSizeInBytes - 2]) == 256) { + counter[blockSizeInBytes - 2] = 0; + if (++(counter[blockSizeInBytes - 3]) == 256) { + counter[blockSizeInBytes - 3] = 0; + ++(counter[blockSizeInBytes - 4]); + } + } + } + } + }; + CTR_prototype._doDecrypt = CTR_prototype._doEncrypt; + + })(Crypto); + + /*! + * Crypto-JS v2.5.4 PBKDF2.js + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2009-2013, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ + (function() { + + // Shortcuts + var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8, + Binary = charenc.Binary; + + C.PBKDF2 = function(password, salt, keylen, options) { + + // Convert to byte arrays + if (password.constructor == String) password = UTF8.stringToBytes(password); + if (salt.constructor == String) salt = UTF8.stringToBytes(salt); + /* else, assume byte arrays already */ + + // Defaults + var hasher = options && options.hasher || C.SHA1, + iterations = options && options.iterations || 1; + + // Pseudo-random function + function PRF(password, salt) { + return C.HMAC(hasher, salt, password, { + asBytes: true + }); + } + + // Generate key + var derivedKeyBytes = [], + blockindex = 1; + while (derivedKeyBytes.length < keylen) { + var block = PRF(password, salt.concat(util.wordsToBytes([blockindex]))); + for (var u = block, i = 1; i < iterations; i++) { + u = PRF(password, u); + for (var j = 0; j < block.length; j++) block[j] ^= u[j]; + } + derivedKeyBytes = derivedKeyBytes.concat(block); + blockindex++; + } + + // Truncate excess bytes + derivedKeyBytes.length = keylen; + + return options && options.asBytes ? derivedKeyBytes : + options && options.asString ? Binary.bytesToString(derivedKeyBytes) : + util.bytesToHex(derivedKeyBytes); + + }; + + })(); + + /* + * Copyright (c) 2010-2011 Intalio Pte, All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + // https://github.com/cheongwy/node-scrypt-js + (function() { + + var MAX_VALUE = 2147483647; + var workerUrl = null; + + //function scrypt(byte[] passwd, byte[] salt, int N, int r, int p, int dkLen) + /* + * N = Cpu cost + * r = Memory cost + * p = parallelization cost + * + */ + GLOBAL.Crypto_scrypt = function(passwd, salt, N, r, p, dkLen, callback) { + if (N == 0 || (N & (N - 1)) != 0) throw Error("N must be > 0 and a power of 2"); + + if (N > MAX_VALUE / 128 / r) throw Error("Parameter N is too large"); + if (r > MAX_VALUE / 128 / p) throw Error("Parameter r is too large"); + + var PBKDF2_opts = { + iterations: 1, + hasher: Crypto.SHA256, + asBytes: true + }; + + var B = Crypto.PBKDF2(passwd, salt, p * 128 * r, PBKDF2_opts); + + try { + var i = 0; + var worksDone = 0; + var makeWorker = function() { + if (!workerUrl) { + var code = '(' + scryptCore.toString() + ')()'; + var blob; + try { + blob = new Blob([code], { + type: "text/javascript" + }); + } catch (e) { + GLOBAL.BlobBuilder = GLOBAL.BlobBuilder || GLOBAL.WebKitBlobBuilder || + GLOBAL.MozBlobBuilder || + GLOBAL.MSBlobBuilder; + blob = new BlobBuilder(); + blob.append(code); + blob = blob.getBlob("text/javascript"); + } + workerUrl = URL.createObjectURL(blob); + } + var worker = new Worker(workerUrl); + worker.onmessage = function(event) { + var Bi = event.data[0], + Bslice = event.data[1]; + worksDone++; + + if (i < p) { + worker.postMessage([N, r, p, B, i++]); + } + + var length = Bslice.length, + destPos = Bi * 128 * r, + srcPos = 0; + while (length--) { + B[destPos++] = Bslice[srcPos++]; + } + + if (worksDone == p) { + callback(Crypto.PBKDF2(passwd, B, dkLen, PBKDF2_opts)); + } + }; + return worker; + }; + var workers = [makeWorker(), makeWorker()]; + workers[0].postMessage([N, r, p, B, i++]); + if (p > 1) { + workers[1].postMessage([N, r, p, B, i++]); + } + } catch (e) { + GLOBAL.setTimeout(function() { + scryptCore(); + callback(Crypto.PBKDF2(passwd, B, dkLen, PBKDF2_opts)); + }, 0); + } + + // using this function to enclose everything needed to create a worker (but also invokable directly for synchronous use) + function scryptCore() { + var XY = [], + V = []; + + if (typeof B === 'undefined') { + onmessage = function(event) { + var data = event.data; + var N = data[0], + r = data[1], + p = data[2], + B = data[3], + i = data[4]; + + var Bslice = []; + arraycopy32(B, i * 128 * r, Bslice, 0, 128 * r); + smix(Bslice, 0, r, N, V, XY); + + postMessage([i, Bslice]); + }; + } else { + for (var i = 0; i < p; i++) { + smix(B, i * 128 * r, r, N, V, XY); + } + } + + function smix(B, Bi, r, N, V, XY) { + var Xi = 0; + var Yi = 128 * r; + var i; + + arraycopy32(B, Bi, XY, Xi, Yi); + + for (i = 0; i < N; i++) { + arraycopy32(XY, Xi, V, i * Yi, Yi); + blockmix_salsa8(XY, Xi, Yi, r); + } + + for (i = 0; i < N; i++) { + var j = integerify(XY, Xi, r) & (N - 1); + blockxor(V, j * Yi, XY, Xi, Yi); + blockmix_salsa8(XY, Xi, Yi, r); + } + + arraycopy32(XY, Xi, B, Bi, Yi); + } + + function blockmix_salsa8(BY, Bi, Yi, r) { + var X = []; + var i; + + arraycopy32(BY, Bi + (2 * r - 1) * 64, X, 0, 64); + + for (i = 0; i < 2 * r; i++) { + blockxor(BY, i * 64, X, 0, 64); + salsa20_8(X); + arraycopy32(X, 0, BY, Yi + (i * 64), 64); + } + + for (i = 0; i < r; i++) { + arraycopy32(BY, Yi + (i * 2) * 64, BY, Bi + (i * 64), 64); + } + + for (i = 0; i < r; i++) { + arraycopy32(BY, Yi + (i * 2 + 1) * 64, BY, Bi + (i + r) * 64, 64); + } + } + + function R(a, b) { + return (a << b) | (a >>> (32 - b)); + } + + function salsa20_8(B) { + var B32 = new Array(32); + var x = new Array(32); + var i; + + for (i = 0; i < 16; i++) { + B32[i] = (B[i * 4 + 0] & 0xff) << 0; + B32[i] |= (B[i * 4 + 1] & 0xff) << 8; + B32[i] |= (B[i * 4 + 2] & 0xff) << 16; + B32[i] |= (B[i * 4 + 3] & 0xff) << 24; + } + + arraycopy(B32, 0, x, 0, 16); + + for (i = 8; i > 0; i -= 2) { + x[4] ^= R(x[0] + x[12], 7); + x[8] ^= R(x[4] + x[0], 9); + x[12] ^= R(x[8] + x[4], 13); + x[0] ^= R(x[12] + x[8], 18); + x[9] ^= R(x[5] + x[1], 7); + x[13] ^= R(x[9] + x[5], 9); + x[1] ^= R(x[13] + x[9], 13); + x[5] ^= R(x[1] + x[13], 18); + x[14] ^= R(x[10] + x[6], 7); + x[2] ^= R(x[14] + x[10], 9); + x[6] ^= R(x[2] + x[14], 13); + x[10] ^= R(x[6] + x[2], 18); + x[3] ^= R(x[15] + x[11], 7); + x[7] ^= R(x[3] + x[15], 9); + x[11] ^= R(x[7] + x[3], 13); + x[15] ^= R(x[11] + x[7], 18); + x[1] ^= R(x[0] + x[3], 7); + x[2] ^= R(x[1] + x[0], 9); + x[3] ^= R(x[2] + x[1], 13); + x[0] ^= R(x[3] + x[2], 18); + x[6] ^= R(x[5] + x[4], 7); + x[7] ^= R(x[6] + x[5], 9); + x[4] ^= R(x[7] + x[6], 13); + x[5] ^= R(x[4] + x[7], 18); + x[11] ^= R(x[10] + x[9], 7); + x[8] ^= R(x[11] + x[10], 9); + x[9] ^= R(x[8] + x[11], 13); + x[10] ^= R(x[9] + x[8], 18); + x[12] ^= R(x[15] + x[14], 7); + x[13] ^= R(x[12] + x[15], 9); + x[14] ^= R(x[13] + x[12], 13); + x[15] ^= R(x[14] + x[13], 18); + } + + for (i = 0; i < 16; ++i) B32[i] = x[i] + B32[i]; + + for (i = 0; i < 16; i++) { + var bi = i * 4; + B[bi + 0] = (B32[i] >> 0 & 0xff); + B[bi + 1] = (B32[i] >> 8 & 0xff); + B[bi + 2] = (B32[i] >> 16 & 0xff); + B[bi + 3] = (B32[i] >> 24 & 0xff); + } + } + + function blockxor(S, Si, D, Di, len) { + var i = len >> 6; + while (i--) { + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + } + } + + function integerify(B, bi, r) { + var n; + + bi += (2 * r - 1) * 64; + + n = (B[bi + 0] & 0xff) << 0; + n |= (B[bi + 1] & 0xff) << 8; + n |= (B[bi + 2] & 0xff) << 16; + n |= (B[bi + 3] & 0xff) << 24; + + return n; + } + + function arraycopy(src, srcPos, dest, destPos, length) { + while (length--) { + dest[destPos++] = src[srcPos++]; + } + } + + function arraycopy32(src, srcPos, dest, destPos, length) { + var i = length >> 5; + while (i--) { + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + } + } + } // scryptCore + }; // GLOBAL.Crypto_scrypt + })(); + + /*! + * Crypto-JS v2.5.4 AES.js + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2009-2013, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ + (function() { + + // Shortcuts + var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8; + + // Precomputed SBOX + var SBOX = [0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, + 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, + 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, + 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, + 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, + 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, + 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, + 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, + 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, + 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 + ]; + + // Compute inverse SBOX lookup table + for (var INVSBOX = [], i = 0; i < 256; i++) INVSBOX[SBOX[i]] = i; + + // Compute multiplication in GF(2^8) lookup tables + var MULT2 = [], + MULT3 = [], + MULT9 = [], + MULTB = [], + MULTD = [], + MULTE = []; + + function xtime(a, b) { + for (var result = 0, i = 0; i < 8; i++) { + if (b & 1) result ^= a; + var hiBitSet = a & 0x80; + a = (a << 1) & 0xFF; + if (hiBitSet) a ^= 0x1b; + b >>>= 1; + } + return result; + } + + for (var i = 0; i < 256; i++) { + MULT2[i] = xtime(i, 2); + MULT3[i] = xtime(i, 3); + MULT9[i] = xtime(i, 9); + MULTB[i] = xtime(i, 0xB); + MULTD[i] = xtime(i, 0xD); + MULTE[i] = xtime(i, 0xE); + } + + // Precomputed RCon lookup + var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]; + + // Inner state + var state = [ + [], + [], + [], + [] + ], + keylength, + nrounds, + keyschedule; + + var AES = C.AES = { + + /** + * Public API + */ + + encrypt: function(message, password, options) { + + options = options || {}; + + // Determine mode + var mode = options.mode || new C.mode.OFB; + + // Allow mode to override options + if (mode.fixOptions) mode.fixOptions(options); + + var + + // Convert to bytes if message is a string + m = ( + message.constructor == String ? + UTF8.stringToBytes(message) : + message + ), + + // Generate random IV + iv = options.iv || util.randomBytes(AES._blocksize * 4), + + // Generate key + k = ( + password.constructor == String ? + // Derive key from pass-phrase + C.PBKDF2(password, iv, 32, { + asBytes: true + }) : + // else, assume byte array representing cryptographic key + password + ); + + // Encrypt + AES._init(k); + mode.encrypt(AES, m, iv); + + // Return ciphertext + m = options.iv ? m : iv.concat(m); + return (options && options.asBytes) ? m : util.bytesToBase64(m); + + }, + + decrypt: function(ciphertext, password, options) { + + options = options || {}; + + // Determine mode + var mode = options.mode || new C.mode.OFB; + + // Allow mode to override options + if (mode.fixOptions) mode.fixOptions(options); + + var + + // Convert to bytes if ciphertext is a string + c = ( + ciphertext.constructor == String ? + util.base64ToBytes(ciphertext) : + ciphertext + ), + + // Separate IV and message + iv = options.iv || c.splice(0, AES._blocksize * 4), + + // Generate key + k = ( + password.constructor == String ? + // Derive key from pass-phrase + C.PBKDF2(password, iv, 32, { + asBytes: true + }) : + // else, assume byte array representing cryptographic key + password + ); + + // Decrypt + AES._init(k); + mode.decrypt(AES, c, iv); + + // Return plaintext + return (options && options.asBytes) ? c : UTF8.bytesToString(c); + + }, + + + /** + * Package private methods and properties + */ + + _blocksize: 4, + + _encryptblock: function(m, offset) { + + // Set input + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = m[offset + col * 4 + row]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[col][row]; + } + + for (var round = 1; round < nrounds; round++) { + + // Sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = SBOX[state[row][col]]; + } + + // Shift rows + state[1].push(state[1].shift()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].unshift(state[3].pop()); + + // Mix columns + for (var col = 0; col < 4; col++) { + + var s0 = state[0][col], + s1 = state[1][col], + s2 = state[2][col], + s3 = state[3][col]; + + state[0][col] = MULT2[s0] ^ MULT3[s1] ^ s2 ^ s3; + state[1][col] = s0 ^ MULT2[s1] ^ MULT3[s2] ^ s3; + state[2][col] = s0 ^ s1 ^ MULT2[s2] ^ MULT3[s3]; + state[3][col] = MULT3[s0] ^ s1 ^ s2 ^ MULT2[s3]; + + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[round * 4 + col][row]; + } + + } + + // Sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = SBOX[state[row][col]]; + } + + // Shift rows + state[1].push(state[1].shift()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].unshift(state[3].pop()); + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[nrounds * 4 + col][row]; + } + + // Set output + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + m[offset + col * 4 + row] = state[row][col]; + } + + }, + + _decryptblock: function(c, offset) { + + // Set input + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = c[offset + col * 4 + row]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[nrounds * 4 + col][row]; + } + + for (var round = 1; round < nrounds; round++) { + + // Inv shift rows + state[1].unshift(state[1].pop()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].push(state[3].shift()); + + // Inv sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = INVSBOX[state[row][col]]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[(nrounds - round) * 4 + col][row]; + } + + // Inv mix columns + for (var col = 0; col < 4; col++) { + + var s0 = state[0][col], + s1 = state[1][col], + s2 = state[2][col], + s3 = state[3][col]; + + state[0][col] = MULTE[s0] ^ MULTB[s1] ^ MULTD[s2] ^ MULT9[s3]; + state[1][col] = MULT9[s0] ^ MULTE[s1] ^ MULTB[s2] ^ MULTD[s3]; + state[2][col] = MULTD[s0] ^ MULT9[s1] ^ MULTE[s2] ^ MULTB[s3]; + state[3][col] = MULTB[s0] ^ MULTD[s1] ^ MULT9[s2] ^ MULTE[s3]; + + } + + } + + // Inv shift rows + state[1].unshift(state[1].pop()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].push(state[3].shift()); + + // Inv sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = INVSBOX[state[row][col]]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[col][row]; + } + + // Set output + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + c[offset + col * 4 + row] = state[row][col]; + } + + }, + + + /** + * Private methods + */ + + _init: function(k) { + keylength = k.length / 4; + nrounds = keylength + 6; + AES._keyexpansion(k); + }, + + // Generate a key schedule + _keyexpansion: function(k) { + + keyschedule = []; + + for (var row = 0; row < keylength; row++) { + keyschedule[row] = [ + k[row * 4], + k[row * 4 + 1], + k[row * 4 + 2], + k[row * 4 + 3] + ]; + } + + for (var row = keylength; row < AES._blocksize * (nrounds + 1); row++) { + + var temp = [ + keyschedule[row - 1][0], + keyschedule[row - 1][1], + keyschedule[row - 1][2], + keyschedule[row - 1][3] + ]; + + if (row % keylength == 0) { + + // Rot word + temp.push(temp.shift()); + + // Sub word + temp[0] = SBOX[temp[0]]; + temp[1] = SBOX[temp[1]]; + temp[2] = SBOX[temp[2]]; + temp[3] = SBOX[temp[3]]; + + temp[0] ^= RCON[row / keylength]; + + } else if (keylength > 6 && row % keylength == 4) { + + // Sub word + temp[0] = SBOX[temp[0]]; + temp[1] = SBOX[temp[1]]; + temp[2] = SBOX[temp[2]]; + temp[3] = SBOX[temp[3]]; + + } + + keyschedule[row] = [ + keyschedule[row - keylength][0] ^ temp[0], + keyschedule[row - keylength][1] ^ temp[1], + keyschedule[row - keylength][2] ^ temp[2], + keyschedule[row - keylength][3] ^ temp[3] + ]; + + } + + } + + }; + + })(); + + /* + * Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) + * Ported to JavaScript by bitaddress.org + */ + ec.FieldElementFp.fastLucasSequence = function(p, P, Q, k) { + // TODO Research and apply "common-multiplicand multiplication here" + + var n = k.bitLength(); + var s = k.getLowestSetBit(); + var Uh = BigInteger.ONE; + var Vl = BigInteger.TWO; + var Vh = P; + var Ql = BigInteger.ONE; + var Qh = BigInteger.ONE; + + for (var j = n - 1; j >= s + 1; --j) { + Ql = Ql.multiply(Qh).mod(p); + if (k.testBit(j)) { + Qh = Ql.multiply(Q).mod(p); + Uh = Uh.multiply(Vh).mod(p); + Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); + Vh = Vh.multiply(Vh).subtract(Qh.shiftLeft(1)).mod(p); + } else { + Qh = Ql; + Uh = Uh.multiply(Vl).subtract(Ql).mod(p); + Vh = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); + Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p); + } + } + + Ql = Ql.multiply(Qh).mod(p); + Qh = Ql.multiply(Q).mod(p); + Uh = Uh.multiply(Vl).subtract(Ql).mod(p); + Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); + Ql = Ql.multiply(Qh).mod(p); + + for (var j = 1; j <= s; ++j) { + Uh = Uh.multiply(Vl).mod(p); + Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p); + Ql = Ql.multiply(Ql).mod(p); + } + + return [Uh, Vl]; + }; + + // ---------------- + // ECPointFp constructor + ec.PointFp = function(curve, x, y, z, compressed) { + this.curve = curve; + this.x = x; + this.y = y; + // Projective coordinates: either zinv == null or z * zinv == 1 + // z and zinv are just BigIntegers, not fieldElements + if (z == null) { + this.z = BigInteger.ONE; + } else { + this.z = z; + } + this.zinv = null; + // compression flag + this.compressed = !!compressed; + }; + + ec.PointFp.prototype.getX = function() { + if (this.zinv == null) { + this.zinv = this.z.modInverse(this.curve.q); + } + var r = this.x.toBigInteger().multiply(this.zinv); + this.curve.reduce(r); + return this.curve.fromBigInteger(r); + }; + + ec.PointFp.prototype.getY = function() { + if (this.zinv == null) { + this.zinv = this.z.modInverse(this.curve.q); + } + var r = this.y.toBigInteger().multiply(this.zinv); + this.curve.reduce(r); + return this.curve.fromBigInteger(r); + }; + + ec.PointFp.prototype.equals = function(other) { + if (other == this) return true; + if (this.isInfinity()) return other.isInfinity(); + if (other.isInfinity()) return this.isInfinity(); + var u, v; + // u = Y2 * Z1 - Y1 * Z2 + u = other.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(other.z)).mod( + this.curve.q); + if (!u.equals(BigInteger.ZERO)) return false; + // v = X2 * Z1 - X1 * Z2 + v = other.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(other.z)).mod( + this.curve.q); + return v.equals(BigInteger.ZERO); + }; + + ec.PointFp.prototype.isInfinity = function() { + if ((this.x == null) && (this.y == null)) return true; + return this.z.equals(BigInteger.ZERO) && !this.y.toBigInteger().equals(BigInteger.ZERO); + }; + + ec.PointFp.prototype.negate = function() { + return new ec.PointFp(this.curve, this.x, this.y.negate(), this.z); + }; + + ec.PointFp.prototype.add = function(b) { + if (this.isInfinity()) return b; + if (b.isInfinity()) return this; + + // u = Y2 * Z1 - Y1 * Z2 + var u = b.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(b.z)).mod( + this.curve.q); + // v = X2 * Z1 - X1 * Z2 + var v = b.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(b.z)).mod( + this.curve.q); + + + if (BigInteger.ZERO.equals(v)) { + if (BigInteger.ZERO.equals(u)) { + return this.twice(); // this == b, so double + } + return this.curve.getInfinity(); // this = -b, so infinity + } + + var THREE = new BigInteger("3"); + var x1 = this.x.toBigInteger(); + var y1 = this.y.toBigInteger(); + var x2 = b.x.toBigInteger(); + var y2 = b.y.toBigInteger(); + + var v2 = v.square(); + var v3 = v2.multiply(v); + var x1v2 = x1.multiply(v2); + var zu2 = u.square().multiply(this.z); + + // x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3) + var x3 = zu2.subtract(x1v2.shiftLeft(1)).multiply(b.z).subtract(v3).multiply(v).mod(this.curve.q); + // y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3 + var y3 = x1v2.multiply(THREE).multiply(u).subtract(y1.multiply(v3)).subtract(zu2.multiply(u)).multiply( + b.z).add(u.multiply(v3)).mod(this.curve.q); + // z3 = v^3 * z1 * z2 + var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.q); + + return new ec.PointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), + z3); + }; + + ec.PointFp.prototype.twice = function() { + if (this.isInfinity()) return this; + if (this.y.toBigInteger().signum() == 0) return this.curve.getInfinity(); + + // TODO: optimized handling of constants + var THREE = new BigInteger("3"); + var x1 = this.x.toBigInteger(); + var y1 = this.y.toBigInteger(); + + var y1z1 = y1.multiply(this.z); + var y1sqz1 = y1z1.multiply(y1).mod(this.curve.q); + var a = this.curve.a.toBigInteger(); + + // w = 3 * x1^2 + a * z1^2 + var w = x1.square().multiply(THREE); + if (!BigInteger.ZERO.equals(a)) { + w = w.add(this.z.square().multiply(a)); + } + w = w.mod(this.curve.q); + //this.curve.reduce(w); + // x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1) + var x3 = w.square().subtract(x1.shiftLeft(3).multiply(y1sqz1)).shiftLeft(1).multiply(y1z1).mod( + this.curve.q); + // y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3 + var y3 = w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1)).shiftLeft(2).multiply( + y1sqz1).subtract(w.square().multiply(w)).mod(this.curve.q); + // z3 = 8 * (y1 * z1)^3 + var z3 = y1z1.square().multiply(y1z1).shiftLeft(3).mod(this.curve.q); + + return new ec.PointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), + z3); + }; + + // Simple NAF (Non-Adjacent Form) multiplication algorithm + // TODO: modularize the multiplication algorithm + ec.PointFp.prototype.multiply = function(k) { + if (this.isInfinity()) return this; + if (k.signum() == 0) return this.curve.getInfinity(); + + var e = k; + var h = e.multiply(new BigInteger("3")); + + var neg = this.negate(); + var R = this; + + var i; + for (i = h.bitLength() - 2; i > 0; --i) { + R = R.twice(); + + var hBit = h.testBit(i); + var eBit = e.testBit(i); + + if (hBit != eBit) { + R = R.add(hBit ? this : neg); + } + } + + return R; + }; + + // Compute this*j + x*k (simultaneous multiplication) + ec.PointFp.prototype.multiplyTwo = function(j, x, k) { + var i; + if (j.bitLength() > k.bitLength()) + i = j.bitLength() - 1; + else + i = k.bitLength() - 1; + + var R = this.curve.getInfinity(); + var both = this.add(x); + while (i >= 0) { + R = R.twice(); + if (j.testBit(i)) { + if (k.testBit(i)) { + R = R.add(both); + } else { + R = R.add(this); + } + } else { + if (k.testBit(i)) { + R = R.add(x); + } + } + --i; + } + + return R; + }; + + // patched by bitaddress.org and Casascius for use with Bitcoin.ECKey + // patched by coretechs to support compressed public keys + ec.PointFp.prototype.getEncoded = function(compressed) { + var x = this.getX().toBigInteger(); + var y = this.getY().toBigInteger(); + var len = 32; // integerToBytes will zero pad if integer is less than 32 bytes. 32 bytes length is required by the Bitcoin protocol. + var enc = ec.integerToBytes(x, len); + + // when compressed prepend byte depending if y point is even or odd + if (compressed) { + if (y.isEven()) { + enc.unshift(0x02); + } else { + enc.unshift(0x03); + } + } else { + enc.unshift(0x04); + enc = enc.concat(ec.integerToBytes(y, len)); // uncompressed public key appends the bytes of the y point + } + return enc; + }; + + ec.PointFp.decodeFrom = function(curve, enc) { + var type = enc[0]; + var dataLen = enc.length - 1; + + // Extract x and y as byte arrays + var xBa = enc.slice(1, 1 + dataLen / 2); + var yBa = enc.slice(1 + dataLen / 2, 1 + dataLen); + + // Prepend zero byte to prevent interpretation as negative integer + xBa.unshift(0); + yBa.unshift(0); + + // Convert to BigIntegers + var x = new BigInteger(xBa); + var y = new BigInteger(yBa); + + // Return point + return new ec.PointFp(curve, curve.fromBigInteger(x), curve.fromBigInteger(y)); + }; + + ec.PointFp.prototype.add2D = function(b) { + if (this.isInfinity()) return b; + if (b.isInfinity()) return this; + + if (this.x.equals(b.x)) { + if (this.y.equals(b.y)) { + // this = b, i.e. this must be doubled + return this.twice(); + } + // this = -b, i.e. the result is the point at infinity + return this.curve.getInfinity(); + } + + var x_x = b.x.subtract(this.x); + var y_y = b.y.subtract(this.y); + var gamma = y_y.divide(x_x); + + var x3 = gamma.square().subtract(this.x).subtract(b.x); + var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y); + + return new ec.PointFp(this.curve, x3, y3); + }; + + ec.PointFp.prototype.twice2D = function() { + if (this.isInfinity()) return this; + if (this.y.toBigInteger().signum() == 0) { + // if y1 == 0, then (x1, y1) == (x1, -y1) + // and hence this = -this and thus 2(x1, y1) == infinity + return this.curve.getInfinity(); + } + + var TWO = this.curve.fromBigInteger(BigInteger.valueOf(2)); + var THREE = this.curve.fromBigInteger(BigInteger.valueOf(3)); + var gamma = this.x.square().multiply(THREE).add(this.curve.a).divide(this.y.multiply(TWO)); + + var x3 = gamma.square().subtract(this.x.multiply(TWO)); + var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y); + + return new ec.PointFp(this.curve, x3, y3); + }; + + ec.PointFp.prototype.multiply2D = function(k) { + if (this.isInfinity()) return this; + if (k.signum() == 0) return this.curve.getInfinity(); + + var e = k; + var h = e.multiply(new BigInteger("3")); + + var neg = this.negate(); + var R = this; + + var i; + for (i = h.bitLength() - 2; i > 0; --i) { + R = R.twice(); + + var hBit = h.testBit(i); + var eBit = e.testBit(i); + + if (hBit != eBit) { + R = R.add2D(hBit ? this : neg); + } + } + + return R; + }; + + ec.PointFp.prototype.isOnCurve = function() { + var x = this.getX().toBigInteger(); + var y = this.getY().toBigInteger(); + var a = this.curve.getA().toBigInteger(); + var b = this.curve.getB().toBigInteger(); + var n = this.curve.getQ(); + var lhs = y.multiply(y).mod(n); + var rhs = x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(n); + return lhs.equals(rhs); + }; + + ec.PointFp.prototype.toString = function() { + return '(' + this.getX().toBigInteger().toString() + ',' + this.getY().toBigInteger().toString() + + ')'; + }; + + /** + * Validate an elliptic curve point. + * + * See SEC 1, section 3.2.2.1: Elliptic Curve Public Key Validation Primitive + */ + ec.PointFp.prototype.validate = function() { + var n = this.curve.getQ(); + + // Check Q != O + if (this.isInfinity()) { + throw new Error("Point is at infinity."); + } + + // Check coordinate bounds + var x = this.getX().toBigInteger(); + var y = this.getY().toBigInteger(); + if (x.compareTo(BigInteger.ONE) < 0 || x.compareTo(n.subtract(BigInteger.ONE)) > 0) { + throw new Error('x coordinate out of bounds'); + } + if (y.compareTo(BigInteger.ONE) < 0 || y.compareTo(n.subtract(BigInteger.ONE)) > 0) { + throw new Error('y coordinate out of bounds'); + } + + // Check y^2 = x^3 + ax + b (mod n) + if (!this.isOnCurve()) { + throw new Error("Point is not on the curve."); + } + + // Check nQ = 0 (Q is a scalar multiple of G) + if (this.multiply(n).isInfinity()) { + // TODO: This check doesn't work - fix. + throw new Error("Point is not a scalar multiple of G."); + } + + return true; + }; + + + + + // ---------------- + // ECCurveFp constructor + ec.CurveFp = function(q, a, b) { + this.q = q; + this.a = this.fromBigInteger(a); + this.b = this.fromBigInteger(b); + this.infinity = new ec.PointFp(this, null, null); + this.reducer = new Barrett(this.q); + } + + ec.CurveFp.prototype.getQ = function() { + return this.q; + }; + + ec.CurveFp.prototype.getA = function() { + return this.a; + }; + + ec.CurveFp.prototype.getB = function() { + return this.b; + }; + + ec.CurveFp.prototype.equals = function(other) { + if (other == this) return true; + return (this.q.equals(other.q) && this.a.equals(other.a) && this.b.equals(other.b)); + }; + + ec.CurveFp.prototype.getInfinity = function() { + return this.infinity; + }; + + ec.CurveFp.prototype.fromBigInteger = function(x) { + return new ec.FieldElementFp(this.q, x); + }; + + ec.CurveFp.prototype.reduce = function(x) { + this.reducer.reduce(x); + }; + + // for now, work with hex strings because they're easier in JS + // compressed support added by bitaddress.org + ec.CurveFp.prototype.decodePointHex = function(s) { + var firstByte = parseInt(s.substr(0, 2), 16); + switch (firstByte) { // first byte + case 0: + return this.infinity; + case 2: // compressed + case 3: // compressed + var yTilde = firstByte & 1; + var xHex = s.substr(2, s.length - 2); + var X1 = new BigInteger(xHex, 16); + return this.decompressPoint(yTilde, X1); + case 4: // uncompressed + case 6: // hybrid + case 7: // hybrid + var len = (s.length - 2) / 2; + var xHex = s.substr(2, len); + var yHex = s.substr(len + 2, len); + + return new ec.PointFp(this, + this.fromBigInteger(new BigInteger(xHex, 16)), + this.fromBigInteger(new BigInteger(yHex, 16))); + + default: // unsupported + return null; + } + }; + + ec.CurveFp.prototype.encodePointHex = function(p) { + if (p.isInfinity()) return "00"; + var xHex = p.getX().toBigInteger().toString(16); + var yHex = p.getY().toBigInteger().toString(16); + var oLen = this.getQ().toString(16).length; + if ((oLen % 2) != 0) oLen++; + while (xHex.length < oLen) { + xHex = "0" + xHex; + } + while (yHex.length < oLen) { + yHex = "0" + yHex; + } + return "04" + xHex + yHex; + }; + + /* + * Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) + * Ported to JavaScript by bitaddress.org + * + * Number yTilde + * BigInteger X1 + */ + ec.CurveFp.prototype.decompressPoint = function(yTilde, X1) { + var x = this.fromBigInteger(X1); + var alpha = x.multiply(x.square().add(this.getA())).add(this.getB()); + var beta = alpha.sqrt(); + // if we can't find a sqrt we haven't got a point on the curve - run! + if (beta == null) throw new Error("Invalid point compression"); + var betaValue = beta.toBigInteger(); + var bit0 = betaValue.testBit(0) ? 1 : 0; + if (bit0 != yTilde) { + // Use the other root + beta = this.fromBigInteger(this.getQ().subtract(betaValue)); + } + return new ec.PointFp(this, x, beta, null, true); + }; + + + ec.fromHex = function(s) { + return new BigInteger(s, 16); + }; + + ec.integerToBytes = function(i, len) { + var bytes = i.toByteArrayUnsigned(); + if (len < bytes.length) { + bytes = bytes.slice(bytes.length - len); + } else + while (len > bytes.length) { + bytes.unshift(0); + } + return bytes; + }; + + + // Named EC curves + // ---------------- + // X9ECParameters constructor + ec.X9Parameters = function(curve, g, n, h) { + this.curve = curve; + this.g = g; + this.n = n; + this.h = h; + } + ec.X9Parameters.prototype.getCurve = function() { + return this.curve; + }; + ec.X9Parameters.prototype.getG = function() { + return this.g; + }; + ec.X9Parameters.prototype.getN = function() { + return this.n; + }; + ec.X9Parameters.prototype.getH = function() { + return this.h; + }; + + // secp256k1 is the Curve used by Bitcoin + ec.secNamedCurves = { + // used by Bitcoin + "secp256k1": function() { + // p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1 + var p = ec.fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"); + var a = BigInteger.ZERO; + var b = ec.fromHex("7"); + var n = ec.fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"); + var h = BigInteger.ONE; + var curve = new ec.CurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798" + + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"); + return new ec.X9Parameters(curve, G, n, h); + } + }; + + // secp256k1 called by Bitcoin's ECKEY + ec.getSECCurveByName = function(name) { + if (ec.secNamedCurves[name] == undefined) return null; + return ec.secNamedCurves[name](); + } +})(typeof global !== "undefined" ? global : window); + +//bitTrx.js +(function(GLOBAL) { + + var bitjs = GLOBAL.bitjs = function() {}; + + function ascii_to_hexa(str) { + var arr1 = []; + for (var n = 0, l = str.length; n < l; n++) { + var hex = Number(str.charCodeAt(n)).toString(16); + arr1.push(hex); + } + return arr1.join(''); + } + + /* public vars */ + bitjs.pub = 0x23; // flochange - changed the prefix to FLO Mainnet PublicKey Prefix 0x23 + bitjs.priv = 0xa3; //flochange - changed the prefix to FLO Mainnet Private key prefix 0xa3 + bitjs.compressed = false; + + /* provide a privkey and return an WIF */ + bitjs.privkey2wif = function(h) { + var r = Crypto.util.hexToBytes(h); + + if (bitjs.compressed == true) { + r.push(0x01); + } + + r.unshift(bitjs.priv); + var hash = Crypto.SHA256(Crypto.SHA256(r, { + asBytes: true + }), { + asBytes: true + }); + var checksum = hash.slice(0, 4); + + return B58.encode(r.concat(checksum)); + } + + /* convert a wif key back to a private key */ + bitjs.wif2privkey = function(wif) { + var compressed = false; + var decode = B58.decode(wif); + var key = decode.slice(0, decode.length - 4); + key = key.slice(1, key.length); + if (key.length >= 33 && key[key.length - 1] == 0x01) { + key = key.slice(0, key.length - 1); + compressed = true; + } + return { + 'privkey': Crypto.util.bytesToHex(key), + 'compressed': compressed + }; + } + + /* convert a wif to a pubkey */ + bitjs.wif2pubkey = function(wif) { + var compressed = bitjs.compressed; + var r = bitjs.wif2privkey(wif); + bitjs.compressed = r['compressed']; + var pubkey = bitjs.newPubkey(r['privkey']); + bitjs.compressed = compressed; + return { + 'pubkey': pubkey, + 'compressed': r['compressed'] + }; + } + + /* convert a wif to a address */ + bitjs.wif2address = function(wif) { + var r = bitjs.wif2pubkey(wif); + return { + 'address': bitjs.pubkey2address(r['pubkey']), + 'compressed': r['compressed'] + }; + } + + /* generate a public key from a private key */ + bitjs.newPubkey = function(hash) { + var privateKeyBigInt = BigInteger.fromByteArrayUnsigned(Crypto.util.hexToBytes(hash)); + var curve = EllipticCurve.getSECCurveByName("secp256k1"); + + var curvePt = curve.getG().multiply(privateKeyBigInt); + var x = curvePt.getX().toBigInteger(); + var y = curvePt.getY().toBigInteger(); + + var publicKeyBytes = EllipticCurve.integerToBytes(x, 32); + publicKeyBytes = publicKeyBytes.concat(EllipticCurve.integerToBytes(y, 32)); + publicKeyBytes.unshift(0x04); + + if (bitjs.compressed == true) { + var publicKeyBytesCompressed = EllipticCurve.integerToBytes(x, 32) + if (y.isEven()) { + publicKeyBytesCompressed.unshift(0x02) + } else { + publicKeyBytesCompressed.unshift(0x03) + } + return Crypto.util.bytesToHex(publicKeyBytesCompressed); + } else { + return Crypto.util.bytesToHex(publicKeyBytes); + } + } + + /* provide a public key and return address */ + bitjs.pubkey2address = function(h, byte) { + var r = ripemd160(Crypto.SHA256(Crypto.util.hexToBytes(h), { + asBytes: true + })); + r.unshift(byte || bitjs.pub); + var hash = Crypto.SHA256(Crypto.SHA256(r, { + asBytes: true + }), { + asBytes: true + }); + var checksum = hash.slice(0, 4); + return B58.encode(r.concat(checksum)); + } + + bitjs.transaction = function() { + var btrx = {}; + btrx.version = 2; //flochange look at this version + btrx.inputs = []; + btrx.outputs = []; + btrx.locktime = 0; + btrx.floData = ""; //flochange .. look at this + + + btrx.addinput = function(txid, index, scriptPubKey, sequence) { + var o = {}; + o.outpoint = { + 'hash': txid, + 'index': index + }; + //o.script = []; Signature and Public Key should be added after singning + o.script = Crypto.util.hexToBytes(scriptPubKey); //push previous output pubkey script + o.sequence = sequence || ((btrx.locktime == 0) ? 4294967295 : 0); + return this.inputs.push(o); + } + + btrx.addoutput = function(address, value) { + var o = {}; + var buf = []; + var addrDecoded = btrx.addressDecode(address); + o.value = new BigInteger('' + Math.round((value * 1) * 1e8), 10); + buf.push(118); //OP_DUP + buf.push(169); //OP_HASH160 + buf.push(addrDecoded.length); + buf = buf.concat(addrDecoded); // address in bytes + buf.push(136); //OP_EQUALVERIFY + buf.push(172); // OP_CHECKSIG + o.script = buf; + return this.outputs.push(o); + } + + + btrx.addflodata = function(txcomments) { // flochange - this whole function needs to be done + this.floData = txcomments; + return this.floData; //flochange .. returning the txcomments -- check if the function return will assign + } + + + // Only standard addresses + btrx.addressDecode = function(address) { + var bytes = B58.decode(address); + var front = bytes.slice(0, bytes.length - 4); + var back = bytes.slice(bytes.length - 4); + var checksum = Crypto.SHA256(Crypto.SHA256(front, { + asBytes: true + }), { + asBytes: true + }).slice(0, 4); + if (checksum + "" == back + "") { + return front.slice(1); + } + } + + /* generate the transaction hash to sign from a transaction input */ + btrx.transactionHash = function(index, sigHashType) { + + var clone = bitjs.clone(this); + var shType = sigHashType || 1; + + /* black out all other ins, except this one */ + for (var i = 0; i < clone.inputs.length; i++) { + if (index != i) { + clone.inputs[i].script = []; + } + } + + + if ((clone.inputs) && clone.inputs[index]) { + + /* SIGHASH : For more info on sig hashs see https://en.bitcoin.it/wiki/OP_CHECKSIG + and https://bitcoin.org/en/developer-guide#signature-hash-type */ + + if (shType == 1) { + //SIGHASH_ALL 0x01 + + } else if (shType == 2) { + //SIGHASH_NONE 0x02 + clone.outputs = []; + for (var i = 0; i < clone.inputs.length; i++) { + if (index != i) { + clone.inputs[i].sequence = 0; + } + } + + } else if (shType == 3) { + + //SIGHASH_SINGLE 0x03 + clone.outputs.length = index + 1; + + for (var i = 0; i < index; i++) { + clone.outputs[i].value = -1; + clone.outputs[i].script = []; + } + + for (var i = 0; i < clone.inputs.length; i++) { + if (index != i) { + clone.inputs[i].sequence = 0; + } + } + + } else if (shType >= 128) { + //SIGHASH_ANYONECANPAY 0x80 + clone.inputs = [clone.inputs[index]]; + + if (shType == 129) { + // SIGHASH_ALL + SIGHASH_ANYONECANPAY + + } else if (shType == 130) { + // SIGHASH_NONE + SIGHASH_ANYONECANPAY + clone.outputs = []; + + } else if (shType == 131) { + // SIGHASH_SINGLE + SIGHASH_ANYONECANPAY + clone.outputs.length = index + 1; + for (var i = 0; i < index; i++) { + clone.outputs[i].value = -1; + clone.outputs[i].script = []; + } + } + } + + var buffer = Crypto.util.hexToBytes(clone.serialize()); + buffer = buffer.concat(bitjs.numToBytes(parseInt(shType), 4)); + var hash = Crypto.SHA256(buffer, { + asBytes: true + }); + var r = Crypto.util.bytesToHex(Crypto.SHA256(hash, { + asBytes: true + })); + return r; + } else { + return false; + } + } + + /* generate a signature from a transaction hash */ + btrx.transactionSig = function(index, wif, sigHashType, txhash) { + + function serializeSig(r, s) { + var rBa = r.toByteArraySigned(); + var sBa = s.toByteArraySigned(); + + var sequence = []; + sequence.push(0x02); // INTEGER + sequence.push(rBa.length); + sequence = sequence.concat(rBa); + + sequence.push(0x02); // INTEGER + sequence.push(sBa.length); + sequence = sequence.concat(sBa); + + sequence.unshift(sequence.length); + sequence.unshift(0x30); // SEQUENCE + + return sequence; + } + + var shType = sigHashType || 1; + var hash = txhash || Crypto.util.hexToBytes(this.transactionHash(index, shType)); + + if (hash) { + var curve = EllipticCurve.getSECCurveByName("secp256k1"); + var key = bitjs.wif2privkey(wif); + var priv = BigInteger.fromByteArrayUnsigned(Crypto.util.hexToBytes(key['privkey'])); + var n = curve.getN(); + var e = BigInteger.fromByteArrayUnsigned(hash); + var badrs = 0 + do { + var k = this.deterministicK(wif, hash, badrs); + var G = curve.getG(); + var Q = G.multiply(k); + var r = Q.getX().toBigInteger().mod(n); + var s = k.modInverse(n).multiply(e.add(priv.multiply(r))).mod(n); + badrs++ + } while (r.compareTo(BigInteger.ZERO) <= 0 || s.compareTo(BigInteger.ZERO) <= 0); + + // Force lower s values per BIP62 + var halfn = n.shiftRight(1); + if (s.compareTo(halfn) > 0) { + s = n.subtract(s); + }; + + var sig = serializeSig(r, s); + sig.push(parseInt(shType, 10)); + + return Crypto.util.bytesToHex(sig); + } else { + return false; + } + } + + // https://tools.ietf.org/html/rfc6979#section-3.2 + btrx.deterministicK = function(wif, hash, badrs) { + // if r or s were invalid when this function was used in signing, + // we do not want to actually compute r, s here for efficiency, so, + // we can increment badrs. explained at end of RFC 6979 section 3.2 + + // wif is b58check encoded wif privkey. + // hash is byte array of transaction digest. + // badrs is used only if the k resulted in bad r or s. + + // some necessary things out of the way for clarity. + badrs = badrs || 0; + var key = bitjs.wif2privkey(wif); + var x = Crypto.util.hexToBytes(key['privkey']) + var curve = EllipticCurve.getSECCurveByName("secp256k1"); + var N = curve.getN(); + + // Step: a + // hash is a byteArray of the message digest. so h1 == hash in our case + + // Step: b + var v = [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, 1, 1, 1 + ]; + + // Step: c + var k = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 + ]; + + // Step: d + k = Crypto.HMAC(Crypto.SHA256, v.concat([0]).concat(x).concat(hash), k, { + asBytes: true + }); + + // Step: e + v = Crypto.HMAC(Crypto.SHA256, v, k, { + asBytes: true + }); + + // Step: f + k = Crypto.HMAC(Crypto.SHA256, v.concat([1]).concat(x).concat(hash), k, { + asBytes: true + }); + + // Step: g + v = Crypto.HMAC(Crypto.SHA256, v, k, { + asBytes: true + }); + + // Step: h1 + var T = []; + + // Step: h2 (since we know tlen = qlen, just copy v to T.) + v = Crypto.HMAC(Crypto.SHA256, v, k, { + asBytes: true + }); + T = v; + + // Step: h3 + var KBigInt = BigInteger.fromByteArrayUnsigned(T); + + // loop if KBigInt is not in the range of [1, N-1] or if badrs needs incrementing. + var i = 0 + while (KBigInt.compareTo(N) >= 0 || KBigInt.compareTo(BigInteger.ZERO) <= 0 || i < + badrs) { + k = Crypto.HMAC(Crypto.SHA256, v.concat([0]), k, { + asBytes: true + }); + v = Crypto.HMAC(Crypto.SHA256, v, k, { + asBytes: true + }); + v = Crypto.HMAC(Crypto.SHA256, v, k, { + asBytes: true + }); + T = v; + KBigInt = BigInteger.fromByteArrayUnsigned(T); + i++ + }; + + return KBigInt; + }; + + /* sign a "standard" input */ + btrx.signinput = function(index, wif, sigHashType) { + var key = bitjs.wif2pubkey(wif); + var shType = sigHashType || 1; + var signature = this.transactionSig(index, wif, shType); + var buf = []; + var sigBytes = Crypto.util.hexToBytes(signature); + buf.push(sigBytes.length); + buf = buf.concat(sigBytes); + var pubKeyBytes = Crypto.util.hexToBytes(key['pubkey']); + buf.push(pubKeyBytes.length); + buf = buf.concat(pubKeyBytes); + this.inputs[index].script = buf; + return true; + } + + /* sign inputs */ + btrx.sign = function(wif, sigHashType) { + var shType = sigHashType || 1; + for (var i = 0; i < this.inputs.length; i++) { + this.signinput(i, wif, shType); + } + return this.serialize(); + } + + + /* serialize a transaction */ + btrx.serialize = function() { + var buffer = []; + buffer = buffer.concat(bitjs.numToBytes(parseInt(this.version), 4)); + + buffer = buffer.concat(bitjs.numToVarInt(this.inputs.length)); + for (var i = 0; i < this.inputs.length; i++) { + var txin = this.inputs[i]; + buffer = buffer.concat(Crypto.util.hexToBytes(txin.outpoint.hash).reverse()); + buffer = buffer.concat(bitjs.numToBytes(parseInt(txin.outpoint.index), 4)); + var scriptBytes = txin.script; + buffer = buffer.concat(bitjs.numToVarInt(scriptBytes.length)); + buffer = buffer.concat(scriptBytes); + buffer = buffer.concat(bitjs.numToBytes(parseInt(txin.sequence), 4)); + + } + buffer = buffer.concat(bitjs.numToVarInt(this.outputs.length)); + + for (var i = 0; i < this.outputs.length; i++) { + var txout = this.outputs[i]; + buffer = buffer.concat(bitjs.numToBytes(txout.value, 8)); + var scriptBytes = txout.script; + buffer = buffer.concat(bitjs.numToVarInt(scriptBytes.length)); + buffer = buffer.concat(scriptBytes); + } + + buffer = buffer.concat(bitjs.numToBytes(parseInt(this.locktime), 4)); + var flohex = ascii_to_hexa(this.floData); + var floDataCount = this.floData.length; + var floDataCountString; + //flochange -- creating unique data character count logic for floData. This string is prefixed before actual floData string in Raw Transaction + if (floDataCount < 16) { + floDataCountString = floDataCount.toString(16); + floDataCountString = "0" + floDataCountString; + } else if (floDataCount < 253) { + floDataCountString = floDataCount.toString(16); + } else if (floDataCount <= 1040) { + floDataCountAdjusted = (floDataCount - 253) + parseInt("0xfd00fd"); + floDataCountStringAdjusted = floDataCountAdjusted.toString(16); + floDataCountString = floDataCountStringAdjusted.substr(0, 2) + floDataCountStringAdjusted.substr(4, 2) + floDataCountStringAdjusted.substr(2, 2); + } else { + floDataCountString = "Character Limit Exceeded"; + } + + + return Crypto.util.bytesToHex(buffer) + floDataCountString + flohex; // flochange -- Addition of floDataCountString and floData in serialization + } + + + + return btrx; + + } + + bitjs.numToBytes = function(num, bytes) { + if (typeof bytes === "undefined") bytes = 8; + if (bytes == 0) { + return []; + } else if (num == -1) { + return Crypto.util.hexToBytes("ffffffffffffffff"); + } else { + return [num % 256].concat(bitjs.numToBytes(Math.floor(num / 256), bytes - 1)); + } + } + + bitjs.numToByteArray = function(num) { + if (num <= 256) { + return [num]; + } else { + return [num % 256].concat(bitjs.numToByteArray(Math.floor(num / 256))); + } + } + + bitjs.numToVarInt = function(num) { + if (num < 253) { + return [num]; + } else if (num < 65536) { + return [253].concat(bitjs.numToBytes(num, 2)); + } else if (num < 4294967296) { + return [254].concat(bitjs.numToBytes(num, 4)); + } else { + return [255].concat(bitjs.numToBytes(num, 8)); + } + } + + bitjs.bytesToNum = function(bytes) { + if (bytes.length == 0) return 0; + else return bytes[0] + 256 * bitjs.bytesToNum(bytes.slice(1)); + } + + /* clone an object */ + bitjs.clone = function(obj) { + if (obj == null || typeof(obj) != 'object') return obj; + var temp = new obj.constructor(); + + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + temp[key] = bitjs.clone(obj[key]); + } + } + return temp; + } + + var B58 = bitjs.Base58 = { + alphabet: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", + validRegex: /^[1-9A-HJ-NP-Za-km-z]+$/, + base: BigInteger.valueOf(58), + + /** + * Convert a byte array to a base58-encoded string. + * + * Written by Mike Hearn for BitcoinJ. + * Copyright (c) 2011 Google Inc. + * + * Ported to JavaScript by Stefan Thomas. + */ + encode: function(input) { + var bi = BigInteger.fromByteArrayUnsigned(input); + var chars = []; + + while (bi.compareTo(B58.base) >= 0) { + var mod = bi.mod(B58.base); + chars.unshift(B58.alphabet[mod.intValue()]); + bi = bi.subtract(mod).divide(B58.base); + } + chars.unshift(B58.alphabet[bi.intValue()]); + + // Convert leading zeros too. + for (var i = 0; i < input.length; i++) { + if (input[i] == 0x00) { + chars.unshift(B58.alphabet[0]); + } else break; + } + + return chars.join(''); + }, + + /** + * Convert a base58-encoded string to a byte array. + * + * Written by Mike Hearn for BitcoinJ. + * Copyright (c) 2011 Google Inc. + * + * Ported to JavaScript by Stefan Thomas. + */ + decode: function(input) { + var bi = BigInteger.valueOf(0); + var leadingZerosNum = 0; + for (var i = input.length - 1; i >= 0; i--) { + var alphaIndex = B58.alphabet.indexOf(input[i]); + if (alphaIndex < 0) { + throw "Invalid character"; + } + bi = bi.add(BigInteger.valueOf(alphaIndex) + .multiply(B58.base.pow(input.length - 1 - i))); + + // This counts leading zero bytes + if (input[i] == "1") leadingZerosNum++; + else leadingZerosNum = 0; + } + var bytes = bi.toByteArrayUnsigned(); + + // Add leading zeros + while (leadingZerosNum-- > 0) bytes.unshift(0); + + return bytes; + } + } + return bitjs; + +})(typeof global !== "undefined" ? global : window); + +//Bitcoin.js +(function(GLOBAL) { + /* + Copyright (c) 2011 Stefan Thomas + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + var Bitcoin = GLOBAL.Bitcoin = {}; + + //https://raw.github.com/bitcoinjs/bitcoinjs-lib/c952aaeb3ee472e3776655b8ea07299ebed702c7/src/base58.js + var B58 = Bitcoin.Base58 = { + alphabet: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", + validRegex: /^[1-9A-HJ-NP-Za-km-z]+$/, + base: BigInteger.valueOf(58), + + /** + * Convert a byte array to a base58-encoded string. + * + * Written by Mike Hearn for BitcoinJ. + * Copyright (c) 2011 Google Inc. + * + * Ported to JavaScript by Stefan Thomas. + */ + encode: function(input) { + var bi = BigInteger.fromByteArrayUnsigned(input); + var chars = []; + + while (bi.compareTo(B58.base) >= 0) { + var mod = bi.mod(B58.base); + chars.unshift(B58.alphabet[mod.intValue()]); + bi = bi.subtract(mod).divide(B58.base); + } + chars.unshift(B58.alphabet[bi.intValue()]); + + // Convert leading zeros too. + for (var i = 0; i < input.length; i++) { + if (input[i] == 0x00) { + chars.unshift(B58.alphabet[0]); + } else break; + } + + return chars.join(''); + }, + + /** + * Convert a base58-encoded string to a byte array. + * + * Written by Mike Hearn for BitcoinJ. + * Copyright (c) 2011 Google Inc. + * + * Ported to JavaScript by Stefan Thomas. + */ + decode: function(input) { + var bi = BigInteger.valueOf(0); + var leadingZerosNum = 0; + for (var i = input.length - 1; i >= 0; i--) { + var alphaIndex = B58.alphabet.indexOf(input[i]); + if (alphaIndex < 0) { + throw "Invalid character"; + } + bi = bi.add(BigInteger.valueOf(alphaIndex) + .multiply(B58.base.pow(input.length - 1 - i))); + + // This counts leading zero bytes + if (input[i] == "1") leadingZerosNum++; + else leadingZerosNum = 0; + } + var bytes = bi.toByteArrayUnsigned(); + + // Add leading zeros + while (leadingZerosNum-- > 0) bytes.unshift(0); + + return bytes; + } + }; + + //https://raw.github.com/bitcoinjs/bitcoinjs-lib/09e8c6e184d6501a0c2c59d73ca64db5c0d3eb95/src/address.js + Bitcoin.Address = function(bytes) { + if (GLOBAL.cryptocoin == "FLO") + this.version = 0x23; // FLO mainnet public address + else if (GLOBAL.cryptocoin == "FLO_TEST") + this.version = 0x73; // FLO testnet public address + if ("string" == typeof bytes) { + bytes = Bitcoin.Address.decodeString(bytes, this.version); + } + this.hash = bytes; + }; + + Bitcoin.Address.networkVersion = 0x23; // (FLO mainnet 0x23, 35D), (Bitcoin Mainnet, 0x00, 0D) // *this has no effect * + + /** + * Serialize this object as a standard Bitcoin address. + * + * Returns the address as a base58-encoded string in the standardized format. + */ + Bitcoin.Address.prototype.toString = function() { + // Get a copy of the hash + var hash = this.hash.slice(0); + + // Version + hash.unshift(this.version); + var checksum = Crypto.SHA256(Crypto.SHA256(hash, { + asBytes: true + }), { + asBytes: true + }); + var bytes = hash.concat(checksum.slice(0, 4)); + return Bitcoin.Base58.encode(bytes); + }; + + Bitcoin.Address.prototype.getHashBase64 = function() { + return Crypto.util.bytesToBase64(this.hash); + }; + + /** + * Parse a Bitcoin address contained in a string. + */ + Bitcoin.Address.decodeString = function(string, version) { + var bytes = Bitcoin.Base58.decode(string); + var hash = bytes.slice(0, 21); + var checksum = Crypto.SHA256(Crypto.SHA256(hash, { + asBytes: true + }), { + asBytes: true + }); + + if (checksum[0] != bytes[21] || + checksum[1] != bytes[22] || + checksum[2] != bytes[23] || + checksum[3] != bytes[24]) { + throw "Checksum validation failed!"; + } + + if (version != hash.shift()) { + throw "Version " + hash.shift() + " not supported!"; + } + + return hash; + }; + //https://raw.github.com/bitcoinjs/bitcoinjs-lib/e90780d3d3b8fc0d027d2bcb38b80479902f223e/src/ecdsa.js + Bitcoin.ECDSA = (function() { + var ecparams = EllipticCurve.getSECCurveByName("secp256k1"); + var rng = new SecureRandom(); + + var P_OVER_FOUR = null; + + function implShamirsTrick(P, k, Q, l) { + var m = Math.max(k.bitLength(), l.bitLength()); + var Z = P.add2D(Q); + var R = P.curve.getInfinity(); + + for (var i = m - 1; i >= 0; --i) { + R = R.twice2D(); + + R.z = BigInteger.ONE; + + if (k.testBit(i)) { + if (l.testBit(i)) { + R = R.add2D(Z); + } else { + R = R.add2D(P); + } + } else { + if (l.testBit(i)) { + R = R.add2D(Q); + } + } + } + + return R; + }; + + var ECDSA = { + getBigRandom: function(limit) { + return new BigInteger(limit.bitLength(), rng) + .mod(limit.subtract(BigInteger.ONE)) + .add(BigInteger.ONE); + }, + sign: function(hash, priv) { + var d = priv; + var n = ecparams.getN(); + var e = BigInteger.fromByteArrayUnsigned(hash); + + do { + var k = ECDSA.getBigRandom(n); + var G = ecparams.getG(); + var Q = G.multiply(k); + var r = Q.getX().toBigInteger().mod(n); + } while (r.compareTo(BigInteger.ZERO) <= 0); + + var s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n); + + return ECDSA.serializeSig(r, s); + }, + + verify: function(hash, sig, pubkey) { + var r, s; + if (Bitcoin.Util.isArray(sig)) { + var obj = ECDSA.parseSig(sig); + r = obj.r; + s = obj.s; + } else if ("object" === typeof sig && sig.r && sig.s) { + r = sig.r; + s = sig.s; + } else { + throw "Invalid value for signature"; + } + + var Q; + if (pubkey instanceof ec.PointFp) { + Q = pubkey; + } else if (Bitcoin.Util.isArray(pubkey)) { + Q = EllipticCurve.PointFp.decodeFrom(ecparams.getCurve(), pubkey); + } else { + throw "Invalid format for pubkey value, must be byte array or ec.PointFp"; + } + var e = BigInteger.fromByteArrayUnsigned(hash); + + return ECDSA.verifyRaw(e, r, s, Q); + }, + + verifyRaw: function(e, r, s, Q) { + var n = ecparams.getN(); + var G = ecparams.getG(); + + if (r.compareTo(BigInteger.ONE) < 0 || + r.compareTo(n) >= 0) + return false; + + if (s.compareTo(BigInteger.ONE) < 0 || + s.compareTo(n) >= 0) + return false; + + var c = s.modInverse(n); + + var u1 = e.multiply(c).mod(n); + var u2 = r.multiply(c).mod(n); + + // TODO(!!!): For some reason Shamir's trick isn't working with + // signed message verification!? Probably an implementation + // error! + //var point = implShamirsTrick(G, u1, Q, u2); + var point = G.multiply(u1).add(Q.multiply(u2)); + + var v = point.getX().toBigInteger().mod(n); + + return v.equals(r); + }, + + /** + * Serialize a signature into DER format. + * + * Takes two BigIntegers representing r and s and returns a byte array. + */ + serializeSig: function(r, s) { + var rBa = r.toByteArraySigned(); + var sBa = s.toByteArraySigned(); + + var sequence = []; + sequence.push(0x02); // INTEGER + sequence.push(rBa.length); + sequence = sequence.concat(rBa); + + sequence.push(0x02); // INTEGER + sequence.push(sBa.length); + sequence = sequence.concat(sBa); + + sequence.unshift(sequence.length); + sequence.unshift(0x30); // SEQUENCE + + return sequence; + }, + + /** + * Parses a byte array containing a DER-encoded signature. + * + * This function will return an object of the form: + * + * { + * r: BigInteger, + * s: BigInteger + * } + */ + parseSig: function(sig) { + var cursor; + if (sig[0] != 0x30) + throw new Error("Signature not a valid DERSequence"); + + cursor = 2; + if (sig[cursor] != 0x02) + throw new Error("First element in signature must be a DERInteger");; + var rBa = sig.slice(cursor + 2, cursor + 2 + sig[cursor + 1]); + + cursor += 2 + sig[cursor + 1]; + if (sig[cursor] != 0x02) + throw new Error("Second element in signature must be a DERInteger"); + var sBa = sig.slice(cursor + 2, cursor + 2 + sig[cursor + 1]); + + cursor += 2 + sig[cursor + 1]; + + //if (cursor != sig.length) + // throw new Error("Extra bytes in signature"); + + var r = BigInteger.fromByteArrayUnsigned(rBa); + var s = BigInteger.fromByteArrayUnsigned(sBa); + + return { + r: r, + s: s + }; + }, + + parseSigCompact: function(sig) { + if (sig.length !== 65) { + throw "Signature has the wrong length"; + } + + // Signature is prefixed with a type byte storing three bits of + // information. + var i = sig[0] - 27; + if (i < 0 || i > 7) { + throw "Invalid signature type"; + } + + var n = ecparams.getN(); + var r = BigInteger.fromByteArrayUnsigned(sig.slice(1, 33)).mod(n); + var s = BigInteger.fromByteArrayUnsigned(sig.slice(33, 65)).mod(n); + + return { + r: r, + s: s, + i: i + }; + }, + + /** + * Recover a public key from a signature. + * + * See SEC 1: Elliptic Curve Cryptography, section 4.1.6, "Public + * Key Recovery Operation". + * + * http://www.secg.org/download/aid-780/sec1-v2.pdf + */ + recoverPubKey: function(r, s, hash, i) { + // The recovery parameter i has two bits. + i = i & 3; + + // The less significant bit specifies whether the y coordinate + // of the compressed point is even or not. + var isYEven = i & 1; + + // The more significant bit specifies whether we should use the + // first or second candidate key. + var isSecondKey = i >> 1; + + var n = ecparams.getN(); + var G = ecparams.getG(); + var curve = ecparams.getCurve(); + var p = curve.getQ(); + var a = curve.getA().toBigInteger(); + var b = curve.getB().toBigInteger(); + + // We precalculate (p + 1) / 4 where p is if the field order + if (!P_OVER_FOUR) { + P_OVER_FOUR = p.add(BigInteger.ONE).divide(BigInteger.valueOf(4)); + } + + // 1.1 Compute x + var x = isSecondKey ? r.add(n) : r; + + // 1.3 Convert x to point + var alpha = x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(p); + var beta = alpha.modPow(P_OVER_FOUR, p); + + var xorOdd = beta.isEven() ? (i % 2) : ((i + 1) % 2); + // If beta is even, but y isn't or vice versa, then convert it, + // otherwise we're done and y == beta. + var y = (beta.isEven() ? !isYEven : isYEven) ? beta : p.subtract(beta); + + // 1.4 Check that nR is at infinity + var R = new EllipticCurve.PointFp(curve, + curve.fromBigInteger(x), + curve.fromBigInteger(y)); + R.validate(); + + // 1.5 Compute e from M + var e = BigInteger.fromByteArrayUnsigned(hash); + var eNeg = BigInteger.ZERO.subtract(e).mod(n); + + // 1.6 Compute Q = r^-1 (sR - eG) + var rInv = r.modInverse(n); + var Q = implShamirsTrick(R, s, G, eNeg).multiply(rInv); + + Q.validate(); + if (!ECDSA.verifyRaw(e, r, s, Q)) { + throw "Pubkey recovery unsuccessful"; + } + + var pubKey = new Bitcoin.ECKey(); + pubKey.pub = Q; + return pubKey; + }, + + /** + * Calculate pubkey extraction parameter. + * + * When extracting a pubkey from a signature, we have to + * distinguish four different cases. Rather than putting this + * burden on the verifier, Bitcoin includes a 2-bit value with the + * signature. + * + * This function simply tries all four cases and returns the value + * that resulted in a successful pubkey recovery. + */ + calcPubkeyRecoveryParam: function(address, r, s, hash) { + for (var i = 0; i < 4; i++) { + try { + var pubkey = Bitcoin.ECDSA.recoverPubKey(r, s, hash, i); + if (pubkey.getBitcoinAddress().toString() == address) { + return i; + } + } catch (e) {} + } + throw "Unable to find valid recovery factor"; + } + }; + + return ECDSA; + })(); + Bitcoin.KeyPool = (function() { + var KeyPool = function() { + this.keyArray = []; + + this.push = function(item) { + if (item == null || item.priv == null) return; + var doAdd = true; + // prevent duplicates from being added to the array + for (var index in this.keyArray) { + var currentItem = this.keyArray[index]; + if (currentItem != null && currentItem.priv != null && item.getBitcoinAddress() == currentItem.getBitcoinAddress()) { + doAdd = false; + break; + } + } + if (doAdd) this.keyArray.push(item); + }; + + this.reset = function() { + this.keyArray = []; + }; + + this.getArray = function() { + // copy array + return this.keyArray.slice(0); + }; + + this.setArray = function(ka) { + this.keyArray = ka; + }; + + this.length = function() { + return this.keyArray.length; + }; + + this.toString = function() { + var keyPoolString = "# = " + this.length() + "\n"; + var pool = this.getArray(); + for (var index in pool) { + var item = pool[index]; + if (Bitcoin.Util.hasMethods(item, 'getBitcoinAddress', 'toString')) { + if (item != null) { + keyPoolString += "\"" + item.getBitcoinAddress() + "\"" + ", \"" + item.toString("wif") + "\"\n"; + } + } + } + + return keyPoolString; + }; + + return this; + }; + + return new KeyPool(); + })(); + + Bitcoin.Bip38Key = (function() { + var Bip38 = function(address, encryptedKey) { + this.address = address; + this.priv = encryptedKey; + }; + + Bip38.prototype.getBitcoinAddress = function() { + return this.address; + }; + + Bip38.prototype.toString = function() { + return this.priv; + }; + + return Bip38; + })(); + + //https://raw.github.com/pointbiz/bitcoinjs-lib/9b2f94a028a7bc9bed94e0722563e9ff1d8e8db8/src/eckey.js + Bitcoin.ECKey = (function() { + var ECDSA = Bitcoin.ECDSA; + var KeyPool = Bitcoin.KeyPool; + var ecparams = EllipticCurve.getSECCurveByName("secp256k1"); + + var ECKey = function(input) { + if (!input) { + // Generate new key + var n = ecparams.getN(); + this.priv = ECDSA.getBigRandom(n); + } else if (input instanceof BigInteger) { + // Input is a private key value + this.priv = input; + } else if (Bitcoin.Util.isArray(input)) { + // Prepend zero byte to prevent interpretation as negative integer + this.priv = BigInteger.fromByteArrayUnsigned(input); + } else if ("string" == typeof input) { + var bytes = null; + try { + + // This part is edited for FLO. FLO WIF are always compressed WIF. FLO WIF (private key) starts with R for mainnet and c for testnet. + if (((GLOBAL.cryptocoin == "FLO") && /^R[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test(input)) || + ((GLOBAL.cryptocoin == "FLO_TEST") && /^c[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test(input))) { + bytes = ECKey.decodeCompressedWalletImportFormat(input); + this.compressed = true; + } else if (ECKey.isHexFormat(input)) { + bytes = Crypto.util.hexToBytes(input); + } + + + /* + if (ECKey.isWalletImportFormat(input)) { + bytes = ECKey.decodeWalletImportFormat(input); + } else if (ECKey.isCompressedWalletImportFormat(input)) { + bytes = ECKey.decodeCompressedWalletImportFormat(input); + this.compressed = true; + } else if (ECKey.isMiniFormat(input)) { + bytes = Crypto.SHA256(input, { asBytes: true }); + } else if (ECKey.isHexFormat(input)) { + bytes = Crypto.util.hexToBytes(input); + } else if (ECKey.isBase64Format(input)) { + bytes = Crypto.util.base64ToBytes(input); + } + */ + } catch (exc1) { + this.setError(exc1); + } + + if (ECKey.isBase6Format(input)) { + this.priv = new BigInteger(input, 6); + } else if (bytes == null || bytes.length != 32) { + this.priv = null; + } else { + // Prepend zero byte to prevent interpretation as negative integer + this.priv = BigInteger.fromByteArrayUnsigned(bytes); + } + } + + this.compressed = (this.compressed == undefined) ? !!ECKey.compressByDefault : this.compressed; + try { + // check not zero + if (this.priv != null && BigInteger.ZERO.compareTo(this.priv) == 0) this.setError("Error: BigInteger equal to zero."); + // valid range [0x1, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140]) + var hexKeyRangeLimit = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140"; + var rangeLimitBytes = Crypto.util.hexToBytes(hexKeyRangeLimit); + var limitBigInt = BigInteger.fromByteArrayUnsigned(rangeLimitBytes); + if (this.priv != null && limitBigInt.compareTo(this.priv) < 0) this.setError("Error: BigInteger outside of curve range.") + + if (this.priv != null) { + KeyPool.push(this); + } + } catch (exc2) { + this.setError(exc2); + } + }; + + if (GLOBAL.cryptocoin == "FLO") + ECKey.privateKeyPrefix = 0xA3; //(Bitcoin mainnet 0x80 testnet 0xEF) (FLO mainnet 0xA3 163 D) + else if (GLOBAL.cryptocoin == "FLO_TEST") + ECKey.privateKeyPrefix = 0xEF; //FLO testnet + + /** + * Whether public keys should be returned compressed by default. + */ + ECKey.compressByDefault = false; + + /** + * Set whether the public key should be returned compressed or not. + */ + ECKey.prototype.setError = function(err) { + this.error = err; + this.priv = null; + return this; + }; + + /** + * Set whether the public key should be returned compressed or not. + */ + ECKey.prototype.setCompressed = function(v) { + this.compressed = !!v; + if (this.pubPoint) this.pubPoint.compressed = this.compressed; + return this; + }; + + /* + * Return public key as a byte array in DER encoding + */ + ECKey.prototype.getPub = function() { + if (this.compressed) { + if (this.pubComp) return this.pubComp; + return this.pubComp = this.getPubPoint().getEncoded(1); + } else { + if (this.pubUncomp) return this.pubUncomp; + return this.pubUncomp = this.getPubPoint().getEncoded(0); + } + }; + + /** + * Return public point as ECPoint object. + */ + ECKey.prototype.getPubPoint = function() { + if (!this.pubPoint) { + this.pubPoint = ecparams.getG().multiply(this.priv); + this.pubPoint.compressed = this.compressed; + } + return this.pubPoint; + }; + + ECKey.prototype.getPubKeyHex = function() { + if (this.compressed) { + if (this.pubKeyHexComp) return this.pubKeyHexComp; + return this.pubKeyHexComp = Crypto.util.bytesToHex(this.getPub()).toString().toUpperCase(); + } else { + if (this.pubKeyHexUncomp) return this.pubKeyHexUncomp; + return this.pubKeyHexUncomp = Crypto.util.bytesToHex(this.getPub()).toString().toUpperCase(); + } + }; + + /** + * Get the pubKeyHash for this key. + * + * This is calculated as RIPE160(SHA256([encoded pubkey])) and returned as + * a byte array. + */ + ECKey.prototype.getPubKeyHash = function() { + if (this.compressed) { + if (this.pubKeyHashComp) return this.pubKeyHashComp; + return this.pubKeyHashComp = Bitcoin.Util.sha256ripe160(this.getPub()); + } else { + if (this.pubKeyHashUncomp) return this.pubKeyHashUncomp; + return this.pubKeyHashUncomp = Bitcoin.Util.sha256ripe160(this.getPub()); + } + }; + + ECKey.prototype.getBitcoinAddress = function() { + var hash = this.getPubKeyHash(); + var addr = new Bitcoin.Address(hash); + return addr.toString(); + }; + + /* + * Takes a public point as a hex string or byte array + */ + ECKey.prototype.setPub = function(pub) { + // byte array + if (Bitcoin.Util.isArray(pub)) { + pub = Crypto.util.bytesToHex(pub).toString().toUpperCase(); + } + var ecPoint = ecparams.getCurve().decodePointHex(pub); + this.setCompressed(ecPoint.compressed); + this.pubPoint = ecPoint; + return this; + }; + + // Sipa Private Key Wallet Import Format + ECKey.prototype.getBitcoinWalletImportFormat = function() { + var bytes = this.getBitcoinPrivateKeyByteArray(); + if (bytes == null) return ""; + bytes.unshift(ECKey.privateKeyPrefix); // prepend 0x80 byte + if (this.compressed) bytes.push(0x01); // append 0x01 byte for compressed format + var checksum = Crypto.SHA256(Crypto.SHA256(bytes, { + asBytes: true + }), { + asBytes: true + }); + bytes = bytes.concat(checksum.slice(0, 4)); + var privWif = Bitcoin.Base58.encode(bytes); + return privWif; + }; + + // Private Key Hex Format + ECKey.prototype.getBitcoinHexFormat = function() { + return Crypto.util.bytesToHex(this.getBitcoinPrivateKeyByteArray()).toString().toUpperCase(); + }; + + // Private Key Base64 Format + ECKey.prototype.getBitcoinBase64Format = function() { + return Crypto.util.bytesToBase64(this.getBitcoinPrivateKeyByteArray()); + }; + + ECKey.prototype.getBitcoinPrivateKeyByteArray = function() { + if (this.priv == null) return null; + // Get a copy of private key as a byte array + var bytes = this.priv.toByteArrayUnsigned(); + // zero pad if private key is less than 32 bytes + while (bytes.length < 32) bytes.unshift(0x00); + return bytes; + }; + + ECKey.prototype.toString = function(format) { + format = format || ""; + if (format.toString().toLowerCase() == "base64" || format.toString().toLowerCase() == "b64") { + return this.getBitcoinBase64Format(); + } + // Wallet Import Format + else if (format.toString().toLowerCase() == "wif") { + return this.getBitcoinWalletImportFormat(); + } else { + return this.getBitcoinHexFormat(); + } + }; + + ECKey.prototype.sign = function(hash) { + return ECDSA.sign(hash, this.priv); + }; + + ECKey.prototype.verify = function(hash, sig) { + return ECDSA.verify(hash, sig, this.getPub()); + }; + + /** + * Parse a wallet import format private key contained in a string. + */ + ECKey.decodeWalletImportFormat = function(privStr) { + var bytes = Bitcoin.Base58.decode(privStr); + var hash = bytes.slice(0, 33); + var checksum = Crypto.SHA256(Crypto.SHA256(hash, { + asBytes: true + }), { + asBytes: true + }); + if (checksum[0] != bytes[33] || + checksum[1] != bytes[34] || + checksum[2] != bytes[35] || + checksum[3] != bytes[36]) { + throw "Checksum validation failed!"; + + } + var version = hash.shift(); + if (version != ECKey.privateKeyPrefix) { + throw "Version " + version + " not supported!"; + } + return hash; + }; + + /** + * Parse a compressed wallet import format private key contained in a string. + */ + ECKey.decodeCompressedWalletImportFormat = function(privStr) { + var bytes = Bitcoin.Base58.decode(privStr); + var hash = bytes.slice(0, 34); + var checksum = Crypto.SHA256(Crypto.SHA256(hash, { + asBytes: true + }), { + asBytes: true + }); + if (checksum[0] != bytes[34] || + checksum[1] != bytes[35] || + checksum[2] != bytes[36] || + checksum[3] != bytes[37]) { + throw "Checksum validation failed!"; + } + var version = hash.shift(); + if (version != ECKey.privateKeyPrefix) { + throw "Version " + version + " not supported!"; + } + hash.pop(); + return hash; + }; + + // 64 characters [0-9A-F] + ECKey.isHexFormat = function(key) { + key = key.toString(); + return /^[A-Fa-f0-9]{64}$/.test(key); + }; + + // 51 characters base58, always starts with a '5' + ECKey.isWalletImportFormat = function(key) { + key = key.toString(); + return (ECKey.privateKeyPrefix == 0x80) ? + (/^5[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{50}$/.test(key)) : + (/^R[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{50}$/.test(key)); + }; + + // 52 characters base58 + ECKey.isCompressedWalletImportFormat = function(key) { + key = key.toString(); + return (ECKey.privateKeyPrefix == 0x80) ? + (/^[LK][123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test(key)) : + (/^R[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test(key)); + }; + + // 44 characters + ECKey.isBase64Format = function(key) { + key = key.toString(); + return (/^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789=+\/]{44}$/.test(key)); + }; + + // 99 characters, 1=1, if using dice convert 6 to 0 + ECKey.isBase6Format = function(key) { + key = key.toString(); + return (/^[012345]{99}$/.test(key)); + }; + + // 22, 26 or 30 characters, always starts with an 'S' + ECKey.isMiniFormat = function(key) { + key = key.toString(); + var validChars22 = /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21}$/.test(key); + var validChars26 = /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{25}$/.test(key); + var validChars30 = /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{29}$/.test(key); + var testBytes = Crypto.SHA256(key + "?", { + asBytes: true + }); + + return ((testBytes[0] === 0x00 || testBytes[0] === 0x01) && (validChars22 || validChars26 || validChars30)); + }; + + return ECKey; + })(); + //https://raw.github.com/bitcoinjs/bitcoinjs-lib/09e8c6e184d6501a0c2c59d73ca64db5c0d3eb95/src/util.js + // Bitcoin utility functions + Bitcoin.Util = { + /** + * Cross-browser compatibility version of Array.isArray. + */ + isArray: Array.isArray || function(o) { + return Object.prototype.toString.call(o) === '[object Array]'; + }, + /** + * Create an array of a certain length filled with a specific value. + */ + makeFilledArray: function(len, val) { + var array = []; + var i = 0; + while (i < len) { + array[i++] = val; + } + return array; + }, + /** + * Turn an integer into a "var_int". + * + * "var_int" is a variable length integer used by Bitcoin's binary format. + * + * Returns a byte array. + */ + numToVarInt: function(i) { + if (i < 0xfd) { + // unsigned char + return [i]; + } else if (i <= 1 << 16) { + // unsigned short (LE) + return [0xfd, i >>> 8, i & 255]; + } else if (i <= 1 << 32) { + // unsigned int (LE) + return [0xfe].concat(Crypto.util.wordsToBytes([i])); + } else { + // unsigned long long (LE) + return [0xff].concat(Crypto.util.wordsToBytes([i >>> 32, i])); + } + }, + /** + * Parse a Bitcoin value byte array, returning a BigInteger. + */ + valueToBigInt: function(valueBuffer) { + if (valueBuffer instanceof BigInteger) return valueBuffer; + + // Prepend zero byte to prevent interpretation as negative integer + return BigInteger.fromByteArrayUnsigned(valueBuffer); + }, + /** + * Format a Bitcoin value as a string. + * + * Takes a BigInteger or byte-array and returns that amount of Bitcoins in a + * nice standard formatting. + * + * Examples: + * 12.3555 + * 0.1234 + * 900.99998888 + * 34.00 + */ + formatValue: function(valueBuffer) { + var value = this.valueToBigInt(valueBuffer).toString(); + var integerPart = value.length > 8 ? value.substr(0, value.length - 8) : '0'; + var decimalPart = value.length > 8 ? value.substr(value.length - 8) : value; + while (decimalPart.length < 8) decimalPart = "0" + decimalPart; + decimalPart = decimalPart.replace(/0*$/, ''); + while (decimalPart.length < 2) decimalPart += "0"; + return integerPart + "." + decimalPart; + }, + /** + * Parse a floating point string as a Bitcoin value. + * + * Keep in mind that parsing user input is messy. You should always display + * the parsed value back to the user to make sure we understood his input + * correctly. + */ + parseValue: function(valueString) { + // TODO: Detect other number formats (e.g. comma as decimal separator) + var valueComp = valueString.split('.'); + var integralPart = valueComp[0]; + var fractionalPart = valueComp[1] || "0"; + while (fractionalPart.length < 8) fractionalPart += "0"; + fractionalPart = fractionalPart.replace(/^0+/g, ''); + var value = BigInteger.valueOf(parseInt(integralPart)); + value = value.multiply(BigInteger.valueOf(100000000)); + value = value.add(BigInteger.valueOf(parseInt(fractionalPart))); + return value; + }, + /** + * Calculate RIPEMD160(SHA256(data)). + * + * Takes an arbitrary byte array as inputs and returns the hash as a byte + * array. + */ + sha256ripe160: function(data) { + return ripemd160(Crypto.SHA256(data, { + asBytes: true + }), { + asBytes: true + }); + }, + // double sha256 + dsha256: function(data) { + return Crypto.SHA256(Crypto.SHA256(data, { + asBytes: true + }), { + asBytes: true + }); + }, + // duck typing method + hasMethods: function(obj /*, method list as strings */ ) { + var i = 1, + methodName; + while ((methodName = arguments[i++])) { + if (typeof obj[methodName] != 'function') { + return false; + } + } + return true; + } + }; +})(typeof global !== "undefined" ? global : window); + +//ellipticCurveEncryption.js +(function(GLOBAL) { + (function(ellipticCurveType) { + + //Defining Elliptic Encryption Object + var ellipticEncryption = GLOBAL.ellipticCurveEncryption = function() {}; + + ellipticEncryption.rng = new SecureRandom(); + + ellipticEncryption.getCurveParameters = function(curveName) { + + //Default is secp256k1 + curveName = typeof curveName !== 'undefined' ? curveName : "secp256k1"; + + var c = EllipticCurve.getSECCurveByName(curveName); + var curveDetails = { + Q: "", + A: "", + B: "", + GX: "", + GY: "", + N: "" + }; + + curveDetails.Q = c.getCurve().getQ().toString(); + curveDetails.A = c.getCurve().getA().toBigInteger().toString(); + curveDetails.B = c.getCurve().getB().toBigInteger().toString(); + curveDetails.GX = c.getG().getX().toBigInteger().toString(); + curveDetails.GY = c.getG().getY().toBigInteger().toString(); + curveDetails.N = c.getN().toString(); + + return curveDetails; + + } + + ellipticEncryption.selectedCurve = ellipticEncryption.getCurveParameters(ellipticCurveType); + + ellipticEncryption.get_curve = function() { + return new EllipticCurve.CurveFp(new BigInteger(this.selectedCurve.Q), + new BigInteger(this.selectedCurve.A), + new BigInteger(this.selectedCurve.B)); + } + + ellipticEncryption.get_G = function(curve) { + return new EllipticCurve.PointFp(curve, + curve.fromBigInteger(new BigInteger(this.selectedCurve.GX)), + curve.fromBigInteger(new BigInteger(this.selectedCurve.GY))); + } + + ellipticEncryption.pick_rand = function() { + var n = new BigInteger(this.selectedCurve.N); + var n1 = n.subtract(BigInteger.ONE); + var r = new BigInteger(n.bitLength(), this.rng); + return r.mod(n1).add(BigInteger.ONE); + } + + ellipticEncryption.senderRandom = function() { + var r = this.pick_rand(); + return r.toString(); + }; + + ellipticEncryption.receiverRandom = function() { + + //This is receivers private key. For now we will use random. CHANGE IT LATER + var r = this.pick_rand(); + return r.toString(); + } + + ellipticEncryption.senderPublicString = function(senderPrivateKey) { + + var senderKeyECData = {}; + + var curve = this.get_curve(); + var G = this.get_G(curve); + var a = new BigInteger(senderPrivateKey); + var P = G.multiply(a); + senderKeyECData.XValuePublicString = P.getX().toBigInteger().toString(); + senderKeyECData.YValuePublicString = P.getY().toBigInteger().toString(); + + return senderKeyECData; + } + + //In real life ellipticEncryption.receiverPublicString is the public key of the receiver. + //you don't have to run receiverRandom and the bottom function + ellipticEncryption.receiverPublicString = function(receiverPublicKey) { + + var receiverKeyECData = {}; + + var curve = this.get_curve(); + var G = this.get_G(curve); + var a = new BigInteger(receiverPublicKey); + var P = G.multiply(a); + receiverKeyECData.XValuePublicString = P.getX().toBigInteger().toString(); + receiverKeyECData.YValuePublicString = P.getY().toBigInteger().toString(); + + return receiverKeyECData; + } + + ellipticEncryption.senderSharedKeyDerivation = function(receiverPublicStringXValue, + receiverPublicStringYValue, senderPrivateKey) { + + var senderDerivedKey = {}; + var curve = this.get_curve(); + var P = new EllipticCurve.PointFp(curve, + curve.fromBigInteger(new BigInteger(receiverPublicStringXValue)), + curve.fromBigInteger(new BigInteger(receiverPublicStringYValue))); + var a = new BigInteger(senderPrivateKey); + var S = P.multiply(a); + + senderDerivedKey.XValue = S.getX().toBigInteger().toString(); + senderDerivedKey.YValue = S.getY().toBigInteger().toString(); + + return senderDerivedKey; + } + + ellipticEncryption.receiverSharedKeyDerivation = function(senderPublicStringXValue, + senderPublicStringYValue, receiverPrivateKey) { + + var receiverDerivedKey = {}; + var curve = this.get_curve(); + var P = new EllipticCurve.PointFp(curve, + curve.fromBigInteger(new BigInteger(senderPublicStringXValue)), + curve.fromBigInteger(new BigInteger(senderPublicStringYValue))); + var a = new BigInteger(receiverPrivateKey); + var S = P.multiply(a); + + receiverDerivedKey.XValue = S.getX().toBigInteger().toString(); + receiverDerivedKey.YValue = S.getY().toBigInteger().toString(); + + return receiverDerivedKey; + } + + })("secp256k1"); +})(typeof global !== "undefined" ? global : window); + +//secrets.js +(function(GLOBAL) { + //Shamir Secret Share by Alexander Stetsyuk - released under MIT License + + var SecretShare = GLOBAL.shamirSecretShare = {}; + var defaults = { + bits: 8, // default number of bits + radix: 16, // work with HEX by default + minBits: 3, + maxBits: 20, // this permits 1,048,575 shares, though going this high is NOT recommended in JS! + + bytesPerChar: 2, + maxBytesPerChar: 6, // Math.pow(256,7) > Math.pow(2,53) + + // Primitive polynomials (in decimal form) for Galois Fields GF(2^n), for 2 <= n <= 30 + // The index of each term in the array corresponds to the n for that polynomial + // i.e. to get the polynomial for n=16, use primitivePolynomials[16] + primitivePolynomials: [null, null, 1, 3, 3, 5, 3, 3, 29, 17, 9, 5, 83, 27, 43, 3, 45, 9, 39, 39, + 9, 5, 3, 33, 27, 9, 71, 39, 9, 5, 83 + ], + + // warning for insecure PRNG + warning: 'WARNING:\nA secure random number generator was not found.\nUsing Math.random(), which is NOT cryptographically strong!' + }; + + // Protected settings object + var config = {}; + + /** @expose **/ + SecretShare.getConfig = function() { + return { + 'bits': config.bits, + 'unsafePRNG': config.unsafePRNG + }; + }; + + function init(bits) { + if (bits && (typeof bits !== 'number' || bits % 1 !== 0 || bits < defaults.minBits || bits > + defaults.maxBits)) { + throw new Error('Number of bits must be an integer between ' + defaults.minBits + ' and ' + + defaults.maxBits + ', inclusive.') + } + + config.radix = defaults.radix; + config.bits = bits || defaults.bits; + config.size = Math.pow(2, config.bits); + config.max = config.size - 1; + + // Construct the exp and log tables for multiplication. + var logs = [], + exps = [], + x = 1, + primitive = defaults.primitivePolynomials[config.bits]; + for (var i = 0; i < config.size; i++) { + exps[i] = x; + logs[x] = i; + x <<= 1; + if (x >= config.size) { + x ^= primitive; + x &= config.max; + } + } + + config.logs = logs; + config.exps = exps; + }; + + /** @expose **/ + SecretShare.init = init; + + function isInited() { + if (!config.bits || !config.size || !config.max || !config.logs || !config.exps || config.logs.length !== + config.size || config.exps.length !== config.size) { + return false; + } + return true; + }; + + // Returns a pseudo-random number generator of the form function(bits){} + // which should output a random string of 1's and 0's of length `bits` + function getRNG() { + var randomBits, crypto; + + function construct(bits, arr, radix, size) { + var str = '', + i = 0, + len = arr.length - 1; + while (i < len || (str.length < bits)) { + str += padLeft(parseInt(arr[i], radix).toString(2), size); + i++; + } + str = str.substr(-bits); + if ((str.match(/0/g) || []).length === str.length) { // all zeros? + return null; + } else { + return str; + } + } + + // node.js crypto.randomBytes() + if (typeof require === 'function') { + return function(bits) { + var bytes = Math.ceil(bits / 8), + str = null; + + while (str === null) { + str = construct(bits, require('crypto').randomBytes(bytes).toString('hex'), 16, 4); + } + return str; + } + } + + // browsers with window.crypto.getRandomValues() + if (GLOBAL['crypto'] && typeof GLOBAL['crypto']['getRandomValues'] === 'function' && typeof GLOBAL[ + 'Uint32Array'] === 'function') { + crypto = GLOBAL['crypto']; + return function(bits) { + var elems = Math.ceil(bits / 32), + str = null, + arr = new GLOBAL['Uint32Array'](elems); + + while (str === null) { + crypto['getRandomValues'](arr); + str = construct(bits, arr, 10, 32); + } + + return str; + } + } + + // A totally insecure RNG!!! (except in Safari) + // Will produce a warning every time it is called. + config.unsafePRNG = true; + warn(); + + var bitsPerNum = 32; + var max = Math.pow(2, bitsPerNum) - 1; + return function(bits) { + var elems = Math.ceil(bits / bitsPerNum); + var arr = [], + str = null; + while (str === null) { + for (var i = 0; i < elems; i++) { + arr[i] = Math.floor(Math.random() * max + 1); + } + str = construct(bits, arr, 10, bitsPerNum); + } + return str; + }; + }; + + // Warn about using insecure rng. + // Called when Math.random() is being used. + function warn() { + GLOBAL['console']['warn'](defaults.warning); + if (typeof GLOBAL['alert'] === 'function' && config.alert) { + GLOBAL['alert'](defaults.warning); + } + } + + // Set the PRNG to use. If no RNG function is supplied, pick a default using getRNG() + /** @expose **/ + SecretShare.setRNG = function(rng, alert) { + if (!isInited()) { + this.init(); + } + config.unsafePRNG = false; + rng = rng || getRNG(); + + // test the RNG (5 times) + if (typeof rng !== 'function' || typeof rng(config.bits) !== 'string' || !parseInt(rng(config.bits), + 2) || rng(config.bits).length > config.bits || rng(config.bits).length < config.bits) { + throw new Error( + "Random number generator is invalid. Supply an RNG of the form function(bits){} that returns a string containing 'bits' number of random 1's and 0's." + ) + } else { + config.rng = rng; + } + config.alert = !!alert; + + return !!config.unsafePRNG; + }; + + function isSetRNG() { + return typeof config.rng === 'function'; + }; + + // Generates a random bits-length number string using the PRNG + /** @expose **/ + SecretShare.random = function(bits) { + if (!isSetRNG()) { + this.setRNG(); + } + + if (typeof bits !== 'number' || bits % 1 !== 0 || bits < 2) { + throw new Error('Number of bits must be an integer greater than 1.') + } + + if (config.unsafePRNG) { + warn(); + } + return bin2hex(config.rng(bits)); + } + + // Divides a `secret` number String str expressed in radix `inputRadix` (optional, default 16) + // into `numShares` shares, each expressed in radix `outputRadix` (optional, default to `inputRadix`), + // requiring `threshold` number of shares to reconstruct the secret. + // Optionally, zero-pads the secret to a length that is a multiple of padLength before sharing. + /** @expose **/ + SecretShare.share = function(secret, numShares, threshold, padLength, withoutPrefix) { + if (!isInited()) { + this.init(); + } + if (!isSetRNG()) { + this.setRNG(); + } + + padLength = padLength || 0; + + if (typeof secret !== 'string') { + throw new Error('Secret must be a string.'); + } + if (typeof numShares !== 'number' || numShares % 1 !== 0 || numShares < 2) { + throw new Error('Number of shares must be an integer between 2 and 2^bits-1 (' + config.max + + '), inclusive.') + } + if (numShares > config.max) { + var neededBits = Math.ceil(Math.log(numShares + 1) / Math.LN2); + throw new Error('Number of shares must be an integer between 2 and 2^bits-1 (' + config.max + + '), inclusive. To create ' + numShares + ' shares, use at least ' + neededBits + + ' bits.') + } + if (typeof threshold !== 'number' || threshold % 1 !== 0 || threshold < 2) { + throw new Error('Threshold number of shares must be an integer between 2 and 2^bits-1 (' + + config.max + '), inclusive.'); + } + if (threshold > config.max) { + var neededBits = Math.ceil(Math.log(threshold + 1) / Math.LN2); + throw new Error('Threshold number of shares must be an integer between 2 and 2^bits-1 (' + + config.max + '), inclusive. To use a threshold of ' + threshold + + ', use at least ' + neededBits + ' bits.'); + } + if (typeof padLength !== 'number' || padLength % 1 !== 0) { + throw new Error('Zero-pad length must be an integer greater than 1.'); + } + + if (config.unsafePRNG) { + warn(); + } + + secret = '1' + hex2bin(secret); // append a 1 so that we can preserve the correct number of leading zeros in our secret + secret = split(secret, padLength); + var x = new Array(numShares), + y = new Array(numShares); + for (var i = 0, len = secret.length; i < len; i++) { + var subShares = this._getShares(secret[i], numShares, threshold); + for (var j = 0; j < numShares; j++) { + x[j] = x[j] || subShares[j].x.toString(config.radix); + y[j] = padLeft(subShares[j].y.toString(2)) + (y[j] ? y[j] : ''); + } + } + var padding = config.max.toString(config.radix).length; + if (withoutPrefix) { + for (var i = 0; i < numShares; i++) { + x[i] = bin2hex(y[i]); + } + } else { + for (var i = 0; i < numShares; i++) { + x[i] = config.bits.toString(36).toUpperCase() + padLeft(x[i], padding) + bin2hex(y[i]); + } + } + + return x; + }; + + // This is the basic polynomial generation and evaluation function + // for a `config.bits`-length secret (NOT an arbitrary length) + // Note: no error-checking at this stage! If `secrets` is NOT + // a NUMBER less than 2^bits-1, the output will be incorrect! + /** @expose **/ + SecretShare._getShares = function(secret, numShares, threshold) { + var shares = []; + var coeffs = [secret]; + + for (var i = 1; i < threshold; i++) { + coeffs[i] = parseInt(config.rng(config.bits), 2); + } + for (var i = 1, len = numShares + 1; i < len; i++) { + shares[i - 1] = { + x: i, + y: horner(i, coeffs) + } + } + return shares; + }; + + // Polynomial evaluation at `x` using Horner's Method + // TODO: this can possibly be sped up using other methods + // NOTE: fx=fx * x + coeff[i] -> exp(log(fx) + log(x)) + coeff[i], + // so if fx===0, just set fx to coeff[i] because + // using the exp/log form will result in incorrect value + function horner(x, coeffs) { + var logx = config.logs[x]; + var fx = 0; + for (var i = coeffs.length - 1; i >= 0; i--) { + if (fx === 0) { + fx = coeffs[i]; + continue; + } + fx = config.exps[(logx + config.logs[fx]) % config.max] ^ coeffs[i]; + } + return fx; + }; + + function inArray(arr, val) { + for (var i = 0, len = arr.length; i < len; i++) { + if (arr[i] === val) { + return true; + } + } + return false; + }; + + function processShare(share) { + + var bits = parseInt(share[0], 36); + if (bits && (typeof bits !== 'number' || bits % 1 !== 0 || bits < defaults.minBits || bits > + defaults.maxBits)) { + throw new Error('Number of bits must be an integer between ' + defaults.minBits + ' and ' + + defaults.maxBits + ', inclusive.') + } + + var max = Math.pow(2, bits) - 1; + var idLength = max.toString(config.radix).length; + + var id = parseInt(share.substr(1, idLength), config.radix); + if (typeof id !== 'number' || id % 1 !== 0 || id < 1 || id > max) { + throw new Error('Share id must be an integer between 1 and ' + config.max + ', inclusive.'); + } + share = share.substr(idLength + 1); + if (!share.length) { + throw new Error('Invalid share: zero-length share.') + } + return { + 'bits': bits, + 'id': id, + 'value': share + }; + }; + + /** @expose **/ + SecretShare._processShare = processShare; + + // Protected method that evaluates the Lagrange interpolation + // polynomial at x=`at` for individual config.bits-length + // segments of each share in the `shares` Array. + // Each share is expressed in base `inputRadix`. The output + // is expressed in base `outputRadix' + function combine(at, shares) { + var setBits, share, x = [], + y = [], + result = '', + idx; + + for (var i = 0, len = shares.length; i < len; i++) { + share = processShare(shares[i]); + if (typeof setBits === 'undefined') { + setBits = share['bits']; + } else if (share['bits'] !== setBits) { + throw new Error('Mismatched shares: Different bit settings.') + } + + if (config.bits !== setBits) { + init(setBits); + } + + if (inArray(x, share['id'])) { // repeated x value? + continue; + } + + idx = x.push(share['id']) - 1; + share = split(hex2bin(share['value'])); + for (var j = 0, len2 = share.length; j < len2; j++) { + y[j] = y[j] || []; + y[j][idx] = share[j]; + } + } + + for (var i = 0, len = y.length; i < len; i++) { + result = padLeft(lagrange(at, x, y[i]).toString(2)) + result; + } + + if (at === 0) { // reconstructing the secret + var idx = result.indexOf('1'); //find the first 1 + return bin2hex(result.slice(idx + 1)); + } else { // generating a new share + return bin2hex(result); + } + }; + + // Combine `shares` Array into the original secret + /** @expose **/ + SecretShare.combine = function(shares) { + return combine(0, shares); + }; + + // Generate a new share with id `id` (a number between 1 and 2^bits-1) + // `id` can be a Number or a String in the default radix (16) + /** @expose **/ + SecretShare.newShare = function(id, shares) { + if (typeof id === 'string') { + id = parseInt(id, config.radix); + } + + var share = processShare(shares[0]); + var max = Math.pow(2, share['bits']) - 1; + + if (typeof id !== 'number' || id % 1 !== 0 || id < 1 || id > max) { + throw new Error('Share id must be an integer between 1 and ' + config.max + ', inclusive.'); + } + + var padding = max.toString(config.radix).length; + return config.bits.toString(36).toUpperCase() + padLeft(id.toString(config.radix), padding) + + combine(id, shares); + }; + + // Evaluate the Lagrange interpolation polynomial at x = `at` + // using x and y Arrays that are of the same length, with + // corresponding elements constituting points on the polynomial. + function lagrange(at, x, y) { + var sum = 0, + product, + i, j; + + for (var i = 0, len = x.length; i < len; i++) { + if (!y[i]) { + continue; + } + + product = config.logs[y[i]]; + for (var j = 0; j < len; j++) { + if (i === j) { + continue; + } + if (at === x[j]) { // happens when computing a share that is in the list of shares used to compute it + product = -1; // fix for a zero product term, after which the sum should be sum^0 = sum, not sum^1 + break; + } + product = (product + config.logs[at ^ x[j]] - config.logs[x[i] ^ x[j]] + config.max /* to make sure it's not negative */ ) % + config.max; + } + + sum = product === -1 ? sum : sum ^ config.exps[product]; // though exps[-1]= undefined and undefined ^ anything = anything in chrome, this behavior may not hold everywhere, so do the check + } + return sum; + }; + + /** @expose **/ + SecretShare._lagrange = lagrange; + + // Splits a number string `bits`-length segments, after first + // optionally zero-padding it to a length that is a multiple of `padLength. + // Returns array of integers (each less than 2^bits-1), with each element + // representing a `bits`-length segment of the input string from right to left, + // i.e. parts[0] represents the right-most `bits`-length segment of the input string. + function split(str, padLength) { + if (padLength) { + str = padLeft(str, padLength) + } + var parts = []; + for (var i = str.length; i > config.bits; i -= config.bits) { + parts.push(parseInt(str.slice(i - config.bits, i), 2)); + } + parts.push(parseInt(str.slice(0, i), 2)); + return parts; + }; + + // Pads a string `str` with zeros on the left so that its length is a multiple of `bits` + function padLeft(str, bits) { + bits = bits || config.bits + var missing = str.length % bits; + return (missing ? new Array(bits - missing + 1).join('0') : '') + str; + }; + + function hex2bin(str) { + var bin = '', + num; + for (var i = str.length - 1; i >= 0; i--) { + num = parseInt(str[i], 16) + if (isNaN(num)) { + throw new Error('Invalid hex character.') + } + bin = padLeft(num.toString(2), 4) + bin; + } + return bin; + } + + function bin2hex(str) { + var hex = '', + num; + str = padLeft(str, 4); + for (var i = str.length; i >= 4; i -= 4) { + num = parseInt(str.slice(i - 4, i), 2); + if (isNaN(num)) { + throw new Error('Invalid binary character.') + } + hex = num.toString(16) + hex; + } + return hex; + } + + // Converts a given UTF16 character string to the HEX representation. + // Each character of the input string is represented by + // `bytesPerChar` bytes in the output string. + /** @expose **/ + SecretShare.str2hex = function(str, bytesPerChar) { + if (typeof str !== 'string') { + throw new Error('Input must be a character string.'); + } + bytesPerChar = bytesPerChar || defaults.bytesPerChar; + + if (typeof bytesPerChar !== 'number' || bytesPerChar % 1 !== 0 || bytesPerChar < 1 || + bytesPerChar > defaults.maxBytesPerChar) { + throw new Error('Bytes per character must be an integer between 1 and ' + defaults.maxBytesPerChar + + ', inclusive.') + } + + var hexChars = 2 * bytesPerChar; + var max = Math.pow(16, hexChars) - 1; + var out = '', + num; + for (var i = 0, len = str.length; i < len; i++) { + num = str[i].charCodeAt(); + if (isNaN(num)) { + throw new Error('Invalid character: ' + str[i]); + } else if (num > max) { + var neededBytes = Math.ceil(Math.log(num + 1) / Math.log(256)); + throw new Error('Invalid character code (' + num + + '). Maximum allowable is 256^bytes-1 (' + max + + '). To convert this character, use at least ' + neededBytes + ' bytes.') + } else { + out = padLeft(num.toString(16), hexChars) + out; + } + } + return out; + }; + + // Converts a given HEX number string to a UTF16 character string. + /** @expose **/ + SecretShare.hex2str = function(str, bytesPerChar) { + if (typeof str !== 'string') { + throw new Error('Input must be a hexadecimal string.'); + } + bytesPerChar = bytesPerChar || defaults.bytesPerChar; + + if (typeof bytesPerChar !== 'number' || bytesPerChar % 1 !== 0 || bytesPerChar < 1 || + bytesPerChar > defaults.maxBytesPerChar) { + throw new Error('Bytes per character must be an integer between 1 and ' + defaults.maxBytesPerChar + + ', inclusive.') + } + + var hexChars = 2 * bytesPerChar; + var out = ''; + str = padLeft(str, hexChars); + for (var i = 0, len = str.length; i < len; i += hexChars) { + out = String.fromCharCode(parseInt(str.slice(i, i + hexChars), 16)) + out; + } + return out; + }; + + // by default, initialize without an RNG + SecretShare.init(); +})(typeof global !== 'undefined' ? global : window); + + +/* FLO Crypto Operators*/ +(function(GLOBAL) { + const floCrypto = GLOBAL.floCrypto = { + + util: { + p: BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16), + + ecparams: EllipticCurve.getSECCurveByName("secp256k1"), + + asciiAlternatives: `‘ '\n’ '\n“ "\n†"\n– --\n— ---\n≥ >=\n≤ <=\n≠ !=\n× *\n÷ /\n↠<-\n→ ->\n↔ <->\n⇒ =>\n⇠<=\n⇔ <=>`, + + exponent1: function() { + return this.p.add(BigInteger.ONE).divide(BigInteger("4")) + }, + + calculateY: function(x) { + let p = this.p; + let exp = this.exponent1(); + // x is x value of public key in BigInteger format without 02 or 03 or 04 prefix + return x.modPow(BigInteger("3"), p).add(BigInteger("7")).mod(p).modPow(exp, p) + }, + getUncompressedPublicKey: function(compressedPublicKey) { + const p = this.p; + // Fetch x from compressedPublicKey + let pubKeyBytes = Crypto.util.hexToBytes(compressedPublicKey); + const prefix = pubKeyBytes.shift() // remove prefix + let prefix_modulus = prefix % 2; + pubKeyBytes.unshift(0) // add prefix 0 + let x = new BigInteger(pubKeyBytes) + let xDecimalValue = x.toString() + // Fetch y + let y = this.calculateY(x); + let yDecimalValue = y.toString(); + // verify y value + let resultBigInt = y.mod(BigInteger("2")); + let check = resultBigInt.toString() % 2; + if (prefix_modulus !== check) + yDecimalValue = y.negate().mod(p).toString(); + return { + x: xDecimalValue, + y: yDecimalValue + }; + }, + + getSenderPublicKeyString: function() { + let privateKey = ellipticCurveEncryption.senderRandom(); + var senderPublicKeyString = ellipticCurveEncryption.senderPublicString(privateKey); + return { + privateKey: privateKey, + senderPublicKeyString: senderPublicKeyString + } + }, + + deriveSharedKeySender: function(receiverCompressedPublicKey, senderPrivateKey) { + let receiverPublicKeyString = this.getUncompressedPublicKey(receiverCompressedPublicKey); + var senderDerivedKey = ellipticCurveEncryption.senderSharedKeyDerivation( + receiverPublicKeyString.x, receiverPublicKeyString.y, senderPrivateKey); + return senderDerivedKey; + }, + + deriveReceiverSharedKey: function(senderPublicKeyString, receiverPrivateKey) { + return ellipticCurveEncryption.receiverSharedKeyDerivation( + senderPublicKeyString.XValuePublicString, senderPublicKeyString.YValuePublicString, receiverPrivateKey); + }, + + getReceiverPublicKeyString: function(privateKey) { + return ellipticCurveEncryption.receiverPublicString(privateKey); + }, + + deriveSharedKeyReceiver: function(senderPublicKeyString, receiverPrivateKey) { + return ellipticCurveEncryption.receiverSharedKeyDerivation( + senderPublicKeyString.XValuePublicString, senderPublicKeyString.YValuePublicString, receiverPrivateKey); + }, + + wifToDecimal: function(pk_wif, isPubKeyCompressed = false) { + let pk = Bitcoin.Base58.decode(pk_wif) + pk.shift() + pk.splice(-4, 4) + //If the private key corresponded to a compressed public key, also drop the last byte (it should be 0x01). + if (isPubKeyCompressed == true) pk.pop() + pk.unshift(0) + let privateKeyDecimal = BigInteger(pk).toString() + let privateKeyHex = Crypto.util.bytesToHex(pk) + return { + privateKeyDecimal: privateKeyDecimal, + privateKeyHex: privateKeyHex + } + } + }, + + //generate a random Interger within range + randInt: function(min, max) { + min = Math.ceil(min); + max = Math.floor(max); + return Math.floor(Math.random() * (max - min + 1)) + min; + }, + + //generate a random String within length (options : alphaNumeric chars only) + randString: function(length, alphaNumeric = true) { + var result = ''; + if (alphaNumeric) + var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + else + var characters = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_+-./*?@#&$<>=[]{}():'; + for (var i = 0; i < length; i++) + result += characters.charAt(Math.floor(Math.random() * characters.length)); + return result; + }, + + //Encrypt Data using public-key + encryptData: function(data, receiverCompressedPublicKey) { + var senderECKeyData = this.util.getSenderPublicKeyString(); + var senderDerivedKey = this.util.deriveSharedKeySender(receiverCompressedPublicKey, senderECKeyData + .privateKey); + let senderKey = senderDerivedKey.XValue + senderDerivedKey.YValue; + let secret = Crypto.AES.encrypt(data, senderKey); + return { + secret: secret, + senderPublicKeyString: senderECKeyData.senderPublicKeyString + }; + }, + + //Decrypt Data using private-key + decryptData: function(data, myPrivateKey) { + var receiverECKeyData = {}; + if (typeof myPrivateKey !== "string") throw new Error("No private key found."); + + let privateKey = this.util.wifToDecimal(myPrivateKey, true); + if (typeof privateKey.privateKeyDecimal !== "string") throw new Error( + "Failed to detremine your private key."); + receiverECKeyData.privateKey = privateKey.privateKeyDecimal; + + var receiverDerivedKey = this.util.deriveReceiverSharedKey(data.senderPublicKeyString, + receiverECKeyData + .privateKey); + + let receiverKey = receiverDerivedKey.XValue + receiverDerivedKey.YValue; + let decryptMsg = Crypto.AES.decrypt(data.secret, receiverKey); + return decryptMsg; + }, + + //Sign data using private-key + signData: function(data, privateKeyHex) { + var key = new Bitcoin.ECKey(privateKeyHex); + key.setCompressed(true); + + var privateKeyArr = key.getBitcoinPrivateKeyByteArray(); + var privateKey = BigInteger.fromByteArrayUnsigned(privateKeyArr); + var messageHash = Crypto.SHA256(data); + + var messageHashBigInteger = new BigInteger(messageHash); + var messageSign = Bitcoin.ECDSA.sign(messageHashBigInteger, key.priv); + + var sighex = Crypto.util.bytesToHex(messageSign); + return sighex; + }, + + //Verify signatue of the data using public-key + verifySign: function(data, signatureHex, publicKeyHex) { + var msgHash = Crypto.SHA256(data); + var messageHashBigInteger = new BigInteger(msgHash); + + var sigBytes = Crypto.util.hexToBytes(signatureHex); + var signature = Bitcoin.ECDSA.parseSig(sigBytes); + + var publicKeyPoint = this.util.ecparams.getCurve().decodePointHex(publicKeyHex); + + var verify = Bitcoin.ECDSA.verifyRaw(messageHashBigInteger, signature.r, signature.s, + publicKeyPoint); + return verify; + }, + + //Generates a new flo ID and returns private-key, public-key and floID + generateNewID: function() { + try { + var key = new Bitcoin.ECKey(false); + key.setCompressed(true); + return { + floID: key.getBitcoinAddress(), + pubKey: key.getPubKeyHex(), + privKey: key.getBitcoinWalletImportFormat() + } + } catch (e) { + console.error(e); + } + }, + + //Returns public-key from private-key + getPubKeyHex: function(privateKeyHex) { + if (!privateKeyHex) + return null; + var key = new Bitcoin.ECKey(privateKeyHex); + if (key.priv == null) + return null; + key.setCompressed(true); + return key.getPubKeyHex(); + }, + + //Returns flo-ID from public-key or private-key + getFloID: function(keyHex) { + if (!keyHex) + return null; + try { + var key = new Bitcoin.ECKey(keyHex); + if (key.priv == null) + key.setPub(keyHex); + return key.getBitcoinAddress(); + } catch (e) { + return null; + } + }, + + //Verify the private-key for the given public-key or flo-ID + verifyPrivKey: function(privateKeyHex, pubKey_floID, isfloID = true) { + if (!privateKeyHex || !pubKey_floID) + return false; + try { + var key = new Bitcoin.ECKey(privateKeyHex); + if (key.priv == null) + return false; + key.setCompressed(true); + if (isfloID && pubKey_floID == key.getBitcoinAddress()) + return true; + else if (!isfloID && pubKey_floID == key.getPubKeyHex()) + return true; + else + return false; + } catch (e) { + console.error(e); + } + }, + + //Check if the given Address is valid or not + validateAddr: function(inpAddr) { + if (!inpAddr) + return false; + try { + var addr = new Bitcoin.Address(inpAddr); + return true; + } catch { + return false; + } + }, + + //Split the str using shamir's Secret and Returns the shares + createShamirsSecretShares: function(str, total_shares, threshold_limit) { + try { + if (str.length > 0) { + var strHex = shamirSecretShare.str2hex(str); + var shares = shamirSecretShare.share(strHex, total_shares, threshold_limit); + return shares; + } + return false; + } catch { + return false + } + }, + + //Verifies the shares and str + verifyShamirsSecret: function(sharesArray, str) { + return (str && this.retrieveShamirSecret(sharesArray) === str) + }, + + //Returns the retrived secret by combining the shamirs shares + retrieveShamirSecret: function(sharesArray) { + try { + if (sharesArray.length > 0) { + var comb = shamirSecretShare.combine(sharesArray.slice(0, sharesArray.length)); + comb = shamirSecretShare.hex2str(comb); + return comb; + } + return false; + } catch { + return false; + } + }, + + validateASCII: function(string, bool = true) { + if (typeof string !== "string") + return null; + if (bool) { + let x; + for (let i = 0; i < string.length; i++) { + x = string.charCodeAt(i); + if (x < 32 || x > 127) + return false; + } + return true; + } else { + let x, invalids = {}; + for (let i = 0; i < string.length; i++) { + x = string.charCodeAt(i); + if (x < 32 || x > 127) + if (x in invalids) + invalids[string[i]].push(i) + else + invalids[string[i]] = [i]; + } + if (Object.keys(invalids).length) + return invalids; + else + return true; + } + }, + + convertToASCII: function(string, mode = 'soft-remove') { + let chars = this.validateASCII(string, false); + if (chars === true) + return string; + else if (chars === null) + return null; + let convertor, result = string, + refAlt = {}; + this.util.asciiAlternatives.split('\n').forEach(a => refAlt[a[0]] = a.slice(2)); + mode = mode.toLowerCase(); + if (mode === "hard-unicode") + convertor = (c) => `\\u${('000'+c.charCodeAt().toString(16)).slice(-4)}`; + else if (mode === "soft-unicode") + convertor = (c) => refAlt[c] || `\\u${('000'+c.charCodeAt().toString(16)).slice(-4)}`; + else if (mode === "hard-remove") + convertor = c => ""; + else if (mode === "soft-remove") + convertor = c => refAlt[c] || ""; + else + return null; + for (let c in chars) + result = result.replaceAll(c, convertor(c)); + return result; + }, + + revertUnicode: function(string) { + return string.replace(/\\u[\dA-F]{4}/gi, + m => String.fromCharCode(parseInt(m.replace(/\\u/g, ''), 16))); + } + } + +})(typeof global !== "undefined" ? global : window); + +/* FLO Blockchain Operator to send/receive data from blockchain using API calls*/ +//floBlockchainAPI v2.2.1a +(function(GLOBAL) { + const floBlockchainAPI = GLOBAL.floBlockchainAPI = { + + util: { + serverList: floGlobals.apiURL[floGlobals.blockchain].slice(0), + curPos: floCrypto.randInt(0, floGlobals.apiURL[floGlobals.blockchain].length - 1), + fetch_retry: function(apicall, rm_flosight) { + return new Promise((resolve, reject) => { + let i = this.serverList.indexOf(rm_flosight) + if (i != -1) this.serverList.splice(i, 1); + this.curPos = floCrypto.randInt(0, this.serverList.length - 1); + this.fetch_api(apicall) + .then(result => resolve(result)) + .catch(error => reject(error)); + }) + }, + fetch_api: function(apicall) { + return new Promise((resolve, reject) => { + if (this.serverList.length === 0) + reject("No floSight server working"); + else { + let flosight = this.serverList[this.curPos]; + fetch(flosight + apicall).then(response => { + if (response.ok) + response.json().then(data => resolve(data)); + else { + this.fetch_retry(apicall, flosight) + .then(result => resolve(result)) + .catch(error => reject(error)); + } + }).catch(error => { + this.fetch_retry(apicall, flosight) + .then(result => resolve(result)) + .catch(error => reject(error)); + }) + } + }) + }, + + current: function() { + return this.serverList[this.curPos]; + } + }, + + //Promised function to get data from API + promisedAPI: function(apicall) { + return new Promise((resolve, reject) => { + //console.log(apicall); + this.util.fetch_api(apicall) + .then(result => resolve(result)) + .catch(error => reject(error)); + }); + }, + + //Get balance for the given Address + getBalance: function(addr) { + return new Promise((resolve, reject) => { + this.promisedAPI(`api/addr/${addr}/balance`) + .then(balance => resolve(parseFloat(balance))) + .catch(error => reject(error)); + }); + }, + + //Write Data into blockchain + writeData: function(senderAddr, data, privKey, receiverAddr = floGlobals.adminID, strict_utxo = true) { + return new Promise((resolve, reject) => { + if (typeof data != "string") + data = JSON.stringify(data); + this.sendTx(senderAddr, receiverAddr, floGlobals.sendAmt, privKey, data, strict_utxo) + .then(txid => resolve(txid)) + .catch(error => reject(error)); + }); + }, + + //Send Tx to blockchain + sendTx: function(senderAddr, receiverAddr, sendAmt, privKey, floData = '', strict_utxo = true) { + return new Promise((resolve, reject) => { + if (!floCrypto.validateASCII(floData)) + return reject("Invalid FLO_Data: only printable ASCII characters are allowed"); + else if (!floCrypto.validateAddr(senderAddr)) + return reject(`Invalid address : ${senderAddr}`); + else if (!floCrypto.validateAddr(receiverAddr)) + return reject(`Invalid address : ${receiverAddr}`); + else if (privKey.length < 1 || !floCrypto.verifyPrivKey(privKey, senderAddr)) + return reject("Invalid Private key!"); + else if (typeof sendAmt !== 'number' || sendAmt <= 0) + return reject(`Invalid sendAmt : ${sendAmt}`); + + //get unconfirmed tx list + this.promisedAPI(`api/addr/${senderAddr}`).then(result => { + this.readTxs(senderAddr, 0, result.unconfirmedTxApperances).then(result => { + let unconfirmedSpent = {}; + for (let tx of result.items) + if (tx.confirmations == 0) + for (let vin of tx.vin) + if (vin.addr === senderAddr) { + if (Array.isArray(unconfirmedSpent[vin.txid])) + unconfirmedSpent[vin.txid].push(vin.vout); + else + unconfirmedSpent[vin.txid] = [vin.vout]; + } + //get utxos list + this.promisedAPI(`api/addr/${senderAddr}/utxo`).then(utxos => { + //form/construct the transaction data + var trx = bitjs.transaction(); + var utxoAmt = 0.0; + var fee = floGlobals.fee; + for (var i = utxos.length - 1; + (i >= 0) && (utxoAmt < sendAmt + fee); i--) { + //use only utxos with confirmations (strict_utxo mode) + if (utxos[i].confirmations || !strict_utxo) { + if (utxos[i].txid in unconfirmedSpent && unconfirmedSpent[utxos[i].txid].includes(utxos[i].vout)) + continue; //A transaction has already used this utxo, but is unconfirmed. + trx.addinput(utxos[i].txid, utxos[i].vout, utxos[i].scriptPubKey); + utxoAmt += utxos[i].amount; + }; + } + if (utxoAmt < sendAmt + fee) + reject("Insufficient FLO balance!"); + else { + trx.addoutput(receiverAddr, sendAmt); + var change = utxoAmt - sendAmt - fee; + if (change > 0) + trx.addoutput(senderAddr, change); + trx.addflodata(floData.replace(/\n/g, ' ')); + var signedTxHash = trx.sign(privKey, 1); + this.broadcastTx(signedTxHash) + .then(txid => resolve(txid)) + .catch(error => reject(error)) + } + }).catch(error => reject(error)) + }).catch(error => reject(error)) + }).catch(error => reject(error)) + }); + }, + + //merge all UTXOs of a given floID into a single UTXO + mergeUTXOs: function(floID, privKey, floData = '') { + return new Promise((resolve, reject) => { + if (!floCrypto.validateAddr(floID)) + return reject(`Invalid floID`); + if (!floCrypto.verifyPrivKey(privKey, floID)) + return reject("Invalid Private Key"); + if (!floCrypto.validateASCII(floData)) + return reject("Invalid FLO_Data: only printable ASCII characters are allowed"); + var trx = bitjs.transaction(); + var utxoAmt = 0.0; + var fee = floGlobals.fee; + this.promisedAPI(`api/addr/${floID}/utxo`).then(utxos => { + for (var i = utxos.length - 1; i >= 0; i--) + if (utxos[i].confirmations) { + trx.addinput(utxos[i].txid, utxos[i].vout, utxos[i].scriptPubKey); + utxoAmt += utxos[i].amount; + } + trx.addoutput(floID, utxoAmt - fee); + trx.addflodata(floData.replace(/\n/g, ' ')); + var signedTxHash = trx.sign(privKey, 1); + this.broadcastTx(signedTxHash) + .then(txid => resolve(txid)) + .catch(error => reject(error)) + }).catch(error => reject(error)) + }) + }, + + /**Write data into blockchain from (and/or) to multiple floID + * @param {Array} senderPrivKeys List of sender private-keys + * @param {string} data FLO data of the txn + * @param {Array} receivers List of receivers + * @param {boolean} preserveRatio (optional) preserve ratio or equal contribution + * @return {Promise} + */ + writeDataMultiple: function(senderPrivKeys, data, receivers = [floGlobals.adminID], preserveRatio = true) { + return new Promise((resolve, reject) => { + if (!Array.isArray(senderPrivKeys)) + return reject("Invalid senderPrivKeys: SenderPrivKeys must be Array"); + if (!preserveRatio) { + let tmp = {}; + let amount = (floGlobals.sendAmt * receivers.length) / senderPrivKeys.length; + senderPrivKeys.forEach(key => tmp[key] = amount); + senderPrivKeys = tmp; + } + if (!Array.isArray(receivers)) + return reject("Invalid receivers: Receivers must be Array"); + else { + let tmp = {}; + let amount = floGlobals.sendAmt; + receivers.forEach(floID => tmp[floID] = amount); + receivers = tmp + } + if (typeof data != "string") + data = JSON.stringify(data); + this.sendTxMultiple(senderPrivKeys, receivers, data) + .then(txid => resolve(txid)) + .catch(error => reject(error)) + }) + }, + + /**Send Tx from (and/or) to multiple floID + * @param {Array or Object} senderPrivKeys List of sender private-key (optional: with coins to be sent) + * @param {Object} receivers List of receivers with respective amount to be sent + * @param {string} floData FLO data of the txn + * @return {Promise} + */ + sendTxMultiple: function(senderPrivKeys, receivers, floData = '') { + return new Promise((resolve, reject) => { + if (!floCrypto.validateASCII(floData)) + return reject("Invalid FLO_Data: only printable ASCII characters are allowed"); + let senders = {}, + preserveRatio; + //check for argument validations + try { + let invalids = { + InvalidSenderPrivKeys: [], + InvalidSenderAmountFor: [], + InvalidReceiverIDs: [], + InvalidReceiveAmountFor: [] + } + let inputVal = 0, + outputVal = 0; + //Validate sender privatekeys (and send amount if passed) + //conversion when only privateKeys are passed (preserveRatio mode) + if (Array.isArray(senderPrivKeys)) { + senderPrivKeys.forEach(key => { + try { + if (!key) + invalids.InvalidSenderPrivKeys.push(key); + else { + let floID = floCrypto.getFloID(key); + senders[floID] = { + wif: key + } + } + } catch (error) { + invalids.InvalidSenderPrivKeys.push(key) + } + }) + preserveRatio = true; + } + //conversion when privatekeys are passed with send amount + else { + for (let key in senderPrivKeys) { + try { + if (!key) + invalids.InvalidSenderPrivKeys.push(key); + else { + if (typeof senderPrivKeys[key] !== 'number' || senderPrivKeys[key] <= 0) + invalids.InvalidSenderAmountFor.push(key); + else + inputVal += senderPrivKeys[key]; + let floID = floCrypto.getFloID(key); + senders[floID] = { + wif: key, + coins: senderPrivKeys[key] + } + } + } catch (error) { + invalids.InvalidSenderPrivKeys.push(key) + } + } + preserveRatio = false; + } + //Validate the receiver IDs and receive amount + for (let floID in receivers) { + if (!floCrypto.validateAddr(floID)) + invalids.InvalidReceiverIDs.push(floID); + if (typeof receivers[floID] !== 'number' || receivers[floID] <= 0) + invalids.InvalidReceiveAmountFor.push(floID); + else + outputVal += receivers[floID]; + } + //Reject if any invalids are found + for (let i in invalids) + if (!invalids[i].length) + delete invalids[i]; + if (Object.keys(invalids).length) + return reject(invalids); + //Reject if given inputVal and outputVal are not equal + if (!preserveRatio && inputVal != outputVal) + return reject(`Input Amount (${inputVal}) not equal to Output Amount (${outputVal})`); + } catch (error) { + return reject(error) + } + //Get balance of senders + let promises = []; + for (let floID in senders) + promises.push(this.getBalance(floID)); + Promise.all(promises).then(results => { + let totalBalance = 0, + totalFee = floGlobals.fee, + balance = {}; + //Divide fee among sender if not for preserveRatio + if (!preserveRatio) + var dividedFee = totalFee / Object.keys(senders).length; + //Check if balance of each sender is sufficient enough + let insufficient = []; + for (let floID in senders) { + balance[floID] = parseFloat(results.shift()); + if (isNaN(balance[floID]) || (preserveRatio && balance[floID] <= totalFee) || + (!preserveRatio && balance[floID] < senders[floID].coins + dividedFee)) + insufficient.push(floID); + totalBalance += balance[floID]; + } + if (insufficient.length) + return reject({ + InsufficientBalance: insufficient + }) + //Calculate totalSentAmount and check if totalBalance is sufficient + let totalSendAmt = totalFee; + for (floID in receivers) + totalSendAmt += receivers[floID]; + if (totalBalance < totalSendAmt) + return reject("Insufficient total Balance"); + //Get the UTXOs of the senders + let promises = []; + for (floID in senders) + promises.push(this.promisedAPI(`api/addr/${floID}/utxo`)); + Promise.all(promises).then(results => { + let wifSeq = []; + var trx = bitjs.transaction(); + for (floID in senders) { + let utxos = results.shift(); + let sendAmt; + if (preserveRatio) { + let ratio = (balance[floID] / totalBalance); + sendAmt = totalSendAmt * ratio; + } else + sendAmt = senders[floID].coins + dividedFee; + let wif = senders[floID].wif; + let utxoAmt = 0.0; + for (let i = utxos.length - 1; + (i >= 0) && (utxoAmt < sendAmt); i--) { + if (utxos[i].confirmations) { + trx.addinput(utxos[i].txid, utxos[i].vout, utxos[i].scriptPubKey); + wifSeq.push(wif); + utxoAmt += utxos[i].amount; + } + } + if (utxoAmt < sendAmt) + return reject("Insufficient balance:" + floID); + let change = (utxoAmt - sendAmt); + if (change > 0) + trx.addoutput(floID, change); + } + for (floID in receivers) + trx.addoutput(floID, receivers[floID]); + trx.addflodata(floData.replace(/\n/g, ' ')); + for (let i = 0; i < wifSeq.length; i++) + trx.signinput(i, wifSeq[i], 1); + var signedTxHash = trx.serialize(); + this.broadcastTx(signedTxHash) + .then(txid => resolve(txid)) + .catch(error => reject(error)) + }).catch(error => reject(error)) + }).catch(error => reject(error)) + }) + }, + + //Broadcast signed Tx in blockchain using API + broadcastTx: function(signedTxHash) { + return new Promise((resolve, reject) => { + if (signedTxHash.length < 1) + return reject("Empty Signature"); + var url = this.util.serverList[this.util.curPos] + 'api/tx/send'; + fetch(url, { + method: "POST", + headers: { + 'Content-Type': 'application/json' + }, + body: `{"rawtx":"${signedTxHash}"}` + }).then(response => { + if (response.ok) + response.json().then(data => resolve(data.txid.result)); + else + response.text().then(data => resolve(data)); + }).catch(error => reject(error)); + }) + }, + + getTx: function(txid) { + return new Promise((resolve, reject) => { + this.promisedAPI(`api/tx/${txid}`) + .then(response => resolve(response)) + .catch(error => reject(error)) + }) + }, + + //Read Txs of Address between from and to + readTxs: function(addr, from, to) { + return new Promise((resolve, reject) => { + this.promisedAPI(`api/addrs/${addr}/txs?from=${from}&to=${to}`) + .then(response => resolve(response)) + .catch(error => reject(error)) + }); + }, + + //Read All Txs of Address (newest first) + readAllTxs: function(addr) { + return new Promise((resolve, reject) => { + this.promisedAPI(`api/addrs/${addr}/txs?from=0&to=1`).then(response => { + this.promisedAPI(`api/addrs/${addr}/txs?from=0&to=${response.totalItems}0`) + .then(response => resolve(response.items)) + .catch(error => reject(error)); + }).catch(error => reject(error)) + }); + }, + + /*Read flo Data from txs of given Address + options can be used to filter data + limit : maximum number of filtered data (default = 1000, negative = no limit) + ignoreOld : ignore old txs (default = 0) + sentOnly : filters only sent data + receivedOnly: filters only received data + pattern : filters data that with JSON pattern + filter : custom filter funtion for floData (eg . filter: d => {return d[0] == '$'}) + tx : (boolean) resolve tx data or not (resolves an Array of Object with tx details) + sender : flo-id(s) of sender + receiver : flo-id(s) of receiver + */ + readData: function(addr, options = {}) { + options.limit = options.limit || 0; + options.ignoreOld = options.ignoreOld || 0; + if (typeof options.sender === "string") options.sender = [options.sender]; + if (typeof options.receiver === "string") options.receiver = [options.receiver]; + return new Promise((resolve, reject) => { + this.promisedAPI(`api/addrs/${addr}/txs?from=0&to=1`).then(response => { + var newItems = response.totalItems - options.ignoreOld; + this.promisedAPI(`api/addrs/${addr}/txs?from=0&to=${newItems*2}`).then(response => { + if (options.limit <= 0) + options.limit = response.items.length; + var filteredData = []; + let numToRead = response.totalItems - options.ignoreOld, + unconfirmedCount = 0; + for (let i = 0; i < numToRead && filteredData.length < options.limit; i++) { + if (!response.items[i].confirmations) { //unconfirmed transactions + unconfirmedCount++; + if (numToRead < response.items[i].length) + numToRead++; + continue; + } + if (options.pattern) { + try { + let jsonContent = JSON.parse(response.items[i].floData); + if (!Object.keys(jsonContent).includes(options.pattern)) + continue; + } catch (error) { + continue; + } + } + if (options.sentOnly) { + let flag = false; + for (let vin of response.items[i].vin) + if (vin.addr === addr) { + flag = true; + break; + } + if (!flag) continue; + } + if (Array.isArray(options.sender)) { + let flag = false; + for (let vin of response.items[i].vin) + if (options.sender.includes(vin.addr)) { + flag = true; + break; + } + if (!flag) continue; + } + if (options.receivedOnly) { + let flag = false; + for (let vout of response.items[i].vout) + if (vout.scriptPubKey.addresses[0] === addr) { + flag = true; + break; + } + if (!flag) continue; + } + if (Array.isArray(options.receiver)) { + let flag = false; + for (let vout of response.items[i].vout) + if (options.receiver.includes(vout.scriptPubKey.addresses[0])) { + flag = true; + break; + } + if (!flag) continue; + } + if (options.filter && !options.filter(response.items[i].floData)) + continue; + + if (options.tx) { + let d = {} + d.txid = response.items[i].txid; + d.time = response.items[i].time; + d.blockheight = response.items[i].blockheight; + d.data = response.items[i].floData; + filteredData.push(d); + } else + filteredData.push(response.items[i].floData); + } + resolve({ + totalTxs: response.totalItems - unconfirmedCount, + data: filteredData + }); + }).catch(error => { + reject(error); + }); + }).catch(error => { + reject(error); + }); + }); + } + } +})(typeof global !== "undefined" ? global : window); + + +/* Token Operator to send/receive tokens from blockchain using API calls*/ +(function(GLOBAL) { + const tokenAPI = GLOBAL.tokenAPI = { + util: { + parseTxData: tx => { + let result = {}; + for (let p in tx.parsedFloData) + result[p] = tx.parsedFloData[p]; + result.sender = tx.transactionDetails.vin[0].addr; + for (let vout of tx.transactionDetails.vout) + if (vout.scriptPubKey.addresses[0] !== result.sender) + result.receiver = vout.scriptPubKey.addresses[0]; + result.time = tx.transactionDetails.time; + return result; + } + }, + fetch_api: function(apicall) { + return new Promise((resolve, reject) => { + console.log(floGlobals.tokenURL + apicall); + fetch(floGlobals.tokenURL + apicall).then(response => { + if (response.ok) + response.json().then(data => resolve(data)); + else + reject(response) + }).catch(error => reject(error)) + }) + }, + getBalance: function(floID, token = floGlobals.currency) { + return new Promise((resolve, reject) => { + this.fetch_api(`api/v1.0/getFloAddressBalance?token=${token}&floAddress=${floID}`) + .then(result => resolve(result.balance || 0)) + .catch(error => reject(error)) + }) + }, + getTx: function(txID) { + return new Promise((resolve, reject) => { + this.fetch_api(`api/v1.0/getTransactionDetails/${txID}`).then(res => { + if (res.result === "error") + reject(res.description); + else if (!res.parsedFloData) + reject("Data piece (parsedFloData) missing"); + else if (!res.transactionDetails) + reject("Data piece (transactionDetails) missing"); + else + resolve(res); + }).catch(error => reject(error)) + }) + }, + sendToken: function(privKey, amount, receiverID, message = "", token = floGlobals.currency) { + return new Promise((resolve, reject) => { + let senderID = floCrypto.getFloID(privKey); + if (typeof amount !== "number" || amount <= 0) + return reject("Invalid amount"); + this.getBalance(senderID, token).then(bal => { + if (amount > bal) + return reject("Insufficiant token balance"); + floBlockchainAPI.writeData(senderID, `send ${amount} ${token}# ${message}`, privKey, receiverID) + .then(txid => resolve(txid)) + .catch(error => reject(error)) + }).catch(error => reject(error)) + }); + }, + getAllTxs: function(floID, token = floGlobals.currency) { + return new Promise((resolve, reject) => { + this.fetch_api(`api/v1.0/getFloAddressTransactions?token=${token}&floAddress=${floID}`) + .then(result => resolve(result)) + .catch(error => reject(error)) + }) + } + } +})(typeof global !== "undefined" ? global : window); + +/* Compact IndexedDB operations */ + +window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; +window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction; +window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange; + +if (!window.indexedDB) + window.alert("Your browser doesn't support a stable version of IndexedDB.") + +const compactIDB = { + + setDefaultDB: function(dbName) { + this.defaultDB = dbName; + }, + + upgradeDB: function(dbName, createList = null, deleteList = null) { + return new Promise((resolve, reject) => { + this.getDBversion(dbName).then(version => { + var idb = indexedDB.open(dbName, version + 1); + idb.onerror = (event) => reject("Error in opening IndexedDB"); + idb.onupgradeneeded = (event) => { + let db = event.target.result; + if (createList instanceof Object) { + if (Array.isArray(createList)) { + let tmp = {} + createList.forEach(o => tmp[o] = {}) + createList = tmp + } + for (let o in createList) { + let obs = db.createObjectStore(o, createList[o].options || {}); + if (createList[o].indexes instanceof Object) + for (let i in createList[o].indexes) + obs.createIndex(i, i, createList[o].indexes || {}); + } + } + if (Array.isArray(deleteList)) + deleteList.forEach(o => db.deleteObjectStore(o)); + resolve('Database upgraded') + } + idb.onsuccess = (event) => event.target.result.close(); + }).catch(error => reject(error)) + }) + }, + + initDB: function(dbName, objectStores = {}) { + return new Promise((resolve, reject) => { + if (!(objectStores instanceof Object)) + return reject('ObjectStores must be an object or array') + this.defaultDB = this.defaultDB || dbName; + var idb = indexedDB.open(dbName); + idb.onerror = (event) => reject("Error in opening IndexedDB"); + idb.onsuccess = (event) => { + var db = event.target.result; + let cList = Object.values(db.objectStoreNames); + var obs = {}, + a_obs = {}, + d_obs = []; + if (!Array.isArray(objectStores)) + var obs = objectStores + else + objectStores.forEach(o => obs[o] = {}) + let nList = Object.keys(obs) + for (let o of nList) + if (!cList.includes(o)) + a_obs[o] = obs[o] + for (let o of cList) + if (!nList.includes(o)) + d_obs.push(o) + if (!Object.keys(a_obs).length && !d_obs.length) + resolve("Initiated IndexedDB"); + else + this.upgradeDB(dbName, a_obs, d_obs) + .then(result => resolve(result)) + .catch(error => reject(error)) + db.close(); + } + }); + }, + + openDB: function(dbName = this.defaultDB) { + return new Promise((resolve, reject) => { + var idb = indexedDB.open(dbName); + idb.onerror = (event) => reject("Error in opening IndexedDB"); + idb.onupgradeneeded = (event) => { + event.target.result.close(); + this.deleteDB(dbName) + reject("Datebase not found") + } + idb.onsuccess = (event) => resolve(event.target.result); + }); + }, + + deleteDB: function(dbName = this.defaultDB) { + return new Promise((resolve, reject) => { + var deleteReq = indexedDB.deleteDatabase(dbName);; + deleteReq.onerror = (event) => reject("Error deleting database!"); + deleteReq.onsuccess = (event) => resolve("Database deleted successfully"); + }); + }, + + getDBversion: function(dbName = this.defaultDB) { + return new Promise((resolve, reject) => { + this.openDB(dbName).then(db => { + resolve(db.version) + db.close() + }).catch(error => reject(error)) + }) + }, + + writeData: function(obsName, data, key = false, dbName = this.defaultDB) { + return new Promise((resolve, reject) => { + this.openDB(dbName).then(db => { + var obs = db.transaction(obsName, "readwrite").objectStore(obsName); + let writeReq = (key ? obs.put(data, key) : obs.put(data)); + writeReq.onsuccess = (evt) => resolve(`Write data Successful`); + writeReq.onerror = (evt) => reject( + `Write data unsuccessful [${evt.target.error.name}] ${evt.target.error.message}` + ); + db.close(); + }).catch(error => reject(error)); + }); + }, + + addData: function(obsName, data, key = false, dbName = this.defaultDB) { + return new Promise((resolve, reject) => { + this.openDB(dbName).then(db => { + var obs = db.transaction(obsName, "readwrite").objectStore(obsName); + let addReq = (key ? obs.add(data, key) : obs.add(data)); + addReq.onsuccess = (evt) => resolve(`Add data successful`); + addReq.onerror = (evt) => reject( + `Add data unsuccessful [${evt.target.error.name}] ${evt.target.error.message}` + ); + db.close(); + }).catch(error => reject(error)); + }); + }, + + removeData: function(obsName, key, dbName = this.defaultDB) { + return new Promise((resolve, reject) => { + this.openDB(dbName).then(db => { + var obs = db.transaction(obsName, "readwrite").objectStore(obsName); + let delReq = obs.delete(key); + delReq.onsuccess = (evt) => resolve(`Removed Data ${key}`); + delReq.onerror = (evt) => reject( + `Remove data unsuccessful [${evt.target.error.name}] ${evt.target.error.message}` + ); + db.close(); + }).catch(error => reject(error)); + }); + }, + + clearData: function(obsName, dbName = this.defaultDB) { + return new Promise((resolve, reject) => { + this.openDB(dbName).then(db => { + var obs = db.transaction(obsName, "readwrite").objectStore(obsName); + let clearReq = obs.clear(); + clearReq.onsuccess = (evt) => resolve(`Clear data Successful`); + clearReq.onerror = (evt) => reject(`Clear data Unsuccessful`); + db.close(); + }).catch(error => reject(error)); + }); + }, + + readData: function(obsName, key, dbName = this.defaultDB) { + return new Promise((resolve, reject) => { + this.openDB(dbName).then(db => { + var obs = db.transaction(obsName, "readonly").objectStore(obsName); + let getReq = obs.get(key); + getReq.onsuccess = (evt) => resolve(evt.target.result); + getReq.onerror = (evt) => reject( + `Read data unsuccessful [${evt.target.error.name}] ${evt.target.error.message}` + ); + db.close(); + }).catch(error => reject(error)); + }); + }, + + readAllData: function(obsName, dbName = this.defaultDB) { + return new Promise((resolve, reject) => { + this.openDB(dbName).then(db => { + var obs = db.transaction(obsName, "readonly").objectStore(obsName); + var tmpResult = {} + let curReq = obs.openCursor(); + curReq.onsuccess = (evt) => { + var cursor = evt.target.result; + if (cursor) { + tmpResult[cursor.primaryKey] = cursor.value; + cursor.continue(); + } else + resolve(tmpResult); + } + curReq.onerror = (evt) => reject( + `Read-All data unsuccessful [${evt.target.error.name}] ${evt.target.error.message}` + ); + db.close(); + }).catch(error => reject(error)); + }); + }, + + /*searchData: function (obsName, options = {}, dbName = this.defaultDB) { + + return new Promise((resolve, reject) => { + this.openDB(dbName).then(db => { + var obs = db.transaction(obsName, "readonly").objectStore(obsName); + var filteredResult = {} + let keyRange; + if(options.lowerKey!==null && options.upperKey!==null) + keyRange = IDBKeyRange.bound(options.lowerKey, options.upperKey); + else if(options.lowerKey!==null) + keyRange = IDBKeyRange.lowerBound(options.lowerKey); + else if (options.upperKey!==null) + keyRange = IDBKeyRange.upperBound(options.upperBound); + else if (options.atKey) + let curReq = obs.openCursor(keyRange, ) + }).catch(error => reject(error)) + }) + },*/ + + searchData: function(obsName, options = {}, dbName = this.defaultDB) { + options.lowerKey = options.atKey || options.lowerKey || 0 + options.upperKey = options.atKey || options.upperKey || false + options.patternEval = options.patternEval || ((k, v) => { + return true + }) + options.limit = options.limit || false; + options.lastOnly = options.lastOnly || false + return new Promise((resolve, reject) => { + this.openDB(dbName).then(db => { + var obs = db.transaction(obsName, "readonly").objectStore(obsName); + var filteredResult = {} + let curReq = obs.openCursor( + options.upperKey ? IDBKeyRange.bound(options.lowerKey, options.upperKey) : IDBKeyRange.lowerBound(options.lowerKey), + options.lastOnly ? "prev" : "next"); + curReq.onsuccess = (evt) => { + var cursor = evt.target.result; + if (cursor) { + if (options.patternEval(cursor.primaryKey, cursor.value)) { + filteredResult[cursor.primaryKey] = cursor.value; + options.lastOnly ? resolve(filteredResult) : cursor.continue(); + } else + cursor.continue(); + } else + resolve(filteredResult); + } + curReq.onerror = (evt) => reject(`Search unsuccessful [${evt.target.error.name}] ${evt.target.error.message}`); + db.close(); + }).catch(error => reject(error)); + }); + } +} + +/* FLO Cloud operations to send/request application data*/ +//floCloudAPI v2.1.3 +const floCloudAPI = { + + util: { + + kBucket: { + SNKB: null, + SNCO: null, + + util: { + decodeID(floID) { + let k = bitjs.Base58.decode(floID) + k.shift() + k.splice(-4, 4) + const decodedId = Crypto.util.bytesToHex(k); + const nodeIdBigInt = new BigInteger(decodedId, 16); + const nodeIdBytes = nodeIdBigInt.toByteArrayUnsigned(); + const nodeIdNewInt8Array = new Uint8Array(nodeIdBytes); + return nodeIdNewInt8Array; + }, + + addNode: function(floID, KB) { + let decodedId = this.decodeID(floID); + const contact = { + id: decodedId, + floID: floID + }; + KB.add(contact) + }, + + removeNode: function(floID, KB) { + let decodedId = this.decodeID(floID); + KB.remove(decodedId) + }, + + isPresent: function(floID, KB) { + let kArray = KB.toArray().map(k => k.floID); + return kArray.includes(floID) + }, + + distanceOf: function(floID, KB) { + let decodedId = this.decodeID(floID); + return KB.distance(KB.localNodeId, decodedId); + }, + + closestOf: function(floID, n, KB) { + let decodedId = this.decodeID(floID); + return KB.closest(decodedId, n) + }, + + constructKB: function(list, refID) { + const KBoptions = { + localNodeId: this.decodeID(refID) + }; + let KB = new BuildKBucket(KBoptions); + for (let id of list) + this.addNode(id, KB) + return KB; + } + }, + + launch: function() { + return new Promise((resolve, reject) => { + try { + let superNodeList = Object.keys(floGlobals.supernodes); + let masterID = floGlobals.SNStorageID; + this.SNKB = this.util.constructKB(superNodeList, masterID); + this.SNCO = superNodeList.map(sn => [this.util.distanceOf(sn, this.SNKB), + sn + ]) + .sort((a, b) => a[0] - b[0]) + .map(a => a[1]) + resolve('Supernode KBucket formed'); + } catch (error) { + reject(error); + } + }); + }, + + innerNodes: function(id1, id2) { + if (!this.SNCO.includes(id1) || !this.SNCO.includes(id2)) + throw Error('Given nodes are not supernode'); + let iNodes = [] + for (let i = this.SNCO.indexOf(id1) + 1; this.SNCO[i] != id2; i++) { + if (i < this.SNCO.length) + iNodes.push(this.SNCO[i]) + else i = -1 + } + return iNodes + }, + + outterNodes: function(id1, id2) { + if (!this.SNCO.includes(id1) || !this.SNCO.includes(id2)) + throw Error('Given nodes are not supernode'); + let oNodes = [] + for (let i = this.SNCO.indexOf(id2) + 1; this.SNCO[i] != id1; i++) { + if (i < this.SNCO.length) + oNodes.push(this.SNCO[i]) + else i = -1 + } + return oNodes + }, + + prevNode: function(id, N = 1) { + let n = N || this.SNCO.length; + if (!this.SNCO.includes(id)) + throw Error('Given node is not supernode'); + let pNodes = [] + for (let i = 0, j = this.SNCO.indexOf(id) - 1; i < n; j--) { + if (j == this.SNCO.indexOf(id)) + break; + else if (j > -1) + pNodes[i++] = this.SNCO[j] + else j = this.SNCO.length + } + return (N == 1 ? pNodes[0] : pNodes) + }, + + nextNode: function(id, N = 1) { + let n = N || this.SNCO.length; + if (!this.SNCO.includes(id)) + throw Error('Given node is not supernode'); + if (!n) n = this.SNCO.length; + let nNodes = [] + for (let i = 0, j = this.SNCO.indexOf(id) + 1; i < n; j++) { + if (j == this.SNCO.indexOf(id)) + break; + else if (j < this.SNCO.length) + nNodes[i++] = this.SNCO[j] + else j = -1 + } + return (N == 1 ? nNodes[0] : nNodes) + }, + + closestNode: function(id, N = 1) { + let decodedId = this.util.decodeID(id); + let n = N || this.SNCO.length; + let cNodes = this.SNKB.closest(decodedId, n) + .map(k => k.floID) + return (N == 1 ? cNodes[0] : cNodes) + } + }, + + inactive: new Set(), + + ws_connect(snID) { + return new Promise((resolve, reject) => { + if (!(snID in floGlobals.supernodes)) + return reject(`${snID} is not a supernode`) + let inactive = this.inactive + if (inactive.has(snID)) + return reject(`${snID} is not active`) + var wsConn = new WebSocket("wss://" + floGlobals.supernodes[snID].uri + "/"); + wsConn.onopen = evt => resolve(wsConn); + wsConn.onerror = evt => { + inactive.add(snID) + reject(`${snID} is unavailable`) + } + }) + }, + + ws_activeConnect(snID, reverse = false) { + return new Promise((resolve, reject) => { + if (this.inactive.size === this.kBucket.SNCO.length) + return reject('Cloud offline'); + if (!(snID in floGlobals.supernodes)) + snID = this.kBucket.closestNode(snID); + this.ws_connect(snID) + .then(node => resolve(node)) + .catch(error => { + if (reverse) + var nxtNode = this.kBucket.prevNode(snID); + else + var nxtNode = this.kBucket.nextNode(snID); + this.ws_activeConnect(nxtNode, reverse) + .then(node => resolve(node)) + .catch(error => reject(error)) + }) + }) + }, + + fetch_API: function(snID, data) { + return new Promise((resolve, reject) => { + if (this.inactive.has(snID)) + return reject(`${snID} is not active`); + let fetcher, sn_url = "https://" + floGlobals.supernodes[snID].uri; + if (typeof data === "string") + fetcher = fetch(sn_url + "?" + data); + else if (typeof data === "object" && data.method === "POST") + fetcher = fetch(sn_url, data); + fetcher.then(response => { + if (response.ok || response.status === 400 || response.status === 500) + resolve(response); + else + reject(response); + }).catch(error => reject(error)) + }) + }, + + fetch_ActiveAPI: function(snID, data, reverse = false) { + return new Promise((resolve, reject) => { + if (this.inactive.size === this.kBucket.SNCO.length) + return reject('Cloud offline'); + if (!(snID in floGlobals.supernodes)) + snID = this.kBucket.closestNode(snID); + this.fetch_API(snID, data) + .then(result => resolve(result)) + .catch(error => { + this.inactive.add(snID) + if (reverse) + var nxtNode = this.kBucket.prevNode(snID); + else + var nxtNode = this.kBucket.nextNode(snID); + this.fetch_ActiveAPI(nxtNode, data, reverse) + .then(result => resolve(result)) + .catch(error => reject(error)); + }) + }) + }, + + singleRequest: function(floID, data_obj, method = "POST") { + return new Promise((resolve, reject) => { + let data; + if (method === "POST") + data = { + method: "POST", + body: JSON.stringify(data_obj) + }; + else + data = new URLSearchParams(JSON.parse(JSON.stringify(data_obj))).toString(); + this.fetch_ActiveAPI(floID, data).then(response => { + if (response.ok) + response.json() + .then(result => resolve(result)) + .catch(error => reject(error)) + else response.text() + .then(result => reject(response.status + ": " + result)) //Error Message from Node + .catch(error => reject(error)) + }).catch(error => reject(error)) + }) + }, + + liveRequest: function(floID, request, callback) { + let self = this; + const filterData = typeof request.status !== 'undefined' ? + data => { + if (request.status) + return data; + else { + let filtered = {}; + for (let i in data) + if (request.trackList.includes(i)) + filtered[i] = data[i]; + return filtered; + } + } : + data => { + data = self.objectifier(data); + let filtered = {}, + r = request; + for (let v in data) { + let d = data[v]; + if ((!r.atVectorClock || r.atVectorClock == v) && + (r.atVectorClock || !r.lowerVectorClock || r.lowerVectorClock <= v) && + (r.atVectorClock || !r.upperVectorClock || r.upperVectorClock >= v) && + (!r.afterTime || r.afterTime < d.log_time) && + r.application == d.application && + r.receiverID == d.receiverID && + (!r.comment || r.comment == d.comment) && + (!r.type || r.type == d.type) && + (!r.senderID || r.senderID.includes(d.senderID))) + filtered[v] = data[v]; + } + return filtered; + }; + + return new Promise((resolve, reject) => { + self.ws_activeConnect(floID).then(node => { + let randID = floCrypto.randString(5); + node.send(JSON.stringify(request)); + node.onmessage = (evt) => { + let d = e = null; + try { + d = filterData(JSON.parse(evt.data)); + } catch (error) { + e = evt.data + } finally { + callback(d, e) + } + } + self.liveRequest[randID] = node; + self.liveRequest[randID].request = request; + resolve(randID); + }).catch(error => reject(error)); + }); + }, + + encodeMessage: function(message) { + return btoa(unescape(encodeURIComponent(JSON.stringify(message)))) + }, + + decodeMessage: function(message) { + return JSON.parse(decodeURIComponent(escape(atob(message)))) + }, + + filterKey: function(type, options) { + return type + (options.comment ? ':' + options.comment : '') + + '|' + (options.group || options.receiverID || floGlobals.adminID) + + '|' + (options.application || floGlobals.application); + }, + + lastCommit: function(method, objName) { + switch (method) { + case "GET": + return JSON.parse(this.lastCommit[objName]); + case "SET": + this.lastCommit[objName] = JSON.stringify(floGlobals.appObjects[objName]); + } + }, + + updateObject: function(objectName, dataSet) { + try { + console.log(dataSet) + let vcList = Object.keys(dataSet).sort(); + for (let vc of vcList) { + if (vc < floGlobals.lastVC[objectName] || dataSet[vc].type !== objectName) + continue; + switch (dataSet[vc].comment) { + case "RESET": + if (dataSet[vc].message.reset) + floGlobals.appObjects[objectName] = dataSet[vc].message.reset; + break; + case "UPDATE": + if (dataSet[vc].message.diff) + floGlobals.appObjects[objectName] = mergeDiff(floGlobals.appObjects[objectName], dataSet[vc].message.diff); + } + floGlobals.lastVC[objectName] = vc; + } + compactIDB.writeData("appObjects", floGlobals.appObjects[objectName], objectName); + compactIDB.writeData("lastVC", floGlobals.lastVC[objectName], objectName); + } catch (error) { + console.error(error) + } + }, + + storeGeneral: function(fk, dataSet) { + try { + console.log(dataSet) + if (typeof floGlobals.generalData[fk] !== "object") + floGlobals.generalData[fk] = {} + for (let vc in dataSet) { + floGlobals.generalData[fk][vc] = dataSet[vc]; + if (dataSet[vc].log_time > floGlobals.lastVC[fk]) + floGlobals.lastVC[fk] = dataSet[vc].log_time; + } + compactIDB.writeData("lastVC", floGlobals.lastVC[fk], fk) + compactIDB.writeData("generalData", floGlobals.generalData[fk], fk) + } catch (error) { + console.error(error) + } + }, + + objectifier: function(data) { + if (!Array.isArray(data)) + data = [data]; + return Object.fromEntries(data.map(d => { + d.message = this.decodeMessage(d.message); + return [d.vectorClock, d]; + })); + } + }, + + //set status as online for myFloID + setStatus: function(options = {}) { + return new Promise((resolve, reject) => { + let callback = options.callback instanceof Function ? options.callback : (d, e) => console.debug(d, e); + var request = { + floID: myFloID, + application: options.application || floGlobals.application, + time: Date.now(), + status: true, + pubKey: myPubKey + } + let hashcontent = ["time", "application", "floID"].map(d => request[d]).join("|"); + request.sign = floCrypto.signData(hashcontent, myPrivKey); + this.util.liveRequest(options.refID || floGlobals.adminID, request, callback) + .then(result => resolve(result)) + .catch(error => reject(error)) + }) + }, + + //request status of floID(s) in trackList + requestStatus: function(trackList, options = {}) { + return new Promise((resolve, reject) => { + if (!Array.isArray(trackList)) + trackList = [trackList]; + let callback = options.callback instanceof Function ? options.callback : (d, e) => console.debug(d, e); + let request = { + status: false, + application: options.application || floGlobals.application, + trackList: trackList + } + this.util.liveRequest(options.refID || floGlobals.adminID, request, callback) + .then(result => resolve(result)) + .catch(error => reject(error)) + }) + }, + + //send any message to supernode cloud storage + sendApplicationData: function(message, type, options = {}) { + return new Promise((resolve, reject) => { + var data = { + senderID: myFloID, + receiverID: options.receiverID || floGlobals.adminID, + pubKey: myPubKey, + message: this.util.encodeMessage(message), + time: Date.now(), + application: options.application || floGlobals.application, + type: type, + comment: options.comment || "" + } + let hashcontent = ["receiverID", "time", "application", "type", "message", "comment"] + .map(d => data[d]).join("|") + data.sign = floCrypto.signData(hashcontent, myPrivKey); + this.util.singleRequest(data.receiverID, data) + .then(result => resolve(result)) + .catch(error => reject(error)) + }) + }, + + //request any data from supernode cloud + requestApplicationData: function(type, options = {}) { + return new Promise((resolve, reject) => { + var request = { + receiverID: options.receiverID || floGlobals.adminID, + senderID: options.senderID || undefined, + application: options.application || floGlobals.application, + type: type, + comment: options.comment || undefined, + lowerVectorClock: options.lowerVectorClock || undefined, + upperVectorClock: options.upperVectorClock || undefined, + atVectorClock: options.atVectorClock || undefined, + afterTime: options.afterTime || undefined, + mostRecent: options.mostRecent || undefined, + } + + if (options.callback instanceof Function) { + this.util.liveRequest(request.receiverID, request, options.callback) + .then(result => resolve(result)) + .catch(error => reject(error)) + } else { + if (options.method === "POST") + request = { + time: Date.now(), + request + }; + this.util.singleRequest(request.receiverID, request, options.method || "GET") + .then(data => resolve(data)).catch(error => reject(error)) + } + }) + }, + + //(NEEDS UPDATE) delete data from supernode cloud (received only) + deleteApplicationData: function(vectorClocks, options = {}) { + return new Promise((resolve, reject) => { + var delreq = { + requestorID: myFloID, + pubKey: myPubKey, + time: Date.now(), + delete: (Array.isArray(vectorClocks) ? vectorClocks : [vectorClocks]), + application: options.application || floGlobals.application + } + let hashcontent = ["time", "application", "delete"] + .map(d => delreq[d]).join("|") + delreq.sign = floCrypto.signData(hashcontent, myPrivKey) + this.util.singleRequest(delreq.requestorID, delreq).then(result => { + let success = [], + failed = []; + result.forEach(r => r.status === 'fulfilled' ? + success.push(r.value) : failed.push(r.reason)); + resolve({ + success, + failed + }) + }).catch(error => reject(error)) + }) + }, + + //(NEEDS UPDATE) edit comment of data in supernode cloud (mutable comments only) + editApplicationData: function(vectorClock, newComment, oldData, options = {}) { + return new Promise((resolve, reject) => { + let p0 + if (!oldData) { + options.atVectorClock = vectorClock; + options.callback = false; + p0 = this.requestApplicationData(false, options) + } else + p0 = Promise.resolve({ + vectorClock: { + ...oldData + } + }) + p0.then(d => { + if (d.senderID != myFloID) + return reject("Invalid requestorID") + else if (!d.comment.startsWith("EDIT:")) + return reject("Data immutable") + let data = { + requestorID: myFloID, + receiverID: d.receiverID, + time: Date.now(), + application: d.application, + edit: { + vectorClock: vectorClock, + comment: newComment + } + } + d.comment = data.edit.comment; + let hashcontent = ["receiverID", "time", "application", "type", "message", + "comment" + ] + .map(x => d[x]).join("|") + data.edit.sign = floCrypto.signData(hashcontent, myPrivKey) + this.util.singleRequest(data.receiverID, data) + .then(result => resolve("Data comment updated")) + .catch(error => reject(error)) + }) + }) + }, + + //tag data in supernode cloud (subAdmin access only) + tagApplicationData: function(vectorClock, tag, options = {}) { + return new Promise((resolve, reject) => { + if (!floGlobals.subAdmins.includes(myFloID)) + return reject("Only subAdmins can tag data") + var request = { + receiverID: options.receiverID || floGlobals.adminID, + requestorID: myFloID, + pubKey: myPubKey, + time: Date.now(), + vectorClock: vectorClock, + tag: tag, + } + let hashcontent = ["time", "vectorClock", 'tag'].map(d => request[d]).join("|"); + request.sign = floCrypto.signData(hashcontent, myPrivKey); + this.util.singleRequest(request.receiverID, request) + .then(result => resolve(result)) + .catch(error => reject(error)) + }) + }, + + //note data in supernode cloud (receiver only or subAdmin allowed if receiver is adminID) + noteApplicationData: function(vectorClock, note, options = {}) { + return new Promise((resolve, reject) => { + var request = { + receiverID: options.receiverID || floGlobals.adminID, + requestorID: myFloID, + pubKey: myPubKey, + time: Date.now(), + vectorClock: vectorClock, + note: note, + } + let hashcontent = ["time", "vectorClock", 'note'].map(d => request[d]).join("|"); + request.sign = floCrypto.signData(hashcontent, myPrivKey); + this.util.singleRequest(request.receiverID, request) + .then(result => resolve(result)) + .catch(error => reject(error)) + }) + }, + + //send general data + sendGeneralData: function(message, type, options = {}) { + return new Promise((resolve, reject) => { + if (options.encrypt) { + let encryptionKey = options.encrypt === true ? + floGlobals.settings.encryptionKey : options.encrypt + message = floCrypto.encryptData(JSON.stringify(message), encryptionKey) + } + this.sendApplicationData(message, type, options).then(result => { + //options.comment = null; + //var fk = this.util.filterKey(type, options) + //this.util.storeGeneral(fk, result) + resolve(result) + }).catch(error => reject(error)) + }) + }, + + //request general data + requestGeneralData: function(type, options = {}) { + return new Promise((resolve, reject) => { + var fk = this.util.filterKey(type, options) + floGlobals.lastVC[fk] = parseInt(floGlobals.lastVC[fk]) || 0; + options.afterTime = options.afterTime || floGlobals.lastVC[fk]; + if (options.callback instanceof Function) { + let new_options = Object.create(options) + new_options.callback = (d, e) => { + this.util.storeGeneral(fk, d); + options.callback(d, e) + } + this.requestApplicationData(type, new_options) + .then(result => resolve(result)) + .catch(error => reject(error)) + } else { + this.requestApplicationData(type, options).then(dataSet => { + this.util.storeGeneral(fk, this.util.objectifier(dataSet)) + resolve(dataSet) + }).catch(error => reject(error)) + } + }) + }, + + //request an object data from supernode cloud + requestObjectData: function(objectName, options = {}) { + return new Promise((resolve, reject) => { + options.lowerVectorClock = options.lowerVectorClock || floGlobals.lastVC[objectName] + 1; + options.senderID = [false, null].includes(options.senderID) ? null : + options.senderID || floGlobals.subAdmins; + options.mostRecent = true; + options.comment = 'RESET'; + let callback = null; + if (options.callback instanceof Function) { + callback = (d, e) => { + this.util.updateObject(objectName, d); + options.callback(d, e); + } + delete options.callback; + } + this.requestApplicationData(objectName, options).then(dataSet => { + this.util.updateObject(objectName, this.util.objectifier(dataSet)); + delete options.comment; + options.lowerVectorClock = floGlobals.lastVC[objectName] + 1; + delete options.mostRecent; + if (callback) { + let new_options = Object.create(options); + new_options.callback = callback; + this.requestApplicationData(objectName, new_options) + .then(result => resolve(result)) + .catch(error => reject(error)) + } else { + this.requestApplicationData(objectName, options).then(dataSet => { + this.util.updateObject(objectName, this.util.objectifier(dataSet)) + this.util.lastCommit("SET", objectName) + resolve(floGlobals.appObjects[objectName]) + }).catch(error => reject(error)) + } + }).catch(error => reject(error)) + }) + }, + + closeRequest: function(requestID) { + return new Promise((resolve, reject) => { + let conn = this.util.liveRequest[requestID] + if (!conn) + return reject('Request not found') + conn.onclose = evt => { + delete this.util.liveRequest[requestID]; + resolve('Request connection closed') + } + conn.close() + }) + }, + + //reset or initialize an object and send it to cloud + resetObjectData: function(objectName, options = {}) { + return new Promise((resolve, reject) => { + let message = { + reset: floGlobals.appObjects[objectName] + } + options.comment = 'RESET'; + this.sendApplicationData(message, objectName, options).then(result => { + this.util.lastCommit("SET", objectName) + resolve(result) + }).catch(error => reject(error)) + }) + }, + + //update the diff and send it to cloud + updateObjectData: function(objectName, options = {}) { + return new Promise((resolve, reject) => { + let message = { + diff: findDiff(this.util.lastCommit("GET", objectName), floGlobals.appObjects[ + objectName]) + } + options.comment = 'UPDATE'; + this.sendApplicationData(message, objectName, options).then(result => { + this.util.lastCommit("SET", objectName) + resolve(result) + }).catch(error => reject(error)) + }) + } +} + +/*Kademlia DHT K-bucket implementation as a binary tree.*/ +function BuildKBucket(options = {}) { + this.localNodeId = options.localNodeId || window.crypto.getRandomValues(new Uint8Array(20)) + this.numberOfNodesPerKBucket = options.numberOfNodesPerKBucket || 20 + this.numberOfNodesToPing = options.numberOfNodesToPing || 3 + this.distance = options.distance || this.distance + this.arbiter = options.arbiter || this.arbiter + this.metadata = Object.assign({}, options.metadata) + + this.createNode = function() { + return { + contacts: [], + dontSplit: false, + left: null, + right: null + } + } + + this.ensureInt8 = function(name, val) { + if (!(val instanceof Uint8Array)) + throw new TypeError(name + ' is not a Uint8Array') + } + + this.arrayEquals = function(array1, array2) { + if (array1 === array2) + return true + if (array1.length !== array2.length) + return false + for (let i = 0, length = array1.length; i < length; ++i) + if (array1[i] !== array2[i]) + return false + return true + } + + this.ensureInt8('option.localNodeId as parameter 1', this.localNodeId) + this.root = this.createNode() + + this.arbiter = function(incumbent, candidate) { + return incumbent.vectorClock > candidate.vectorClock ? incumbent : candidate + } + + this.distance = function(firstId, secondId) { + let distance = 0 + let i = 0 + const min = Math.min(firstId.length, secondId.length) + const max = Math.max(firstId.length, secondId.length) + for (; i < min; ++i) + distance = distance * 256 + (firstId[i] ^ secondId[i]) + for (; i < max; ++i) distance = distance * 256 + 255 + return distance + } + + this.add = function(contact) { + this.ensureInt8('contact.id', (contact || {}).id) + let bitIndex = 0 + let node = this.root + while (node.contacts === null) + node = this._determineNode(node, contact.id, bitIndex++) + const index = this._indexOf(node, contact.id) + if (index >= 0) { + this._update(node, index, contact) + return this + } + if (node.contacts.length < this.numberOfNodesPerKBucket) { + node.contacts.push(contact) + return this + } + if (node.dontSplit) + return this + this._split(node, bitIndex) + return this.add(contact) + } + + this.closest = function(id, n = Infinity) { + this.ensureInt8('id', id) + if ((!Number.isInteger(n) && n !== Infinity) || n <= 0) + throw new TypeError('n is not positive number') + let contacts = [] + for (let nodes = [this.root], bitIndex = 0; nodes.length > 0 && contacts.length < n;) { + const node = nodes.pop() + if (node.contacts === null) { + const detNode = this._determineNode(node, id, bitIndex++) + nodes.push(node.left === detNode ? node.right : node.left) + nodes.push(detNode) + } else + contacts = contacts.concat(node.contacts) + } + return contacts + .map(a => [this.distance(a.id, id), a]) + .sort((a, b) => a[0] - b[0]) + .slice(0, n) + .map(a => a[1]) + } + + this.count = function() { + let count = 0 + for (const nodes = [this.root]; nodes.length > 0;) { + const node = nodes.pop() + if (node.contacts === null) + nodes.push(node.right, node.left) + else + count += node.contacts.length + } + return count + } + + this._determineNode = function(node, id, bitIndex) { + const bytesDescribedByBitIndex = bitIndex >> 3 + const bitIndexWithinByte = bitIndex % 8 + if ((id.length <= bytesDescribedByBitIndex) && (bitIndexWithinByte !== 0)) + return node.left + const byteUnderConsideration = id[bytesDescribedByBitIndex] + if (byteUnderConsideration & (1 << (7 - bitIndexWithinByte))) + return node.right + return node.left + } + + this.get = function(id) { + this.ensureInt8('id', id) + let bitIndex = 0 + let node = this.root + while (node.contacts === null) + node = this._determineNode(node, id, bitIndex++) + const index = this._indexOf(node, id) + return index >= 0 ? node.contacts[index] : null + } + + this._indexOf = function(node, id) { + for (let i = 0; i < node.contacts.length; ++i) + if (this.arrayEquals(node.contacts[i].id, id)) + return i + return -1 + } + + this.remove = function(id) { + this.ensureInt8('the id as parameter 1', id) + let bitIndex = 0 + let node = this.root + while (node.contacts === null) + node = this._determineNode(node, id, bitIndex++) + const index = this._indexOf(node, id) + if (index >= 0) + node.contacts.splice(index, 1)[0] + return this + } + + this._split = function(node, bitIndex) { + node.left = this.createNode() + node.right = this.createNode() + for (const contact of node.contacts) + this._determineNode(node, contact.id, bitIndex).contacts.push(contact) + node.contacts = null + const detNode = this._determineNode(node, this.localNodeId, bitIndex) + const otherNode = node.left === detNode ? node.right : node.left + otherNode.dontSplit = true + } + + this.toArray = function() { + let result = [] + for (const nodes = [this.root]; nodes.length > 0;) { + const node = nodes.pop() + if (node.contacts === null) + nodes.push(node.right, node.left) + else + result = result.concat(node.contacts) + } + return result + } + + this._update = function(node, index, contact) { + if (!this.arrayEquals(node.contacts[index].id, contact.id)) + throw new Error('wrong index for _update') + const incumbent = node.contacts[index] + const selection = this.arbiter(incumbent, contact) + if (selection === incumbent && incumbent !== contact) return + node.contacts.splice(index, 1) + node.contacts.push(selection) + } +} + +/* +Functions: +findDiff(original, updatedObj) returns an object with the added, deleted and updated differences +mergeDiff(original, allDiff) returns a new object from original object merged with all differences (allDiff is returned object of findDiff) +*/ +(function() { + const isDate = d => d instanceof Date; + const isEmpty = o => Object.keys(o).length === 0; + const isObject = o => o != null && typeof o === 'object'; + const properObject = o => isObject(o) && !o.hasOwnProperty ? { + ...o + } : o; + const getLargerArray = (l, r) => l.length > r.length ? l : r; + + const preserve = (diff, left, right) => { + if (!isObject(diff)) return diff; + return Object.keys(diff).reduce((acc, key) => { + const leftArray = left[key]; + const rightArray = right[key]; + if (Array.isArray(leftArray) && Array.isArray(rightArray)) { + const array = [...getLargerArray(leftArray, rightArray)]; + return { + ...acc, + [key]: array.reduce((acc2, item, index) => { + if (diff[key].hasOwnProperty(index)) { + acc2[index] = preserve(diff[key][index], leftArray[index], rightArray[index]); // diff recurse and check for nested arrays + return acc2; + } + delete acc2[index]; // no diff aka empty + return acc2; + }, array) + }; + } + return { + ...acc, + [key]: diff[key] + }; + }, {}); + }; + + const updatedDiff = (lhs, rhs) => { + if (lhs === rhs) return {}; + if (!isObject(lhs) || !isObject(rhs)) return rhs; + const l = properObject(lhs); + const r = properObject(rhs); + if (isDate(l) || isDate(r)) { + if (l.valueOf() == r.valueOf()) return {}; + return r; + } + return Object.keys(r).reduce((acc, key) => { + if (l.hasOwnProperty(key)) { + const difference = updatedDiff(l[key], r[key]); + if (isObject(difference) && isEmpty(difference) && !isDate(difference)) return acc; + return { + ...acc, + [key]: difference + }; + } + return acc; + }, {}); + }; + + + const diff = (lhs, rhs) => { + if (lhs === rhs) return {}; // equal return no diff + if (!isObject(lhs) || !isObject(rhs)) return rhs; // return updated rhs + const l = properObject(lhs); + const r = properObject(rhs); + const deletedValues = Object.keys(l).reduce((acc, key) => { + return r.hasOwnProperty(key) ? acc : { + ...acc, + [key]: null + }; + }, {}); + if (isDate(l) || isDate(r)) { + if (l.valueOf() == r.valueOf()) return {}; + return r; + } + return Object.keys(r).reduce((acc, key) => { + if (!l.hasOwnProperty(key)) return { + ...acc, + [key]: r[key] + }; // return added r key + const difference = diff(l[key], r[key]); + if (isObject(difference) && isEmpty(difference) && !isDate(difference)) return acc; // return no diff + return { + ...acc, + [key]: difference + }; // return updated key + }, deletedValues); + }; + + const addedDiff = (lhs, rhs) => { + if (lhs === rhs || !isObject(lhs) || !isObject(rhs)) return {}; + const l = properObject(lhs); + const r = properObject(rhs); + return Object.keys(r).reduce((acc, key) => { + if (l.hasOwnProperty(key)) { + const difference = addedDiff(l[key], r[key]); + if (isObject(difference) && isEmpty(difference)) return acc; + return { + ...acc, + [key]: difference + }; + } + return { + ...acc, + [key]: r[key] + }; + }, {}); + }; + + const arrayDiff = (lhs, rhs) => { + if (lhs === rhs) return {}; // equal return no diff + if (!isObject(lhs) || !isObject(rhs)) return rhs; // return updated rhs + const l = properObject(lhs); + const r = properObject(rhs); + const deletedValues = Object.keys(l).reduce((acc, key) => { + return r.hasOwnProperty(key) ? acc : { + ...acc, + [key]: null + }; + }, {}); + if (isDate(l) || isDate(r)) { + if (l.valueOf() == r.valueOf()) return {}; + return r; + } + if (Array.isArray(r) && Array.isArray(l)) { + const deletedValues = l.reduce((acc, item, index) => { + return r.hasOwnProperty(index) ? acc.concat(item) : acc.concat(null); + }, []); + return r.reduce((acc, rightItem, index) => { + if (!deletedValues.hasOwnProperty(index)) { + return acc.concat(rightItem); + } + const leftItem = l[index]; + const difference = diff(rightItem, leftItem); + if (isObject(difference) && isEmpty(difference) && !isDate(difference)) { + delete acc[index]; + return acc; // return no diff + } + return acc.slice(0, index).concat(rightItem).concat(acc.slice(index + 1)); // return updated key + }, deletedValues); + } + + return Object.keys(r).reduce((acc, key) => { + if (!l.hasOwnProperty(key)) return { + ...acc, + [key]: r[key] + }; // return added r key + const difference = diff(l[key], r[key]); + if (isObject(difference) && isEmpty(difference) && !isDate(difference)) return acc; // return no diff + return { + ...acc, + [key]: difference + }; // return updated key + }, deletedValues); + }; + + const deletedDiff = (lhs, rhs) => { + if (lhs === rhs || !isObject(lhs) || !isObject(rhs)) return {}; + const l = properObject(lhs); + const r = properObject(rhs); + return Object.keys(l).reduce((acc, key) => { + if (r.hasOwnProperty(key)) { + const difference = deletedDiff(l[key], r[key]); + if (isObject(difference) && isEmpty(difference)) return acc; + return { + ...acc, + [key]: difference + }; + } + return { + ...acc, + [key]: null + }; + }, {}); + }; + window.findDiff = (lhs, rhs) => ({ + added: addedDiff(lhs, rhs), + deleted: deletedDiff(lhs, rhs), + updated: updatedDiff(lhs, rhs), + }); + + const mergeRecursive = (obj1, obj2) => { + for (var p in obj2) { + try { + if (obj2[p].constructor == Object) + obj1[p] = mergeRecursive(obj1[p], obj2[p]); + // Property in destination object set; update its value. + else if (Ext.isArray(obj2[p])) { + // obj1[p] = []; + if (obj2[p].length < 1) + obj1[p] = obj2[p]; + else + obj1[p] = mergeRecursive(obj1[p], obj2[p]); + } else + obj1[p] = obj2[p]; + } catch (e) { + // Property in destination object not set; create it and set its value. + obj1[p] = obj2[p]; + } + } + return obj1; + } + + const cleanse = (obj) => { + Object.keys(obj).forEach(key => { + var value = obj[key]; + if (typeof value === "object" && value !== null) { + // Recurse... + cleanse(value); + // ...and remove if now "empty" (NOTE: insert your definition of "empty" here) + //if (!Object.keys(value).length) + // delete obj[key]; + } else if (value === null) + delete obj[key]; // null, remove it + }); + if (obj.constructor.toString().indexOf("Array") != -1) { + obj = obj.filter(function(el) { + return el != null; + }); + } + return obj; + } + + /*obj is original object or array, diff is the output of findDiff */ + window.mergeDiff = (obj, diff) => { + if (Object.keys(diff.updated).length !== 0) + obj = mergeRecursive(obj, diff.updated) + if (Object.keys(diff.deleted).length !== 0) { + obj = mergeRecursive(obj, diff.deleted) + obj = cleanse(obj) + } + if (Object.keys(diff.added).length !== 0) + obj = mergeRecursive(obj, diff.added) + return obj + } +})(); + +/* General functions for FLO Dapps*/ +const floDapps = { + + util: { + + initIndexedDB: function() { + return new Promise((resolve, reject) => { + var obs_g = { + //general + lastTx: {}, + //supernode (cloud list) + supernodes: { + indexes: { + uri: null, + pubKey: null + } + } + } + var obs_a = { + //login credentials + credentials: {}, + //for Dapps + subAdmins: {}, + settings: {}, + appObjects: {}, + generalData: {}, + lastVC: {} + } + //add other given objectStores + this.initIndexedDB.appObs = this.initIndexedDB.appObs || {} + for (o in this.initIndexedDB.appObs) + if (!(o in obs_a)) + obs_a[o] = this.initIndexedDB.appObs[o] + Promise.all([ + compactIDB.initDB(floGlobals.application, obs_a), + compactIDB.initDB("floDapps", obs_g) + ]).then(result => { + compactIDB.setDefaultDB(floGlobals.application) + resolve("IndexedDB App Storage Initated Successfully") + }).catch(error => reject(error)); + }) + }, + + initUserDB: function(floID) { + return new Promise((resolve, reject) => { + var obs = { + contacts: {}, + pubKeys: {}, + messages: {} + } + compactIDB.initDB(`floDapps#${floID}`, obs).then(result => { + resolve("UserDB Initated Successfully") + }).catch(error => reject('Init userDB failed')); + }) + }, + + loadUserDB: function(floID) { + return new Promise((resolve, reject) => { + var loadData = ["contacts", "pubKeys", "messages"] + var promises = [] + for (var i = 0; i < loadData.length; i++) + promises[i] = compactIDB.readAllData(loadData[i], `floDapps#${floID}`) + Promise.all(promises).then(results => { + for (var i = 0; i < loadData.length; i++) + floGlobals[loadData[i]] = results[i] + resolve("Loaded Data from userDB") + }).catch(error => reject('Load userDB failed')) + }) + }, + + startUpFunctions: { + + readSupernodeListFromAPI: function() { + return new Promise((resolve, reject) => { + compactIDB.readData("lastTx", floGlobals.SNStorageID, "floDapps").then(lastTx => { + floBlockchainAPI.readData(floGlobals.SNStorageID, { + ignoreOld: lastTx, + sentOnly: true, + pattern: "SuperNodeStorage" + }).then(result => { + for (var i = result.data.length - 1; i >= 0; i--) { + var content = JSON.parse(result.data[i]).SuperNodeStorage; + for (sn in content.removeNodes) + compactIDB.removeData("supernodes", sn, "floDapps"); + for (sn in content.newNodes) + compactIDB.writeData("supernodes", content.newNodes[sn], sn, "floDapps"); + } + compactIDB.writeData("lastTx", result.totalTxs, floGlobals.SNStorageID, "floDapps"); + compactIDB.readAllData("supernodes", "floDapps").then(result => { + floGlobals.supernodes = result; + floCloudAPI.util.kBucket.launch() + .then(result => resolve("Loaded Supernode list\n" + result)) + .catch(error => reject(error)) + }) + }) + }).catch(error => reject(error)) + }) + }, + + readAppConfigFromAPI: function() { + return new Promise((resolve, reject) => { + compactIDB.readData("lastTx", `${floGlobals.application}|${floGlobals.adminID}`, "floDapps").then(lastTx => { + floBlockchainAPI.readData(floGlobals.adminID, { + ignoreOld: lastTx, + sentOnly: true, + pattern: floGlobals.application + }).then(result => { + for (var i = result.data.length - 1; i >= 0; i--) { + var content = JSON.parse(result.data[i])[floGlobals.application]; + if (!content || typeof content !== "object") + continue; + if (Array.isArray(content.removeSubAdmin)) + for (var j = 0; j < content.removeSubAdmin.length; j++) + compactIDB.removeData("subAdmins", content.removeSubAdmin[j]); + if (Array.isArray(content.addSubAdmin)) + for (var k = 0; k < content.addSubAdmin.length; k++) + compactIDB.writeData("subAdmins", true, content.addSubAdmin[k]); + if (content.settings) + for (let l in content.settings) + compactIDB.writeData("settings", content.settings[l], l) + } + compactIDB.writeData("lastTx", result.totalTxs, `${floGlobals.application}|${floGlobals.adminID}`, "floDapps"); + compactIDB.readAllData("subAdmins").then(result => { + floGlobals.subAdmins = Object.keys(result); + compactIDB.readAllData("settings").then(result => { + floGlobals.settings = result; + resolve("Read app configuration from blockchain"); + }) + }) + }) + }).catch(error => reject(error)) + }) + }, + + loadDataFromAppIDB: function() { + return new Promise((resolve, reject) => { + var loadData = ["appObjects", "generalData", "lastVC"] + var promises = [] + for (var i = 0; i < loadData.length; i++) + promises[i] = compactIDB.readAllData(loadData[i]) + Promise.all(promises).then(results => { + for (var i = 0; i < loadData.length; i++) + floGlobals[loadData[i]] = results[i] + resolve("Loaded Data from app IDB") + }).catch(error => reject(error)) + }) + } + }, + + getCredentials: function() { + + const defaultInput = function(type) { + return new Promise((resolve, reject) => { + let inputVal = prompt(`Enter ${type}: `) + if (inputVal === null) + reject(null) + else + resolve(inputVal) + }) + } + + const inputFn = this.getCredentials.privKeyInput || defaultInput; + + const readSharesFromIDB = function(indexArr) { + return new Promise((resolve, reject) => { + var promises = [] + for (var i = 0; i < indexArr.length; i++) + promises.push(compactIDB.readData('credentials', indexArr[i])) + Promise.all(promises).then(shares => { + var secret = floCrypto.retrieveShamirSecret(shares) + if (secret) + resolve(secret) + else + reject("Shares are insufficient or incorrect") + }).catch(error => { + floDapps.clearCredentials(); + location.reload(); + }) + }) + } + + const writeSharesToIDB = function(shares, i = 0, resultIndexes = []) { + return new Promise(resolve => { + if (i >= shares.length) + return resolve(resultIndexes) + var n = floCrypto.randInt(0, 100000) + compactIDB.addData("credentials", shares[i], n).then(res => { + resultIndexes.push(n) + writeSharesToIDB(shares, i + 1, resultIndexes) + .then(result => resolve(result)) + }).catch(error => { + writeSharesToIDB(shares, i, resultIndexes) + .then(result => resolve(result)) + }) + }) + } + + const getPrivateKeyCredentials = function() { + return new Promise((resolve, reject) => { + var indexArr = localStorage.getItem(`${floGlobals.application}#privKey`) + if (indexArr) { + readSharesFromIDB(JSON.parse(indexArr)) + .then(result => resolve(result)) + .catch(error => reject(error)) + } else { + var privKey; + inputFn("PRIVATE_KEY").then(result => { + if (!result) + return reject("Empty Private Key") + var floID = floCrypto.getFloID(result) + if (!floID || !floCrypto.validateAddr(floID)) + return reject("Invalid Private Key") + privKey = result; + }).catch(error => { + console.log(error, "Generating Random Keys") + privKey = floCrypto.generateNewID().privKey + }).finally(_ => { + if (!privKey) + return; + var threshold = floCrypto.randInt(10, 20) + var shares = floCrypto.createShamirsSecretShares(privKey, threshold, threshold) + writeSharesToIDB(shares).then(resultIndexes => { + //store index keys in localStorage + localStorage.setItem(`${floGlobals.application}#privKey`, JSON.stringify(resultIndexes)) + //also add a dummy privatekey to the IDB + var randomPrivKey = floCrypto.generateNewID().privKey + var randomThreshold = floCrypto.randInt(10, 20) + var randomShares = floCrypto.createShamirsSecretShares(randomPrivKey, randomThreshold, randomThreshold) + writeSharesToIDB(randomShares) + //resolve private Key + resolve(privKey) + }) + }) + } + }) + } + + const checkIfPinRequired = function(key) { + return new Promise((resolve, reject) => { + if (key.length == 52) + resolve(key) + else { + inputFn("PIN/Password").then(pwd => { + try { + let privKey = Crypto.AES.decrypt(key, pwd); + resolve(privKey) + } catch (error) { + reject("Access Denied: Incorrect PIN/Password") + } + }).catch(error => reject("Access Denied: PIN/Password required")) + } + }) + } + + return new Promise((resolve, reject) => { + getPrivateKeyCredentials().then(key => { + checkIfPinRequired(key).then(privKey => { + try { + myPrivKey = privKey + myPubKey = floCrypto.getPubKeyHex(myPrivKey) + myFloID = floCrypto.getFloID(myPubKey) + resolve('Login Credentials loaded successful') + } catch (error) { + console.log(error) + reject("Corrupted Private Key") + } + }).catch(error => reject(error)) + }).catch(error => reject(error)) + }) + }, + + startUpLog: function(status, log) { + if (status) + console.log(log) + else + console.error(log) + }, + + callStartUpFunction: function(fname) { + return new Promise((resolve, reject) => { + this.startUpFunctions[fname]().then(result => { + this.callStartUpFunction.completed += 1 + this.startUpLog(true, `${result}\nCompleted ${this.callStartUpFunction.completed}/${this.callStartUpFunction.total} Startup functions`) + resolve(true) + }).catch(error => { + this.callStartUpFunction.failed += 1 + this.startUpLog(false, `${error}\nFailed ${this.callStartUpFunction.failed}/${this.callStartUpFunction.total} Startup functions`) + reject(false) + }) + }) + } + }, + + launchStartUp: function() { + return new Promise((resolve, reject) => { + this.util.initIndexedDB().then(log => { + console.log(log) + this.util.callStartUpFunction.total = Object.keys(this.util.startUpFunctions).length + this.util.callStartUpFunction.completed = 0 + this.util.callStartUpFunction.failed = 0 + var p0 = [] + for (fn in this.util.startUpFunctions) + p0.push(this.util.callStartUpFunction(fn)) + const CnL = p => new Promise((res, rej) => { + p.then(r => { + this.util.startUpLog(true, r) + res(r) + }).catch(e => { + this.util.startUpLog(false, e) + rej(e) + }) + }) + const callMidStartup = () => new Promise((res, rej) => { + if (this.launchStartUp.midFunction instanceof Function) { + this.launchStartUp.midFunction() + .then(r => res("Mid startup function completed")) + .catch(e => rej("Mid startup function failed")) + } else + res("No mid startup function") + }) + let p1 = new Promise((res, rej) => { + Promise.all(p0).then(r => { + CnL(callMidStartup()) + .then(r => res(true)) + .catch(e => rej(false)) + }) + }); + let p2 = new Promise((res, rej) => { + CnL(this.util.getCredentials()).then(r => { + CnL(this.util.initUserDB(myFloID)).then(r => { + CnL(this.util.loadUserDB(myFloID)) + .then(r => res(true)) + .catch(e => rej(false)) + }).catch(e => rej(false)) + }).catch(e => rej(false)) + }) + Promise.all([p1, p2]) + .then(r => resolve('App Startup finished successful')) + .catch(e => reject('App Startup failed')) + }).catch(error => reject("App database initiation failed")) + }) + }, + + addStartUpFunction: function(fname, fn) { + if (fname in this.util.startUpFunctions) + throw (`Function ${fname} already defined`) + this.util.startUpFunctions[fname] = fn; + }, + + setMidStartup: function(fn) { + if (fn instanceof Function) + this.launchStartUp.midFunction = fn; + }, + + setCustomStartupLogger: function(logger) { + this.util.startUpLog = logger; + }, + + setCustomPrivKeyInput: function(customFn) { + this.util.getCredentials.privKeyInput = customFn + }, + + setAppObjectStores: function(appObs) { + this.util.initIndexedDB.appObs = appObs + }, + + storeContact(floID, name) { + return new Promise((resolve, reject) => { + if (!floCrypto.validateAddr(floID)) + return reject("Invalid floID!") + compactIDB.writeData("contacts", name, floID, `floDapps#${myFloID}`).then(result => { + floGlobals.contacts[floID] = name; + resolve("Contact stored") + }).catch(error => reject(error)) + }); + }, + + storePubKey(floID, pubKey) { + return new Promise((resolve, reject) => { + if (floID in floGlobals.pubKeys) + return resolve("pubKey already stored") + if (!floCrypto.validateAddr(floID)) + return reject("Invalid floID!") + if (floCrypto.getFloID(pubKey) != floID) + return reject("Incorrect pubKey") + compactIDB.writeData("pubKeys", pubKey, floID, `floDapps#${myFloID}`).then(result => { + floGlobals.pubKeys[floID] = pubKey; + resolve("pubKey stored") + }).catch(error => reject(error)) + }); + }, + + sendMessage(floID, message) { + return new Promise((resolve, reject) => { + let options = { + receiverID: floID, + application: "floDapps", + comment: floGlobals.application + } + if (floID in floGlobals.pubKeys) + message = floCrypto.encryptData(JSON.stringify(message), floGlobals.pubKeys[floID]) + floCloudAPI.sendApplicationData(message, "Message", options) + .then(result => resolve(result)) + .catch(error => reject(error)) + }) + }, + + requestInbox(callback) { + return new Promise((resolve, reject) => { + let lastVC = Object.keys(floGlobals.messages).sort().pop() + let options = { + receiverID: myFloID, + application: "floDapps", + lowerVectorClock: lastVC + 1 + } + options.callback = (d, e) => { + for (let v in d) { + try { + if (d[v].message instanceof Object && "secret" in d[v].message) + d[v].message = floCrypto.decryptData(d[v].message, myPrivKey) + } catch (error) {} + compactIDB.writeData("messages", d[v], v, `floDapps#${myFloID}`) + floGlobals.messages[v] = d[v] + } + if (callback instanceof Function) + callback(d, e) + } + floCloudAPI.requestApplicationData("Message", options) + .then(result => resolve(result)) + .catch(error => reject(error)) + }) + }, + + manageAppConfig(adminPrivKey, addList, rmList, settings) { + return new Promise((resolve, reject) => { + if (!Array.isArray(addList) || !addList.length) addList = undefined; + if (!Array.isArray(rmList) || !rmList.length) rmList = undefined; + if (!settings || typeof settings !== "object" || !Object.keys(settings).length) settings = undefined; + if (!addList && !rmList && !settings) + return reject("No configuration change") + var floData = { + [floGlobals.application]: { + addSubAdmin: addList, + removeSubAdmin: rmList, + settings: settings + } + } + var floID = floCrypto.getFloID(adminPrivKey) + if (floID != floGlobals.adminID) + reject('Access Denied for Admin privilege') + else + floBlockchainAPI.writeData(floID, JSON.stringify(floData), adminPrivKey) + .then(result => resolve(['Updated App Configuration', result])) + .catch(error => reject(error)) + }) + }, + + clearCredentials: function() { + return new Promise((resolve, reject) => { + compactIDB.clearData('credentials', floGlobals.application).then(result => { + localStorage.removeItem(`${floGlobals.application}#privKey`) + myPrivKey = myPubKey = myFloID = undefined; + resolve("privKey credentials deleted!") + }).catch(error => reject(error)) + }) + }, + + deleteUserData: function(credentials = false) { + return new Promise((resolve, reject) => { + let p = [] + p.push(compactIDB.deleteDB(`floDapps#${myFloID}`)) + if (credentials) + p.push(this.clearCredentials()) + Promise.all(p) + .then(result => resolve('User database(local) deleted')) + .catch(error => reject(error)) + }) + }, + + deleteAppData: function() { + return new Promise((resolve, reject) => { + compactIDB.deleteDB(floGlobals.application).then(result => { + localStorage.removeItem(`${floGlobals.application}#privKey`) + myPrivKey = myPubKey = myFloID = undefined; + compactIDB.removeData('lastTx', `${floGlobals.application}|${floGlobals.adminID}`, 'floDapps') + .then(result => resolve("App database(local) deleted")) + .catch(error => reject(error)) + }).catch(error => reject(error)) + }) + }, + + securePrivKey: function(pwd) { + return new Promise((resolve, reject) => { + let indexArr = localStorage.getItem(`${floGlobals.application}#privKey`) + if (!indexArr) + return reject("PrivKey not found"); + indexArr = JSON.parse(indexArr) + let encryptedKey = Crypto.AES.encrypt(myPrivKey, pwd); + let threshold = indexArr.length; + let shares = floCrypto.createShamirsSecretShares(encryptedKey, threshold, threshold) + let promises = []; + let overwriteFn = (share, index) => + compactIDB.writeData("credentials", share, index, floGlobals.application); + for (var i = 0; i < threshold; i++) + promises.push(overwriteFn(shares[i], indexArr[i])); + Promise.all(promises) + .then(results => resolve("Private Key Secured")) + .catch(error => reject(error)) + }) + }, + + verifyPin: function(pin = null) { + const readSharesFromIDB = function(indexArr) { + return new Promise((resolve, reject) => { + var promises = [] + for (var i = 0; i < indexArr.length; i++) + promises.push(compactIDB.readData('credentials', indexArr[i])) + Promise.all(promises).then(shares => { + var secret = floCrypto.retrieveShamirSecret(shares) + console.info(shares, secret) + if (secret) + resolve(secret) + else + reject("Shares are insufficient or incorrect") + }).catch(error => { + floDapps.clearCredentials(); + location.reload(); + }) + }) + } + return new Promise((resolve, reject) => { + var indexArr = localStorage.getItem(`${floGlobals.application}#privKey`) + console.info(indexArr) + if (!indexArr) + reject('No login credentials found') + readSharesFromIDB(JSON.parse(indexArr)).then(key => { + if (key.length == 52) { + if (pin === null) + resolve("Private key not secured") + else + reject("Private key not secured") + } else { + if (pin === null) + return reject("PIN/Password required") + try { + let privKey = Crypto.AES.decrypt(key, pin); + resolve("PIN/Password verified") + } catch (error) { + reject("Incorrect PIN/Password") + } + } + }).catch(error => reject(error)) + }) + + + }, + + getNextGeneralData: function(type, vectorClock = null, options = {}) { + var fk = floCloudAPI.util.filterKey(type, options) + vectorClock = vectorClock || this.getNextGeneralData[fk] || '0'; + var filteredResult = {} + if (floGlobals.generalData[fk]) { + for (let d in floGlobals.generalData[fk]) + if (d > vectorClock) + filteredResult[d] = JSON.parse(JSON.stringify(floGlobals.generalData[fk][d])) + } else if (options.comment) { + let comment = options.comment; + delete options.comment; + let fk = floCloudAPI.util.filterKey(type, options); + for (let d in floGlobals.generalData[fk]) + if (d > vectorClock && floGlobals.generalData[fk][d].comment == comment) + filteredResult[d] = JSON.parse(JSON.stringify(floGlobals.generalData[fk][d])) + } + if (options.decrypt) { + let decryptionKey = (options.decrypt === true) ? myPrivKey : options.decrypt; + if (!Array.isArray(decryptionKey)) + decryptionKey = [decryptionKey]; + for (let f in filteredResult) { + let data = filteredResult[f] + try { + if (data.message instanceof Object && "secret" in data.message) { + for (let key of decryptionKey) { + try { + let tmp = floCrypto.decryptData(data.message, key) + data.message = JSON.parse(tmp) + break; + } catch (error) {} + } + } + } catch (error) {} + } + } + this.getNextGeneralData[fk] = Object.keys(filteredResult).sort().pop(); + return filteredResult; + }, + + syncData: { + oldDevice: function() { + return new Promise((resolve, reject) => { + let sync = { + contacts: floGlobals.contacts, + pubKeys: floGlobals.pubKeys, + messages: floGlobals.messages + } + let message = Crypto.AES.encrypt(JSON.stringify(sync), myPrivKey) + let options = { + receiverID: myFloID, + application: "floDapps" + } + floCloudAPI.sendApplicationData(message, "syncData", options) + .then(result => resolve(result)) + .catch(error => reject(error)) + }) + }, + + newDevice() { + return new Promise((resolve, reject) => { + var options = { + receiverID: myFloID, + senderIDs: myFloID, + application: "floDapps", + mostRecent: true, + } + floCloudAPI.requestApplicationData("syncData", options).then(response => { + let vc = Object.keys(response).sort().pop() + let sync = JSON.parse(Crypto.AES.decrypt(response[vc].message, myPrivKey)) + let promises = [] + let store = (key, val, obs) => promises.push(compactIDB.writeData(obs, val, key, `floDapps#${floID}`)); + ["contacts", "pubKeys", "messages"].forEach(c => { + for (let i in sync[c]) { + store(i, sync[c][i], c) + floGlobals[c][i] = sync[c][i] + } + }) + Promise.all(promises) + .then(results => resolve("Sync data successful")) + .catch(error => reject(error)) + }).catch(error => reject(error)) + }) + } + } +} \ No newline at end of file diff --git a/scripts/std_ui.js b/scripts/std_ui.js new file mode 100644 index 0000000..1985074 --- /dev/null +++ b/scripts/std_ui.js @@ -0,0 +1,507 @@ +/*jshint esversion: 6 */ +// Global variables +const domRefs = {}; +const currentYear = new Date().getFullYear(); + +//Checks for internet connection status +if (!navigator.onLine) + notify( + "There seems to be a problem connecting to the internet, Please check you internet connection.", + "error" + ); +window.addEventListener("offline", () => { + notify( + "There seems to be a problem connecting to the internet, Please check you internet connection.", + "error", + { pinned: true } + ); +}); +window.addEventListener("online", () => { + getRef("notification_drawer").clearAll(); + notify("We are back online.", "success"); +}); + +// Use instead of document.getElementById +function getRef(elementId) { + if (!domRefs.hasOwnProperty(elementId)) { + domRefs[elementId] = { + count: 1, + ref: null, + }; + return document.getElementById(elementId); + } else { + if (domRefs[elementId].count < 3) { + domRefs[elementId].count = domRefs[elementId].count + 1; + return document.getElementById(elementId); + } else { + if (!domRefs[elementId].ref) + domRefs[elementId].ref = document.getElementById(elementId); + return domRefs[elementId].ref; + } + } +} + +// returns dom with specified element +function createElement(tagName, options = {}) { + const { className, textContent, innerHTML, attributes = {} } = options + const elem = document.createElement(tagName) + for (let attribute in attributes) { + elem.setAttribute(attribute, attributes[attribute]) + } + if (className) + elem.className = className + if (textContent) + elem.textContent = textContent + if (innerHTML) + elem.innerHTML = innerHTML + return elem +} + +// Use when a function needs to be executed after user finishes changes +const debounce = (callback, wait) => { + let timeoutId = null; + return (...args) => { + window.clearTimeout(timeoutId); + timeoutId = window.setTimeout(() => { + callback.apply(null, args); + }, wait); + }; +} + +let zIndex = 10 +// function required for popups or modals to appear +function showPopup(popupId, pinned) { + zIndex++ + getRef(popupId).setAttribute('style', `z-index: ${zIndex}`) + getRef(popupId).show({ pinned }) + return getRef(popupId); +} + +// hides the popup or modal +function hidePopup() { + if (popupStack.peek() === undefined) + return; + popupStack.peek().popup.hide() +} + +document.addEventListener('popupopened', async e => { + switch (e.target.id) { + case 'saved_ids_popup': + const frag = document.createDocumentFragment() + const allSavedIds = await getArrayOfSavedIds() + allSavedIds.forEach(({ floID, name }) => { + frag.append(render.savedIdPickerCard(floID, name)) + }) + getRef('saved_ids_picker_list').innerHTML = '' + getRef('saved_ids_picker_list').append(frag) + getRef('search_saved_ids_picker').focusIn() + break; + case 'get_private_key_popup': + break; + } +}) +document.addEventListener('popupclosed', e => { + zIndex-- + switch (e.target.id) { + case 'saved_ids_popup': + getRef('saved_ids_picker_list').innerHTML = '' + getRef('search_saved_ids_picker').value = '' + break; + case 'get_private_key_popup': + getRef('get_private_key').classList.remove('hide') + getRef('transaction_result').classList.add('hide') + getRef('confirm_transaction_button').classList.remove('hide') + getRef('confirm_transaction_button').nextElementSibling.classList.add('hide') + break; + case 'retrieve_flo_id_popup': + getRef('recovered_flo_id_wrapper').classList.add('hide') + break; + } +}) + +// displays a popup for asking permission. Use this instead of JS confirm +const getConfirmation = (title, options = {}) => { + return new Promise(resolve => { + const { message, cancelText = 'Cancel', confirmText = 'OK' } = options + showPopup('confirmation_popup', true) + getRef('confirm_title').textContent = title; + getRef('confirm_message').textContent = message; + let cancelButton = getRef('confirmation_popup').children[2].children[0], + submitButton = getRef('confirmation_popup').children[2].children[1] + submitButton.textContent = confirmText + cancelButton.textContent = cancelText + submitButton.onclick = () => { + hidePopup() + resolve(true); + } + cancelButton.onclick = () => { + hidePopup() + resolve(false); + } + }) +} + +//Function for displaying toast notifications. pass in error for mode param if you want to show an error. +function notify(message, mode, options = {}) { + const { pinned = false, sound = false } = options + let icon + switch (mode) { + case 'success': + icon = `` + break; + case 'error': + icon = `` + break; + } + getRef("notification_drawer").push(message, { pinned, icon }); + if (mode === 'error') { + console.error(message) + } +} + +function getFormattedTime(time, format) { + try { + if (String(time).indexOf('_')) + time = String(time).split('_')[0] + const intTime = parseInt(time) + if (String(intTime).length < 13) + time *= 1000 + let [day, month, date, year] = new Date(intTime).toString().split(' '), + minutes = new Date(intTime).getMinutes(), + hours = new Date(intTime).getHours(), + currentTime = new Date().toString().split(' ') + + minutes = minutes < 10 ? `0${minutes}` : minutes + let finalHours = ``; + if (hours > 12) + finalHours = `${hours - 12}:${minutes}` + else if (hours === 0) + finalHours = `12:${minutes}` + else + finalHours = `${hours}:${minutes}` + + finalHours = hours >= 12 ? `${finalHours} PM` : `${finalHours} AM` + switch (format) { + case 'date-only': + return `${month} ${date}, ${year}`; + break; + default: + return `${month} ${date} ${year}, ${finalHours}`; + } + } catch (e) { + console.error(e); + return time; + } +} +// implement event delegation +function delegate(el, event, selector, fn) { + el.addEventListener(event, function (e) { + const potentialTarget = e.target.closest(selector) + if (potentialTarget) { + e.delegateTarget = potentialTarget + fn.call(this, e) + } + }) +} + +window.addEventListener('hashchange', e => showPage(window.location.hash)) +window.addEventListener("load", () => { + document.body.classList.remove('hide') + document.querySelectorAll('sm-input[data-flo-id]').forEach(input => input.customValidation = floCrypto.validateAddr) + document.querySelectorAll('sm-input[data-private-key]').forEach(input => input.customValidation = floCrypto.getPubKeyHex) + document.addEventListener('keyup', (e) => { + if (e.key === 'Escape') { + hidePopup() + } + }) + document.addEventListener('copy', () => { + notify('copied', 'success') + }) + document.addEventListener("pointerdown", (e) => { + if (e.target.closest("button:not([disabled]), sm-button:not([disabled]), .interact")) { + createRipple(e, e.target.closest("button, sm-button, .interact")); + } + }); + +}); +function createRipple(event, target) { + const circle = document.createElement("span"); + const diameter = Math.max(target.clientWidth, target.clientHeight); + const radius = diameter / 2; + const targetDimensions = target.getBoundingClientRect(); + circle.style.width = circle.style.height = `${diameter}px`; + circle.style.left = `${event.clientX - (targetDimensions.left + radius)}px`; + circle.style.top = `${event.clientY - (targetDimensions.top + radius)}px`; + circle.classList.add("ripple"); + const rippleAnimation = circle.animate( + [ + { + transform: "scale(4)", + opacity: 0, + }, + ], + { + duration: 600, + fill: "forwards", + easing: "ease-out", + } + ); + target.append(circle); + rippleAnimation.onfinish = () => { + circle.remove(); + }; +} + +const pagesData = { + params: {} +} + +let tempData +async function showPage(targetPage, options = {}) { + const { firstLoad, hashChange, isPreview } = options + let pageId + let params = {} + let searchParams + if (targetPage === '') { + pageId = 'home' + } else { + if (targetPage.includes('/')) { + if (targetPage.includes('?')) { + const splitAddress = targetPage.split('?') + searchParams = splitAddress.pop() + const pages = splitAddress.pop().split('/') + pageId = pages[1] + subPageId = pages[2] + } else { + const pages = targetPage.split('/') + pageId = pages[1] + subPageId = pages[2] + } + } else { + pageId = targetPage + } + } + if (searchParams) { + const urlSearchParams = new URLSearchParams('?' + searchParams); + params = Object.fromEntries(urlSearchParams.entries()); + } + if (pagesData.lastPage !== pageId) { + pagesData.lastPage = pageId + } + if (params) + pagesData.params = params + switch (pageId) { + case 'transactions': + break; + default: + + } + const animOptions = { + duration: 100, + fill: 'forwards', + } + let previousActiveElement = getRef('main_navbar').querySelector('.nav-item--active') + const currentActiveElement = document.querySelector(`.nav-item[href="#/${pageId}"]`) + if (currentActiveElement) { + if (getRef('main_navbar').classList.contains('hide')) { + getRef('main_navbar').classList.remove('hide-away') + getRef('main_navbar').classList.remove('hide') + getRef('main_navbar').animate([ + { + transform: isMobileView ? `translateY(100%)` : `translateX(-100%)`, + opacity: 0, + }, + { + transform: `none`, + opacity: 1, + }, + ], { + duration: 100, + fill: 'forwards', + easing: 'ease' + }) + } + getRef('main_header').classList.remove('hide') + const previousActiveElementIndex = [...getRef('main_navbar').querySelectorAll('.nav-item')].indexOf(previousActiveElement) + const currentActiveElementIndex = [...getRef('main_navbar').querySelectorAll('.nav-item')].indexOf(currentActiveElement) + const isOnTop = previousActiveElementIndex < currentActiveElementIndex + const currentIndicator = createElement('div', { className: 'nav-item__indicator' }); + let previousIndicator = getRef('main_navbar').querySelector('.nav-item__indicator') + if (!previousIndicator) { + previousIndicator = currentIndicator.cloneNode(true) + previousActiveElement = currentActiveElement + previousActiveElement.append(previousIndicator) + } else if (currentActiveElementIndex !== previousActiveElementIndex) { + const indicatorDimensions = previousIndicator.getBoundingClientRect() + const currentActiveElementDimensions = currentActiveElement.getBoundingClientRect() + let moveBy + if (isMobileView) { + moveBy = ((currentActiveElementDimensions.width - indicatorDimensions.width) / 2) + indicatorDimensions.width + } else { + moveBy = ((currentActiveElementDimensions.height - indicatorDimensions.height) / 2) + indicatorDimensions.height + } + indicatorObserver.observe(previousIndicator) + previousIndicator.animate([ + { + transform: 'none', + opacity: 1, + }, + { + transform: `translate${isMobileView ? 'X' : 'Y'}(${isOnTop ? `${moveBy}px` : `-${moveBy}px`})`, + opacity: 0, + }, + ], { ...animOptions, easing: 'ease-in' }).onfinish = () => { + previousIndicator.remove() + } + tempData = { + currentActiveElement, + currentIndicator, + isOnTop, + animOptions, + moveBy + } + } + previousActiveElement.classList.remove('nav-item--active'); + currentActiveElement.classList.add('nav-item--active') + } else { + if (!getRef('main_navbar').classList.contains('hide')) { + getRef('main_navbar').classList.add('hide-away') + getRef('main_navbar').animate([ + { + transform: `none`, + opacity: 1, + }, + { + transform: isMobileView ? `translateY(100%)` : `translateX(-100%)`, + opacity: 0, + }, + ], { + duration: 200, + fill: 'forwards', + easing: 'ease' + }).onfinish = () => { + getRef('main_navbar').classList.add('hide') + } + getRef('main_header').classList.add('hide') + } + } + document.querySelectorAll('.page').forEach(page => page.classList.add('hide')) + getRef(pageId).classList.remove('hide') + getRef(pageId).animate([{ opacity: 0 }, { opacity: 1 }], { duration: 300, fill: 'forwards', easing: 'ease' }) +} + +const indicatorObserver = new IntersectionObserver(entries => { + entries.forEach(entry => { + if (!entry.isIntersecting) { + const { currentActiveElement, currentIndicator, isOnTop, animOptions, moveBy } = tempData + currentActiveElement.append(currentIndicator) + currentIndicator.animate([ + { + transform: `translate${isMobileView ? 'X' : 'Y'}(${isOnTop ? `-${moveBy}px` : `${moveBy}px`})`, + opacity: 0, + }, + { + transform: 'none', + opacity: 1 + }, + ], { ...animOptions, easing: 'ease-out' }) + } + }) +}, { + threshold: 1 +}) + +// class based lazy loading +class LazyLoader { + constructor(container, elementsToRender, renderFn, options = {}) { + const { batchSize = 10, freshRender } = options + + this.elementsToRender = elementsToRender + this.arrayOfElements = (typeof elementsToRender === 'function') ? this.elementsToRender() : elementsToRender || [] + this.renderFn = renderFn + this.intersectionObserver + + this.batchSize = batchSize + this.freshRender = freshRender + + this.lazyContainer = document.querySelector(container) + + this.update = this.update.bind(this) + this.render = this.render.bind(this) + this.init = this.init.bind(this) + this.clear = this.clear.bind(this) + } + init() { + this.intersectionObserver = new IntersectionObserver((entries, observer) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + observer.disconnect() + this.render({ lazyLoad: true }) + } + }) + }, { + threshold: 0.3 + }) + this.mutationObserver = new MutationObserver(mutationList => { + mutationList.forEach(mutation => { + if (mutation.type === 'childList') { + if (mutation.addedNodes.length) { + this.intersectionObserver.observe(this.lazyContainer.lastElementChild) + } + } + }) + }) + this.mutationObserver.observe(this.lazyContainer, { + childList: true, + }) + this.render() + } + update(elementsToRender) { + this.arrayOfElements = (typeof elementsToRender === 'function') ? this.elementsToRender() : elementsToRender || [] + this.render() + } + render(options = {}) { + let { lazyLoad = false } = options + const frag = document.createDocumentFragment(); + if (lazyLoad) { + this.updateStartIndex = this.updateEndIndex + this.updateEndIndex = this.arrayOfElements.length > this.updateEndIndex + this.batchSize ? this.updateEndIndex + this.batchSize : this.arrayOfElements.length + } else { + this.intersectionObserver.disconnect() + this.lazyContainer.innerHTML = ``; + this.updateStartIndex = 0 + this.updateEndIndex = this.arrayOfElements.length > this.batchSize ? this.batchSize : this.arrayOfElements.length + } + for (let index = this.updateStartIndex; index < this.updateEndIndex; index++) { + frag.append(this.renderFn(this.arrayOfElements[index])) + } + this.lazyContainer.append(frag) + // Callback to be called if elements are updated or rendered for first time + if (!lazyLoad && this.freshRender) + this.freshRender() + } + clear() { + this.intersectionObserver.disconnect() + this.mutationObserver.disconnect() + this.lazyContainer.innerHTML = ``; + } + reset() { + this.arrayOfElements = (typeof this.elementsToRender === 'function') ? this.elementsToRender() : this.elementsToRender || [] + this.render() + } +} +function animateTo(element, keyframes, options) { + const anime = element.animate(keyframes, { ...options, fill: 'both' }) + anime.finished.then(() => { + anime.commitStyles() + anime.cancel() + }) + return anime +} +let isMobileView = false +const mobileQuery = window.matchMedia('(max-width: 40rem)') +function handleMobileChange(e) { + isMobileView = e.matches +} +mobileQuery.addEventListener('change', handleMobileChange) +handleMobileChange(mobileQuery) \ No newline at end of file