Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
hipchat4 / opt / HipChat4 / qtwebengine_resources_100p.pak
Size: Mime:
0­
/®
3$¯
B°
°±
!˲
bë³
õ´
ù
µ
»¶
™˜·
¸
£¹
ª¥º
l©»
P¬¼
M³½
˹¾
ž½¿
\ÛÀ
ÞâÁ
ÏíÂ
™óÃ
ýÄ
|Å
ªÆ
E
Ç
ÂÈ
&É
U(Ê
},Ë
Þ3Ì
²@Í
_UÎ
fÏ
!Ð
ْÑ
¸•Ò
”˜Ó
øÔ
{¡Õ
¹²Ö
]Æ×
Sר
+ÚÙ
ëÞÚ
èÛ
»ðÜ
kòÝ
!úÞ
M	ß
à
á
Jâ
Š ã
Û'ä
Û/å
7æ
§9ç
ô>è
´KtöWuX|}Y}ëY~AZ‰Z€ßZx[‚\ƒ©\„q]…Ðd†l‡«rˆ:s‰p|Šm~‹¨ŒՆBŽæ!”\—‘Ĝ’¬£“”¥”"ª•®–à±—µ˜ ¸™¼šð¿›<ÊœwΝ—ÑžÕŸŸØ ~Ü¡¹ß¢§á£–ê¤Yó¥>ú¦·ÿ§¼¨¤©ªý«#	¬ˆ	­ø
®h¯J°À±c²á³u´	µ†¶·•¸'¹™º(!»¥"¼7$½´%¾H'¿¸(ÀY)Ák+€-ñ/ÄW1Å3<Æ%?Çô?ÈnEÉîJÊPKËÌKÌLLÍ
MÎïMÏnNÐéNÑNOÒÕOÓ`PÔ6QÕRÖÚR׿SزTÙ™UÚkVÛgXÜ<YÝZÞæZß»[à\áe]âE_ã#aäcå×cæ¬dçeè<—é˜êʘë‘™ì~šíã›îaïԝð*žñ’žò%ŸóN ô+¡õü¡ö­¢÷^£ø¤ù’¤ú¥û¡¥ü¦ý¦¦þ|§ÿR¨ݨ³©‰ª¼«â¬õ®ʰ.²…³	vÄ
±Û Ü“Ü
ÝyÝÓÝ&Þ|ÞÍÞßdß©ßÿßDà‰àÎàáXááâá'âlâ ±â!öâ";ã#€ã$Åã%
ä&Oä'”ä(Ùä)å*cå+¨å,íå-2æ.wæ/¼æ0ç1Fç2‹ç3Ðç4è5Zè6Ÿè7äè8)é9né:³é;ùé<Eê=ê>Ôê?ë@`ëA¦ëBóëC>ìDìEÐìF íGcíH¦íIéíJ9îK‰îLÕîM ïNmïO¶ïPðQKðR–ðSáðT,ñUxñVÃñWòXYòY£òZîò[9ó\„ó]Ïó^ô_fô`³ôaüôbFõc‘õdÜõe'öfrög©÷hŸøi–ùjk
kzlømýå<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no">
<script>
function setMessage(msg) {
  document.getElementById('message').textContent = msg;
}
function notifyDidFinishLoading() {
  if (plugin.didFinishLoading)
    plugin.didFinishLoading();
}
</script>

<style>/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file. */

html, body {
  -webkit-user-select: none;
  font-family: sans-serif;
  height: 100%;
  margin: 0;
  overflow: hidden;
  text-align: center;
  width: 100%;
}

h1 {
  font-size: 10pt;
  font-weight: normal;
  padding: 0pt 10pt;
visibility: hidden;
}

#outer:hover h1, #outer:hover #close {
  visibility: visible;
}

p {
  font-size: 8pt;
  padding: 0pt 14pt;
}

#outer {
  align-items: center;
  border: 1px black solid;
  box-sizing: border-box;
  display: flex;
  height: 100%;
  justify-content: center;
  position: absolute;
  width: 100%;
}

#close {
  background-image: -webkit-image-set(
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAiElEQVR42r2RsQrDMAxEBRdl8SDcX8lQPGg1GBI6lvz/h7QyRRXV0qUULwfvwZ1tenw5PxToRPWMC52eA9+WDnlh3HFQ/xBQl86NFYJqeGflkiogrOvVlIFhqURFVho3x1moGAa3deMs+LS30CAhBN5nNxeT5hbJ1zwmji2k+aF6NENIPf/hs54f0sZFUVAMigAAAABJRU5ErkJggg==) 1x,
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAA9UlEQVR4Xu3UsWrCUByH0fMEouiuhrg4xohToJVGH0CHLBncEwfx/VvIFHLJBWmHDvKbv7PcP9f3L/fXwBsApZSRpUpEgbOnxwiReng6x4AvjdrNXRLkibubWqMcB9Yujk7qjhjmtZOji/U4wELuoBwQXa50kFsQA5jK+kQ/l5kSA4ZEK5Fo+3kcCIlGM8ijQEhUqkEeBUKiUPTyl4C5vZ1cbmdv/iqwclXY6aZwtXoFSLQqhVwmkytUWglxAMG7T0yCu4gD0v7ZBKeVxoEwFxIxYBPmIWEzDnyEeUj4HAfYdvmMcGYdsSUGsOzlIbHEv/uV38APrreiBRBIs3QAAAAASUVORK5CYII=) 2x);
  background-position: right top;
  background-repeat: no-repeat;
  cursor: pointer;
  height: 14px;
  position: absolute;
  right: 3px;
  top: 3px;
visibility: hidden;
  width: 14px;
}

#close[data-plugin-type='document'] {
  display: none;
}

#close:hover {
  background-image: -webkit-image-set(
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAqUlEQVR4XqWRMQqEMBBF/1E8Ra6x6V3FRnS9QbCxtJg6Z7CzE9lTiIXXyUb3C8EULixDIMM8Zt4kcDfxM5A45U+cgeXnC1tREgkzAgob3hiq3CUHvGLG4FTQoSgxQGDrzN8WTLBGnx2IVDksen9GH7Z9hA5E6uxABMJyCHDMCEGHzugLQPPlBCBNGq+5YtpnGw1Bv+te15ypljTpVzdak5Opy+z+qf//zQ+Lg+07ay5KsgAAAABJRU5ErkJggg==) 1x,
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAB4UlEQVR42u2VsWoCQRBAh+MUFP0C1V9QD4NEOxs9xBQHQVCwSJFWVBAtBNXCxk6wTkBJYUTwEwQLC61E8QP0NzZzt5g5726DkC7EYWHZ8T3WndkV2C/jLwn4hwVYBIdLn9vkLp79QcBCTDMiy3w2gQ9XeTYkEHA8vqj2rworXu3HF1YFfSWgp5QFnKVLvYvzDEKEZ5hW70oXOCtcEbQLIkx7+IQtfMBSOjU6XEF4oyOdYInZbXyOuajjDlpNeQgleIUJKUz4BDMledhqOu/AzVSmzZ49CUjCC0yvim98iqtJT2L2jKsqczsdok9XrHNexaww415lnTNwn6CM/KxJIR8bnUZHPhLO6yMoIyk2pNjLewFuE5AiY1KMMQx8Q7hQYFek4AkjxXFe1rsF84I/BTFQMGL+1Lxwl4DwdtM1gjwKohgxyLtG7SYpxALqugOMcfOKN+bFXeBsLB1uulNcRqq7/tt36k41zoL6QlxGjtd6lrahiqCi1iOFYyvXuxY8yzK33VnvUivbLlOlj/jktm0s3YnXrNIXXufHNxuOGasi8S68zkwrlnV8ZcJJsTIUxbLgQcFZWE8N0gau2p40VVcM0gYeFpSRK6445UhBuKiRgiyKw+34rLt59nb1/7+RwReVkaFtqvNBuwAAAABJRU5ErkJggg==) 2x);
}

#close:active {
  background-image: -webkit-image-set(
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAQklEQVR4AWP4TwBSTQGDHcMZIIYAKA9VwRkwtINJgyCaCTAlCBaKAoQ+hFmoCqBKENKkK8C0gpAjCXuTyICiQ2QBAPSwyG3ByZlCAAAAAElFTkSuQmCC) 1x,
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAA/ElEQVR4Xu3UsWrCUBiG4efGlIBoIMFbcnYolYJ3pg4iKGrGYFTRwaUFhYAekiDt0EG++X2W83N8/3J/DbwBMJJSsdQItcDY1VlCOImzq3Ed8OmicHASB3ns5KBw8VUNpDJrW7uAiJ3sbK1l0mqArpmFTUlQ5jYWZrrUAUSmT0SZm4qoA56JvVhs/5g3A7RLolA85A1ASOTye65NMxASK6syfxGITMzvMxG9CvRkliWwlOm9AsSOcitzU1NzK7mjuBkQvHtLK7iLBiB5PhttJSGpB8I8vM6kDuiHeUjoVwMfYR4SRtUAw1veIZzOjRhSBzCoyKFjgH/3K7+BHzg+Cgw0eSW3AAAAAElFTkSuQmCC) 2x);
}
</style>
<style>
body {
  background-color: rgb(187, 187, 187);
}

#plugin_icon {
  opacity: .6;
}
</style>
</head>

<body id="t" onload="notifyDidFinishLoading();">
<div i18n-values="title:name" id="outer">
  <div id="inner">
<div><img id="plugin_icon" src="data:image/png;base64,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"></div>

    <h1 id="message" i18n-content="message"></h1>
  </div>
  <div id="close" i18n-values="title:hide;data-plugin-type:pluginType"
      onclick="plugin.hide();">
  </div>
</div>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no">
<script>
function insertLink() {
  // Replace the chrome://plugins text with a working link (i18n_template
  // doesn't allow raw HTML in template data).
  var link = document.getElementById("enable_link");
  var link_html = link.innerHTML;
  link.parentNode.removeChild(link);
  var message = document.getElementById("message");
  var message_html = message.innerHTML;
  message.innerHTML = message_html.replace('chrome://plugins', link_html);
}
</script>
<style>/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file. */

html, body {
  -webkit-user-select: none;
  font-family: sans-serif;
  height: 100%;
  margin: 0;
  overflow: hidden;
  text-align: center;
  width: 100%;
}

h1 {
  font-size: 10pt;
  font-weight: normal;
  padding: 0pt 10pt;
visibility: hidden;
}

#outer:hover h1, #outer:hover #close {
  visibility: visible;
}

p {
  font-size: 8pt;
  padding: 0pt 14pt;
}

#outer {
  align-items: center;
  border: 1px black solid;
  box-sizing: border-box;
  display: flex;
  height: 100%;
  justify-content: center;
  position: absolute;
  width: 100%;
}

#close {
  background-image: -webkit-image-set(
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAiElEQVR42r2RsQrDMAxEBRdl8SDcX8lQPGg1GBI6lvz/h7QyRRXV0qUULwfvwZ1tenw5PxToRPWMC52eA9+WDnlh3HFQ/xBQl86NFYJqeGflkiogrOvVlIFhqURFVho3x1moGAa3deMs+LS30CAhBN5nNxeT5hbJ1zwmji2k+aF6NENIPf/hs54f0sZFUVAMigAAAABJRU5ErkJggg==) 1x,
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAA9UlEQVR4Xu3UsWrCUByH0fMEouiuhrg4xohToJVGH0CHLBncEwfx/VvIFHLJBWmHDvKbv7PcP9f3L/fXwBsApZSRpUpEgbOnxwiReng6x4AvjdrNXRLkibubWqMcB9Yujk7qjhjmtZOji/U4wELuoBwQXa50kFsQA5jK+kQ/l5kSA4ZEK5Fo+3kcCIlGM8ijQEhUqkEeBUKiUPTyl4C5vZ1cbmdv/iqwclXY6aZwtXoFSLQqhVwmkytUWglxAMG7T0yCu4gD0v7ZBKeVxoEwFxIxYBPmIWEzDnyEeUj4HAfYdvmMcGYdsSUGsOzlIbHEv/uV38APrreiBRBIs3QAAAAASUVORK5CYII=) 2x);
  background-position: right top;
  background-repeat: no-repeat;
  cursor: pointer;
  height: 14px;
  position: absolute;
  right: 3px;
  top: 3px;
visibility: hidden;
  width: 14px;
}

#close[data-plugin-type='document'] {
  display: none;
}

#close:hover {
  background-image: -webkit-image-set(
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAqUlEQVR4XqWRMQqEMBBF/1E8Ra6x6V3FRnS9QbCxtJg6Z7CzE9lTiIXXyUb3C8EULixDIMM8Zt4kcDfxM5A45U+cgeXnC1tREgkzAgob3hiq3CUHvGLG4FTQoSgxQGDrzN8WTLBGnx2IVDksen9GH7Z9hA5E6uxABMJyCHDMCEGHzugLQPPlBCBNGq+5YtpnGw1Bv+te15ypljTpVzdak5Opy+z+qf//zQ+Lg+07ay5KsgAAAABJRU5ErkJggg==) 1x,
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAB4UlEQVR42u2VsWoCQRBAh+MUFP0C1V9QD4NEOxs9xBQHQVCwSJFWVBAtBNXCxk6wTkBJYUTwEwQLC61E8QP0NzZzt5g5726DkC7EYWHZ8T3WndkV2C/jLwn4hwVYBIdLn9vkLp79QcBCTDMiy3w2gQ9XeTYkEHA8vqj2rworXu3HF1YFfSWgp5QFnKVLvYvzDEKEZ5hW70oXOCtcEbQLIkx7+IQtfMBSOjU6XEF4oyOdYInZbXyOuajjDlpNeQgleIUJKUz4BDMledhqOu/AzVSmzZ49CUjCC0yvim98iqtJT2L2jKsqczsdok9XrHNexaww415lnTNwn6CM/KxJIR8bnUZHPhLO6yMoIyk2pNjLewFuE5AiY1KMMQx8Q7hQYFek4AkjxXFe1rsF84I/BTFQMGL+1Lxwl4DwdtM1gjwKohgxyLtG7SYpxALqugOMcfOKN+bFXeBsLB1uulNcRqq7/tt36k41zoL6QlxGjtd6lrahiqCi1iOFYyvXuxY8yzK33VnvUivbLlOlj/jktm0s3YnXrNIXXufHNxuOGasi8S68zkwrlnV8ZcJJsTIUxbLgQcFZWE8N0gau2p40VVcM0gYeFpSRK6445UhBuKiRgiyKw+34rLt59nb1/7+RwReVkaFtqvNBuwAAAABJRU5ErkJggg==) 2x);
}

#close:active {
  background-image: -webkit-image-set(
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAQklEQVR4AWP4TwBSTQGDHcMZIIYAKA9VwRkwtINJgyCaCTAlCBaKAoQ+hFmoCqBKENKkK8C0gpAjCXuTyICiQ2QBAPSwyG3ByZlCAAAAAElFTkSuQmCC) 1x,
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAA/ElEQVR4Xu3UsWrCUBiG4efGlIBoIMFbcnYolYJ3pg4iKGrGYFTRwaUFhYAekiDt0EG++X2W83N8/3J/DbwBMJJSsdQItcDY1VlCOImzq3Ed8OmicHASB3ns5KBw8VUNpDJrW7uAiJ3sbK1l0mqArpmFTUlQ5jYWZrrUAUSmT0SZm4qoA56JvVhs/5g3A7RLolA85A1ASOTye65NMxASK6syfxGITMzvMxG9CvRkliWwlOm9AsSOcitzU1NzK7mjuBkQvHtLK7iLBiB5PhttJSGpB8I8vM6kDuiHeUjoVwMfYR4SRtUAw1veIZzOjRhSBzCoyKFjgH/3K7+BHzg+Cgw0eSW3AAAAAElFTkSuQmCC) 2x);
}
</style>
<style>
body {
  background-color: rgb(187, 187, 187);
}

#plugin_icon {
  opacity: .6;
}
</style>
</head>

<body id="t" onLoad="insertLink()">
<div i18n-values="title:name" id="outer">
  <div id="inner">
    <div><img id="plugin_icon" src="data:image/png;base64,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" /></div>
    <h1 id="message" i18n-content="message"></h1>
    <div id="enable_link">
      <a href="#" onclick="plugin.openAboutPlugins();">chrome://plugins</a>
    </div>
  </div>
  <div id="close" i18n-values="title:hide;data-plugin-type:pluginType"
      onclick="plugin.hide();">
  </div>
</div>
</body>
</html>
<!doctype html>
<html i18n-values="dir:textdirection;lang:language">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0,
                                 maximum-scale=1.0, user-scalable=no">
  <title i18n-content="title"></title>
  <style>/* Copyright 2014 The Chromium Authors. All rights reserved.
   Use of this source code is governed by a BSD-style license that can be
   found in the LICENSE file. */

a {
  color: #585858;
}

.bad-clock .icon {
  background-image: -webkit-image-set(
      url(data:image/png;base64,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) 1x,
      url(data:image/png;base64,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) 2x);
}

body {
  background-color: #f7f7f7;
  color: #646464;
}

body.safe-browsing {
  background-color: rgb(206, 52, 38);
  color: white;
}

button {
  -webkit-user-select: none;
  background: rgb(76, 142, 250);
  border: 0;
  border-radius: 2px;
  box-sizing: border-box;
  color: #fff;
  cursor: pointer;
  float: right;
  font-size: .875em;
  margin: 0;
  padding: 10px 24px;
  transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
}

[dir='rtl'] button {
  float: left;
}

button:active {
  background: rgb(50, 102, 213);
  outline: 0;
}

button:hover {
  box-shadow: 0 1px 3px rgba(0, 0, 0, .50);
}

#debugging {
  display: inline;
  overflow: auto;
}

.debugging-content {
  line-height: 1em;
  margin-bottom: 0;
  margin-top: 1em;
}

.debugging-title {
  font-weight: bold;
}

#details {
  color: #696969;
  margin: 45px 0 50px;
}

#details p:not(:first-of-type) {
  margin-top: 20px;
}

#details-button {
  background: inherit;
  border: 0;
  float: none;
  margin: 0;
  padding: 10px 0;
  text-decoration: underline;
}

#details-button:hover {
  box-shadow: inherit;
}

.error-code {
  color: #777;
  display: inline;
  font-size: .86667em;
  margin-top: 15px;
  opacity: .5;
  text-transform: uppercase;
}

#error-debugging-info {
  font-size: 0.8em;
}

h1 {
  color: #333;
  font-size: 1.6em;
  font-weight: normal;
  line-height: 1.25em;
  margin-bottom: 16px;
}

h2 {
  font-size: 1.2em;
  font-weight: normal;
}

.hidden {
  display: none;
}

html {
  -webkit-text-size-adjust: 100%;
  font-size: 125%;
}

.icon {
  background-repeat: no-repeat;
  background-size: 100%;
  height: 72px;
  margin: 0 0 40px;
  width: 72px;
}

input[type=checkbox] {
  opacity: 0;
}

input[type=checkbox]:focus ~ .checkbox {
  outline: -webkit-focus-ring-color auto 5px;
}

.interstitial-wrapper {
  box-sizing: border-box;
  font-size: 1em;
  line-height: 1.6em;
  margin: 100px auto 0;
  max-width: 600px;
  width: 100%;
}

#main-message > p {
  display: inline;
}

#extended-reporting-opt-in {
  font-size: .875em;
  margin-top: 39px;
}

#extended-reporting-opt-in label {
  position: relative;
}

.nav-wrapper {
  margin-top: 51px;
}

.nav-wrapper::after {
  clear: both;
  content: '';
  display: table;
  width: 100%;
}

.safe-browsing :-webkit-any(
    a, #details, #details-button, h1, h2, p, .small-link) {
  color: white;
}

.safe-browsing button {
  background-color: rgba(255, 255, 255, .15);
}

.safe-browsing button:active {
  background-color: rgba(255, 255, 255, .25);
}

.safe-browsing button:hover {
  box-shadow: 0 2px 3px rgba(0, 0, 0, .5);
}

.safe-browsing .error-code {
  display: none;
}

.safe-browsing .icon {
  background-image: -webkit-image-set(
      url(data:image/png;base64,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) 1x,
      url(data:image/png;base64,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) 2x);
}

.small-link {
  color: #696969;
  font-size: .875em;
}

.ssl .icon {
  background-image: -webkit-image-set(
      url(data:image/png;base64,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) 1x,
      url(data:image/png;base64,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) 2x);
}

.captive-portal .icon {
  background-image: -webkit-image-set(
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAQAAAD/5HvMAAAEyElEQVR4Xu3afWhVZRwH8LvdmjVSjKyQbKazia1k1sL6YzXoZdy28/J8f5XRC7hwEVk0hZQCXY2SipCgYgappXMQ5Ya9ELZqoEM3VHqxBkapm21jOBWmbLfudk+0Peeu2+mc3zk9514WbN9/zz18ds75Pc/vPM+JTP9NZzrT+b9Fn2nGxHrainb8ggEaRgLn0IOjaMFroloU/Ssg1yxBLZpxBD00QufpODrRiFX6IiUKXY8XcRAJsryC3nRL7EpsQJ/r0V3iSS0/MKU4D6uoQwLY/P1q4i0aYX9xVqyPRH1jbr8UtfSbE8CDqIK60wBjOEb7aDf24CBO/gN12LjJF4dM+dPAoNgMdNkUxLENQltAFViJdbTWfFTcaRbiMXyCpE1CM4vR5uAzdwB/hcxCDI5jXqGFeAadNJoGH0ErVhg3YPs46Ad9JldNS3GCAbDPkFGG/eJGWktn3PA4IUB3oxPzGY4AXSBLCSTLgfZxx2MLV1Q5tFHeWxWQDNalHulWeo4q9GW4VVShng5J0KgZ8+bkYpcEqIJk6H2y0CiW4H58gGMYQhyn8DlqUUltZIk1XF01kKUW5yhm3gVB3Q76MDaRyXBQR1aIIJnyi6jNZUgs8uTQfUiGDJIxZ9OPfxEwhAO0F70To5NR5skxrsUgWaGDZLQCHBHVxnKxWjwuivRS7McK7na1kpUZkEwUzXbFiZfZcVk8pE6xZ3u34AV5TFJUsV2ObBHU0+Q5wu0eJ21krw+eD4lzBvOYf7wLeyI5DEfLx2l1DPqoSXK8SItis/gm41mlago/9P2UApklZE0pkHhdAv6YIiB8NwEQL9HvUwCkzZHz15g5Gw8jmR0QtsizvOoACUjAIdlOZQUkHpCgDqd1gwRslhX3djZAmDsBwpATJPtDUZPqGFuyUWU453IWu7fFHZOvhjiQ+aqiDheQ/bJjXpf2oP+caRA+cgPJpkxckeZfiIHMgmirC8gee4rz0qF6KV3IJEi86R8kg0oazQ6Iv2Uyoiajt4x/qJ1BfcCe6JQZC/BQ82XvDLYHJPUEK3tmYHTmlotpbzCSwsDomDpc+mD6VgHETB3M5Or2c5xUBvGTq7P98DjBEjqrBOLbD2eDZj7o+aJdhnhooJxUbd/r1cJ+yl1mJMMBGWUSP6zlezT5SIirGNKacEB4bwKEXcxrEN7gThUGSCtILaZXMC+KiGN+5kHYITndkSj7Ko3GTIPMEvtJFKt9LDYgiZtVQTLnqUPUOJcV8KWE95df4m85ps0+CQ/ig68xN72lscF4yveCFTa5g9AXnDR5lczC1Jr+4UhuCsAv6YlH3EDURFbgPCG3Y2altmPG9FIJ8LnoOYLbXNDzgi+Myvkqii9sIuocAHZZuN9tAKi6hnaiBwka9f942y2rzFcut4tZOO+3r5J6xcVmYEeKc9xlPuC3FhDHynBA6LQ5GGA2ftnNl82RqDrIDgb1ZU4AnxzUTc7raDeWhwPCUW0BA/C7gYeP9cWqILSUX8YAgmxxIoF3tYL/DkK9Y/znwm8CI4lvRLV+dVAQThOpOPht8p+ogZ4W9/jijFFD5eXhWPgPCXjMh/pSVYD6pxaywPGOKOIBWfkYhXYKozgvy5/rYBva8avzcx19sSrgT2jJnjJMVMiUAAAAAElFTkSuQmCC) 1x,
      url(data:image/png;base64,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) 2x);
}

.checkbox {
  background: transparent;
  border: 1px solid white;
  border-radius: 2px;
  display: block;
  height: 14px;
  left: 0;
  position: absolute;
  right: 0;
  top: -1px;
  width: 14px;
}

.checkbox::before {
  background: transparent;
  border: 2px solid white;
  border-right-width: 0;
  border-top-width: 0;
  content: '';
  height: 4px;
  left: 2px;
  opacity: 0;
  position: absolute;
  top: 3px;
  transform: rotate(-45deg);
  width: 9px;
}

.ssl-opt-in .checkbox {
  border-color: #696969;
}

.ssl-opt-in .checkbox::before {
  border-color: #696969;
}

input[type=checkbox]:checked ~ .checkbox::before {
  opacity: 1;
}

@media (max-width: 700px) {
  .interstitial-wrapper {
    padding: 0 10%;
  }

  #error-debugging-info {
    overflow: auto;
  }
}

@media (max-height: 600px) {
  .error-code {
    margin-top: 10px;
  }
}

@media (max-width: 420px) {
  button,
  [dir='rtl'] button,
  .small-link {
    float: none;
    font-size: .825em;
    font-weight: 400;
    margin: 0;
    text-transform: uppercase;
    width: 100%;
  }

  #details {
    margin: 20px 0 20px 0;
  }

  #details p:not(:first-of-type) {
    margin-top: 10px;
  }

  #details-button {
    display: block;
    margin-top: 20px;
    text-align: center;
    width: 100%;
  }

  .interstitial-wrapper {
    padding: 0 5%;
  }

  #extended-reporting-opt-in {
    margin-top: 24px;
  }

  .nav-wrapper {
    margin-top: 30px;
  }
}

/**
 * Mobile specific styling.
 * Navigation buttons are anchored to the bottom of the screen.
 * Details message replaces the top content in its own scrollable area.
 */

@media (max-width: 420px) and (max-height: 736px) and (orientation: portrait) {
  #details-button {
    border: 0;
    margin: 8px 0 0;
  }

  .secondary-button {
    -webkit-margin-end: 0;
    margin-top: 16px;
  }
}

/* Fixed nav. */
@media (min-width: 240px) and (max-width: 420px) and
       (min-height: 401px) and (max-height: 736px) and (orientation:portrait),
       (min-width: 421px) and (max-width: 736px) and (min-height: 240px) and
       (max-height: 420px) and (orientation:landscape) {
  body .nav-wrapper {
    background: #f7f7f7;
    bottom: 0;
    box-shadow: 0 -22px 40px rgb(247, 247, 247);
    left: 0;
    margin: 0;
    max-width: 736px;
    padding-left: 24px;
    padding-right: 24px;
    position: fixed;
    z-index: 1;
  }

  body.safe-browsing .nav-wrapper {
    background: rgb(206, 52, 38);
    box-shadow: 0 -22px 40px rgb(206, 52, 38);
  }

  .interstitial-wrapper {
    max-width: 736px;
  }

  #details,
  #main-content {
    padding-bottom: 40px;
  }
}

@media (max-width: 420px) and (max-height: 736px) and (orientation: portrait),
       (max-width: 736px) and (max-height: 420px) and (orientation: landscape) {
  body {
    margin: 0 auto;
  }

  button,
  [dir='rtl'] button,
  button.small-link {
    font-family: Roboto-Regular,Helvetica;
    font-size: .933em;
    font-weight: 600;
    margin: 6px 0;
    text-transform: uppercase;
  }

  .nav-wrapper {
    box-sizing: border-box;
    padding-bottom: 8px;
    width: 100%;
  }

  .error-code {
    margin-top: 0;
  }

  #details {
    box-sizing: border-box;
    height: auto;
    margin: 0;
    opacity: 1;
    transition: opacity 250ms cubic-bezier(0.4, 0, 0.2, 1);
  }

  #details.hidden,
  #main-content.hidden {
    display: block;
    height: 0;
    opacity: 0;
    overflow: hidden;
  }

  #details-button {
    padding-bottom: 16px;
    padding-top: 16px;
  }

  h1 {
    font-size: 1.5em;
    margin-bottom: 8px;
  }

  .icon {
    margin-bottom: 12px;
  }

  .interstitial-wrapper {
    box-sizing: border-box;
    margin: 24px auto 12px;
    padding: 0 24px;
    position: relative;
  }

  .interstitial-wrapper p {
    font-size: .95em;
    line-height: 1.61em;
    margin-top: 8px;
  }

  #main-content {
    margin: 0;
    transition: opacity 100ms cubic-bezier(0.4, 0, 0.2, 1);
  }

  .small-link {
    border: 0;
  }

  .suggested-left > #control-buttons,
  .suggested-right > #control-buttons {
    float: none;
    margin: 0;
  }
}

@media (min-height: 400px) and (orientation:portrait) {
  body:not(.extended-reporting-has-checkbox) .interstitial-wrapper {
    margin-bottom: 145px;
  }
}

@media (min-height: 299px) and (orientation:portrait) {
  .nav-wrapper {
    padding-bottom: 16px;
  }
}

@media (min-height: 405px) and (max-height: 736px) and
       (max-width: 420px) and (orientation:portrait) {
  .icon {
    margin-bottom: 24px;
  }

  .interstitial-wrapper {
    margin-top: 64px;
  }
}

@media (min-height: 480px) and (max-width: 420px) and
       (max-height: 736px) and (orientation: portrait),
       (min-height: 338px) and (max-height: 420px) and (max-width: 736px) and
       (orientation: landscape) {
  .icon {
    margin-bottom: 24px;
  }

  .nav-wrapper {
    padding-bottom: 24px;
  }
}

@media (min-height: 500px) and (max-width: 414px) and (orientation: portrait) {
  :not(.extended-reporting-has-checkbox) .interstitial-wrapper {
    margin-top: 96px;
  }
}

/* Phablet sizing */
@media (min-width: 375px) and (min-height: 641px) and (max-height: 736px) and
       (max-width: 414px) and (orientation: portrait) {
  button,
  [dir='rtl'] button,
  .small-link {
    font-size: 1em;
    padding-bottom: 12px;
    padding-top: 12px;
  }

  body:not(.offline) .icon {
    height: 80px;
    width: 80px;
  }

  #details-button {
    margin-top: 28px;
  }

  h1 {
    font-size: 1.7em;
  }

  .icon {
    margin-bottom: 28px;
  }

  .interstitial-wrapper {
    padding: 28px;
  }

  .interstitial-wrapper p {
    font-size: 1.05em;
  }

  .nav-wrapper {
    padding: 28px;
  }
}

@media (min-width: 420px) and (max-width: 736px) and
       (min-height: 240px) and (max-height: 298px) and
       (orientation:landscape) {
  body:not(.offline) .icon {
    height: 50px;
    width: 50px;
  }

  .icon {
    padding-top: 0;
  }

  .interstitial-wrapper {
    margin-top: 16px;
  }

  .nav-wrapper {
    padding: 0 24px 8px;
  }
}

@media (min-width: 420px) and (max-width: 736px) and
       (min-height: 240px) and (max-height: 420px) and
       (orientation:landscape) {
  #details-button {
    margin: 0;
  }

  .interstitial-wrapper {
    margin-bottom: 70px;
  }

  .nav-wrapper {
    margin-top: 0;
  }

  #extended-reporting-opt-in {
    margin-top: 0;
  }
}

/* Phablet landscape */
@media (min-width: 680px) and (max-height: 414px) {
  .interstitial-wrapper {
    margin: 24px auto;
  }

  .nav-wrapper {
    margin: 16px auto 0;
  }
}

@media (max-height: 240px) and (orientation: landscape),
       (max-height: 480px) and (orientation: portrait),
       (max-width: 419px) and (max-height: 323px) {
  body:not(.offline) .icon {
    height: 56px;
    width: 56px;
  }

  .icon {
    margin-bottom: 16px;
  }
}

/* Small mobile screens. No fixed nav. */
@media (max-height: 400px) and (orientation: portrait),
       (max-height: 239px) and (orientation: landscape),
       (max-width: 419px) and (max-height: 399px) {
  .interstitial-wrapper {
    display: flex;
    flex-direction: column;
    margin-bottom: 0;
  }

  #details {
    flex: 1 1 auto;
    order: 0;
  }

  #main-content {
    flex: 1 1 auto;
    order: 0;
  }

  .nav-wrapper {
    flex: 0 1 auto;
    margin-top: 8px;
    order: 1;
    padding-left: 0;
    padding-right: 0;
    position: relative;
    width: 100%;
  }
}

/* Extended reporting opt-in. No fixed nav. */
@media (max-height: 736px) and (orientation: portrait),
       (max-height: 360px) and (max-width: 680px) and (orientation: landscape) {
  .extended-reporting-has-checkbox .interstitial-wrapper {
    display: flex;
    flex-direction: column;
    margin-bottom: 0;
  }

  .extended-reporting-has-checkbox #details {
    flex: 1 1 auto;
    order: 0;
  }

  .extended-reporting-has-checkbox #main-content {
    flex: 1 1 auto;
    order: 0;
    padding-bottom: 0;
  }

  .extended-reporting-has-checkbox #extended-reporting-opt-in {
    margin-bottom: 8px;
  }

  body.extended-reporting-has-checkbox .nav-wrapper {
    flex: 0 1 auto;
    margin-top: 0;
    order: 1;
    padding-left: 0;
    padding-right: 0;
    position: relative;
    width: 100%;
  }
}

@media (max-width: 239px) and (orientation: portrait) {
  .nav-wrapper {
    padding-left: 0;
    padding-right: 0;
  }
}
</style>
  <style>/* Copyright 2013 The Chromium Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file. */

/* Don't use the main frame div when the error is in a subframe. */
html[subframe] #main-frame-error {
  display: none;
}

/* Don't use the subframe error div when the error is in a main frame. */
html:not([subframe]) #sub-frame-error {
  display: none;
}

#diagnose-button {
  -webkit-margin-start: 0;
  float: none;
  margin-bottom: 10px;
  margin-top: 20px;
}

h1 {
  margin-top: 0;
}

h2 {
  color: #666;
  font-size: 1.2em;
  font-weight: normal;
  margin: 10px 0;
}

a {
  color: rgb(17, 85, 204);
  text-decoration: none;
}

.icon {
  -webkit-user-select: none;
  content: '';
}

.icon-generic {
  /**
   * Can't access chrome://theme/IDR_ERROR_NETWORK_GENERIC from an untrusted
   * renderer process, so embed the resource manually.
   */
  content: -webkit-image-set(
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABIAQMAAABvIyEEAAAABlBMVEUAAABTU1OoaSf/AAAAAXRSTlMAQObYZgAAAENJREFUeF7tzbEJACEQRNGBLeAasBCza2lLEGx0CxFGG9hBMDDxRy/72O9FMnIFapGylsu1fgoBdkXfUHLrQgdfrlJN1BdYBjQQm3UAAAAASUVORK5CYII=) 1x,
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJAAAACQAQMAAADdiHD7AAAABlBMVEUAAABTU1OoaSf/AAAAAXRSTlMAQObYZgAAAFJJREFUeF7t0cENgDAMQ9FwYgxG6WjpaIzCCAxQxVggFuDiCvlLOeRdHR9yzjncHVoq3npu+wQUrUuJHylSTmBaespJyJQoObUeyxDQb3bEm5Au81c0pSCD8HYAAAAASUVORK5CYII=) 2x);
}

.icon-offline {
  content: -webkit-image-set(
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABIAQMAAABvIyEEAAAABlBMVEUAAABTU1OoaSf/AAAAAXRSTlMAQObYZgAAAGxJREFUeF7tyMEJwkAQRuFf5ipMKxYQiJ3Z2nSwrWwBA0+DQZcdxEOueaePp9+dQZFB7GpUcURSVU66yVNFj6LFICatThZB6r/ko/pbRpUgilY0Cbw5sNmb9txGXUKyuH7eV25x39DtJXUNPQGJtWFV+BT/QAAAAABJRU5ErkJggg==) 1x,
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJAAAACQBAMAAAAVaP+LAAAAGFBMVEUAAABTU1NNTU1TU1NPT09SUlJSUlJTU1O8B7DEAAAAB3RSTlMAoArVKvVgBuEdKgAAAJ1JREFUeF7t1TEOwyAMQNG0Q6/UE+RMXD9d/tC6womIFSL9P+MnAYOXeTIzMzMzMzMzaz8J9Ri6HoITmuHXhISE8nEh9yxDh55aCEUoTGbbQwjqHwIkRAEiIaG0+0AA9VBMaE89Rogeoww936MQrWdBr4GN/z0IAdQ6nQ/FIpRXDwHcA+JIJcQowQAlFUA0MfQpXLlVQfkzR4igS6ENjknm/wiaGhsAAAAASUVORK5CYII=) 2x);
  position: relative;
}

.icon-disabled {
  content: -webkit-image-set(
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHAAAABICAMAAAAZF4G5AAAABlBMVEVMaXFTU1OXUj8tAAAAAXRSTlMAQObYZgAAASZJREFUeAHd11Fq7jAMRGGf/W/6PoWB67YMqv5DybwG/CFjRuR8JBw3+ByiRjgV9W/TJ31P0tBfC6+cj1haUFXKHmVJo5wP98WwQ0ZCbfUc6LQ6VuUBz31ikADkLMkDrfUC4rR6QGW+gF6rx7NaHWCj1Y/W6lf4L7utvgBSt3rBFSS/XBMPUILcJINHCBWYUfpWn4NBi1ZfudIc3rf6/NGEvEA+AsYTJozmXemjXeLZAov+mnkN2HfzXpMSVQDnGw++57qNJ4D1xitA2sJ+VAWMygSEaYf2mYPTjZfk2K8wmP7HLIH5Mg4/pP+PEcDzUvDMvYbs/2NWwPO5vBdMZE4EE5UTQLiBFDaUlTDPBRoJ9HdAYIkIo06og3BNXtCzy7zA1aXk5x+tJARq63eAygAAAABJRU5ErkJggg==) 1x,
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOAAAACQAQMAAAArwfVjAAAABlBMVEVMaXFTU1OXUj8tAAAAAXRSTlMAQObYZgAAAYdJREFUeF7F1EFqwzAUBNARAmVj0FZe5QoBH6BX+dn4GlY2PYNzGx/A0CvkCIJuvIraKJKbgBvzf2g62weDGD7CYggpfFReis4J0ey9EGFIiEQQojFSlA9kSIiqd0KkFjKsewgRbStEN19mxUPTtmW9HQ/h6tyqNQ8NlSMZdzyE6qkoE0trVYGFm0n1WYeBhduzwbwBC7voS+vIxfeMjeaiLxsMMtQNwMPtuew+DjzcTHk8YMfDknEcIUOtf2lVfgVH3K4Xv5PRYAXRVMtItIJ3rfaCIVn9DsTH2NxisAVRex2Hh3hX+/mRUR08bAwPEYsI51ZxWH4Q0SpicQRXeyEaIug48FEdegARfMz/tADVsRciwTAxW308ehmC2gLraC+YCbV3QoTZexa+zegAEW5PhhgYfmbvJgcRqngGByOSXdFJcLk2JeDPEN0kxe1JhIt5FiFA+w+ItMELsUyPF2IaJ4aILqb4FbxPwhImwj6JauKgDUCYaxmYIsd4KXdMjIC9ItB5Bn4BNRwsG0XM2nwAAAAASUVORK5CYII=) 2x);
  width: 112px;
}

.error-code {
  display: block;
}

#content-top {
  margin: 20px;
}

#help-box-inner {
  background-color: #f9f9f9;
  border-top: 1px solid #EEE;
  color: #444;
  padding: 20px;
  text-align: start;
}

.hidden {
  display: none;
}

#suggestion {
  margin-top: 15px;
}

#short-suggestion {
  margin-top: 5px;
}

#sub-frame-error-details {
  color: #8F8F8F;
/* Not done on mobile for performance reasons. */
  text-shadow: 0 1px 0 rgba(255,255,255,0.3);
}

[jscontent=failedUrl] {
  overflow-wrap: break-word;
}

#search-container {
  /* Prevents a space between controls. */
  display: flex;
  margin-top: 20px;
}

#search-box {
  border: 1px solid #cdcdcd;
  flex-grow: 1;
  font-size: 16px;
  height: 26px;
  margin-right: 0;
  padding: 1px 9px;
}

#search-box:focus {
  border: 1px solid rgb(93, 154, 255);
  outline: none;
}

#search-button {
  border: none;
  border-bottom-left-radius: 0;
  border-top-left-radius: 0;
  box-shadow: none;
  display: flex;
  height: 30px;
  margin: 0;
  padding: 0;
  width: 60px;
}

#search-image {
  content:
      -webkit-image-set(
          url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAPCAQAAAB+HTb/AAAArElEQVR4Xn3NsUoCUBzG0XvB3U0chR4geo5qihpt6gkCx0bXFsMERWj2KWqIanAvmlUUoQapwU6g4l8H5bd9Z/iSPS0hu/RqZqrncBuzLl7U3Rn4cSpQFTeroejJl1Lgs7f4ceDPdeBMXYp86gaONYJkY83AnqHiGk9wHnjk16PKgo5N9BUCkzPf5j6M0PfuVg5MymoetFwoaKAlB26WdXAvJ7u5mezitqtkT//7Sv/u96CaLQAAAABJRU5ErkJggg==) 1x,
          url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAeCAQAAACVzLYUAAABYElEQVR4Xr3VMUuVURzH8XO98jgkGikENkRD0KRGDUVDQy0h2SiC4IuIiktL4AvQt1CDBJUJwo1KXXS6cWdHw7tcjWwoC5Hrx+UZgnNO5CXiO/75jD/+QZf9MzjskVU7DrU1zRv9G9ir5hsA4Nii83+GA9ZI1nI1D6tWAE1TRlQMuuuFDthzMQefgo4nKr+f3dIGDdUUHPYD1ISoMQdgJgUfgqaKEOcxWE/BVTArJBvwC0cGY7gNLgiZNsD1GP4EPVn4EtyLYRuczcJ34HYMP4E7GdajDS7FcB48z8AJ8FmI4TjouBkzZ2yBuRQMlsButIZ+dfDVUBqOaIHvavpLVHXfFmAqv45r9gEHNr3y3hcAfLSgSMPgiiZR+6Z9AMuKNAwqpjUcA2h55pxgAfBWkYRlQ254YMJloaxPHbCkiGCymL5RlLA7GnRDXyuC7uhicLoKdRyaDE5Pl00K//93nABqPgBDK8sfWgAAAABJRU5ErkJggg==) 2x);
  margin: auto;
}

.secondary-button {
  -webkit-margin-end: 16px;
  background: #d9d9d9;
  color: #696969;
}

.snackbar {
  background: #323232;
  border-radius: 2px;
  bottom: 24px;
  box-sizing: border-box;
  color: #fff;
  font-size: .87em;
  left: 24px;
  max-width: 568px;
  min-width: 288px;
  opacity: 0;
  padding: 16px 24px 12px;
  position: fixed;
  transform: translateY(90px);
  will-change: opacity, transform;
  z-index: 999;
}

.snackbar-show {
  -webkit-animation:
    show-snackbar .25s cubic-bezier(0.0, 0.0, 0.2, 1) forwards,
    hide-snackbar .25s cubic-bezier(0.4, 0.0, 1, 1) forwards 5s;
}

@-webkit-keyframes show-snackbar {
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

@-webkit-keyframes hide-snackbar {
  0% {
    opacity: 1;
    transform: translateY(0);
  }
  100% {
    opacity: 0;
    transform: translateY(90px);
  }
}

.suggestions {
  margin-top: 18px;
}

.suggestion-header {
  font-weight: bold;
  margin-bottom: 4px;
}

.suggestion-body {
  color: #777;
}

/* Increase line height at higher resolutions. */
@media (min-width: 641px) and (min-height: 641px) {
  #help-box-inner {
    line-height: 18px;
  }
}

/* Decrease padding at low sizes. */
@media (max-width: 640px), (max-height: 640px) {
  h1 {
    margin: 0 0 15px;
  }
  #content-top {
    margin: 15px;
  }
  #help-box-inner {
    padding: 20px;
  }
  .suggestions {
    margin-top: 10px;
  }
  .suggestion-header {
    margin-bottom: 0;
  }
  .error-code {
    margin-top: 10px;
  }
}

/* Don't allow overflow when in a subframe. */
html[subframe] body {
  overflow: hidden;
}

#sub-frame-error {
  -webkit-align-items: center;
  background-color: #DDD;
  display: -webkit-flex;
  -webkit-flex-flow: column;
  height: 100%;
  -webkit-justify-content: center;
  left: 0;
  position: absolute;
  top: 0;
  transition: background-color .2s ease-in-out;
  width: 100%;
}

#sub-frame-error:hover {
  background-color: #EEE;
}

#sub-frame-error .icon-generic {
  margin: 0 0 16px;
}

#sub-frame-error-details {
  margin: 0 10px;
  text-align: center;
  visibility: hidden;
}

/* Show details only when hovering. */
#sub-frame-error:hover #sub-frame-error-details {
  visibility: visible;
}

/* If the iframe is too small, always hide the error code. */
/* TODO(mmenke): See if overflow: no-display works better, once supported. */
@media (max-width: 200px), (max-height: 95px) {
  #sub-frame-error-details {
    display: none;
  }
}

/* Adjust icon for small embedded frames in apps. */
@media (max-height: 100px) {
  #sub-frame-error .icon-generic {
    height: auto;
    margin: 0;
    padding-top: 0;
    width: 25px;
  }
}

/* details-button is special; it's a <button> element that looks like a link. */
#details-button {
  box-shadow: none;
  min-width: 0;
}

/* Styles for platform dependent separation of controls and details button. */
.suggested-left > #control-buttons,
.suggested-left #stale-load-button,
.suggested-right > #details-button {
  float: left;
}

.suggested-right > #control-buttons,
.suggested-right #stale-load-button,
.suggested-left > #details-button {
  float: right;
}

.suggested-left .secondary-button {
  -webkit-margin-end: 0px;
  -webkit-margin-start: 16px;
}

#details-button.singular {
  float: none;
}

#buttons::after {
  clear: both;
  content: '';
  display: block;
  width: 100%;
}

/* Offline page */
.offline .interstitial-wrapper {
  color: #2b2b2b;
  font-size: 1em;
  line-height: 1.55;
  margin: 0 auto;
  max-width: 600px;
  padding-top: 100px;
  width: 100%;
}

.offline .runner-container {
  height: 150px;
  max-width: 600px;
  overflow: hidden;
  position: absolute;
  top: 35px;
  width: 44px;
}

.offline .runner-canvas {
  height: 150px;
  max-width: 600px;
  opacity: 1;
  overflow: hidden;
  position: absolute;
  top: 0;
  z-index: 2;
}

.offline .controller {
  background: rgba(247,247,247, .1);
  height: 100vh;
  left: 0;
  position: absolute;
  top: 0;
  width: 100vw;
  z-index: 1;
}

#offline-resources {
  display: none;
}

@media (max-width: 420px) {
  .suggested-left > #control-buttons,
  .suggested-right > #control-buttons {
    float: none;
  }

  .snackbar {
    left: 0;
    bottom: 0;
    width: 100%;
    border-radius: 0;
  }
}

@media (max-height: 350px) {
  h1 {
    margin: 0 0 15px;
  }

  .icon-offline {
    margin: 0 0 10px;
  }

  .interstitial-wrapper {
    margin-top: 5%;
  }

  .nav-wrapper {
    margin-top: 30px;
  }
}

@media (min-width: 600px) and (max-width: 736px) and (orientation: landscape) {
  .offline .interstitial-wrapper {
    margin-left: 0;
    margin-right: 0;
  }
}

@media (min-width: 420px) and (max-width: 736px) and
       (min-height: 240px) and (max-height: 420px) and
       (orientation:landscape) {
  .interstitial-wrapper {
    margin-bottom: 100px;
  }
}

@media (min-height: 240px) and (orientation: landscape) {
  .offline .interstitial-wrapper {
    margin-bottom: 90px;
  }

  .icon-offline {
    margin-bottom: 20px;
  }
}

@media (max-height: 320px) and (orientation: landscape) {
  .icon-offline {
    margin-bottom: 0;
  }

  .offline .runner-container {
    top: 10px;
  }
}

@media (max-width: 240px) {
  button {
    padding-left: 12px;
    padding-right: 12px;
  }

  .interstitial-wrapper {
    overflow: inherit;
    padding: 0 8px;
  }
}

@media (max-width: 120px) {
  button {
    width: auto;
  }
}</style>
  <script>// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var mobileNav = false;

/**
 * For small screen mobile the navigation buttons are moved
 * below the advanced text.
 */
function onResize() {
  var helpOuterBox = document.querySelector('#details');
  var mainContent = document.querySelector('#main-content');
  var mediaQuery = '(min-width: 240px) and (max-width: 420px) and ' +
      '(max-height: 736px) and (orientation: portrait),' +
      '(max-width: 736px) and (max-height: 420px) and (orientation: landscape)';
  var detailsHidden = helpOuterBox.classList.contains('hidden');
  var runnerContainer = document.querySelector('.runner-container');

  // Check for change in nav status.
  if (mobileNav != window.matchMedia(mediaQuery).matches) {
    mobileNav = !mobileNav;

    // Handle showing the top content / details sections according to state.
    if (mobileNav) {
      mainContent.classList.toggle('hidden', !detailsHidden);
      helpOuterBox.classList.toggle('hidden', detailsHidden);
      if (runnerContainer) {
        runnerContainer.classList.toggle('hidden', !detailsHidden);
      }
    } else if (!detailsHidden) {
      // Non mobile nav with visible details.
      mainContent.classList.remove('hidden');
      helpOuterBox.classList.remove('hidden');
      if (runnerContainer) {
        runnerContainer.classList.remove('hidden');
      }
    }
  }
}

function setupMobileNav() {
  window.addEventListener('resize', onResize);
  onResize();
}

document.addEventListener('DOMContentLoaded', setupMobileNav);
</script>
  <script>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

function toggleHelpBox() {
  var helpBoxOuter = document.getElementById('details');
  helpBoxOuter.classList.toggle('hidden');
  var detailsButton = document.getElementById('details-button');
  if (helpBoxOuter.classList.contains('hidden'))
    detailsButton.innerText = detailsButton.detailsText;
  else
    detailsButton.innerText = detailsButton.hideDetailsText;

  // Details appears over the main content on small screens.
  if (mobileNav) {
    document.getElementById('main-content').classList.toggle('hidden');
    var runnerContainer = document.querySelector('.runner-container');
    if (runnerContainer) {
      runnerContainer.classList.toggle('hidden');
    }
  }
}

function diagnoseErrors() {
  var extensionId = 'idddmepepmjcgiedknnmlbadcokidhoa';
  var diagnoseFrame = document.getElementById('diagnose-frame');
  diagnoseFrame.innerHTML =
      '<iframe src="chrome-extension://' + extensionId +
      '/index.html"></iframe>';
}

// Subframes use a different layout but the same html file.  This is to make it
// easier to support platforms that load the error page via different
// mechanisms (Currently just iOS).
if (window.top.location != window.location)
  document.documentElement.setAttribute('subframe', '');

// Re-renders the error page using |strings| as the dictionary of values.
// Used by NetErrorTabHelper to update DNS error pages with probe results.
function updateForDnsProbe(strings) {
  var context = new JsEvalContext(strings);
  jstProcess(context, document.getElementById('t'));
}

// Given the classList property of an element, adds an icon class to the list
// and removes the previously-
function updateIconClass(classList, newClass) {
  var oldClass;

  if (classList.hasOwnProperty('last_icon_class')) {
    oldClass = classList['last_icon_class'];
    if (oldClass == newClass)
      return;
  }

  classList.add(newClass);
  if (oldClass !== undefined)
    classList.remove(oldClass);

  classList['last_icon_class'] = newClass;

  if (newClass == 'icon-offline') {
    document.body.classList.add('offline');
    new Runner('.interstitial-wrapper');
  } else {
    document.body.classList.add('neterror');
  }
}

// Does a search using |baseSearchUrl| and the text in the search box.
function search(baseSearchUrl) {
  var searchTextNode = document.getElementById('search-box');
  document.location = baseSearchUrl + searchTextNode.value;
  return false;
}

// Use to track clicks on elements generated by the navigation correction
// service.  If |trackingId| is negative, the element does not come from the
// correction service.
function trackClick(trackingId) {
  // This can't be done with XHRs because XHRs are cancelled on navigation
  // start, and because these are cross-site requests.
  if (trackingId >= 0 && errorPageController)
    errorPageController.trackClick(trackingId);
}

// Called when an <a> tag generated by the navigation correction service is
// clicked.  Separate function from trackClick so the resources don't have to
// be updated if new data is added to jstdata.
function linkClicked(jstdata) {
  trackClick(jstdata.trackingId);
}

// Implements button clicks.  This function is needed during the transition
// between implementing these in trunk chromium and implementing them in
// iOS.
function reloadButtonClick(url) {
  if (window.errorPageController) {
    errorPageController.reloadButtonClick();
  } else {
    location = url;
  }
}

function showSavedCopyButtonClick() {
  if (window.errorPageController) {
    errorPageController.showSavedCopyButtonClick();
  }
}

function detailsButtonClick() {
  if (window.errorPageController)
    errorPageController.detailsButtonClick();
}

/**
 * Replace the reload button with the Google cached copy suggestion.
 */
function setUpCachedButton(buttonStrings) {
  var reloadButton = document.getElementById('reload-button');

  reloadButton.textContent = buttonStrings.msg;
  var url = buttonStrings.cacheUrl;
  var trackingId = buttonStrings.trackingId;
  reloadButton.onclick = function(e) {
    e.preventDefault();
    trackClick(trackingId);
    if (window.errorPageController) {
      errorPageController.trackCachedCopyButtonClick(
          buttonStrings.defaultLabel);
    }
    location = url;
  };
  reloadButton.style.display = '';
  document.getElementById('control-buttons').hidden = false;
}

var primaryControlOnLeft = true;
primaryControlOnLeft = false;

function onDocumentLoad() {
  var controlButtonDiv = document.getElementById('control-buttons');
  var reloadButton = document.getElementById('reload-button');
  var detailsButton = document.getElementById('details-button');
  var showSavedCopyButton = document.getElementById('show-saved-copy-button');

  var primaryButton, secondaryButton;
  if (showSavedCopyButton.primary) {
    primaryButton = showSavedCopyButton;
    secondaryButton = reloadButton;
  } else {
    primaryButton = reloadButton;
    secondaryButton = showSavedCopyButton;
  }

  // Sets up the proper button layout for the current platform.
  if (primaryControlOnLeft) {
    buttons.classList.add('suggested-left');
    controlButtonDiv.insertBefore(secondaryButton, primaryButton);
  } else {
    buttons.classList.add('suggested-right');
    controlButtonDiv.insertBefore(primaryButton, secondaryButton);
  }

  if (reloadButton.style.display == 'none' &&
      showSavedCopyButton.style.display == 'none') {
    detailsButton.classList.add('singular');
  }

// Hide the details button if there are no details to show.
  if (loadTimeData.valueExists('summary') &&
          !loadTimeData.getValue('summary').msg) {
    detailsButton.style.display = 'none';
  }

  // Show control buttons.
  if (loadTimeData.valueExists('reloadButton') &&
          loadTimeData.getValue('reloadButton').msg ||
      loadTimeData.valueExists('showSavedCopyButton') &&
          loadTimeData.getValue('showSavedCopyButton').msg) {
    controlButtonDiv.hidden = false;

    // Set the secondary button state in the cases of two call to actions.
    if (loadTimeData.valueExists('reloadButton') &&
            loadTimeData.getValue('reloadButton').msg &&
        loadTimeData.valueExists('showSavedCopyButton') &&
            loadTimeData.getValue('showSavedCopyButton').msg) {
      secondaryButton.classList.add('secondary-button');
    }
  }

  // Add a main message paragraph.
  if (loadTimeData.valueExists('primaryParagraph')) {
    var p = document.querySelector('#main-message p');
    p.innerHTML = loadTimeData.getString('primaryParagraph');
    p.hidden = false;
  }

  // Check for Google cached copy suggestion.
  if (loadTimeData.valueExists('cacheButton')) {
    setUpCachedButton(loadTimeData.getValue('cacheButton'));
  }
}

document.addEventListener('DOMContentLoaded', onDocumentLoad);
</script>
  <script>// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
(function() {
'use strict';
/**
 * T-Rex runner.
 * @param {string} outerContainerId Outer containing element id.
 * @param {Object} opt_config
 * @constructor
 * @export
 */
function Runner(outerContainerId, opt_config) {
  // Singleton
  if (Runner.instance_) {
    return Runner.instance_;
  }
  Runner.instance_ = this;

  this.outerContainerEl = document.querySelector(outerContainerId);
  this.containerEl = null;
  this.snackbarEl = null;
  this.detailsButton = this.outerContainerEl.querySelector('#details-button');

  this.config = opt_config || Runner.config;

  this.dimensions = Runner.defaultDimensions;

  this.canvas = null;
  this.canvasCtx = null;

  this.tRex = null;

  this.distanceMeter = null;
  this.distanceRan = 0;

  this.highestScore = 0;

  this.time = 0;
  this.runningTime = 0;
  this.msPerFrame = 1000 / FPS;
  this.currentSpeed = this.config.SPEED;

  this.obstacles = [];

  this.started = false;
  this.activated = false;
  this.crashed = false;
  this.paused = false;

  this.resizeTimerId_ = null;

  this.playCount = 0;

  // Sound FX.
  this.audioBuffer = null;
  this.soundFx = {};

  // Global web audio context for playing sounds.
  this.audioContext = null;

  // Images.
  this.images = {};
  this.imagesLoaded = 0;

  if (this.isDisabled()) {
    this.setupDisabledRunner();
  } else {
    this.loadImages();
  }
}
window['Runner'] = Runner;


/**
 * Default game width.
 * @const
 */
var DEFAULT_WIDTH = 600;

/**
 * Frames per second.
 * @const
 */
var FPS = 60;

/** @const */
var IS_HIDPI = window.devicePixelRatio > 1;

/** @const */
var IS_IOS = window.navigator.userAgent.indexOf('CriOS') > -1 ||
    window.navigator.userAgent == 'UIWebViewForStaticFileContent';

/** @const */
var IS_MOBILE = window.navigator.userAgent.indexOf('Mobi') > -1 || IS_IOS;

/** @const */
var IS_TOUCH_ENABLED = 'ontouchstart' in window;

/**
 * Default game configuration.
 * @enum {number}
 */
Runner.config = {
  ACCELERATION: 0.001,
  BG_CLOUD_SPEED: 0.2,
  BOTTOM_PAD: 10,
  CLEAR_TIME: 3000,
  CLOUD_FREQUENCY: 0.5,
  GAMEOVER_CLEAR_TIME: 750,
  GAP_COEFFICIENT: 0.6,
  GRAVITY: 0.6,
  INITIAL_JUMP_VELOCITY: 12,
  MAX_CLOUDS: 6,
  MAX_OBSTACLE_LENGTH: 3,
  MAX_OBSTACLE_DUPLICATION: 2,
  MAX_SPEED: 13,
  MIN_JUMP_HEIGHT: 35,
  MOBILE_SPEED_COEFFICIENT: 1.2,
  RESOURCE_TEMPLATE_ID: 'audio-resources',
  SPEED: 6,
  SPEED_DROP_COEFFICIENT: 3
};


/**
 * Default dimensions.
 * @enum {string}
 */
Runner.defaultDimensions = {
  WIDTH: DEFAULT_WIDTH,
  HEIGHT: 150
};


/**
 * CSS class names.
 * @enum {string}
 */
Runner.classes = {
  CANVAS: 'runner-canvas',
  CONTAINER: 'runner-container',
  CRASHED: 'crashed',
  ICON: 'icon-offline',
  SNACKBAR: 'snackbar',
  SNACKBAR_SHOW: 'snackbar-show',
  TOUCH_CONTROLLER: 'controller'
};


/**
 * Sprite definition layout of the spritesheet.
 * @enum {Object}
 */
Runner.spriteDefinition = {
  LDPI: {
    CACTUS_LARGE: {x: 332, y: 2},
    CACTUS_SMALL: {x: 228, y: 2},
    CLOUD: {x: 86, y: 2},
    HORIZON: {x: 2, y: 54},
    PTERODACTYL: {x: 134, y: 2},
    RESTART: {x: 2, y: 2},
    TEXT_SPRITE: {x: 484, y: 2},
    TREX: {x: 677, y: 2}
  },
  HDPI: {
    CACTUS_LARGE: {x: 652,y: 2},
    CACTUS_SMALL: {x: 446,y: 2},
    CLOUD: {x: 166,y: 2},
    HORIZON: {x: 2,y: 104},
    PTERODACTYL: {x: 260,y: 2},
    RESTART: {x: 2,y: 2},
    TEXT_SPRITE: {x: 954,y: 2},
    TREX: {x: 1338,y: 2}
  }
};


/**
 * Sound FX. Reference to the ID of the audio tag on interstitial page.
 * @enum {string}
 */
Runner.sounds = {
  BUTTON_PRESS: 'offline-sound-press',
  HIT: 'offline-sound-hit',
  SCORE: 'offline-sound-reached'
};


/**
 * Key code mapping.
 * @enum {Object}
 */
Runner.keycodes = {
  JUMP: {'38': 1, '32': 1},  // Up, spacebar
  DUCK: {'40': 1},  // Down
  RESTART: {'13': 1}  // Enter
};


/**
 * Runner event names.
 * @enum {string}
 */
Runner.events = {
  ANIM_END: 'webkitAnimationEnd',
  CLICK: 'click',
  KEYDOWN: 'keydown',
  KEYUP: 'keyup',
  MOUSEDOWN: 'mousedown',
  MOUSEUP: 'mouseup',
  RESIZE: 'resize',
  TOUCHEND: 'touchend',
  TOUCHSTART: 'touchstart',
  VISIBILITY: 'visibilitychange',
  BLUR: 'blur',
  FOCUS: 'focus',
  LOAD: 'load'
};


Runner.prototype = {
  /**
   * Whether the easter egg has been disabled. CrOS enterprise enrolled devices.
   * @return {boolean}
   */
  isDisabled: function() {
    return loadTimeData && loadTimeData.valueExists('disabledEasterEgg');
  },

  /**
   * For disabled instances, set up a snackbar with the disabled message.
   */
  setupDisabledRunner: function() {
    this.containerEl = document.createElement('div');
    this.containerEl.className = Runner.classes.SNACKBAR;
    this.containerEl.textContent = loadTimeData.getValue('disabledEasterEgg');
    this.outerContainerEl.appendChild(this.containerEl);

    // Show notification when the activation key is pressed.
    document.addEventListener(Runner.events.KEYDOWN, function(e) {
      if (Runner.keycodes.JUMP[e.keyCode]) {
        this.containerEl.classList.add(Runner.classes.SNACKBAR_SHOW);
        document.querySelector('.icon').classList.add('icon-disabled');
      }
    }.bind(this));
  },

  /**
   * Setting individual settings for debugging.
   * @param {string} setting
   * @param {*} value
   */
  updateConfigSetting: function(setting, value) {
    if (setting in this.config && value != undefined) {
      this.config[setting] = value;

      switch (setting) {
        case 'GRAVITY':
        case 'MIN_JUMP_HEIGHT':
        case 'SPEED_DROP_COEFFICIENT':
          this.tRex.config[setting] = value;
          break;
        case 'INITIAL_JUMP_VELOCITY':
          this.tRex.setJumpVelocity(value);
          break;
        case 'SPEED':
          this.setSpeed(value);
          break;
      }
    }
  },

  /**
   * Cache the appropriate image sprite from the page and get the sprite sheet
   * definition.
   */
  loadImages: function() {
    if (IS_HIDPI) {
      Runner.imageSprite = document.getElementById('offline-resources-2x');
      this.spriteDef = Runner.spriteDefinition.HDPI;
    } else {
      Runner.imageSprite = document.getElementById('offline-resources-1x');
      this.spriteDef = Runner.spriteDefinition.LDPI;
    }

    this.init();
  },

  /**
   * Load and decode base 64 encoded sounds.
   */
  loadSounds: function() {
    if (!IS_IOS) {
      this.audioContext = new AudioContext();

      var resourceTemplate =
          document.getElementById(this.config.RESOURCE_TEMPLATE_ID).content;

      for (var sound in Runner.sounds) {
        var soundSrc =
            resourceTemplate.getElementById(Runner.sounds[sound]).src;
        soundSrc = soundSrc.substr(soundSrc.indexOf(',') + 1);
        var buffer = decodeBase64ToArrayBuffer(soundSrc);

        // Async, so no guarantee of order in array.
        this.audioContext.decodeAudioData(buffer, function(index, audioData) {
            this.soundFx[index] = audioData;
          }.bind(this, sound));
      }
    }
  },

  /**
   * Sets the game speed. Adjust the speed accordingly if on a smaller screen.
   * @param {number} opt_speed
   */
  setSpeed: function(opt_speed) {
    var speed = opt_speed || this.currentSpeed;

    // Reduce the speed on smaller mobile screens.
    if (this.dimensions.WIDTH < DEFAULT_WIDTH) {
      var mobileSpeed = speed * this.dimensions.WIDTH / DEFAULT_WIDTH *
          this.config.MOBILE_SPEED_COEFFICIENT;
      this.currentSpeed = mobileSpeed > speed ? speed : mobileSpeed;
    } else if (opt_speed) {
      this.currentSpeed = opt_speed;
    }
  },

  /**
   * Game initialiser.
   */
  init: function() {
    // Hide the static icon.
    document.querySelector('.' + Runner.classes.ICON).style.visibility =
        'hidden';

    this.adjustDimensions();
    this.setSpeed();

    this.containerEl = document.createElement('div');
    this.containerEl.className = Runner.classes.CONTAINER;

    // Player canvas container.
    this.canvas = createCanvas(this.containerEl, this.dimensions.WIDTH,
        this.dimensions.HEIGHT, Runner.classes.PLAYER);

    this.canvasCtx = this.canvas.getContext('2d');
    this.canvasCtx.fillStyle = '#f7f7f7';
    this.canvasCtx.fill();
    Runner.updateCanvasScaling(this.canvas);

    // Horizon contains clouds, obstacles and the ground.
    this.horizon = new Horizon(this.canvas, this.spriteDef, this.dimensions,
        this.config.GAP_COEFFICIENT);

    // Distance meter
    this.distanceMeter = new DistanceMeter(this.canvas,
          this.spriteDef.TEXT_SPRITE, this.dimensions.WIDTH);

    // Draw t-rex
    this.tRex = new Trex(this.canvas, this.spriteDef.TREX);

    this.outerContainerEl.appendChild(this.containerEl);

    if (IS_MOBILE) {
      this.createTouchController();
    }

    this.startListening();
    this.update();

    window.addEventListener(Runner.events.RESIZE,
        this.debounceResize.bind(this));
  },

  /**
   * Create the touch controller. A div that covers whole screen.
   */
  createTouchController: function() {
    this.touchController = document.createElement('div');
    this.touchController.className = Runner.classes.TOUCH_CONTROLLER;
  },

  /**
   * Debounce the resize event.
   */
  debounceResize: function() {
    if (!this.resizeTimerId_) {
      this.resizeTimerId_ =
          setInterval(this.adjustDimensions.bind(this), 250);
    }
  },

  /**
   * Adjust game space dimensions on resize.
   */
  adjustDimensions: function() {
    clearInterval(this.resizeTimerId_);
    this.resizeTimerId_ = null;

    var boxStyles = window.getComputedStyle(this.outerContainerEl);
    var padding = Number(boxStyles.paddingLeft.substr(0,
        boxStyles.paddingLeft.length - 2));

    this.dimensions.WIDTH = this.outerContainerEl.offsetWidth - padding * 2;

    // Redraw the elements back onto the canvas.
    if (this.canvas) {
      this.canvas.width = this.dimensions.WIDTH;
      this.canvas.height = this.dimensions.HEIGHT;

      Runner.updateCanvasScaling(this.canvas);

      this.distanceMeter.calcXPos(this.dimensions.WIDTH);
      this.clearCanvas();
      this.horizon.update(0, 0, true);
      this.tRex.update(0);

      // Outer container and distance meter.
      if (this.activated || this.crashed) {
        this.containerEl.style.width = this.dimensions.WIDTH + 'px';
        this.containerEl.style.height = this.dimensions.HEIGHT + 'px';
        this.distanceMeter.update(0, Math.ceil(this.distanceRan));
        this.stop();
      } else {
        this.tRex.draw(0, 0);
      }

      // Game over panel.
      if (this.crashed && this.gameOverPanel) {
        this.gameOverPanel.updateDimensions(this.dimensions.WIDTH);
        this.gameOverPanel.draw();
      }
    }
  },

  /**
   * Play the game intro.
   * Canvas container width expands out to the full width.
   */
  playIntro: function() {
    if (!this.started && !this.crashed) {
      this.playingIntro = true;
      this.tRex.playingIntro = true;

      // CSS animation definition.
      var keyframes = '@-webkit-keyframes intro { ' +
            'from { width:' + Trex.config.WIDTH + 'px }' +
            'to { width: ' + this.dimensions.WIDTH + 'px }' +
          '}';
      document.styleSheets[0].insertRule(keyframes, 0);

      this.containerEl.addEventListener(Runner.events.ANIM_END,
          this.startGame.bind(this));

      this.containerEl.style.webkitAnimation = 'intro .4s ease-out 1 both';
      this.containerEl.style.width = this.dimensions.WIDTH + 'px';

      if (this.touchController) {
        this.outerContainerEl.appendChild(this.touchController);
      }
      this.activated = true;
      this.started = true;
    } else if (this.crashed) {
      this.restart();
    }
  },


  /**
   * Update the game status to started.
   */
  startGame: function() {
    this.runningTime = 0;
    this.playingIntro = false;
    this.tRex.playingIntro = false;
    this.containerEl.style.webkitAnimation = '';
    this.playCount++;

    // Handle tabbing off the page. Pause the current game.
    window.addEventListener(Runner.events.VISIBILITY,
          this.onVisibilityChange.bind(this));

    window.addEventListener(Runner.events.BLUR,
          this.onVisibilityChange.bind(this));

    window.addEventListener(Runner.events.FOCUS,
          this.onVisibilityChange.bind(this));
  },

  clearCanvas: function() {
    this.canvasCtx.clearRect(0, 0, this.dimensions.WIDTH,
        this.dimensions.HEIGHT);
  },

  /**
   * Update the game frame.
   */
  update: function() {
    this.drawPending = false;

    var now = getTimeStamp();
    var deltaTime = now - (this.time || now);
    this.time = now;

    if (this.activated) {
      this.clearCanvas();

      if (this.tRex.jumping) {
        this.tRex.updateJump(deltaTime);
      }

      this.runningTime += deltaTime;
      var hasObstacles = this.runningTime > this.config.CLEAR_TIME;

      // First jump triggers the intro.
      if (this.tRex.jumpCount == 1 && !this.playingIntro) {
        this.playIntro();
      }

      // The horizon doesn't move until the intro is over.
      if (this.playingIntro) {
        this.horizon.update(0, this.currentSpeed, hasObstacles);
      } else {
        deltaTime = !this.started ? 0 : deltaTime;
        this.horizon.update(deltaTime, this.currentSpeed, hasObstacles);
      }

      // Check for collisions.
      var collision = hasObstacles &&
          checkForCollision(this.horizon.obstacles[0], this.tRex);

      if (!collision) {
        this.distanceRan += this.currentSpeed * deltaTime / this.msPerFrame;

        if (this.currentSpeed < this.config.MAX_SPEED) {
          this.currentSpeed += this.config.ACCELERATION;
        }
      } else {
        this.gameOver();
      }

      var playAcheivementSound = this.distanceMeter.update(deltaTime,
          Math.ceil(this.distanceRan));

      if (playAcheivementSound) {
        this.playSound(this.soundFx.SCORE);
      }
    }

    if (!this.crashed) {
      this.tRex.update(deltaTime);
      this.raq();
    }
  },

  /**
   * Event handler.
   */
  handleEvent: function(e) {
    return (function(evtType, events) {
      switch (evtType) {
        case events.KEYDOWN:
        case events.TOUCHSTART:
        case events.MOUSEDOWN:
          this.onKeyDown(e);
          break;
        case events.KEYUP:
        case events.TOUCHEND:
        case events.MOUSEUP:
          this.onKeyUp(e);
          break;
      }
    }.bind(this))(e.type, Runner.events);
  },

  /**
   * Bind relevant key / mouse / touch listeners.
   */
  startListening: function() {
    // Keys.
    document.addEventListener(Runner.events.KEYDOWN, this);
    document.addEventListener(Runner.events.KEYUP, this);

    if (IS_MOBILE) {
      // Mobile only touch devices.
      this.touchController.addEventListener(Runner.events.TOUCHSTART, this);
      this.touchController.addEventListener(Runner.events.TOUCHEND, this);
      this.containerEl.addEventListener(Runner.events.TOUCHSTART, this);
    } else {
      // Mouse.
      document.addEventListener(Runner.events.MOUSEDOWN, this);
      document.addEventListener(Runner.events.MOUSEUP, this);
    }
  },

  /**
   * Remove all listeners.
   */
  stopListening: function() {
    document.removeEventListener(Runner.events.KEYDOWN, this);
    document.removeEventListener(Runner.events.KEYUP, this);

    if (IS_MOBILE) {
      this.touchController.removeEventListener(Runner.events.TOUCHSTART, this);
      this.touchController.removeEventListener(Runner.events.TOUCHEND, this);
      this.containerEl.removeEventListener(Runner.events.TOUCHSTART, this);
    } else {
      document.removeEventListener(Runner.events.MOUSEDOWN, this);
      document.removeEventListener(Runner.events.MOUSEUP, this);
    }
  },

  /**
   * Process keydown.
   * @param {Event} e
   */
  onKeyDown: function(e) {
    // Prevent native page scrolling whilst tapping on mobile.
    if (IS_MOBILE) {
      e.preventDefault();
    }

    if (e.target != this.detailsButton) {
      if (!this.crashed && (Runner.keycodes.JUMP[e.keyCode] ||
           e.type == Runner.events.TOUCHSTART)) {
        if (!this.activated) {
          this.loadSounds();
          this.activated = true;
          errorPageController.trackEasterEgg();
        }

        if (!this.tRex.jumping && !this.tRex.ducking) {
          this.playSound(this.soundFx.BUTTON_PRESS);
          this.tRex.startJump(this.currentSpeed);
        }
      }

      if (this.crashed && e.type == Runner.events.TOUCHSTART &&
          e.currentTarget == this.containerEl) {
        this.restart();
      }
    }

    if (this.activated && !this.crashed && Runner.keycodes.DUCK[e.keyCode]) {
      e.preventDefault();
      if (this.tRex.jumping) {
        // Speed drop, activated only when jump key is not pressed.
        this.tRex.setSpeedDrop();
      } else if (!this.tRex.jumping && !this.tRex.ducking) {
        // Duck.
        this.tRex.setDuck(true);
      }
    }
  },


  /**
   * Process key up.
   * @param {Event} e
   */
  onKeyUp: function(e) {
    var keyCode = String(e.keyCode);
    var isjumpKey = Runner.keycodes.JUMP[keyCode] ||
       e.type == Runner.events.TOUCHEND ||
       e.type == Runner.events.MOUSEDOWN;

    if (this.isRunning() && isjumpKey) {
      this.tRex.endJump();
    } else if (Runner.keycodes.DUCK[keyCode]) {
      this.tRex.speedDrop = false;
      this.tRex.setDuck(false);
    } else if (this.crashed) {
      // Check that enough time has elapsed before allowing jump key to restart.
      var deltaTime = getTimeStamp() - this.time;

      if (Runner.keycodes.RESTART[keyCode] || this.isLeftClickOnCanvas(e) ||
          (deltaTime >= this.config.GAMEOVER_CLEAR_TIME &&
          Runner.keycodes.JUMP[keyCode])) {
        this.restart();
      }
    } else if (this.paused && isjumpKey) {
      // Reset the jump state
      this.tRex.reset();
      this.play();
    }
  },

  /**
   * Returns whether the event was a left click on canvas.
   * On Windows right click is registered as a click.
   * @param {Event} e
   * @return {boolean}
   */
  isLeftClickOnCanvas: function(e) {
    return e.button != null && e.button < 2 &&
        e.type == Runner.events.MOUSEUP && e.target == this.canvas;
  },

  /**
   * RequestAnimationFrame wrapper.
   */
  raq: function() {
    if (!this.drawPending) {
      this.drawPending = true;
      this.raqId = requestAnimationFrame(this.update.bind(this));
    }
  },

  /**
   * Whether the game is running.
   * @return {boolean}
   */
  isRunning: function() {
    return !!this.raqId;
  },

  /**
   * Game over state.
   */
  gameOver: function() {
    this.playSound(this.soundFx.HIT);
    vibrate(200);

    this.stop();
    this.crashed = true;
    this.distanceMeter.acheivement = false;

    this.tRex.update(100, Trex.status.CRASHED);

    // Game over panel.
    if (!this.gameOverPanel) {
      this.gameOverPanel = new GameOverPanel(this.canvas,
          this.spriteDef.TEXT_SPRITE, this.spriteDef.RESTART,
          this.dimensions);
    } else {
      this.gameOverPanel.draw();
    }

    // Update the high score.
    if (this.distanceRan > this.highestScore) {
      this.highestScore = Math.ceil(this.distanceRan);
      this.distanceMeter.setHighScore(this.highestScore);
    }

    // Reset the time clock.
    this.time = getTimeStamp();
  },

  stop: function() {
    this.activated = false;
    this.paused = true;
    cancelAnimationFrame(this.raqId);
    this.raqId = 0;
  },

  play: function() {
    if (!this.crashed) {
      this.activated = true;
      this.paused = false;
      this.tRex.update(0, Trex.status.RUNNING);
      this.time = getTimeStamp();
      this.update();
    }
  },

  restart: function() {
    if (!this.raqId) {
      this.playCount++;
      this.runningTime = 0;
      this.activated = true;
      this.crashed = false;
      this.distanceRan = 0;
      this.setSpeed(this.config.SPEED);

      this.time = getTimeStamp();
      this.containerEl.classList.remove(Runner.classes.CRASHED);
      this.clearCanvas();
      this.distanceMeter.reset(this.highestScore);
      this.horizon.reset();
      this.tRex.reset();
      this.playSound(this.soundFx.BUTTON_PRESS);

      this.update();
    }
  },

  /**
   * Pause the game if the tab is not in focus.
   */
  onVisibilityChange: function(e) {
    if (document.hidden || document.webkitHidden || e.type == 'blur') {
      this.stop();
    } else if (!this.crashed) {
      this.tRex.reset();
      this.play();
    }
  },

  /**
   * Play a sound.
   * @param {SoundBuffer} soundBuffer
   */
  playSound: function(soundBuffer) {
    if (soundBuffer) {
      var sourceNode = this.audioContext.createBufferSource();
      sourceNode.buffer = soundBuffer;
      sourceNode.connect(this.audioContext.destination);
      sourceNode.start(0);
    }
  }
};


/**
 * Updates the canvas size taking into
 * account the backing store pixel ratio and
 * the device pixel ratio.
 *
 * See article by Paul Lewis:
 * http://www.html5rocks.com/en/tutorials/canvas/hidpi/
 *
 * @param {HTMLCanvasElement} canvas
 * @param {number} opt_width
 * @param {number} opt_height
 * @return {boolean} Whether the canvas was scaled.
 */
Runner.updateCanvasScaling = function(canvas, opt_width, opt_height) {
  var context = canvas.getContext('2d');

  // Query the various pixel ratios
  var devicePixelRatio = Math.floor(window.devicePixelRatio) || 1;
  var backingStoreRatio = Math.floor(context.webkitBackingStorePixelRatio) || 1;
  var ratio = devicePixelRatio / backingStoreRatio;

  // Upscale the canvas if the two ratios don't match
  if (devicePixelRatio !== backingStoreRatio) {
    var oldWidth = opt_width || canvas.width;
    var oldHeight = opt_height || canvas.height;

    canvas.width = oldWidth * ratio;
    canvas.height = oldHeight * ratio;

    canvas.style.width = oldWidth + 'px';
    canvas.style.height = oldHeight + 'px';

    // Scale the context to counter the fact that we've manually scaled
    // our canvas element.
    context.scale(ratio, ratio);
    return true;
  } else if (devicePixelRatio == 1) {
    // Reset the canvas width / height. Fixes scaling bug when the page is
    // zoomed and the devicePixelRatio changes accordingly.
    canvas.style.width = canvas.width + 'px';
    canvas.style.height = canvas.height + 'px';
  }
  return false;
};


/**
 * Get random number.
 * @param {number} min
 * @param {number} max
 * @param {number}
 */
function getRandomNum(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}


/**
 * Vibrate on mobile devices.
 * @param {number} duration Duration of the vibration in milliseconds.
 */
function vibrate(duration) {
  if (IS_MOBILE && window.navigator.vibrate) {
    window.navigator.vibrate(duration);
  }
}


/**
 * Create canvas element.
 * @param {HTMLElement} container Element to append canvas to.
 * @param {number} width
 * @param {number} height
 * @param {string} opt_classname
 * @return {HTMLCanvasElement}
 */
function createCanvas(container, width, height, opt_classname) {
  var canvas = document.createElement('canvas');
  canvas.className = opt_classname ? Runner.classes.CANVAS + ' ' +
      opt_classname : Runner.classes.CANVAS;
  canvas.width = width;
  canvas.height = height;
  container.appendChild(canvas);

  return canvas;
}


/**
 * Decodes the base 64 audio to ArrayBuffer used by Web Audio.
 * @param {string} base64String
 */
function decodeBase64ToArrayBuffer(base64String) {
  var len = (base64String.length / 4) * 3;
  var str = atob(base64String);
  var arrayBuffer = new ArrayBuffer(len);
  var bytes = new Uint8Array(arrayBuffer);

  for (var i = 0; i < len; i++) {
    bytes[i] = str.charCodeAt(i);
  }
  return bytes.buffer;
}


/**
 * Return the current timestamp.
 * @return {number}
 */
function getTimeStamp() {
  return IS_IOS ? new Date().getTime() : performance.now();
}


//******************************************************************************


/**
 * Game over panel.
 * @param {!HTMLCanvasElement} canvas
 * @param {Object} textImgPos
 * @param {Object} restartImgPos
 * @param {!Object} dimensions Canvas dimensions.
 * @constructor
 */
function GameOverPanel(canvas, textImgPos, restartImgPos, dimensions) {
  this.canvas = canvas;
  this.canvasCtx = canvas.getContext('2d');
  this.canvasDimensions = dimensions;
  this.textImgPos = textImgPos;
  this.restartImgPos = restartImgPos;
  this.draw();
};


/**
 * Dimensions used in the panel.
 * @enum {number}
 */
GameOverPanel.dimensions = {
  TEXT_X: 0,
  TEXT_Y: 13,
  TEXT_WIDTH: 191,
  TEXT_HEIGHT: 11,
  RESTART_WIDTH: 36,
  RESTART_HEIGHT: 32
};


GameOverPanel.prototype = {
  /**
   * Update the panel dimensions.
   * @param {number} width New canvas width.
   * @param {number} opt_height Optional new canvas height.
   */
  updateDimensions: function(width, opt_height) {
    this.canvasDimensions.WIDTH = width;
    if (opt_height) {
      this.canvasDimensions.HEIGHT = opt_height;
    }
  },

  /**
   * Draw the panel.
   */
  draw: function() {
    var dimensions = GameOverPanel.dimensions;

    var centerX = this.canvasDimensions.WIDTH / 2;

    // Game over text.
    var textSourceX = dimensions.TEXT_X;
    var textSourceY = dimensions.TEXT_Y;
    var textSourceWidth = dimensions.TEXT_WIDTH;
    var textSourceHeight = dimensions.TEXT_HEIGHT;

    var textTargetX = Math.round(centerX - (dimensions.TEXT_WIDTH / 2));
    var textTargetY = Math.round((this.canvasDimensions.HEIGHT - 25) / 3);
    var textTargetWidth = dimensions.TEXT_WIDTH;
    var textTargetHeight = dimensions.TEXT_HEIGHT;

    var restartSourceWidth = dimensions.RESTART_WIDTH;
    var restartSourceHeight = dimensions.RESTART_HEIGHT;
    var restartTargetX = centerX - (dimensions.RESTART_WIDTH / 2);
    var restartTargetY = this.canvasDimensions.HEIGHT / 2;

    if (IS_HIDPI) {
      textSourceY *= 2;
      textSourceX *= 2;
      textSourceWidth *= 2;
      textSourceHeight *= 2;
      restartSourceWidth *= 2;
      restartSourceHeight *= 2;
    }

    textSourceX += this.textImgPos.x;
    textSourceY += this.textImgPos.y;

    // Game over text from sprite.
    this.canvasCtx.drawImage(Runner.imageSprite,
        textSourceX, textSourceY, textSourceWidth, textSourceHeight,
        textTargetX, textTargetY, textTargetWidth, textTargetHeight);

    // Restart button.
    this.canvasCtx.drawImage(Runner.imageSprite,
        this.restartImgPos.x, this.restartImgPos.y,
        restartSourceWidth, restartSourceHeight,
        restartTargetX, restartTargetY, dimensions.RESTART_WIDTH,
        dimensions.RESTART_HEIGHT);
  }
};


//******************************************************************************

/**
 * Check for a collision.
 * @param {!Obstacle} obstacle
 * @param {!Trex} tRex T-rex object.
 * @param {HTMLCanvasContext} opt_canvasCtx Optional canvas context for drawing
 *    collision boxes.
 * @return {Array<CollisionBox>}
 */
function checkForCollision(obstacle, tRex, opt_canvasCtx) {
  var obstacleBoxXPos = Runner.defaultDimensions.WIDTH + obstacle.xPos;

  // Adjustments are made to the bounding box as there is a 1 pixel white
  // border around the t-rex and obstacles.
  var tRexBox = new CollisionBox(
      tRex.xPos + 1,
      tRex.yPos + 1,
      tRex.config.WIDTH - 2,
      tRex.config.HEIGHT - 2);

  var obstacleBox = new CollisionBox(
      obstacle.xPos + 1,
      obstacle.yPos + 1,
      obstacle.typeConfig.width * obstacle.size - 2,
      obstacle.typeConfig.height - 2);

  // Debug outer box
  if (opt_canvasCtx) {
    drawCollisionBoxes(opt_canvasCtx, tRexBox, obstacleBox);
  }

  // Simple outer bounds check.
  if (boxCompare(tRexBox, obstacleBox)) {
    var collisionBoxes = obstacle.collisionBoxes;
    var tRexCollisionBoxes = tRex.ducking ?
        Trex.collisionBoxes.DUCKING : Trex.collisionBoxes.RUNNING;

    // Detailed axis aligned box check.
    for (var t = 0; t < tRexCollisionBoxes.length; t++) {
      for (var i = 0; i < collisionBoxes.length; i++) {
        // Adjust the box to actual positions.
        var adjTrexBox =
            createAdjustedCollisionBox(tRexCollisionBoxes[t], tRexBox);
        var adjObstacleBox =
            createAdjustedCollisionBox(collisionBoxes[i], obstacleBox);
        var crashed = boxCompare(adjTrexBox, adjObstacleBox);

        // Draw boxes for debug.
        if (opt_canvasCtx) {
          drawCollisionBoxes(opt_canvasCtx, adjTrexBox, adjObstacleBox);
        }

        if (crashed) {
          return [adjTrexBox, adjObstacleBox];
        }
      }
    }
  }
  return false;
};


/**
 * Adjust the collision box.
 * @param {!CollisionBox} box The original box.
 * @param {!CollisionBox} adjustment Adjustment box.
 * @return {CollisionBox} The adjusted collision box object.
 */
function createAdjustedCollisionBox(box, adjustment) {
  return new CollisionBox(
      box.x + adjustment.x,
      box.y + adjustment.y,
      box.width,
      box.height);
};


/**
 * Draw the collision boxes for debug.
 */
function drawCollisionBoxes(canvasCtx, tRexBox, obstacleBox) {
  canvasCtx.save();
  canvasCtx.strokeStyle = '#f00';
  canvasCtx.strokeRect(tRexBox.x, tRexBox.y, tRexBox.width, tRexBox.height);

  canvasCtx.strokeStyle = '#0f0';
  canvasCtx.strokeRect(obstacleBox.x, obstacleBox.y,
      obstacleBox.width, obstacleBox.height);
  canvasCtx.restore();
};


/**
 * Compare two collision boxes for a collision.
 * @param {CollisionBox} tRexBox
 * @param {CollisionBox} obstacleBox
 * @return {boolean} Whether the boxes intersected.
 */
function boxCompare(tRexBox, obstacleBox) {
  var crashed = false;
  var tRexBoxX = tRexBox.x;
  var tRexBoxY = tRexBox.y;

  var obstacleBoxX = obstacleBox.x;
  var obstacleBoxY = obstacleBox.y;

  // Axis-Aligned Bounding Box method.
  if (tRexBox.x < obstacleBoxX + obstacleBox.width &&
      tRexBox.x + tRexBox.width > obstacleBoxX &&
      tRexBox.y < obstacleBox.y + obstacleBox.height &&
      tRexBox.height + tRexBox.y > obstacleBox.y) {
    crashed = true;
  }

  return crashed;
};


//******************************************************************************

/**
 * Collision box object.
 * @param {number} x X position.
 * @param {number} y Y Position.
 * @param {number} w Width.
 * @param {number} h Height.
 */
function CollisionBox(x, y, w, h) {
  this.x = x;
  this.y = y;
  this.width = w;
  this.height = h;
};


//******************************************************************************

/**
 * Obstacle.
 * @param {HTMLCanvasCtx} canvasCtx
 * @param {Obstacle.type} type
 * @param {Object} spritePos Obstacle position in sprite.
 * @param {Object} dimensions
 * @param {number} gapCoefficient Mutipler in determining the gap.
 * @param {number} speed
 */
function Obstacle(canvasCtx, type, spriteImgPos, dimensions,
    gapCoefficient, speed) {

  this.canvasCtx = canvasCtx;
  this.spritePos = spriteImgPos;
  this.typeConfig = type;
  this.gapCoefficient = gapCoefficient;
  this.size = getRandomNum(1, Obstacle.MAX_OBSTACLE_LENGTH);
  this.dimensions = dimensions;
  this.remove = false;
  this.xPos = 0;
  this.yPos = 0;
  this.width = 0;
  this.collisionBoxes = [];
  this.gap = 0;
  this.speedOffset = 0;

  // For animated obstacles.
  this.currentFrame = 0;
  this.timer = 0;

  this.init(speed);
};

/**
 * Coefficient for calculating the maximum gap.
 * @const
 */
Obstacle.MAX_GAP_COEFFICIENT = 1.5;

/**
 * Maximum obstacle grouping count.
 * @const
 */
Obstacle.MAX_OBSTACLE_LENGTH = 3,


Obstacle.prototype = {
  /**
   * Initialise the DOM for the obstacle.
   * @param {number} speed
   */
  init: function(speed) {
    this.cloneCollisionBoxes();

    // Only allow sizing if we're at the right speed.
    if (this.size > 1 && this.typeConfig.multipleSpeed > speed) {
      this.size = 1;
    }

    this.width = this.typeConfig.width * this.size;
    this.xPos = this.dimensions.WIDTH - this.width;

    // Check if obstacle can be positioned at various heights.
    if (Array.isArray(this.typeConfig.yPos))  {
      var yPosConfig = IS_MOBILE ? this.typeConfig.yPosMobile :
          this.typeConfig.yPos;
      this.yPos = yPosConfig[getRandomNum(0, yPosConfig.length - 1)];
    } else {
      this.yPos = this.typeConfig.yPos;
    }

    this.draw();

    // Make collision box adjustments,
    // Central box is adjusted to the size as one box.
    //      ____        ______        ________
    //    _|   |-|    _|     |-|    _|       |-|
    //   | |<->| |   | |<--->| |   | |<----->| |
    //   | | 1 | |   | |  2  | |   | |   3   | |
    //   |_|___|_|   |_|_____|_|   |_|_______|_|
    //
    if (this.size > 1) {
      this.collisionBoxes[1].width = this.width - this.collisionBoxes[0].width -
          this.collisionBoxes[2].width;
      this.collisionBoxes[2].x = this.width - this.collisionBoxes[2].width;
    }

    // For obstacles that go at a different speed from the horizon.
    if (this.typeConfig.speedOffset) {
      this.speedOffset = Math.random() > 0.5 ? this.typeConfig.speedOffset :
          -this.typeConfig.speedOffset;
    }

    this.gap = this.getGap(this.gapCoefficient, speed);
  },

  /**
   * Draw and crop based on size.
   */
  draw: function() {
    var sourceWidth = this.typeConfig.width;
    var sourceHeight = this.typeConfig.height;

    if (IS_HIDPI) {
      sourceWidth = sourceWidth * 2;
      sourceHeight = sourceHeight * 2;
    }

    // X position in sprite.
    var sourceX = (sourceWidth * this.size) * (0.5 * (this.size - 1)) +
        this.spritePos.x;

    // Animation frames.
    if (this.currentFrame > 0) {
      sourceX += sourceWidth * this.currentFrame;
    }

    this.canvasCtx.drawImage(Runner.imageSprite,
      sourceX, this.spritePos.y,
      sourceWidth * this.size, sourceHeight,
      this.xPos, this.yPos,
      this.typeConfig.width * this.size, this.typeConfig.height);
  },

  /**
   * Obstacle frame update.
   * @param {number} deltaTime
   * @param {number} speed
   */
  update: function(deltaTime, speed) {
    if (!this.remove) {
      if (this.typeConfig.speedOffset) {
        speed += this.speedOffset;
      }
      this.xPos -= Math.floor((speed * FPS / 1000) * deltaTime);

      // Update frame
      if (this.typeConfig.numFrames) {
        this.timer += deltaTime;
        if (this.timer >= this.typeConfig.frameRate) {
          this.currentFrame =
              this.currentFrame == this.typeConfig.numFrames - 1 ?
              0 : this.currentFrame + 1;
          this.timer = 0;
        }
      }
      this.draw();

      if (!this.isVisible()) {
        this.remove = true;
      }
    }
  },

  /**
   * Calculate a random gap size.
   * - Minimum gap gets wider as speed increses
   * @param {number} gapCoefficient
   * @param {number} speed
   * @return {number} The gap size.
   */
  getGap: function(gapCoefficient, speed) {
    var minGap = Math.round(this.width * speed +
          this.typeConfig.minGap * gapCoefficient);
    var maxGap = Math.round(minGap * Obstacle.MAX_GAP_COEFFICIENT);
    return getRandomNum(minGap, maxGap);
  },

  /**
   * Check if obstacle is visible.
   * @return {boolean} Whether the obstacle is in the game area.
   */
  isVisible: function() {
    return this.xPos + this.width > 0;
  },

  /**
   * Make a copy of the collision boxes, since these will change based on
   * obstacle type and size.
   */
  cloneCollisionBoxes: function() {
    var collisionBoxes = this.typeConfig.collisionBoxes;

    for (var i = collisionBoxes.length - 1; i >= 0; i--) {
      this.collisionBoxes[i] = new CollisionBox(collisionBoxes[i].x,
          collisionBoxes[i].y, collisionBoxes[i].width,
          collisionBoxes[i].height);
    }
  }
};


/**
 * Obstacle definitions.
 * minGap: minimum pixel space betweeen obstacles.
 * multipleSpeed: Speed at which multiples are allowed.
 * speedOffset: speed faster / slower than the horizon.
 * minSpeed: Minimum speed which the obstacle can make an appearance.
 */
Obstacle.types = [
  {
    type: 'CACTUS_SMALL',
    width: 17,
    height: 35,
    yPos: 105,
    multipleSpeed: 4,
    minGap: 120,
    minSpeed: 0,
    collisionBoxes: [
      new CollisionBox(0, 7, 5, 27),
      new CollisionBox(4, 0, 6, 34),
      new CollisionBox(10, 4, 7, 14)
    ]
  },
  {
    type: 'CACTUS_LARGE',
    width: 25,
    height: 50,
    yPos: 90,
    multipleSpeed: 7,
    minGap: 120,
    minSpeed: 0,
    collisionBoxes: [
      new CollisionBox(0, 12, 7, 38),
      new CollisionBox(8, 0, 7, 49),
      new CollisionBox(13, 10, 10, 38)
    ]
  },
  {
    type: 'PTERODACTYL',
    width: 46,
    height: 40,
    yPos: [ 100, 75, 50 ], // Variable height.
    yPosMobile: [ 100, 50 ], // Variable height mobile.
    multipleSpeed: 999,
    minSpeed: 8.5,
    minGap: 150,
    collisionBoxes: [
      new CollisionBox(15, 15, 16, 5),
      new CollisionBox(18, 21, 24, 6),
      new CollisionBox(2, 14, 4, 3),
      new CollisionBox(6, 10, 4, 7),
      new CollisionBox(10, 8, 6, 9)
    ],
    numFrames: 2,
    frameRate: 1000/6,
    speedOffset: .8
  }
];


//******************************************************************************
/**
 * T-rex game character.
 * @param {HTMLCanvas} canvas
 * @param {Object} spritePos Positioning within image sprite.
 * @constructor
 */
function Trex(canvas, spritePos) {
  this.canvas = canvas;
  this.canvasCtx = canvas.getContext('2d');
  this.spritePos = spritePos;
  this.xPos = 0;
  this.yPos = 0;
  // Position when on the ground.
  this.groundYPos = 0;
  this.currentFrame = 0;
  this.currentAnimFrames = [];
  this.blinkDelay = 0;
  this.animStartTime = 0;
  this.timer = 0;
  this.msPerFrame = 1000 / FPS;
  this.config = Trex.config;
  // Current status.
  this.status = Trex.status.WAITING;

  this.jumping = false;
  this.ducking = false;
  this.jumpVelocity = 0;
  this.reachedMinHeight = false;
  this.speedDrop = false;
  this.jumpCount = 0;
  this.jumpspotX = 0;

  this.init();
};


/**
 * T-rex player config.
 * @enum {number}
 */
Trex.config = {
  DROP_VELOCITY: -5,
  GRAVITY: 0.6,
  HEIGHT: 47,
  HEIGHT_DUCK: 25,
  INIITAL_JUMP_VELOCITY: -10,
  INTRO_DURATION: 1500,
  MAX_JUMP_HEIGHT: 30,
  MIN_JUMP_HEIGHT: 30,
  SPEED_DROP_COEFFICIENT: 3,
  SPRITE_WIDTH: 262,
  START_X_POS: 50,
  WIDTH: 44,
  WIDTH_DUCK: 59
};


/**
 * Used in collision detection.
 * @type {Array<CollisionBox>}
 */
Trex.collisionBoxes = {
  DUCKING: [
    new CollisionBox(1, 18, 55, 25)
  ],
  RUNNING: [
    new CollisionBox(22, 0, 17, 16),
    new CollisionBox(1, 18, 30, 9),
    new CollisionBox(10, 35, 14, 8),
    new CollisionBox(1, 24, 29, 5),
    new CollisionBox(5, 30, 21, 4),
    new CollisionBox(9, 34, 15, 4)
  ]
};


/**
 * Animation states.
 * @enum {string}
 */
Trex.status = {
  CRASHED: 'CRASHED',
  DUCKING: 'DUCKING',
  JUMPING: 'JUMPING',
  RUNNING: 'RUNNING',
  WAITING: 'WAITING'
};

/**
 * Blinking coefficient.
 * @const
 */
Trex.BLINK_TIMING = 7000;


/**
 * Animation config for different states.
 * @enum {Object}
 */
Trex.animFrames = {
  WAITING: {
    frames: [44, 0],
    msPerFrame: 1000 / 3
  },
  RUNNING: {
    frames: [88, 132],
    msPerFrame: 1000 / 12
  },
  CRASHED: {
    frames: [220],
    msPerFrame: 1000 / 60
  },
  JUMPING: {
    frames: [0],
    msPerFrame: 1000 / 60
  },
  DUCKING: {
    frames: [262, 321],
    msPerFrame: 1000 / 8
  }
};


Trex.prototype = {
  /**
   * T-rex player initaliser.
   * Sets the t-rex to blink at random intervals.
   */
  init: function() {
    this.blinkDelay = this.setBlinkDelay();
    this.groundYPos = Runner.defaultDimensions.HEIGHT - this.config.HEIGHT -
        Runner.config.BOTTOM_PAD;
    this.yPos = this.groundYPos;
    this.minJumpHeight = this.groundYPos - this.config.MIN_JUMP_HEIGHT;

    this.draw(0, 0);
    this.update(0, Trex.status.WAITING);
  },

  /**
   * Setter for the jump velocity.
   * The approriate drop velocity is also set.
   */
  setJumpVelocity: function(setting) {
    this.config.INIITAL_JUMP_VELOCITY = -setting;
    this.config.DROP_VELOCITY = -setting / 2;
  },

  /**
   * Set the animation status.
   * @param {!number} deltaTime
   * @param {Trex.status} status Optional status to switch to.
   */
  update: function(deltaTime, opt_status) {
    this.timer += deltaTime;

    // Update the status.
    if (opt_status) {
      this.status = opt_status;
      this.currentFrame = 0;
      this.msPerFrame = Trex.animFrames[opt_status].msPerFrame;
      this.currentAnimFrames = Trex.animFrames[opt_status].frames;

      if (opt_status == Trex.status.WAITING) {
        this.animStartTime = getTimeStamp();
        this.setBlinkDelay();
      }
    }

    // Game intro animation, T-rex moves in from the left.
    if (this.playingIntro && this.xPos < this.config.START_X_POS) {
      this.xPos += Math.round((this.config.START_X_POS /
          this.config.INTRO_DURATION) * deltaTime);
    }

    if (this.status == Trex.status.WAITING) {
      this.blink(getTimeStamp());
    } else {
      this.draw(this.currentAnimFrames[this.currentFrame], 0);
    }

    // Update the frame position.
    if (this.timer >= this.msPerFrame) {
      this.currentFrame = this.currentFrame ==
          this.currentAnimFrames.length - 1 ? 0 : this.currentFrame + 1;
      this.timer = 0;
    }

    // Speed drop becomes duck if the down key is still being pressed.
    if (this.speedDrop && this.yPos == this.groundYPos) {
      this.speedDrop = false;
      this.setDuck(true);
    }
  },

  /**
   * Draw the t-rex to a particular position.
   * @param {number} x
   * @param {number} y
   */
  draw: function(x, y) {
    var sourceX = x;
    var sourceY = y;
    var sourceWidth = this.ducking && this.status != Trex.status.CRASHED ?
        this.config.WIDTH_DUCK : this.config.WIDTH;
    var sourceHeight = this.config.HEIGHT;

    if (IS_HIDPI) {
      sourceX *= 2;
      sourceY *= 2;
      sourceWidth *= 2;
      sourceHeight *= 2;
    }

    // Adjustments for sprite sheet position.
    sourceX += this.spritePos.x;
    sourceY += this.spritePos.y;

    // Ducking.
    if (this.ducking && this.status != Trex.status.CRASHED) {
      this.canvasCtx.drawImage(Runner.imageSprite, sourceX, sourceY,
          sourceWidth, sourceHeight,
          this.xPos, this.yPos,
          this.config.WIDTH_DUCK, this.config.HEIGHT);
    } else {
      // Crashed whilst ducking. Trex is standing up so needs adjustment.
      if (this.ducking && this.status == Trex.status.CRASHED) {
        this.xPos++;
      }
      // Standing / running
      this.canvasCtx.drawImage(Runner.imageSprite, sourceX, sourceY,
          sourceWidth, sourceHeight,
          this.xPos, this.yPos,
          this.config.WIDTH, this.config.HEIGHT);
    }
  },

  /**
   * Sets a random time for the blink to happen.
   */
  setBlinkDelay: function() {
    this.blinkDelay = Math.ceil(Math.random() * Trex.BLINK_TIMING);
  },

  /**
   * Make t-rex blink at random intervals.
   * @param {number} time Current time in milliseconds.
   */
  blink: function(time) {
    var deltaTime = time - this.animStartTime;

    if (deltaTime >= this.blinkDelay) {
      this.draw(this.currentAnimFrames[this.currentFrame], 0);

      if (this.currentFrame == 1) {
        // Set new random delay to blink.
        this.setBlinkDelay();
        this.animStartTime = time;
      }
    }
  },

  /**
   * Initialise a jump.
   * @param {number} speed
   */
  startJump: function(speed) {
    if (!this.jumping) {
      this.update(0, Trex.status.JUMPING);
      // Tweak the jump velocity based on the speed.
      this.jumpVelocity = this.config.INIITAL_JUMP_VELOCITY - (speed / 10);
      this.jumping = true;
      this.reachedMinHeight = false;
      this.speedDrop = false;
    }
  },

  /**
   * Jump is complete, falling down.
   */
  endJump: function() {
    if (this.reachedMinHeight &&
        this.jumpVelocity < this.config.DROP_VELOCITY) {
      this.jumpVelocity = this.config.DROP_VELOCITY;
    }
  },

  /**
   * Update frame for a jump.
   * @param {number} deltaTime
   * @param {number} speed
   */
  updateJump: function(deltaTime, speed) {
    var msPerFrame = Trex.animFrames[this.status].msPerFrame;
    var framesElapsed = deltaTime / msPerFrame;

    // Speed drop makes Trex fall faster.
    if (this.speedDrop) {
      this.yPos += Math.round(this.jumpVelocity *
          this.config.SPEED_DROP_COEFFICIENT * framesElapsed);
    } else {
      this.yPos += Math.round(this.jumpVelocity * framesElapsed);
    }

    this.jumpVelocity += this.config.GRAVITY * framesElapsed;

    // Minimum height has been reached.
    if (this.yPos < this.minJumpHeight || this.speedDrop) {
      this.reachedMinHeight = true;
    }

    // Reached max height
    if (this.yPos < this.config.MAX_JUMP_HEIGHT || this.speedDrop) {
      this.endJump();
    }

    // Back down at ground level. Jump completed.
    if (this.yPos > this.groundYPos) {
      this.reset();
      this.jumpCount++;
    }

    this.update(deltaTime);
  },

  /**
   * Set the speed drop. Immediately cancels the current jump.
   */
  setSpeedDrop: function() {
    this.speedDrop = true;
    this.jumpVelocity = 1;
  },

  /**
   * @param {boolean} isDucking.
   */
  setDuck: function(isDucking) {
    if (isDucking && this.status != Trex.status.DUCKING) {
      this.update(0, Trex.status.DUCKING);
      this.ducking = true;
    } else if (this.status == Trex.status.DUCKING) {
      this.update(0, Trex.status.RUNNING);
      this.ducking = false;
    }
  },

  /**
   * Reset the t-rex to running at start of game.
   */
  reset: function() {
    this.yPos = this.groundYPos;
    this.jumpVelocity = 0;
    this.jumping = false;
    this.ducking = false;
    this.update(0, Trex.status.RUNNING);
    this.midair = false;
    this.speedDrop = false;
    this.jumpCount = 0;
  }
};


//******************************************************************************

/**
 * Handles displaying the distance meter.
 * @param {!HTMLCanvasElement} canvas
 * @param {Object} spritePos Image position in sprite.
 * @param {number} canvasWidth
 * @constructor
 */
function DistanceMeter(canvas, spritePos, canvasWidth) {
  this.canvas = canvas;
  this.canvasCtx = canvas.getContext('2d');
  this.image = Runner.imageSprite;
  this.spritePos = spritePos;
  this.x = 0;
  this.y = 5;

  this.currentDistance = 0;
  this.maxScore = 0;
  this.highScore = 0;
  this.container = null;

  this.digits = [];
  this.acheivement = false;
  this.defaultString = '';
  this.flashTimer = 0;
  this.flashIterations = 0;

  this.config = DistanceMeter.config;
  this.maxScoreUnits = this.config.MAX_DISTANCE_UNITS;
  this.init(canvasWidth);
};


/**
 * @enum {number}
 */
DistanceMeter.dimensions = {
  WIDTH: 10,
  HEIGHT: 13,
  DEST_WIDTH: 11
};


/**
 * Y positioning of the digits in the sprite sheet.
 * X position is always 0.
 * @type {Array<number>}
 */
DistanceMeter.yPos = [0, 13, 27, 40, 53, 67, 80, 93, 107, 120];


/**
 * Distance meter config.
 * @enum {number}
 */
DistanceMeter.config = {
  // Number of digits.
  MAX_DISTANCE_UNITS: 5,

  // Distance that causes achievement animation.
  ACHIEVEMENT_DISTANCE: 100,

  // Used for conversion from pixel distance to a scaled unit.
  COEFFICIENT: 0.025,

  // Flash duration in milliseconds.
  FLASH_DURATION: 1000 / 4,

  // Flash iterations for achievement animation.
  FLASH_ITERATIONS: 3
};


DistanceMeter.prototype = {
  /**
   * Initialise the distance meter to '00000'.
   * @param {number} width Canvas width in px.
   */
  init: function(width) {
    var maxDistanceStr = '';

    this.calcXPos(width);
    this.maxScore = this.maxScoreUnits;
    for (var i = 0; i < this.maxScoreUnits; i++) {
      this.draw(i, 0);
      this.defaultString += '0';
      maxDistanceStr += '9';
    }

    this.maxScore = parseInt(maxDistanceStr);
  },

  /**
   * Calculate the xPos in the canvas.
   * @param {number} canvasWidth
   */
  calcXPos: function(canvasWidth) {
    this.x = canvasWidth - (DistanceMeter.dimensions.DEST_WIDTH *
        (this.maxScoreUnits + 1));
  },

  /**
   * Draw a digit to canvas.
   * @param {number} digitPos Position of the digit.
   * @param {number} value Digit value 0-9.
   * @param {boolean} opt_highScore Whether drawing the high score.
   */
  draw: function(digitPos, value, opt_highScore) {
    var sourceWidth = DistanceMeter.dimensions.WIDTH;
    var sourceHeight = DistanceMeter.dimensions.HEIGHT;
    var sourceX = DistanceMeter.dimensions.WIDTH * value;
    var sourceY = 0;

    var targetX = digitPos * DistanceMeter.dimensions.DEST_WIDTH;
    var targetY = this.y;
    var targetWidth = DistanceMeter.dimensions.WIDTH;
    var targetHeight = DistanceMeter.dimensions.HEIGHT;

    // For high DPI we 2x source values.
    if (IS_HIDPI) {
      sourceWidth *= 2;
      sourceHeight *= 2;
      sourceX *= 2;
    }

    sourceX += this.spritePos.x;
    sourceY += this.spritePos.y;

    this.canvasCtx.save();

    if (opt_highScore) {
      // Left of the current score.
      var highScoreX = this.x - (this.maxScoreUnits * 2) *
          DistanceMeter.dimensions.WIDTH;
      this.canvasCtx.translate(highScoreX, this.y);
    } else {
      this.canvasCtx.translate(this.x, this.y);
    }

    this.canvasCtx.drawImage(this.image, sourceX, sourceY,
        sourceWidth, sourceHeight,
        targetX, targetY,
        targetWidth, targetHeight
      );

    this.canvasCtx.restore();
  },

  /**
   * Covert pixel distance to a 'real' distance.
   * @param {number} distance Pixel distance ran.
   * @return {number} The 'real' distance ran.
   */
  getActualDistance: function(distance) {
    return distance ? Math.round(distance * this.config.COEFFICIENT) : 0;
  },

  /**
   * Update the distance meter.
   * @param {number} distance
   * @param {number} deltaTime
   * @return {boolean} Whether the acheivement sound fx should be played.
   */
  update: function(deltaTime, distance) {
    var paint = true;
    var playSound = false;

    if (!this.acheivement) {
      distance = this.getActualDistance(distance);

      // Score has gone beyond the initial digit count.
      if (distance > this.maxScore && this.maxScoreUnits ==
        this.config.MAX_DISTANCE_UNITS) {
        this.maxScoreUnits++;
        this.maxScore = parseInt(this.maxScore + '9');
      } else {
        this.distance = 0;
      }

      if (distance > 0) {
        // Acheivement unlocked
        if (distance % this.config.ACHIEVEMENT_DISTANCE == 0) {
          // Flash score and play sound.
          this.acheivement = true;
          this.flashTimer = 0;
          playSound = true;
        }

        // Create a string representation of the distance with leading 0.
        var distanceStr = (this.defaultString +
            distance).substr(-this.maxScoreUnits);
        this.digits = distanceStr.split('');
      } else {
        this.digits = this.defaultString.split('');
      }
    } else {
      // Control flashing of the score on reaching acheivement.
      if (this.flashIterations <= this.config.FLASH_ITERATIONS) {
        this.flashTimer += deltaTime;

        if (this.flashTimer < this.config.FLASH_DURATION) {
          paint = false;
        } else if (this.flashTimer >
            this.config.FLASH_DURATION * 2) {
          this.flashTimer = 0;
          this.flashIterations++;
        }
      } else {
        this.acheivement = false;
        this.flashIterations = 0;
        this.flashTimer = 0;
      }
    }

    // Draw the digits if not flashing.
    if (paint) {
      for (var i = this.digits.length - 1; i >= 0; i--) {
        this.draw(i, parseInt(this.digits[i]));
      }
    }

    this.drawHighScore();

    return playSound;
  },

  /**
   * Draw the high score.
   */
  drawHighScore: function() {
    this.canvasCtx.save();
    this.canvasCtx.globalAlpha = .8;
    for (var i = this.highScore.length - 1; i >= 0; i--) {
      this.draw(i, parseInt(this.highScore[i], 10), true);
    }
    this.canvasCtx.restore();
  },

  /**
   * Set the highscore as a array string.
   * Position of char in the sprite: H - 10, I - 11.
   * @param {number} distance Distance ran in pixels.
   */
  setHighScore: function(distance) {
    distance = this.getActualDistance(distance);
    var highScoreStr = (this.defaultString +
        distance).substr(-this.maxScoreUnits);

    this.highScore = ['10', '11', ''].concat(highScoreStr.split(''));
  },

  /**
   * Reset the distance meter back to '00000'.
   */
  reset: function() {
    this.update(0);
    this.acheivement = false;
  }
};


//******************************************************************************

/**
 * Cloud background item.
 * Similar to an obstacle object but without collision boxes.
 * @param {HTMLCanvasElement} canvas Canvas element.
 * @param {Object} spritePos Position of image in sprite.
 * @param {number} containerWidth
 */
function Cloud(canvas, spritePos, containerWidth) {
  this.canvas = canvas;
  this.canvasCtx = this.canvas.getContext('2d');
  this.spritePos = spritePos;
  this.containerWidth = containerWidth;
  this.xPos = containerWidth;
  this.yPos = 0;
  this.remove = false;
  this.cloudGap = getRandomNum(Cloud.config.MIN_CLOUD_GAP,
      Cloud.config.MAX_CLOUD_GAP);

  this.init();
};


/**
 * Cloud object config.
 * @enum {number}
 */
Cloud.config = {
  HEIGHT: 14,
  MAX_CLOUD_GAP: 400,
  MAX_SKY_LEVEL: 30,
  MIN_CLOUD_GAP: 100,
  MIN_SKY_LEVEL: 71,
  WIDTH: 46
};


Cloud.prototype = {
  /**
   * Initialise the cloud. Sets the Cloud height.
   */
  init: function() {
    this.yPos = getRandomNum(Cloud.config.MAX_SKY_LEVEL,
        Cloud.config.MIN_SKY_LEVEL);
    this.draw();
  },

  /**
   * Draw the cloud.
   */
  draw: function() {
    this.canvasCtx.save();
    var sourceWidth = Cloud.config.WIDTH;
    var sourceHeight = Cloud.config.HEIGHT;

    if (IS_HIDPI) {
      sourceWidth = sourceWidth * 2;
      sourceHeight = sourceHeight * 2;
    }

    this.canvasCtx.drawImage(Runner.imageSprite, this.spritePos.x,
        this.spritePos.y,
        sourceWidth, sourceHeight,
        this.xPos, this.yPos,
        Cloud.config.WIDTH, Cloud.config.HEIGHT);

    this.canvasCtx.restore();
  },

  /**
   * Update the cloud position.
   * @param {number} speed
   */
  update: function(speed) {
    if (!this.remove) {
      this.xPos -= Math.ceil(speed);
      this.draw();

      // Mark as removeable if no longer in the canvas.
      if (!this.isVisible()) {
        this.remove = true;
      }
    }
  },

  /**
   * Check if the cloud is visible on the stage.
   * @return {boolean}
   */
  isVisible: function() {
    return this.xPos + Cloud.config.WIDTH > 0;
  }
};


//******************************************************************************

/**
 * Horizon Line.
 * Consists of two connecting lines. Randomly assigns a flat / bumpy horizon.
 * @param {HTMLCanvasElement} canvas
 * @param {Object} spritePos Horizon position in sprite.
 * @constructor
 */
function HorizonLine(canvas, spritePos) {
  this.spritePos = spritePos;
  this.canvas = canvas;
  this.canvasCtx = canvas.getContext('2d');
  this.sourceDimensions = {};
  this.dimensions = HorizonLine.dimensions;
  this.sourceXPos = [this.spritePos.x, this.spritePos.x +
      this.dimensions.WIDTH];
  this.xPos = [];
  this.yPos = 0;
  this.bumpThreshold = 0.5;

  this.setSourceDimensions();
  this.draw();
};


/**
 * Horizon line dimensions.
 * @enum {number}
 */
HorizonLine.dimensions = {
  WIDTH: 600,
  HEIGHT: 12,
  YPOS: 127
};


HorizonLine.prototype = {
  /**
   * Set the source dimensions of the horizon line.
   */
  setSourceDimensions: function() {

    for (var dimension in HorizonLine.dimensions) {
      if (IS_HIDPI) {
        if (dimension != 'YPOS') {
          this.sourceDimensions[dimension] =
              HorizonLine.dimensions[dimension] * 2;
        }
      } else {
        this.sourceDimensions[dimension] =
            HorizonLine.dimensions[dimension];
      }
      this.dimensions[dimension] = HorizonLine.dimensions[dimension];
    }

    this.xPos = [0, HorizonLine.dimensions.WIDTH];
    this.yPos = HorizonLine.dimensions.YPOS;
  },

  /**
   * Return the crop x position of a type.
   */
  getRandomType: function() {
    return Math.random() > this.bumpThreshold ? this.dimensions.WIDTH : 0;
  },

  /**
   * Draw the horizon line.
   */
  draw: function() {
    this.canvasCtx.drawImage(Runner.imageSprite, this.sourceXPos[0],
        this.spritePos.y,
        this.sourceDimensions.WIDTH, this.sourceDimensions.HEIGHT,
        this.xPos[0], this.yPos,
        this.dimensions.WIDTH, this.dimensions.HEIGHT);

    this.canvasCtx.drawImage(Runner.imageSprite, this.sourceXPos[1],
        this.spritePos.y,
        this.sourceDimensions.WIDTH, this.sourceDimensions.HEIGHT,
        this.xPos[1], this.yPos,
        this.dimensions.WIDTH, this.dimensions.HEIGHT);
  },

  /**
   * Update the x position of an indivdual piece of the line.
   * @param {number} pos Line position.
   * @param {number} increment
   */
  updateXPos: function(pos, increment) {
    var line1 = pos;
    var line2 = pos == 0 ? 1 : 0;

    this.xPos[line1] -= increment;
    this.xPos[line2] = this.xPos[line1] + this.dimensions.WIDTH;

    if (this.xPos[line1] <= -this.dimensions.WIDTH) {
      this.xPos[line1] += this.dimensions.WIDTH * 2;
      this.xPos[line2] = this.xPos[line1] - this.dimensions.WIDTH;
      this.sourceXPos[line1] = this.getRandomType() + this.spritePos.x;
    }
  },

  /**
   * Update the horizon line.
   * @param {number} deltaTime
   * @param {number} speed
   */
  update: function(deltaTime, speed) {
    var increment = Math.floor(speed * (FPS / 1000) * deltaTime);

    if (this.xPos[0] <= 0) {
      this.updateXPos(0, increment);
    } else {
      this.updateXPos(1, increment);
    }
    this.draw();
  },

  /**
   * Reset horizon to the starting position.
   */
  reset: function() {
    this.xPos[0] = 0;
    this.xPos[1] = HorizonLine.dimensions.WIDTH;
  }
};


//******************************************************************************

/**
 * Horizon background class.
 * @param {HTMLCanvasElement} canvas
 * @param {Object} spritePos Sprite positioning.
 * @param {Object} dimensions Canvas dimensions.
 * @param {number} gapCoefficient
 * @constructor
 */
function Horizon(canvas, spritePos, dimensions, gapCoefficient) {
  this.canvas = canvas;
  this.canvasCtx = this.canvas.getContext('2d');
  this.config = Horizon.config;
  this.dimensions = dimensions;
  this.gapCoefficient = gapCoefficient;
  this.obstacles = [];
  this.obstacleHistory = [];
  this.horizonOffsets = [0, 0];
  this.cloudFrequency = this.config.CLOUD_FREQUENCY;
  this.spritePos = spritePos;

  // Cloud
  this.clouds = [];
  this.cloudSpeed = this.config.BG_CLOUD_SPEED;

  // Horizon
  this.horizonLine = null;

  this.init();
};


/**
 * Horizon config.
 * @enum {number}
 */
Horizon.config = {
  BG_CLOUD_SPEED: 0.2,
  BUMPY_THRESHOLD: .3,
  CLOUD_FREQUENCY: .5,
  HORIZON_HEIGHT: 16,
  MAX_CLOUDS: 6
};


Horizon.prototype = {
  /**
   * Initialise the horizon. Just add the line and a cloud. No obstacles.
   */
  init: function() {
    this.addCloud();
    this.horizonLine = new HorizonLine(this.canvas, this.spritePos.HORIZON);
  },

  /**
   * @param {number} deltaTime
   * @param {number} currentSpeed
   * @param {boolean} updateObstacles Used as an override to prevent
   *     the obstacles from being updated / added. This happens in the
   *     ease in section.
   */
  update: function(deltaTime, currentSpeed, updateObstacles) {
    this.runningTime += deltaTime;
    this.horizonLine.update(deltaTime, currentSpeed);
    this.updateClouds(deltaTime, currentSpeed);

    if (updateObstacles) {
      this.updateObstacles(deltaTime, currentSpeed);
    }
  },

  /**
   * Update the cloud positions.
   * @param {number} deltaTime
   * @param {number} currentSpeed
   */
  updateClouds: function(deltaTime, speed) {
    var cloudSpeed = this.cloudSpeed / 1000 * deltaTime * speed;
    var numClouds = this.clouds.length;

    if (numClouds) {
      for (var i = numClouds - 1; i >= 0; i--) {
        this.clouds[i].update(cloudSpeed);
      }

      var lastCloud = this.clouds[numClouds - 1];

      // Check for adding a new cloud.
      if (numClouds < this.config.MAX_CLOUDS &&
          (this.dimensions.WIDTH - lastCloud.xPos) > lastCloud.cloudGap &&
          this.cloudFrequency > Math.random()) {
        this.addCloud();
      }

      // Remove expired clouds.
      this.clouds = this.clouds.filter(function(obj) {
        return !obj.remove;
      });
    }
  },

  /**
   * Update the obstacle positions.
   * @param {number} deltaTime
   * @param {number} currentSpeed
   */
  updateObstacles: function(deltaTime, currentSpeed) {
    // Obstacles, move to Horizon layer.
    var updatedObstacles = this.obstacles.slice(0);

    for (var i = 0; i < this.obstacles.length; i++) {
      var obstacle = this.obstacles[i];
      obstacle.update(deltaTime, currentSpeed);

      // Clean up existing obstacles.
      if (obstacle.remove) {
        updatedObstacles.shift();
      }
    }
    this.obstacles = updatedObstacles;

    if (this.obstacles.length > 0) {
      var lastObstacle = this.obstacles[this.obstacles.length - 1];

      if (lastObstacle && !lastObstacle.followingObstacleCreated &&
          lastObstacle.isVisible() &&
          (lastObstacle.xPos + lastObstacle.width + lastObstacle.gap) <
          this.dimensions.WIDTH) {
        this.addNewObstacle(currentSpeed);
        lastObstacle.followingObstacleCreated = true;
      }
    } else {
      // Create new obstacles.
      this.addNewObstacle(currentSpeed);
    }
  },

  /**
   * Add a new obstacle.
   * @param {number} currentSpeed
   */
  addNewObstacle: function(currentSpeed) {
    var obstacleTypeIndex = getRandomNum(0, Obstacle.types.length - 1);
    var obstacleType = Obstacle.types[obstacleTypeIndex];

    // Check for multiples of the same type of obstacle.
    // Also check obstacle is available at current speed.
    if (this.duplicateObstacleCheck(obstacleType.type) ||
        currentSpeed < obstacleType.minSpeed) {
      this.addNewObstacle(currentSpeed);
    } else {
      var obstacleSpritePos = this.spritePos[obstacleType.type];

      this.obstacles.push(new Obstacle(this.canvasCtx, obstacleType,
          obstacleSpritePos, this.dimensions,
          this.gapCoefficient, currentSpeed));

      this.obstacleHistory.unshift(obstacleType.type);

      if (this.obstacleHistory.length > 1) {
        this.obstacleHistory.splice(Runner.config.MAX_OBSTACLE_DUPLICATION);
      }
    }
  },

  /**
   * Returns whether the previous two obstacles are the same as the next one.
   * Maximum duplication is set in config value MAX_OBSTACLE_DUPLICATION.
   * @return {boolean}
   */
  duplicateObstacleCheck: function(nextObstacleType) {
    var duplicateCount = 0;

    for (var i = 0; i < this.obstacleHistory.length; i++) {
      duplicateCount = this.obstacleHistory[i] == nextObstacleType ?
          duplicateCount + 1 : 0;
    }
    return duplicateCount >= Runner.config.MAX_OBSTACLE_DUPLICATION;
  },

  /**
   * Reset the horizon layer.
   * Remove existing obstacles and reposition the horizon line.
   */
  reset: function() {
    this.obstacles = [];
    this.horizonLine.reset();
  },

  /**
   * Update the canvas width and scaling.
   * @param {number} width Canvas width.
   * @param {number} height Canvas height.
   */
  resize: function(width, height) {
    this.canvas.width = width;
    this.canvas.height = height;
  },

  /**
   * Add a new cloud to the horizon.
   */
  addCloud: function() {
    this.clouds.push(new Cloud(this.canvas, this.spritePos.CLOUD,
        this.dimensions.WIDTH));
  }
};
})();
</script>
</head>
<body id="t" i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize">
  <div id="main-frame-error" class="interstitial-wrapper">
    <div id="main-content">
      <img class="icon"
          jseval="updateIconClass(this.classList, iconClass)">
      <div id="main-message">
        <h1 i18n-content="heading"></h1>
        <p hidden></p>
        <div class="error-code" jscontent="errorCode"></div>
      </div>
    </div>
    <div id="buttons" class="nav-wrapper">
      <div id="control-buttons" hidden>
        <button id="reload-button"
            class="blue-button text-button"
            onclick="trackClick(this.trackingId);
                     reloadButtonClick(this.url);"
            jsselect="reloadButton"
            jsvalues=".url:reloadUrl; .trackingId:reloadTrackingId"
            jscontent="msg"></button>
        <button id="show-saved-copy-button"
            class="blue-button text-button"
            onclick="showSavedCopyButtonClick()"
            jsselect="showSavedCopyButton"
            jscontent="msg" jsvalues="title:title; .primary:primary">
        </button>
      </div>
      <button id="details-button" class="text-button small-link"
         onclick="detailsButtonClick(); toggleHelpBox()"
         jsdisplay="details" jscontent="details"
         jsvalues=".detailsText:details; .hideDetailsText:hideDetails;"></button>
    </div>
    <div id="details" class="hidden">
      <div jsselect="summary">
        <span jsvalues=".innerHTML:msg"></span>
      </div>
      <div class="suggestions" jsselect="suggestions">
        <div class="suggestion-header" jsvalues=".innerHTML:header"></div>
        <div class="suggestion-body" jsvalues=".innerHTML:body"></div>
      </div>
      <button class="text-button" id="diagnose-button"
          onclick="diagnoseErrors()" jscontent="diagnose"
          jsdisplay="diagnose"></button>
      <div id="diagnose-frame" class="hidden"></div>
      <form class="suggestions" jsdisplay="searchUrl"
          jsvalues=".url:searchUrl; .trackingId:searchTrackingId"
          onsubmit="trackClick(this.trackingId); return search(this.url);">
        <div class="suggestion-header" jscontent="searchHeader"></div>
        <div id="search-container">
          <input type="text" name="q" id="search-box"
              jsvalues=".value:searchTerms" />
          <button type="submit" id="search-button" class="blue-button"
              jsvalues="aria-label:searchHeader">
            <img id="search-image">
          </button>
        </div>
      </form>
    </div>
  </div>
  <div id="sub-frame-error">
    <!-- Show details when hovering over the icon, in case the details are
         hidden because they're too large. -->
    <img class="icon" jseval="updateIconClass(this.classList, iconClass)"
        jsvalues=".title:errorDetails">
    <div id="sub-frame-error-details" jsvalues=".innerHTML:errorDetails"></div>
  </div>

  <div id="offline-resources">
    <img id="offline-resources-1x" src="data:image/png;base64,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">
    <img id="offline-resources-2x" src="data:image/png;base64,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">
    <template id="audio-resources">
      <audio id="offline-sound-press" src="data:audio/mpeg;base64,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"></audio>
      <audio id="offline-sound-hit" src="data:audio/mpeg;base64,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"></audio>
      <audio id="offline-sound-reached" src="data:audio/mpeg;base64,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"></audio>
    </template>
  </div>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no">
<script>
  window.onload = function() {
    if (plugin.didFinishLoading)
      plugin.didFinishLoading();
  };

  window.onkeydown = function(e) {
    if (e.keyIdentifier == 'Enter' || e.keyIdentifier == 'U+0020') {
      plugin.load();
      e.preventDefault();
    }
  };
</script>
<style>/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file. */

html, body {
  -webkit-user-select: none;
  font-family: sans-serif;
  height: 100%;
  margin: 0;
  overflow: hidden;
  text-align: center;
  width: 100%;
}

h1 {
  font-size: 10pt;
  font-weight: normal;
  padding: 0pt 10pt;
visibility: hidden;
}

#outer:hover h1, #outer:hover #close {
  visibility: visible;
}

p {
  font-size: 8pt;
  padding: 0pt 14pt;
}

#outer {
  align-items: center;
  border: 1px black solid;
  box-sizing: border-box;
  display: flex;
  height: 100%;
  justify-content: center;
  position: absolute;
  width: 100%;
}

#close {
  background-image: -webkit-image-set(
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAiElEQVR42r2RsQrDMAxEBRdl8SDcX8lQPGg1GBI6lvz/h7QyRRXV0qUULwfvwZ1tenw5PxToRPWMC52eA9+WDnlh3HFQ/xBQl86NFYJqeGflkiogrOvVlIFhqURFVho3x1moGAa3deMs+LS30CAhBN5nNxeT5hbJ1zwmji2k+aF6NENIPf/hs54f0sZFUVAMigAAAABJRU5ErkJggg==) 1x,
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAA9UlEQVR4Xu3UsWrCUByH0fMEouiuhrg4xohToJVGH0CHLBncEwfx/VvIFHLJBWmHDvKbv7PcP9f3L/fXwBsApZSRpUpEgbOnxwiReng6x4AvjdrNXRLkibubWqMcB9Yujk7qjhjmtZOji/U4wELuoBwQXa50kFsQA5jK+kQ/l5kSA4ZEK5Fo+3kcCIlGM8ijQEhUqkEeBUKiUPTyl4C5vZ1cbmdv/iqwclXY6aZwtXoFSLQqhVwmkytUWglxAMG7T0yCu4gD0v7ZBKeVxoEwFxIxYBPmIWEzDnyEeUj4HAfYdvmMcGYdsSUGsOzlIbHEv/uV38APrreiBRBIs3QAAAAASUVORK5CYII=) 2x);
  background-position: right top;
  background-repeat: no-repeat;
  cursor: pointer;
  height: 14px;
  position: absolute;
  right: 3px;
  top: 3px;
visibility: hidden;
  width: 14px;
}

#close[data-plugin-type='document'] {
  display: none;
}

#close:hover {
  background-image: -webkit-image-set(
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAqUlEQVR4XqWRMQqEMBBF/1E8Ra6x6V3FRnS9QbCxtJg6Z7CzE9lTiIXXyUb3C8EULixDIMM8Zt4kcDfxM5A45U+cgeXnC1tREgkzAgob3hiq3CUHvGLG4FTQoSgxQGDrzN8WTLBGnx2IVDksen9GH7Z9hA5E6uxABMJyCHDMCEGHzugLQPPlBCBNGq+5YtpnGw1Bv+te15ypljTpVzdak5Opy+z+qf//zQ+Lg+07ay5KsgAAAABJRU5ErkJggg==) 1x,
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAB4UlEQVR42u2VsWoCQRBAh+MUFP0C1V9QD4NEOxs9xBQHQVCwSJFWVBAtBNXCxk6wTkBJYUTwEwQLC61E8QP0NzZzt5g5726DkC7EYWHZ8T3WndkV2C/jLwn4hwVYBIdLn9vkLp79QcBCTDMiy3w2gQ9XeTYkEHA8vqj2rworXu3HF1YFfSWgp5QFnKVLvYvzDEKEZ5hW70oXOCtcEbQLIkx7+IQtfMBSOjU6XEF4oyOdYInZbXyOuajjDlpNeQgleIUJKUz4BDMledhqOu/AzVSmzZ49CUjCC0yvim98iqtJT2L2jKsqczsdok9XrHNexaww415lnTNwn6CM/KxJIR8bnUZHPhLO6yMoIyk2pNjLewFuE5AiY1KMMQx8Q7hQYFek4AkjxXFe1rsF84I/BTFQMGL+1Lxwl4DwdtM1gjwKohgxyLtG7SYpxALqugOMcfOKN+bFXeBsLB1uulNcRqq7/tt36k41zoL6QlxGjtd6lrahiqCi1iOFYyvXuxY8yzK33VnvUivbLlOlj/jktm0s3YnXrNIXXufHNxuOGasi8S68zkwrlnV8ZcJJsTIUxbLgQcFZWE8N0gau2p40VVcM0gYeFpSRK6445UhBuKiRgiyKw+34rLt59nb1/7+RwReVkaFtqvNBuwAAAABJRU5ErkJggg==) 2x);
}

#close:active {
  background-image: -webkit-image-set(
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAQklEQVR4AWP4TwBSTQGDHcMZIIYAKA9VwRkwtINJgyCaCTAlCBaKAoQ+hFmoCqBKENKkK8C0gpAjCXuTyICiQ2QBAPSwyG3ByZlCAAAAAElFTkSuQmCC) 1x,
      url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAA/ElEQVR4Xu3UsWrCUBiG4efGlIBoIMFbcnYolYJ3pg4iKGrGYFTRwaUFhYAekiDt0EG++X2W83N8/3J/DbwBMJJSsdQItcDY1VlCOImzq3Ed8OmicHASB3ns5KBw8VUNpDJrW7uAiJ3sbK1l0mqArpmFTUlQ5jYWZrrUAUSmT0SZm4qoA56JvVhs/5g3A7RLolA85A1ASOTye65NMxASK6syfxGITMzvMxG9CvRkliWwlOm9AsSOcitzU1NzK7mjuBkQvHtLK7iLBiB5PhttJSGpB8I8vM6kDuiHeUjoVwMfYR4SRtUAw1veIZzOjRhSBzCoyKFjgH/3K7+BHzg+Cgw0eSW3AAAAAElFTkSuQmCC) 2x);
}
</style>
<style>
#outer {
  border: none;
  cursor: pointer;
}

#shielding {
  background-color: rgba(0, 0, 0, 0.5);
  height: 100%;
  left: 0px;
  position: absolute;
  top: 0px;
  width: 100%;
  z-index: 2;
}

#plugin-icon {
  display: block;
  opacity: 0.8;
}

#plugin-icon:hover {
  opacity: 0.95;
}

#poster {
  height: 100%;
  object-fit: contain;
  width: 100%;
  z-index: 1;
}

#inner-container {
  align-items: center;
  display: flex;
  justify-content: center;
  left: 0px;
  position: absolute;
  top: 0px;
  z-index: 2;
}
</style>
<base i18n-values="href:baseurl">
</head>

<body>
  <div i18n-values="title:name" id="outer">
    <img id="poster" i18n-values="srcset:poster">
    <div id="shielding"></div>
    <div id="inner-container"
         i18n-values=".style.width:visibleWidth;.style.height:visibleHeight">
      <div id="inner">
        <img id="plugin-icon" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAA8dJREFUaAXdWs9vEkEUZkvZQloNxJoY40kxJsDNo9GDif+Bf4CHpjEmJPoPeMce1F408dYjQePBgycv3vRG4GBMPREPLSlpCUWggN+3ncVl6PJrZ5a6k0x2Z2fnve/befPmzcwaIbVpGeLCyEsiG5L4Pso9kbu4nkj1CysSaAQ5trm5uV6pVB4eHx+/brVan3u93s9+v19Fbolc5TPW8R2+yzZsK2TIpPFYf6LS6Pb29rX9/f0NgPsIsA3kWVODbSmDsigT2TdCZjabvVyv158D9eGsyMe8f0iZlA0yJrK2FE4mkxer1eoTmMjvMYA8VVE2dVAXmHC8KU1mPp9Pdjqd755QztCYuqgTLJT1TrRYLN7T2Qtu/KiTukGGY8dTiu3t7T2CoqabMh+eN4kBLOjd5kpRQcIHrJNVCDIz94zJLoX4RfaEzK4pzGzqMRPmIFvEmJCRy2ViEg5gsjej2/PTO8lgJ5WJTbjmsePFpA+fJGzR9cQIFq4mZnBWPY8mJX84YhQRwJnhTFSEHXK7mcrNZvMdGjBQ1JqIFb0y4sUMBm3Q7Dl2KpVKd5jx1Xa1MgFWEWgO9UqEEagKxSSBL7WSy+WuIrJ9r0Kmmwxihi4uIwYpJkJxtzZTPxdE7IXVaq1We4bGWkyNmMHAmvGpMIQFzqppmg8GtNTccCXYSCQSb8rl8n2Q+aVG7D8pxEzs9pNlrtam/uQTXnT0iC2f14guUyN2yOcSO7TCpecEfFNXuxChHvY+Te0phCkzNWInB8uWw+HwLWrSnGxTe6vS1AT2JYtIJBK5oZmEU/yfTCbzbWtr62673f7grJjnXmC3xvoaupq7HUrSGNOScaoytSoEr1lMcHNB1uJDWZWpWdhtIj7g1qvCcltQUUe+pFfViHR+xBi82EY8Hn+Be9dodqTl8ANit1wix0ZtuE57ifPKFczMOyDxCtrmJRES2PvskR4WK7uYJZPa4Z8qiMIh3E6lUjuGYVz3qpPYyYHd2+t2uz+8CpyiPXVxQnycTqe/qCBBnQK7RaR7cHDwdQogXl5xmtJLCJrblGQQAjt39q2gcR22Ns8mNMfXUDpjHqEp6VqfNMSO/oCfzjBeaWzl/GojYTzonBwdHX0a0PJ+o82UnNAE5qHDosAsdUk0EJsPJBKY7SCSCcQGHYmEgrJlSi7B2MQmE6RAHCucUoEXC8JBj00mEEdvNplAHIbaZMxCoXDTzwMg6lJ9PG2TCcQPAzYZXv/7XzicZALxU41M6Fz85jR02uNEOOc9NzN4dMz1ObMsX9uPZ38BvwZw6z92PI4AAAAASUVORK5CYII="
             i18n-values=".style.maxWidth:visibleWidth;
                          .style.maxHeight:visibleHeight" />
      </div>
    </div>
  </div>
  <script>
    document.getElementById('poster').onerror = function() {
      this.hidden = true;
    };

    document.getElementById('outer').onclick = function() {
      plugin.load();
    };

    window.setPosterMargin = function(marginLeft, marginTop) {
      var container = document.getElementById('inner-container');
      container.style.marginLeft = marginLeft;
      container.style.marginTop = marginTop;
    };
  </script>
</body>
</html>
// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var chrome;
if (!chrome)
  chrome = {};

if (!chrome.embeddedSearch) {
  chrome.embeddedSearch = new function() {
    this.searchBox = new function() {

      // =======================================================================
      //                            Private functions
      // =======================================================================
      native function Focus();
      native function GetDisplayInstantResults();
      native function GetMostVisitedItemData();
      native function GetQuery();
      native function GetSearchRequestParams();
      native function GetRightToLeft();
      native function GetStartMargin();
      native function GetSuggestionToPrefetch();
      native function IsFocused();
      native function IsKeyCaptureEnabled();
      native function Paste();
      native function SetVoiceSearchSupported();
      native function StartCapturingKeyStrokes();
      native function StopCapturingKeyStrokes();

      // =======================================================================
      //                           Exported functions
      // =======================================================================
      this.__defineGetter__('displayInstantResults', GetDisplayInstantResults);
      this.__defineGetter__('isFocused', IsFocused);
      this.__defineGetter__('isKeyCaptureEnabled', IsKeyCaptureEnabled);
      this.__defineGetter__('rtl', GetRightToLeft);
      this.__defineGetter__('startMargin', GetStartMargin);
      this.__defineGetter__('suggestion', GetSuggestionToPrefetch);
      this.__defineGetter__('value', GetQuery);
      Object.defineProperty(this, 'requestParams',
                            { get: GetSearchRequestParams });

      this.focus = function() {
        Focus();
      };

      // This method is restricted to chrome-search://most-visited pages by
      // checking the invoking context's origin in searchbox_extension.cc.
      this.getMostVisitedItemData = function(restrictedId) {
        var item = GetMostVisitedItemData(restrictedId);
        if (item) {
          var sizeInPx = Math.floor(48 * window.devicePixelRatio + 0.5);
          // Populate large icon and fallback icon data, if they exist. We'll
          // render everything here, once these become available by default.
          if (item.largeIconUrl) {
            item.largeIconUrl +=
                sizeInPx + "/" + item.renderViewId + "/" + item.rid;
          }
          if (item.fallbackIconUrl) {
            item.fallbackIconUrl +=
                sizeInPx + ",,,,/" + item.renderViewId + "/" + item.rid;
          }
        }
        return item;
      };

      this.paste = function(value) {
        Paste(value);
      };

      this.setVoiceSearchSupported = function(supported) {
        SetVoiceSearchSupported(supported);
      };

      this.startCapturingKeyStrokes = function() {
        StartCapturingKeyStrokes();
      };

      this.stopCapturingKeyStrokes = function() {
        StopCapturingKeyStrokes();
      };

      this.onfocuschange = null;
      this.onkeycapturechange = null;
      this.onmarginchange = null;
      this.onsubmit = null;
      this.onsuggestionchange = null;
      this.ontogglevoicesearch = null;

      //TODO(jered): Remove this empty method when google no longer requires it.
      this.setRestrictedValue = function() {};
    };

    this.newTabPage = new function() {

      // =======================================================================
      //                            Private functions
      // =======================================================================
      native function CheckIsUserSignedInToChromeAs();
      native function CheckIsUserSyncingHistory();
      native function DeleteMostVisitedItem();
      native function GetAppLauncherEnabled();
      native function GetDispositionFromClick();
      native function GetMostVisitedItems();
      native function GetThemeBackgroundInfo();
      native function IsInputInProgress();
      native function LogEvent();
      native function LogMostVisitedImpression();
      native function LogMostVisitedNavigation();
      native function NavigateContentWindow();
      native function UndoAllMostVisitedDeletions();
      native function UndoMostVisitedDeletion();

      function GetMostVisitedItemsWrapper() {
        var mostVisitedItems = GetMostVisitedItems();
        for (var i = 0, item; item = mostVisitedItems[i]; ++i) {
          item.faviconUrl = GenerateFaviconURL(item.renderViewId, item.rid);

          // These properties are private data and should not be returned to
          // the page. They are only accessible via getMostVisitedItemData().
          delete item.url;
          delete item.title;
          delete item.domain;
          delete item.direction;
          delete item.renderViewId;
          delete item.largeIconUrl;
          delete item.fallbackIconUrl;
        }
        return mostVisitedItems;
      }

      function GenerateFaviconURL(renderViewId, rid) {
        return "chrome-search://favicon/size/16@" +
            window.devicePixelRatio + "x/" +
            renderViewId + "/" + rid;
      }

      // =======================================================================
      //                           Exported functions
      // =======================================================================
      this.__defineGetter__('appLauncherEnabled', GetAppLauncherEnabled);
      this.__defineGetter__('isInputInProgress', IsInputInProgress);
      this.__defineGetter__('mostVisited', GetMostVisitedItemsWrapper);
      this.__defineGetter__('themeBackgroundInfo', GetThemeBackgroundInfo);

      this.deleteMostVisitedItem = function(restrictedId) {
        DeleteMostVisitedItem(restrictedId);
      };

      this.getDispositionFromClick = function(middle_button,
                                              alt_key,
                                              ctrl_key,
                                              meta_key,
                                              shift_key) {
        return GetDispositionFromClick(middle_button,
                                       alt_key,
                                       ctrl_key,
                                       meta_key,
                                       shift_key);
      };

      this.checkIsUserSignedIntoChromeAs = function(identity) {
        CheckIsUserSignedInToChromeAs(identity);
      };

      this.checkIsUserSyncingHistory = function() {
        CheckIsUserSyncingHistory();
      };

      // This method is restricted to chrome-search://most-visited pages by
      // checking the invoking context's origin in searchbox_extension.cc.
      this.logEvent = function(histogram_name) {
        LogEvent(histogram_name);
      };

      // This method is restricted to chrome-search://most-visited pages by
      // checking the invoking context's origin in searchbox_extension.cc.
      this.logMostVisitedImpression = function(position, provider) {
        LogMostVisitedImpression(position, provider);
      };

      // This method is restricted to chrome-search://most-visited pages by
      // checking the invoking context's origin in searchbox_extension.cc.
      this.logMostVisitedNavigation = function(position, provider) {
        LogMostVisitedNavigation(position, provider);
      };

      this.navigateContentWindow = function(destination, disposition) {
        NavigateContentWindow(destination, disposition);
      };

      this.undoAllMostVisitedDeletions = function() {
        UndoAllMostVisitedDeletions();
      };

      this.undoMostVisitedDeletion = function(restrictedId) {
        UndoMostVisitedDeletion(restrictedId);
      };

      this.onsignedincheckdone = null;
      this.onhistorysynccheckdone = null;
      this.oninputcancel = null;
      this.oninputstart = null;
      this.onmostvisitedchange = null;
      this.onthemechange = null;
    };

    // TODO(jered): Remove when google no longer expects this object.
    chrome.searchBox = this.searchBox;
  };
}
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the app API.

var GetAvailability = requireNative('v8_context').GetAvailability;
if (!GetAvailability('app').is_available) {
  exports.binding = {};
  exports.onInstallStateResponse = function(){};
  return;
}

var appNatives = requireNative('app');
var process = requireNative('process');
var extensionId = process.GetExtensionId();
var logActivity = requireNative('activityLogger');

function wrapForLogging(fun) {
  if (!extensionId)
    return fun;  // nothing interesting to log without an extension

  return function() {
    // TODO(ataly): We need to make sure we use the right prototype for
    // fun.apply. Array slice can either be rewritten or similarly defined.
    logActivity.LogAPICall(extensionId, "app." + fun.name,
        $Array.slice(arguments));
    return $Function.apply(fun, this, arguments);
  };
}

// This becomes chrome.app
var app = {
  getIsInstalled: wrapForLogging(appNatives.GetIsInstalled),
  getDetails: wrapForLogging(appNatives.GetDetails),
  getDetailsForFrame: wrapForLogging(appNatives.GetDetailsForFrame),
  runningState: wrapForLogging(appNatives.GetRunningState)
};

// Tricky; "getIsInstalled" is actually exposed as the getter "isInstalled",
// but we don't have a way to express this in the schema JSON (nor is it
// worth it for this one special case).
//
// So, define it manually, and let the getIsInstalled function act as its
// documentation.
app.__defineGetter__('isInstalled', wrapForLogging(appNatives.GetIsInstalled));

// Called by app_bindings.cc.
function onInstallStateResponse(state, callbackId) {
  var callback = callbacks[callbackId];
  delete callbacks[callbackId];
  if (typeof(callback) == 'function') {
    try {
      callback(state);
    } catch (e) {
      console.error('Exception in chrome.app.installState response handler: ' +
                    e.stack);
    }
  }
}

// TODO(kalman): move this stuff to its own custom bindings.
var callbacks = {};
var nextCallbackId = 1;

app.installState = function getInstallState(callback) {
  var callbackId = nextCallbackId++;
  callbacks[callbackId] = callback;
  appNatives.GetInstallState(callbackId);
};
if (extensionId)
  app.installState = wrapForLogging(app.installState);

exports.binding = app;
exports.onInstallStateResponse = onInstallStateResponse;
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom bindings for the automation API.
var AutomationNode = require('automationNode').AutomationNode;
var AutomationRootNode = require('automationNode').AutomationRootNode;
var automation = require('binding').Binding.create('automation');
var automationInternal =
    require('binding').Binding.create('automationInternal').generate();
var eventBindings = require('event_bindings');
var Event = eventBindings.Event;
var forEach = require('utils').forEach;
var lastError = require('lastError');
var logging = requireNative('logging');
var nativeAutomationInternal = requireNative('automationInternal');
var GetRoutingID = nativeAutomationInternal.GetRoutingID;
var GetSchemaAdditions = nativeAutomationInternal.GetSchemaAdditions;
var schema = GetSchemaAdditions();

/**
 * A namespace to export utility functions to other files in automation.
 */
window.automationUtil = function() {};

// TODO(aboxhall): Look into using WeakMap
var idToAutomationRootNode = {};
var idToCallback = {};

var DESKTOP_TREE_ID = 0;

automationUtil.storeTreeCallback = function(id, callback) {
  if (!callback)
    return;

  var targetTree = idToAutomationRootNode[id];
  if (!targetTree) {
    // If we haven't cached the tree, hold the callback until the tree is
    // populated by the initial onAccessibilityEvent call.
    if (id in idToCallback)
      idToCallback[id].push(callback);
    else
      idToCallback[id] = [callback];
  } else {
    callback(targetTree);
  }
};

/**
 * Global list of tree change observers.
 * @type {Array<TreeChangeObserver>}
 */
automationUtil.treeChangeObservers = [];

automation.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  // TODO(aboxhall, dtseng): Make this return the speced AutomationRootNode obj.
  apiFunctions.setHandleRequest('getTree', function getTree(tabID, callback) {
    var routingID = GetRoutingID();

    // enableTab() ensures the renderer for the active or specified tab has
    // accessibility enabled, and fetches its ax tree id to use as
    // a key in the idToAutomationRootNode map. The callback to
    // enableTab is bound to the callback passed in to getTree(), so that once
    // the tree is available (either due to having been cached earlier, or after
    // an accessibility event occurs which causes the tree to be populated), the
    // callback can be called.
    var params = { routingID: routingID, tabID: tabID };
    automationInternal.enableTab(params,
        function onEnable(id) {
          if (lastError.hasError(chrome)) {
            callback();
            return;
          }
          automationUtil.storeTreeCallback(id, callback);
        });
  });

  var desktopTree = null;
  apiFunctions.setHandleRequest('getDesktop', function(callback) {
    desktopTree =
        idToAutomationRootNode[DESKTOP_TREE_ID];
    if (!desktopTree) {
      if (DESKTOP_TREE_ID in idToCallback)
        idToCallback[DESKTOP_TREE_ID].push(callback);
      else
        idToCallback[DESKTOP_TREE_ID] = [callback];

      var routingID = GetRoutingID();

      // TODO(dtseng): Disable desktop tree once desktop object goes out of
      // scope.
      automationInternal.enableDesktop(routingID, function() {
        if (lastError.hasError(chrome)) {
          delete idToAutomationRootNode[
              DESKTOP_TREE_ID];
          callback();
          return;
        }
      });
    } else {
      callback(desktopTree);
    }
  });

  function removeTreeChangeObserver(observer) {
    var observers = automationUtil.treeChangeObservers;
    for (var i = 0; i < observers.length; i++) {
      if (observer == observers[i])
        observers.splice(i, 1);
    }
  }
  apiFunctions.setHandleRequest('removeTreeChangeObserver', function(observer) {
    removeTreeChangeObserver(observer);
  });

  function addTreeChangeObserver(observer) {
    removeTreeChangeObserver(observer);
    automationUtil.treeChangeObservers.push(observer);
  }
  apiFunctions.setHandleRequest('addTreeChangeObserver', function(observer) {
    addTreeChangeObserver(observer);
  });

});

// Listen to the automationInternal.onAccessibilityEvent event, which is
// essentially a proxy for the AccessibilityHostMsg_Events IPC from the
// renderer.
automationInternal.onAccessibilityEvent.addListener(function(data) {
  var id = data.treeID;
  var targetTree = idToAutomationRootNode[id];
  if (!targetTree) {
    // If this is the first time we've gotten data for this tree, it will
    // contain all of the tree's data, so create a new tree which will be
    // bootstrapped from |data|.
    targetTree = new AutomationRootNode(id);
    idToAutomationRootNode[id] = targetTree;
  }
  if (!privates(targetTree).impl.onAccessibilityEvent(data))
    return;

  // If we're not waiting on a callback to getTree(), we can early out here.
  if (!(id in idToCallback))
    return;

  // We usually get a 'placeholder' tree first, which doesn't have any url
  // attribute or child nodes. If we've got that, wait for the full tree before
  // calling the callback.
  // TODO(dmazzoni): Don't send down placeholder (crbug.com/397553)
  if (id != DESKTOP_TREE_ID && !targetTree.attributes.url &&
      targetTree.children.length == 0) {
    return;
  }

  // If the tree wasn't available when getTree() was called, the callback will
  // have been cached in idToCallback, so call and delete it now that we
  // have the complete tree.
  for (var i = 0; i < idToCallback[id].length; i++) {
    console.log('calling getTree() callback');
    var callback = idToCallback[id][i];
    callback(targetTree);
  }
  delete idToCallback[id];
});

automationInternal.onAccessibilityTreeDestroyed.addListener(function(id) {
  var targetTree = idToAutomationRootNode[id];
  if (targetTree) {
    privates(targetTree).impl.destroy();
    delete idToAutomationRootNode[id];
  } else {
    logging.WARNING('no targetTree to destroy');
  }
  delete idToAutomationRootNode[id];
});

exports.binding = automation.generate();

// Add additional accessibility bindings not specified in the automation IDL.
// Accessibility and automation share some APIs (see
// ui/accessibility/ax_enums.idl).
forEach(schema, function(k, v) {
  exports.binding[k] = v;
});
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var utils = require('utils');

var AutomationEventImpl = function(type, target) {
  this.propagationStopped = false;

  // TODO(aboxhall): make these read-only properties
  this.type = type;
  this.target = target;
  this.eventPhase = Event.NONE;
};

AutomationEventImpl.prototype = {
  stopPropagation: function() {
    this.propagationStopped = true;
  }
};

exports.AutomationEvent = utils.expose(
    'AutomationEvent',
    AutomationEventImpl,
    { functions: ['stopPropagation'],
      readonly: ['type', 'target', 'eventPhase'] });
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var AutomationEvent = require('automationEvent').AutomationEvent;
var automationInternal =
    require('binding').Binding.create('automationInternal').generate();
var IsInteractPermitted =
    requireNative('automationInternal').IsInteractPermitted;

var lastError = require('lastError');
var logging = requireNative('logging');
var schema = requireNative('automationInternal').GetSchemaAdditions();
var utils = require('utils');

/**
 * A single node in the Automation tree.
 * @param {AutomationRootNodeImpl} root The root of the tree.
 * @constructor
 */
function AutomationNodeImpl(root) {
  this.rootImpl = root;
  this.childIds = [];
  // Public attributes. No actual data gets set on this object.
  this.attributes = {};
  // Internal object holding all attributes.
  this.attributesInternal = {};
  this.listeners = {};
  this.location = { left: 0, top: 0, width: 0, height: 0 };
}

AutomationNodeImpl.prototype = {
  id: -1,
  role: '',
  state: { busy: true },
  isRootNode: false,

  get root() {
    return this.rootImpl.wrapper;
  },

  get parent() {
    return this.hostTree || this.rootImpl.get(this.parentID);
  },

  get firstChild() {
    return this.childTree || this.rootImpl.get(this.childIds[0]);
  },

  get lastChild() {
    var childIds = this.childIds;
    return this.childTree || this.rootImpl.get(childIds[childIds.length - 1]);
  },

  get children() {
    if (this.childTree)
      return [this.childTree];

    var children = [];
    for (var i = 0, childID; childID = this.childIds[i]; i++) {
      logging.CHECK(this.rootImpl.get(childID));
      children.push(this.rootImpl.get(childID));
    }
    return children;
  },

  get previousSibling() {
    var parent = this.parent;
    if (parent && this.indexInParent > 0)
      return parent.children[this.indexInParent - 1];
    return undefined;
  },

  get nextSibling() {
    var parent = this.parent;
    if (parent && this.indexInParent < parent.children.length)
      return parent.children[this.indexInParent + 1];
    return undefined;
  },

  doDefault: function() {
    this.performAction_('doDefault');
  },

  focus: function() {
    this.performAction_('focus');
  },

  makeVisible: function() {
    this.performAction_('makeVisible');
  },

  setSelection: function(startIndex, endIndex) {
    this.performAction_('setSelection',
                        { startIndex: startIndex,
                          endIndex: endIndex });
  },

  showContextMenu: function() {
    this.performAction_('showContextMenu');
  },

  domQuerySelector: function(selector, callback) {
    automationInternal.querySelector(
      { treeID: this.rootImpl.treeID,
        automationNodeID: this.id,
        selector: selector },
      this.domQuerySelectorCallback_.bind(this, callback));
  },

  find: function(params) {
    return this.findInternal_(params);
  },

  findAll: function(params) {
    return this.findInternal_(params, []);
  },

  matches: function(params) {
    return this.matchInternal_(params);
  },

  addEventListener: function(eventType, callback, capture) {
    this.removeEventListener(eventType, callback);
    if (!this.listeners[eventType])
      this.listeners[eventType] = [];
    this.listeners[eventType].push({callback: callback, capture: !!capture});
  },

  // TODO(dtseng/aboxhall): Check this impl against spec.
  removeEventListener: function(eventType, callback) {
    if (this.listeners[eventType]) {
      var listeners = this.listeners[eventType];
      for (var i = 0; i < listeners.length; i++) {
        if (callback === listeners[i].callback)
          listeners.splice(i, 1);
      }
    }
  },

  toJSON: function() {
    return { treeID: this.treeID,
             id: this.id,
             role: this.role,
             attributes: this.attributes };
  },

  dispatchEvent: function(eventType) {
    var path = [];
    var parent = this.parent;
    while (parent) {
      path.push(parent);
      parent = parent.parent;
    }
    var event = new AutomationEvent(eventType, this.wrapper);

    // Dispatch the event through the propagation path in three phases:
    // - capturing: starting from the root and going down to the target's parent
    // - targeting: dispatching the event on the target itself
    // - bubbling: starting from the target's parent, going back up to the root.
    // At any stage, a listener may call stopPropagation() on the event, which
    // will immediately stop event propagation through this path.
    if (this.dispatchEventAtCapturing_(event, path)) {
      if (this.dispatchEventAtTargeting_(event, path))
        this.dispatchEventAtBubbling_(event, path);
    }
  },

  toString: function() {
    var impl = privates(this).impl;
    if (!impl)
      impl = this;
    return 'node id=' + impl.id +
        ' role=' + this.role +
        ' state=' + $JSON.stringify(this.state) +
        ' parentID=' + impl.parentID +
        ' childIds=' + $JSON.stringify(impl.childIds) +
        ' attributes=' + $JSON.stringify(this.attributes);
  },

  dispatchEventAtCapturing_: function(event, path) {
    privates(event).impl.eventPhase = Event.CAPTURING_PHASE;
    for (var i = path.length - 1; i >= 0; i--) {
      this.fireEventListeners_(path[i], event);
      if (privates(event).impl.propagationStopped)
        return false;
    }
    return true;
  },

  dispatchEventAtTargeting_: function(event) {
    privates(event).impl.eventPhase = Event.AT_TARGET;
    this.fireEventListeners_(this.wrapper, event);
    return !privates(event).impl.propagationStopped;
  },

  dispatchEventAtBubbling_: function(event, path) {
    privates(event).impl.eventPhase = Event.BUBBLING_PHASE;
    for (var i = 0; i < path.length; i++) {
      this.fireEventListeners_(path[i], event);
      if (privates(event).impl.propagationStopped)
        return false;
    }
    return true;
  },

  fireEventListeners_: function(node, event) {
    var nodeImpl = privates(node).impl;
    var listeners = nodeImpl.listeners[event.type];
    if (!listeners)
      return;
    var eventPhase = event.eventPhase;
    for (var i = 0; i < listeners.length; i++) {
      if (eventPhase == Event.CAPTURING_PHASE && !listeners[i].capture)
        continue;
      if (eventPhase == Event.BUBBLING_PHASE && listeners[i].capture)
        continue;

      try {
        listeners[i].callback(event);
      } catch (e) {
        console.error('Error in event handler for ' + event.type +
                      'during phase ' + eventPhase + ': ' +
                      e.message + '\nStack trace: ' + e.stack);
      }
    }
  },

  performAction_: function(actionType, opt_args) {
    // Not yet initialized.
    if (this.rootImpl.treeID === undefined ||
        this.id === undefined) {
      return;
    }

    // Check permissions.
    if (!IsInteractPermitted()) {
      throw new Error(actionType + ' requires {"desktop": true} or' +
          ' {"interact": true} in the "automation" manifest key.');
    }

    automationInternal.performAction({ treeID: this.rootImpl.treeID,
                                       automationNodeID: this.id,
                                       actionType: actionType },
                                     opt_args || {});
  },

  domQuerySelectorCallback_: function(userCallback, resultAutomationNodeID) {
    // resultAutomationNodeID could be zero or undefined or (unlikely) null;
    // they all amount to the same thing here, which is that no node was
    // returned.
    if (!resultAutomationNodeID) {
      userCallback(null);
      return;
    }
    var resultNode = this.rootImpl.get(resultAutomationNodeID);
    if (!resultNode) {
      logging.WARNING('Query selector result not in tree: ' +
                      resultAutomationNodeID);
      userCallback(null);
    }
    userCallback(resultNode);
  },

  findInternal_: function(params, opt_results) {
    var result = null;
    this.forAllDescendants_(function(node) {
      if (privates(node).impl.matchInternal_(params)) {
        if (opt_results)
          opt_results.push(node);
        else
          result = node;
        return !opt_results;
      }
    });
    if (opt_results)
      return opt_results;
    return result;
  },

  /**
   * Executes a closure for all of this node's descendants, in pre-order.
   * Early-outs if the closure returns true.
   * @param {Function(AutomationNode):boolean} closure Closure to be executed
   *     for each node. Return true to early-out the traversal.
   */
  forAllDescendants_: function(closure) {
    var stack = this.wrapper.children.reverse();
    while (stack.length > 0) {
      var node = stack.pop();
      if (closure(node))
        return;

      var children = node.children;
      for (var i = children.length - 1; i >= 0; i--)
        stack.push(children[i]);
    }
  },

  matchInternal_: function(params) {
    if (Object.keys(params).length == 0)
      return false;

    if ('role' in params && this.role != params.role)
        return false;

    if ('state' in params) {
      for (var state in params.state) {
        if (params.state[state] != (state in this.state))
          return false;
      }
    }
    if ('attributes' in params) {
      for (var attribute in params.attributes) {
        if (!(attribute in this.attributesInternal))
          return false;

        var attrValue = params.attributes[attribute];
        if (typeof attrValue != 'object') {
          if (this.attributesInternal[attribute] !== attrValue)
            return false;
        } else if (attrValue instanceof RegExp) {
          if (typeof this.attributesInternal[attribute] != 'string')
            return false;
          if (!attrValue.test(this.attributesInternal[attribute]))
            return false;
        } else {
          // TODO(aboxhall): handle intlist case.
          return false;
        }
      }
    }
    return true;
  }
};

// Maps an attribute to its default value in an invalidated node.
// These attributes are taken directly from the Automation idl.
var AutomationAttributeDefaults = {
  'id': -1,
  'role': '',
  'state': {},
  'location': { left: 0, top: 0, width: 0, height: 0 }
};


var AutomationAttributeTypes = [
  'boolAttributes',
  'floatAttributes',
  'htmlAttributes',
  'intAttributes',
  'intlistAttributes',
  'stringAttributes'
];

/**
 * Maps an attribute name to another attribute who's value is an id or an array
 * of ids referencing an AutomationNode.
 * @param {!Object<string>}
 * @const
 */
var ATTRIBUTE_NAME_TO_ID_ATTRIBUTE = {
  'aria-activedescendant': 'activedescendantId',
  'aria-controls': 'controlsIds',
  'aria-describedby': 'describedbyIds',
  'aria-flowto': 'flowtoIds',
  'aria-labelledby': 'labelledbyIds',
  'aria-owns': 'ownsIds'
};

/**
 * A set of attributes ignored in the automation API.
 * @param {!Object<boolean>}
 * @const
 */
var ATTRIBUTE_BLACKLIST = {'activedescendantId': true,
                           'childTreeId': true,
                           'controlsIds': true,
                           'describedbyIds': true,
                           'flowtoIds': true,
                           'labelledbyIds': true,
                           'ownsIds': true
};

function defaultStringAttribute(opt_defaultVal) {
  return { default: undefined, reflectFrom: 'stringAttributes' };
}

function defaultIntAttribute(opt_defaultVal) {
  var defaultVal = (opt_defaultVal !== undefined) ? opt_defaultVal : 0;
  return { default: defaultVal, reflectFrom: 'intAttributes' };
}

function defaultFloatAttribute(opt_defaultVal) {
  var defaultVal = (opt_defaultVal !== undefined) ? opt_defaultVal : 0;
  return { default: defaultVal, reflectFrom: 'floatAttributes' };
}

function defaultBoolAttribute(opt_defaultVal) {
  var defaultVal = (opt_defaultVal !== undefined) ? opt_defaultVal : false;
  return { default: defaultVal, reflectFrom: 'boolAttributes' };
}

function defaultHtmlAttribute(opt_defaultVal) {
  var defaultVal = (opt_defaultVal !== undefined) ? opt_defaultVal : '';
  return { default: defaultVal, reflectFrom: 'htmlAttributes' };
}

function defaultIntListAttribute(opt_defaultVal) {
  var defaultVal = (opt_defaultVal !== undefined) ? opt_defaultVal : [];
  return { default: defaultVal, reflectFrom: 'intlistAttributes' };
}

function defaultNodeRefAttribute(idAttribute, opt_defaultVal) {
  var defaultVal = (opt_defaultVal !== undefined) ? opt_defaultVal : null;
  return { default: defaultVal,
           idFrom: 'intAttributes',
           idAttribute: idAttribute,
           isRef: true };
}

function defaultNodeRefListAttribute(idAttribute, opt_defaultVal) {
  var defaultVal = (opt_defaultVal !== undefined) ? opt_defaultVal : [];
  return { default: [],
           idFrom: 'intlistAttributes',
           idAttribute: idAttribute,
           isRef: true };
}

// Maps an attribute to its default value in an invalidated node.
// These attributes are taken directly from the Automation idl.
var DefaultMixinAttributes = {
  description: defaultStringAttribute(),
  help: defaultStringAttribute(),
  name: defaultStringAttribute(),
  value: defaultStringAttribute(),
  htmlTag: defaultStringAttribute(),
  hierarchicalLevel: defaultIntAttribute(),
  controls: defaultNodeRefListAttribute('controlsIds'),
  describedby: defaultNodeRefListAttribute('describedbyIds'),
  flowto: defaultNodeRefListAttribute('flowtoIds'),
  labelledby: defaultNodeRefListAttribute('labelledbyIds'),
  owns: defaultNodeRefListAttribute('ownsIds'),
  wordStarts: defaultIntListAttribute(),
  wordEnds: defaultIntListAttribute()
};

var ActiveDescendantMixinAttribute = {
  activedescendant: defaultNodeRefAttribute('activedescendantId')
};

var LinkMixinAttributes = {
  url: defaultStringAttribute()
};

var DocumentMixinAttributes = {
  docUrl: defaultStringAttribute(),
  docTitle: defaultStringAttribute(),
  docLoaded: defaultStringAttribute(),
  docLoadingProgress: defaultFloatAttribute()
};

var ScrollableMixinAttributes = {
  scrollX: defaultIntAttribute(),
  scrollXMin: defaultIntAttribute(),
  scrollXMax: defaultIntAttribute(),
  scrollY: defaultIntAttribute(),
  scrollYMin: defaultIntAttribute(),
  scrollYMax: defaultIntAttribute()
};

var EditableTextMixinAttributes = {
  textSelStart: defaultIntAttribute(-1),
  textSelEnd: defaultIntAttribute(-1),
  type: defaultHtmlAttribute()
};

var RangeMixinAttributes = {
  valueForRange: defaultFloatAttribute(),
  minValueForRange: defaultFloatAttribute(),
  maxValueForRange: defaultFloatAttribute()
};

var TableMixinAttributes = {
  tableRowCount: defaultIntAttribute(),
  tableColumnCount: defaultIntAttribute()
};

var TableCellMixinAttributes = {
  tableCellColumnIndex: defaultIntAttribute(),
  tableCellColumnSpan: defaultIntAttribute(1),
  tableCellRowIndex: defaultIntAttribute(),
  tableCellRowSpan: defaultIntAttribute(1)
};

var LiveRegionMixinAttributes = {
  containerLiveAtomic: defaultBoolAttribute(),
  containerLiveBusy: defaultBoolAttribute(),
  containerLiveRelevant: defaultStringAttribute(),
  containerLiveStatus: defaultStringAttribute(),
};

/**
 * AutomationRootNode.
 *
 * An AutomationRootNode is the javascript end of an AXTree living in the
 * browser. AutomationRootNode handles unserializing incremental updates from
 * the source AXTree. Each update contains node data that form a complete tree
 * after applying the update.
 *
 * A brief note about ids used through this class. The source AXTree assigns
 * unique ids per node and we use these ids to build a hash to the actual
 * AutomationNode object.
 * Thus, tree traversals amount to a lookup in our hash.
 *
 * The tree itself is identified by the accessibility tree id of the
 * renderer widget host.
 * @constructor
 */
function AutomationRootNodeImpl(treeID) {
  AutomationNodeImpl.call(this, this);
  this.treeID = treeID;
  this.axNodeDataCache_ = {};
}

AutomationRootNodeImpl.prototype = {
  __proto__: AutomationNodeImpl.prototype,

  isRootNode: true,
  treeID: -1,

  get: function(id) {
    if (id == undefined)
      return undefined;

    return this.axNodeDataCache_[id];
  },

  unserialize: function(update) {
    var updateState = { pendingNodes: {}, newNodes: {} };
    var oldRootId = this.id;

    if (update.nodeIdToClear < 0) {
        logging.WARNING('Bad nodeIdToClear: ' + update.nodeIdToClear);
        lastError.set('automation',
                      'Bad update received on automation tree',
                      null,
                      chrome);
        return false;
    } else if (update.nodeIdToClear > 0) {
      var nodeToClear = this.axNodeDataCache_[update.nodeIdToClear];
      if (!nodeToClear) {
        logging.WARNING('Bad nodeIdToClear: ' + update.nodeIdToClear +
                        ' (not in cache)');
        lastError.set('automation',
                      'Bad update received on automation tree',
                      null,
                      chrome);
        return false;
      }
      if (nodeToClear === this.wrapper) {
        this.invalidate_(nodeToClear);
      } else {
        var children = nodeToClear.children;
        for (var i = 0; i < children.length; i++)
          this.invalidate_(children[i]);
        var nodeToClearImpl = privates(nodeToClear).impl;
        nodeToClearImpl.childIds = []
        updateState.pendingNodes[nodeToClearImpl.id] = nodeToClear;
      }
    }

    for (var i = 0; i < update.nodes.length; i++) {
      if (!this.updateNode_(update.nodes[i], updateState))
        return false;
    }

    if (Object.keys(updateState.pendingNodes).length > 0) {
      logging.WARNING('Nodes left pending by the update: ' +
          $JSON.stringify(updateState.pendingNodes));
      lastError.set('automation',
                    'Bad update received on automation tree',
                    null,
                    chrome);
      return false;
    }

    // Notify tree change observers of new nodes.
    // TODO(dmazzoni): Notify tree change observers of changed nodes,
    // and handle subtreeCreated and nodeCreated properly.
    var observers = automationUtil.treeChangeObservers;
    if (observers.length > 0) {
      for (var nodeId in updateState.newNodes) {
        var node = updateState.newNodes[nodeId];
        var treeChange =
            {target: node, type: schema.TreeChangeType.nodeCreated};
        for (var i = 0; i < observers.length; i++) {
          try {
            observers[i](treeChange);
          } catch (e) {
            console.error('Error in tree change observer for ' +
                treeChange.type + ': ' + e.message +
                '\nStack trace: ' + e.stack);
          }
        }
      }
    }

    return true;
  },

  destroy: function() {
    if (this.hostTree)
      this.hostTree.childTree = undefined;
    this.hostTree = undefined;

    this.dispatchEvent(schema.EventType.destroyed);
    this.invalidate_(this.wrapper);
  },

  onAccessibilityEvent: function(eventParams) {
    if (!this.unserialize(eventParams.update)) {
      logging.WARNING('unserialization failed');
      return false;
    }

    var targetNode = this.get(eventParams.targetID);
    if (targetNode) {
      var targetNodeImpl = privates(targetNode).impl;
      targetNodeImpl.dispatchEvent(eventParams.eventType);
    } else {
      logging.WARNING('Got ' + eventParams.eventType +
                      ' event on unknown node: ' + eventParams.targetID +
                      '; this: ' + this.id);
    }
    return true;
  },

  toString: function() {
    function toStringInternal(node, indent) {
      if (!node)
        return '';
      var output =
          new Array(indent).join(' ') +
          AutomationNodeImpl.prototype.toString.call(node) +
          '\n';
      indent += 2;
      for (var i = 0; i < node.children.length; i++)
        output += toStringInternal(node.children[i], indent);
      return output;
    }
    return toStringInternal(this, 0);
  },

  invalidate_: function(node) {
    if (!node)
      return;

    // Notify tree change observers of the removed node.
    var observers = automationUtil.treeChangeObservers;
    if (observers.length > 0) {
      var treeChange = {target: node, type: schema.TreeChangeType.nodeRemoved};
      for (var i = 0; i < observers.length; i++) {
        try {
          observers[i](treeChange);
        } catch (e) {
          console.error('Error in tree change observer for ' + treeChange.type +
              ': ' + e.message + '\nStack trace: ' + e.stack);
        }
      }
    }

    var children = node.children;

    for (var i = 0, child; child = children[i]; i++) {
      // Do not invalidate into subrooted nodes.
      // TODO(dtseng): Revisit logic once out of proc iframes land.
      if (child.root != node.root)
        continue;
      this.invalidate_(child);
    }

    // Retrieve the internal AutomationNodeImpl instance for this node.
    // This object is not accessible outside of bindings code, but we can access
    // it here.
    var nodeImpl = privates(node).impl;
    var id = nodeImpl.id;
    for (var key in AutomationAttributeDefaults) {
      nodeImpl[key] = AutomationAttributeDefaults[key];
    }

    nodeImpl.attributesInternal = {};
    for (var key in DefaultMixinAttributes) {
      var mixinAttribute = DefaultMixinAttributes[key];
      if (!mixinAttribute.isRef)
        nodeImpl.attributesInternal[key] = mixinAttribute.default;
    }
    nodeImpl.childIds = [];
    nodeImpl.id = id;
    delete this.axNodeDataCache_[id];
  },

  deleteOldChildren_: function(node, newChildIds) {
    // Create a set of child ids in |src| for fast lookup, and return false
    // if a duplicate is found;
    var newChildIdSet = {};
    for (var i = 0; i < newChildIds.length; i++) {
      var childId = newChildIds[i];
      if (newChildIdSet[childId]) {
        logging.WARNING('Node ' + privates(node).impl.id +
                        ' has duplicate child id ' + childId);
        lastError.set('automation',
                      'Bad update received on automation tree',
                      null,
                      chrome);
        return false;
      }
      newChildIdSet[newChildIds[i]] = true;
    }

    // Delete the old children.
    var nodeImpl = privates(node).impl;
    var oldChildIds = nodeImpl.childIds;
    for (var i = 0; i < oldChildIds.length;) {
      var oldId = oldChildIds[i];
      if (!newChildIdSet[oldId]) {
        this.invalidate_(this.axNodeDataCache_[oldId]);
        oldChildIds.splice(i, 1);
      } else {
        i++;
      }
    }
    nodeImpl.childIds = oldChildIds;

    return true;
  },

  createNewChildren_: function(node, newChildIds, updateState) {
    logging.CHECK(node);
    var success = true;

    for (var i = 0; i < newChildIds.length; i++) {
      var childId = newChildIds[i];
      var childNode = this.axNodeDataCache_[childId];
      if (childNode) {
        if (childNode.parent != node) {
          var parentId = -1;
          if (childNode.parent) {
            var parentImpl = privates(childNode.parent).impl;
            parentId = parentImpl.id;
          }
          // This is a serious error - nodes should never be reparented.
          // If this case occurs, continue so this node isn't left in an
          // inconsistent state, but return failure at the end.
          logging.WARNING('Node ' + childId + ' reparented from ' +
                          parentId + ' to ' + privates(node).impl.id);
          lastError.set('automation',
                        'Bad update received on automation tree',
                        null,
                        chrome);
          success = false;
          continue;
        }
      } else {
        childNode = new AutomationNode(this);
        this.axNodeDataCache_[childId] = childNode;
        privates(childNode).impl.id = childId;
        updateState.pendingNodes[childId] = childNode;
        updateState.newNodes[childId] = childNode;
      }
      privates(childNode).impl.indexInParent = i;
      privates(childNode).impl.parentID = privates(node).impl.id;
    }

    return success;
  },

  setData_: function(node, nodeData) {
    var nodeImpl = privates(node).impl;

    // TODO(dtseng): Make into set listing all hosting node roles.
    if (nodeData.role == schema.RoleType.webView ||
        nodeData.role == schema.RoleType.embeddedObject) {
      if (nodeImpl.childTreeID !== nodeData.intAttributes.childTreeId)
        nodeImpl.pendingChildFrame = true;

      if (nodeImpl.pendingChildFrame) {
        nodeImpl.childTreeID = nodeData.intAttributes.childTreeId;
        automationUtil.storeTreeCallback(nodeImpl.childTreeID, function(root) {
          nodeImpl.pendingChildFrame = false;
          nodeImpl.childTree = root;
          privates(root).impl.hostTree = node;
          if (root.attributes.docLoadingProgress == 1)
            privates(root).impl.dispatchEvent(schema.EventType.loadComplete);
          nodeImpl.dispatchEvent(schema.EventType.childrenChanged);
        });
        automationInternal.enableFrame(nodeImpl.childTreeID);
      }
    }
    for (var key in AutomationAttributeDefaults) {
      if (key in nodeData)
        nodeImpl[key] = nodeData[key];
      else
        nodeImpl[key] = AutomationAttributeDefaults[key];
    }

    // Set all basic attributes.
    this.mixinAttributes_(nodeImpl, DefaultMixinAttributes, nodeData);

    // If this is a rootWebArea or webArea, set document attributes.
    if (nodeData.role == schema.RoleType.rootWebArea ||
        nodeData.role == schema.RoleType.webArea) {
      this.mixinAttributes_(nodeImpl, DocumentMixinAttributes, nodeData);
    }

    // If this is a scrollable area, set scrollable attributes.
    for (var scrollAttr in ScrollableMixinAttributes) {
      var spec = ScrollableMixinAttributes[scrollAttr];
      if (this.findAttribute_(scrollAttr, spec, nodeData) !== undefined) {
        this.mixinAttributes_(nodeImpl, ScrollableMixinAttributes, nodeData);
        break;
      }
    }

    // If this is inside a live region, set live region mixins.
    var attr = 'containerLiveStatus';
    var spec = LiveRegionMixinAttributes[attr];
    if (this.findAttribute_(attr, spec, nodeData) !== undefined) {
      this.mixinAttributes_(nodeImpl, LiveRegionMixinAttributes, nodeData);
    }

    // If this is a link, set link attributes
    if (nodeData.role == 'link') {
      this.mixinAttributes_(nodeImpl, LinkMixinAttributes, nodeData);
    }

    // If this is an editable text area, set editable text attributes.
    if (nodeData.role == schema.RoleType.textField ||
        nodeData.role == schema.RoleType.spinButton) {
      this.mixinAttributes_(nodeImpl, EditableTextMixinAttributes, nodeData);
    }

    // If this is a range type, set range attributes.
    if (nodeData.role == schema.RoleType.progressIndicator ||
        nodeData.role == schema.RoleType.scrollBar ||
        nodeData.role == schema.RoleType.slider ||
        nodeData.role == schema.RoleType.spinButton) {
      this.mixinAttributes_(nodeImpl, RangeMixinAttributes, nodeData);
    }

    // If this is a table, set table attributes.
    if (nodeData.role == schema.RoleType.table) {
      this.mixinAttributes_(nodeImpl, TableMixinAttributes, nodeData);
    }

    // If this is a table cell, set table cell attributes.
    if (nodeData.role == schema.RoleType.cell) {
      this.mixinAttributes_(nodeImpl, TableCellMixinAttributes, nodeData);
    }

    // If this has an active descendant, expose it.
    if ('intAttributes' in nodeData &&
        'activedescendantId' in nodeData.intAttributes) {
      this.mixinAttributes_(nodeImpl, ActiveDescendantMixinAttribute, nodeData);
    }

    for (var i = 0; i < AutomationAttributeTypes.length; i++) {
      var attributeType = AutomationAttributeTypes[i];
      for (var attributeName in nodeData[attributeType]) {
        nodeImpl.attributesInternal[attributeName] =
            nodeData[attributeType][attributeName];
        if (ATTRIBUTE_BLACKLIST.hasOwnProperty(attributeName) ||
            nodeImpl.attributes.hasOwnProperty(attributeName)) {
          continue;
        } else if (
          ATTRIBUTE_NAME_TO_ID_ATTRIBUTE.hasOwnProperty(attributeName)) {
          this.defineReadonlyAttribute_(nodeImpl,
                                        nodeImpl.attributes,
                                        attributeName,
                                        true);
        } else {
          this.defineReadonlyAttribute_(nodeImpl,
                                        nodeImpl.attributes,
                                        attributeName);
        }
      }
    }
  },

  mixinAttributes_: function(nodeImpl, attributes, nodeData) {
    for (var attribute in attributes) {
      var spec = attributes[attribute];
      if (spec.isRef)
        this.mixinRelationshipAttribute_(nodeImpl, attribute, spec, nodeData);
      else
        this.mixinAttribute_(nodeImpl, attribute, spec, nodeData);
    }
  },

  mixinAttribute_: function(nodeImpl, attribute, spec, nodeData) {
    var value = this.findAttribute_(attribute, spec, nodeData);
    if (value === undefined)
      value = spec.default;
    nodeImpl.attributesInternal[attribute] = value;
    this.defineReadonlyAttribute_(nodeImpl, nodeImpl, attribute);
  },

  mixinRelationshipAttribute_: function(nodeImpl, attribute, spec, nodeData) {
    var idAttribute = spec.idAttribute;
    var idValue = spec.default;
    if (spec.idFrom in nodeData) {
      idValue = idAttribute in nodeData[spec.idFrom]
          ? nodeData[spec.idFrom][idAttribute] : idValue;
    }

    // Ok to define a list attribute with an empty list, but not a
    // single ref with a null ID.
    if (idValue === null)
      return;

    nodeImpl.attributesInternal[idAttribute] = idValue;
    this.defineReadonlyAttribute_(
      nodeImpl, nodeImpl, attribute, true, idAttribute);
  },

  findAttribute_: function(attribute, spec, nodeData) {
    if (!('reflectFrom' in spec))
      return;
    var attributeGroup = spec.reflectFrom;
    if (!(attributeGroup in nodeData))
      return;

    return nodeData[attributeGroup][attribute];
  },

  defineReadonlyAttribute_: function(
      node, object, attributeName, opt_isIDRef, opt_idAttribute) {
    if (attributeName in object)
      return;

    if (opt_isIDRef) {
      $Object.defineProperty(object, attributeName, {
        enumerable: true,
        get: function() {
          var idAttribute = opt_idAttribute ||
                            ATTRIBUTE_NAME_TO_ID_ATTRIBUTE[attributeName];
          var idValue = node.attributesInternal[idAttribute];
          if (Array.isArray(idValue)) {
            return idValue.map(function(current) {
              return node.rootImpl.get(current);
            }, this);
          }
          return node.rootImpl.get(idValue);
        }.bind(this),
      });
    } else {
      $Object.defineProperty(object, attributeName, {
        enumerable: true,
        get: function() {
          return node.attributesInternal[attributeName];
        }.bind(this),
      });
    }

    if (object instanceof AutomationNodeImpl) {
      // Also expose attribute publicly on the wrapper.
      $Object.defineProperty(object.wrapper, attributeName, {
        enumerable: true,
        get: function() {
          return object[attributeName];
        },
      });

    }
  },

  updateNode_: function(nodeData, updateState) {
    var node = this.axNodeDataCache_[nodeData.id];
    var didUpdateRoot = false;
    if (node) {
      delete updateState.pendingNodes[privates(node).impl.id];
    } else {
      if (nodeData.role != schema.RoleType.rootWebArea &&
          nodeData.role != schema.RoleType.desktop) {
        logging.WARNING(String(nodeData.id) +
                     ' is not in the cache and not the new root.');
        lastError.set('automation',
                      'Bad update received on automation tree',
                      null,
                      chrome);
        return false;
      }
      // |this| is an AutomationRootNodeImpl; retrieve the
      // AutomationRootNode instance instead.
      node = this.wrapper;
      didUpdateRoot = true;
      updateState.newNodes[this.id] = this.wrapper;
    }
    this.setData_(node, nodeData);

    // TODO(aboxhall): send onChanged event?
    logging.CHECK(node);
    if (!this.deleteOldChildren_(node, nodeData.childIds)) {
      if (didUpdateRoot) {
        this.invalidate_(this.wrapper);
      }
      return false;
    }
    var nodeImpl = privates(node).impl;

    var success = this.createNewChildren_(node,
                                          nodeData.childIds,
                                          updateState);
    nodeImpl.childIds = nodeData.childIds;
    this.axNodeDataCache_[nodeImpl.id] = node;

    return success;
  }
};


var AutomationNode = utils.expose('AutomationNode',
                                  AutomationNodeImpl,
                                  { functions: ['doDefault',
                                                'find',
                                                'findAll',
                                                'focus',
                                                'makeVisible',
                                                'matches',
                                                'setSelection',
                                                'showContextMenu',
                                                'addEventListener',
                                                'removeEventListener',
                                                'domQuerySelector',
                                                'toString' ],
                                    readonly: ['parent',
                                               'firstChild',
                                               'lastChild',
                                               'children',
                                               'previousSibling',
                                               'nextSibling',
                                               'isRootNode',
                                               'role',
                                               'state',
                                               'location',
                                               'attributes',
                                               'indexInParent',
                                               'root'] });

var AutomationRootNode = utils.expose('AutomationRootNode',
                                      AutomationRootNodeImpl,
                                      { superclass: AutomationNode });

exports.AutomationNode = AutomationNode;
exports.AutomationRootNode = AutomationRootNode;
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the browserAction API.

var binding = require('binding').Binding.create('browserAction');

var setIcon = require('setIcon').setIcon;
var getExtensionViews = requireNative('runtime').GetExtensionViews;
var sendRequest = require('sendRequest').sendRequest;
var lastError = require('lastError');

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setHandleRequest('setIcon', function(details, callback) {
    setIcon(details, function(args) {
      sendRequest(this.name, [args, callback], this.definition.parameters);
    }.bind(this));
  });

  apiFunctions.setCustomCallback('openPopup',
      function(name, request, callback, response) {
    if (!callback)
      return;

    if (lastError.hasError(chrome)) {
      callback();
    } else {
      var views = getExtensionViews(-1, 'POPUP');
      callback(views.length > 0 ? views[0] : null);
    }
  });
});

exports.binding = binding.generate();
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the Cast Streaming RtpStream API.

var binding = require('binding').Binding.create('cast.streaming.rtpStream');
var natives = requireNative('cast_streaming_natives');

binding.registerCustomHook(function(bindingsAPI, extensionId) {
  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setHandleRequest('destroy',
      function(transportId) {
        natives.DestroyCastRtpStream(transportId);
  });
  apiFunctions.setHandleRequest('getSupportedParams',
      function(transportId) {
        return natives.GetSupportedParamsCastRtpStream(transportId);
  });
  apiFunctions.setHandleRequest('start',
      function(transportId, params) {
        natives.StartCastRtpStream(transportId, params);
  });
  apiFunctions.setHandleRequest('stop',
      function(transportId) {
        natives.StopCastRtpStream(transportId);
  });
  apiFunctions.setHandleRequest('toggleLogging',
      function(transportId, enable) {
        natives.ToggleLogging(transportId, enable);
  });
  apiFunctions.setHandleRequest('getRawEvents',
      function(transportId, extraData, callback) {
        natives.GetRawEvents(transportId, extraData, callback);
  });
  apiFunctions.setHandleRequest('getStats',
      function(transportId, callback) {
        natives.GetStats(transportId, callback);
  });
});

exports.binding = binding.generate();
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the Cast Streaming Session API.

var binding = require('binding').Binding.create('cast.streaming.session');
var natives = requireNative('cast_streaming_natives');

binding.registerCustomHook(function(bindingsAPI, extensionId) {
  var apiFunctions = bindingsAPI.apiFunctions;
  apiFunctions.setHandleRequest('create',
      function(audioTrack, videoTrack, callback) {
        natives.CreateSession(audioTrack, videoTrack, callback);
  });
});

exports.binding = binding.generate();
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the Cast Streaming UdpTransport API.

var binding = require('binding').Binding.create('cast.streaming.udpTransport');
var natives = requireNative('cast_streaming_natives');

binding.registerCustomHook(function(bindingsAPI, extensionId) {
  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setHandleRequest('destroy', function(transportId) {
    natives.DestroyCastUdpTransport(transportId);
  });
  apiFunctions.setHandleRequest('setDestination',
    function(transportId, destination) {
      natives.SetDestinationCastUdpTransport(transportId, destination);
  });
  apiFunctions.setHandleRequest('setOptions',
    function(transportId, options) {
      natives.SetOptionsCastUdpTransport(transportId, options);
  });
});

exports.binding = binding.generate();
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the Cast Streaming Session API.

var binding = require('binding').Binding.create(
    'cast.streaming.receiverSession');
var natives = requireNative('cast_streaming_natives');

binding.registerCustomHook(function(bindingsAPI, extensionId) {
  var apiFunctions = bindingsAPI.apiFunctions;
  apiFunctions.setHandleRequest('createAndBind',
      function(ap, vp, local, weidgth, height, fr, url, cb, op) {
        natives.StartCastRtpReceiver(
            ap, vp, local, weidgth, height, fr, url, cb, op);
  });
});

exports.binding = binding.generate();
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var Event = require('event_bindings').Event;
var sendRequest = require('sendRequest').sendRequest;
var validate = require('schemaUtils').validate;

function extendSchema(schema) {
  var extendedSchema = $Array.slice(schema);
  extendedSchema.unshift({'type': 'string'});
  return extendedSchema;
}

function ChromeDirectSetting(prefKey, valueSchema) {
  this.get = function(details, callback) {
    var getSchema = this.functionSchemas.get.definition.parameters;
    validate([details, callback], getSchema);
    return sendRequest('types.private.ChromeDirectSetting.get',
                       [prefKey, details, callback],
                       extendSchema(getSchema));
  };
  this.set = function(details, callback) {
    var setSchema = $Array.slice(
        this.functionSchemas.set.definition.parameters);
    setSchema[0].properties.value = valueSchema;
    validate([details, callback], setSchema);
    return sendRequest('types.private.ChromeDirectSetting.set',
                       [prefKey, details, callback],
                       extendSchema(setSchema));
  };
  this.clear = function(details, callback) {
    var clearSchema = this.functionSchemas.clear.definition.parameters;
    validate([details, callback], clearSchema);
    return sendRequest('types.private.ChromeDirectSetting.clear',
                       [prefKey, details, callback],
                       extendSchema(clearSchema));
  };
  this.onChange = new Event('types.private.ChromeDirectSetting.' +
                            prefKey +
                            '.onChange');
};

exports.ChromeDirectSetting = ChromeDirectSetting;

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var Event = require('event_bindings').Event;
var sendRequest = require('sendRequest').sendRequest;
var validate = require('schemaUtils').validate;

function extendSchema(schema) {
  var extendedSchema = $Array.slice(schema);
  extendedSchema.unshift({'type': 'string'});
  return extendedSchema;
}

function ChromeSetting(prefKey, valueSchema) {
  this.get = function(details, callback) {
    var getSchema = this.functionSchemas.get.definition.parameters;
    validate([details, callback], getSchema);
    return sendRequest('types.ChromeSetting.get',
                       [prefKey, details, callback],
                       extendSchema(getSchema));
  };
  this.set = function(details, callback) {
    var setSchema = $Array.slice(
        this.functionSchemas.set.definition.parameters);
    setSchema[0].properties.value = valueSchema;
    validate([details, callback], setSchema);
    return sendRequest('types.ChromeSetting.set',
                       [prefKey, details, callback],
                       extendSchema(setSchema));
  };
  this.clear = function(details, callback) {
    var clearSchema = this.functionSchemas.clear.definition.parameters;
    validate([details, callback], clearSchema);
    return sendRequest('types.ChromeSetting.clear',
                       [prefKey, details, callback],
                       extendSchema(clearSchema));
  };
  this.onChange = new Event('types.ChromeSetting.' + prefKey + '.onChange');
};

exports.ChromeSetting = ChromeSetting;
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var binding = require('binding').Binding.create('chromeWebViewInternal');
var contextMenusHandlers = require('contextMenusHandlers');

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  var handlers = contextMenusHandlers.create(true /* isWebview */);

  apiFunctions.setHandleRequest('contextMenusCreate',
      handlers.requestHandlers.create);

  apiFunctions.setCustomCallback('contextMenusCreate',
      handlers.callbacks.create);

  apiFunctions.setCustomCallback('contextMenusUpdate',
      handlers.callbacks.update);

  apiFunctions.setCustomCallback('contextMenusRemove',
      handlers.callbacks.remove);

  apiFunctions.setCustomCallback('contextMenusRemoveAll',
      handlers.callbacks.removeAll);

});

exports.ChromeWebView = binding.generate();
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This module implements chrome-specific <webview> API.
// See web_view_api_methods.js for details.

var ChromeWebView = require('chromeWebViewInternal').ChromeWebView;
var ChromeWebViewSchema =
    requireNative('schema_registry').GetSchema('chromeWebViewInternal');
var CreateEvent = require('guestViewEvents').CreateEvent;
var EventBindings = require('event_bindings');
var GuestViewInternalNatives = requireNative('guest_view_internal');
var idGeneratorNatives = requireNative('id_generator');
var Utils = require('utils');
var WebViewImpl = require('webView').WebViewImpl;

// This is the only "webViewInternal.onClicked" named event for this renderer.
//
// Since we need an event per <webview>, we define events with suffix
// (subEventName) in each of the <webview>. Behind the scenes, this event is
// registered as a ContextMenusEvent, with filter set to the webview's
// |viewInstanceId|. Any time a ContextMenusEvent is dispatched, we re-dispatch
// it to the subEvent's listeners. This way
// <webview>.contextMenus.onClicked behave as a regular chrome Event type.
var ContextMenusEvent = CreateEvent('chromeWebViewInternal.onClicked');
// See comment above.
var ContextMenusHandlerEvent =
    CreateEvent('chromeWebViewInternal.onContextMenuShow');

// -----------------------------------------------------------------------------
// ContextMenusOnClickedEvent object.

// This event is exposed as <webview>.contextMenus.onClicked.
function ContextMenusOnClickedEvent(webViewInstanceId,
                                    opt_eventName,
                                    opt_argSchemas,
                                    opt_eventOptions) {
  var subEventName = GetUniqueSubEventName(opt_eventName);
  EventBindings.Event.call(this,
                           subEventName,
                           opt_argSchemas,
                           opt_eventOptions,
                           webViewInstanceId);

  var view = GuestViewInternalNatives.GetViewFromID(webViewInstanceId);
  if (!view) {
    return;
  }
  view.events.addScopedListener(ContextMenusEvent, function() {
    // Re-dispatch to subEvent's listeners.
    $Function.apply(this.dispatch, this, $Array.slice(arguments));
  }.bind(this), {instanceId: webViewInstanceId});
}

ContextMenusOnClickedEvent.prototype.__proto__ = EventBindings.Event.prototype;

function ContextMenusOnContextMenuEvent(webViewInstanceId,
                                        opt_eventName,
                                        opt_argSchemas,
                                        opt_eventOptions) {
  var subEventName = GetUniqueSubEventName(opt_eventName);
  EventBindings.Event.call(this,
                           subEventName,
                           opt_argSchemas,
                           opt_eventOptions,
                           webViewInstanceId);

  var view = GuestViewInternalNatives.GetViewFromID(webViewInstanceId);
  if (!view) {
    return;
  }
  view.events.addScopedListener(ContextMenusHandlerEvent, function(e) {
    var defaultPrevented = false;
    var event = {
      'preventDefault': function() { defaultPrevented = true; }
    };

    // Re-dispatch to subEvent's listeners.
    $Function.apply(this.dispatch, this, [event]);

    if (!defaultPrevented) {
      // TODO(lazyboy): Remove |items| parameter completely from
      // ChromeWebView.showContextMenu as we don't do anything useful with it
      // currently.
      var items = [];
      var guestInstanceId = GuestViewInternalNatives.
          GetViewFromID(webViewInstanceId).guest.getId();
      ChromeWebView.showContextMenu(guestInstanceId, e.requestId, items);
    }
  }.bind(this), {instanceId: webViewInstanceId});
}

ContextMenusOnContextMenuEvent.prototype.__proto__ =
    EventBindings.Event.prototype;

// -----------------------------------------------------------------------------
// WebViewContextMenusImpl object.

// An instance of this class is exposed as <webview>.contextMenus.
function WebViewContextMenusImpl(viewInstanceId) {
  this.viewInstanceId_ = viewInstanceId;
}

WebViewContextMenusImpl.prototype.create = function() {
  var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
  return $Function.apply(ChromeWebView.contextMenusCreate, null, args);
};

WebViewContextMenusImpl.prototype.remove = function() {
  var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
  return $Function.apply(ChromeWebView.contextMenusRemove, null, args);
};

WebViewContextMenusImpl.prototype.removeAll = function() {
  var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
  return $Function.apply(ChromeWebView.contextMenusRemoveAll, null, args);
};

WebViewContextMenusImpl.prototype.update = function() {
  var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
  return $Function.apply(ChromeWebView.contextMenusUpdate, null, args);
};

var WebViewContextMenus = Utils.expose(
    'WebViewContextMenus', WebViewContextMenusImpl,
    { functions: ['create', 'remove', 'removeAll', 'update'] });

// -----------------------------------------------------------------------------

WebViewImpl.prototype.maybeSetupContextMenus = function() {
  if (!this.contextMenusOnContextMenuEvent_) {
    var eventName = 'chromeWebViewInternal.onContextMenuShow';
    var eventSchema =
        Utils.lookup(ChromeWebViewSchema.events, 'name', 'onShow');
    var eventOptions = {supportsListeners: true};
    this.contextMenusOnContextMenuEvent_ = new ContextMenusOnContextMenuEvent(
        this.viewInstanceId, eventName, eventSchema, eventOptions);
  }

  var createContextMenus = function() {
    return this.weakWrapper(function() {
      if (this.contextMenus_) {
        return this.contextMenus_;
      }

      this.contextMenus_ = new WebViewContextMenus(this.viewInstanceId);

      // Define 'onClicked' event property on |this.contextMenus_|.
      var getOnClickedEvent = function() {
        return this.weakWrapper(function() {
          if (!this.contextMenusOnClickedEvent_) {
            var eventName = 'chromeWebViewInternal.onClicked';
            var eventSchema =
                Utils.lookup(ChromeWebViewSchema.events, 'name', 'onClicked');
            var eventOptions = {supportsListeners: true};
            var onClickedEvent = new ContextMenusOnClickedEvent(
                this.viewInstanceId, eventName, eventSchema, eventOptions);
            this.contextMenusOnClickedEvent_ = onClickedEvent;
            return onClickedEvent;
          }
          return this.contextMenusOnClickedEvent_;
        });
      }.bind(this);
      $Object.defineProperty(
          this.contextMenus_,
          'onClicked',
          {get: getOnClickedEvent(), enumerable: true});
      $Object.defineProperty(
          this.contextMenus_,
          'onShow',
          {
            get: this.weakWrapper(function() {
              return this.contextMenusOnContextMenuEvent_;
            }),
            enumerable: true
          });
      return this.contextMenus_;
    });
  }.bind(this);

  // Expose <webview>.contextMenus object.
  // TODO(lazyboy): Add documentation for contextMenus:
  // http://crbug.com/470979.
  $Object.defineProperty(
      this.element,
      'contextMenus',
      {
        get: createContextMenus(),
        enumerable: true
      });
};

function GetUniqueSubEventName(eventName) {
  return eventName + '/' + idGeneratorNatives.GetNextId();
}
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the contentSettings API.

var sendRequest = require('sendRequest').sendRequest;
var validate = require('schemaUtils').validate;

function extendSchema(schema) {
  var extendedSchema = $Array.slice(schema);
  extendedSchema.unshift({'type': 'string'});
  return extendedSchema;
}

function ContentSetting(contentType, settingSchema) {
  this.get = function(details, callback) {
    var getSchema = this.functionSchemas.get.definition.parameters;
    validate([details, callback], getSchema);
    return sendRequest('contentSettings.get',
                       [contentType, details, callback],
                       extendSchema(getSchema));
  };
  this.set = function(details, callback) {
    var setSchema = $Array.slice(
        this.functionSchemas.set.definition.parameters);
    setSchema[0].properties.setting = settingSchema;
    validate([details, callback], setSchema);
    return sendRequest('contentSettings.set',
                       [contentType, details, callback],
                       extendSchema(setSchema));
  };
  this.clear = function(details, callback) {
    var clearSchema = this.functionSchemas.clear.definition.parameters;
    validate([details, callback], clearSchema);
    return sendRequest('contentSettings.clear',
                       [contentType, details, callback],
                       extendSchema(clearSchema));
  };
  this.getResourceIdentifiers = function(callback) {
    var schema =
        this.functionSchemas.getResourceIdentifiers.definition.parameters;
    validate([callback], schema);
    return sendRequest(
        'contentSettings.getResourceIdentifiers',
        [contentType, callback],
        extendSchema(schema));
  };
}

exports.ContentSetting = ContentSetting;
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the declarativeContent API.

var binding = require('binding').Binding.create('declarativeContent');

var utils = require('utils');
var validate = require('schemaUtils').validate;
var canonicalizeCompoundSelector =
    requireNative('css_natives').CanonicalizeCompoundSelector;
var setIcon = require('setIcon').setIcon;

binding.registerCustomHook( function(api) {
  var declarativeContent = api.compiledApi;

  // Returns the schema definition of type |typeId| defined in |namespace|.
  function getSchema(typeId) {
    return utils.lookup(api.schema.types,
                        'id',
                        'declarativeContent.' + typeId);
  }

  // Helper function for the constructor of concrete datatypes of the
  // declarative content API.
  // Makes sure that |this| contains the union of parameters and
  // {'instanceType': 'declarativeContent.' + typeId} and validates the
  // generated union dictionary against the schema for |typeId|.
  function setupInstance(instance, parameters, typeId) {
    for (var key in parameters) {
      if ($Object.hasOwnProperty(parameters, key)) {
        instance[key] = parameters[key];
      }
    }
    instance.instanceType = 'declarativeContent.' + typeId;
    var schema = getSchema(typeId);
    validate([instance], [schema]);
  }

  function canonicalizeCssSelectors(selectors) {
    for (var i = 0; i < selectors.length; i++) {
      var canonicalizedSelector = canonicalizeCompoundSelector(selectors[i]);
      if (canonicalizedSelector == '') {
        throw new Error(
            'Element of \'css\' array must be a ' +
            'list of valid compound selectors: ' +
            selectors[i]);
      }
      selectors[i] = canonicalizedSelector;
    }
  }

  // Setup all data types for the declarative content API.
  declarativeContent.PageStateMatcher = function(parameters) {
    setupInstance(this, parameters, 'PageStateMatcher');
    if ($Object.hasOwnProperty(this, 'css')) {
      canonicalizeCssSelectors(this.css);
    }
  };
  declarativeContent.ShowPageAction = function(parameters) {
    setupInstance(this, parameters, 'ShowPageAction');
  };
  declarativeContent.RequestContentScript = function(parameters) {
    setupInstance(this, parameters, 'RequestContentScript');
  };
  // TODO(rockot): Do not expose this in M39 stable. Making this restriction
  // possible will take some extra work. See http://crbug.com/415315
  declarativeContent.SetIcon = function(parameters) {
    setIcon(parameters, function (data) {
      setupInstance(this, data, 'SetIcon');
    }.bind(this));
  };
});

exports.binding = binding.generate();
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the desktopCapture API.

var binding = require('binding').Binding.create('desktopCapture');
var sendRequest = require('sendRequest').sendRequest;
var idGenerator = requireNative('id_generator');

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  var pendingRequests = {};

  function onRequestResult(id, result) {
    if (id in pendingRequests) {
      var callback = pendingRequests[id];
      delete pendingRequests[id];
      callback(result);
    }
  }

  apiFunctions.setHandleRequest('chooseDesktopMedia',
                                function(sources, target_tab, callback) {
    // |target_tab| is an optional parameter.
    if (callback === undefined) {
      callback = target_tab;
      target_tab = undefined;
    }
    var id = idGenerator.GetNextId();
    pendingRequests[id] = callback;
    sendRequest(this.name,
                [id, sources, target_tab, onRequestResult.bind(null, id)],
                this.definition.parameters, {});
    return id;
  });

  apiFunctions.setHandleRequest('cancelChooseDesktopMedia', function(id) {
    if (id in pendingRequests) {
      delete pendingRequests[id];
      sendRequest(this.name, [id], this.definition.parameters, {});
    }
  });
});

exports.binding = binding.generate();
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the developerPrivate API.

var binding = require('binding').Binding.create('developerPrivate');

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  // Converts the argument of |functionName| from DirectoryEntry to URL.
  function bindFileSystemFunction(functionName) {
    apiFunctions.setUpdateArgumentsPostValidate(
        functionName, function(directoryEntry, callback) {
          var fileSystemName = directoryEntry.filesystem.name;
          var relativePath = $String.slice(directoryEntry.fullPath, 1);
          var url = directoryEntry.toURL();
          return [fileSystemName, relativePath, url, callback];
    });
  }

  bindFileSystemFunction('loadDirectory');

  // developerPrivate.enable is the same as chrome.management.setEnabled.
  // TODO(devlin): Migrate callers off developerPrivate.enable.
  bindingsAPI.compiledApi.enable = chrome.management.setEnabled;

  apiFunctions.setHandleRequest('allowFileAccess',
                                function(id, allow, callback) {
    chrome.developerPrivate.updateExtensionConfiguration(
        {extensionId: id, fileAccess: allow}, callback);
  });

  apiFunctions.setHandleRequest('allowIncognito',
                                function(id, allow, callback) {
    chrome.developerPrivate.updateExtensionConfiguration(
        {extensionId: id, incognitoAccess: allow}, callback);
  });

  apiFunctions.setHandleRequest('inspect', function(options, callback) {
    var renderViewId = options.render_view_id;
    if (typeof renderViewId == 'string') {
      renderViewId = parseInt(renderViewId);
      if (isNaN(renderViewId))
        throw new Error('Invalid value for render_view_id');
    }
    var renderProcessId = options.render_process_id;
    if (typeof renderProcessId == 'string') {
      renderProcessId = parseInt(renderProcessId);
      if (isNaN(renderProcessId))
        throw new Error('Invalid value for render_process_id');
    }
    chrome.developerPrivate.openDevTools({
        extensionId: options.extension_id,
        renderProcessId: renderProcessId,
        renderViewId: renderViewId,
        incognito: options.incognito
    }, callback);
  });
});

exports.binding = binding.generate();
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom bindings for the downloads API.

var binding = require('binding').Binding.create('downloads');
var downloadsInternal = require('binding').Binding.create(
    'downloadsInternal').generate();
var eventBindings = require('event_bindings');

eventBindings.registerArgumentMassager(
    'downloads.onDeterminingFilename',
    function massage_determining_filename(args, dispatch) {
  var downloadItem = args[0];
  // Copy the id so that extensions can't change it.
  var downloadId = downloadItem.id;
  var suggestable = true;
  function isValidResult(result) {
    if (result === undefined)
      return false;
    if (typeof(result) != 'object') {
      console.error('Error: Invocation of form suggest(' + typeof(result) +
                    ') doesn\'t match definition suggest({filename: string, ' +
                    'conflictAction: string})');
      return false;
    } else if ((typeof(result.filename) != 'string') ||
               (result.filename.length == 0)) {
      console.error('Error: "filename" parameter to suggest() must be a ' +
                    'non-empty string');
      return false;
    } else if ([undefined, 'uniquify', 'overwrite', 'prompt'].indexOf(
                 result.conflictAction) < 0) {
      console.error('Error: "conflictAction" parameter to suggest() must be ' +
                    'one of undefined, "uniquify", "overwrite", "prompt"');
      return false;
    }
    return true;
  }
  function suggestCallback(result) {
    if (!suggestable) {
      console.error('suggestCallback may not be called more than once.');
      return;
    }
    suggestable = false;
    if (isValidResult(result)) {
      downloadsInternal.determineFilename(
          downloadId, result.filename, result.conflictAction || "");
    } else {
      downloadsInternal.determineFilename(downloadId, "", "");
    }
  }
  try {
    var results = dispatch([downloadItem, suggestCallback]);
    var async = (results &&
                 results.results &&
                 (results.results.length != 0) &&
                 (results.results[0] === true));
    if (suggestable && !async)
      suggestCallback();
  } catch (e) {
    suggestCallback();
    throw e;
  }
});
exports.binding = binding.generate();
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the enterprise.platformKeys API.

// The platformKeys API consists of two major parts:
//   - the certificate management.
//   - the key generation and crypto operations and
// The former is implemented without custom binding as static functions.
// The latter is exposed by implementing WebCrypto's SubtleCrypto interface.
// The internal API provides the key and crypto operations through static
// functions expecting token IDs and this custom binding adds the SubtleCrypto
// wrapper.
// The Token object holds the token id and the SubtleCrypto member.

var binding = require('binding').Binding.create('enterprise.platformKeys');
var Token = require('enterprise.platformKeys.Token').Token;
var internalAPI = require('enterprise.platformKeys.internalAPI');

binding.registerCustomHook(function(api) {
  var apiFunctions = api.apiFunctions;

  var ret = apiFunctions.setHandleRequest('getTokens', function(callback) {
    internalAPI.getTokens(function(tokenIds) {
      callback($Array.map(tokenIds,
                          function(tokenId) { return new Token(tokenId); }));
    });
  });
});

exports.binding = binding.generate();
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var binding = require('binding')
                  .Binding.create('enterprise.platformKeysInternal')
                  .generate();

exports.getTokens = binding.getTokens;
exports.generateKey = binding.generateKey;
exports.sign = binding.sign;
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var utils = require('utils');
var intersect = require('platformKeys.utils').intersect;
var keyModule = require('platformKeys.Key');
var Key = keyModule.Key;
var KeyType = keyModule.KeyType;
var KeyUsage = keyModule.KeyUsage;

/**
 * Implementation of WebCrypto.KeyPair used in enterprise.platformKeys.
 * @param {ArrayBuffer} publicKeySpki The Subject Public Key Info in DER
 *   encoding.
 * @param {KeyAlgorithm} algorithm The algorithm identifier.
 * @param {KeyUsage[]} usages The allowed key usages.
 * @constructor
 */
var KeyPairImpl = function(publicKeySpki, algorithm, usages) {
  this.publicKey = new Key(KeyType.public,
                           publicKeySpki,
                           algorithm,
                           intersect([KeyUsage.verify], usages),
                           true /* extractable */);
  this.privateKey = new Key(KeyType.private,
                            publicKeySpki,
                            algorithm,
                            intersect([KeyUsage.sign], usages),
                            false /* not extractable */);
};

exports.KeyPair = utils.expose('KeyPair',
                               KeyPairImpl,
                               {readonly:['publicKey', 'privateKey']});
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var utils = require('utils');
var internalAPI = require('enterprise.platformKeys.internalAPI');
var intersect = require('platformKeys.utils').intersect;
var subtleCryptoModule = require('platformKeys.SubtleCrypto');
var SubtleCrypto = subtleCryptoModule.SubtleCrypto;
var SubtleCryptoImpl = subtleCryptoModule.SubtleCryptoImpl;
var KeyPair = require('enterprise.platformKeys.KeyPair').KeyPair;
var KeyUsage = require('platformKeys.Key').KeyUsage;

var normalizeAlgorithm =
    requireNative('platform_keys_natives').NormalizeAlgorithm;

// This error is thrown by the internal and public API's token functions and
// must be rethrown by this custom binding. Keep this in sync with the C++ part
// of this API.
var errorInvalidToken = "The token is not valid.";

// The following errors are specified in WebCrypto.
// TODO(pneubeck): These should be DOMExceptions.
function CreateNotSupportedError() {
  return new Error('The algorithm is not supported');
}

function CreateInvalidAccessError() {
  return new Error('The requested operation is not valid for the provided key');
}

function CreateDataError() {
  return new Error('Data provided to an operation does not meet requirements');
}

function CreateSyntaxError() {
  return new Error('A required parameter was missing or out-of-range');
}

function CreateOperationError() {
  return new Error('The operation failed for an operation-specific reason');
}

// Catches an |internalErrorInvalidToken|. If so, forwards it to |reject| and
// returns true.
function catchInvalidTokenError(reject) {
  if (chrome.runtime.lastError &&
      chrome.runtime.lastError.message == errorInvalidToken) {
    reject(chrome.runtime.lastError);
    return true;
  }
  return false;
}

// Returns true if |array| is a BigInteger describing the standard public
// exponent 65537. In particular, it ignores leading zeros as required by the
// BigInteger definition in WebCrypto.
function equalsStandardPublicExponent(array) {
  var expected = [0x01, 0x00, 0x01];
  if (array.length < expected.length)
    return false;
  for (var i = 0; i < array.length; i++) {
    var expectedDigit = 0;
    if (i < expected.length) {
      // |expected| is symmetric, endianness doesn't matter.
      expectedDigit = expected[i];
    }
    if (array[array.length - 1 - i] !== expectedDigit)
      return false;
  }
  return true;
}

/**
 * Implementation of WebCrypto.SubtleCrypto used in enterprise.platformKeys.
 * Derived from platformKeys.SubtleCrypto.
 * @param {string} tokenId The id of the backing Token.
 * @constructor
 */
var EnterpriseSubtleCryptoImpl = function(tokenId) {
  SubtleCryptoImpl.call(this, tokenId);
};

EnterpriseSubtleCryptoImpl.prototype =
    Object.create(SubtleCryptoImpl.prototype);

EnterpriseSubtleCryptoImpl.prototype.generateKey =
    function(algorithm, extractable, keyUsages) {
  var subtleCrypto = this;
  return new Promise(function(resolve, reject) {
    // TODO(pneubeck): Apply the algorithm normalization of the WebCrypto
    // implementation.

    if (extractable) {
      // Note: This deviates from WebCrypto.SubtleCrypto.
      throw CreateNotSupportedError();
    }
    if (intersect(keyUsages, [KeyUsage.sign, KeyUsage.verify]).length !=
        keyUsages.length) {
      throw CreateDataError();
    }
    var normalizedAlgorithmParameters =
        normalizeAlgorithm(algorithm, 'GenerateKey');
    if (!normalizedAlgorithmParameters) {
      // TODO(pneubeck): It's not clear from the WebCrypto spec which error to
      // throw here.
      throw CreateSyntaxError();
    }

    // normalizeAlgorithm returns an array, but publicExponent should be a
    // Uint8Array.
    normalizedAlgorithmParameters.publicExponent =
        new Uint8Array(normalizedAlgorithmParameters.publicExponent);

    if (normalizedAlgorithmParameters.name !== 'RSASSA-PKCS1-v1_5' ||
        !equalsStandardPublicExponent(
            normalizedAlgorithmParameters.publicExponent)) {
      // Note: This deviates from WebCrypto.SubtleCrypto.
      throw CreateNotSupportedError();
    }

    internalAPI.generateKey(subtleCrypto.tokenId,
                            normalizedAlgorithmParameters.modulusLength,
                            function(spki) {
      if (catchInvalidTokenError(reject))
        return;
      if (chrome.runtime.lastError) {
        reject(CreateOperationError());
        return;
      }
      resolve(new KeyPair(spki, normalizedAlgorithmParameters, keyUsages));
    });
  });
};

exports.SubtleCrypto =
    utils.expose('SubtleCrypto',
                 EnterpriseSubtleCryptoImpl,
                 {
                   superclass: SubtleCrypto,
                   functions: ['generateKey']
                   // ['sign', 'exportKey'] are exposed by the base class
                 });
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var utils = require('utils');
var SubtleCrypto = require('enterprise.platformKeys.SubtleCrypto').SubtleCrypto;

/**
 * Implementation of enterprise.platformKeys.Token.
 * @param {string} id The id of the new Token.
 * @constructor
 */
var TokenImpl = function(id) {
  this.id = id;
  this.subtleCrypto = new SubtleCrypto(id);
};

exports.Token =
    utils.expose('Token', TokenImpl, {readonly:['id', 'subtleCrypto']});
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom bindings for the feedbackPrivate API.

var binding = require('binding').Binding.create('feedbackPrivate');

var blobNatives = requireNative('blob_natives');

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;
  apiFunctions.setUpdateArgumentsPostValidate(
      "sendFeedback", function(feedbackInfo, callback) {
    var attachedFileBlobUuid = '';
    var screenshotBlobUuid = '';

    if (feedbackInfo.attachedFile)
      attachedFileBlobUuid =
          blobNatives.GetBlobUuid(feedbackInfo.attachedFile.data);
    if (feedbackInfo.screenshot)
      screenshotBlobUuid =
          blobNatives.GetBlobUuid(feedbackInfo.screenshot);

    feedbackInfo.attachedFileBlobUuid = attachedFileBlobUuid;
    feedbackInfo.screenshotBlobUuid = screenshotBlobUuid;

    return [feedbackInfo, callback];
  });
});

exports.binding = binding.generate();
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the fileBrowserHandler API.

var binding = require('binding').Binding.create('fileBrowserHandler');

var eventBindings = require('event_bindings');
var fileBrowserNatives = requireNative('file_browser_handler');
var GetExternalFileEntry = fileBrowserNatives.GetExternalFileEntry;
var fileBrowserHandlerInternal = require('binding').Binding.create(
    'fileBrowserHandlerInternal').generate();

eventBindings.registerArgumentMassager('fileBrowserHandler.onExecute',
    function(args, dispatch) {
  if (args.length < 2) {
    dispatch(args);
    return;
  }
  var fileList = args[1].entries;
  if (!fileList) {
    dispatch(args);
    return;
  }
  // The second parameter for this event's payload is file definition
  // dictionary that we used to reconstruct File API's Entry instance
  // here.
  for (var i = 0; i < fileList.length; i++)
    fileList[i] = GetExternalFileEntry(fileList[i]);
  dispatch(args);
});

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setHandleRequest('selectFile',
                                function(selectionParams, callback) {
    function internalCallback(externalCallback, internalResult) {
      if (!externalCallback)
        return;
      var result = undefined;
      if (internalResult) {
        result = { success: internalResult.success, entry: null };
        if (internalResult.success)
          result.entry = GetExternalFileEntry(internalResult.entry);
      }

      externalCallback(result);
    }

    return fileBrowserHandlerInternal.selectFile(
        selectionParams, $Function.bind(internalCallback, null, callback));
  });
});

exports.binding = binding.generate();
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the fileManagerPrivate API.

// Bindings
var binding = require('binding').Binding.create('fileManagerPrivate');
var eventBindings = require('event_bindings');

// Natives
var fileManagerPrivateNatives = requireNative('file_manager_private');
var fileBrowserHandlerNatives = requireNative('file_browser_handler');

// Internals
var fileManagerPrivateInternal =
    require('binding').Binding.create('fileManagerPrivateInternal').generate();

// Shorthands
var GetFileSystem = fileManagerPrivateNatives.GetFileSystem;
var GetExternalFileEntry = fileBrowserHandlerNatives.GetExternalFileEntry;

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setCustomCallback('searchDrive',
      function(name, request, callback, response) {
    if (response && !response.error && response.entries) {
      response.entries = response.entries.map(function(entry) {
        return GetExternalFileEntry(entry);
      });
    }

    // So |callback| doesn't break if response is not defined.
    if (!response)
      response = {};

    if (callback)
      callback(response.entries, response.nextFeed);
  });

  apiFunctions.setCustomCallback('searchDriveMetadata',
      function(name, request, callback, response) {
    if (response && !response.error) {
      for (var i = 0; i < response.length; i++) {
        response[i].entry =
            GetExternalFileEntry(response[i].entry);
      }
    }

    // So |callback| doesn't break if response is not defined.
    if (!response)
      response = {};

    if (callback)
      callback(response);
  });

  apiFunctions.setHandleRequest('resolveIsolatedEntries',
                                function(entries, callback) {
    var urls = entries.map(function(entry) {
      return fileBrowserHandlerNatives.GetEntryURL(entry);
    });
    fileManagerPrivateInternal.resolveIsolatedEntries(urls, function(
        entryDescriptions) {
      callback(entryDescriptions.map(function(description) {
        return GetExternalFileEntry(description);
      }));
    });
  });

  apiFunctions.setHandleRequest('getEntryProperties',
                                function(entries, names, callback) {
    var urls = entries.map(function(entry) {
      return fileBrowserHandlerNatives.GetEntryURL(entry);
    });
    fileManagerPrivateInternal.getEntryProperties(urls, names, callback);
  });

  apiFunctions.setHandleRequest('addFileWatch', function(entry, callback) {
    var url = fileBrowserHandlerNatives.GetEntryURL(entry);
    fileManagerPrivateInternal.addFileWatch(url, callback);
  });

  apiFunctions.setHandleRequest('removeFileWatch', function(entry, callback) {
    var url = fileBrowserHandlerNatives.GetEntryURL(entry);
    fileManagerPrivateInternal.removeFileWatch(url, callback);
  });
});

eventBindings.registerArgumentMassager(
    'fileManagerPrivate.onDirectoryChanged', function(args, dispatch) {
  // Convert the entry arguments into a real Entry object.
  args[0].entry = GetExternalFileEntry(args[0].entry);
  dispatch(args);
});

exports.binding = binding.generate();
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var fileSystemNatives = requireNative('file_system_natives');
var GetIsolatedFileSystem = fileSystemNatives.GetIsolatedFileSystem;
var sendRequest = require('sendRequest');
var lastError = require('lastError');
var GetModuleSystem = requireNative('v8_context').GetModuleSystem;
// TODO(sammc): Don't require extension. See http://crbug.com/235689.
var GetExtensionViews = requireNative('runtime').GetExtensionViews;

// For a given |apiName|, generates object with two elements that are used
// in file system relayed APIs:
// * 'bindFileEntryCallback' function that provides mapping between JS objects
//   into actual FileEntry|DirectoryEntry objects.
// * 'entryIdManager' object that implements methods for keeping the tracks of
//   previously saved file entries.
function getFileBindingsForApi(apiName) {
  // Fallback to using the current window if no background page is running.
  var backgroundPage = GetExtensionViews(-1, 'BACKGROUND')[0] || window;
  var backgroundPageModuleSystem = GetModuleSystem(backgroundPage);

  // All windows use the bindFileEntryCallback from the background page so their
  // FileEntry objects have the background page's context as their own. This
  // allows them to be used from other windows (including the background page)
  // after the original window is closed.
  if (window == backgroundPage) {
    var bindFileEntryCallback = function(functionName, apiFunctions) {
      apiFunctions.setCustomCallback(functionName,
          function(name, request, callback, response) {
        if (callback) {
          if (!response) {
            callback();
            return;
          }

          var entries = [];
          var hasError = false;

          var getEntryError = function(fileError) {
            if (!hasError) {
              hasError = true;
              lastError.run(
                  apiName + '.' + functionName,
                  'Error getting fileEntry, code: ' + fileError.code,
                  request.stack,
                  callback);
            }
          }

          // Loop through the response entries and asynchronously get the
          // FileEntry for each. We use hasError to ensure that only the first
          // error is reported. Note that an error can occur either during the
          // loop or in the asynchronous error callback to getFile.
          $Array.forEach(response.entries, function(entry) {
            if (hasError)
              return;
            var fileSystemId = entry.fileSystemId;
            var baseName = entry.baseName;
            var id = entry.id;
            var fs = GetIsolatedFileSystem(fileSystemId);

            try {
              var getEntryCallback = function(fileEntry) {
                if (hasError)
                  return;
                entryIdManager.registerEntry(id, fileEntry);
                entries.push(fileEntry);
                // Once all entries are ready, pass them to the callback. In the
                // event of an error, this condition will never be satisfied so
                // the callback will not be called with any entries.
                if (entries.length == response.entries.length) {
                  if (response.multiple) {
                    sendRequest.safeCallbackApply(
                        apiName + '.' + functionName, request, callback,
                        [entries]);
                  } else {
                    sendRequest.safeCallbackApply(
                        apiName + '.' + functionName, request, callback,
                        [entries[0]]);
                  }
                }
              }
              // TODO(koz): fs.root.getFile() makes a trip to the browser
              // process, but it might be possible avoid that by calling
              // WebDOMFileSystem::createV8Entry().
              if (entry.isDirectory) {
                fs.root.getDirectory(baseName, {}, getEntryCallback,
                                     getEntryError);
              } else {
                fs.root.getFile(baseName, {}, getEntryCallback, getEntryError);
              }
            } catch (e) {
              if (!hasError) {
                hasError = true;
                lastError.run(apiName + '.' + functionName,
                              'Error getting fileEntry: ' + e.stack,
                              request.stack,
                              callback);
              }
            }
          });
        }
      });
    };
    var entryIdManager = require('entryIdManager');
  } else {
    // Force the fileSystem API to be loaded in the background page. Using
    // backgroundPageModuleSystem.require('fileSystem') is insufficient as
    // requireNative is only allowed while lazily loading an API.
    backgroundPage.chrome.fileSystem;
    var bindFileEntryCallback = backgroundPageModuleSystem.require(
        apiName).bindFileEntryCallback;
    var entryIdManager = backgroundPageModuleSystem.require('entryIdManager');
  }
  return {bindFileEntryCallback: bindFileEntryCallback,
          entryIdManager: entryIdManager};
}

exports.getFileBindingsForApi = getFileBindingsForApi;
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the fileSystem API.

var binding = require('binding').Binding.create('fileSystem');
var sendRequest = require('sendRequest');

var getFileBindingsForApi =
    require('fileEntryBindingUtil').getFileBindingsForApi;
var fileBindings = getFileBindingsForApi('fileSystem');
var bindFileEntryCallback = fileBindings.bindFileEntryCallback;
var entryIdManager = fileBindings.entryIdManager;
var fileSystemNatives = requireNative('file_system_natives');

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;
  var fileSystem = bindingsAPI.compiledApi;

  function bindFileEntryFunction(functionName) {
    apiFunctions.setUpdateArgumentsPostValidate(
        functionName, function(fileEntry, callback) {
      var fileSystemName = fileEntry.filesystem.name;
      var relativePath = $String.slice(fileEntry.fullPath, 1);
      return [fileSystemName, relativePath, callback];
    });
  }
  $Array.forEach(['getDisplayPath', 'getWritableEntry', 'isWritableEntry'],
                  bindFileEntryFunction);

  $Array.forEach(['getWritableEntry', 'chooseEntry', 'restoreEntry'],
                  function(functionName) {
    bindFileEntryCallback(functionName, apiFunctions);
  });

  apiFunctions.setHandleRequest('retainEntry', function(fileEntry) {
    var id = entryIdManager.getEntryId(fileEntry);
    if (!id)
      return '';
    var fileSystemName = fileEntry.filesystem.name;
    var relativePath = $String.slice(fileEntry.fullPath, 1);

    sendRequest.sendRequest(this.name, [id, fileSystemName, relativePath],
      this.definition.parameters, {});
    return id;
  });

  apiFunctions.setHandleRequest('isRestorable',
      function(id, callback) {
    var savedEntry = entryIdManager.getEntryById(id);
    if (savedEntry) {
      sendRequest.safeCallbackApply(
          'fileSystem.isRestorable',
          {},
          callback,
          [true]);
    } else {
      sendRequest.sendRequest(
          this.name, [id, callback], this.definition.parameters, {});
    }
  });

  apiFunctions.setUpdateArgumentsPostValidate('restoreEntry',
      function(id, callback) {
    var savedEntry = entryIdManager.getEntryById(id);
    if (savedEntry) {
      // We already have a file entry for this id so pass it to the callback and
      // send a request to the browser to move it to the back of the LRU.
      sendRequest.safeCallbackApply(
          'fileSystem.restoreEntry',
          {},
          callback,
          [savedEntry]);
      return [id, false, null];
    } else {
      // Ask the browser process for a new file entry for this id, to be passed
      // to |callback|.
      return [id, true, callback];
    }
  });

  apiFunctions.setCustomCallback('requestFileSystem',
      function(name, request, callback, response) {
    var fileSystem;
    if (response && response.file_system_id) {
      fileSystem = fileSystemNatives.GetIsolatedFileSystem(
          response.file_system_id, response.file_system_path);
    }
    sendRequest.safeCallbackApply(
        'fileSystem.requestFileSystem',
        request,
        callback,
        [fileSystem]);
  });

  // TODO(benwells): Remove these deprecated versions of the functions.
  fileSystem.getWritableFileEntry = function() {
    console.log("chrome.fileSystem.getWritableFileEntry is deprecated");
    console.log("Please use chrome.fileSystem.getWritableEntry instead");
    $Function.apply(fileSystem.getWritableEntry, this, arguments);
  };

  fileSystem.isWritableFileEntry = function() {
    console.log("chrome.fileSystem.isWritableFileEntry is deprecated");
    console.log("Please use chrome.fileSystem.isWritableEntry instead");
    $Function.apply(fileSystem.isWritableEntry, this, arguments);
  };

  fileSystem.chooseFile = function() {
    console.log("chrome.fileSystem.chooseFile is deprecated");
    console.log("Please use chrome.fileSystem.chooseEntry instead");
    $Function.apply(fileSystem.chooseEntry, this, arguments);
  };
});

exports.bindFileEntryCallback = bindFileEntryCallback;
exports.binding = binding.generate();
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the fileSystemProvider API.

var binding = require('binding').Binding.create('fileSystemProvider');
var fileSystemProviderInternal =
    require('binding').Binding.create('fileSystemProviderInternal').generate();
var eventBindings = require('event_bindings');
var fileSystemNatives = requireNative('file_system_natives');
var GetDOMError = fileSystemNatives.GetDOMError;

/**
 * Maximum size of the thumbnail in bytes.
 * @type {number}
 * @const
 */
var METADATA_THUMBNAIL_SIZE_LIMIT = 32 * 1024 * 1024;

/**
 * Regular expression to validate if the thumbnail URI is a valid data URI,
 * taking into account allowed formats.
 * @type {RegExp}
 * @const
 */
var METADATA_THUMBNAIL_FORMAT = new RegExp(
    '^data:image/(png|jpeg|webp);', 'i');

/**
 * Annotates a date with its serialized value.
 * @param {Date} date Input date.
 * @return {Date} Date with an extra <code>value</code> attribute.
 */
function annotateDate(date) {
  // Copy in case the input date is frozen.
  var result = new Date(date.getTime());
  result.value = result.toString();
  return result;
}

/**
 * Verifies if the passed image URI is valid.
 * @param {*} uri Image URI.
 * @return {boolean} True if valid, valse otherwise.
 */
function verifyImageURI(uri) {
  // The URI is specified by a user, so the type may be incorrect.
  if (typeof uri != 'string' && !(uri instanceof String))
    return false;

  return METADATA_THUMBNAIL_FORMAT.test(uri);
}

/**
 * Annotates an entry metadata by serializing its modifiedTime value.
 * @param {EntryMetadata} metadata Input metadata.
 * @return {EntryMetadata} metadata Annotated metadata, which can be passed
 *     back to the C++ layer.
 */
function annotateMetadata(metadata) {
  var result = {
    isDirectory: metadata.isDirectory,
    name: metadata.name,
    size: metadata.size,
    modificationTime: annotateDate(metadata.modificationTime)
  };
  if ('mimeType' in metadata)
    result.mimeType = metadata.mimeType;
  if ('thumbnail' in metadata)
    result.thumbnail = metadata.thumbnail;
  return result;
}

/**
 * Massages arguments of an event raised by the File System Provider API.
 * @param {Array<*>} args Input arguments.
 * @param {function(Array<*>)} dispatch Closure to be called with massaged
 *     arguments.
 */
function massageArgumentsDefault(args, dispatch) {
  var executionStart = Date.now();
  var options = args[0];
  var onSuccessCallback = function(hasNext) {
    fileSystemProviderInternal.operationRequestedSuccess(
        options.fileSystemId, options.requestId, Date.now() - executionStart);
  };
  var onErrorCallback = function(error) {
    fileSystemProviderInternal.operationRequestedError(
        options.fileSystemId, options.requestId, error,
        Date.now() - executionStart);
  }
  dispatch([options, onSuccessCallback, onErrorCallback]);
}

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onUnmountRequested',
    massageArgumentsDefault);

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onGetMetadataRequested',
    function(args, dispatch) {
      var executionStart = Date.now();
      var options = args[0];
      var onSuccessCallback = function(metadata) {
        var error;
        // It is invalid to return a thumbnail when it's not requested. The
        // restriction is added in order to avoid fetching the thumbnail while
        // it's not needed.
        if (!options.thumbnail && metadata.thumbnail)
          error = 'Thumbnail data provided, but not requested.';

        // Check the format and size. Note, that in the C++ layer, there is
        // another sanity check to avoid passing any evil URL.
        if ('thumbnail' in metadata && !verifyImageURI(metadata.thumbnail))
          error = 'Thumbnail format invalid.';

        if ('thumbnail' in metadata &&
            metadata.thumbnail.length > METADATA_THUMBNAIL_SIZE_LIMIT) {
          error = 'Thumbnail data too large.';
        }

        if (error) {
          console.error(error);
          fileSystemProviderInternal.operationRequestedError(
              options.fileSystemId, options.requestId, 'FAILED',
              Date.now() - executionStart);
          return;
        }

        fileSystemProviderInternal.getMetadataRequestedSuccess(
            options.fileSystemId,
            options.requestId,
            annotateMetadata(metadata),
            Date.now() - executionStart);
      };

      var onErrorCallback = function(error) {
        fileSystemProviderInternal.operationRequestedError(
            options.fileSystemId, options.requestId, error,
            Date.now() - executionStart);
      }

      dispatch([options, onSuccessCallback, onErrorCallback]);
    });

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onGetActionsRequested',
    function(args, dispatch) {
      var executionStart = Date.now();
      var options = args[0];
      var onSuccessCallback = function(actions) {
        fileSystemProviderInternal.getActionsRequestedSuccess(
            options.fileSystemId,
            options.requestId,
            actions,
            Date.now() - executionStart);
      };

      var onErrorCallback = function(error) {
        fileSystemProviderInternal.operationRequestedError(
            options.fileSystemId, options.requestId, error,
            Date.now() - executionStart);
      }

      dispatch([options, onSuccessCallback, onErrorCallback]);
    });

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onReadDirectoryRequested',
    function(args, dispatch) {
      var executionStart = Date.now();
      var options = args[0];
      var onSuccessCallback = function(entries, hasNext) {
        var annotatedEntries = entries.map(annotateMetadata);
        // It is invalid to return a thumbnail when it's not requested.
        var error;
        annotatedEntries.forEach(function(metadata) {
          if (metadata.thumbnail) {
            var error =
                'Thumbnails must not be provided when reading a directory.';
            return;
          }
        });

        if (error) {
          console.error(error);
          fileSystemProviderInternal.operationRequestedError(
              options.fileSystemId, options.requestId, 'FAILED',
              Date.now() - executionStart);
          return;
        }

        fileSystemProviderInternal.readDirectoryRequestedSuccess(
            options.fileSystemId, options.requestId, annotatedEntries, hasNext,
            Date.now() - executionStart);
      };

      var onErrorCallback = function(error) {
        fileSystemProviderInternal.operationRequestedError(
            options.fileSystemId, options.requestId, error,
            Date.now() - executionStart);
      }
      dispatch([options, onSuccessCallback, onErrorCallback]);
    });

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onOpenFileRequested',
    massageArgumentsDefault);

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onCloseFileRequested',
    massageArgumentsDefault);

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onReadFileRequested',
    function(args, dispatch) {
      var executionStart = Date.now();
      var options = args[0];
      var onSuccessCallback = function(data, hasNext) {
        fileSystemProviderInternal.readFileRequestedSuccess(
            options.fileSystemId, options.requestId, data, hasNext,
            Date.now() - executionStart);
      };
      var onErrorCallback = function(error) {
        fileSystemProviderInternal.operationRequestedError(
            options.fileSystemId, options.requestId, error,
            Date.now() - executionStart);
      }
      dispatch([options, onSuccessCallback, onErrorCallback]);
    });

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onCreateDirectoryRequested',
    massageArgumentsDefault);

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onDeleteEntryRequested',
    massageArgumentsDefault);

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onCreateFileRequested',
    massageArgumentsDefault);

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onCopyEntryRequested',
    massageArgumentsDefault);

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onMoveEntryRequested',
    massageArgumentsDefault);

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onTruncateRequested',
    massageArgumentsDefault);

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onWriteFileRequested',
    massageArgumentsDefault);

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onAbortRequested',
    massageArgumentsDefault);

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onObserveDirectoryRequested',
    massageArgumentsDefault);

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onUnobserveEntryRequested',
    massageArgumentsDefault);

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onAddWatcherRequested',
    massageArgumentsDefault);

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onRemoveWatcherRequested',
    massageArgumentsDefault);

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onConfigureRequested',
    massageArgumentsDefault);

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onExecuteActionRequested',
    massageArgumentsDefault);

eventBindings.registerArgumentMassager(
    'fileSystemProvider.onMountRequested',
    function(args, dispatch) {
      var onSuccessCallback = function() {
        // TODO(mtomasz): To be implemented.
      };
      var onErrorCallback = function(error) {
        // TODO(mtomasz): To be implemented.
      }
      dispatch([onSuccessCallback, onErrorCallback]);
    });

exports.binding = binding.generate();
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the GCM API.

var binding = require('binding').Binding.create('gcm');
var forEach = require('utils').forEach;

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;
  var gcm = bindingsAPI.compiledApi;

  apiFunctions.setUpdateArgumentsPostValidate(
    'send', function(message, callback) {
      // Validate message.data.
      var payloadSize = 0;
      forEach(message.data, function(property, value) {
        if (property.length == 0)
          throw new Error("One of data keys is empty.");

        var lowerCasedProperty = property.toLowerCase();
        // Issue an error for forbidden prefixes of property names.
        if (lowerCasedProperty.indexOf("goog.") == 0 ||
            lowerCasedProperty.indexOf("google") == 0 ||
            property.indexOf("collapse_key") == 0) {
          throw new Error("Invalid data key: " + property);
        }

        payloadSize += property.length + value.length;
      });

      if (payloadSize > gcm.MAX_MESSAGE_SIZE)
        throw new Error("Payload exceeded allowed size limit. Payload size is: "
            + payloadSize);

      if (payloadSize == 0)
        throw new Error("No data to send.");

      return arguments;
    });
});

exports.binding = binding.generate();
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the Identity API.

var binding = require('binding').Binding.create('identity');

binding.registerCustomHook(function(binding, id, contextType) {
  var apiFunctions = binding.apiFunctions;
  var identity = binding.compiledApi;

  apiFunctions.setHandleRequest('getRedirectURL', function(path) {
    if (path === null || path === undefined)
      path = '/';
    else
      path = String(path);
    if (path[0] != '/')
      path = '/' + path;
    return 'https://' + id + '.chromiumapp.org' + path;
  });
});

exports.binding = binding.generate();
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the image writer private API.

var binding = require('binding').Binding.create('imageWriterPrivate');

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setUpdateArgumentsPostValidate(
      'writeFromFile', function(device, fileEntry, options, callback) {
    var fileSystemName = fileEntry.filesystem.name;
    var relativePath = $String.slice(fileEntry.fullPath, 1);
    return [device, fileSystemName, relativePath, callback];
  });
});

exports.binding = binding.generate();
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the input ime API. Only injected into the
// v8 contexts for extensions which have permission for the API.

var binding = require('binding').Binding.create('input.ime');

var Event = require('event_bindings').Event;

binding.registerCustomHook(function(api) {
  var input_ime = api.compiledApi;

  input_ime.onKeyEvent.dispatchToListener = function(callback, args) {
    var engineID = args[0];
    var keyData = args[1];

    var result = false;
    try {
      result = $Function.call(Event.prototype.dispatchToListener,
          this, callback, args);
    } catch (e) {
      console.error('Error in event handler for onKeyEvent: ' + e.stack);
    }
    if (!input_ime.onKeyEvent.async) {
      input_ime.keyEventHandled(keyData.requestId, result);
    }
  };

  input_ime.onKeyEvent.addListener = function(cb, opt_extraInfo) {
    input_ime.onKeyEvent.async = false;
    if (opt_extraInfo instanceof Array) {
      for (var i = 0; i < opt_extraInfo.length; ++i) {
        if (opt_extraInfo[i] == "async") {
          input_ime.onKeyEvent.async = true;
        }
      }
    }
    $Function.call(Event.prototype.addListener, this, cb);
  };
});

exports.binding = binding.generate();
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the logPrivate API.
var binding = require('binding').Binding.create('logPrivate');
var sendRequest = require('sendRequest');

var getFileBindingsForApi =
    require('fileEntryBindingUtil').getFileBindingsForApi;
var fileBindings = getFileBindingsForApi('logPrivate');
var bindFileEntryCallback = fileBindings.bindFileEntryCallback;

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;
  var fileSystem = bindingsAPI.compiledApi;

  $Array.forEach(['dumpLogs'],
                  function(functionName) {
    bindFileEntryCallback(functionName, apiFunctions);
  });

});

exports.bindFileEntryCallback = bindFileEntryCallback;
exports.binding = binding.generate();
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the Media Gallery API.

var binding = require('binding').Binding.create('mediaGalleries');
var blobNatives = requireNative('blob_natives');
var mediaGalleriesNatives = requireNative('mediaGalleries');

var blobsAwaitingMetadata = {};
var mediaGalleriesMetadata = {};

function createFileSystemObjectsAndUpdateMetadata(response) {
  var result = [];
  mediaGalleriesMetadata = {};  // Clear any previous metadata.
  if (response) {
    for (var i = 0; i < response.length; i++) {
      var filesystem = mediaGalleriesNatives.GetMediaFileSystemObject(
          response[i].fsid);
      $Array.push(result, filesystem);
      var metadata = response[i];
      delete metadata.fsid;
      mediaGalleriesMetadata[filesystem.name] = metadata;
    }
  }
  return result;
}

binding.registerCustomHook(function(bindingsAPI, extensionId) {
  var apiFunctions = bindingsAPI.apiFunctions;

  // getMediaFileSystems, addUserSelectedFolder, and addScanResults use a
  // custom callback so that they can instantiate and return an array of file
  // system objects.
  apiFunctions.setCustomCallback('getMediaFileSystems',
                                 function(name, request, callback, response) {
    var result = createFileSystemObjectsAndUpdateMetadata(response);
    if (callback)
      callback(result);
  });

  apiFunctions.setCustomCallback('addScanResults',
      function(name, request, callback, response) {
    var result = createFileSystemObjectsAndUpdateMetadata(response);
    if (callback)
      callback(result);
  });

  apiFunctions.setCustomCallback('addUserSelectedFolder',
      function(name, request, callback, response) {
    var fileSystems = [];
    var selectedFileSystemName = "";
    if (response && 'mediaFileSystems' in response &&
        'selectedFileSystemIndex' in response) {
      fileSystems = createFileSystemObjectsAndUpdateMetadata(
          response['mediaFileSystems']);
      var selectedFileSystemIndex = response['selectedFileSystemIndex'];
      if (selectedFileSystemIndex >= 0) {
        selectedFileSystemName = fileSystems[selectedFileSystemIndex].name;
      }
    }
    if (callback)
      callback(fileSystems, selectedFileSystemName);
  });

  apiFunctions.setCustomCallback('dropPermissionForMediaFileSystem',
      function(name, request, callback, response) {
    var galleryId = response;

    if (galleryId) {
      for (var key in mediaGalleriesMetadata) {
        if (mediaGalleriesMetadata[key].galleryId == galleryId) {
          delete mediaGalleriesMetadata[key];
          break;
        }
      }
    }
    if (callback)
      callback();
  });

  apiFunctions.setHandleRequest('getMediaFileSystemMetadata',
                                function(filesystem) {
    if (filesystem && filesystem.name &&
        filesystem.name in mediaGalleriesMetadata) {
      return mediaGalleriesMetadata[filesystem.name];
    }
    return {
      'name': '',
      'galleryId': '',
      'isRemovable': false,
      'isMediaDevice': false,
      'isAvailable': false,
    };
  });

  apiFunctions.setUpdateArgumentsPostValidate('getMetadata',
      function(mediaFile, options, callback) {
    var blobUuid = blobNatives.GetBlobUuid(mediaFile)
    // Store the blob in a global object to keep its refcount nonzero -- this
    // prevents the object from being garbage collected before any metadata
    // parsing gets to occur (see crbug.com/415792).
    blobsAwaitingMetadata[blobUuid] = mediaFile;
    return [blobUuid, options, callback];
  });

  apiFunctions.setCustomCallback('getMetadata',
      function(name, request, callback, response) {
    if (response.attachedImagesBlobInfo) {
      for (var i = 0; i < response.attachedImagesBlobInfo.length; i++) {
        var blobInfo = response.attachedImagesBlobInfo[i];
        var blob = blobNatives.TakeBrowserProcessBlob(
            blobInfo.blobUUID, blobInfo.type, blobInfo.size);
        response.metadata.attachedImages.push(blob);
      }
    }

    if (callback)
      callback(response.metadata);

    // The UUID was in position 0 in the setUpdateArgumentsPostValidate
    // function.
    var uuid = request.args[0];
    delete blobsAwaitingMetadata[uuid];
  });
});

exports.binding = binding.generate();
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom bindings for the notifications API.
//
var binding = require('binding').Binding.create('notifications');

var sendRequest = require('sendRequest').sendRequest;
var exceptionHandler = require('uncaught_exception_handler');
var imageUtil = require('imageUtil');
var lastError = require('lastError');
var notificationsPrivate = requireNative('notifications_private');

function imageDataSetter(context, key) {
  var f = function(val) {
    this[key] = val;
  };
  return $Function.bind(f, context);
}

// A URL Spec is an object with the following keys:
//  path: The resource to be downloaded.
//  width: (optional) The maximum width of the image to be downloaded in device
//         pixels.
//  height: (optional) The maximum height of the image to be downloaded in
//          device pixels.
//  callback: A function to be called when the URL is complete. It
//    should accept an ImageData object and set the appropriate
//    field in |notificationDetails|.
function getUrlSpecs(imageSizes, notificationDetails) {
  var urlSpecs = [];

  // |iconUrl| might be optional for notification updates.
  if (notificationDetails.iconUrl) {
    $Array.push(urlSpecs, {
      path: notificationDetails.iconUrl,
      width: imageSizes.icon.width * imageSizes.scaleFactor,
      height: imageSizes.icon.height * imageSizes.scaleFactor,
      callback: imageDataSetter(notificationDetails, 'iconBitmap')
    });
  }

  // |appIconMaskUrl| is optional.
  if (notificationDetails.appIconMaskUrl) {
    $Array.push(urlSpecs, {
      path: notificationDetails.appIconMaskUrl,
      width: imageSizes.appIconMask.width * imageSizes.scaleFactor,
      height: imageSizes.appIconMask.height * imageSizes.scaleFactor,
      callback: imageDataSetter(notificationDetails, 'appIconMaskBitmap')
    });
  }

  // |imageUrl| is optional.
  if (notificationDetails.imageUrl) {
    $Array.push(urlSpecs, {
      path: notificationDetails.imageUrl,
      width: imageSizes.image.width * imageSizes.scaleFactor,
      height: imageSizes.image.height * imageSizes.scaleFactor,
      callback: imageDataSetter(notificationDetails, 'imageBitmap')
    });
  }

  // Each button has an optional icon.
  var buttonList = notificationDetails.buttons;
  if (buttonList && typeof buttonList.length === 'number') {
    var numButtons = buttonList.length;
    for (var i = 0; i < numButtons; i++) {
      if (buttonList[i].iconUrl) {
        $Array.push(urlSpecs, {
          path: buttonList[i].iconUrl,
          width: imageSizes.buttonIcon.width * imageSizes.scaleFactor,
          height: imageSizes.buttonIcon.height * imageSizes.scaleFactor,
          callback: imageDataSetter(buttonList[i], 'iconBitmap')
        });
      }
    }
  }

  return urlSpecs;
}

function replaceNotificationOptionURLs(notification_details, callback) {
  var imageSizes = notificationsPrivate.GetNotificationImageSizes();
  var url_specs = getUrlSpecs(imageSizes, notification_details);
  if (!url_specs.length) {
    callback(true);
    return;
  }

  var errors = 0;

  imageUtil.loadAllImages(url_specs, {
    onerror: function(index) {
      errors++;
    },
    oncomplete: function(imageData) {
      if (errors > 0) {
        callback(false);
        return;
      }
      for (var index = 0; index < url_specs.length; index++) {
        var url_spec = url_specs[index];
        url_spec.callback(imageData[index]);
      }
      callback(true);
    }
  });
}

function genHandle(name, failure_function) {
  return function(id, input_notification_details, callback) {
    // TODO(dewittj): Remove this hack. This is used as a way to deep
    // copy a complex JSON object.
    var notification_details = $JSON.parse(
        $JSON.stringify(input_notification_details));
    var that = this;
    var stack = exceptionHandler.getExtensionStackTrace();
    replaceNotificationOptionURLs(notification_details, function(success) {
      if (success) {
        sendRequest(that.name,
            [id, notification_details, callback],
            that.definition.parameters, {stack: stack});
        return;
      }
      lastError.run(name,
                    'Unable to download all specified images.',
                    stack,
                    failure_function, [callback || function() {}, id]);
    });
  };
}

var handleCreate = genHandle('notifications.create',
                             function(callback, id) { callback(id); });
var handleUpdate = genHandle('notifications.update',
                             function(callback, id) { callback(false); });

var notificationsCustomHook = function(bindingsAPI, extensionId) {
  var apiFunctions = bindingsAPI.apiFunctions;
  apiFunctions.setHandleRequest('create', handleCreate);
  apiFunctions.setHandleRequest('update', handleUpdate);
};

binding.registerCustomHook(notificationsCustomHook);

exports.binding = binding.generate();
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the omnibox API. Only injected into the v8 contexts
// for extensions which have permission for the omnibox API.

var binding = require('binding').Binding.create('omnibox');

var eventBindings = require('event_bindings');
var sendRequest = require('sendRequest').sendRequest;

// Remove invalid characters from |text| so that it is suitable to use
// for |AutocompleteMatch::contents|.
function sanitizeString(text, shouldTrim) {
  // NOTE: This logic mirrors |AutocompleteMatch::SanitizeString()|.
  // 0x2028 = line separator; 0x2029 = paragraph separator.
  var kRemoveChars = /(\r|\n|\t|\u2028|\u2029)/gm;
  if (shouldTrim)
    text = text.trimLeft();
  return text.replace(kRemoveChars, '');
}

// Parses the xml syntax supported by omnibox suggestion results. Returns an
// object with two properties: 'description', which is just the text content,
// and 'descriptionStyles', which is an array of style objects in a format
// understood by the C++ backend.
function parseOmniboxDescription(input) {
  var domParser = new DOMParser();

  // The XML parser requires a single top-level element, but we want to
  // support things like 'hello, <match>world</match>!'. So we wrap the
  // provided text in generated root level element.
  var root = domParser.parseFromString(
      '<fragment>' + input + '</fragment>', 'text/xml');

  // DOMParser has a terrible error reporting facility. Errors come out nested
  // inside the returned document.
  var error = root.querySelector('parsererror div');
  if (error) {
    throw new Error(error.textContent);
  }

  // Otherwise, it's valid, so build up the result.
  var result = {
    description: '',
    descriptionStyles: []
  };

  // Recursively walk the tree.
  function walk(node) {
    for (var i = 0, child; child = node.childNodes[i]; i++) {
      // Append text nodes to our description.
      if (child.nodeType == Node.TEXT_NODE) {
        var shouldTrim = result.description.length == 0;
        result.description += sanitizeString(child.nodeValue, shouldTrim);
        continue;
      }

      // Process and descend into a subset of recognized tags.
      if (child.nodeType == Node.ELEMENT_NODE &&
          (child.nodeName == 'dim' || child.nodeName == 'match' ||
           child.nodeName == 'url')) {
        var style = {
          'type': child.nodeName,
          'offset': result.description.length
        };
        $Array.push(result.descriptionStyles, style);
        walk(child);
        style.length = result.description.length - style.offset;
        continue;
      }

      // Descend into all other nodes, even if they are unrecognized, for
      // forward compat.
      walk(child);
    }
  };
  walk(root);

  return result;
}

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setUpdateArgumentsPreValidate('setDefaultSuggestion',
                                             function(suggestResult) {
    if (suggestResult.content != undefined) {  // null, etc.
      throw new Error(
          'setDefaultSuggestion cannot contain the "content" field');
    }
    return [suggestResult];
  });

  apiFunctions.setHandleRequest('setDefaultSuggestion', function(details) {
    var parseResult = parseOmniboxDescription(details.description);
    sendRequest(this.name, [parseResult], this.definition.parameters);
  });

  apiFunctions.setUpdateArgumentsPostValidate(
      'sendSuggestions', function(requestId, userSuggestions) {
    var suggestions = [];
    for (var i = 0; i < userSuggestions.length; i++) {
      var parseResult = parseOmniboxDescription(
          userSuggestions[i].description);
      parseResult.content = userSuggestions[i].content;
      $Array.push(suggestions, parseResult);
    }
    return [requestId, suggestions];
  });
});

eventBindings.registerArgumentMassager('omnibox.onInputChanged',
    function(args, dispatch) {
  var text = args[0];
  var requestId = args[1];
  var suggestCallback = function(suggestions) {
    chrome.omnibox.sendSuggestions(requestId, suggestions);
  };
  dispatch([text, suggestCallback]);
});

exports.binding = binding.generate();
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the pageAction API.

var binding = require('binding').Binding.create('pageAction');

var setIcon = require('setIcon').setIcon;
var sendRequest = require('sendRequest').sendRequest;

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setHandleRequest('setIcon', function(details, callback) {
    setIcon(details, function(args) {
      sendRequest(this.name, [args, callback], this.definition.parameters);
    }.bind(this));
  });
});

exports.binding = binding.generate();
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the pageCapture API.

var binding = require('binding').Binding.create('pageCapture');

var handleUncaughtException = require('uncaught_exception_handler').handle;
var pageCaptureNatives = requireNative('page_capture');
var CreateBlob = pageCaptureNatives.CreateBlob;
var SendResponseAck = pageCaptureNatives.SendResponseAck;

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setCustomCallback('saveAsMHTML',
      function(name, request, callback, response) {
    if (response)
      response = CreateBlob(response.mhtmlFilePath, response.mhtmlFileLength);

    try {
      callback(response);
    } catch (e) {
      handleUncaughtException(
          'Error in chrome.pageCapture.saveAsMHTML callback', e, request.stack);
    } finally {
      // Notify the browser. Now that the blob is referenced from JavaScript,
      // the browser can drop its reference to it.
      SendResponseAck(request.id);
    }
  });
});

exports.binding = binding.generate();
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the platformKeys API.

var binding = require('binding').Binding.create('platformKeys');
var SubtleCrypto = require('platformKeys.SubtleCrypto').SubtleCrypto;
var getPublicKey = require('platformKeys.getPublicKey').getPublicKey;
var internalAPI = require('platformKeys.internalAPI');

var keyModule = require('platformKeys.Key');
var Key = keyModule.Key;
var KeyType = keyModule.KeyType;
var KeyUsage = keyModule.KeyUsage;

function createPublicKey(publicKeySpki, algorithm) {
  return new Key(KeyType.public, publicKeySpki, algorithm, [KeyUsage.verify],
                 true /* extractable */);
}

function createPrivateKey(publicKeySpki, algorithm) {
  return new Key(KeyType.private, publicKeySpki, algorithm, [KeyUsage.sign],
                 false /* not extractable */);
}

binding.registerCustomHook(function(api) {
  var apiFunctions = api.apiFunctions;
  var subtleCrypto = new SubtleCrypto('' /* tokenId */);

  apiFunctions.setHandleRequest(
      'selectClientCertificates', function(details, callback) {
        internalAPI.selectClientCertificates(details, function(matches) {
          if (chrome.runtime.lastError) {
            callback([]);
            return;
          }
          callback($Array.map(matches, function(match) {
            // internalAPI.selectClientCertificates returns publicExponent as
            // ArrayBuffer, but it should be a Uint8Array.
            if (match.keyAlgorithm.publicExponent) {
              match.keyAlgorithm.publicExponent =
                  new Uint8Array(match.keyAlgorithm.publicExponent);
            }
            return match;
          }));
        });
      });

  apiFunctions.setHandleRequest(
      'subtleCrypto', function() { return subtleCrypto });

  apiFunctions.setHandleRequest(
      'getKeyPair', function(cert, params, callback) {
        getPublicKey(cert, params, function(publicKey, algorithm) {
          if (chrome.runtime.lastError) {
            callback();
            return;
          }
          callback(createPublicKey(publicKey, algorithm),
                   createPrivateKey(publicKey, algorithm));
        });
      });
});

exports.binding = binding.generate();
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var internalAPI = require('platformKeys.internalAPI');

var normalizeAlgorithm =
    requireNative('platform_keys_natives').NormalizeAlgorithm;

// Returns the normalized parameters of |importParams|.
// Any unknown parameters will be ignored.
function normalizeImportParams(importParams) {
  if (!importParams.name ||
      Object.prototype.toString.call(importParams.name) != '[object String]') {
    throw new Error('Algorithm: name: Missing or not a String');
  }

  var filteredParams = { name: importParams.name };

  var hashIsNone = false;
  if (importParams.hash) {
    if (importParams.hash.name.toLowerCase() === 'none') {
      hashIsNone = true;
      // Temporarily replace |hash| by a valid WebCrypto Hash for normalization.
      // This will be reverted to 'none' after normalization.
      filteredParams.hash = { name: 'SHA-1' };
    } else {
      filteredParams.hash = { name: importParams.hash.name }
    }
  }

  // Apply WebCrypto's algorithm normalization.
  var resultParams = normalizeAlgorithm(filteredParams, 'ImportKey');
  if (!resultParams ) {
    throw new Error('A required parameter was missing or out-of-range');
  }
  if (hashIsNone) {
    resultParams.hash = { name: 'none' };
  }
  return resultParams;
}

function combineAlgorithms(algorithm, importParams) {
  // internalAPI.getPublicKey returns publicExponent as ArrayBuffer, but it
  // should be a Uint8Array.
  if (algorithm.publicExponent) {
    algorithm.publicExponent = new Uint8Array(algorithm.publicExponent);
  }

  algorithm.hash = importParams.hash;
  return algorithm;
}

function getPublicKey(cert, importParams, callback) {
  importParams = normalizeImportParams(importParams);
  internalAPI.getPublicKey(
      cert, importParams.name, function(publicKey, algorithm) {
        if (chrome.runtime.lastError) {
          callback();
          return;
        }
        var combinedAlgorithm = combineAlgorithms(algorithm, importParams);
        callback(publicKey, combinedAlgorithm);
      });
}

exports.getPublicKey = getPublicKey;
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var binding = require('binding')
                  .Binding.create('platformKeysInternal')
                  .generate();

exports.selectClientCertificates = binding.selectClientCertificates;
exports.sign = binding.sign;
exports.getPublicKey = binding.getPublicKey;
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var utils = require('utils');

/**
 * Enum of possible key types (subset of WebCrypto.KeyType).
 * @enum {string}
 */
var KeyType = {
  public: 'public',
  private: 'private'
};

/**
 * Enum of possible key usages (subset of WebCrypto.KeyUsage).
 * @enum {string}
 */
var KeyUsage = {
  sign: 'sign',
  verify: 'verify'
};

/**
 * Implementation of WebCrypto.Key used in enterprise.platformKeys.
 * @param {KeyType} type The type of the new key.
 * @param {ArrayBuffer} publicKeySpki The Subject Public Key Info in DER
 *   encoding.
 * @param {KeyAlgorithm} algorithm The algorithm identifier.
 * @param {KeyUsage[]} usages The allowed key usages.
 * @param {boolean} extractable Whether the key is extractable.
 * @constructor
 */
var KeyImpl = function(type, publicKeySpki, algorithm, usages, extractable) {
  this.type = type;
  this.spki = publicKeySpki;
  this.algorithm = algorithm;
  this.usages = usages;
  this.extractable = extractable;
};

var KeyBase = function() {};

Object.defineProperty(KeyBase.prototype, 'algorithm', {
  enumerable: true,
  get: function() {
    return utils.deepCopy(privates(this).impl.algorithm);
  }
});

var Key = utils.expose(
    'Key',
    KeyImpl,
    {superclass: KeyBase, readonly: ['extractable', 'type', 'usages']});

/**
 * Returns |key|'s Subject Public Key Info. Throws an exception if |key| is not
 * a valid Key object.
 * @param {Key} key
 * @return {ArrayBuffer} The Subject Public Key Info in DER encoding of |key|.
 */
function getSpki(key) {
  if (!privates(key))
    throw new Error('Invalid key object.');
  var keyImpl = privates(key).impl;
  if (!keyImpl || !keyImpl.spki)
    throw new Error('Invalid key object.');
  return keyImpl.spki;
}

exports.Key = Key;
exports.KeyType = KeyType;
exports.KeyUsage = KeyUsage;
exports.getSpki = getSpki;
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var utils = require('utils');
var internalAPI = require('platformKeys.internalAPI');
var keyModule = require('platformKeys.Key');
var getSpki = keyModule.getSpki;
var KeyUsage = keyModule.KeyUsage;

var normalizeAlgorithm =
    requireNative('platform_keys_natives').NormalizeAlgorithm;

// This error is thrown by the internal and public API's token functions and
// must be rethrown by this custom binding. Keep this in sync with the C++ part
// of this API.
var errorInvalidToken = "The token is not valid.";

// The following errors are specified in WebCrypto.
// TODO(pneubeck): These should be DOMExceptions.
function CreateNotSupportedError() {
  return new Error('The algorithm is not supported');
}

function CreateInvalidAccessError() {
  return new Error('The requested operation is not valid for the provided key');
}

function CreateDataError() {
  return new Error('Data provided to an operation does not meet requirements');
}

function CreateSyntaxError() {
  return new Error('A required parameter was missing or out-of-range');
}

function CreateOperationError() {
  return new Error('The operation failed for an operation-specific reason');
}

// Catches an |internalErrorInvalidToken|. If so, forwards it to |reject| and
// returns true.
function catchInvalidTokenError(reject) {
  if (chrome.runtime.lastError &&
      chrome.runtime.lastError.message == errorInvalidToken) {
    reject(chrome.runtime.lastError);
    return true;
  }
  return false;
}

/**
 * Implementation of WebCrypto.SubtleCrypto used in platformKeys and
 * enterprise.platformKeys.
 * @param {string} tokenId The id of the backing Token.
 * @constructor
 */
var SubtleCryptoImpl = function(tokenId) {
  this.tokenId = tokenId;
};

SubtleCryptoImpl.prototype.sign = function(algorithm, key, dataView) {
  var subtleCrypto = this;
  return new Promise(function(resolve, reject) {
    if (key.type != 'private' || key.usages.indexOf(KeyUsage.sign) == -1)
      throw CreateInvalidAccessError();

    var normalizedAlgorithmParameters =
        normalizeAlgorithm(algorithm, 'Sign');
    if (!normalizedAlgorithmParameters) {
      // TODO(pneubeck): It's not clear from the WebCrypto spec which error to
      // throw here.
      throw CreateSyntaxError();
    }

    // Create an ArrayBuffer that equals the dataView. Note that dataView.buffer
    // might contain more data than dataView.
    var data = dataView.buffer.slice(dataView.byteOffset,
                                     dataView.byteOffset + dataView.byteLength);
    internalAPI.sign(subtleCrypto.tokenId,
                     getSpki(key),
                     key.algorithm.hash.name,
                     data,
                     function(signature) {
      if (catchInvalidTokenError(reject))
        return;
      if (chrome.runtime.lastError) {
        reject(CreateOperationError());
        return;
      }
      resolve(signature);
    });
  });
};

SubtleCryptoImpl.prototype.exportKey = function(format, key) {
  return new Promise(function(resolve, reject) {
    if (format == 'pkcs8') {
      // Either key.type is not 'private' or the key is not extractable. In both
      // cases the error is the same.
      throw CreateInvalidAccessError();
    } else if (format == 'spki') {
      if (key.type != 'public')
        throw CreateInvalidAccessError();
      resolve(getSpki(key));
    } else {
      // TODO(pneubeck): It should be possible to export to format 'jwk'.
      throw CreateNotSupportedError();
    }
  });
};

// Required for subclassing.
exports.SubtleCryptoImpl = SubtleCryptoImpl

exports.SubtleCrypto =
    utils.expose('SubtleCrypto',
                 SubtleCryptoImpl,
                 {functions:['sign', 'exportKey']});
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Returns the intersection of the arrays |a| and |b|, which do not have to be
// sorted.
function intersect(a, b) {
  var result = [];
  for (var i = 0; i < a.length; i++) {
    if (b.indexOf(a[i]) >= 0)
      result.push(a[i]);
  }
  return result;
};

exports.intersect = intersect;
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the syncFileSystem API.

var binding = require('binding').Binding.create('syncFileSystem');

var eventBindings = require('event_bindings');
var fileSystemNatives = requireNative('file_system_natives');
var syncFileSystemNatives = requireNative('sync_file_system');

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  // Functions which take in an [instanceOf=FileEntry].
  function bindFileEntryFunction(functionName) {
    apiFunctions.setUpdateArgumentsPostValidate(
        functionName, function(entry, callback) {
      var fileSystemUrl = entry.toURL();
      return [fileSystemUrl, callback];
    });
  }
  $Array.forEach(['getFileStatus'], bindFileEntryFunction);

  // Functions which take in a FileEntry array.
  function bindFileEntryArrayFunction(functionName) {
    apiFunctions.setUpdateArgumentsPostValidate(
        functionName, function(entries, callback) {
      var fileSystemUrlArray = [];
      for (var i=0; i < entries.length; i++) {
        $Array.push(fileSystemUrlArray, entries[i].toURL());
      }
      return [fileSystemUrlArray, callback];
    });
  }
  $Array.forEach(['getFileStatuses'], bindFileEntryArrayFunction);

  // Functions which take in an [instanceOf=DOMFileSystem].
  function bindFileSystemFunction(functionName) {
    apiFunctions.setUpdateArgumentsPostValidate(
        functionName, function(filesystem, callback) {
      var fileSystemUrl = filesystem.root.toURL();
      return [fileSystemUrl, callback];
    });
  }
  $Array.forEach(['getUsageAndQuota'], bindFileSystemFunction);

  // Functions which return an [instanceOf=DOMFileSystem].
  apiFunctions.setCustomCallback('requestFileSystem',
      function(name, request, callback, response) {
    var result = null;
    if (response) {
      result = syncFileSystemNatives.GetSyncFileSystemObject(
          response.name, response.root);
    }
    if (callback)
      callback(result);
  });

  // Functions which return an array of FileStatusInfo object
  // which has [instanceOf=FileEntry].
  apiFunctions.setCustomCallback('getFileStatuses',
      function(name, request, callback, response) {
    var results = [];
    if (response) {
      for (var i = 0; i < response.length; i++) {
        var result = {};
        var entry = response[i].entry;
        result.fileEntry = fileSystemNatives.GetFileEntry(
            entry.fileSystemType,
            entry.fileSystemName,
            entry.rootUrl,
            entry.filePath,
            entry.isDirectory);
        result.status = response[i].status;
        result.error = response[i].error;
        $Array.push(results, result);
      }
    }
    if (callback)
      callback(results);
  });
});

eventBindings.registerArgumentMassager(
    'syncFileSystem.onFileStatusChanged', function(args, dispatch) {
  // Make FileEntry object using all the base string fields.
  var fileEntry = fileSystemNatives.GetFileEntry(
      args[0].fileSystemType,
      args[0].fileSystemName,
      args[0].rootUrl,
      args[0].filePath,
      args[0].isDirectory);

  // Combine into a single dictionary.
  var fileInfo = new Object();
  fileInfo.fileEntry = fileEntry;
  fileInfo.status = args[1];
  if (fileInfo.status == "synced") {
    fileInfo.action = args[2];
    fileInfo.direction = args[3];
  }
  dispatch([fileInfo]);
});

exports.binding = binding.generate();
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the systemIndicator API.
// TODO(dewittj) Refactor custom binding to reduce redundancy between the
// extension action APIs.

var binding = require('binding').Binding.create('systemIndicator');

var setIcon = require('setIcon').setIcon;
var sendRequest = require('sendRequest').sendRequest;

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setHandleRequest('setIcon', function(details, callback) {
    setIcon(details, function(args) {
      sendRequest(this.name, [args, callback], this.definition.parameters);
    }.bind(this));
  });
});

exports.binding = binding.generate();
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the Tab Capture API.

var binding = require('binding').Binding.create('tabCapture');

binding.registerCustomHook(function(bindingsAPI, extensionId) {
  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setCustomCallback('capture',
      function(name, request, callback, response) {
    if (!callback)
      return;

    if (response) {
      var options = {};
      if (response.audioConstraints)
        options.audio = response.audioConstraints;
      if (response.videoConstraints)
        options.video = response.videoConstraints;

      try {
        navigator.webkitGetUserMedia(options,
                                     function(stream) { callback(stream); },
                                     function() { callback(null); });
      } catch (e) {
        callback(null);
      }
    } else {
      callback(null);
    }
  });
});

exports.binding = binding.generate();
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the tabs API.

var binding = require('binding').Binding.create('tabs');

var messaging = require('messaging');
var tabsNatives = requireNative('tabs');
var OpenChannelToTab = tabsNatives.OpenChannelToTab;
var sendRequestIsDisabled = requireNative('process').IsSendRequestDisabled();
var forEach = require('utils').forEach;

binding.registerCustomHook(function(bindingsAPI, extensionId) {
  var apiFunctions = bindingsAPI.apiFunctions;
  var tabs = bindingsAPI.compiledApi;

  apiFunctions.setHandleRequest('connect', function(tabId, connectInfo) {
    var name = '';
    var frameId = -1;
    if (connectInfo) {
      name = connectInfo.name || name;
      frameId = connectInfo.frameId;
      if (typeof frameId == 'undefined' || frameId < 0)
        frameId = -1;
    }
    var portId = OpenChannelToTab(tabId, frameId, extensionId, name);
    return messaging.createPort(portId, name);
  });

  apiFunctions.setHandleRequest('sendRequest',
                                function(tabId, request, responseCallback) {
    if (sendRequestIsDisabled)
      throw new Error(sendRequestIsDisabled);
    var port = tabs.connect(tabId, {name: messaging.kRequestChannel});
    messaging.sendMessageImpl(port, request, responseCallback);
  });

  apiFunctions.setHandleRequest('sendMessage',
      function(tabId, message, options, responseCallback) {
    var connectInfo = {
      name: messaging.kMessageChannel
    };
    if (options) {
      forEach(options, function(k, v) {
        connectInfo[k] = v;
      });
    }

    var port = tabs.connect(tabId, connectInfo);
    messaging.sendMessageImpl(port, message, responseCallback);
  });
});

exports.binding = binding.generate();
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

function watchForTag(tagName, cb) {
  if (!document.body)
    return;

  function findChildTags(queryNode) {
    $Array.forEach(queryNode.querySelectorAll(tagName), function(node) {
      cb(node);
    });
  }
  // Query tags already in the document.
  findChildTags(document.body);

  // Observe the tags added later.
  var documentObserver = new MutationObserver(function(mutations) {
    $Array.forEach(mutations, function(mutation) {
      $Array.forEach(mutation.addedNodes, function(addedNode) {
        if (addedNode.nodeType == Node.ELEMENT_NODE) {
          if (addedNode.tagName == tagName)
            cb(addedNode);
          findChildTags(addedNode);
        }
      });
    });
  });
  documentObserver.observe(document, {subtree: true, childList: true});
}

// Expose a function to watch the |tagName| introduction via mutation observer.
//
// We employee mutation observer to watch on any introduction of |tagName|
// within document so that we may handle it accordingly (either creating it or
// reporting error due to lack of permission).
// Think carefully about when to call this. On one hand, mutation observer
// functions on document, so we need to make sure document is finished
// parsing. To satisfy this, document.readyState has to be "interactive" or
// after. On the other hand, we intend to do this as early as possible so that
// developer would have no chance to bring in any conflicted property. To meet
// this requirement, we choose "readystatechange" event of window and use
// capturing way.
function addTagWatcher(tagName, cb) {
  var useCapture = true;
  window.addEventListener('readystatechange', function listener(event) {
    if (document.readyState == 'loading')
      return;

    watchForTag(tagName, cb);
    window.removeEventListener(event.type, listener, useCapture);
  }, useCapture);
}

exports.addTagWatcher = addTagWatcher;
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the tts API.

var binding = require('binding').Binding.create('tts');

var idGenerator = requireNative('id_generator');
var sendRequest = require('sendRequest').sendRequest;
var lazyBG = requireNative('lazy_background_page');

binding.registerCustomHook(function(api) {
  var apiFunctions = api.apiFunctions;
  var tts = api.compiledApi;
  var handlers = {};

  function ttsEventListener(event) {
    var eventHandler = handlers[event.srcId];
    if (eventHandler) {
      eventHandler({
                     type: event.type,
                     charIndex: event.charIndex,
                     errorMessage: event.errorMessage
                   });
      if (event.isFinalEvent) {
        delete handlers[event.srcId];
        // Balanced in 'speak' handler.
        lazyBG.DecrementKeepaliveCount();
      }
    }
  }

  // This file will get run if an extension needs the ttsEngine permission, but
  // it doesn't necessarily have the tts permission. If it doesn't, trying to
  // add a listener to chrome.tts.onEvent will fail.
  // See http://crbug.com/122474.
  try {
    tts.onEvent.addListener(ttsEventListener);
  } catch (e) {}

  apiFunctions.setHandleRequest('speak', function() {
    var args = arguments;
    if (args.length > 1 && args[1] && args[1].onEvent) {
      var id = idGenerator.GetNextId();
      args[1].srcId = id;
      handlers[id] = args[1].onEvent;
      // Keep the page alive until the event finishes.
      // Balanced in eventHandler.
      lazyBG.IncrementKeepaliveCount();
    }
    sendRequest(this.name, args, this.definition.parameters);
    return id;
  });
});

exports.binding = binding.generate();
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the ttsEngine API.

var binding = require('binding').Binding.create('ttsEngine');

var eventBindings = require('event_bindings');

eventBindings.registerArgumentMassager('ttsEngine.onSpeak',
    function(args, dispatch) {
  var text = args[0];
  var options = args[1];
  var requestId = args[2];
  var sendTtsEvent = function(event) {
    chrome.ttsEngine.sendTtsEvent(requestId, event);
  };
  dispatch([text, options, sendTtsEvent]);
});

exports.binding = binding.generate();
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the webrtcDesktopCapturePrivate API.

var binding = require('binding').Binding.create('webrtcDesktopCapturePrivate');
var sendRequest = require('sendRequest').sendRequest;
var idGenerator = requireNative('id_generator');

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  var pendingRequests = {};

  function onRequestResult(id, result) {
    if (id in pendingRequests) {
      var callback = pendingRequests[id];
      delete pendingRequests[id];
      callback(result);
    }
  }

  apiFunctions.setHandleRequest('chooseDesktopMedia',
                                function(sources, request, callback) {
    var id = idGenerator.GetNextId();
    pendingRequests[id] = callback;
    sendRequest(this.name,
                [id, sources, request, onRequestResult.bind(null, id)],
                this.definition.parameters, {});
    return id;
  });

  apiFunctions.setHandleRequest('cancelChooseDesktopMedia', function(id) {
    if (id in pendingRequests) {
      delete pendingRequests[id];
      sendRequest(this.name, [id], this.definition.parameters, {});
    }
  });
});

exports.binding = binding.generate();
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the webstore API.

var webstoreNatives = requireNative('webstore');
var Event = require('event_bindings').Event;

function Installer() {
  this._pendingInstall = null;
  this.onInstallStageChanged =
      new Event(null, [{name: 'stage', type: 'string'}], {unmanaged: true});
  this.onDownloadProgress =
      new Event(null, [{name: 'progress', type: 'number'}], {unmanaged: true});
}

Installer.prototype.install = function(url, onSuccess, onFailure) {
  if (this._pendingInstall)
    throw new Error('A Chrome Web Store installation is already pending.');
  if (url !== undefined && typeof(url) !== 'string') {
    throw new Error(
        'The Chrome Web Store item link URL parameter must be a string.');
  }
  if (onSuccess !== undefined && typeof(onSuccess) !== 'function')
    throw new Error('The success callback parameter must be a function.');
  if (onFailure !== undefined && typeof(onFailure) !== 'function')
    throw new Error('The failure callback parameter must be a function.');

  // Since we call Install() with a bool for if we have listeners, listeners
  // must be set prior to the inline installation starting (this is also
  // noted in the Event documentation in
  // chrome/common/extensions/api/webstore.json).
  var installId = webstoreNatives.Install(
      this.onInstallStageChanged.hasListeners(),
      this.onDownloadProgress.hasListeners(),
      url,
      onSuccess,
      onFailure);
  if (installId !== undefined) {
    this._pendingInstall = {
      installId: installId,
      onSuccess: onSuccess,
      onFailure: onFailure
    };
  }
};

Installer.prototype.onInstallResponse =
    function(installId, success, error, resultCode) {
  var pendingInstall = this._pendingInstall;
  if (!pendingInstall || pendingInstall.installId != installId) {
    // TODO(kalman): should this be an error?
    return;
  }

  try {
    if (success && pendingInstall.onSuccess)
      pendingInstall.onSuccess();
    else if (!success && pendingInstall.onFailure)
      pendingInstall.onFailure(error, resultCode);
  } catch (e) {
    console.error('Exception in chrome.webstore.install response handler: ' +
                  e.stack);
  } finally {
    this._pendingInstall = null;
  }
};

Installer.prototype.onInstallStageChanged = function(installStage) {
  this.onInstallStageChanged.dispatch(installStage);
};

Installer.prototype.onDownloadProgress = function(progress) {
  this.onDownloadProgress.dispatch(progress);
};

var installer = new Installer();

var chromeWebstore = {
  install: function (url, onSuccess, onFailure) {
    installer.install(url, onSuccess, onFailure);
  },
  onInstallStageChanged: installer.onInstallStageChanged,
  onDownloadProgress: installer.onDownloadProgress
};

exports.binding = chromeWebstore;

// Called by webstore_bindings.cc.
exports.onInstallResponse =
    Installer.prototype.onInstallResponse.bind(installer);
exports.onInstallStageChanged =
    Installer.prototype.onInstallStageChanged.bind(installer);
exports.onDownloadProgress =
    Installer.prototype.onDownloadProgress.bind(installer);
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

exports.didCreateDocumentElement = function() {
  var root = document.documentElement.createShadowRoot();
  root.appendChild(document.createElement('style')).innerText =
      // TODO(jeremya): switch this to use automatic inlining once grit
      // supports inlining into JS. See http://crbug.com/146319.
      "x-titlebar { height: 24px; width: 100%; " +
        "position: fixed; left: 0; top: 0; }\n" +
      "div { margin-top: 24px; position: absolute; top: 0px; width: 100%; " +
        "-webkit-widget-region: region(control rectangle); }\n" +
      ":-webkit-full-screen * { display: none; }\n" +
      ":-webkit-full-screen-document * { display: none; }\n" +
      "div:-webkit-full-screen, div:-webkit-full-screen-document { " +
        "margin-top: 0; }\n" +
      "button { -webkit-widget-region: region(control rectangle); }\n" +
      "button.close { border: 0; background-color: transparent; " +
      "width: 16px; height: 16px; " +
      "position: absolute; right: 4px; top: 4px; }\n" +
      "button.close { background-image: url(data:image/png;base64," +
      "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA9ElEQVQ4T7VTQQ6CMBCk0H" +
      "AyIfAQbiZ+QHyDL/QLxqvx4MWDB+MvFAWMAuKsacmmSjkQSDbQ2Z3Z3WkQzsBHDOQ7owgs" +
      "MdUacTGmi3BeIFYcNycgciGlfFRVtcd3qoojz/PmdV0XOD8RGy1iCoQgT5G8IyREjni7IC" +
      "cg58ilwA7A8i4BwgMUxkKIV9M0PggTAoFlJpnwLhO5iEuFapq2s20CyoWIGbpeaRICyrI8" +
      "89FtAtqwGxdQ65yYsV8NcwVN5obR/uTJW4mQsfp2fgToGjPqbBjWeoJVfNRsbSskSO7+7B" +
      "sAiznZdgu6Qe97lH+htysv+AA10msRAt5JYQAAAABJRU5ErkJggg==); }\n" +
      "button.close:hover { background-image: url(data:image/png;base64," +
      "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABTElEQVQ4T2NkoBAwUqifAc" +
      "WA////KwANFAPiV4yMjA+QDcclBzcApCA6Otpz2bJluQkJCf3z58/fDTMEnxyyAWZADQuA" +
      "tj4B4ncpKSnbZs+efQjkCqjBmUDmMyD+ADSwD6j2FEgOxQWJiYmuCxYscIYawpWamnr89+" +
      "/fHECxbKjmB2VlZbs6OzsvwFyHEQZATXZz5syxAGr4BMR8QCwJDYvn1dXVO1taWi4ihw9G" +
      "LID8m5aWZgt0viXUEBaQAUDNh9E1o3gBFuIgA6Be8QKK3QXiLyA5oNMvIDsdph7DC9AASw" +
      "cquI9sAJDNk5GRcX769OlHsXoBKapAoQ2KiQcgPwMDkbGrq8sGyP8DChNQwM6aNeswRiAC" +
      "DYBF4yOgwnuwAAM5NTMz03rGjBnWsIAFql2ANxqB/l2B7F/kgCUYjUBbyEvKsFAllaY4Nw" +
      "IAmJDPEd+LFvYAAAAASUVORK5CYII=); }\n" +
      "button.close:active { background-image: url(data:image/png;base64," +
      "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAZ0lEQVQ4T2NkoBAwUqifge" +
      "oG2AFd1AfERUB8CM11WOXQXXAGSROyITDNMGkTGAPdAHSFIENAAOQqGEBxHbYwQDcE2ScY" +
      "XsMViNgMwRYuOGOBIgMo8gLFgUi1aCQ7IZGcNaieF0h2AQCMABwRdsuhtQAAAABJRU5Erk" +
      "Jggg==); }\n"
  var titlebar = root.appendChild(document.createElement('x-titlebar'));
  var closeButton = titlebar.appendChild(document.createElement('button'));
  closeButton.className = 'close'
  closeButton.addEventListener('click', function() { window.close(); });
  var container = root.appendChild(document.createElement('div'));
  container.appendChild(document.createElement('content'));
}
‰PNG


IHDR**oÊÐ`IDATx^í×1
 CÑÜÿÒ
nò‡.…´3(¥¼Aé $ހìÉC;—‚Ëߎ DŽ,`ºíN3QlÃyJ 	ÝÿúAõg
uJŒ!îC™7 £'*膟”.Ms€ß*IEND®B`‚‰PNG


IHDRJAÌuϵIDATx^µÓQj1@QÁ¸•î-º!áý
·¯#©#¥ÓK¾($y ˜,;Ùltó¿YvÓÙBz¦«ÀOó(#DQ6«&«}úŒɝE'¥Ú̲Œ®¦°Ú,”9VF|۲á&ÓÑòï&Ýä~Ÿ¯«½!jY͑›…Èa¶›¼­RoFZ7'•”Ê!€fg¿7m¼>wÓ%Zëá§Ùa-Ÿ-Ÿ4…­çȿõޤ‘I]ÏIEND®B`‚‰PNG


IHDR>1áå5IDATxÚÅÒ1@Ä@êóß¶â:ÞÅßDÀ6	D²Üç–FAr¦*>f¼lx¢-Ã%zOc¥q2ÂãIEND®B`‚‰PNG


IHDRé'O2IDATxcˆšþ?ˆ_ƒo€ø?ˆ@a%àŠ{²!‹"+IEND®B`‚‰PNG


IHDRfEØeIDATxcˆšþˆˆ à½AÄÞIEND®B`‚‰PNG


IHDRé'O2IDATxcˆšþÿ5‚ÿø
Œñƒñ®!‹á¯oIEND®B`‚‰PNG


IHDRüš¯„`IDATxcøO6¤·ÖQ­lÿ¥pABZ¥ôûåÞÊ@‡r¯ÌËþ‹Ъò]ó¿6Ôü¯sÿ¿­y{;˜~G‡Ÿk—²•õ¿ïÿŠÿU°ü¿õ‚i4˜Fƒi•£Z=>iô3ÒñIEND®B`‚‰PNG


IHDRüš¯„dIDATxcøO6¤·ÖQ­lÿ¥pABZ¥Üû­ßÚ|@‡֯üÊþ‹Ðêö=øØÿpdäþ÷¹ÿ_Š€֎½‰_’¿£äϓ—²•õ¿ïÿŠÿU°ü¿õ‚i4˜Fƒi•£ZÈ/{eϩIEND®B`‚‰PNG


IHDRüš¯„[IDATxcøO6¤·ÖQ­lÿ¥pABZ¥Äû™Þ2}¯Êþ‹ÐÊò»ûøîÿ—" 5t/÷ÎïèïsÆrB¶²þ÷ý_ñ¿
–ÿw¢^0Óh0
¡RbT+ñYJ™<‹·IEND®B`‚‰PNG


IHDRJ~õsIDATxc€ƒQPâRìJ‚òb÷’%g2‰5ݼôQé‡Bÿ&¢”Y•_ª|QâO¤é…f嗪>—†©¼̵ôqù³_b½êZr¯âé÷’ۥ·aõ­òI”k@8©ìY!ØID{ºâbåçÂ0è`-Yb“qŘHJÅ$ARâ+tsF³±PþñŠIEND®B`‚‰PNG


IHDRDD8“²&IDATx^íœKlTUÇí´i)-ˆøJQ„¸Rn’
l
„€š`W¦l`¡!Ý(AÂÃMY¢
l(C¤!!E(J¥-jKÃÜÞ;Ӂ¶ÐΔ‘>îñû9‡É8ôEÛ{;H¾Ì0çõýþï¼î9óŒR*^Ú	•••S²;¡ФͲ¬’®`pcWW×ÞPW×ϡP躤™ba1…é÷&iä!/e(K3lÉ<Ž
BzN0|GÀ`K÷ݻªïþ}	‡U4UƒƒƒjxxXŒŒ(۶1Þóiä!/ee©ƒº¨“ºÓF¿ßÿ¬üewÀ߽==j``@


<-£ê¢Nê¦
ÚJYA:
c‘„ėò¾7O Âôš
ڢMÚNA®]»æ‘ÐøDÞwã$a€F[Z˜n|YÄ2Í×Wúûúˆ{fÅhðE|Zî¾ t˜ÀûRi?q
@*¾à¾á£+‚\¸p!Wâö½ÿÇH)Ã'|ÃG|uT[--s¤wÿ¥¿¿?>\¦¢á>â+>;"ȟ7oJŒV‡¥!ÒÁðŸñ}Ña"3Ç1ÒJ|‡a¦ñH<~ۯÅHGÃwaØËtÉ	XÖtRºÏHKÃw„åC˜¦,ˆá��}z4Ikƒ˜¦$HuuuH€Œ0X`‚íI!Tv0û “&aûÆIÒÜܼ$$ë=Ï(ƒ	6'+ˆG¦¾_±h 
6aPÆÆÆçDÁ{z՚‘Œ7›šO$ˆGâëýíÈhƒV˜Ç¤ªªª@záv½¹“Ñ£°vÀ<– 9²%Wv¯·×]€sç”ڼY©²2^•}ú´²]šÂ
3ì£	’Žºº¿qü¸R¥¥™]QáÖþ	ë÷°&áÒêZ¸D£J­Y3ª jõje?xàVشÁþ˜ -ÍÍËÙîw-T‚AàÇ4ÛçsŘeÏdE² Ã0>b”2‚´µ¹â̝†ñ1$
’gYÖþH$’u‚À;$
R ‹÷Ÿh4ëv4H¤P6P™çg› 0Ή‚̕޶‹)m¶	2iL4H¤Hæöv–²M‘áa¹‡‰‚sÁɆÕ޽Jí٣ì+WbiwîŒ/ˆiÆjk)GyÇ|öA4Hdžガ[ƒ=|8–&á©6n]
H•;tˆ4ʻ+ˆÓ!£ö틁mڤìG³áëוZ»6QþÏ礓ü¤QÞѐI¤X>9ک^½‡¶Oœø_rì!k²xùtÊ;ک&R$CO“Óî*/®Z¥ì3gÆ |䧜ÓÃnSr§:7`Y¿:>1“~J­_dÌvîTöŋÊ~´åÐӣ욚¸pùíînG'f°'»…fgçA7¦ں؉mËe[–ãSwؓ'f>Ÿo‡k‹;:ÕÊÊx‡™dŒ>¤“ϕÅìÉS÷¼†7Þvuù1ªµ·+µ}{LˆmÛbË~'ˆ0744¬L^ÜyÄHçÒ1û©j×.áÕõ}Uaö^¼üNJ$–*ØVËA`…öQ·e×ì=6^³EXa†}ÔMæS§N-–°ñgËcXak“9G¬Øûö×Ùò 
V˜Çzå×ÔÔ,“©l_¦?ʄV˜Ç}”)6ßðû¿Ëäo	—
„ñ ¬ã>ÊÔVpéÒ%N(÷fêqØjkk߄uRÇ!P®£½}w¦˜
ÆI‡Ж/½]¯ç%a°ÀŒOt¤J¬¨¾¾¾TB'œ)‡î`	¶':R…é±yakkëg™r,˜`›ê9U†¤%†ñCºÜ†aiZwÅ
Ož<ùŠešUéz´ßa€¦ií&æÎz½K–õ[ºþÇg|‡aºG»“E)öz½¯ËêЛ.×CðŸñ†™¾/“KÅ>%†aT¤ú"|ÄW-F®37ªtøˆ½ÜzëV¹c‘T»b†Oø†ñ0qøΝGwNK~¯«{7ü‘*—񥮮®ߴ×.!ê!y¡„ЫmmmŸóôk¶®©Ò6>à>á›[—“-W‡Ðrci¥ì/çî»u‘™¶¤ͣ´ڗÜټȜøma±ôÒùóçßòut|ƵSWݩ›6h‹6i;þ­H•«îºo)ÐαxZ*Ûûë
¿ÿ'0&ùc€úcÔA]ÔIݺùºMOªÝýO&_‡Ò"1fˆ¯Õ^¾\*ÇËoû|GLÓ<+«οxÀ.ÿ¢ú§2†ØÅp“4ò—2”¥êÒué6<iõsº)ÐĞ×_ñýWfÒô†ØrmËøL§•—2ºl‘®+7U.c*ÃužŽõ9bs5d±Ø<^1ÀIÓyòuþÅI°§ö/#ã蘀\‰IEND®B`‚‰PNG


IHDRDD8“²IDATx^íœKoTeÇeÚtèD¼¥‰(B\)·lð˜¸0ꘘàʰc¡Ý(AàBÃƅr۔išB¤Ðªµ�C;—sæ.ÐË̔‘ގÏo|3‡é&çíÌHžÌ0ç½<¿çyÎ{;óŒeY%öÔ
§OŸ.Ø?é´cÇÛSÉä©Têët*õ[:þS®ÅIJb¦ÞǸFÊR‡ºNú¦ø„ö6%“Éwì˜îܾmÍÎÌX¹lÖÊçóÖüü¼µ¸¸h---YËËËïùŒk”¡l¡uiƒ¶h“¶kFÃ0ž•¿ì›º{ך››³®Èhƒ¶h“¶郾ªV¨iøFÞOe³Ù5D¨\ú /ú¤ïªäæ͛	Ïäýœ$Ða��ƒø²¡‚Äc±}×}™ÙYâ€
1úÆ|ŸöjD%ÌDâCyŸ!®¨Ã|Â7|Ô"Èå˗$n‘ýï߿@U>á>⫣‚Ü
6Kvÿ=“Éo—Õhø†øŠώ2:2Ò,1ڝÍd¨	ÃW|Æ÷ʱ‡‰ŒmbԌ(øCł¨Â‰Ç2JŒZ4|†£°T$™:D’r ghÍ)0ËÇ0=± ¦aì“×Yu7©iƒ˜žHîîîF:s¹®0X`‚í±Q¡rˆÑn2˜„ís×-Èøøø®´ÌÔpÜUl0®K2±}¿eÒ€
6a]SáááçDÁi5ku¥Áãˆ߿sUAPLâë+õípµÁ+Ì+
ÒÑÑá•,T‹;®6…5óJ‚l2ãàôԔV€H$buuuYgϞ-¼ƒAm}Ã
3ìåiH$'u®oŒŽŽZÒï#622¢ký„äúìå!\&t…ýœ;w®œ |Îu]a3	û#‚ÆÇ÷²ܯ+Tr¹ð+ÚÌ̌?`–5“}vA<¦i~¨Z™žžÖâÌQÓü
Ji”ݱ£8Yo‚À;”
â•äâû7Ÿ¯;A`†
Ji–”aÆùõ&̰£A© -’mSiëMÅÿï414(¤UÆö9V–êM¥ÅE™FƒRAÚd’ãhÇ}}}Voo¯%ƒ¿â h5AÔ|Š„G=ê;曰ϣA© [œDæÐÁÁÁâ:§Ïç++ƅ¸å¹F}½‚827nÜ(€uvva¥Oëüùó‰Áÿù\‰Fy®Qßѐ±Ò&¦Lª²;_„{(—øý~B‚×b¨`”Su¨ïhRµÒ*·¿ӷÝ+W®àΜ9c…B¡Õ¸N9ÊSÏéۮߞT[d±¤Ë遉Tå’"h,³òªß{÷îYÑh´(Fy>wr`»ý¶Û‹Fëº²
ìZF9Ê;~û‡Ý>0ó†ÃáCº&w$Ë@ PL˜vãîÃuã"˜a·Ý‡ßVÓ­Æ4ÿâŋÁ+ÿ×Ú?ÌCCCûí“;Ø6I.¡XOíééA^µ¯«
svûôk•X:Eâ«A`…ö²Kˆ²jö¯õ"¬0Ã^v‘YÖ2wJØõ²
+Ì+-2ok3"‘ïêe£
V˜Wچ®^½ºG†²³nßʄV˜WÝÊÛjƏnþ–ä„MÃ
óZ»ÿÞk׮qByʭÇ!`“5–7a]×q”ƒGÜz`6a]ï	¢&ɾ/Êjô€—¸Â`	6ëH•XëÀÀÀ	¬[ÝÁlu¤
S÷æí_¸åX&,0Áö¤çT›ÄvEMóçZ?¸+¿ÀSEwŚåìÆ+ñX¬£Vvã;°ÀTñÑnb®ÓçÛ-+K=µvøŸñ†JvÛEi“…›×ev諕ÇCðŸñ½(F…‚ؓl›„O»iš§ªý"|ÄW%FƒÃGìå‰[·Ëm,Wm˜á¾áci˜8!H©(Ídì?úûߕ­ɿªå!D|éïï?ˆoÊG¶‡Õ-y»„Ы“““_²ûµQ©Ò7>à>ᛞ‡ËçBèybi¿‰œçft=ÈL_ÒçIúÆ|±å­‚ؿ-L–^ºtéÒ[áPè{¬zԝ¶郾蓾íß
ý‚”Ï-^å“§ݲ¼ÿ¾i¿
€¹ÎC¼ì!ÐmÑ&m«>¶ª>=u¯H˜&J;Ä!¾Ö{ýú9þx8ŸíËN™uþÍ»ü˫ŸÊX`KÀc\£e©C]ڠ-Õf«êÃSS?—¡rŒWl{^}ÅÛÕ_™AÓb{•íá3u­²ÔQu[U[
:~.C‡R*Ö7‹µ(È6±-¼b
¼E•iRu<ü+
RbOí?ª'þ%i<pIEND®B`‚‰PNG


IHDRDD8“²bIDATx^íœ[LWÆË.a…Eª­¥¶†¤V«éSëC_a
* «ÁcñÁz½$Ҙ&$jŒUË4QcLT¨‰¾4š–›´	M£֤M!ÐJkQ(EQ˜Óÿ¯{¶#÷u†ÝY¾lœ=—ï÷á9œ9s†”RAz®ÿΝ;7&©ÔÔ	«/++¥áôôO|¾#-íº\ou‹”V7×øŽ2”¥ui#DÆgi ”˜÷ì¨6Šhƒ¶h“¶#&K—¾(?ÙÝЈ¢mú ¯°
äavöKýééåÐ	€Mê¤Oú›@~ٱÃ%Cc½t0IêÀ^&5GYYó
Ÿï{ÂAxOól„IíIFF±Ü Ìtox´%º}ûÜ2¡ œ…G¼ZH{qñéè"Axų%üµn]¼ŒÑZ"IxÆû3
D“"Qx‡áY¯ÕOˆd	ÃaXB
$¦Ïï_€$,ïÃ4Ñ@X†Ï€{N	˜&È7GŽÄèE—“lã
„¡ò!N”°•Â8æ@î¬^,w”N
6LjëIfæ>œ,a5?6lxY¼ëô@`¼µ~ýŒÑq=öû? +ÌÃréØ1$w3ZÖf˜‡$FÖ¶”—+£¹Y}}|*uð Rii¶y€ö¡q?Î̬²5ŒãǕaOI8açäú9ìCâ‘E˯¶…á÷+ãáCxZ½½JeeٵPû
ö§i[µjž­C¥ øa¥֬±͋°Ï7âêY²¤$¬Y»Ö6/=ÙِAp ±òtìp´;⑍ًÑìdH¼ì*ý­ÀNA$È"åN”¾kâ•@Dk ÜאAp ‰–wzù²2®\QjçÎ@~þȁví¢õ­ô÷˜‚™jy ííØêê€ϧŒÖ֡¹}›ïõjj¸F}{±zȵµ°–¥ÒÓ›7+£§'8þÍu(Gy®SßÒ!c$Q&–6K‡Íöíƒá²òÿsɩS	>•Z¹D9Ê#ê[:©šñÊ9‹Ÿ-6׮ûû•:p`$¾§å©g©/Ø͓j‚Üé~€¥Z±Bmm@tõªR{ö(•“ÈÍUª¬l08åU^ž¥¾`7ÿڍï]¼¸«Ő0]MMJZî	vóÂÌs//ϾÇLªƒ¦Y­­|O9[üÀn^ºÇÞܸñ]l;c%%ʨ¯ÑÐÀm?×mõÑ\ZºÀ|sçM“5}ó¤ìmÖÕŸ“q2àwØͷÿÈ+céd´3ìCn!ÊÎQ^´3ìCn2_8}z†›[Dƒ`…y¸MæQb÷²eû£%Xaî1Šû¡¼|®¬íï9=a…yÄG™¢$yxó™Ó‘Mõ
XG|”©幾w/'”;l7ÊÊކuLÇ!Hîn~þn§Œc:¡wá̙™²ý£Ó€	6Çu¤Jämڴ)U&Ÿn§„L°ëH•–[4½£°ð#§L°Môœjœ(Yõô0„á,0…tpWþìÙY-ú2RÃÀ;°ÀòÑn‘÷몪Ùré»HÏx‡!ԣÝæP¥á9rwx1RÂÀ+žñó~_ÆMÃ2|Rd•w2ÜÃÀ#^un^ >¢×ÿ.*Úbz–ÂÞ𨽺,}ÅL‡/Jnغ5Sv¬o„Kx©߶-oڣ˶—õJoúùêê7þ)((3|¾I;ìKßxÀžðf×KˆæÜz½Z·ÿ‚JF]6.鳊¾񠽸'ë½]óÿ–$Ñkß:ôN×òå‡ä
&Ë6¬i›>è‹>é[{ˆ	›WÝõÜâÑæfŠfËöþ
™íOˣÂ?C
6h‹6i[÷‘¤ût…ۻÿæ`âôPzI4Kô¦ì?¤Ê+£[îçæVÊÊñ’ÜuÖËÑ6b½ú	»XÞÂw”¡,u¨K´¥Ûôê>\õç2ôãÑÓD¯èÿâ)ú§<Gô–hžÖ\®éïR(K]׫ÛrÛñç2ìK«ÇúQ‚†LMåið]&N×qYéÍHžë_ÌC{[4áù¨IEND®B`‚‰PNG


IHDRü|”lVIDATx^eϱ
À DQ²SDi)ÝRE,Ää¸Â_r÷¾®pÑyז“«ßÚ)ÇpS¬”c¸KS“ñU
ãG°ƒjè]°ƒS×Ѐ2Á§d¿pÉ ÿ#íIEND®B`‚‰PNG


IHDR@@`¹UýIDATx^í™kpUÕý†ß@’sr;¹‡„B\$$@¡*X­…ÑÚiíX¬X‹Š"¥8t°ढ़*„QükۿŽ¢ã࠶Öb¬ ƒB©w¢E”p“[ˆ„ÜHÈ9'çifÍɚ=ŒÄÙ'ú¥óÌ0¾¬g޽æ]¿u–ø/ó?s}ÎOL?ÃÃ
æoó¿r‰;»ôpÅ)^yûI0ÿz¯8źÐp/`—öÌó™۵6°½ïa >Üuæ©ã?½/CřD¬ÄPœ¡›ÅÿYÜQno#ÜֹöµÑòD’²€ÅÄ«ø»2Úÿî€vêyˆEÌç6îe#'$Z›oW‚É!f¨ÎåãäÝQü L=sˆCNˆa›ÀÐõì…>Å…¡
Øåö\nØE-:/WҌQX¯$«0»ü3Â3
J!û8ºHIŠ3{aˆ±òÞ72t`ún(§èk»¯P	f;F/`v¾G)­ëþŒœpki`/°ž9È}œø£|ò˜Ï­€‰?±n\ø"Y¦³œ°™+Ìi Ô<3O‰æ3D'`ŠÇ#ßá‘åçtnøìå¦7më‘eMwÚ¢ˆU¢2ºނéV Š6<Q0[iºfTý°ý„cüô½_¤d)Q±Q
˜¬œP3|Œ,¯ð×û5U“U©‰š¤šWV¬C–gøè:“íE·ù”G¼†,­@G“jU¡ñ*Ò«<³¦ç8t:ršÊ0D)àUšüo"Ë pzTµŠåW޲•§B•ïZ°Y6P?K)Šװhҕß{!ËC¼
”-ŸR”¡<×LuÂ1GE_@ÛËJ7}µÀÉz€J+0’^ 竄QÊP²’”ªuo]Úú	ÀîgeÑh6룕J6ÕH•ëçn°õ¼{ƒ²•öñ%íÿ:çrU, åq¥Ék
ɵ@¼|ÊÍ+ë9]dX
<ØôrˆÝ ËJ„0¥Üqcaä\pÝqJR¶Š>¬ûÖ
f—y…”cÇr3[Áòõ½Jµ¸,¢e¨`zM¨Žo¾†÷YLúV&ñ΀âÉrm.š Wã¾|à&dÙ
-hbX
†ƒ˕jKم€ùÊRá‚Yá |†,óØK”µ`ö²L®†˫TTɑMWZ8Žp2c
·°œE|XdƧ‘l)»†E6â˜Õ?؂,¿`b*Ñ–#\‹,—<ªLSÊîL¦Uzê=€*+FÁ_ ‹i(6ΐϔ²+{&ª襅Ï!Ë#؅ƒGßýÛ—ÌÕŵsßþÀ	¼VàzZ7(#RÊnL	JW~|yç>ï@ƒ@¨ûµ3çhšjT­MՌž€Žýò5îý}™-e¦•¢*~k%@²làñŪQ¥ÊUªrUÞzu_/Àd¹“Ê[ʮl!Vm6ÇôWÀ7ï©R%2³AÝÜîý`pŒª©t}­W²…äBÀQH»X‚,ÛhÝþáÝۮÿ|ië¦pà
¶!Ë,³…äF 2fjôœé}ÝpÐq=Ç1pB‡NS¬Àh‚@ïþ9&·‘£9Oã›6üY²yÄJìãQJâG<,øt¾-$ҰR^|y8GICNÁh|ÎäK H¨ û_vJt#à,å½Ïl!
Êí¬F–·xóvJt!àÈ`ô¤Î&€ŒDÀÃýt8r™@û&[HnlywͬPÀi–Œ΅DnÅ8–:Žç/BÏLQ²É€½)*S*߼´³L£\Š˜Éíl¤mMá vœŽ7Ðò¤Ò#…äBÀޕ5BEIUÝGÂ4ÂyéØÿUÞÙ{ëæY/'p÷ⱑBr%`ú r6–ì\ë˜É:šÀI¸óО—[¤iýL_r=ÀGç^Ý9xÏ@!¹°[qRu°½‹t„ðQËrà›ƻL¸\ÓT­*UôS©êæwf["º¶G¦wö3˜Jú÷S8'e!¼ðZUk¢JU¤Â~ƪü酯"KÐצ™“ѥ€³’n¸40W1b™H¿ö¿¨TdîŒYÊÖH©âÌAèA–”gѽ€³’¿w0Bxh¦¯g^üÊTŠ’”¢L_hÓȲÓÌò›£ٽ€sN|ðøYVûV®R• •ž|ÀSÈr8{XùJRÀ9'¶4ÀeV “nB§~S®4%*AÉïÎîÞ	ÐLžãºpâUåG€sN|áxYV_-zaÂ]þ¿W·=ð5åI¶ß)¿™¢°s¢Ê:¿;àwtƒåëÈ@–‰ôgå•)×ÌÈQ	8çı[—A=rÉ|êx‚¸šäÀÇç4¬T‘²e“(ìœ8*yB[#܆¾“vpr{|¹ق	.šp°–Î	´…X€e{èüêҋT¤œ™ J›Aºü*©»îl<wދz6kÐúÉU—j¼üöw£¡˜’•¥•Ýteó.èæ/\F<²¤rÏrÂ{6ä֪T£”©$3E>åh´Ê4ùÅe­Aö°×ÙÁú BëîoT•JÍok)v4^À>äxBJ4Qտ¾¶aݡ-m_vŸœî>~ªq_ýæÕ?ûñGÿ¿v¦¨B㔯,¥ȫX÷3áyg£%¿ŠTª
MRj5Õp¡¹/NV¥&¨D…ÊS†’í£ÖÐl
%)MÙò«PÅ*Q™.è§\e*ÕxkŒ
4RÙJ<äØå‡*à|MLP²Ҕ©åɯ|ƒ_#•k~ÎÍ0‹{#¯i..§nrˆ—W‰J–O©JSºҔ*_?ÉJR¹OšÑþ¤;ð¨kðDžtͣ®]ü¼ÿ+è=D¦,âIEND®B`‚‰PNG


IHDR@@`¹UÄIDATx^íÙQ‹‚@Fá“eIȀPŠèMEA ±ÐÿÿO-x±6}ÂÔ.Lïeˆύãy|xà´@ÏoĈ€€qgAû½“{Œ˜1cþ»!“á ·‰/-BŽ"b1qY`ÚÛuÖB·€ˆ%+°bIä0fFB¦2fŒÝærc˜¿P(€bÀ<À<À<ÀNM}SbRJP’3e¬OòUvjê‹1¬©@ÍC¬\kå«ÔÔÔgôéù*IMçÉWX©éfv¾
@RÓù$_`¥¦›Ùù*IMç“|}o¯¿ñÈÐ}
Üì§@Î*öœ¹ÒèãÆ7÷×î|s£ÑǕ3{*9:'!*¶ìùRwàąF4\8qЯgϖŠœ„w†9…º’šGpdGMI¡.'c…‘wAçmȂ%	F)kJv
`Gɚ£„%y~´>\Dÿ:J=À<À<Àr=5Ýô|uÿ½%_ŸSÓ!ÀÎW;5ú‡’¯ϩ	½
°óÕNM‡€á_NuÀÓMÏLÈyIEND®B`‚‰PNG


IHDR@@`¹UIDATx^íØ=K#QÅñ£Nތ/‰F#ɺA
[‰,ø)¶Y_š-+a]A?ÓÊZY[Ùm/"kgc¹½{ðž…Á3NFb3ó´üȝ¹pï<ïH) ¤€@ gÀFl‰}‘7€Èr†þ~Á
!â¶Íý¤€fd6] !’ ã:›È" c  óYî·\Ç9#$€yn
;ç:÷[(AB@ç‹wÛÌóÁ	™H@†Ð1HøóE#€Êßìú<eŒ"	Èq«ìœ'ÜìAtþÔªGž,ñ0•çVÕñ9
@çá5L 	(p«öŽ$@绀9”^(aÎ4Á:o€ú«uÐè¼æ_
˜7€ @ä4Á:o€*!pHL–4 y,`%
bFPâÖB"ìÁ"o€øƒ‚D>1@ôoŸ|¢	"ß7‚?¿nw,ßÂív÷l
¿۶|ÿ<¬ó¬SQ¼Þ#ô
pò¸ÞC‘ud1Š©«ý§Gú–z¼ÚÇËYxš‡žПüÅ!š]@E”QGëüèeBȟ¡ÅbÙÿ‡Á,Ÿá­–?;Æ2kþý*è¾FN`Ñ6B€
|Æ:Öô`[,½œo³4âÅíž(¡öÁø„U´±,¦Un­±¥ò5Öì¿P€´°€æÅ4¸ÑŠãÎÿüÎsœ& Åø4*(‰©p£–TÞNCAHö> ó„doD:oEHôN¨óЄÞ2hB/™4¡—‘$_±?͘ÿõ]ç
 	Kþ¤ŒõqêO¼%7€&4±xyà:±>Ï;—XDSç
 	U̢þû[œ
n×1‹ªÎ@Æ1‰
Êq®hˆ­`ã:oeM(1ʉqIî3^ðùÈNô5ӹ8×tà>ãA¬¼¾¨äĸ¨ôÛÆMHøÞx;½-O) àŸôm‹
¸tÍIEND®B`‚‰PNG


IHDR@@`¹UôIDATx^͘mˆUÇgæޛö!$-X-´¢’`/ë–”R¹õ¡Óò¥¨ úPFŸLÒÕòmWWñK`-ÅÊE`A,T¢D¡Q°‚©»¾ìû:sçt8ïäNw{.ØüØOsï>¿}þóœsv<ÍõŃëÊÿH@a¸êª5”Á3øÿŠgP^ªŠW[‰‡uVq–¾!o(d’7ø…jŠÀêx…ƒWž!‡‡qœxy]×U]ÑåL*æ3u¯©¼ñǿ©w¤Ë:NLÁ3ä¡eòx†T|r€?uߙ•TP†…֞
äš;€í@ÿ¶=NLÁ}»e
øx¤BÀ&ðg‚J"¤e|¼tܯx7¥@
i}MÒàAJÿ¬٫GZH€‚ädÈtš‰ír•&C@¢ @¬ @® @® @® @® @® @® @® ®…P@„P ­Ð%P8…OÒ
h—}&蔀XAӀ–i£€XAF@ÍVsÔýj¾Z4.óÍý9jv" €XbêԨP" 8.%*Ԩ[T!‡GLH™c†+ãaï–(S'r+œî²14¨Sn¡ej„Įr…YŸ^‰DԩRɤšÐÈè€@¡a%²
Iyð }
fuôÝ@f´éº ^	å
¡Bz›ÁK*ùNÙþ–¢Çå°
gžÂGYÚ#Ðޝø²°ïFžtñÊ^ç0 AÓ
\lLéRËÔµ8ÙdªªSݧîUw«™ªcÚg¨6E°‘€
à8Àenö·?NH•’Á-±v•‹h Û6†ëÙZ³‚éÐ<¼̮üÅÔVPv{\à%¶¢t_ßð¥kÀÑM̭SߚMÝö hÚh*®Z(ð";Pº÷sG¿„Õ á4x¬~MHjz«!$9pV±Å7;Ÿø”`C1º¥i¶ÓçΚĄ©Í&)/Šàyv£ø~ے>JQñÄϰƒüFÞ;²ŽŠ˜X7®"¶H"x–½øíXØK¡øþ¾yt¦†qÖ
&S°í<–?Í|~ÜõÀnƒ²?ΜkÆƸqÊÁÅäÉáµK@ÂçøÞy;)JöÇ0pD³‚HØ,}Èã)¯Èq²gn·-_qOxùÍ//†ւã#4ÓîéšNޅ Ðħzælu]'ĞóJI!x¡iQ꽍I”T@0Üs×fʮ|d©S£úa_™Ž¦a<ܾ|Úd|<„ڍ왱	W>9¿E„˜(ú>kóGègŸ´‘PÀ)4ïx;I½†]N´¹ÐDԨP8Ñɣ¼ʯe9èáSÛ×?v¬=chÿҠš,§!¦¼»Q¥´yp$„¶p'åú·Ç:×Îذîb À-ªMå±wìƒxvôäwøktǡ©kê¦H‰*F<Cd±ÍOÇC…àЁ¡¯W½ѱîåϫç9Ï—(R%$wÀ'h­ÓŠè=þà¦ޟ¸€)ÏF¹L@Eځ´‚F+N€*E.sÁpΕ/R±Ãê¾ãhó+š8	aŒKŒ2’/Ùò
ƒ4‚l\5ÊM/¢֊ËH–¤:Õäð鎒ëoÒ¹¸ÎZ>WIEND®B`‚‰PNG


IHDR@@ªiqÞ	4IDATx^í[}lVWçýì[úñBûÒõ»S*Z¶“¡Ø1†ÃA‰‚K±¢Ý©Ä"$$‚’…„¿œؒj•Ď™!I#! F‚eP *ý²¾Jéñù%¿ӜÜÜ֛޼7Ñ'ùårï9ç9<¿óô<Ï}îy'(¥þ§álø?–ìã]Æ$ ä†ј´Œ¼=Á	§ÑALd2ø<Æ~aÏÿ_gƒsÒGÕâj²ì3Nã0níڵɛ7o¾vï޽]?þxxxx@‰àŠ{<G;ú‘Œ¨I„gǤmh``à{Z)ÉùE€cÅã˖-Ëéééùá“'Oº”A?é߀qoz„7h<Ýj"õ‰ҕrŸi(
3Nò§Nš)«û‘¢œû×Gê§m›Õ+ïÎW•¿)WٿãŠ{<G»҂q§OŸž=¦7x% ã¹¹C7nÜX-mYn$؈éyœ;qþüùâÞ}˜øjÿõÝ÷kUôí	*2Ў~èÁxè!	1M‚°úp¡”¢CW¯^}Íq®|[[ÛâÊ=˜°µ³U6N‚žþÇ?‰^èszÂXDØ9)(T”m۶I‚54~á…ùƒƒƒç1ÑŸR?w7Ò×vŒÃxˆèûz5	^ÈL”p4øCWŸz²oݺõ&¸ÜwI¥~Eƒ¼`ã?éíPè…~ÎC/›€<A™A€_$èÕÏ\¼xq‘¸l7”¿þçe0Šz CCCÝÐOۢ^	(7ð‹½ú9/^|JÿÑõ!°'€€>ôcí^¨0ð®>ÿäúúúöB!BÚx}þþþ÷0éŸŽ{Lb7åáÇ¡q}<	˜ßR­ ¢ÿŸ˜‡óÅì°'Átÿ\A¡„¬;P„äF`#ZGqS¾‚@?æÁ|z3´#s$͈c†>qõÌÃù2,	°'$rKe§¾X1?<ú1çKØ`O‚I@Ùýû÷;0øå–}Ù<xЁy¬	°'ÁݺººÞÇù±/Qú}ð{1cÇ~„Avµ+Ð9~üøöQ ªªêY)nôú‘	B/ôû,Hpä‚Ϟ={ö€Þö] oGæȻ€èýôÛä~63AAYii錻wï^ϷAèƒ^è·É}!ˆ3GJ0uë֭¯‰Ëþþré€öÏ@Œ£ë@ôB¿ͻÀx’ð¦&A×õœŒÓ_hllü>þóÐÙ•Oƣúkã¡ú —ú'êÕ÷—ï$d€^³¹T¦o޼ùõ;wît8k‚ˆëEy0WÜ;k‚JÆ]Âx衾)f=H8o.]õiŸŸÿ¥#GŽüLÊó=ʃ úcšúr]+BöؓI$$IBÝwfyyù¼}ûömíììü@V÷²¸÷=(À÷xŽvôCŽ« ž¤Y´!Àzݶ”Øt6[€՝«ÁûÙlŸÎþ¥ŸëZ¶'ÀOà}W±Œq|š JðŒ隣½Œýó8Þ}åí	🃈Æï)ÌäJ¸Âe¼–ðùöËḸ»ñöøO£§AYté$
ÕHòy–«á4>
ØGùT_‡J:	°O–h”Ýù{ÒN‚WãÒ@@ðI>öå5‹3B€„à°hÑ"e)æù„L3ÄŠ€ÚÚZ׶P(¤.\¸ l…'Uðz›6mRêêj×öuëÖ)HooïP2™ü¶´Õ¾*xIð¢jÁW_f~?ƒin93½ÆýH`ذaƒҲwï^×>ÙÙÙø8© ïŠHÛBúEÁ,jâ9æùŸgŽ_"HŽ€õë×ã,ä£
£Š‹‹]ûîرCVèáÊÏ|NðÌe‚+^¦ó|ŸˊN,Ô×׏ßÒÒòÇk׮õáfûöí®ý+++ñP[¶l©Ã[,äsN't®ŸCã3±	®Y³fÄøýû÷¿#mßinnþܾ}[ÅãqW<¨ ÖÚY´(¤|‘q…Î÷cNãÓB@]]6^Iù©YÚ^,F£+¤:ó
+W®t%@Ž©èƒKO¦N:‹‡ÝáÌùÓF*U«ð•UANœ8ÑĊL5wô¥òìïh;sæÌh!GUäܹs`å&W×꼐–LpŊ#ÆË)ÌfîàÏY–,YòY]™;w®+	


"ç{û¹	¦èæáÀ°|ùòãÛÛÛßaèšƪkÿý‚ æʕ+]è·gϞQC¢œ?Vݻw£RÄ"H4h”goõ7¶ßkãuá‘(á®þ’l†¿•耵***r%¡©©Iqü@'ë/xrîv—´=¯gèÊÑÅK2;++ë’²þ·($ÒBW3NÄüÁ €‡¥££ÆÏ0׵;€$²,½@ÎçžÀ89Ã?jH<|ø°Öýó¤þj›n‚I‚"qýúõ]Œٕ¦ñfèâ˜<ÖäçÊyýzÙäԨ!‘…!ñA*•±y$3œFxjƒ&º»»g¤¦Å.Ƈˆ(ãy	SÜW%Ü݄'Ož1:#P@F¨´:tè
ÌG›€83³I²cðCkît{ï=RŒó$÷o֛gMMڸq#ÜÝüuǰxWÇΝ;8¦ (Di$ëðsq‡ñ„yês½åy‰ߔŸAeãÿ££GþmΜ9õÒo	?mU‚¼ rÔàŽ\|¬ßEHR÷Œy­­­m‰ú-PBäîD"Ø_+ø:úðµ·ä¥}0kï4(JD<üjLoÌZ½zuüöç¯r݄&wK¯°èñ=&E‹¥› d ìñwxæŸA6½ ’éò|@¾&x™†?ÇöF,soI'¶ˆQä)VsªŒ*OŸEŽLÇg-PÌßи”ñE·HPÀϱ0<Ð8#ÉD†Î\\Ǫê‹{˜›¨‰ˆÓðtðkl,M^LݶIEND®B`‚‰PNG


IHDR@@`¹UkIDATx^íÙ1
À @Qϑ;{fk·‚J—çŸÏ!SR¹7j²µü–æß^@ïD-ÏÖ+
©œ Ä°RÿÕʌ5<ˆk€Ö€“
ÀÃ3ü"ç IEND®B`‚‰PNG


IHDR@@`¹UIDATx^íØ=K#QÅñ£Nތ/‰F#ɺA
[‰,ø)¶Y_š-+a]A?ÓÊZY[Ùm/"kgc¹½{ðž…Á3NFb3ó´üȝ¹pï<ïH) ¤€@ gÀFl‰}‘7€Èr†þ~Á
!â¶Íý¤€fd6] !’ ã:›È" c  óYî·\Ç9#$€yn
;ç:÷[(AB@ç‹wÛÌóÁ	™H@†Ð1HøóE#€Êßìú<eŒ"	Èq«ìœ'ÜìAtþÔªGž,ñ0•çVÕñ9
@çá5L 	(p«öŽ$@绀9”^(aÎ4Á:o€ú«uÐè¼æ_
˜7€ @ä4Á:o€*!pHL–4 y,`%
bFPâÖB"ìÁ"o€øƒ‚D>1@ôoŸ|¢	"ß7‚?¿nw,ßÂív÷l
¿۶|ÿ<¬ó¬SQ¼Þ#ô
pò¸ÞC‘ud1Š©«ý§Gú–z¼ÚÇËYxš‡žПüÅ!š]@E”QGëüèeBȟ¡ÅbÙÿ‡Á,Ÿá­–?;Æ2kþý*è¾FN`Ñ6B€
|Æ:Öô`[,½œo³4âÅíž(¡öÁø„U´±,¦Un­±¥ò5Öì¿P€´°€æÅ4¸ÑŠãÎÿüÎsœ& Åø4*(‰©p£–TÞNCAHö> ó„doD:oEHôN¨óЄÞ2hB/™4¡—‘$_±?͘ÿõ]ç
 	Kþ¤ŒõqêO¼%7€&4±xyà:±>Ï;—XDSç
 	U̢þû[œ
n×1‹ªÎ@Æ1‰
Êq®hˆ­`ã:oeM(1ʉqIî3^ðùÈNô5ӹ8×tà>ãA¬¼¾¨äĸ¨ôÛÆMHøÞx;½-O) àŸôm‹
¸tÍIEND®B`‚‰PNG


IHDR@@`¹UIDATx^íØ=K#QÅñ£Nތ/‰F#ɺA
[‰,ø)¶Y_š-+a]A?ÓÊZY[Ùm/"kgc¹½{ðž…Á3NFb3ó´üȝ¹pï<ïH) ¤€@ gÀFl‰}‘7€Èr†þ~Á
!â¶Íý¤€fd6] !’ ã:›È" c  óYî·\Ç9#$€yn
;ç:÷[(AB@ç‹wÛÌóÁ	™H@†Ð1HøóE#€Êßìú<eŒ"	Èq«ìœ'ÜìAtþÔªGž,ñ0•çVÕñ9
@çá5L 	(p«öŽ$@绀9”^(aÎ4Á:o€ú«uÐè¼æ_
˜7€ @ä4Á:o€*!pHL–4 y,`%
bFPâÖB"ìÁ"o€øƒ‚D>1@ôoŸ|¢	"ß7‚?¿nw,ßÂív÷l
¿۶|ÿ<¬ó¬SQ¼Þ#ô
pò¸ÞC‘ud1Š©«ý§Gú–z¼ÚÇËYxš‡žПüÅ!š]@E”QGëüèeBȟ¡ÅbÙÿ‡Á,Ÿá­–?;Æ2kþý*è¾FN`Ñ6B€
|Æ:Öô`[,½œo³4âÅíž(¡öÁø„U´±,¦Un­±¥ò5Öì¿P€´°€æÅ4¸ÑŠãÎÿüÎsœ& Åø4*(‰©p£–TÞNCAHö> ó„doD:oEHôN¨óЄÞ2hB/™4¡—‘$_±?͘ÿõ]ç
 	Kþ¤ŒõqêO¼%7€&4±xyà:±>Ï;—XDSç
 	U̢þû[œ
n×1‹ªÎ@Æ1‰
Êq®hˆ­`ã:oeM(1ʉqIî3^ðùÈNô5ӹ8×tà>ãA¬¼¾¨äĸ¨ôÛÆMHøÞx;½-O) àŸôm‹
¸tÍIEND®B`‚‰PNG


IHDR@@`¹U/IDATx^í×}¨–gÇñÏußÏ9í8§ÕY´E؆•Ô2FÖ‡ 7Xåp•4
Lƒة
涃­|	k‹¶^d:ÉQQsj­li#–8¦é*Šƒ
ÜÆÈô¨Íóò¼ÜW0.¸á¹9p{Eõ½ÿ8ÿë{ý~×Û¢/™ÿuÔ €ˆˆz"¢¡Q2AQúb
‰Ðk!r
óÝéQû=á»>ª_.Yz NAɽËcæ­´ßr£:âÌ/ 7àá|î—ý٘ӆ½—Ak5dB3*æÿ6W-s·…Ì5èqWð1/×0ó	dšJÐo³ÍÑÌxAf”UhÉf>T‚*äò™O€0å éd˜é
 ügÞábÄÿòëøÿH'D "ãÅÈ5ô™-ˆFE…Ò+áâ¼Óç]k³Ï]žÑ!ˆñâlÑwµyfiÆf\ï:owRGˆuo›¾õցÛm˜ç6i+D¢ĺA@ĩo¸RÉ
6ðVïp‹%æih:f§uþ©PÔJ 
–	.·HÇgeSP(™K|ÜÀ|¯ÃÙþã'ô>-DQ¬
¨¾þ\ã’cÂf÷«뻆Í>
xÉGì[â:Oië¤2J
d•=Ýg•–.̿à³æ_bȰµô[`¶÷Ã[,s·5ë“ËdB%}ŸÏÙ0Û}V
ØhµÍo´Ër“j2 (Éàk.÷ÚiÈ?t@„Œrþ[;×o­%²†+lóÓç²ØáA‹Yê	säBw駇›å¸V	ë|’«¬×Š~õ¸ÜNKÝì€å¼ÙJ}2j}²L	y‹tq¯·ºTÉ"²Å*Ý,ð
а>¨!„ª@î$Ïé¦ß6¯VåJݠ$x“6êæU^	2™ê.s›¨›×zÐô)ž‚crUø‰gvZ§Êr7š¯÷E«<		Õ
¢¨Ðt›3wڣÊ×]âü¹É7¼À8ˆÝm-Ϻ«SÜdD7op«ވ2êo
Q2Êùkkš´×ý'|ØÝ\¯79Á!E)PM`҄	[ìø‹µ]X~ûuJ2(´^VóU‡öZãÂòsÖÑQ¨&2hš0á¬Û=ÿM[]8F=ɈçËá«	D…–IãƼ`±!G\(~¡Ã~mmE5 *¤Œ;jݘ
†Gaö”	”E¤Æí°ﰟêÆý’ž–ª	¤í˜RøßÖ;ìvŽ=šÒ`jRaÒG‡ýQïl‡_k§§™Š
?恨GZvqÆﵧH ZCڒM?ó÷­á¤ÞØg”aIUՕ ­éœG^r_Ô?‚Ýݰ*PUh™ôCg¿FMŸ¦휶_;)Ԑ΄–S¶¶>ö²N±۸V*@½bRhÚêìý^4]]eõJh:åûcáK¦ǨÇxÎÓZI¡¶@,ׁ8¾5œæü'x\3
º婨tÎúè3EÓù³‰Âö4ÿ(Ö¨¾“v;'¿q˜½Ži¥[°¶@õ~\ïøºðQ}Z5µªýC£¦@®á¤[⦡yCΓß9(-@ÎW©„Læ¯>eµ«u‰F¬5©YYµb© xÖé7>j¤—ž¹šÚ
‘úÕGŠô·O.ԩ/ݩ-qºi.I )—êP¤s¤•æoÚ©†BG&j&ŠôïI€Hú7!}uˆé›bpøu=cP¶®„,IEND®B`‚‰PNG


IHDR@@`¹U¯IDATx^íÙkŒ”WÇñïÜﳷ™aöÊˊ°[V¶ ´KƒTӆvA[nj(	ZkS_5!ƘTIÖl”¨$
	¶oššµ-
ÛµA75¥7ʂ\Êì2?ÉÉÉ83q	'ÏDßx~¯çùæ9×çyÐÿ8Èæÿ|”R¡tÏď¹byûOû“
A˜9ʮBa"D"DÃÐm~‚„4yé+„	Àç
°×黸ëÏNü¹ðúø®Ó÷DZˆ)¦|„¸¤És#\"Üyñ!¢=\xSUmbäø‚†0% Dœ´$iòÔF‚ @x¤¯p@’.j·6k…úµRßÕIIÅk#÷µ„)Rd,yòýÍXÂü„ˆ]’Æõ¤b¢,aí–4ùÁc9C˜ JyIz¶Šp‡€0ɟöêU	訤SO‘$Œ*@ŒZ%	G‚í€iòc/JCB1­Ós҃–ð5I—_¦ž¨éØ)´€;Át!u´­VñŠ~ 1Éf™,–ôñ12$ÝÐaÎÛiòÌ>H¦¼µoòcÙ{°TÒø;L#EÿԀéàNð"A–Î6JÿxcÇ«/¾'ýÍÈm’Æ^¢™´	à3øžfºön`Ñ××^;#×!”Ш¤7¾íp'Ø{ÐH³»Ÿ”þ¨;
_”tíݖ9]àN°3!E–Žc;¤J
¡z½*iòÊsщ„'‚Ÿf2_="=jøYýURáüÎ/3‡;
nŸ]Κ'ÎJͰGÒÕ÷¶¬aÓɘßûÁàBPi5ÐMÉooKúþFæ3“i¤1ÿßà@°3Ìzú®É
ݬe¶¹ý1‚ø®»£4ЮŠ¶óKöö‡LyN„ÒUê;cÒ+ڦï骤׿I+vø
`qšö?$*PZ/ü¼]€p¸AâdÞÞ.í³à^I׏“'åPM؂%T~·N:lk%]>èá8|Ðt÷œÉKҰ´^§$<ëàB(kÚ<U¼!Û.éžKŽ$!G€;A`ÏEtý葏ö_9wøðg, ƒ&â„ð9Ü	²;"M´ÓÍ|ú襇äíè
p'ØÝ E†V:™ÅL:ÈSoþ¿p¸üø	%IYrdi"MÜò^	b$H’$N”-ïðF°§6ö™Ðàa,Øøñ™®ï„êæàààa›ªˆÀ;¡ö€Ïëö;_°ǯË>ÜáÜc„kxZÒ@a›¤ó“u²Š{XÎÝ&,e1ý, ›²¤ˆ¨	àIIÒóe€¤.Hڳ‡ûXÊBúX`3ŸyÌa&­djø†ŠR±¨	µ”vJ:sŽåô2›L·頝VòdÌúª`«)ÿ«_~ðOiG K7oå™MôÐNŽ&Ki Žq"5„_5å_Úźá_Kg.#ì—ôþQ撧ޱ²D‰²åñؤ¢¤W‡YɚàúËÒãe€û%nÎê³çÝ@Eü&>O€
š”thˆ%pk–ŽTLÆ’Žý‚6Òñ‰ê+ázSþ­aòÉ[égÅO$-)#l—4~Ùdˆâ¯)àSþè.ú覓étó)Vü»´¯b2^’´wÍ$	Ö
Ð!I’Þù¹)ßF–,­ô°|ø'EÝPsaHÒÙ:i Œ¿†é/»¹˔o"E’F:éO|á\¡z2U,#N €Ú$it7lù$"$Éó	V¼vH:]1+iôک#„Ï>d“>ÜÍ\ºly3HÒÈ,–<¸u\•“qƒ¤ÂõL7Dð{ø‰&;ö3³¤¶”Êûð$E+½¬<qZú“øu¿~£›’¤—7“%FÀ+ L‚údŽidi ‰ÙLJݓ¡›e;‡'$­ҷ4jJß,~8úãít“« H„iÒv-·å>BÔÓÁ]Í_<Smã7\´•ø4]d¼|&j×òÊoFâä˜˲߿V4;áðÞèYÍ2æÑF½÷1à+=P	T53#¤éômÜôæ+ŸfkYý,fö”'@å׾êH’£‹…|†ûøŸe1ó颕F¶ünûä?™ô˜³O3i!Cš˜}üªn5ø#M†<­4“£‘ÔÔÅk(}Y$Išdå™ç¿ 4HKÀà_̃J°%‹zÙIEND®B`‚‰PNG


IHDR@@`¹U¯IDATxÚíÙO(aðofͲF«´‹vKmÂJV{P\”)·­-®›h/ړr -i
má⢵’¶³»‹“‹¨­ÍC}m߈e>'ù¦çú]æ2Ãw& ŽJQ3õB8™Á…1(ðæCá¤^ÐL¥(öûÎü ¦ÚI
ø¢㮻Ï9Ì;3CSc†Ÿ¼ÁÇÊnæ"f9è¼(Ÿ"æfÎÊÂó‹û—\%±à*͞`ÓhƒfÏ	G(¨ksÇXA*t õ5g<îºF)¸ÁdÁÓãñöÒè“
Pšyle1FyAØ>8í¯Œ @€ @€ ðïštÛïú4ȸG‡x|¸‹EôÊÔvïð8~Že¤P)÷٘þÌcýåj‹ˆK+­àAÇãTûXh¿yZG	´ Ê€(.ùÜnÁ„/ù=ø`|¬-¥T·ýûhjX“PÝ~]^OÂ
þè„ÜòúU½×O¿¨ïOÕ{öúóúþ
X#îg¨’æ¾IEND®B`‚‰PNG


IHDR@@`¹UUIDATx^½Ù_OiðV†°X” ¬„?Ò&¥½©-AaC‚÷
ßGoֽÞMŒÊzµ›¸üù<«1¡ÔbVw³êPµØÚÙ3=ÉäP§OÂ;¡s2!¡'y~í̼s&ó֧ðò»–~ìÞ/õTð·¯׀>	€×ø¥ñ+<£¯w÷0ôå¡/ۗ‡‚GŽ?ˆáÊ#߯Kù~å†1¨€KüŃÇAüºT@8xŒ‹Jp¸ÇCŠâx<%¸xüOÇxKxbÇx­µ®„øÏ	ñ<žñ”àpˆ§‰w"¸l¼l?û‹å…ï›Ï ƒÀ<>ºfC,ßm;Ü0àñÍZ¥X)îuP:(5;ÍãàÿÚô6k>ÿ,€û{ø\ƲԒÔ2V°zô¡pô«X	{–?—}ÿ>9,€Æßõs
¸‰䑓}·¾¾ï|}[XÔé¼rz:’¡6 úJ¢3HaNö򑀼éÈU_‚°øÁ,~8ì³ÈÖÞujï5€€Å+਄”D_B—q©H@J>¹,—„:*)€,ÀÆn„ñ0‡q‰ÿ^öq$#IÓ1g„ oúýè/`;€@ãÐjÔß6ޜüTãMýmë¤Ð:éèh(€@ãà¸*ÀÖ]%üè±7+}*².„€]:<pBø”ƒa®¥„ʆá)¡ª˜¯g„!I;=Üi>>EžÚÇ“ÿü®„Þ|ÿÿ$¤Êy.ÿ©„ó?	÷7‘z0$rÅm%œïe¸·ƒ’’¨‡@OBŒbJT…ÝC0€æqõ?[QÑéŽæ±˜øÝ–´Q=	ÃËc˜FBˆXŠ+¯ÛãƏX–}·#’ۦcµòÚlü‚¤ÌHZx†®`Æ,àÓ~{Ü( /û
,EÎK¸¡ÁÈòi_‘ñWìBÿ[¶%èD$ÑY7í6Øˆx¼™A’ö¸qã²_ë:\ÓéÌê@Âã
€bގ×H¼Bœ„Æ[%ÜsÉîküvt¼P‚>˜T_Ö^ԟ7þª?¯½¨¾l5:­Æé}0aßÞ¡¸çѬ¸Eâ
€ò{›àYNjö6‘'ñÀó¸^Ú
΅µ³ó$ÞaiBàñiL“x`„1!Ì#_ܦ;ûê±Ïc^ðc®ç]Æ.<ˆOàñ“Àã''¬Ÿ!þGwðÚx||8aÆÇp‰w8h||'ôN¹»…‰	à÷ˆ\ùYùr§×ü½¶Ã¦DZ*‰)„k~_\b˜”šÀh¬—p~u‹F¤äÕmüâ/¯1(åaÀ=þ¡Öъ7qØIEND®B`‚‰PNG


IHDR@@`¹U¦IDATx^íٻoUÆáßîìeÆãY|Yvm᯽+ãKDbPšHHD‚††(¨nґŽ*eþ7(E¢@J4q$
‰IlCjß3Gc>Ér2sr¤¡Ùy¥mßGs9óÍYÔÿœ> èú€“N#8
QŠQƒ£¢€5  «ËTq£x™âR¥L)FX¤~£sô@ìeÜõ¹ÇƀAª”ì|µåýM¥î(_‘!âS¦h4€æõK»[BÈ¥F{e<êŒ1uíòζRMê¸8öOC•€aÚÌ\½òô/!¤ڄx¶9CŒò
½Õ!¤&,)„¿…@uF™bî³÷„@4h2ýñÛÿü©ÔOª‘#@nƑϗŸþ!õù*7æwïK}ޗ;9»wOês¿	oužU_°P8ŽN¯?øýôúwÕÊa€6¿ÿ&ãú]%¥) 7Žlt(ãÄ…yýNL\¥ŽÞ폦õ?ßúð£'…`бøðÑúž²Öÿò
¹øÉ²:šªFMø~þ˜^ÿŽ®ÿõkγÄ"ç>}?&¬+ßààRc$¬Ç×r3!88Iý½çÕÿöKt™æ,^[]I†€ã1ÀO· J%Sý&i2N‹3ô‚Á<ààÒÒâÿß-ܜÍP?M‹a2&ó‚) ­J_ž¿1¿w?SýKx¸PGÏW¯ìh-c€ö·v7²Õ'÷##3×.ïm+Å8
Ül€	Ą;`^/_251ÁÔõKû[ŒP3d¾ †£¹¶L¨yE€Lë
Â(å`^/„*~—J4XÖ#ßÒT¨ÈËÍ`Sr7!yÁc5‰NZ½ ’€=àÇxiz²ºB—I†	RëŎ5@–¦í/ޢIEÈ «ãæÚ2C¸8ráàѷKÈȒ#@·djÊ ™šò˜ìæ{@[™z‚–õÀàR§©”9án79V€"UjzߣÇ9.ðæ3óF”¼Î"]ÎÐ$ħ‚=€2>!/3Å=æRÒc–³L2–[@úӄQš´™xnÚQZŒ3BH€›º$¥d„ð©Q'̔5ñ¨àØ4RŒ0،×ÛñRo°ÿCú€>à_#:„¤¡E€{IEND®B`‚‰PNG


IHDR@@`¹U¦IDATx^íٻoUÆáßîìeÆãY|Yvm᯽+ãKDbPšHHD‚††(¨nґŽ*eþ7(E¢@J4q$
‰IlCjß3Gc>Ér2sr¤¡Ùy¥mßGs9óÍYÔÿœ> èú€“N#8
QŠQƒ£¢€5  «ËTq£x™âR¥L)FX¤~£sô@ìeÜõ¹ÇƀAª”ì|µåýM¥î(_‘!âS¦h4€æõK»[BÈ¥F{e<êŒ1uíòζRMê¸8öOC•€aÚÌ\½òô/!¤ڄx¶9CŒò
½Õ!¤&,)„¿…@uF™bî³÷„@4h2ýñÛÿü©ÔOª‘#@nƑϗŸþ!õù*7æwïK}ޗ;9»wOês¿	oužU_°P8ŽN¯?øýôúwÕÊa€6¿ÿ&ãú]%¥) 7Žlt(ãÄ…yýNL\¥ŽÞ폦õ?ßúð£'…`бøðÑúž²Öÿò
¹øÉ²:šªFMø~þ˜^ÿŽ®ÿõkγÄ"ç>}?&¬+ßààRc$¬Ç×r3!88Iý½çÕÿöKt™æ,^[]I†€ã1ÀO· J%Sý&i2N‹3ô‚Á<ààÒÒâÿß-ܜÍP?M‹a2&ó‚) ­J_ž¿1¿w?SýKx¸PGÏW¯ìh-c€ö·v7²Õ'÷##3×.ïm+Å8
Ül€	Ą;`^/_251ÁÔõKû[ŒP3d¾ †£¹¶L¨yE€Lë
Â(å`^/„*~—J4XÖ#ßÒT¨ÈËÍ`Sr7!yÁc5‰NZ½ ’€=àÇxiz²ºB—I†	RëŎ5@–¦í/ޢIEÈ «ãæÚ2C¸8ráàѷKÈȒ#@·djÊ ™šò˜ìæ{@[™z‚–õÀàR§©”9án79V€"UjzߣÇ9.ðæ3óF”¼Î"]ÎÐ$ħ‚=€2>!/3Å=æRÒc–³L2–[@úӄQš´™xnÚQZŒ3BH€›º$¥d„ð©Q'̔5ñ¨àØ4RŒ0،×ÛñRo°ÿCú€>à_#:„¤¡E€{IEND®B`‚‰PNG


IHDR@@`¹UçIDATx^í×OKbQ‡ñ§n×?WM¼é YŠŽX)%ô6š†þ¬Zͬ„i‚æ5ML+׽Þ@Ä³i´¬œë„ýˆ{8Œýnjõ|…¿CoÄ{3ý>´‰`“ƒ©Ÿ‘§B` âS¸ûû¸L)ÄLàà»ÿÜ{ê=ÝÃÅv:ÁûsäûŸ§߇xD‚]€Î'îŽûùÁú„»#Á*@çoOT^ù„Ûc` ç‚]€œ	–r^&XÈy™` äß'ØÈy™p¢	ƃ¼@0ä%‚@ÊLBޔ`0ËËÿ!rޜ Î
âêWøðjòG}YÇ'K8@D=c€ž:Y"aQRä(Q§É:›l±M›vÙ{À»ìж͛¬ӤN‰)¢8&€,Eª,²Ä
Í`-Öؠ-Úl°F‹¦Ú
K,R¥HÖàâ1M–<Eæ)QV¡FƒU°JƒÊj%æ)’'Ë4®ÿ£x¤H“ÁŒ*4@ƒ
røzҤðˆ†ÿ#T\¢Ĉë%ñ)P5
ø$‰£GŒ¨>ÛCÝŠ æ G„$9* BŽ$œWÓO7¡CŸ²(ãǑŽÒÑƀ1`ƀ1`ô_Ç#>HBŸd¶Îò‡OŠþ(µó0ù{ˆ‡kx–ߜö	=v¡ò7§ú,7{˜\}yVƒüËóõӇÉ$Ì0G½ÛQƒ|·C9fHè§Y¸Ç)iòTY¾:“	rþêŒeªäIëÇiøç9>Eh]ž1yN‹Šø&Ïs™`œ7¸‚QÞäKÐùŸ߇óf™*æ™"o
Eóæ€9o ÞÉ[È9o ļ}À0¡ÙÿŽxyþ��·&Ìò‘F·ÓíÐà#³BÞ:@Ȑ§D5X‰<!o
§	i²|–%'çÕDÀ?ã@ÜeÈլIEND®B`‚‰PNG


IHDR@@`¹UçIDATx^í×OKbQ‡ñ§n×?WM¼é YŠŽX)%ô6š†þ¬Zͬ„i‚æ5ML+׽Þ@Ä³i´¬œë„ýˆ{8Œýnjõ|…¿CoÄ{3ý>´‰`“ƒ©Ÿ‘§B` âS¸ûû¸L)ÄLàà»ÿÜ{ê=ÝÃÅv:ÁûsäûŸ§߇xD‚]€Î'îŽûùÁú„»#Á*@çoOT^ù„Ûc` ç‚]€œ	–r^&XÈy™` äß'ØÈy™p¢	ƃ¼@0ä%‚@ÊLBޔ`0ËËÿ!rޜ Î
âêWøðjòG}YÇ'K8@D=c€ž:Y"aQRä(Q§É:›l±M›vÙ{À»ìж͛¬ӤN‰)¢8&€,Eª,²Ä
Í`-Öؠ-Úl°F‹¦Ú
K,R¥HÖàâ1M–<Eæ)QV¡FƒU°JƒÊj%æ)’'Ë4®ÿ£x¤H“ÁŒ*4@ƒ
røzҤðˆ†ÿ#T\¢Ĉë%ñ)P5
ø$‰£GŒ¨>ÛCÝŠ æ G„$9* BŽ$œWÓO7¡CŸ²(ãǑŽÒÑƀ1`ƀ1`ô_Ç#>HBŸd¶Îò‡OŠþ(µó0ù{ˆ‡kx–ߜö	=v¡ò7§ú,7{˜\}yVƒüËóõӇÉ$Ì0G½ÛQƒ|·C9fHè§Y¸Ç)iòTY¾:“	rþêŒeªäIëÇiøç9>Eh]ž1yN‹Šø&Ïs™`œ7¸‚QÞäKÐùŸ߇óf™*æ™"o
Eóæ€9o ÞÉ[È9o ļ}À0¡ÙÿŽxyþ��·&Ìò‘F·ÓíÐà#³BÞ:@Ȑ§D5X‰<!o
§	i²|–%'çÕDÀ?ã@ÜeÈլIEND®B`‚‰PNG


IHDR@@`¹U¯IDATx^íÙMoUÅáŸ=ö¼db'ÅÉ;Â-qjË4IEP6HH ñ"6l€+D°ƒ+–|‚nUbÔê¦^ƒT$+¢M[Ú5͛“áf®¬¿°p|ÇS
çìsžѵæ'Dÿs&€	`˜=9•¼Š• y•œ
‰€Q€¸¼@Ï(®ŠC1fäÒt½*ÿßÙn
!
 €ÃtRÀÑN·ƒK1= OŸà€Aü¨«‡w¯nàcc¥8”©*€qýÁýÏ^ ԀôG`á2K¨†õ{}ò2
˜ţHz50¬ÿè5V©3G	G - ®õ»®\¦ÍST™‘çÏ`RŸ0²þƒ7èР*§™‚èGøûÏw_b…
SRŸ@»|¼ɼ|ø2aÿ÷ÏÏSÂÎ ©Ąƒ߾<‡—É䆮53øúэè•!„ÞhB®Ÿ1råìAyóði=Z¤¾·7!.·(n7o÷'KB€ÝT˜Gß~ç§kI	ýys«u|;Šp±±¤~÷Á{o±ÅÖÏߤÞëvŽvâ*i 1@êß“¬³ÁÅ_¾6%ôë¿?tG¯&¦q̺^_9ÏÐä,+´Øøõ+#‚…¥ë{êé»0OËtH}›3,±HÈ2M֌6S××zwOêõÄd‘J@<7ô…Ë3T˜c‰•Ó?Äõv,Qún½_,à™–tý‡¯ë¹Á,S¸x”x„p îˆ/.êz?¢¨™\*,žLMµõVen`éÁþo«Cûۇ÷¤>) Ìüá=µtÔeíèWŠ9¡_/ê&€|\¨²ÀÜÀØÊ¤>1 Ÿu R¡$õˆ õ‰ºÀÆÅWñp¤>)qúòÀƖËL	隐—oü1+!=™Â:•ÐdCÝBH’„á„s,Ӻr¹÷(Šnd
€<<*„Ÿ¾¸w_¿t³È1¸Ì\Ý<”—nF™Sßnôv¤>#€¬ëkRŸ!@֎Ôg¬¿)õê³X8ݎžšIB-%@žÿVKêÍCÈ,.騸„œ¡Å:Ïr‰çTžšK\ Mƒ*eòi–°À2g9G›Έ´Y¥Sø
Ã"G€K‰€yY¢¦R?55Bªúk	ré6Ӕ©e–2¾ž7i2Y\ó?èÇå½®RÒÿCc ûLÀ?YrtÉÄ>ĊIEND®B`‚‰PNG


IHDR@@`¹U¯IDATx^íÙMoUÅáŸ=ö¼db'ÅÉ;Â-qjË4IEP6HH ñ"6l€+D°ƒ+–|‚nUbÔê¦^ƒT$+¢M[Ú5͛“áf®¬¿°p|ÇS
çìsžѵæ'Dÿs&€	`˜=9•¼Š• y•œ
‰€Q€¸¼@Ï(®ŠC1fäÒt½*ÿßÙn
!
 €ÃtRÀÑN·ƒK1= OŸà€Aü¨«‡w¯nàcc¥8”©*€qýÁýÏ^ ԀôG`á2K¨†õ{}ò2
˜ţHz50¬ÿè5V©3G	G - ®õ»®\¦ÍST™‘çÏ`RŸ0²þƒ7èР*§™‚èGøûÏw_b…
SRŸ@»|¼ɼ|ø2aÿ÷ÏÏSÂÎ ©Ąƒ߾<‡—É䆮53øúэè•!„ÞhB®Ÿ1råìAyóði=Z¤¾·7!.·(n7o÷'KB€ÝT˜Gß~ç§kI	ýys«u|;Šp±±¤~÷Á{o±ÅÖÏߤÞëvŽvâ*i 1@êß“¬³ÁÅ_¾6%ôë¿?tG¯&¦q̺^_9ÏÐä,+´Øøõ+#‚…¥ë{êé»0OËtH}›3,±HÈ2M֌6S××zwOêõÄd‘J@<7ô…Ë3T˜c‰•Ó?Äõv,Qún½_,à™–tý‡¯ë¹Á,S¸x”x„p îˆ/.êz?¢¨™\*,žLMµõVen`éÁþo«Cûۇ÷¤>) Ìüá=µtÔeíèWŠ9¡_/ê&€|\¨²ÀÜÀØÊ¤>1 Ÿu R¡$õˆ õ‰ºÀÆÅWñp¤>)qúòÀƖËL	隐—oü1+!=™Â:•ÐdCÝBH’„á„s,Ӻr¹÷(Šnd
€<<*„Ÿ¾¸w_¿t³È1¸Ì\Ý<”—nF™Sßnôv¤>#€¬ëkRŸ!@֎Ôg¬¿)õê³X8ݎžšIB-%@žÿVKêÍCÈ,.騸„œ¡Å:Ïr‰çTžšK\ Mƒ*eòi–°À2g9G›Έ´Y¥Sø
Ã"G€K‰€yY¢¦R?55Bªúk	ré6Ӕ©e–2¾ž7i2Y\ó?èÇå½®RÒÿCc ûLÀ?YrtÉÄ>ĊIEND®B`‚‰PNG


IHDR@@ªiqÞ
IDATx^í[}LTÙßÁ)3ÀÈÇ2"ˆbT]Ñ-®µKYݏV³‹ÛݦJMëvuÝøUi¬¦MMì¶ÑhHmq7Q0.d5²Y?𢬶Dc4l¢È"à–ongrîd¼yÌ#½™¼IړüÂË}çžÇù½wι_óœâjÃÿ	b±1BLÀzã¿،0“ºR>|œž؁o)ÀÁ÷ì¬2®ÿWQP™ž000'
ú3ª%f޳ӵµµ3Ÿ>}úûÁÁÁó###mp¤tt´ghh¨	mŸѽ˗/ϖdø!”€É6چ?~ü\‡ú°k êÿà¸xñâ¬þþþ“ô¿s&]êÃDØL	ð>—F»»»W¡-5"ASTçå[»wïÞr¼å'220 ¾*ýX4ä­Ÿ/*_„>'ªg${ÚZËJ=:$èó”ú’
¶%_œ9Ü!ˆôe¶µµu
Ú"ŒHÐcçÃAúNòm•âlò4=¿ ¶ŠrÁ2B6ȖB‚)`"àV?¯æææuF$hìø’ßÒҲÎó"‡‡ōß¨ŽŠs³RÅç¹oŽ~¾ì-ºVï{úP_²A¶$	2ü0³j/XöìÙã—@Wd腕——§Ñ', ¾ÎWÿÞðžø¦¹Y¨Bmt¯B!A†Ceeå²-s‚¤$
\’÷ ټB@ZO–©oVÜýðˆ½¯ÚÚھ@ÒûZ¶=8W-N…{õɆԭ ۀC†‚ÏÓ|$	2ïD?~<lS2«Jˆå7oLÂððpÿþýûGVqqñúúúR{çùϼ}ªâcdb>zôè<_s’ôH0ûQíí퐖’b¯ÃÿzïWânÑߞ%áH‘—„C‡mGß×òòòV€„nj§pº÷Š	²MÏðý
̘®H×ÎI*Ÿê?äòOßñ:Ðóå—Ô4&	õ>|x3ú/<qâÄ鶴÷î]¯Þåw"HÈ6=ƒŸe× @“ãÏßÄaT×! ŸNLxj<‹)	EEE8ÎW1z�s3SHÇc‹„lÓ3—-ôI`8ù	È؞€­´yµÙY‚¤§§§b~<_Âýû÷멡vÉbN%ÀÕ`ž!“¡>ú$Hœ@4(	øÄù,„]ٷoßÎñÐÛÛÛ懀D~–S}Tb€©˜Ô<êÔéτ%7|ދ8°Ì	5È6=ˆÑ @‡s=zT;V¤Gٞ²¾	=Íͣj$ۚè“`·nÝú³Z©¤‘`Àӹjժw ÷
HØê‡Ã2H¶uB  $¨Ip÷îÝo VGԁ7’„.kw"<xpÛ$<;ê��m$Ô2¤"‹* 4½•ÑðöAÍ9!…J]GGG=ªC‹a‰d
²I¶uÊ`@HPBDú֭[³ãßȍ‚ÿýd}IÈÙ$Û:¡€ …¹NϨ®®þ­œ7~°‰bpu¨[šMð\«÷7½ï“-²I¶u†#ÀÛÝ@†õ½?É‘Öò“ã^‘3@êK6ÈÛt«“!
´HÈWHñ“d`nYYٯ=¼$FՁʚ\#Ð5µÑ=ґŸ}oiié²v&›L‡uÐ'agò£9Rȁüüü\¬êԌB„‰P!]êÃΧ°­h“MôI°û®1LB20xiíڵo_¹råpgggF†]pvˆ@×ÔF÷6lØð.érŸd¶£.‰YD€9	IB4‡C'±9À<`ð2Aàë|oë&qßh“EQ
OBÇm,‡Ät®å3ù
§1fs[*ë$pŸH“eqü×ÁíQìT;˜Le$r[é°n„º1(¢M@àIðÝã°p‘1Œhns±Ž²5ÆÎ[C€~‰ÔÙXô	°’›þö¸>֓ !V`=	Ö`=	ÁO€þʒÆ!¬'!ø	X²d‰Ð>Ÿ LhlAEöæÛm6›¸yó¦Ð>©òK
… #   @dffêlڴI<|øp8**jÚr€7€EÀ+>È~Èœù>“›IÀDeNo=۶mR°a¨ãr¹h]^CÐöcvô% U0HãIN2÷ÝAG-[¯SŒBhRL™2ÅP{ùr…¶›ßü÷€ïß!²$ÓØñxv>R™ÚZKÀƍ½Î;vì(Ne}Mº{÷î5ÔOMM¥½;víڵm/°“r÷¼bxv7QNt‚"	®_¿Þëü©S§þжŸ~L
X¡¡¡†$œ9sF ¬]CÛ, ÞgúfƒÉNˆ¥eKSÒyqá…B´e¹v»}å“'O†¨[X†dggˍʑ”””t&`¢¬ï~ Lx,"`õêմâ*Hêêêò’T&gô\´}AúW¯^³$޾}[\¿~ýC^Ј”ãu‘àʕ+½Î744rŸØ¼¾téÒ÷ñvIFF†!	›7o$ØÇÄIÐ-7+ƒ–€å˗{¿víÅ|:×ço“_ȹsçNogYqþX”””äór–°I‚…ÊIccãé<¾“‰œÕ!þ9‚60EBB‚!	ØÙœ0o2‰1r„|0nܸñ/=Kçc9¹HŸ™ñ†¬ƒf%$F1„ÎäRLøĆ`ijj"ç_Tœw†‹3úlàuW¯ã³yc–ijgÏJÛe<ˆâRg³š§ܞl5}Ä5;Õ×y¥t99lR€Œe˖mD’þJ"*Š,‰}n·{÷w!V žؘÔÕÕUä34b།açpHä!nÊ]»€Ô××{		ñŒNŸ>íJ©ªªZǹ$ŒìZM@(̢‘±ãx‹i‡…Ëw2b:n“…ûÊ䙓“#¶oßN¡$Xˆ:Êބó>›¹O\P ìÈD”±¸Ñ/Fl¿ÑüµÌCxŸA¡BcàҥKÿ\°`ÁFè-~Àá嶚õW¡êƃÉo†&0Iqœ3ÖÔÔ\¤l/g(‘%8àDµ?x“t€4Î-ÑPl»1f?ESO|ÅpÞH_³fÍZl[ŸÇßš0?r/ްšÀ`'f|¿´©'¾x¸ü*/€,^cÇçòýDÎþJxYF€Œº¼ Wyø:™+Š[ÝÂf²Í$˜	à’È{ûìd¼²…ý<0QÃñ &7’¨[Ú.“U "@jŒ·®­$à?
“!<…R/IEND®B`‚‰PNG


IHDR@@`¹UIDATx^͘]h\E†Ÿ™³®Ò4ÊV1±^ÑÛ*‚ЪP(±6±*j+¶õ"*("*5â•B(
‰š´MŒJJj„–ñÂ"B£ բV±Á"Es‘ìž=û¿ã0v؅p‡3Îs±WËûð~ó±ÃJ…_$xå$ ÐXÄp	bi–YêEb\’@"Ó,>D
‰LFA6Å\FpåÄ|úÓ($Ü@@
®>x¡×*$' 	H\¿ÿ|"
­—P’€ sÔ*$y	€×Z‰Ä
$« ¡E
SÐJ²
ü*Hð« o‚¿
ü*Hð« o‚¿
ü*Hð« á?+ôY…$¬»ç¼%øUàWA‚_	~$øUàWA‚_	~$øUàWA‚s…^«à@ÀÁ{uÀÔ%ÙFჃ>ì9ÉY–8úÿ…ù-Hg#xžC¬…Å0ðÏq¸[Ü%ÖǬkE·¸MÜ*n"sÍ4ÂÑžå-àì™dŽU‰È’ӄä‰(R¢J
ål
û¥ê=,‡˜	àñÍDäȲh!KHD‰25êv±¡>š;•b7öS熍.3„¦ÛB¡тjSàIFêäЦéO>…¤!æ7Ž!/߳…
%Š,fe*¦…jCà	FœÚp˜Â³ÙsM»0tn[)©Q¥BÙB¥ßÎcÁ7ûîœ$Òf§ {Nð©åGî:NÕ,ªnhgÛ8@Àé‘;&ˆÈk¢þ™êBÝ-˸bGü4wû*ÞÊ$ߍ®#oˆ(ü”ýýHó2Ž“eY÷Ìj# \	(€	øþ@×ÛD†E4ÃSªÖCÆ.#ï붓"@8}§øq|õp#¼¤)SšûûË4OcÏ>Wõ¼r­é	€¢pn|ÕÞÆFW¨*”¿8;š–ñ⊧±´' 45øs|å›Dq|™ªY)£ðð×ᯙ¦e<d¶ߔvрÒè ùý7ØøxŸëÓY)Ø›oä3‚^ƏÖ#4¨QYñ2E
qù:^郊*»¦«ÝÜËsüÌq6AåâÌÇ=]_¹ÙêxŠñìu<@£ƒò¹¹£pŒAn¦pqöžû3/ný¥ÁÍtÍoÛÑz”FÞW5Ôü驗®{àö±£Å÷¤n$Œ@ÇLùÐ: Jƒ̾þê掝}Çs‹ä‰âa)
(ê1ª5^c†@aÍäg	ɚøxU©·'Ъ P€ˆß@¡&o/«ýŽÅå³Üޑ"òDM¿üX#P3-”æªÚð$b\Ó(C[ç_¤[ ™w/–HIEND®B`‚‰PNG


IHDR@@`¹UçIDATx^í×OKbQ‡ñ§n×?WM¼é YŠŽX)%ô6š†þ¬Zͬ„i‚æ5ML+׽Þ@Ä³i´¬œë„ýˆ{8Œýnjõ|…¿CoÄ{3ý>´‰`“ƒ©Ÿ‘§B` âS¸ûû¸L)ÄLàà»ÿÜ{ê=ÝÃÅv:ÁûsäûŸ§߇xD‚]€Î'îŽûùÁú„»#Á*@çoOT^ù„Ûc` ç‚]€œ	–r^&XÈy™` äß'ØÈy™p¢	ƃ¼@0ä%‚@ÊLBޔ`0ËËÿ!rޜ Î
âêWøðjòG}YÇ'K8@D=c€ž:Y"aQRä(Q§É:›l±M›vÙ{À»ìж͛¬ӤN‰)¢8&€,Eª,²Ä
Í`-Öؠ-Úl°F‹¦Ú
K,R¥HÖàâ1M–<Eæ)QV¡FƒU°JƒÊj%æ)’'Ë4®ÿ£x¤H“ÁŒ*4@ƒ
røzҤðˆ†ÿ#T\¢Ĉë%ñ)P5
ø$‰£GŒ¨>ÛCÝŠ æ G„$9* BŽ$œWÓO7¡CŸ²(ãǑŽÒÑƀ1`ƀ1`ô_Ç#>HBŸd¶Îò‡OŠþ(µó0ù{ˆ‡kx–ߜö	=v¡ò7§ú,7{˜\}yVƒüËóõӇÉ$Ì0G½ÛQƒ|·C9fHè§Y¸Ç)iòTY¾:“	rþêŒeªäIëÇiøç9>Eh]ž1yN‹Šø&Ïs™`œ7¸‚QÞäKÐùŸ߇óf™*æ™"o
Eóæ€9o ÞÉ[È9o ļ}À0¡ÙÿŽxyþ��·&Ìò‘F·ÓíÐà#³BÞ:@Ȑ§D5X‰<!o
§	i²|–%'çÕDÀ?ã@ÜeÈլIEND®B`‚‰PNG


IHDR@@`¹U¯IDATx^íÙMoUÅáŸ=ö¼db'ÅÉ;Â-qjË4IEP6HH ñ"6l€+D°ƒ+–|‚nUbÔê¦^ƒT$+¢M[Ú5͛“áf®¬¿°p|ÇS
çìsžѵæ'Dÿs&€	`˜=9•¼Š• y•œ
‰€Q€¸¼@Ï(®ŠC1fäÒt½*ÿßÙn
!
 €ÃtRÀÑN·ƒK1= OŸà€Aü¨«‡w¯nàcc¥8”©*€qýÁýÏ^ ԀôG`á2K¨†õ{}ò2
˜ţHz50¬ÿè5V©3G	G - ®õ»®\¦ÍST™‘çÏ`RŸ0²þƒ7èР*§™‚èGøûÏw_b…
SRŸ@»|¼ɼ|ø2aÿ÷ÏÏSÂÎ ©Ąƒ߾<‡—É䆮53øúэè•!„ÞhB®Ÿ1råìAyóði=Z¤¾·7!.·(n7o÷'KB€ÝT˜Gß~ç§kI	ýys«u|;Šp±±¤~÷Á{o±ÅÖÏߤÞëvŽvâ*i 1@êß“¬³ÁÅ_¾6%ôë¿?tG¯&¦q̺^_9ÏÐä,+´Øøõ+#‚…¥ë{êé»0OËtH}›3,±HÈ2M֌6S××zwOêõÄd‘J@<7ô…Ë3T˜c‰•Ó?Äõv,Qún½_,à™–tý‡¯ë¹Á,S¸x”x„p îˆ/.êz?¢¨™\*,žLMµõVen`éÁþo«Cûۇ÷¤>) Ìüá=µtÔeíèWŠ9¡_/ê&€|\¨²ÀÜÀØÊ¤>1 Ÿu R¡$õˆ õ‰ºÀÆÅWñp¤>)qúòÀƖËL	隐—oü1+!=™Â:•ÐdCÝBH’„á„s,Ӻr¹÷(Šnd
€<<*„Ÿ¾¸w_¿t³È1¸Ì\Ý<”—nF™Sßnôv¤>#€¬ëkRŸ!@֎Ôg¬¿)õê³X8ݎžšIB-%@žÿVKêÍCÈ,.騸„œ¡Å:Ïr‰çTžšK\ Mƒ*eòi–°À2g9G›Έ´Y¥Sø
Ã"G€K‰€yY¢¦R?55Bªúk	ré6Ӕ©e–2¾ž7i2Y\ó?èÇå½®RÒÿCc ûLÀ?YrtÉÄ>ĊIEND®B`‚‰PNG


IHDR@@`¹UçIDATx^í×OKbQ‡ñ§n×?WM¼é YŠŽX)%ô6š†þ¬Zͬ„i‚æ5ML+׽Þ@Ä³i´¬œë„ýˆ{8Œýnjõ|…¿CoÄ{3ý>´‰`“ƒ©Ÿ‘§B` âS¸ûû¸L)ÄLàà»ÿÜ{ê=ÝÃÅv:ÁûsäûŸ§߇xD‚]€Î'îŽûùÁú„»#Á*@çoOT^ù„Ûc` ç‚]€œ	–r^&XÈy™` äß'ØÈy™p¢	ƃ¼@0ä%‚@ÊLBޔ`0ËËÿ!rޜ Î
âêWøðjòG}YÇ'K8@D=c€ž:Y"aQRä(Q§É:›l±M›vÙ{À»ìж͛¬ӤN‰)¢8&€,Eª,²Ä
Í`-Öؠ-Úl°F‹¦Ú
K,R¥HÖàâ1M–<Eæ)QV¡FƒU°JƒÊj%æ)’'Ë4®ÿ£x¤H“ÁŒ*4@ƒ
røzҤðˆ†ÿ#T\¢Ĉë%ñ)P5
ø$‰£GŒ¨>ÛCÝŠ æ G„$9* BŽ$œWÓO7¡CŸ²(ãǑŽÒÑƀ1`ƀ1`ô_Ç#>HBŸd¶Îò‡OŠþ(µó0ù{ˆ‡kx–ߜö	=v¡ò7§ú,7{˜\}yVƒüËóõӇÉ$Ì0G½ÛQƒ|·C9fHè§Y¸Ç)iòTY¾:“	rþêŒeªäIëÇiøç9>Eh]ž1yN‹Šø&Ïs™`œ7¸‚QÞäKÐùŸ߇óf™*æ™"o
Eóæ€9o ÞÉ[È9o ļ}À0¡ÙÿŽxyþ��·&Ìò‘F·ÓíÐà#³BÞ:@Ȑ§D5X‰<!o
§	i²|–%'çÕDÀ?ã@ÜeÈլIEND®B`‚‰PNG


IHDR@@`¹U¦IDATx^íٻoUÆáßîìeÆãY|Yvm᯽+ãKDbPšHHD‚††(¨nґŽ*eþ7(E¢@J4q$
‰IlCjß3Gc>Ér2sr¤¡Ùy¥mßGs9óÍYÔÿœ> èú€“N#8
QŠQƒ£¢€5  «ËTq£x™âR¥L)FX¤~£sô@ìeÜõ¹ÇƀAª”ì|µåýM¥î(_‘!âS¦h4€æõK»[BÈ¥F{e<êŒ1uíòζRMê¸8öOC•€aÚÌ\½òô/!¤ڄx¶9CŒò
½Õ!¤&,)„¿…@uF™bî³÷„@4h2ýñÛÿü©ÔOª‘#@nƑϗŸþ!õù*7æwïK}ޗ;9»wOês¿	oužU_°P8ŽN¯?øýôúwÕÊa€6¿ÿ&ãú]%¥) 7Žlt(ãÄ…yýNL\¥ŽÞ폦õ?ßúð£'…`бøðÑúž²Öÿò
¹øÉ²:šªFMø~þ˜^ÿŽ®ÿõkγÄ"ç>}?&¬+ßààRc$¬Ç×r3!88Iý½çÕÿöKt™æ,^[]I†€ã1ÀO· J%Sý&i2N‹3ô‚Á<ààÒÒâÿß-ܜÍP?M‹a2&ó‚) ­J_ž¿1¿w?SýKx¸PGÏW¯ìh-c€ö·v7²Õ'÷##3×.ïm+Å8
Ül€	Ą;`^/_251ÁÔõKû[ŒP3d¾ †£¹¶L¨yE€Lë
Â(å`^/„*~—J4XÖ#ßÒT¨ÈËÍ`Sr7!yÁc5‰NZ½ ’€=àÇxiz²ºB—I†	RëŎ5@–¦í/ޢIEÈ «ãæÚ2C¸8ráàѷKÈȒ#@·djÊ ™šò˜ìæ{@[™z‚–õÀàR§©”9án79V€"UjzߣÇ9.ðæ3óF”¼Î"]ÎÐ$ħ‚=€2>!/3Å=æRÒc–³L2–[@úӄQš´™xnÚQZŒ3BH€›º$¥d„ð©Q'̔5ñ¨àØ4RŒ0،×ÛñRo°ÿCú€>à_#:„¤¡E€{IEND®B`‚‰PNG


IHDR@@`¹UIDATx^íØ=K#QÅñ£Nތ/‰F#ɺA
[‰,ø)¶Y_š-+a]A?ÓÊZY[Ùm/"kgc¹½{ðž…Á3NFb3ó´üȝ¹pï<ïH) ¤€@ gÀFl‰}‘7€Èr†þ~Á
!â¶Íý¤€fd6] !’ ã:›È" c  óYî·\Ç9#$€yn
;ç:÷[(AB@ç‹wÛÌóÁ	™H@†Ð1HøóE#€Êßìú<eŒ"	Èq«ìœ'ÜìAtþÔªGž,ñ0•çVÕñ9
@çá5L 	(p«öŽ$@绀9”^(aÎ4Á:o€ú«uÐè¼æ_
˜7€ @ä4Á:o€*!pHL–4 y,`%
bFPâÖB"ìÁ"o€øƒ‚D>1@ôoŸ|¢	"ß7‚?¿nw,ßÂív÷l
¿۶|ÿ<¬ó¬SQ¼Þ#ô
pò¸ÞC‘ud1Š©«ý§Gú–z¼ÚÇËYxš‡žПüÅ!š]@E”QGëüèeBȟ¡ÅbÙÿ‡Á,Ÿá­–?;Æ2kþý*è¾FN`Ñ6B€
|Æ:Öô`[,½œo³4âÅíž(¡öÁø„U´±,¦Un­±¥ò5Öì¿P€´°€æÅ4¸ÑŠãÎÿüÎsœ& Åø4*(‰©p£–TÞNCAHö> ó„doD:oEHôN¨óЄÞ2hB/™4¡—‘$_±?͘ÿõ]ç
 	Kþ¤ŒõqêO¼%7€&4±xyà:±>Ï;—XDSç
 	U̢þû[œ
n×1‹ªÎ@Æ1‰
Êq®hˆ­`ã:oeM(1ʉqIî3^ðùÈNô5ӹ8×tà>ãA¬¼¾¨äĸ¨ôÛÆMHøÞx;½-O) àŸôm‹
¸tÍIEND®B`‚‰PNG


IHDR@@`¹UµIDATx^í×?KëPð“hZ‚AÔBÄ"-Xÿ€‚[)]A\•Î*‚SÕAÁAo/¢xë¥Eºu·ˆ(*.íæÐIQ:8´¶tsRMNkèÈi‡—gz§óã$yÎ	CƒÓ€ @§Nån8@ç©NÔ‰¦à³!ùíØ|1¹`ͥ¼BjƴE¦f­9u @€„¾ñۑcý› ·XZ…G:gþð¥~V7
µb
ÁüÝ:àä&2Tô­µØožZ1
-㚶ɓÙéëèî%˜Š¶çxÂ1hº#—â¹D$kRày
}€­`öøþ3ˆïˆï€\ª½Ñû«ÓR
	÷RN¦ÏÇ^k„áehÌ4x
çŸÒØG»Øq5ñoë–rÁ4ª= ¿W’ˆc!ø ¸Ö
|aÛ7µpšpóð
)"/p8ñl7AÖ9!«b+™3þœÓpPèa('ùièÜ¡…nD¿@ç%)`G·†+bΪôwL€ ð
¨R.aQ–IEND®B`‚‰PNG


IHDR@@`¹U¶IDATx^íÙkp\uÇñ'÷ͽͥMLڦ÷@[Zjah‹€ãTñ‚0ÅQGp†‹8¨3T±
Î`gÐñE•¡‚µÙ={kÒdJQK	¥”n’†Ü6ÙK6»¹oö|=ýÏéxv§MO¢‚/Øß$³çÕó9ÿ˳ç"|Èù|ø b¥œã“e$[%çlÔQ–‘ù|ìÌÒ9’'ùR Ž{¼V׶êϵâ0R y’«(Yÿ€Y:WòëÛâOûSý`f2ùÎÄÑ;4ˆC1ì!ìÌ3ϓ‚_/ùqªT˜ LQ0Ã̔³{‡J¾
„}€*nœùgˢê1€nžf
d™Ê".å.ö1	ÀôëooU#‘£àÿ)À<wGۥÉcÛÈFΙ
î'ŒýâÚrÉ7WÄ<Öò…]7ë£pŠë¤„Ý$ɖ=uR`NÅ|fù¢¾ÛHÂó” ¶r5=Àôñ½ËÅa%ؤ•ïØÉìBì‡:ځ©<Tkæ°¾û2=#sL5§€±}R*j9ΐ+ŽË+§ކ½HF
¹‰çéBÆ9Â#lÊ$°ŠÐû=)–|sìÔùçKéÀ.8Eq ‡Û€Ìð*gnRÃϬ–"ɓì¹Ôì?А!cåWâ 9šèŠ
¶ŽÐg`Š;2ûÈsRfNƒm@–äH”õÿ´Œ™}HMÇN[[†šU†šƒ‡B¯OܟXŽ>þø)6ÇÀ6 WŠJ«¦߇miƒï’cá#¡æðp?ì{U|Æ÷ƒC-ñºΗÒ¯=»¤Ü{5ÿeþÐE–p:ûð‘ÈhoØu‡Ü
FÈñD|¨y´BTZ7“ǤRŠ$×&@M@¡,ì
ž²”/&Œ¼9ó&´¸+êr)CÆ÷˜6â��qxÌ(`ôGÖI©Ú6yR,ՉVØa|HÆϔÕƜ‰¦HSŸ	ès…㸖pGý±cП6n߷ÉqHŽ=€ڀR“Â2àE`¬#êKåǚ¢MýÎNMèÔúѦ„3nŒBğš„Ë-€§€îݖI°(òO.‡‰´39
¿1썻M±f­ݣ´{:´ AŠ;‡ÝßÄÜk|úƒT«`ЅßßCˆ%)t¢þ¨;êLjöŽvè<iì¯Éb)µ	PK°âgW@·
èzØrÍÔ½‰÷tžµ¾DR#ejÚܼbˆ%㤈
i³zÝAOütŠG2oè/R«ú¡m@¥£AŸÖ)²þNŠᣃî>­C{ËsØçly¹Mx¹ÍÙrØwÌp÷¸û½ã¡·Zïÿf®€
Y:~Š´߸'I1ÚsÐí:î>âsµìkUöµºZŽøÞötiÆø§f¦YdìÞܥ¶§Àa–÷ÝÀt’Épó«Ïթµ»[ý®fÀÕÜêowwj½ZÐ=˜GX~÷e©1[‘Í]°@êŽ<¯ –¸I1Ö5ÚN¿3 ½éiõ+­þ7=­×èŒі©dŠ/X@r¤j­,’û۰@ʤöŽ­úÌ$À&0'ƞ6Üÿîw°)⌻§â)ö§¡ú^•åR%ŪÙlÅ%†xeäPæÏë×ÐÑõ©“	§ê„ÚqO»÷¸§SësEœ£þä°N‹-€BBÀ¿!K¤B
%Ç. WФR–½ômf\ÿ€ =vöj]ZÀm,=-ä{wf¬Iß$NÈZ˰CªV4ƎÁn$-Ÿ#ŒN’‰ёÞPGðdøôHx2•Dg?iØzbwÉ
sØd›“°bϭz*ÉU„
%È4“Œ3Æ8“LqÏg@sp~Ù 
Reù%°yET(¥^Oüz¨G2’ËV¾Ë<ϸ•%ç¼=сèÑ!çå‹͋²,û¥ùR"ղ|ÁÆÈðÕȜs—"$^ڰÐr—dë²<W­ƒÉêk®Nà$+lr¸Æ$|Š›¸`ìÅM,÷Š6ÙêºÈèˆÒxãö‘w Æ-¶õ¸йÇÚJ&ÁޝQŽ9
Kå¢ÍW÷zö³aV@!÷©b s­
Â,“P ¥a™4ÊfÏÓqÐy/â8 ‘Ÿ0@w[ð(ìDf%Ød«•P¦Fa­l¼áúš™˜ÀËnîf'7ñMb/ {÷¹ʶ.܉ÌJ˜N(•*©“•²N6_á_FOè:df:ÞyàWw˕r…\yl/Ĺ꜄„…0ÀJ(bY(5²LÖÈzÙ,—úúßß߶çä+§µ_—«ýÏÏûVé'd‹l’
²^.)»ìý$äH¶ÍgDj9I™TI­X%e6-r™ÊµQÖÉZY!
s…4–Ü!ëÂë8”K¥,–:Udµ¬1J6«e¥,—%o‘TY|fÍ„¿Ÿ0úBU©ä+‚
ÀÙqÈ3ER*Fµ©‘Z•U¸BʤÄ@«±Zb¶œžeúï=۞mҟ•ŠÃ`23¥ªp¡ÁËSqH©"4žðU`ú””«Û5»a2T¡|#ê¿ùœ؈š.³,=!›ðÀ*Qc``…˜3æ±ùQÄÂÀÃëԕ²
€íØ%l’ƒ…õêÁÅÜó'ÜBÙl§xïi©›`þ„¿Œ Ҷôbu¿8Àü	jSÊ&ïccÝCGŸ]t‰4HõÜáü	õ²úLÿÌö¯“ͲNVJ­چ¹sنó'”H…Q°Á@4ÊE¥Á8Z(EçnDöcŸ¯Úx•ÔH‘©6ŽŠfiÅÿåd©6îPMºÜH™Á9ûNE>€X߶©X^m}0³‰gôNÉ|Èù\"·ÏÚçc‚IEND®B`‚‰PNG


IHDR@@`¹UŠIDATx^í˜{pTÕÀç޻Ù]!<"
µ"iÇ vÂCªíŠSe:V
íT°
Å)´#µvZ§¶±P_VßÀ(
°J ¢ƒ”È#˜˜çnvï=_»×3sf§!܌Íø¿oÎÎ=»™|¿ùÎs®¾X¾`¾øRÀ#DØ^>(Óì ¶u±`S+T.nIŒ+,MnÒÁ]#’€2ᔻëGöŸåuN!DÚýý]©
ÛVO:B€Q¡Ë(éhlÑ]œ彯¹¹èûÎBҴ’¢Aæõ#^K€t.`ŠîLJ<1§÷|UyŽשæ##ڃaŒäR&²o}0ïœwŒÈçP(\Ü7Ï:ÿ/޹°–{X¦#úpó~ãýS—¬M ¹ø&½Wsåà?«Â}ÌáU:§ˆEÌţ}ÓÊko>Ne(¤Ã}&Õ~oÈãªð¯|ã¤顅ÛË!âßøê£ñ̊‰„Óqúý߸ïn®£…hlä"v;{Ú3w”…®
Øâ¯ýú©Ëp±˜®PËXöQðͅÍZçúî=ƬTE±„|’\ÍԠÚx‹ÅTO“h¤Çw݄g"GüðܲŸV,.7°„2ò—XÀ,0'џ>pÁOjÉ »2	Ãò/(í+ÌÉK_Êk,§¿µå@ýŽ£ێ¾Y·­aOêˆWðO~ˆžbNïëo³S1jñvʂµLÀҏCg›kÒÇ­ƒvœXѐD˜ϽXÎa¤–VÜQKÆÔ zzô½îÁâòÃðÛvdÆü\ij¹È=9éæš÷#K¹
Ën^F%§_¥VÀT॑±AX‡e6•èlã»*åŸ	¸AØÂ'/hÿ¸õ€b¥XVý¦˜‰H4³ù­„ç²h٧RŸ¥ô¦¤ùÍ}™‡e5)â×áâD¯€ƒƒ×óBX‡e
}ñ›ý:7Léh/puÌ47×rߴÖÀ
6íluùEÑÌ釛8va¹h¯S:""M†&×Ï}ëAƒn?…ó±ìJ‡íB¢p.IzÒÄr>B¦^Á­Ì~aPˆ µB2
‰²Q¼…ä ›>¢Ày½ ÁRŽà·!¥8!Ÿ¬	ڄAXê§¢	¨\HB
‹ƒƒ_èX2€S€2!ςí-PŒEӆV*ÐY%"Â'XzAчÔ-’íëAöPSHú_odðÉ*­°î¸Zy…ð>–¯©º®ž†’ÖéC±üˆ—ŠrpÅ!÷iÃôEá8nIÀkXÎê Q+ €4}<c$;0ð$·/‹ ݕ˜…'ŽòH–»îFŽaT¿‹ M@>¸uÀäKyo³žK¼¢ÓÚöHy(î߉Ä`ÅﰜÉéøMsw£‘0"V@£W¼qÞݓÜ>Ôc`.ÛHTMكŽP‚A”£µ£ÜøÏ[ÃX®Žm8ž1+ Ñ:ò˭}FßdWª™ɣ$‡Å¿ÆՎ`(IÄF¸=kù–$³€MÏâ£ÑHÔI(hüuÀ<а<Îmˆ*š¸À)QÿÅ!J9ž7$1Êëý!ã8ŠåGô¥eﴭø¡BÄ!ŒÀԍŸîpî"nÇòöò¥%ÎEÒ*
’&«ª§ÓV1z,å,ÖüÞ\È4D_>Y2U÷Îzt®ó"›°¼ÂPneý
U!a3¿æE,ಂbŽl¸z£)?]!È	ÜüÎûxTQŽêYÈ@.æîã,a:ƒcÒ[F1ˆ»ïðüS]Ì&õVìàQ@’¢޽ö?Üç¼jÆQGW™Í&c˳£fT§0ó ʝPÐá ´Úvռ–ýÃÙÄiDÅå[ü‘±\Ãš(š²õ¡ŠDçw‚|Ðá ¤Io¨›>«齡lçZ¢PÎjÖñcÖó43™&zLݼ¼"iN" ‚ ɒ!MÛóWΪ]WL¯0œÎHrï2ÅýŒÇÀæˆ
D”²(@m¯+ÿéë׌™=¹ç$^a«I“œÉṳ?ppK<9 ¢?ä)¬¢×Ô͌ž±#h@:°ËÑ(2®jâºßÞøµ+/_Nš-¼ÍG4¥œÉh3GßÿÛʙÿ¨YÅЩÂIDh|̲Ä_shÍÒËVÜ5ùì	½‡UªJòÉ6ڼæåÙÛTS-üŠj6u °‘1¡ 1tþ†ÄÁ
e<Œ
ð*Knqک¥eñ"×ó³-õÇþ½õ½¥{›3øN¯øîŃ&639OFçhy&Tðt´wD*§JÄÂÃÃ%<ødÑ.Ņտˆ  ‘“½¨eR„»#^..*Aç"Ѐ‹ß(ÃﬖA“V1¹ÁØ™q\òç‚lj0&qM8v9Yóï\¤‘á‹vªÁO 0m×ցː<“Ö\Áa³¿	\ Q¸k')Ìà)úÎa%A”
äK€6¥Ç4ÄFT…j¤c…gh¤øŒý–&@¢TÀJ€tø¶<ÿS0t¨`Vw,Ž‹ˆ,ÐAŽÐ8ø)Œ£ÿØ}¨ˆ¬0“§*y¨©J	yxЭ
ÁàoW±‡" ~Ëø‡îÈW¤Q†ÜùÆÎ¯ïõUH×í}ú²eÇÚÌ˅|n«‚ ÇVñ섒B÷ù㴓¦ŒYV ÛÄ\pb¯µ¡ðɆ
ÙV@ý¿Ì5ÂÒgÈ⣻³VAa®ú¸˜ç0Ìu½»@Ðf̺7}éÎU€Mg¿!%|±üiÞå2ÞàIEND®B`‚‰PNG


IHDR@@`¹U¬IDATx^ÅÖkŒ]U‡ñßÞ{n½*†ÖRK¸¶É(ŠB‚Z41‚EDÃ-š)Xl´ÔÄÐhhE¹©$Rä¢I¥ÃU ´8,:#ˆM[¦Îíœ9ÊÎJV89ΜÂó~›ù°žõß��¼·•zyïHÆSo‘†zc­TTîžD*•ÉԅJ¥IyŸ'¾’$É×ät7ù«G­q¡÷çI’¼K3ä'ÊÌö¤Û-t‚c}ÑÕÚ|L®™ÐçL^I¢oðÍ_Öj›/ZRJ¦»ÃԼY¨4ɒ¼-µ
ÄN×;ØW,v²÷©Ïkžžìnóì¯Ña®KÎã`ghÔàp,բY½LP¨E „íPwÛâN7ø“nK4ht<-‘³áS´J‡[üÄ*mtj.‘HjÇ?b~s²܍–ØoŠ•–j2é"̂ƒüÚés’nu•“¤G¹ә²Ê
¤UܿÞ
^â~ä|×yÆþ\f–)ʘÇ9~žç|Ç9.ñ ¿iLüØdY­	dšœxˆ•Àá–ÑèT™J4q•'8‹išeÒZHe¦k˜+™ÍR•
#Â0C&­5>¥ÿŠp„ŒٕطÌlÕIkA=m
"Ma–LEÊGc+l—„ªa%ºúuŠp$¦©ÈTèפy%a'T)PBIID˜R‘ýD ›^ýêòª—ɂJùñFtð¬GAմ `+¯™æ{÷²
~fN˜‡¤zv#’jZðª“Ýç‚ú¹Ok˜ë›Ö;[]XLÒ*Žѫ§Ýp¹€j聙É~`›n;ýÒä?w´Lú΂@Qç€v‘}ÌD5	tƒÅ.·/&Yìœ+ü>T“@Q1ŒaUì[ž‰œG©«2A{…1¬:&Í"{ X@T(ê4²¡ffõ"OÀfáû±Úvùw»A‘9Õ¡Oˆ°ž©vˆS0dS
	ôàZ)zVXr•’PPŠï€
"8@eö٦٦ƒ.½y®H+|ÿ¥a]†—2ØT>†sªxݘêH‘V%žɏ/)‘Vøøœ­Å>oŠ:™  K1&ßpJ¼-`’k_Þ)QžRÒ»TƒÜæ«\ï]¾eª:)Júü«ÀH‹{}X„&m–JG€u[¯¨ˆ߾GxÔ‡¦W¸ٹg¸ÆF'
:ڌF£ÃD »l^ÑÅ&»Cb™©֘u©N߷ȯ¼d¡t¶Õîq´L¢“õÆÆIî5_d-ü]1(A
!þ3¶ÀJ
€™nñ¬OóYkÝìp/Ðfl|Î)¦”<'€44 SçD¾-GkµڜÔ|��ÆÈµôj+O@˜þ©œÄiÚÝæÐÔG˜n<¬÷OT#Hœ©¼ª©›ýÞ\4þ+ÄûÇ$ROs£ʐùªv§÷1b]8>¶¥¼îòÆծ´wSÔNvÚl	R”PR´ÓE¥í˝§`âáxØpܐ‚EÃڜ£çf_²ûÝX§· Ø#

Øâë6=hž×M,ƒZyÅKqŁ!ýöxÝùÖmtœ.ÉZ}<V~R ä
;]êÎnŸÔjâ¸'4 L€( ~ý†úìr•ëw”N´ÆÄ0â~vy2”'Š!…=¹Äo,:ËM&‚G¼Î:‚å”â(æ}ta±÷|?4~~‰ǗD…8}öxÊbÛ.·Ìø°†ùŽ’@xŽoSèÓe‘׮u™ñp—^Ò–*D‰¢áð"öØb±­+ýVí\«
+„U@hİPB·e†–ԼšZ=ÇÏ+(Ž> ¾‰\!ž·j‡‹ÔÆÕp«áÞY >ˠàÿ\ícçq÷ÓéaCq«7Cފ]¾kp‘vccÈp­¡8Õ
ˆÈ:­Øíþc,,×ÎCž4h(¨V |9õû£Û^ñ/«–_ø)[­0(4€1	ÄG®q×Ǻ݀Ñ)h·Ѕ¼éboÄû5ð¶½p¥ë·
Í$ɨU¯٭ôX¤݀ÁøÆ,‡1,¦UÎrŸç½8jmö˜•ÎÐaO.î_‹@P“Ý6»Â-ÎÞk-°ÀR·ۡO¿Ãñ#¤0	QaWÕ՗ß?ÎÍQa (ôêõæ(Õk—ÝùýÃñ㈿á{Áîü€JþÂŽǏO@ü^0h ¯þJþ7X¾ý*ó?ÄP°R)ªŽÔIEND®B`‚‰PNG


IHDR@@`¹U@IDATx^íÙáTWÇñϹ3˲%ÄPjڠ­ZM)ñE«DŨ¤Mc‚ÚVcKB¢B"ÆB@Û465Òؔhզ‘j©¡"”Ä,‘•‚e»ؚ¡A
ڄ¢‰$twggî_ô$—L®Ûvˆ/ä{þ€ç{~Ï3çœÜ	Ñÿ–Ìÿ»À%KU‚7%€ˆ 
€€ˆ”„àüE¡51Fã#´ۂT>S5Ϸm3h—
–š¢GU÷[î?òcûºëTeBH ¤|EÕýî*T}Þ7Ýá ,S@ôCkäò Ʈ¤ò·[5ÇZ1Ӱ#~ê'sâ+,›k¥w™b²3þfm8¶Ân»ÐQA4ŽPµøo£ß|0Õ
n0պ™îf/)¸Ú”ÉDQS±|6ÈÞ43¸V·À{Ép=¼Ódð¨ýN:唃÷!i6:H	x•c­ÖLÒÂ[ ÏMv[Òû¾¹ÓçN»bÚä÷ø‚gÜ*)t>™ÌëäÚ$sï¤êF‹U@n§ÏVF¾£¹<±ý™N˜áÊOúœ
 â&72Ë;ôêѣª"“	ã%¤¥}¦ñ6Зû´…úüÅ{54EQlh)š%ßéSÂz׀Zâwîô9ˆYkÇUT]ë>Ûüڃ®W´Or®ù¸jÜÈGms™ŠYë̛å	Üm‘…–ù­{Tµ0Û|嘤»Ê$Ÿð¬[˜o‰™P¤C×ûÜ6'{Ô+NÙäªÌR7káJ´Ã­ôˆ;ÌÖ
SÌT=7«ªB•¢¼ë¯ôÝëzÁíú˜ýJXd‘a0Ï<˕ñVWÃU
¹fÈTL÷D¥o³o)*^n“ªr¸L»×T„¬è¾e޾ÆgÀu–›8Ó¼‡dÅ¥þûŠV¸Ï4á‹vø•‚à%€*¤¦2³4¾&­@!@îøÆÊTü™§•±Ln1ìOsNS2@Àfq•3Zá
ïÖ-ž“s@žcYñ ô’M¯”NA·€!¹¦fjA*Ÿkxȑ-s1ÙIÝ>¹¼H€(×P÷ºÕÎ}Í‹WᠳRdһMؚã֎XìÌÅÛ?¿—§Àù-3jÄvOðU‡íð¬†4ÎP7fԨuN<iP÷9g¯yY£5¤jFµŽïê>F٣QŒ`!Ó ŽU3èø€“ºM?<“öß2JFmÍmÔ]ê¶sڋI H UAݘ~#ë5u“½Î0¨&	Ð*@ÊùÍ	Ow¿»‹òåÅïa£øîõ3ì9ñ€fjÃQ/٭[üÁIžw.(ˆElà~ÝbìTא‹å-éXn3ä𠽺AÓVFìIñ/êƬïVûœdÈYI€rPØíðƒ&ÎÏa‡zûéfð=VŠ&ƨ§8[Ö2ÆÍàyCû=iblsš]†%Æ€”šu«6~ýêmÄóŸ(Gmü»U.œã8n¿$ËÊ3PSóˆ¿n°مò}M~a,ímÄâbª9ku<·ԀÎáeñO¿,oU(W1ePqÔ]êυòÿ6¦.c»Hs “ÙçN_6KÐ)u{lUSOû׶@Œá92²RL¦}R†F$Ú­£˜^Œ´J›Zˆbh?D䈢†šªLèH ]îÅþu$Ò4Td~7ŒI!ה‹bçD4“Bgå!&‰˜Êw.€(
.Œ¢R.ýw|Ià?ñÛyÈlNªIEND®B`‚‰PNG


IHDRnàMèÌIDATx^½Ô?ha‡ñç.¹\Z5=*IEO	èRpÈ$¸Hî¦s—€8ˆ A$ÄA»8¹œ‹ƒà°—£i‘–t„þA¡)‘‚-5Rܾ^—»€Ky¸í>üÞß;¼è¿;TB&Y,rXd0à_$“Ü×ÉýÝÎÇΟö÷kä0‡{kƗ+„yښÁÆL'ÖۋAäkª‡}Þ{x#˜Œnޫ
j·Ú-/¢ýnjb¦“c눯é©é©ý~Me­í1Ž5„´®BUm<ÕTѬvµVæ¤ŒS½9WÈqeõ{8dÓÖÏQ|sÓªËׯúîF5â7Èc$ÈPÀÝYvä¨÷ãɭÍO]!W¿)I&y&î6¢ª„_MÈ×óKØI²Œqvg¹.¢ê
DH¾æ(f21æܾê+Ð7m¯Ì?íu*B]q+™Äû,.!WšL¾¼Ó
â+H&6¥WµªPsðå™/Ghõ'I#ñœwKŽˆó´òˆv:1ÈS¼~ùý\sÐЬVó÷9ÃXê.ñœ#LpŽ”ÃÎã2Ž9Œdaĉ°"…Jbdba“ˑòó'wÓ_0Õ1IEND®B`‚‰PNG


IHDRnàMè¯IDATx^½”±
Ä 'b+ÁFHHH•ÿÿ­Üáä<8²S¬#Êõ3/*O‘‰@$‘À$ºJ ]÷#J$_æb
™8¢$Š”BSª”úWE•Œ™&¥1“|=_éCãê=+uðõ\¥ªç”/‹IÑb,lìÆib'»±±øÅ‰L¡UÊJ£…¬ãÿùíۗâëQFÕS¥ž"T»š®â2ˆW˜ç%øOlÛ?£IEND®B`‚‰PNG


IHDRnàMè7IDATx^ÍԿNÂPÆáßi-mBø7t²3š0‘8Td—I.Êè.wá¬wÀÄ̘ô˜àˉ_
QâÆûNïð§=9ȿ{¹äaÎì2ÁÃÿ¼ÅwŒÛÞ1Q.‡;K„ïˆO´³Ë!¡¢"
棕¡Aő

‘ÜÎGŠŠ(Èm*"ÄDŽDÄ"©Ø\À°y*|“M¢¢M:"”@	 §¡„Á"uà·:´H	0`ßÓM6>Cîe“}Ü:B<›¬ò:‰«|6!v„€:ÉËô€DÐç¦hŸ8ðüHBãŽO‹î‰Ð#áºhBOd¼OSº´ÜñAP´¶§ymŽ(šM¶YùWn³×JµßÆå³ßmJU©•¯%5ª
„ãxø\ácÜ6n{üsf_îsñЫ֞ܗÈIEND®B`‚‰PNG


IHDRnàMè°IDATx^Ó=kQÅñÿÎÍÞ\–I6«.³;!
‰ ˆÄBÐÂFŒˆ…J¢À^°HÀ/ ~-ì´VÔÆJßA|©YÈë›=rafôœb`¸?žæBЊ¶ÍAà6Wp$ÒÂá	¦GÁa2þy‰i‹GP%Ϝ´;þxÅ"Àӓ0•èáúÒù
Y$e"!#	C	‹J’EIò’ädHL±è¦ôéjDÿžRGûžFbQ—¡*!³¤†^¯1à(˜.ºÌ"=¼!U´5~yƒCò¢=Β:Š“ºtjw̒ƒBÌîñîÅcØX²®§t\û£ìg8Å1晡Ý@"Øú>Þ=,ôB¯î°HNŸ9B9EE)ïغ¶¿]¾öùÉ=¡Uí¼g@ZlŸ@¤½¯«+œ¼»ökâ5¥zv‘Pþ©u2͡ý/·Îr„œ¥ћ›B=&%i"mf7NЧKJöüö=Ôޟߏ˜Å5‡§C ñÂÒæÛw÷¯Ÿcž´™´Hp$ñIàqEºøæÅl”:˜ïÑHʉί‘¿¦–»˜±Ó³IEND®B`‚‰PNG


IHDRÄé…cíIDATx^µ–ßKSaÇ;g¹årþH›#‘5”˜Њ.’„¢AWA8ªm×"ô/¨àE‘nº궼½±›åüA,ñκ´å<ÝÄùô|áåeÙ9ǣÑ^Þ¼Ÿó<Ï;Ø"²…³=£ýSJäÅƙN§¯¬®®Þň¹XWþI¡25ÙlöV¹\Noh4÷mŽ0òü3ֱϨ§‘‚L&Ñ˺žœŒSËP55b$̱>??[ˆ”ÓHL]©TÊ$&_âr@ŒëØÇ9œ—‚„sbb"”ÿ•G†¬cçpގD©BeÜSSSÑt.
D؟™™yĒZ‰|=µÌæ¦HÿFÔN&###a|”•D‚O¡PˆÚÛÛqè§Ïç#¿ßOºYOâ_ÐÎÎδYe¢0.æ²Çã¡ÃÃC<M‚ãææ&õõõÑVq‹Œ^—¶§퍏?fA‹AOd‰ xȼjhhµŽD"tpp@š¦Qoo/­¬¬à‹i][G0R¡Pø:::ú„—L^—ìÁûÎÎNŠF£T-FV´¿¿OÉd’ÖÖÖhyy™¸G4==M===¸è9*À4þõ;Y8™¤ë:!ÆÆÆ*t$*•
DÈ¥£T*!…ÃaHbL«¸Kþâ¥Ddq/H	úaXGéУÝÝ]ÚÞÞ&·Û]aÁu¦a(ñ3âñ8Ù
Q.d™‹âÅL‚›™nUUóKKK¶E¼a¼âáÈ0jüyñ2^Çb1ے`0ÉSæSc%Qp@»\®R.—;V°¸¸Á&ÈxÕJԪlÞ%‰c%ƒƒƒ¼eü²ÖÙdÓåp8򳳳¦‚b±H^¯¯ê¾A©Ì$27ÓÆ<c¾3dA
™‹
¨6%²7õ¢lW™Ó}„.æ`šD» 
QxÖ>Qó¶*0oã’Yœ@òÇ?æœ	¸ü¬(f’ÿÎowÏ=O*Ó@IEND®B`‚‰PNG


IHDRnàMè,IDATxcøO2)ZhT‰Z`°¨âЂ;ŒG™-ÔJü£ZQU{.Ǚ.^IEND®B`‚‰PNG


IHDRnàMè7IDATx^ÍԿNÂPÆáßi-mBø7t²3š0‘8Td—I.Êè.wá¬wÀÄ̘ô˜àˉ_
QâÆûNïð§=9ȿ{¹äaÎì2ÁÃÿ¼ÅwŒÛÞ1Q.‡;K„ïˆO´³Ë!¡¢"
棕¡Aő

‘ÜÎGŠŠ(Èm*"ÄDŽDÄ"©Ø\À°y*|“M¢¢M:"”@	 §¡„Á"uà·:´H	0`ßÓM6>Cîe“}Ü:B<›¬ò:‰«|6!v„€:ÉËô€DÐç¦hŸ8ðüHBãŽO‹î‰Ð#áºhBOd¼OSº´ÜñAP´¶§ymŽ(šM¶YùWn³×JµßÆå³ßmJU©•¯%5ª
„ãxø\ácÜ6n{üsf_îsñЫ֞ܗÈIEND®B`‚‰PNG


IHDRnàMè7IDATx^ÍԿNÂPÆáßi-mBø7t²3š0‘8Td—I.Êè.wá¬wÀÄ̘ô˜àˉ_
QâÆûNïð§=9ȿ{¹äaÎì2ÁÃÿ¼ÅwŒÛÞ1Q.‡;K„ïˆO´³Ë!¡¢"
棕¡Aő

‘ÜÎGŠŠ(Èm*"ÄDŽDÄ"©Ø\À°y*|“M¢¢M:"”@	 §¡„Á"uà·:´H	0`ßÓM6>Cîe“}Ü:B<›¬ò:‰«|6!v„€:ÉËô€DÐç¦hŸ8ðüHBãŽO‹î‰Ð#áºhBOd¼OSº´ÜñAP´¶§ymŽ(šM¶YùWn³×JµßÆå³ßmJU©•¯%5ª
„ãxø\ácÜ6n{üsf_îsñЫ֞ܗÈIEND®B`‚‰PNG


IHDRnàMè©IDATx^Ò=kQÅá߽³3³³“Ýhb–̺DbwƒQ,TÐ"Z¥QÁB,´°²³Õ*¢Xù´°Dý‚/˜€us$s1¹™Hâ9õýþhÇý?âÅ`	ÙE‹–r*ˆ%æq}¬p‡»25¢ú¬è7{¨m‡Ôéj-£b†xkbH诓>	fkÒ`°Næé`ÊÄ_+eöÉÔ¯9À4!S$†€„ÜæŒ#Çr¸_j‹—4óI@Êó£º"»ìȉœ,h¨UM‹OÜ#ÆnCÄÂ!­HZ”#÷sr#‡—ôA3bž³ANwV—´–k*晤“â<‰OêLòäœþHú¦r~©1d–Ô'cxsWÕy!޳×,
2NÙåw•ä¦X¤M¼yäM¦xpµ’ôÄEÆ}âVçxüóc	¼Kôhú#»XRº<½^"·Ä#2L‘¸æ‚/¯äç»ÚCκo‰¡Ãe¾"¿<¤KŠ­"†]æˆ+sd»‰0U,!#Œ3IF'oÆ-w_ÕÄÝtDÝkL­xü;î_øšĤðŸ8IEND®B`‚‰PNG


IHDRnàMè=IDATx^uÒMHTaÇá߽w3Î8S“:~ôadTÐ&*hZVPbµª]›¨E›ˆ‚”¤E‹Š EíŠhUHáFŠÀ̅AԴJ†­qMï¿t@/w˜ÿY¼›÷á!0–Jø«r˜XÓX˜A"00±qãÂÄB¸^áG'a?ÀÄޑøwÂ+,dfú;#Xj¥|áÓQ?ÀzÛæ¯«M®¶kH¹\L.)i`“œ=¥“º¦5iaŠ8¡ið!?:ï)7¾8JUòæHá”HZ"€‹o|r67ö@–z45LŠð*	 \Rï.
ÊÐEýÉÞ8H;@JhìX		l™{ýڠùü¹C4Áò‘r$Q›¹/IÅI6“ÀƐ Â&™}٣Mêæ^"˜"H‚(üŸ¼¸¢´²ÞÀ.ª0‚¤EHÜjÏO,ä'î²·Œ”£‘.4ÐÊZˆc‹2²FèŽV³X?B
I’ÄVVï'½z*æêÚÙÍNÚh$†‹ƒ]ºãéÕÌ÷B¾EhPo.³‰4)jq±0ðeåÆzõëÛá®ÏÏú…ºõû#õDqq°0¡œÔK³_»;ØqõøOÏQH½:€‹á»jT*„Y[ürfëIӚ{Z¨O¹§D1+›Xß6RĉR÷ú¨iv.û˜V%báP‹½„›[§?ŒÜ>±F¢•‰‰…¹üº$i^1ŽSy0,\¢ÔP½ü˭LJ-ÿ÷ ù’
¡²Æ.rÌIEND®B`‚‰PNG


IHDRnàMèjIDATxcøO2¤Š–„ÿi(0°–4 ñ“aײ
†]@ú?P1¶|‰c¨bøÇPõ%dq~‰úšÂðÿWÒÿ(R¼ŸqEZFµŒj¡<Y"ÿ÷XXâ'>‹ýbØ
Ìb»áYŒòŒLŒýý…+é
ÃÞIEND®B`‚‰PNG


IHDRnàMèEIDATx^…бŠÂ@àß.`‘ÖøÚX¨ÍmŒâ4g›W¹{G°s×Xî-ã0xó7Ëÿ\ õ	þ!"¨ëúº†Bôž0ˆϹ5֜sȘÀic¬vÚ{Ú’D‚ßÂòI"@‚ÈJฉzÂÀZׁaŒy"&´X`9,±p¢ *y2ÃüEæ˜9± vF¾€ºhïC袡0âoý¸mÿ%…{Ü~rÄD¶åÝ
#p·m‰´'
	²¦òˆVXá7Ã’¾XäåӚ]‰/Fï­u…)ÆÏõÝ5UgBÅ:ãã®3…Xº3_ŸÂ(ƒã&Œ¦tˆו®I$"P ‰8Dg{‚Ф-Û‚P‚Ô'aÀ	O…ØGy˜?$3Bç¸GIEND®B`‚‰PNG


IHDRnàMè[IDATx^ÍԱJÃPÆñrIri¡´Ғ´d©f*¨¨‹¾€uÑgPñ	tÚWp(®îâìØե«J±øjlʱÆJBCný¾õþ¸çžá"ÿ˜b °pЉÚ(Œlb>øÓGY•M…nk2ì$f¡‚sšÚé^8ê$‰‹Î{‹E™æÝÅD‚˜4ÒÄÀ|õ01Åû£ðý@µ¢°§}…3h¾ý€¶Œ¥“I,J"_Ͻ€â ÎÁûÇÍåÛkç‡ÔÓġ*ҕÉppƒ«3¶÷Ñ^šh<fh,àú˜ŸæñîdH'Mêé MV(R¦ÖmQÂJ“†s4–ÛVpPXh
بl÷ùr¾Iõ»~&F.!ZD/ÀJ$M\YÈ×SßÇÌ&6VÙ`'ê6ë¸PÙD¡©à҈ZǣJ	“yÒÄ@a£u°P1YúïâŽb"IEND®B`‚‰PNG


IHDRnàMè[IDATx^ÍԱJÃPÆñrIri¡´Ғ´d©f*¨¨‹¾€uÑgPñ	tÚWp(®îâìØե«J±øjlʱÆJBCný¾õþ¸çžá"ÿ˜b °pЉÚ(Œlb>øÓGY•M…nk2ì$f¡‚sšÚé^8ê$‰‹Î{‹E™æÝÅD‚˜4ÒÄÀ|õ01Åû£ðý@µ¢°§}…3h¾ý€¶Œ¥“I,J"_Ͻ€â ÎÁûÇÍåÛkç‡ÔÓġ*ҕÉppƒ«3¶÷Ñ^šh<fh,àú˜ŸæñîdH'Mêé MV(R¦ÖmQÂJ“†s4–ÛVpPXh
بl÷ùr¾Iõ»~&F.!ZD/ÀJ$M\YÈ×SßÇÌ&6VÙ`'ê6ë¸PÙD¡©à҈ZǣJ	“yÒÄ@a£u°P1YúïâŽb"IEND®B`‚‰PNG


IHDRnàMèDIDATx^¥Ò1nÂ0à߄”HUh;0!°1°u¥* S9TU[Tê-¨¸C»0MØpŸÚð$«/©ÚúŸüGŸl=ö×)ÜR}Åéêð·ãí>?­õÌh£×3´‰„Áj®ÍÔN­6«9#0xM†‹d≄¯äLôž‘D¼Íä¤m¹@9¯“ÞLà}'
>BDà£3HvjCøPÂ)p…b™iס6N¡b×è1éÑ. փª{Ê“÷#ÿ¿¼÷»ÓNòîm$¹‰ð%=îç){Ü?§є‡|‰nžšƒBçºôūøapƒþrq0i	f¹@ŸZù‡±.úä!;¨Ѕ~z`€JÂ(γ<C̠š0j£Ci3	‡|´(>q^õPe ‘/ËÔvD§rIEND®B`‚‰PNG


IHDRnàMèDIDATx^¥Ò1nÂ0à߄”HUh;0!°1°u¥* S9TU[Tê-¨¸C»0MØpŸÚð$«/©ÚúŸüGŸl=ö×)ÜR}Åéêð·ãí>?­õÌh£×3´‰„Áj®ÍÔN­6«9#0xM†‹d≄¯äLôž‘D¼Íä¤m¹@9¯“ÞLà}'
>BDà£3HvjCøPÂ)p…b™iס6N¡b×è1éÑ. փª{Ê“÷#ÿ¿¼÷»ÓNòîm$¹‰ð%=îç){Ü?§є‡|‰nžšƒBçºôūøapƒþrq0i	f¹@ŸZù‡±.úä!;¨Ѕ~z`€JÂ(γ<C̠š0j£Ci3	‡|´(>q^õPe ‘/ËÔvD§rIEND®B`‚‰PNG


IHDRnàMèYIDATx^ÍԱJÃ`Åñÿ—$-”*-ik—j¦‚Šºøm}†
>®Bó
ÅÕ]wÇnNºÅw°­A®i RêÖ{æßpÎp‘gÝ	
ƒIÄÅF£b@†hŒ¤îwü¸…•O6$Q` ߯A›:Ÿ<I€Ù{ÿ˜*kiÄė¹Ü_ТŒZìғéäá”"Z@a}԰P9d séFhöùÔÁEcš¿ct–Ô%Ÿ·W“iŒž»‡þϋ%ì,©IXú¤ÃÁõy…ˉÜ4q©|¿†+µhâßô'Ó^„æRä‰M)hS¥L‘MZ1ò…ˆPύCƒÆ
‘w9_€˜4²Da¡±P/^ì½ÂR‚c졿(ÍÊÄ5ÃYS‡·Œh
xøìrÈQ”=¶ÙÀɐ8X8”¨P£N#ŠƒÎ'
‹IÄA£Öþ]üŠ„EöIEND®B`‚‰PNG


IHDRnàMèYIDATx^ÍԱJÃ`Åñÿ—$-”*-ik—j¦‚Šºøm}†
>®Bó
ÅÕ]wÇnNºÅw°­A®i RêÖ{æßpÎp‘gÝ	
ƒIÄÅF£b@†hŒ¤îwü¸…•O6$Q` ߯A›:Ÿ<I€Ù{ÿ˜*kiÄė¹Ü_ТŒZìғéäá”"Z@a}԰P9d séFhöùÔÁEcš¿ct–Ô%Ÿ·W“iŒž»‡þϋ%ì,©IXú¤ÃÁõy…ˉÜ4q©|¿†+µhâßô'Ó^„æRä‰M)hS¥L‘MZ1ò…ˆPύCƒÆ
‘w9_€˜4²Da¡±P/^ì½ÂR‚c졿(ÍÊÄ5ÃYS‡·Œh
xøìrÈQ”=¶ÙÀɐ8X8”¨P£N#ŠƒÎ'
‹IÄA£Öþ]üŠ„EöIEND®B`‚‰PNG


IHDRÄé…c9IDATx^µ“]HSa€;gÙt9—Vs‰1Ãáï͜d7Òՠ‹/¼ŠPÁڕÂP‚ ^™?yvD†ᕻÐy¡cñB6m77Ûy{ßÃËa¸u<½ðpø¾};Ïûó+ 	Žbû"æ!œ¹¬„_X2??o>88x‹ÅÜ��«¦}þ“„¥‘Hdè,N„!8=
ô¤õÑÑÑ0ýN¢ËHÁþþþp"€å†XikƒÞ^zÊkÚ…BŠè2’’±±±»g§§ÇËMMð¹´Â߿ƒ$I¿Óéttg|pŸ*:öx<µt^h)ÏCKK”¹„éKe¥,Âê|$¢ŠB߾ItŽÎk‘yèc0|œš‚¾>¹°H^oôôÀϙ	ÏyPR®"Q^Z†<Dî“q,,,¼¢J~8€™ǨYTU%‹Vìv‰~÷ù|/PR¡&YàµÛíP__O‡~Y,hll„x4š[ÆçÎĤR©W$ψö³©T²»»»U­Ñ#÷ŒF#µ2™ Œ^ápFGGAív­¯¯¿A¥p&Ü"<A^šL&à€ÎÎNÈf³ÇÁétÂÞÞdNN ï;¡uÒëõ¾¥S‘ۥÌàSKKtuuA¾d¯g.—£9Ààà ìîî‚ßï¼Ұ¹¹	.—êêê†PЀÜ*øN¸ŠkÈãææf8Á)fggsp.XDɭ›œœ”…”­©ædù‹ϓðN«ժHh"jÍ(™LB4ƒPCArƒ»BQTrù:00Z‚’ áêê*eêGj9Y¡¨„ÛuiEñp{{´†Ûí&É{ÄÌG‰bƒ¿Îټëïï×,±Ùl$y†T!%jðÁz½þ¿æ[[[$ˆ!6ĈˆjB̫æ#]Ջbdd„$xž<5	φ«qètºõµµ¿
‰˜ÍfºUεJM¢Tc@j^$‚€
ÓH-w@Ô(QfSÁnBìHû9H+bE*¹‚&	#²¨œ¯µ…{^“­os2z¥
í¥"gXZ~ùU*’ÿËÓZY̨ÙÜ2IEND®B`‚‰PNG


IHDRnàMèVIDATx^һJCA€áÿä$'‡p’ˆr#
¦PD°ÓÂFŒˆ…J´´óì¾€øiì´VÄ^o… ^*Q“›Œ›H„Œd¦Xöcf˜E°š)hÉߛ€»œÃÆ×?ñã6joKñõKD*µ»•H!.1‘yi$)‚‚4’AE:ёN:è~µéDE:Q‘NT¤éDGÿ’!A¥­¿gc©dONȄÔKñf˜fœ4a1àó¥Vä\.v#EŒÜÞU’bÀ×óòÚÃñ¾ yù¾!‡‹ƒÝ{–„Hõ)Ÿcjwý½áˆ_^åtKÛKáúãÖ,£¤Ȗ.7)HéO_e€Ha’Q<âg۷R”êÏG‘¶FlB¸†œɖ¯®6æHãéÄÂ×Ҝ¸’iµÅÑë0¡&":iWl×z‘_¼™ñž9ȝóIEND®B`‚‰PNG


IHDRnàMèDIDATx^¥Ò1nÂ0à߄”HUh;0!°1°u¥* S9TU[Tê-¨¸C»0MØpŸÚð$«/©ÚúŸüGŸl=ö×)ÜR}Åéêð·ãí>?­õÌh£×3´‰„Áj®ÍÔN­6«9#0xM†‹d≄¯äLôž‘D¼Íä¤m¹@9¯“ÞLà}'
>BDà£3HvjCøPÂ)p…b™iס6N¡b×è1éÑ. փª{Ê“÷#ÿ¿¼÷»ÓNòîm$¹‰ð%=îç){Ü?§є‡|‰nžšƒBçºôūøapƒþrq0i	f¹@ŸZù‡±.úä!;¨Ѕ~z`€JÂ(γ<C̠š0j£Ci3	‡|´(>q^õPe ‘/ËÔvD§rIEND®B`‚‰PNG


IHDRnàMèYIDATx^ÍԱJÃ`Åñÿ—$-”*-ik—j¦‚Šºøm}†
>®Bó
ÅÕ]wÇnNºÅw°­A®i RêÖ{æßpÎp‘gÝ	
ƒIÄÅF£b@†hŒ¤îwü¸…•O6$Q` ߯A›:Ÿ<I€Ù{ÿ˜*kiÄė¹Ü_ТŒZìғéäá”"Z@a}԰P9d séFhöùÔÁEcš¿ct–Ô%Ÿ·W“iŒž»‡þϋ%ì,©IXú¤ÃÁõy…ˉÜ4q©|¿†+µhâßô'Ó^„æRä‰M)hS¥L‘MZ1ò…ˆPύCƒÆ
‘w9_€˜4²Da¡±P/^ì½ÂR‚c졿(ÍÊÄ5ÃYS‡·Œh
xøìrÈQ”=¶ÙÀɐ8X8”¨P£N#ŠƒÎ'
‹IÄA£Öþ]üŠ„EöIEND®B`‚‰PNG


IHDRnàMèDIDATx^¥Ò1nÂ0à߄”HUh;0!°1°u¥* S9TU[Tê-¨¸C»0MØpŸÚð$«/©ÚúŸüGŸl=ö×)ÜR}Åéêð·ãí>?­õÌh£×3´‰„Áj®ÍÔN­6«9#0xM†‹d≄¯äLôž‘D¼Íä¤m¹@9¯“ÞLà}'
>BDà£3HvjCøPÂ)p…b™iס6N¡b×è1éÑ. փª{Ê“÷#ÿ¿¼÷»ÓNòîm$¹‰ð%=îç){Ü?§є‡|‰nžšƒBçºôūøapƒþrq0i	f¹@ŸZù‡±.úä!;¨Ѕ~z`€JÂ(γ<C̠š0j£Ci3	‡|´(>q^õPe ‘/ËÔvD§rIEND®B`‚‰PNG


IHDRnàMè[IDATx^ÍԱJÃPÆñrIri¡´Ғ´d©f*¨¨‹¾€uÑgPñ	tÚWp(®îâìØե«J±øjlʱÆJBCný¾õþ¸çžá"ÿ˜b °pЉÚ(Œlb>øÓGY•M…nk2ì$f¡‚sšÚé^8ê$‰‹Î{‹E™æÝÅD‚˜4ÒÄÀ|õ01Åû£ðý@µ¢°§}…3h¾ý€¶Œ¥“I,J"_Ͻ€â ÎÁûÇÍåÛkç‡ÔÓġ*ҕÉppƒ«3¶÷Ñ^šh<fh,àú˜ŸæñîdH'Mêé MV(R¦ÖmQÂJ“†s4–ÛVpPXh
بl÷ùr¾Iõ»~&F.!ZD/ÀJ$M\YÈ×SßÇÌ&6VÙ`'ê6ë¸PÙD¡©à҈ZǣJ	“yÒÄ@a£u°P1YúïâŽb"IEND®B`‚‰PNG


IHDRnàMè7IDATx^ÍԿNÂPÆáßi-mBø7t²3š0‘8Td—I.Êè.wá¬wÀÄ̘ô˜àˉ_
QâÆûNïð§=9ȿ{¹äaÎì2ÁÃÿ¼ÅwŒÛÞ1Q.‡;K„ïˆO´³Ë!¡¢"
棕¡Aő

‘ÜÎGŠŠ(Èm*"ÄDŽDÄ"©Ø\À°y*|“M¢¢M:"”@	 §¡„Á"uà·:´H	0`ßÓM6>Cîe“}Ü:B<›¬ò:‰«|6!v„€:ÉËô€DÐç¦hŸ8ðüHBãŽO‹î‰Ð#áºhBOd¼OSº´ÜñAP´¶§ymŽ(šM¶YùWn³×JµßÆå³ßmJU©•¯%5ª
„ãxø\ácÜ6n{üsf_îsñЫ֞ܗÈIEND®B`‚‰PNG


IHDRnàMèhIDATxcøO2$O˨–„ÿiÿp¨
d-iÿ7€ª@Õòó{Ìÿ(œ¢ÞÇ1üAײ›¡êC
P+ü”ÌPŰMK}Ã?¼~þW[A’-R@¶å
CŒp¼¤T³d9ªi²5¡êfîIEND®B`‚‰PNG


IHDRnàMèÙIDATx^½ԽkSQÇñï¹÷¦Ijs1©¥
¦V(ÑIñ¨`G×qí "GÛ(hS¡¦‹…,QðÚÅAÝtÈߊ©IíR¡jÒü<Ak—òãá¹ˇ‡ËsÎAÿ$ Ÿ€ˆ-³ÐI0ca5»>ós~}¦š	0Û<ºJÃ͏54i«¦æçÒqºðÜŒ'77rŠ!l¿¡͍wÃ7	Níi,å„ökJÏm¥…E¥Ó}.bˆ•ÏÕUZ+’lO+®šÊç‰a:‰ObunV(/µ‰ʹЬVçHàw’€äڄÐ3ÑNû[׵¶@’ “DHU‹¡é¦T-’"âœòæ’ë_¾iñ‚›ø$Žf~U&…ESz¡|+-tER)G¯‹bô?È6ï岆tVõ֗ktã;öBÈ=Ñ»}Mè¾V$
Xôõ*q<ÇöÙÍcÇßÏWË‹ã/ïÖ['ÚHŸÎÅ8Î!ý’á0‡lyu»Þº£ïOèÁwždb$H’²ée™׷ꭼ–õ!Gˆ¿ý}±¡›>†]\~úöæÞÁÎ)Žà#Ešƒ¶RDñ¶wퟣ�Û}Œƒ8bððm<`G_˜ß”%×IEND®B`‚‰PNG


IHDRnàMèÜIDATx^½ÔÍKTaÇñï}љçҌ‰i2µ*ú*hÙÖ!ZE¹‰ ÂpW:åآE`ºIp“PA/ › —]-ÜLT–6c"˜ŽÃè¯!jó ´ñþ8<wóáp8Ͻ迳‹dâRgàmÔ<Â]Z_*f»#ƒÞŸú©Îê璆ÕoURõëÔ	êñÝ<§×VsJvÞÒÚêÇNCž›„göV¦sB4 —V­ÂPeúl3¡‹xÄJŠ©UsZYøöfeaÎPB%.ǫ%ÉùÑ¡¼6ŸA¡͏’$¨%!©ʼn>¡b#öŽnjq‚a-©#]ü§˰Šc¤©svyec–å-³üÔä%7±YŽeVfú…¡½RÞº&i*G“‹xÄiy”­V¶îåª:t^åõï½48öBDۃ®ß3¶}õ顿$u	2ôã:	|ÇöÙCÛÁãO{>ÏLõ¼¾_ÖɿH_ÎÃsÜ1"Zh'Ã[}{·lÝ[ÿõŒFçM&N’iKûɼ»SV^³*Ü "Øù{±Ð@3O.Ï>ÿp{_{mGÇIÓÊ!«41ümÄ|b4YÅÀAñŒØÕ?Ì|Ì|liSIEND®B`‚‰PNG


IHDRnàMèøIDATx^•Ô=hqÇñïÝårIZª&ÍÅ&
hM}ÃB‰‹
qt*)‚ƒ “8«“ Hq¨"8º¨´â¤8ˆ[!“â"Ep¨ƒø%µjúòŽ<K’ú{ٞwÿÿÚuÅÅéTO3îPe’$ž±8ââ“ç Y–ÇT/	9Fš„AP¸™jçD³ªm鐼ßeñ•>N?’ L´Wµ¡1MK’êz$iA,‘ÁíGЉö†¤KFôIÒ3ñŠQR¸8½¤ÀǦ¤F´.éžØÄB<œn²¸ ©Ù!3Qoè¾65-®‘2bç$ÇÜEIëá«Q?¯o’.ˆ¸ꌻ$™b†QΏÆnEýNÔ/KÚQAL1hÄ%ÅÃ:-V™óÚ-Y֢>/郸Bٞ>բZÑu¡÷êÍ]ñ”ý¶‹CŠSeýQ½ÖÏ>䌸BŒx^ם¥ Í	†ðÀ^lã<×JY˔ÈàqIr˜ۅ­w}É9qƒ<I0âà‘!Ï8üæçð]é¿TÙCˆ¡4ÃT˜¯é_¹.)ÙÅ4b§3ÌÞÎjM–m=‘ÿ‹Y’8ÝÄvšàmdÅ
³èù‰v
©0A•“QMr”CqŸ˜�Š¡@ŽA|\è%†\|RVøöË0‚v]ÿ•ÒÓüÆLÝIEND®B`‚‰PNG


IHDRnàMèmIDATx^íÒ1KQÅñÿ›qf×]Ɋ‹£˪ˆšfQÄF­ÄŠVV¢…–BìíR†`aiýZ˜*ú
a"‚	ìÙ׸óöžSÿ¸ï>.zuy#¤bÚê&ƒ|bæ™&Ç(B|Ìÿ‰G̏š†Åm¢²øÉ(U<L61DTójê¯jjeH}*‰3òX–&Ÿˆeö{Ôʬ%+j¨©ªøÍ^ŠØ¾OhU–è“%»nèZÃb‘óD!K㺗tؐ“cIsb8Mb*–4õ<ÿÔÕ`œœKN¶•SqŠ;%¤—)¯~™I>Š#JDîú9Ê|ÞÊ$#b"ûÉEf¢‡_rs!n!ï~2xvη¹Ù_Iˆ1.1„™ôëç)p§RƒöY¸<º`“?(Õ/”ÉáeC@2cԘ–IÞSá!æ¥K覗~lú(Øû"›€Á'¤³­î񿺏F\¸QŠÂ/IEND®B`‚‰PNG


IHDR

¿øƒ
£IDATx^ìԱ
!Aߋþ[æ Â9MêlåÌ2V¾2¤4Ò@Hi 
¤4Hi 
¤4Ò@Hi 
Ò@Hi 
¤4Ò@ 
¤4Ò@¼fTÓÒwn³ãø~2è—Î\ÞO#[w~CNG2®Eá“üì›AŠ$GEõUnðÚÆ+3‡ðýÁW˜CÌÞë†1•YB<äHÊŒ
Õ'ÉHeÏb‚×ÿKQ´ž„F¤%zâ­ÞcSª”^‡Ž×1 ËH+Joß×ÿ
?0×AEíý]c_=Šu´A£¬µ}Géí܂WޡÖ
m°Uµ~îŸÓê`u‹ÇÑà\£ƒ¾éï™. T°P ý<*M&”=ª!&ÝÅ	´*	ٱޏ³ÚkBÑ`±Gk��‘# I•ü¦žcŽåcƒÅ%@º£QB!€ dz’{ÁÒæÈK¨ ¨W´öB!;ò:¡³*“J×Àøo,œðpri#$Cr?ý `ˆ
à
Ð؀áé¾T„àx0ÐY¬Õ͎‹&wSD
á耆ê(¡O„ÀAçè#VË7´Öæ«~Þ	#å‡w"ƒ|­	}ãm…ž‘xٱð°{x‡àˆÞãhøÍ+<€
D–l/Yê4—’ñXHø¿xxá
Ш'Ê×DJã8!¡„Gø…L.
Р†^wíTww q€ágp
-\Cl@ãJr@á@¦ˆ•æG^ŒOP,ϸ?®……ŽähD[|½–ãHüd_ìûXõ³!e¨°±m&l?×ja°ðønÙ7ûûQw4£@¢A À3âï]è_Lö§}Ú|²~¶?ìwû¶ 8¯…ÃZÁ7ý‰ÇV‡s¸ýj_	ÆÈ>í«ýfŽ.ÌsȾRþr,*þÃí£càø0½*"V
ЀO`äͧ’?¤¤l¬ûŠØadר©™²kÄ€ôŽžG¸Æm(u×(xŒØ
МŒ0ù…ۭæ~d²[Þ/ìç)uAC睞ñ¿\c\ƒ¾¡×Áá¯û®Œ',®õÓkúF¾«C¯‘Ÿ<y‡vÊ( H~áØÙ~ç)J†Z׸¤¼OÂNöŸPÒSÒÖ5Æ5”ÅíåÂJ¡ç{é5BÜéŽëm|£øŒ6žaý†WÕlҸÆN‚_”ƒk£ƒrÚ]áƒF-¾ i׆î›Ð] L \iD»¡¡XÑÓ¹øŒ’·" éeɟ]g|Uï@! t¿4¡̄âp
@Ñ
•]GTG÷І:¡!>‹÷hžú4ÜS× 4zŒC{Z¡Á3
øÉ¢7ðl£Dg¤öÌAù”cqÖÜÁ5´ûˆÕh#ìYµ»]'”:^lT«Š~J-Æ
¡QâžAÍÑ ×rÀ錆ð,<³:Úï÷LÝ…ˆ{‰Hô¢0H</±ҷ
ÕîÝÊF×Î?õ{wl0CQxÿ6@.lEŠîZh@¹ÄÀøi ¡¹Èó¯40PÒ@ 
¤4Ò@Hi 
¤4@Hi 
¤4Ò@Hi€4Ò@Hi 
¤4Òi 
¤4Ò@Hi 
¤4@Hi 
¤4Ò@Hi€4Ò@Hi 
¤4Òi 
¤4Ò@9Ìܟ‚‚4Fk¹ì"'­»\RûÇ8¹„³¤>x	ýDxÙ9£Ô<b7yjr€^'‡éÝCš¶Ð<´Y«ňÁ,D¡_‹$¯w7º_4²ÿSêŠ-‘йÞ݊×(FÄ*W
“l#{l2]-É;òbÎÁØJ(ކ`Ûv’Ê\Á:ÖCÃbçԟ„­Dºf­n4¤.¬­„B¶uµ´©)E%¶…[µ—«´¡¦±åuU;3«؆Úrn2þ3Œh%¥z;ÅÒ#¯­p­ÄRJŠÿؾÛÐD¾B‡«v¯aR;ˆ¯206}±n²²u?C1ÝÊ
 ØZK ÐíªUý%î0Œ³žÊ6”TÐuT7£3c+PF]C±)ëyݬ>´шÅ5¢d-eÅKŠéLM%?(ßJÌ“¬Š¡˜^)“N<[=àD§EÂjµ¡Æ׌_xÚp,ôˆ'ü̚PæwÑý;»esît4"Ñ\_ðŸpcRc¸pcÇÊ–™˜EgPxÞyp—ÝI4ˆ¨± 8ñŒϸû£Çȍ£"Gž[ÁßÔê€"1ò‰G>yÝåtCZ÷
UÃИ§‘шEçmC÷ìo
(óêa|£ñ½	Ž"²9SÌ''8Ÿŷ¡‡Œv«†¢Xm²•Cðhx›Ë-‡Âߣ±@ªF=4´j@ªÆÐT?Nœx,˜ƒ
lC!Z70ððŸý1¾âqj‡ÍkFw(¼bP]±¨‡‡hHw@~8&ÄF¾(+ÖkxÅкá¦âð|ð€ñùÅ1· Uì$>ٙ[ѮÆÂ6ôßÄL¤f”ߡ°SÀ3¼à»îOÀ&”"¥Ñ Ôd)Z78ãS¤ÜÅX+äš!§ ¼G#™žF=ƒ½†g
*>îòQ®‹
Áp,h/&U0ª1h(8Ù|¶Â`hÕHN7ôʱàHØÊŠÖ¯	¾@4óÖ þÞA@Ní5jjÙ'X‚‡Õ0ÔCÃqð±WŠÑÐ=\Ò~í5ÔêIÐՠJ ¡[W1“!îS a“twRyóWªˆx^˜
jœkZT7áàg*£Íh‹£|ôAíPd¨¸fX^ƒZÂцÜT–õ¢gfRßTrsY( Ìi¨Ô
x
0Nùc~ЅVîÏ,Ŷi6c0´fXÉJÇ0¯`†â!ýˆçª"BÃÌ;FéJcÆŽš†ƒqˆ°Ã(®w
Ç,(ŠÚ{¨ý/ôšrƒf qÌcb!W@Càˆ텐p0â_´ÛF#‡ƒW:"ª1”¸r@1؀!hÔ8(÷´YMÇGba‰`q<L[Óy·ÔA9q ÎLð€"2ŠÂG^yߑԝ©ì¶{
^èL,ba3iÓÙ.†e€$Xߋ³›í5r8x#!Ϯ#cÎá,£9zGq¸*ЉŽ9…ÐÈáöáÝd^E–Ï€ðnF
48ñ`NŸ•…Be™½P–?S0ê ´ü5…@g7•EÀä_W
½•ÛCþ5×#ßÇä_S¼B\¿jäÀXYM4ø(UûÝÞ£ÂPÜÈÞÿʱҥû0SYXÉÁ&ϚÞîIø(Ÿ×ò0ÊÔÖE8i̘k#ˆü4¦ö $\‡ê/F#
¤4Ò@H¤4Ò@Hi 
¤4Hi 
¤4Ò@Hi 
¸‡Ú2ÚI§IEND®B`‚‰PNG


IHDR

"ÌÀ:ŸPLTEÿÿÿ®H*5tRNSH8?Do
=39Ad4;(!%-OE G6Bkn>CF@	"Œ³—[ÍIDATx^íÐ×qT1@$9^¸äœs6ÐmPÒ0»%ì—!„xrøµ‡'1„Ðrã÷q
½HÇ×m7òm
ýH·¹åFŽG¡'G1·Ûȱ¬BOV%ævsڅžìÒÜp£/¡'/Ci·Çé2ôärc»ToBOnjj¹±Ø=Ù[ô³aÆ
6lذaÆ
6lذaÆ
6lذaÆ
6lذaÆ
6lذaÆ
6lذaÆ
6lذaÆ
6lذaÆ
6lذaÆ
6lذaÆ
6lذaÆ
6lذaÆ
6lذaÆ
6lذaÆ
6lذaÆ
6lذaÆ
6lذñ9„~Ÿ7vË_¡uù³íF=;?¸øރ‡ûƒó³Úrcœ®×ÛåݷÜ-·ëýil·‘Ëpuºޮž—í=¯¶ëӫ¡ävsª›‹·ǧýöžß.65Í
7bù¨ï›×=xݼ׏Ûm„K¦ºèA†Tbí6BŽsSÆ2ÇZn„œsìEÎ9üÝøOÀŸû‰ƒÑ1
ªIEND®B`‚‰PNG


IHDRØYþG–IDATx^ÅÊ1nÂ0€Ñg˶ÈZ:€ Œ‘0ÊàLôþ÷èöK‘²ó¾õóIÙΨ/ídߎš¥æèK ¹hBh.’MÖM²PÌÖ͊P=¬{¨Bó´î©}|»Ûaã®	ÕÕÍÖÒÖMW…â`öòö½½ÌА
ÎFÝoԍÎYHªÁÞÉOt²7¨’@’U‹ª"KÀ?ü—\=ô@´IEND®B`‚‰PNG


IHDR€€i7©@AIDATx^íÝïO•eÇñ÷}ŸûàÜG¥”ìXêdNqc2bSsl\©˜ ÉH“ê‰ÙÖÑ\¶ìôËÖf¹™®Vj5]ùcs+œ=@¨•N6œ蜓óøìîáõ Îáؾ±¾—÷çúÞ/ìÜçpApŸŸ B€    à?ŸC‚æSE-UÌgcqíe /íRÌÂæWN}{åüÀå ¸|åü™c_¥†¸Âçÿ€Ceoì¸r>øÛnl{‹rÆáX€C!?R®»jq
ÀäWžëÒîFÉ:&à(Í7ëê¤O€t¾Yënfá*Í7»u“Zb
¤óÍöîc®Ù|³ß{¨"ª@6ßlh:²H盱ޏé|3šÈU
`òµä[ ŸßÛG-¾Ù|³ýßSIŽÙ|³;˜BL	€|~gKIQ Ÿ?<œl¡„òùwî®øˆx
äók?f	…dáèÏ’"rpÈ䛵a˜|’ù»ŽRǃÄM¾áüÉøDtĄòWQL.^€*<ʿùR2_óöí•ÌW Ÿ¯
@>_€|¾*ù|UòùªäóUÈ竐ÏW Ÿ¯
@>_€|¾±üwÚxfXɊQ>µTSÆ$Ü`òïö@Ïéݭ,fn†úóS|±Œ<œÌL¾Eë<A…8™DL¾=;×A%	œ‘\Jßû °p')Ç	Àaâ̦»w+·e'SqÓxTvu–îÒEž š! zs`ñÖn§'5@„ÙÛðã)*ðRD©éëµàúU–‘• ›ú¡ÁÀ걖œÔ>ëËÇzütMÖ4‘› apèþXÞÛgsþµkÔã§û!øØþïl8ÙAUº‚Q¦,Øa3@ý»LK÷k0B‚¥]¶æ_¼ÄÓà¥pȡ$¹uxØN€÷0'ý‹¡5[¿°1ÿØjOt¤—ÃYLä©Ö#¶å·w³†éÄqG~ gu»Žڔßv–F搇—Ù#±\ŠYeÁÍ[Ïíg5%äÅÉð¡¨üùï¯â%SLÑŠÊ¼}œ¼ÉöÑ?lãeYÄT
‰ãeøX\žàý¯YÉL¦3m”ϣ$™Ä8r‰Ýû#‚{°cÈÕã'ÏÄ߀(~½ÌÓöæ¨Fyyuòêä	ÔȨ'P O @ž@€<:Cðé	]†àaִwËèû£©<æÐxºG†@€!ȧTŽ@€C”|æ
”Q Op÷NS¥¸ºä	fãj'ØbTÈÌ\ÏDòæNIEò՛)ÀQ Opð0³‰¨'è륆˜"yžQu•–<Ïâ+ °÷BEC`=€<Áà
Šä	~ù%ÄÕÈ|xˆ25×êÊ±B¢Jä	¶}ÎãŒÁU OÐÞM”\®.Opõzr+³ðqm0¥4¶Mº‡˜O¾uÿ`ÁPÂꍟ]èÿ§Oñm8@sKÇ6CÇdѼ|ÏWíúûoAÿým?/û„M,æ!òòÅäçàg<S(gÍl¢…M<O=$)ÄÇÃArÒs‰â3–"ŠI2•$ÅQ€OÀv‡1²‰ã'›˜ÀW^à~<!@„!@„!À_.ىØjwD¼IEND®B`‚‰PNG


IHDR€€i7©@GIDATx^íÝkoe€á{fg·íNˡ@„Ål*¥$
MmRÔ"´B„P¤ê”DŠŒCQX`P„hbc &b0@[Q?Åp$
!„ÊA>´ýöúquw<Ÿ—yÞ_p_ÙÌfÞ9aîó„!@„!@@À=‡AL †Zꨥ†28ü·s›Yå²Lvy—Rf,[yxÏÅS=Œé¹pñÔþo›_g
I\Ÿöÿ‡!T®yçVùÇ\<õÖ:*(ı‡‡˜~¬ݤŸ÷RE1Ž•8+[|µÛdœ£TvxTéR4à2¾us)@  FÝÍkÆh%të¶ P€@@”ړ]Æ(ÈeA¯1J|aêòi2F€@=€<ýîc@ýÙsjò˜úc»1Jb”L^gŒN€	æt•!Ðàǣ©–¾>'C	fÔÜÛ/C À!‡bfÕ}"E oCÄ%ÌnÝiŒ€€ ÎÌ۰KŠ@߮pŸQ’Êxä“d¾AG
€<AÇ>*ñÈ|þ“ðÈlÛ('P O @ž@€<:yuòêä	ÔȨ'P O @žà®pIө£~€×\iæ÷vËÜ
€K)37·vºÕcÔN@pg…Tüí.>k²8SÕùC`Av‡ÕG;‚‹"·àQٱÏX8|D9n6—’U덕Óß;®‰á8™¢L;ÆX:G:©ÆËà\ù¾±x¦¿Æ`œôU~² ­Lj¤Èaö•K6œ8ÎSDÓä±ÈX=7®Ó@nzŸ%Æòa1ñôù4YЄ\¿Ac&Ÿ†˗m8~‚YÄ3k÷uØ°ý;žÈtÌaLÃF›&¯et¦¿AÁ,8sÞÖüÎ#<C‘ô>“^Ùbg~__ª…2òp2Ÿ
¥nÏaZ¾b	¼l§ÃqÆò|û1Ûò[wò,ÃÉÁɾ!RÈîþզü
»˜ÇH⸷³%¥ˆ2ž{qûµ›ÖäÏ'I~ö-±€ $3yõͶ¿ÿñ§%ùޝl‹{Ä)¦„©,dkxû¬µ¬w¯\þ_‰‘ÏF’âaÆðË8æ~ø\þÝ^óÈ!ŽOþ€®LٲC._ßÅÑI۶J櫐ÏW Ÿ¯
@>_€|¾*ù|EòùUòùªäóUÈ竐ÏW ÿý/A¾éüC]4òZš’Ï_È
Õ=6GD,¿œ"¢8ڝ-߸I$b¯—ò¦Õý½’ùŠpy¼i•l¾"†["›¯ xŸ¤d¾*†N[!™¯
 BåÁýrùúb<}î¬T¾F€<^Ê×	à³D"_õëô$òUä«XÔ×'‘¯÷0«ë¤@¾Z€\*6µ	䫈RÌÒë7ò•¸ðäš/ò¿\}óڏ	ä+pñŸj¹tE _íЍáåC]éóÛ¦ßëÓàci\ºãßîD<ݽìæSäÛ1š™,ŸýéîßNww_5¦ûêéî¯Ûçl¡™©Œ¢oÀ?²2€ãàáSLŠ*x‰å¬f9ÍÔSɃ!އƒÀÈȏKŸL IŠR$Á |¢¸v¿„¹Äñ‰“KŒÈÀjëþ\!@„!@„!À_!þìün>IEND®B`‚‰PNG


IHDRrÿY)IDAT•caðe–’`Šc˜bà€Pœ(„â†P‚JB½QŸzŠ[GZIEND®B`‚‰PNG


IHDRò®ä CIDAT•cafÐb```a0Þ,îÊ	b°9ÌñÄ`ˆüÂÀf0%Ð\07„ñ›AÂxΠ’da¸ÆÀ2ø	&ŵëIEND®B`‚‰PNG


IHDRò®ä GIDATq
@@Ð'ùÍq	…Ά¸9
a‹!W‰¨¼×)hj¼+çXY>6¥3ƒ=$ $ ô@€0/,x\áFS+š¨^÷÷7IEND®B`‚‰PNG


IHDRµú7êˆIDATxڽ‘±
Ã0Deñ Ü_ÉP<h5:–üÿ‡´2EÕҥ/ï]mz|9?èDõŒžߖyaÜqPÿP—΍‚jxgå’* ¬ëՔa©DEV7ÇY¨·uã,ø´·Ð !Þg7“æÉ×<&Ž-¤ù¡z4CH=ÿ᳞ÒÆEQPŠIEND®B`‚‰PNG


IHDRµú7ê©IDATx^¥‘1
„0EÿQ<E®±é]ÅFt½A°±´˜:g°³ÙSˆ…×ÉF÷Á.,C Ã<fÞ$p7ñ38åOœåç[Q	3
ÞªÜ%¼bÆàTС(1@`ëÌßL°FŸˆT9,zF¶}„Dêì@ÂrpÌA‡Îè@óå M¯¹bÚg
A¿ë^ל©–4éW7Z““©Ëìþ©ÿÿÍ‹ƒí;k.J²IEND®B`‚‰PNG


IHDRµú7êFIDATxc #¸8íU&Œý*óâ4éõÓ@J Ò\!x¨äUæM¸b4%7ÁJÀ$\S	Bš°‚Vt$Ao
(ú–pay
ܫðIEND®B`‚‰PNG


IHDRµú7êBIDATxcøORMƒÃ †(UÁ0´ƒIƒ š	0%Š„>„Y¨
 JҤ+4‚#	{“Ȁ¢Cdô°ÈmÁəBIEND®B`‚‰PNG


IHDR

';6,IDATxc`hB€ðè?\ÁC0,!„†ÄԎiV'au<Ü
!ñ­âJIEND®B`‚‰PNG


IHDR:˜ ½NIDATxcÐ@ä
¸%ƒÈx¸@òï*
²?-•¿«Êÿ4 ›QñûOŠ¡•~W#Tý®ªø]ƒHù]ҕpO‘‰Pk)÷v
9Q›>9¾IEND®B`‚‰PNG


IHDRµAåZRIDATx^¥Ïa
À @aoà]ß
'è¥Z¬HmâýüDTÚOÇHÁP¤§%ãE#Ð^аŒŠ?c(ãäAȊñ“߭µ÷ _ª镚péož¢lñ¶'IEND®B`‚‰PNG


IHDRµAåZIDATx^…A‚@E{ä&CÉx	<É;&Ï ^d@蜴b7æíúÚä÷FAÏȒè(ljª%±9&Z•ªVž•¬…
ѮID½.…NGG„@Ê„¨³^lŸJu°%•£°°9ýQÊÓËð#ïÂàT rúºŠß@•Tê+µ…Ú^ùSB†³WÌVŸ/þƋÎ{ñoǙÍN8-ð›IEND®B`‚‰PNG


IHDRµAåZœIDATx^}A
ƒ@EsëAŒ 0½„=‘W¬½Èh»°]h5	]”·ËKBò…Œ–ži¥£!۫ª¨I,ށZ¥ªY…g޴pb`¡"Út"Rét.4Z:#ÒJ@ˆZk…ÎúÕaoRÙ‹Ӧ”·—áG>µ¶°púnƒ
P®¯”þJ{åF¯->üƒ/n\±à¿ÑМN»ޚIEND®B`‚‰PNG


IHDRµú7ê–IDATx^•ËˊÂ@…ÁBtHKƒ¢@ x]húÿw›4¤™ßÙÖñ]k­û1‰ϮU{³0:9eÙqùž…› yȒÒ$܄K!Ù`-ŒV.2	h…9°ÎT¤+ÀF©H/l®²T‘·§R#{h$´Je³ÁÁ^ï%üªJîâ³gy×H§³õMû㣯|AIEND®B`‚‰PNG


IHDRµú7ê¬IDATx^•͡‹BAÀᯜEä‚,šžõTL®ٌÚ,>b¾C\}ó§_9,~S3ã=}‰—>tB­¤æËÍÓÞÊÚN–-ëí›pÒ$#ÅÁÓI8–dèîÐ×Ùë9VÉVH@#¬ðQ%aL„5TW¦Â;êÄF´²åQë×U‘dÒ´B§Q°ôp·µ0µñ£ó­fä,þçªñR237öŽ?dw$‹uÐÊIEND®B`‚‰PNG


IHDRµú7êºIDATx•Í!na€Ñg‹F`ê¬ øm8CÛ
O‚ë	8W œ
(Ã!Zƒ B–©!²̾±ßÌh¦-7ÔñһR{=5Ÿ.îÖfæV
…iuû"´™“›¾dãî lSÒuuh+­µl+ÉRȀa†·J2FÀP˜Cåʷ0:VԒ…0Ø+díü9Kz
'ݔì„RŽdêæjiâ˯ҏš¾£xÎYî¥ÌÈØ@ÿ#[Hvæ²aˆIEND®B`‚‰PNG


IHDRóÿa®IDATx^¥A
ƒ@E\ØÛY7^À x»³Z±^P¨ÎfRPÔLZúáí>ŸďÈdš&Ö "„HBÁn¬ªêƒeY0Ž##N,ðþèl› )Š3†á!}A*eY¢ïN,ðâ[{çù¹³®/tݝZPחé)¢8çB¤§ˆ``ŽP[` =ý‰ö‰tì äùI ÔFÛÞL¼WMs¥oÁÅrÙñȫÙzIEND®B`‚‰PNG


IHDR  Ùs²™IDATxcúÏ@db  Ðô|ÛdˆÓ¨Ãíê„8Ï5à1€0(e`ØӤ׀ÿŒ¨þ¿§QÓ@½ÃþFm2]€0¢A‹Fˆ2ì¯×D6€dÐ ƸŸD<G‹Öâ$ÉЄÿ“˜*ÉÌ»`ԀÁ£a0ê( ârÁ?â!vl&Â[å !DL‚UIEND®B`‚‰PNG


IHDR@@ªiqÞÃIDATx^í™=nÂ@…ÇÆüœ.ؐ.Tœ!ƒÎ!e¸
)À/Ú(h"‚@oÙ	3Ò'Ñ}š7< @™Ž<ø˜pá¬VïÉrùV­×k9GYVa#0¾¡ÛM¥×Ëf»Ýg]H۶ÈqÆ㱗‡ˆ›¶/Z¤(¼„»äC—@èd	Ú$Ôu#7eYý#8¾¢â'Eñ-!I’Íp83üß"ä$ý§ívW‚¿Ÿ•ç…ôû½Ù	´D‚—Ð4ÛJÁ¤Ipqð¸˟—繗  18‘@ÀäúçŒF^‚‚#ÈÀK¨ë¦bl@Ð"´Ù|\ÅÏÌ(H&“ç› ³	ý~5‡ÃApnˆ
p7ˆâØÿ=FŽ rÄaPP…° m@äù÷ï‘"@ˤ°Ø´
EGЪ°E€õ1¨ê nìcЊ€¡o€ý(j7е
« DF¤X&!+Bj I€E@ö]À"À,BI’Ä·"išJ–eQâÞ@,B‹ÅBœÌ築&ì^„	0_Ý_H]8ŸIEND®B`‚‰PNG


IHDRÔôUœIDATxc 
£ ¾¶‡ˆ+€øÿÑP>+µ-â⃠K øŒ
碦e=Pƒ÷±TLćŠ÷RӲ×PC¥Ðĥ ⯩f,ÈðËQn‰6_FCÕiSbÙ5A$àk)j‡®e@~+Ñô°ì'Tü3½|ö…Ÿ&K$æ³딖 Wˆ´è
¸`ŒZàYgIEND®B`‚‰PNG


IHDRÔôUœIDATxc 
£ §o>+Wñ þ¢¡|Vj[ÄÄA–@ñ*ÎEMËz ïb5¨˜ˆ復e¯¡†J¡‰KAÅ_SÍ2XᗣÜm ¾2Œ†ªӦIJk ƒHÀ×(>RÔ]ˀüV þ¢éaÙO¨øgzùì)>M —HÌg×)-A®iÑp	2$À(™‹-¦
´'IEND®B`‚‰PNG


IHDRÔôUœIDATxc 
£ 8·Šˆ+€øÿÑP>+µ-â⃠K øŒ
碦e=Pƒ÷±TLćŠ÷RӲ×PC¥Ðĥ ⯩f,ÈðËQn‰6_FCÕiSbÙ5A$àk)j‡®e@~+Ñô°ì'Tü3½|ö…Ÿ&K$æ³딖 Wˆ´è
¸`Œ“"­{hIEND®B`‚‰PNG


IHDRÔôUœIDATxc 
£àïA&V ®â;@üDCù¬Զˆˆ‚,â?06Tœ‹š–õ@
ÞÄjP1
*ÞKMË^C
•B—‚Š¿¦še° Ã/G¹%Ú@|d!U§M‰e×@‘€¯Q|¤¨º–ù­@üDÓòŸPñÏôòÙR|6š@.‘˜ϮSZ‚\!Ң+àdH€Q0
5@cË͊äIEND®B`‚‰PNG


IHDRÔôUœIDATxc 
£à÷eV ®â;@üDCù¬Զˆˆ‚,â?06Tœ‹š–õ@
ÞÄjP1
*ÞKMË^C
•B—‚Š¿¦še° Ã/G¹%Ú@|d!U§M‰e×@‘€¯Q|¤¨º–ù­@üDÓòŸPñÏôòÙR|6š@.‘˜ϮSZ‚\!Ң+àdH€Q0
P¹7ڃÑIEND®B`‚‰PNG


IHDRÔôUœIDATxc 
£àý.V ®â;@üDCù¬Զˆˆ‚,â?06Tœ‹š–õ@
ÞÄjP1
*ÞKMË^C
•B—‚Š¿¦še° Ã/G¹%Ú@|d!U§M‰e×@‘€¯Q|¤¨º–ù­@üDÓòŸPñÏôòÙR|6š@.‘˜ϮSZ‚\!Ң+àdH€Q0
=tBÊÜÕö;IEND®B`‚‰PNG


IHDR'Ý<Þ§IDATx^•ԱKUaÀá÷x¯aå¢!C2)(hn¬ ªÁÁý4U 5˜!Ys•ƒs:8AC”¦6µTFf_K\Î9œƒÈo:ž÷;>ÞP¬ۨg_løౚ(VD£Ö̺ªþĐ3Â	ӚU츰OS³۔o.(25“–í•óÆÞ"»ãµn±iÍ,ëòR=:ŒY‘¬ӑco
·Y¡Nó’ä¯$™יaG­ê!L:c’9…~s’{"Ӕ"4üԓc«’>!„>ÉjŽõá²"W’ŠO…¶…ÛZ2`A*fÁ@ó4ä[’J[ʰAKáTÅV¿Ýe#¤-³šÏaC£”[7^5,¼3XÊþHÖKY·CášþŠÓ~UœvÅó[þ·Y—Bx¨w¬iMWÜo³÷RiËm֫%BØã«Ãí[²X‚۷¤+»ZnŠÍS·ìd~—lWß5¼rWäٰEufÜ*Û\#¾›ÖQº¹ÎU{²麰_ˀÿÉE3~˜PyVìˆ'>ù-9+Ü0¢!òýê  n‚',‹IEND®B`‚‰PNG


IHDR'Ý<Þ¥IDATx^•ԱKUQÀñŸ„A>
+Ÿ
A’IAAscQ
>È(褩©Áɚƒ¨„èpp>Ð¥i„M-•‚Ái‘Çáp"ßé^øüνpÎ	eÝF½pHøjÃGOµ‰²Z3ëºÚæˆ!ç„S¦Õ[±“ÂuQf¯)ß]R2m&-Û-ZvÂ[ûKvÝbËê9ëôZ-íƬHVŒiϙw†›¬¨ü$ù'Iæudì¸U½"„IgsfB2ç°ÐoNò@dMy$B—_zrfUÒ'„Ð'Y͙C"\õJäIRùT´#ÜÕÈȀ©̂]𼜳$U¶”±AKáLõ¶~k¶ÍÚ|	º*ٸu㭆…÷+Ù_Éz%ëv$ÜÐ_½šßի¹æeˆmÿ۬+!<ֻ
V·¦3„'6Ù©²å&ëÕ!ìóÍÑæ.Y¬@‹Í]ҙŸ·†ÛbëÔ,;-?ovªmº¼q_șaŸŠ֙qG”,ŒøaZ{åÍuQ䧼¼`n
5صI.›ñӄ6Q°¢cžùìä¼pˈ®rýÿ@Ùbp`IEND®B`‚‰PNG


IHDR'Ý<Þ¦IDATx^•ÓMKTQÀáÿ8ch9B´L

Z·¬ ª…2
ú´ª@ja†dÏ:ˆʅ}.‚ E”¦¶jS!˜A œÉpïåN"¿Õ9ðœ8'ë4♃Âë>x¬"ŠшU3®©n.1è¬pҔz+vBد.Šé6雋ŠLń%»Eˎ{c_‘ÝõZ§زz–ux©šmF-K–j˱·†š¬P»9I²!Iæ´gØ1+zþ±	grl\2ëÐgVr_dšôP„šŸºrlEһ9ꕬäX—A®x!r%©8*´#ÜÑȐ~óR1óú3輧!ߢTÚb†
X§ËØzÖë!m›U|ëj¥l̚±V‹…wJÙÉZ)ët8\×W¾›_廹êyˆmßmÆåéÙ«[Õšì½TÚR“õhˆöúêHó•,” …æ+éÈþ·†[bëT-9•ÿo;U·@5¯Üy6䣁ÿ²i·E‘…aßMi+Ý.�…ºÂ
ývm’K¦ý0®"ò¬ØQO|ò[rN¸iXMäûéVK?\IEND®B`‚‰PNG


IHDRÔôUœIDATxc 
£àïA&V ®â;@üDCù¬Զˆˆ‚,â?06Tœ‹š–õ@
ÞÄjP1
*ÞKMË^C
•B—‚Š¿¦še° Ã/G¹%Ú@|d!U§M‰e×@‘€¯Q|¤¨º–ù­@üDÓòŸPñÏôòÙR|6š@.‘˜ϮSZ‚\!Ң+àdH€Q0
5@cË͊äIEND®B`‚‰PNG


IHDRÔôUœIDATxc 
£à÷eV ®â;@üDCù¬Զˆˆ‚,â?06Tœ‹š–õ@
ÞÄjP1
*ÞKMË^C
•B—‚Š¿¦še° Ã/G¹%Ú@|d!U§M‰e×@‘€¯Q|¤¨º–ù­@üDÓòŸPñÏôòÙR|6š@.‘˜ϮSZ‚\!Ң+àdH€Q0
P¹7ڃÑIEND®B`‚‰PNG


IHDRÔôUœIDATxc 
£àý.V ®â;@üDCù¬Զˆˆ‚,â?06Tœ‹š–õ@
ÞÄjP1
*ÞKMË^C
•B—‚Š¿¦še° Ã/G¹%Ú@|d!U§M‰e×@‘€¯Q|¤¨º–ù­@üDÓòŸPñÏôòÙR|6š@.‘˜ϮSZ‚\!Ң+àdH€Q0
=tBÊÜÕö;IEND®B`‚‰PNG


IHDR¿¾-|1‚IDATx^ݝÛw׵³±1`Àvžó_ä%#‰ÏÉÎÞ6„n\b¼m'9çáŒ3â�b„ÌEB`0vl0ØN|9ñŽã+؎	I kK­–„!@·nIݭju«ú̅¿²§k—ºªºj®<ÆI=ôó7ç·æºtiõ÷._¾ìK)6R£h£˜xî͉OV13AÑNñÅ&Š¥߳	0\Å=Œužâ:ÅōÇM½EŒƒ¥`ÌA,¡ØDñt
QÄ)nRtPüéÑÓÅĸ' Vtu(=ÓQ°áÿ%]wS”P¥h§GM]¯Pl¦Xf«Á;«¬6“…ºµªܚº|r¸Â×`9еº^Bo€5ª¾«~
BW«ׄՇÐLáyxa¬a°_
’żÑOLC_'ÅqÔK"‡£ÐUº|X ^ðað¬»T=P¯N0cнë)þ)Àñu„y>v
è*a>¼‰ŽP„àr��ñ*úÄó!׵<`χ½Á{ԋÐ5Öc•8¾J™çÇ0¾F؜RŽºÁZ]­l^¾öËеęá}mý~X"У:˜yÚ–TûX=·˜Õë:XQ¡y¹¬v6
±õÆFè
Ê릆5ïQSÖyYÀó6óWÀް®±áCè<
ÝvÞÀú×]¨¹õ8ޱ;Ö[o”âu~Y||…ؼ|ãëe3‡~XˆÿF±þ½3C»ÙÚ&a³Ž‚._¼¥åÇ(ÚÎuv™=б6;̕^YG±Œ>X13ï[ց°Š(ŽPt`ï:Eq}íîÄߙç—¥¬6ŠaŠ8Å
è<òÄá©
L—ÞŠRìÁ;)nR$ØÞü8EÛ/̃®ŠW)Z)FÃ`¿ÝK¬9ÉårváÄÚV›Y/èꀮMloî‡w7ó|‹òXã`åçnyˆÅêuœÕkڬXe>Ï8k£Mo ‡/ãçKü°KO5_+^ćìŒè.¿gD|Nyõ“›ï(=ÈaT±Û-˝ÆO>ÈJнh´9Ûޘ8M€œ%’5«¶¬8çðø—ªdŸ
ke	\AQ†ž[,º{TÚG÷CW!¬ç1䜢¾}°—ÏS¬(€u/Ån–C§Hâõžsˆzíq££¨B9ÿ7ìuÕÈZáQW¬U²vƒåº^²V#'	—¬Šý>êµÏC½&)*u° «ÖkVÂ}#æև>X+tëòX¯ºY+=Žå¤Ï#'	9¬ñÓ½xÇ.Ì_žzo¦±<…~¸BC½’>=¿OÓøZN±݃ç>굊é’Ì!Ÿ+cë•ð0¾ö‚%½˜òÑ7VyÕ/-÷zV
êֵº<±Þøì†bU{ì½{
aaPóØi/¼Œe¬}ØØåž:=íbµÛÆ®uQ$øžC¡<º؜≷’³x<HZ=ÎËnt�sz!!]¨tå‹êwÇÎZ{”G޽ÕL—SÄ_úhä6Wz᭠Ø:²ðº½l녷
õJºa!×uȽ§Ã/Ôk'EÌ«Æë9_^ê…<¬*ðÌa—tz¬׽ŒåymóեËY¿“¬Ix	ÞðÄ[i¿>¿píb;·ñvøUL1ˆqõêՋãããͳ³³=Ùlvb>c$&gŒ‰ŽlO͇sÍëö¤ú	`¥(ñ Œ³rÄꙘ˜h0YIÅìÌö¼ðiú\ѾT˜±F)ñÀõ7«t5)V&“ù†Eìpèrü4±ºkºܲ¡ç,ÒuÎÔeFÂd©ï“îðoŽLž+F±ÎkÅ«WX3‡JŸb«Ü«[½Ž"÷¿^šü”EYÜa®‹³Tn•.“…ǒBXÈa·é
bDÍz™ºìX`¸‰uVϡ…UæYëm<oçx#bÑU䖅ñËçyԋ³rˆ˜G]ÿJ1ÊXð†-õõò¨k<Ÿççç£vÞÀB±ŒB|¶ëQ©Tª—X± õŠð•G×Z9´z¾‘³ˆUlÕÿÕÏ-ž_疅ÚF­9t©kõvË*²°zzTIJ‰(÷X/>¾n犼Y¤GuûèQlê…~hÉ!æ”BÇ2X#ùrhףú¡ÛõFË!¯WØ&‡Ç×CȻÛùËZ¯²BÇ×ÀÀ%ErÆøêác٧7Âùê¥þ_¸7|öÛÅsØkÉáC^rèrN‰€Åsó8–×[ÖQ°œǗwÖ:‡z9/—جÙÔøRs$XQ»V©ۃ”¾‹WŠ,ºzá
‡zc!ÖӆkøLÛà•|ó²òÆ"se¹ÖŠ1¬Ïӑ‹ƒ!Òužõyk½ú,ºÖydM€e¨=Ï;çnQ:\¬±'YÝð6PDÁʭݓº¨öY�›[°Œe֣òø0˪K±:ˆ¥ö“óÙ\‚¯±mÖó¥XŌ•[¿7ÕsèÓtCçկY³i#96mLGÓvž§Xふž"ÊX}u§•®ñ¸1‘"–úWåôö÷#×[í×Î<ìwÇÁ2ëÀ'ésmW²‘Xòk]S؛¤ï«ÿ3×ép"ƒq¹ÁÃaÔzžCªWg)]*—í`)Ýæk¾3ÙCÌ2·‡_ðƸÕ-—²‘“Ñ䭯ëEìÛu´ìÍc.öæù¼Ñ[ûá\“ҥ3s¤9dgœUêa[¼÷¯c'y½T®”Žhâk–ʥb£^œ5îñÌa
¼›«yo´^åP±Ìñ•ÎäÖz1֤Ç3‡uÖ5ö-³§ÕøRz¸ç÷4פr¬8ˆ/gDX/ܴ®Ù3³_³æþ‹7Âà°z¹;üªàyjDs.þ#ÑKjR=ZEñ}aϚ
gpp°Ë-«ÿÆB±¸Àç\$°R±L]·nÝêwÊº`”íJ—ëLW·[VÏõl_imª‹±vºеÃÂêsÃRú¿h9ÃÌï†UÁëå–577×G¯©|4´þ¢*ùG¬…°”~õz6¹T¹Î!1êå•e(…$+ÄtUº`mc9ya©<˜ºPw'Ïï,ć4æû-ºvåÖó!ÞèäÞKć|ÃâÒ¿ó¡+ށü¸_¹|ØÏǗKÖvç~è<–Ýùó—÷ö›žG<ï҇9>ô2–+¼Î_œåч•|Sî%‡Ôk'gù¨Wµֳ…Žek’ëö}^°†<yõò©Ë@~Üû=ÊÃz£ۣ7ž«ÅY»Àpۣ:˜SxžÂÚá·^|®t8HÙ^^o¾„ƒC_kgÖsæÚõ?^Ožöè
ޣvº`Uš{
ZŸ‡CW³ýzTغ>tʡ©Kí;Bƒ®Y}‹ôCWºŠkR}ák`°Ævqh³Ãd•íO…h_åiïà‘UÁX]joê’ÕkYÏW¸`=Ka ‡9çéQ¶žg>ìr˚LÌ÷òõ<Ÿ¿òðvR`u»­Wøz¶¿¤6ÕóÖ?†ۜÖÜ&«hoê"ָ> úvš9¡똞v:üêé»òÌ]Áør=–{‡o³B&cÇͺ7§úá¿OžéF½\貞T¹ay^à́çÐ%ë^÷°`YÏmv¹8#ú?r«KyK½ªÁZôð« uÊ€§8ðqº‰Y\tcÖ|4­÷Ê1(^<•n F¬|›°ê‚Yˆ?}‘>ËXÛ6AêÚé4¸(2ê݋BXG>»͚7Íèb£—)4‡ã±3Ôx.™ސ¬—Ê=iHS¨njŸv¡k9ôÁrÜ\V³zóZw±Ð~¬l¡ºT>T½ÁrU/b5¨ë,rèÄÚåÇÐÕäRWU>T9̺`m@×9æ?׫±ª\ø0ãg,{ò!X¾t9³vúe©9֥7vð>ïCWÚEߨÅYÂõªðߣàygֶ€zԼ׾!Üç+ƒ©ï½Î,=ª‘éz֥Ï	ú³²~Æg9F٣ªcћŒ4u٣ˆát¸‘iêMžöåygV%XÙC'Ó
†,kW@¬4X;ò°ž+Cû¨F#˜õ†S3¤ëœaøË||å­=ÒløY:³ªLí£
^G1Öö<¬j“¥ž2ü÷
¾×[ì@/£tk]ó‡Éó¾×XÚñ*ßÿw“U¨®—?OŸ¥û¹Ï^r~¡`\9|rž÷̪WyÁÓm;]¬1/ûcQTºXG¥՘ôu¾áÌzÆïùt¥]<tóXÙ×VVõb‡_¥¥ãñx« ™Læ^zé¥ÜSO=¥þU_ÛO…2p“¨µ¦¨ééé6?¬Ϻ2çX¥&‹tµøa}ܑiÁ^AQ¶ȣ€†ï‚Åt۱‚Òuò»õ*ϓÃXAyc³
«„åÐ+‘HœÿŸG&ÿ‘‡µ!@ÖÖìKlXe¬^A²ìt)¿`µúÍ!cmY¤^9–àXk5æ°<+­^뇥jÀX›òô,X¾rèàG ˷7T
À2à9‚¬7$û¼Õóx~,¿9Ìæѵ¬ù€sXfÇɡ½®"ޣˡ½çËØzCº–ò¾!ܣJKz|ñ~¤ç7ذʥæJá¾ÑÂëeÝ,?ÿîؚK—nëά«¥¸G)~c<h?´a›‡¶gõá":g€¨7lXåЕþ°-ã»G1V±
«ºҟtf.ø��
Œåw,·Zç/«.Ó[¯6¬‡¡+ó~ë|[€>\gÃ*ƒ.äз®…±ȟýA×<íÅö)VÏ<¾ÊۧÐÃ	_¬kcž½^Æïü¥Æ'ý)éÕÏÏ_»ˆõ´ík6¿,~o_9ð™ÆÅêÄç6øÚΙ9ô{FtŠXLW‘õðë>óubkÊ=òÈ#¹¢¢¢\ee¥ú÷ö×ÃÃöÀWÿ‘®gªýÀrIڈbá”2HÖ$Å–Ëßơ+=)Õ֔…µ’"TqjyޱV3Ö}Œu.Ö+_¤Ø}c÷[YAÖëؗ¬^ð†Ï	°x½V1V},U÷÷뇺è×±VqÏ]/•vXÌó²b±X=XÓ¶õRÞÐõ€…5ÉÆrºƑ7K$‡“ÐÂëeæ°)`֔¥^«™7‚®×$÷!4N±bº¼Þoçyz*âB,ª{3_`±%ãÃqõš€÷,=
}CÖó÷=¾T~x?ÔÔ7Ɛ7Û5€°çWšº”Wƒô| ¹ްö¨`ñkêÊaLé²\=ºöùDÇõ›±ÀÖ¬^÷1Ö}X憎"h”X0Öj°ÔzµAb,[tM0]’¬{Í{œ^úŒt	Ì_]1A]+-õŠAWÐkÑi«.3‡‡NŠè²z~Œ‚žb	¼^ãV]Üóså*
Þ7ƙ7‚ì“ÖÞ[ß>ص¦:
–e?Wòý²€®aùօ¿b:˽aYcO9§ü	{sú Ï,9\Éu	œ98ÔK”5&q…q??üªÝmv L&“ûõ¯{üñÇsÙlö6œ.ÊÌ=úè£êûêç¶2ý©fÂà‡P,º+«ņUVW,º¬¬Œµ¬ö@Yµ©6°êë X׫¬ƒŒõ‚P½Loa¬:°ڄXÜûáùV™Ê{CyÞI^8~òÆvƪ•ȡòšýaΒð¡êC6¬:!Ö°jx’ð±Zl9߸.x,>–Ÿ®—Åó"¬V°êlêÕ&äC–¾ñ%âmzT‹]{…úó†è¼̽Q#¼Þà9|Qƒ7΃õ‚FサØø’èQû°Ñë\—É*Þ¯xù£›M`	Œå:ÅAÔ➙6)2Ö~Åڰ/Õ)Õ78KX×aÆÚV»!Ó7ösîq’š¿ö1Ö^ԫː™—kmêôZ4dS¯½±,©ù‹³j(ÔެUh]g~Ñ’m#ւ€/p_c\¼ ÔÚÌ_Ö6u²s¥üžè“ócŸڬ7ö1–ęƒÝþ«+àýòyƲz£]ê<Ê<üZF1KaЅC‹9÷“Ÿü$÷ÕW_}G@$ÉýøÇ?V?·…]]¸®.Å,Ž`¥$Xt!ß01°Vá#š“¬K#C`%)î!†ŠAÖӵTŠuyô])Ôkr¨.h`™ºV0o,­k`>”öXºê•LÍýseò²ò¡™C°rA³ÒéôuUôŠ{%s¨ò¤òÖ*Þ7Äu!‡B¬!°’x׿.3‡j|IèÞ`,]³ЅÊz¬åÂÞ0à½Â>Ò=¾4×k¬»)âÂ,xžýPp|qÎhèQ|þÊIûÐê
Éõ–kJהP½¸çՓ0Ë1o—nf‡|hæp1–âÝmC­çDt!‡ÄP1C‘ë̊y¬ef/Þ\—Õ:ÛdхÐbýºî¦H€%£s
ó†ºT[҇÷2ÏÇrkaoØè’_ªYúÆÝ`åú†$篥æší,}šéàxV€órBx^NñùKü¼{ó¤ø¼Œu”䚍³$ë¥Æ+=eVÿù…kaÔ
ë^ÔKn¿¼Òê
Éó(uøõgÔ.FFFr>ø`nllŒ³ný³ŸýLýۧ¤ÚqÚöq¶‚Õ)bwNBŒõ¨&ÖVèËa½#Ätm«[‚Uüm½cºº„½ñ8g	ëz’å°SHW«
+,¤«ƒù𗒬pÿйšÿ­ÿ��…Ç2ìq֣z„Xm`=ÉúFH’]%`E„Y[5ԫ,ޣºD½–&þ›Fo”RlÖbºD{¯ÒÖc¬^!aŸSº%ë–ëj5u™>èÕÁÖÕnææ°GéáÁÃÅNJz¬-øø~é~øq63–d·g+XZêÅXºr(=§l5½±nO*,œÃǿѵWLW¬'uÕÞØ*ìù6]>äë÷ΕþÛSõ›Ì\îQ±õ|—4‹ïS¤ÇŸ—¥{”Æù{=ùzõK]û/i]êiMu(UZWœRMgOªï?ç»󠾾>÷«_ý*÷£ýèö¿¿ýíoÍàßW¯[ì>®s€½Mœ7%Yt@³
«Q‚Ew5u‚8oHéÂ}\fß!ÎkL—$ë/u½
–˜.ºs Y‹ëzWº^t¿A#Xoç(»ÛFr,¿#íX,fށ týºÎ±ÀRº^פKùðXMÂ,ñ¥üÍu	³L]ʯjÒõ–FÏK‹7x®z”Pq¯—pßຎkò×Õ$͢;,÷ÓÇÃ'Ç×7õ¢yå
ܣ#Þ{M–ºÃU˜õ&q^դëÏÄy÷9‰²P¯×qQ“ð¼|‚8ÇÁjԐãšêõ–éCŸ¦›…ÆWXÑì
Œe}¬Ÿ¤uôù7Ñ{¥=œ­E›$×6˜OŽéZðyY˜eÙë‰{ãcI×ëMMõz[zÝu%q¦£g 
]G™7DÏRÔáW˜õÚ<òyû±­[·æ>œ«¨¨Èm۶Íõµú¾ú¹zz½ݟ#öÖGœM¬~“5;;«CWøNÑÕs=ÛV¯t½z‡¿ÑuQ4‡ÐÅXÝZ¼]wŠûP/°:%uM¥#šª_»;qJZ—Ê}ŸFV?ó¡4«W³®°°®>°"ȡ]½LWŸ´%uá1úcéò!æ/mc¹KF—~o†~S—™ÃT*Õ/ä
S—š3»)úodŽAœ.Š\øXBºÀ
+V7X’=
,ZƒÈêâ¬Ð`V´GՍÊë«kPK½z4իåP¼šÞ˳."‡:X}7^ÿ æ½Ñúqyq]áy™Í)Z×6¬NMë(žCñ±–®õaä܉Ÿ9¨u]tñ—¦ÿó{¸cA]6a÷Q’ê1²óçÏoôsõ:ۏšL¥	l˜gp×GnaaA„5û-k–8	èŠJ°¦RF¬(q¦%s˜¸õ®)i]3s߰gJ’•ú–•”öáäŒeޘ„¥ë5‡z‰çãkŒé’öü(Ó%Z/io¨|¡ù¦t²¤}¨jVT—.pbšXqøPñ¥YfRjFuzC˜Å篨†Æ5隅7tèšÑè[{þ:vJ]Ԟ͊çpƼßf:eˆ׋8£Š•˜gMB—ִù)t‰[⬄©k<nD5zCzþš N,9ŒkªWÊôF,)^¯$¯—V–|ïa}^҇³qk6Mså´Æy9zé˜+g4®{g5®{õ¾RZö)ßÃ%j
pË
›™™Éýâ¿ȝ:uÊ:@9Ký\½N½ÞN÷Ìÿy%vF ¢,l˜'«‹¥UêeƝƚ—dßeëeܡžOßIõz°bf’bZG?TZäP–…ШËШk^£®…;T—¡‘•½³Ɨ~ÏãCirمœVF#+K¡Úr¸`haÍ+–¡Gׂb¥3u¹;Íó*pǍ/CW½º{¦º"“šú|ú¿],½ë^¾ד×uç±ú=Gé²<ùåÍúJDmm­Ìéq'ˆ"¬Äìwž“d%o}ÃRš’,þô;]–֕öƭùœɚåïhÈa\²^֧çtùPZò‹¿ۦÁSºƗ´çç³ÆÄßꇺÎuö£G	äÐá‰YVŠ"¡iN_üés¥Øü%ŸCÇ'õ$=o†ɚ”®"à7G&OmÚ?݄§ED½_îfÝ2ŸƊ&RÕÇÓXâõKÍi⽗8“L—$kN£7Rð†]	âÄð$‘xBu°gR“çoчID®Nt¥æÄuñ'èu°F5­f)Æ5±3¡i}ˆ}¥–5Îy™±Äû¼®z3-œC“5ÅuI{^ã>eÖrç—3¬¹¹9÷Ãþ0÷ôÓOÛ\îàè‘dÍÌÎõ~~þÚÅc'oþMX¿ÿHéëdñ»±,W<+2deÉç¬N¦K:‡®K>‡ò,ø0¢Ëó¬^Ҟ¿Èû†´7tõ
èê¾Sz/¿O9ó†õÎ/Mºz5Εýw‹׫K£»/]º¼LÍIçð+󎛖ËÙ~i]ü^'	¿_Œ8]¸kI:‡½ì®%Qt…5éêç÷:ióÆUxC–խ©^½êÕgÍaøšo@—´7.ޡóöÚXaMóXXGɳº…×l:}ØÇX=Z¼––u¯þµhº4îSäuY>íцøꫯrSSS®`üvøMþB,þ©m¯Jê:Õyë̃;fԓ0øä9ÿTDþ‰’,袐cñOÞg½¦)‡oçuAÿ´Ç7ø'ÑH°Ž~™në„Æz½ÅǗV–¼_E›%Xï5ßjxêXôô»_@ïЕ÷“ï…Y–_üÇà
-9©—ó§X6
±L]o‚¥e½AObí§?eNЧ›	°ì?©ððÉt“¤.°Ž³OR“eA×ø4:Éz稤.þI üÓ¥uñO¾“îQ&ž—Öõ*t‰÷(âœ'sJ÷¨wX¥u½M/×üßãÑÓýƒÓõbõÒ?½¹YË^OãœbùDuQ–å“ýÅׯkZðzI÷ù·¹ç…uIï+9ë/<‡ê��&M=НÙÞV‡_)ØիWCvŒýô§?͵µµcôsõ:ÛÆè÷¶öE©0«¬')¶€Õ)¥ë«K—³ô¤Ù/‰C!Ç*®IµcÃüt‰åpþT¬_çQIVIMª
,U¯­`u‰°X™®°P½:ÀzŒ{C¸^O0V·0ë1V¯pŸ`¬!o´ڰBX›%=_´/Õ
ú¡œç#¯™ØãҺ”ÀzŒåNá9ž×2Wrotçp«†¹²“׋þä÷ZÍß&?b…Ì’ï¥Pã@ª^í`=i²ÖîIõ
ûðqâ”0]Ҭ­·Y{Sݒ,Ôk‹b­ۓ
Kzºƒ.ñ¥t¡^¢žG½4yã	
ºڙ.°Äëõ¤™ÃMu©óÒã‹í‰z$Yèójš¿gûʰô^±:…½Á×؝Â9ä{½n
k€͚ÖQ|¯'Ý7¸7º¤{”†zµk\‹v1nմ>ܪ2½¡¿–áoc
zrÈòø{îç?ÿyî÷¿ÿ}îÝwßͽóÎ;ÖPßW?W¯»ýzJ§Ó×	²€ß/ÅrŠ$k–dAWJƒ®•w+],U“ýÿ9Zÿ/UIõ(örèa]Y…©³J×=R¬±…ëœ%é+£ßa)o,¥HæÐk•æz-5ïZԕ¤XŠzMIèê^‹{c†±¼ꥅ…zIxþâMxžGJŽå¹-uӧ‰±9œ‘ꇸv–±’zæ/â%>ÁBºÌÎ@ÓrSWjV¤^¦®eÿöÂÔróN5ÎEta^&Æ2Š
ƒú—¨7Ô܌ޘë¿!ÊZ	–]«˜.ÔKT×RŠ8r(Ò7àó‚9ä¬V¯¤0‹{>%ä!k½0–}˜RõâcÞÍááF¾ìÿêÊú¼Dg°¾¾K|Nç5îõV‚•Һ¯”_o¬Ҭk©†uT’¯4èâ9\ÐÀZæäÆ2֢¨—ðš-oÜ#é
žCMã+	MbãK՟euø¥¢Ž"788ø_ŽÔÞÿýÜC=”[³fMníڵÖPßW?¿ý:ëôû.à”í°â öãd/hÖy°^d¬:°º‚dá֪kXëjµÑU+ÁzúDòS<)ÂYuõ*۟:–7:f]ëc„ç[ƒd•Ö~Ã:ÈX5̇¬:žCèj	’Uòí“Xk—„7 ËêÐ%Å:"٣<Íf3¾ö‚
´^µ©6°j…{Ïá>ϷÉzêxò¤º×}Iל"ڣôϕ`aN¡º}ï‹×*ÊkãM4Î;`Y-`Õ)b/…ê)í†L½^`¬]j<Ùçù;ô‡k?žN	¬«٬cÕ!‡RžÁÊڰ¼!Ã:ÂX5`u	­£jm|ØfÈxã€ÕÔ+[¤ú¯</Ö7x…u⬮L^þ¨y줄çy"înáõ<ïó{KbŸrÐfÕ*åC–”k)¤÷°mvó²KÕßf¯w­£$¼ñ‚M[„Æ×A–Ž5Û!6¾Dæ/éz©šØäpcIô¨6g]Bž? º7G¹7LØ}ÑÅîâ0Cݒ¯þåow7@=@Ó? ଱€YgÁ£¸ßšbMYt­¤ˆÕKågÖjЉ€Y
ŠuðýÑÏhò·Ô+X]ÇϤÏb³<NñcÝV õÂKõ`M
ëâ¬ikÅ8»+À÷Š50]‹y¾!–ºû¬(Å*k<Hֱ/‘Cî
^/ä0`֔ÕAûP݋¼!Ƃ®³Ì+ë^ÖçöaÌZ/ޣ®×ÄÁ÷G8kuОoîK}y‰Þ%œ²Úa|I͕+ÿ¯§‡;Ÿžš5-æÆr%ÆîÕ	Ž? 8ˆû(&qçRSÀseO,q]“ìn¢@æJ>/[tÅÎáYæ
Ûªþd½àùVԼÓLÂ󌥸ã",ûzM˜ÞðájÆRžŒ	ùpœ{ž×kÿGs-A°p¯_#ƙðÌYzÝo²*ß¿®Aï•èQÖ9%ªi=¿,•g‘ñ%¼'âõz@Ó\9޼٭£ÆòÖõ¼®ý2_J̕Œµ
Zoç9àKếϕ“v9x|q`Ix#f9ßX)çy¬í=Ԛ­1ÏùƈDy½ȌRˆNÇãqL˜…E"‘8O€4`›Ààñ?›ŸžžnUdÃ*+M¯½ˠ(·a•A³o–ªÓUœG×|õºÀX¥6¬b蚇._¬æÐիôÞEZЬ³Ó”O…2ˆ‘Ɔy³
k£ËÎó‚ª×Éï²J%}]
cÖÃAåϺ2癮õy¼‘õ›ÃO:3-Þ(*‡¶ßfeÁÚ"٣>ïΜwÐU”ç?îøN‹óxÞw½¾èÎ43֖<õÊøËðᆽñ–îށ¢ÅÆWOߕÉúÞùó~X7&RͶs%¥žwl
¼3Ož
²ϗs¢ù͒geÃc£É"ÉÚbÃ*+M½3ˆy9Ëë†5‡iªW0ë
èCk£
«¬ìm™ÖY¿´aa¾ÉÂó~ë•ɓÃS×GÁz~³
«¬t/ËãìÙH:PÏ[Y¿¨J®;~ê†Ҟ
xï`eñ>ŸհOYÇX­Õˠ(±a­ÇÏ2ôÚ@û†ÃúP+à}ÊF0tìa×-²Þ0˜7tä0pó®Ef•Ø×Ë?÷A5óޛ'‡Ø‰Ök=XY
ž_`½ZêUÆu4§¨•µÖd©}¥DŸ·«Mƒ°“DׁӼ³T
]<gŠ£ÓØs¬g˜®³²êkgVXiÒÕX «±*ó°v‚•!Vƒ]ó`Uåaíb¬F¿¬Hÿ•|9¬‡‡þ>r‹è]Œ¸çéé…scî*ðëyz¢@±æjΧËËø–•ˍ7²ȡg½ËŽåp;Åb¬*“5>>Þ\HÁʚ9tZ§¤‹>%­Ñe½ž)x|EOÔ#‡N¬]~¼'¾Î2V¾±\åÇxjî,ϡVæ‹Pê´!ÄR~	E*®Nt«×Òø/È>N7ѧ&Փ]|þâÄNh/˜uýæäYÖçwÙqÕ`eiœ4Î_ŒUmÇAl+sèӴŸ9%ã‚UeæPõµBXj¬°yù9I–umN^=VÀ »Øe²T_3
Ôå’UV–<ïǎ,îù<ïǎ¬f߬Ÿ;ãËάÊ5Չ­µ”‹B=ßDŒ¬‹¯72`Ó7ìc»…å»^nև˜—%uUøZ‹¢G1ֳNk°êع]o4úð¡|½ôïa¼êËoŸßå¼ÿ˿7ªœYò>äûe
çAô(}#z	œ9ˆ=—‡µç0];8Ã
û¾iÜ5¡KÃ.ºÐëúéõ=
‚x¿Ûøc…éB²>'.Ië£;:«ډ…‰À«‡XýnXêÿ‰t…½è‚
ÜQ‚.W,®‹7
'ãƒÕ
]nrØK¬.pO,ÔKռÀzUbT/v°z]„=³öü¿±§X߇vƒåÐm½ú(ëö$ÚÍ"ºž+¤^ƒãÙ^ºW#ށˆ“+ùXv««çz¶Ïd!v{a)_¹õ]^«tu1]lAí0‰a|yÐE÷»ô0]UJ…Ûö˭®>ºk.ÄX»\xc»×–µ^Õ.êUÅrèz,‡¯gûIW'8†K]4u}r~ìtøZֵ7ˆÕÅtít¡kû«ŸÜlV^¢ZG<°úL]ˆÊEXvٜúÿŒ-¸òaïðw½ñóÉ6sŠíaXnYêu*ꠎþd(“琍Çs&‹|ÕÝí2‡}ÃYš+¿žS{˜®E7è&KMò——ù+ÄX»½°P/×ó2clqè–R5÷¬Ëù@Ž¦.ò²g]ˆ]à8±¼ë¼la}߁UÉ|öR/ëZÔ«Š{~fvÎK¹ç+œX虿Õua^öµ>ÌÇêêÀzÃÇZÔú·@V?±Âֱìv®TùÇ\YH½Ð{çJ¯ó2tuyԵï<êêf=j'n×Q]Xc»_krˆ,‡}¾<ïœÝ,‡aO>ô¾¯ü¯—ð¾r‡u}X`Ÿ¯t㍀X»\{>¤¹“7<ú°‚÷
ïgÞsÈ÷•rõ²öCï,~àq_éú@y‰±*\žÛä
¬ú¡ý!ÛbÀbŠ	@
دž² æÉf³Qº ©þ¥¯{èûMª™Aî:À#sîâaŠ›ŒV§—&Ë0Œd&“Q¬}¿X]Œ£(÷ÀZO1ba5(Véj´, &=²ÖQŒƒ•¸¤r˜J¥zçççcŠeæº"Ðe²ֹe¡^1¦«×̡҃zñ†Mê\ê‘5Á”lX=6¬˜|³zÃ̡…UO¬nÎbƵb«ÇâÃËá9>ù7u^
ÿ÷3%XëÀrªWXáƎÁëx
k‚¢,·��Àjd,>¾·œia“å`yö†u|™¬qùzңA]jLƒÝñµFq^êeüÕ+–4¢¡Ál½›_¯.¡f¬(E)c¹÷!cÍzÍÌ-DçæsÉÉb]ÍöÔ~4״~oª‡±b`¹Íá«®¾«ÓgÚ²ÅH¥äx܈vÐ×u§IW7X…Ôk­٣蓭Ҵéíû`®¹år62:mDg‰¥˜Šuð“ô9ÒÕgñF‘Özbܠƒž+æ¥à‡è)‹ö+وª“ҥþU,õý
êRº‰Q„¼çTP=z÷S]Kånf¬9t¨—ݟMM€e(]ÊÛmÄ™"]Ä›Ϋ«¬¼Ä:“…ö¨ºÀ¤ë[oøº^V¯ØηÇ׹á ÖSŒ™ºÔïzáSb‘®hòkoL!‡J/r˜£»ØÎaþÚ膃(6Y<‡jì*=¦ç•ÎÚçšöÿ}òëócÅY¼^=ô;áo=O‡¦æÚ&bYÛ<âƒխt©>¡s™\"Y˜`óW—uþ²p<³:‰O-LØÌËݖõF©÷|ÌZ¯xò–Ùçù:ªÉŠB—+ÆbÔd©Úc-Êç/Û5úh¹ÖŠÑÍuӍèó|-j·Žêa,xÞ«æ½чmæåz¥c‘5_ÈOQ”¸ea®œdsJϡƒ7b×óEL—]ƒ\c—ذòԋë§(öÈâk›¾Åö)*·ªž®÷¡+²È;Â<°š¹.ÅRknæC£ za}˜g¯—Pëz»}
XeXÿJ1jç
žCÚL÷¨'l +Ç÷°>rا¼§GE+æQW‘Ç}J¥÷yÙÃ:xž³¬9œ( ‡ÜÝÖz)o�9ſæ/ÏõBïã½×ÜóX¯µ–¾Ñg9ßHX÷æ>Îàyûsëù†M*öqæНG—µŽò5|ÀUøĮ N‘ÄëWà%Vâ“’.Y	Šý²VPìu«¦ØçƒUíA×4Þ-¿·ÖjõJª¬*˜߭7öû`yõF]¬{፸‡zíµ\ìÅóÕêÿ߯Ğ!†grQë†õ«§Îâ#Å÷S¬f¬À|X÷·Ñ¶)ORÔq‹îjšfÆbºXšÃGžO„0FÂF——¾Qiúð™ÑÓvËAÔn?õ¢C‹/–zc)íÛޘX…§ÒX{½°LíÈE
jîÈB½j‹‡Óa‡ҵσ®8E…ÓXæ˅à{(â.YSÈÃjžÃZ9ŒíIl‡§Üs žtâÐ
×.]ŽáÝòU°V»¨—Ñ0f(ê
ԵÆ=mÇ9òáH£Ëùg]Vo”×ƛó̕µ`¹çpo ‡“j²à°ðꢈª7\Î˻ÑG½²Vüãµ?º]@W]ºøÚfÒ%+ò¿`ž¯-µ
ë¢i·,Ÿºž÷¨«NËÞc٧®˜[^¿B§7|ìS’ºXtMQT	Œ/	îö0¾’x½ϻfőóUê•ËϾ2®Á+±¯{¬×J9ôäBÏ kÒ5ûeMިÍçC7Х¸$ì5ŠŠ(ŒÅ×'pÁÜR^Y7a˜ë(ŽƒuO¬{ðNÝqÆJ@WH± û® tÕFB1‘×ñʒXKp2ý
ê3‚Ž‚}?"‡w«¢^­¨ÓNiÛðýM{ã~÷cu2o,ˆUŠ\µãä>Žzu¢^ƒ¬—ՇÐÕÁ=ï°)÷4¾ kºn˜¬÷뇊‰±4 VÅ蚀®맚¯ý¯Ql¦X†5¼²62]Qºçä&ž&éd¬¥³:è)£nl£`§xºüæðŸ(Öo©›ÞMŒvŠQëÅŠ»ý°ðú¥¸„üEH1:ÖË›(–2¾þn<Ñq¬	Šþ
AW™U—7—Ëq׵	h£Ð8¾>ž×úÝ[†]ۡg
º:k™œ|qrtTé€×ã¨W‡ªê¹Ďãq£¾9z…éJ"‡íÈm9Å=ŽOÌ9Çè:¢t@OukE78uC±Üøͱ^ðF+qx¿ý½3CûØzÃ?>äި~wìcô^s®\æƒý±	>ìø͑ÉO°ŽZç?®kÓþé}l^N€Õ$ë÷¯O܍§Z^ÄzcÈ2½Œ¹t‰_rSŠõ_Œ€õ
Ey@ëÃ%ø]G:Ö8دµ,ˆu/[G5S²õ|»­ë¨6äpZhͦ¼Q
¿…+V9^„®ð['êÅ<hïâ{"6¾ÆØz¾
lŸV,¾×ۢ<$°×³ö(°–åyäªû”8ïQBº:Ø{˜éÚ «Œí+'Ø>=
½7¸Å=?eî+ÑOʂܛãw^àûJ‰ÖQ˾r_³ù+V	ÛWŽšs
rú*t6§ð³>–Åzö•þ	9\°7ÎÜu¢ԍ®ÿÂH)çbq›IEND®B`‚‰PNG


IHDRÔôUŽIDATxc 
£ ôb0+Wñ þ¢¡|VZX–²Šÿ ±1­,T‡²5€x/ÔÂ^z­Բ×t‰KXpRà m ¾2Œ†ªӦIJk ƒHÀ×èDµC×2 ¿ˆ?ƒhzXö*þ™^>ûBŠÏFÈ%óÙuJK+DZt\‚	0
F8Ô*¯ß½IEND®B`‚‰PNG


IHDRÔôUŽIDATxc 
£ ña<+Wñ þ¢¡|VZX–²Šÿ ±1­,T‡²5€x/ÔÂ^z­Բ×t‰KXpRà m ¾2Œ†ªӦIJk ƒHÀ×èDµC×2 ¿ˆ?ƒhzXö*þ™^>ûBŠÏFÈ%óÙuJK+DZt\‚	0
FÅ"(WjkIEND®B`‚‰PNG


IHDRÔôUŽIDATxc 
£À÷ +Wñ þ¢¡|VZX–²Šÿ ±1­,T‡²5€x/ÔÂ^z­Բ×t‰KXpRà m ¾2Œ†ªӦIJk ƒHÀ×èDµC×2 ¿ˆ?ƒhzXö*þ™^>ûBŠÏFÈ%óÙuJK+DZt\‚	0
FŠjþ.-‹ˆÕIEND®B`‚‰PNG


IHDRVΎW´IDATxµÔ1
Â0‡ñl֞ÁÍQEíQ­Ö<Š‚W°”:{B&~C‡ÇKÓhà·døøg‰ùë¹O¦lQâѺ"ÅFÓ2X¸/ÞØ`¤C2r‚ëé(c2”ÃyJuhÙñÓr,æ2”Áù„„T†ª€P)CM@èù«P#C5Ü@•‹v2”Y¬dÈàç)‡ѡÈc’âË,
D0:¤%(pëUcuÇ7î<õwh¼;IEND®B`‚‰PNG


IHDR¹åi,IDATx^͔¯JQGÏ]Á	&ƒ ÍfôŸbÁâƒÉ`Õ.cÁ"6ñ,öEA°¹É`’u—ù{?ùÁ–•»² >¾áwœ™1-ZL‘€ãí e”ÎÑÅýùD2‰ö÷I’ ^_ž¸¾ºMx™ªWVé=> œóˆ–ÏX^ZPµ!"ªU–î´Á3¬m…}xY¼÷8=¹TµÆ5e˜ÎW€á̃Æûð\ã|v5"{þá›y@²†Iª¡öa$¬O³¬.%R4%„2òÏY-Y•° R!ª4Èú2ª
(ûß5h0ÈâÊPY•Aèï®ÓG÷Žù¹YbæåXYç즛2!ë[mF03ì÷Е	÷ïþg_‡‰õîÞ6zûIEND®B`‚‰PNG


IHDR¹åiEIDATx^͔=KÄ@†ßًžøY]!(ZV‚à°ÓÊÖF¯´Ñö
m,-¹k[ÿ„¥•¥V–b!Eâ]4ÙqvÂBÈqˆC†g²Ïì’ì3cPa0ÀªŽvW÷m§ٺ¸îT’9ÑæÖæ—´ˆ¢Hyvrêt‚
Ý13=…øå÷7Z3ecvAçeìpp¸ƒáÆ4ˆܣ„B¨C’°¼ï·ÚÞmòÓ‚ÉQh˜@¬ÌÆ0F©	› äġB*$7A’ibka™¬û–±>X˜DŔ~©"åŸUS½DfÓ_éÈ.vÒ\&RÓU3q…Ÿ¶÷žÉm¢$=É.¿
?ÁÖV<q$`€m.Υ©ÈRþ£ãôK×çÐ#áÿÖ/[Y߯ùÕ%úˆ&˜¹}‡w›ô/î³o±yU/A²IEND®B`‚‰PNG


IHDRµú7ê:IDATxcøOÒOA9:ü_ŽWÁDQ€)iÂTiTpa„4à«„n¬
žÃT0ðqÃlîg€ƒ¯IEND®B`‚‰PNG


IHDR…l$[IDATxc¨ú_ł Æã?‚ñÆ@¨ë­hI;’ÆêIEND®B`‚‰PNG


IHDR	=Zà/IDATxc`°døÀð_1h1\ð-ƒƒ?irU£6r8Ñ:WIEND®B`‚‰PNG


IHDRnvZIDATx^-ȱ	€0á„ìaë*Î Ø;A\Â6•èBœå��pÕ}bà¤CV ы•ÂcÈf!£›Ï6"ÑÈZP…@v¸ÚFöJâõrJbò­mŒ?TNø¤ÐwIEND®B`‚‰PNG


IHDRóÿaðIDATxڥ’I
Â@E=ˆ8‘ ¸ÜxvÑ؉qHô”â5Q4H@Ä+”¿ Wڭ‹ßԢÿ£†Ÿ#¢¿¤ôÉjwLÈø	гºµÑ`xƒԆ ou뎰Sߛˉ½2æÌ÷¹ô)^­i.Îw\PÀÜt…ýý€6ëˆ×@ʲÒ`nÁü|3'èÂP¾Ϝ™Y)ÌU­3bY6o£˜–á";Ž©SÏà™3`,S+Hh»È"ÔäÁ0•¤Àù„ŸO"§ÂAÚiG÷/pDŽR^ž—g)ì@_/‘¦
ÌË5>IEND®B`‚‰PNG


IHDRµú7ê¤IDATx^…‘M
Â0…=H¨?$(nlBɴ˜)e¼·x
¡Xl‚H¯0jÁ]¦2Ëï[¼÷fÁ.r“ëÁîŠG­·‡!p`I
îϚ‰›®Ê‚sðúbêqÈàÆ	GÔÉ0Lx¨·BÍp%>qK#GMýGà2:#…º×ì£5ÂP¸¢î§Cá’nÄÈþ,NµM[©™gT"ƒtoŒ/÷Z’á)VIEND®B`‚‰PNG


IHDRµú7ê˜IDATx^…ÑA
Â@PÑ4!™”)ŠM·¯!‹d@Ä+ÄZp—T²üo‘ülìÏ8 雼`×>Ú9°ÇÊƆÀŸbji$vñõuuv€¾—¸Hv¯:ÄU¶Y|Uë,ê#ušQ>(J:½«‰áL‚¢$éø#AQ"z[È9¬ZX‡4­<‹‰ÉÙ!š”ÂïâÑIEND®B`‚‰PNG


IHDRµú7êxIDATx^¥‘±
!‰ j„oc:»àp-8xG˜ˆÕë$ے5á,ZÂüÂo"c,ŒJ$p2)hd$w,:IBÙA l¥H0¦“ðÒyÝÀu|Åp[pE±ª„DwO|>
Õɸ©Nž‹“CSÿÿ›o]úKߟDeIEND®B`‚‰PNG


IHDRµú7êxIDATx^¥‘1B!©à\g®ó¿ς…VHC6B¢&fʝÇ&‹_øM`‚'cô‰‘ñ8ބHe*	øABZn²”$Á'˜„§îõM8*úV!á¬HŠ¥%cãFø4T#rL]¸¸O.Цþÿ7_ւøü†R!+IEND®B`‚‰PNG


IHDRµú7êxIDATx^¥‘1à ¯‚GÐÍÿÀϼ…É[œ©+ë¤$R4å,Zl|á7	‰†sNœF¸	…ƒ!8(H ­Xt²„ºÖR%8#‚Kxé¼nັâKU±š„LO|?
Õ)„©7vž“MSÿÿ›oÕåܵzøIEND®B`‚‰PNG


IHDR(-SPLTEÿÿÿa^_[XYOMNQOPifgA*‹útRNS@æØfIDATxc 0³@3T€‰
˜ Œ¬PÀ8„M‰º–™Š¶IEND®B`‚‰PNG


IHDRµú7êCIDATx^¥Î1
 CQï†âØ%›Œc°¥È_ÿðõ†à,Åy'QÊsW	üG^xOƒáõ>ÃS†§¯aØ&€:&ž8o·IEND®B`‚‰PNG


IHDRµú7êZIDATx^…Ž1
1Ãü£RB¦Yîÿ_ò
R¦hB÷°Á‚—(¶P·h~BK-èR ü7Ön/Fð{9‚Û+LÁîæÁî
„Û;‚Ý;üL
¾a^þxéIEND®B`‚‰PNG


IHDRµú7êAIDATx^¥Î1
 CQÏ!”‚÷¿c2µJ$È_ÿðyÃÄQ½ي:$V+ñ<‚ÇAðƒLð˜à±+Ï2lJë	œ!ÃqIEND®B`‚‰PNG


IHDRµAåZRIDATx^¥ÏÑ	À0Q7p×۰BºTšRÛþ„û|"*ã§m¤a(2SŒ–ñ`è,XFÅ/Ž5”ñæEHÅøÂE¿­µç ¯õôJOXÚÄž¢òf…/IEND®B`‚‰PNG


IHDRµAåZIDATx^…A‚@E{ä&CÉx	<É;&Ï ^d@蜴b7æíúÚä÷FAÏȒè(ljª%±9&Z•ªVž•¬…
ѮID½.…NGG„@Ê„¨³^lŸJu°%•£°°9ýQÊÓËð#ïÂàT rúºŠß@•Tê+µ…Ú^ùSB†³WÌVŸ/þƋÎ{ñoǙÍN8-ð›IEND®B`‚‰PNG


IHDRµAåZIDATx^}ÐA‚@…á¹ɐ@2^ðŸŽg/è] “—Á4.ÌÛõk“¶†BAÏȚ2ÐQ ªˆ–‰·ËL+mŸÄƁ9ACÌÓ‘FӥѩtÄL)#ªÖCî¯Ä5	GcfÞIyz?x7GÊñu_(~ªüB¥N©ý)Ôù”ÿOHáÄ≽Ï?þƋÎûã?Aݖ­ŸQDIEND®B`‚‰PNG


IHDRµAåZRIDATx^¥ÏÑ	À0Q7p×۰BºTšRÛþ„û|"*ã§m¤a(2SŒ–ñ`è,XFÅ/Ž5”ñæEHÅøÂE¿­µç ¯õôJOXÚÄž¢òf…/IEND®B`‚‰PNG


IHDRµAåZIDATx^…A‚@E{ä&CÉx	<É;&Ï ^d@蜴b7æíúÚä÷FAÏȒè(ljª%±9&Z•ªVž•¬…
ѮID½.…NGG„@Ê„¨³^lŸJu°%•£°°9ýQÊÓËð#ïÂàT rúºŠß@•Tê+µ…Ú^ùSB†³WÌVŸ/þƋÎ{ñoǙÍN8-ð›IEND®B`‚‰PNG


IHDRµAåZIDATx^}ÐA‚@…á¹ɐ@2^ðŸŽg/è] “—Á4.ÌÛõk“¶†BAÏȚ2ÐQ ªˆ–‰·ËL+mŸÄƁ9ACÌÓ‘FӥѩtÄL)#ªÖCî¯Ä5	GcfÞIyz?x7GÊñu_(~ªüB¥N©ý)Ôù”ÿOHáÄ≽Ï?þƋÎûã?Aݖ­ŸQDIEND®B`‚‰PNG


IHDRµú7êúIDATxڅÊ?NÃ0Åq#31`îPN‚0ä¿eRË&Máì$:!&ÄJÅÆĀ»°#ñpÔ&úô–'}¾ƒÉ{Yw?ؑõÑòW*H±âh¡¡®„ɣý¶HîÞr{£xÏò2…A…²ÉGR¬Xs°Ž÷f¨3JDÒòCË}Ü:œa֘ÝL¤‹	J˜g0è¦"ì?Ž	Ìû”ð¹ŸEH]N(û9D$ð‹EZ¯¹¶Ip(bÊ~§ˆ/Æë Q]Pö›B#üëÙÍû;ð詀ŸxÎÞ²å [úÃ^ëM0ì›óšþÙ<{üâiž0IEND®B`‚‰PNG


IHDRµú7êíIDATx^…Ê1NÅ ÆqLÄ;< E ”G±ø7Ïà%Ü=Œ&:'㌩qsr0ю]ÜMü„à#TóM_~‚ÙêÛzX?¶Ã>ý
ô‡§‰ţ>/Ë{÷å oXy	wÙV™ù™‚…G?꧉M²f¯áûÑ.U‘ï"ç@];îv›À=º'"0£/؇ØbŸ}+yæ ÊؒçAš¤jHœƒí"¨©Lœwyº·ñ0*†eâ¼â$³»rÈßV‰‡È&póڢE3;վwf3žfeŸí‹>šøgß:"ôûUIEND®B`‚‰PNG


IHDRóÿaÚIDATxڥ“K/Q†Œ•…ñXhU/´3Óji«¥eá7øöþ†û­QEP	×L•Ä=‚„.mì%>ï'UF§+‹79™sž÷{¿ïœD$FÜÍ÷4‹9ͺ	éŠŰ7©X’Z‹½V5(¶ºœo¹.'á ü^êhÍï†\„½D…Á*O)–¿ýè4êù(D=„u)¤ox?ÜFØKm`T^Ø騻nâ*]ô*ÅÍNG#§ø
#”öÙDÙ`pB³†9òY‡îâÝÆÕâq¤½q5`—³~ûŒD¹½Œ9ý žÀÁLð}ŸÆœˆ»i=àñ=ˆD—½
á[I÷cÀÕœ‹ˆm
ów6F"Jym<T£|·E ïçë˜j
?ô{YÜ?-úlòèß'`
?–Ä-.v˜L«V}eü­ë¸Ҡ¾€¯pFµÊ0¨
³Îa€3Cb
8Ã-ð=ëáê0ë*¦Z¥Ÿí̗AÆ=óHCî[˜IºŠ̉†%ôtRzaé½P›„—(6:OxªÄÂúuóAղx蜀u;A×K>êN"Zmº´	(‚k½‚îñ”c³¨föÓqÿÒ'ìϼɑ²l¼IEND®B`‚‰PNG


IHDRóÿaœIDATx^•“ONÂ`ŋK6,¸{7$¬IJ©¥ZÊÿz4zÖÆwÆs@<!ìÄ%›q~Lƒ–Äń—yïÍÐï}Ÿ!"–cۋªSJñK’.q@«á-û®PŠWgXf)g™f\6KÙk׽녝ýÍx"˜´xmYשl«÷Ãuœ§š[ݴ[¾Dƒ¡ÜN¦XèaA‹¯¡“ça°E:퐿,ãáˆ͘w˜´xð¾×|‹†i4>þ®ukqÐí¥(0½¸^£åy£þàñ°ô»½ËÓTèaA«ž¼Fè…É(‚„xOJ
ڶäRðêõ¼’L&¶ÄphЪ§pL!åÕê³ØÑD~}=¸؀{¼†޴Wý;û%뫲]ԼS˜\ì/‡8‡89Di6<bÚQ`z'‡(x‰1£‘lµù©‚g%7¹<!Æ,phÐâÁûBäôr¤qeõÒܩhÏ6
¬½™žA
Z<g“n]Ʈò꿯‘-‹ØcJ|Î_1¯òú¶hIEND®B`‚‰PNG


IHDRµú7ê+IDATxÚ]QAnÂ0L8æ’C>‘c6åÔxqò/¨ÚpFýê
ñ*ÞE¹5s™®­ZÙҎf43Ú“ò¯GlBPgõýDÈÒ,â?‘[388˜An³„‘(K™0E'Ä~Ùj*‚Ʋ{F»yÈ]	ƒW~Äꪯzº#%ä.P'‚»MCõ*\…T»æ†Ô)P3ûÁJï½øf7ľ«¯Z¯yµ—ÇìöRa
]Œ-ŠÂzý„`.¬G¡}‹ðe3 ÿ-äÂ`$¼ÍÃ@5دM^gaæuÑXŒÇ@í,î!¡ {Ù+˜;b¡¸fL»ºO×úZ+ž±vËȕ:³c™šˆc%´uCå•mLÂHT¦OǢ³'ÐôX“r‡ñX“sÿۨü¢öWïIEND®B`‚‰PNG


IHDRµú7êIDATx^uQ;nA¡¤Ùb›ù{fªíi¨÷^%Øq”qgX­¶)·qì!D€Yé=¿‘ýl¡÷
êÏGîIàN€€îü"PšÓ[Û
L3Âd7ª&f®èʌæËlíà1""z´ƒÙ;êJØ.  gâò•3%m'ü‘%û؂ÛÔÿ2èÂÏâG.w7°H·fï~F0¬ÆˣŸxá/aY\¸%O AD·bҭ‹Í_³,‚7-…9L7ØëVI%uëúˆ¥šƒðƒ›5‡öj¯Ž-ß7B6«4æï´ËC"("•	íˆ}Å. UC6¹¬:Oi
51óм+žŠûó¿ׄ=àéÜ?ˆç©ͤÞwIEND®B`‚‰PNG


IHDR
_ò#’@¸IDATx^íÝ{tUå™Çñ}B@ˆá&"hEۂ(¶RDÔz錗zcl½NDQ‹W4ÖË8RZtµŠUªvR¡êˆŽT¼ ‹(SPKQQŠ\+	AHòÌ÷t-ÖY'9ϻÏ~ÏÞIžßZŸ?Mp¿ïþåœ}yß@DԌ1ÆBBc¥aŒ±Ò0Ƙ¼å´q;Zc0Fa^Áûø;*±ÛP‰O°“QŽ!èÄ‹Å""ދ¢cð*vArô!Æ)HM?‹•'sÃ|ÔA<Yƒ{qP X,Ç=wa9îÍâ’_œ¼íq6Aò¨T+m,f¶ØÒàd-À5¨„Ĩw¢uC,+
]aÄ{Y‰AÇX,VîeÑ
cQI ”û¼Xj±Xièã@¼if¡]à!‹•†®0úb-¤	Y†ƒc±Xiè¯_lƒä¨ËPŸã
\€Óp>.Ãh<Šױ’£ÿ"ŠÅb¥¡/Œªïl<‡!èâúÉ`<€GåñچÅb¥Á	wT…±	å(èYBÁ_X‹•'\7¬ùÉân´õôxz
—`C¼…a±Xi¤-Xq´‡çé%¸ý19…a±Xiü
âè~´
ò~çO±;¦°X¬48éŽG­ã‘AŒá÷Ÿˆûó\‹•']V:ƥA‹Åb¥qÄÁõA‹ŠÅb¥‘þzûVˆÒï‚‹ÅJãvˆÒ
´	Zf,+
 ›®c´èX,VÙ×—X,V¯:<íÙ5h¹±X¬4(ƒž˘8ÇòÅéŠÑ…AÌÞ׊JPxŒÇW: ¨¥•Fý|kë«4†B”Ž‹•C{œƒ0kPÙÇn¬ÄK¸'£(!åpF K°’f+– #Ð;!Ñ	ã÷X‚¯2|J^Žɸû7‡Ò`îôÀPL»ØÙG-Ö`6î ¤r-©…¥A¦XQ¤p&^@5$„/ð8úÅPûã&,ƒ„´· 4†²8/`ÄÁNü7Mûy嘟ÅÐ8KƒyR€‹ñê Ž>Åíh¶46Cn	Òc…q>€Dh6ŽÉÓWŽq¨‚Dd;~‰’<”Åñ˜ÉÑ܋¢úŸ[Éâ޸Jƒ¹ñoX
‰ÀV\ƒuið?ߢÔ?øg¬,Å\ˆ'µ˜ˆvž
ãBl„x²	?ñTm1ÑÃf\Ð%©¥Á\èŠ?A<˜ÚÒ8¢°
´‘¥¾é·Aòà#aY´S<y
m#,Œ#ðē¿`NÒJ£þ:ÄFˆG›ð=Miü¢°8 Æm<ێ3"(ŒNXɳÅèAaÀˆoI*
Æþ,ì‚äAf+ß@&{þ~ÚÄd rðî…ÄdÎΡ0Jñ>$& Cóã8TAZRiÔßYû’GUèÓXiü¢p_®€KLÞUÞõ˜í …QŒ·!1û3ŠC̍ðҒJƒ±îm¬AdžJãYˆ˜f\_*¾Oð9^ÄÃø&b6*!!¬GÇҘ	¡K1ԛŒ¥¨„ð¸ã¼(ÆÿAB؂ÿÅ#‡Gñ*ª’^Œqރ8ڋ×1Ã1c0›!¦7T3!
£›mií¼vXqPßâè,÷ÙOÇLˆ£™…q.ÄÑjŒB§F~nGŒÂjˆ£óæŃux'!ÕÀÏ,¹X”àÒø9ÄÁ܇³̹°
¢tQ¦ҘQ¸©™—F·ô¯ ,ĕñUç*
c?¬…(}ƒÛÐʡ”Za¾(}ŽvŠ9qj JÃ@Çyw9¶ÇQYžðÜQš‹ó­
žvøšRœ^“´©™—F¯·{ J÷!•Ããç/C”V¢ Ë	]Qڂ9\h=[ JåŠ9ñº㾽%!ç^_lLPi<Qz…!Ÿb~	¢0&½4&@&6óÒè—áÀ>QRmý¨ø;¢tq#'q[ü¢P…£#¸¥ÛÛ 
[Ñ.ËӞ¢4­sœGãë¸Kƒ1-uø”ñ¤r˜oݕ×ê6 õ¾¥qDáõf^=Óh[l‡(̈ð9|
Q˜ßÈ	|9Dé¼;¢te#óá9ˆÂ:tŒh^ž€ÒQø+ڄœcp3>(]¶oiœQXßÌK㠴{©Ã=í®?@v:D¡e
œ¼s!
ÏxxD}
Da^s¡Õ…s"ž‡oÄ\s 
§†˜W09äƒb÷-# J==ï[²̓]…â´<¢pwà!ïµ\“á¤m=,jÐÓCi”¡FùûÛg˜Cz˜‡'ÇUŒe1vC²Xì0öÃ0¼ÉQŸ–F+ì„(m‚‹°Ü
Éâ‹{“òžxO¥ñ#ˆÂNÚ3!
3<¾A;¢pV†1{¢à노•1•Æ`ˆÂHÅü9¡’£¯ñ;”íûjü+…YM°4žѼ¤”ᖗ(ÌóøŽKª4·Ä2œ°wA.÷XAîÉ0fjÖÂð¸Áø¸˜Jã:ˆBÏæL+Á<HÞÇ(”¤­§á´AÒ^tib¥ñ)$‹©iÿTˆByà1ÊנkQœvÂþ¢ÐÍcit…(LI¯Bì‰óÂ<?û¬˜JãAH_eøïÂ=XÉÑ7˜Š³-ÂÓ¢t[Ð$â´Vȭiƒp…ú+q°¬wÚ	û&$‹/ÏQ>·±0ḿ(<äqޔÅTÓ Y|°Ïs§böBrônÇ.«‘/‡(lB›&R£ 
§¥
Þ
?{¿¸ÿ;ú§¬Ë!Y¬|FÿïXžáy	Q¸Ùã¼)ˆ¡4´Ÿ,Wa4VF´ÐÓË8a¶0
Qº¡‰”ÆH»ÒK°¾qEáHϥ1¢ퟏ�õ#H‹òPó!Y|–6fƒ!
Ã=ϝ1”Æ|Hüãph®ûžtqX˜µ
‰ŒóW®ÙïFõ_xqÿ»¡þÂ{Žr¡âiãÖ?!/PJ¥1âÑ[¸­£ÜËõqˆҴ ‰q¢ðÚƒ7¢p¦çÒæ'âH›óP4«z¥[oˆÂXs§sL¥ñ‚§UßA__@—9.?2¡…1¢°3޿Bnö\/Bڥ¬ÏB:y,ŒRˆÂóic·DaºÏùSi<‰ÈrŒD;›%¥°‰¥jNXa´Ç*ˆ³
œ¬=!
/y,Œld±.Ã	û_êu-ãa±Æp-$‹ÍHyšC7'ê9
½ÝxZ±º[ä¥Ñ•¥J|'!…Qˆ J'6rÂV*Û)ñT'Cfe8a/€(LñX…gÇ…“<ͣ7b*ã!!¬ƭP,Þì¡4œ·i¶à»	(Œ§ J󳜴3 
?óTϫ¿"e^u¼’E5ºz(Œ.¨†dQ‡NÆòzˆÂ=̣ÃQSi´Â‡ۥ3q
bØ5>ã[qP…³b*Œv˜q0 ËI{Da#J".Œc¶Úûv!	?â¡4&@–40ž½ 
5èñ\z2ַ\õ¬žòð‡êp¤r).Øq4Ey,Œ#ð>ÄSŠXŠÝ…Ç"¸ÖXQx·‘wD¡'DXÇ;,:|m#ãúDámF¸Ícm̥qD¡ý#œwG 
sQ¦+Ìq ¾8ú'y.‹V¸» >G偬€(
‹hðž„(]åîÅvˆÂzAaôÀ:ˆÂtjd|/(Mˆè6ëg	X„§
6;ì¾W\;¥ݦ½
)Ei(Oo&¾ïáߟ`Uȍ~;Ì>¨søŽyEWˆ‰Ž[#´Îrw\üÐ×Ðø¢4^1Ϋ!J÷#rNuÄ;	Z#ôˆÒØ/‡y×+ ¼†^šÒпá÷6®F§Êâ[¸k!!]â N‚8xíG^ƒ8®܆q+DéK	Qç‡ø=c~!ÄÁKèê8¯úãㄭF^‚
¥eèbnŸŠ­®CJSú+Úzµx¿U„CÐ)ìî8gãfLR…FyÈ&î‚/Clht-Je1;!!¥<¡‡AÍi(häç¦p*æ@p˜w¯@TâtUÜ%y{ºïɥ!öڹ‡(V!?!Ä~;³ÒJC=€W`¤‰)Ïñ;ßùª1¿ÀÅ(<ˆwPqôsø‹ÖãiŒÁÐzcð4ÖAB˜”ÜëŽ/ Žöb>Æc$†âj<ˆ¥Md[Æÿ8ªÃü7`(FàvLÁZHÃÒJé8~ ÄøÕbtD(ÇCbV‹óC>Òý1$f£cˆ9÷Cìi{¹–b$fd¹¦¡ă±’`Uꕪõ›ËL‚ÄhD*ÆzHL֣,‡kZÿi»ÆŠ
˜LC¡¢4Ôw1nÅNHÂ,Åá~)Đ<«Áðn‰Ó'ŽOÐ;‚;gW¢¦¹•†r÷ø5<«@¡îî‰û’zÏA`ÊÑÊóۧc°’[qfďx¿ɓ7q@„·ÜÏD%ēÕx+†ÒÐÜý3$OîÓ?§~0c6$5¨ÀAϤ¿\äÿûæôðð˜wÊQ
ñd7î@‡ûza1$bC*Té歷óükþEñDh¤z,žÆˆgÛ1½Q>ò=•}‚!yX$§¦¡‘:LG/ÏO§p6A"0¥‰­4ôó®/æ@"T_¡Dñî‰×u-~Š?E|Ýc¦ãB/û^„ßñ}4>€„T‡×ñcÅ[‹Q—Ƿñ*!!}…'ð<¿¬Ø7àcHqJP‡Ҹµ‘ÒX‹mYü1‚y7Ï`$¤‹nno¹úØÖ8wây,Ç.å+÷ï`*nÄÅõЏ¤nÅ,¬ËrqóLÅHtb'|1ÎƯñª 
؎wðküÅ	Y±m,c{#׽–à>ôËaƒ­Ñ	šsíq1Çû¨βüßü§hÿ@éKÃÿÇËÎè‰cpúã[(Ã~AÓMúîó‡£?¡?ÊPÄý¦G}0 ^Ŀ¨´þp~8ýq
ÿÝ<H—$xΥÐGa ¾‡£ÐÙÃz‹E¹+ߠ G_‹FˆÂAVqÆbq"ùNµoÖn+
‹E
?ÄÔ@pSq”ËF¾l¥‘ÜX¬,:âÆn©V¡{„¿«7j|í#k¥a±ø_ûu’âÖü›Š5i£^»ã0+äÅb¥q,D©…9þ¾rˆÂÒ ±±ҰXq̄(MÃþ!¯•ÜQºÒJ#¹±Xiå¸ßœ‡”òç÷Å\ˆÒz[i$;+ޱG+pŽCqÚûPýqæB]$>V+",‚äàkì†äà
¤‚&+
‹G7ü“-è4©XiX¬8zc}L«Á
šl¬4,Våyqêӂ&+
‹=!ú2ijÕ8*h6±ҰØ{(#Péi½ÙGÑ>hv±ҰXytÆxl‡äh/žGŸ ÙÇJÃbåÑÿW°;Ä֍· [Ð"c¥a±)Æ@Ç/0õ&àÃ÷C>Ýi¥!"Æ“¤Ò0ÆXic¬4Œ1æÿ#lœì_)CIEND®B`‚‰PNG


IHDR
_ò#’@IDATx^íkŒUU–ÇyÔD§¥G;¡'0{ÒӱNԨiÝIvtZ˜Á	Ý)nI4-
JÛ(%$‚ÊC) ¡  
ª(Š*¡ ^P@!¢â+~àƒ	˜õKܚÛ瞽Ï=÷žs9µV²cäÖ=w¯½Ïþïõ^}¢¢Ãþµ¯Œ<2ŠdL1Šœ‘ïü}ß>ñ&%%% 
f>?cðž={îé8ÚQÒÕյìóÏ?ßöå—_¶|ýõ×Ýß|óÍÅo¿ýöròÏ.ðù_|±Ÿ¿ç{'ŽŸ˜{èСGV¬X1Ô”þ×þ*)))Pô“1 ¡¡ᾓ'O.Cß$Àðã÷ß9Sã»ᄏ|á…n¡G¾qƑ€SD҈’¾ó…ǎ{þôéÓÓU۫îç½qá
ª¶o/þì³Ïˁ>o€Lƒ‰lÜÜåeˑBòÂâ[IC`Yºïn÷ÙîŠiÏ<;°×-Ú'Ÿ|ò ¨µ^Ó"!u|õÕWí¨")¬Mçϟ¯—Ϗ¥) Ú\’çTȜ~ôVRՂåïmlü­òFÓ!D
˜U__‡cä,tŒ›ý]F¾óùÀښšÑíííÓPC°}øÝæ )x()`DlÜ\³zõˆ³gÏnô’,°9?~|^ٻïs€ Èoæ½0cæàæææIA:àQSSs»N•2ua.--ÕÑÑñ\ò5y›	08OŽŸp}¯Y¬֖ÖÉrëÿbAðz|wäȑ€ɖ:„էÝã’Ø[–̝=çF,¤¤„aÓ(etw—÷ŠŒÃvæôéµ^ÆÈ3gά-]²d`†x8ùU[ºNZ¥º¢¤ qºëô¸K}֬Z5BnöfãæE$$‘°ݻ[·lù•Ä|´[ª)ûß^üÖ?G¹žJ
üM¬í;vì(¬ËC¹°«¶ö.pT¼¹hÑM"å”+`()hD,aHÐI1 à€
à’ÖìÎÎΆ’’‚ƪ>áC+·VޖKFEܴ†’’‚ÆëÞ,v‚c^žˆýû÷ÿ.×¶
%Â{Ϟ­ðbZԀE¹ª
h(`()h„썐°Y^#LœðÄõ9:ÿ!†’’‚FuUu±„}ÿè‹Aè8vŒ\
%½¦ísçÎm3ÄbD
J
!Åc´¶´L6¥Ÿ×�3×ի& ¤¤ BÒѻLÁQ~­¤¤ Áíܷ­­mš‰ѶÖ֧±e()))hyÅd00޾6þÍ}”””4öíÛ÷ ‰I©²Um4€Ɵ””4Вb:å&&KíMUM2ڮa@öý•‡¬͛¹&æñÑ/Aƒýpٯ"g-ò9¨†eSbw¯‰¶lXòöÛ?oinJŠ,S•š¨´c ô¡Œˬù•öÚk¥ÂÙ\§bª<¤=ïÂõå壤DäT§UF5õf{Î;ãtWW ª¤aæ½hGõŽ[ÙŠü\iҳ%ˆP¥7eŽeR‹æ9֊½ö%jjzĦPï¸ÿúïRHðFv€âXGÇ,€À)ƒè{PÅýԩSK¶UVþ;·»ò`7ï֮~âĉ—¨«b˜wà!Y·1<õļgð.àx2Ý*þâyž#:Æ&AêԮVê¥J5°e™ìíÂfH·uËV#¿òàþþ®”¦YÌ;)Š94à}ÙҥC¤¯ТLí!xÔèKaÔš^­‘y~ñ'Ôïp{aÝÙ7oÞ|c˖-¿lmm/`]†¸h#åñ“ž|òzå!A¼r;Nu«Uˍ+´€9655k¬ÜÄ/û©)Ësí{Š<QB9Ô|LætÞm­9¯t"<Ôtè!øgX<¤6@/utKÿgò”ë\™?nÜ
6(E/’ÄM¡„¾Žç+6Áåeòťï¼3„ÍõzƜY/ÜHs'¾cÚJ-–‹þÉ
ÓÛyøýĉƒ¨UërbËxα©ôu³wH9‡mJCR»n׮1=Œ½Œ‚¨½'f5‡;¹T ŽÄ ¦²y>|x‚€j§D5yҤA.ÉiU·Z .ȳ(¡ë¨:BAô‹.Yí†õF~¨|ݺQ6· ·zuuõ½•nz^h·CNA(›ç"ñÈ[a!m\Ü۸÷>ž©ËÕÌû…Oöîý
ûj#]R+‡çXÌñà Ä6+Ð8yÒaPCnÕ9n†6^BG¤K‹þöæ›7ÑÎæE6Glyà¦a›HýéþýûyR‡\†Ël@nó¦M¿ˆ4¦<õԠT€Q³sç­~×ò٧Ÿ¹NöÊ؟ðÿ=›Æ.��q¤½}º``ì«~ú§^—‰âȶ·õúõëGřs—à™×‡ð]k£V¡EðÖuª«ÌÍ~±»n÷½é^ ^}õfš6™Ô4Z’\eîdgç|
;K57z£ˢž§´”EÍ!æ³Qþ^äøóP±yó/RÅIã¬ҝëû+Wµ™«Øx^¸Â
ö
U2…dXÄÖȳÅÈ=ÝÄ;F쫼 ÁäJ
hk­—ÊK@¢_&׆gµ´´Láٖ›Ù?î<`Œ¥	WŠ›ðŒ•ÙNÖÄÐûÖâ·~6hð›n †·‹ؔ {µðµ×nFb1ñŽÁÛ4Ô{‚h˜ª^*@BëÉð‹!%^œJ	 Š;HHHáyA½1¦²qc¾Ȅ€)1(*Y^&’Uq'›x·íd? ¹—ÃÓc1¨¸î!-ËV¸´4Ÿº×&²‘˜CW8¤Äx¾2»ùÓqUrÈÂ
ܧ©‚ֈÉH“±¿¾ù/¨}&`—ß{Ã:Ý6,ذX±$xöòé‹Ï{lt¥þyµãÊϐù7gÛކøm:<ຏ׍4B/°¬­­4O…&ê^ïArb˙·¼lùЫ .è1Õ6¸ÖÒà†~ØkMV}¸jD6Àf³?äyð’ő,÷Ì3۠Á-*χbúø@£(•ÊDòÙÌçgN'’”<2Ö„TѻçºÏU4<øˆ[\	EcVKðH/“2òX<‘í2éÆÙd`Âc݀ÌRG$bŒAµY™)õJŒ·Mó”—’0@c׮]£ÍûfŸùÛØØx™ȩ"Àq½b³Y»fÍpO[ɦM›n±
b÷{“«²WÆ#ƒÊÚíç€ú¯ãǃ9–Èlµ'ÜÎ&’M Az»4˜֝8‰m)!ç$•ZÈúI¦û8žgu¾A+Û9ÑMk{“1]¾£
HÄÄG-A}^yè”ËÊ ¡tf*›ç ˜æ˜mÐhIô)ið=FaCCÃÝòü•ØhRIuØKœZù¾Û/RX&l\c W.´Œdr2¤忢c—æh »Z;.¸Šč¬<|Hèé™RI)6ä5Gì€Ù
sö9<#õ4šΞ9k0ÉzDã¦úyE$¬ábO[¥ã‹g‘lU”C‡Mˆº™“,ö²L×Hè>Û]Ñó¶}‘¬r4IФØÔ<‰6ïblŸ©Ì_\¸^slسçî@£ˆ(]ÏJz»wßzVmß^̜	ÀJ‡#96‹‰uɘ¦€¿×Ä`rŒÜcÚ3ÏLÞ4ʢñy8FÄŒ06¢—Ƈû¤Jl&C͒
Ò7z 1½1Di¯ĝífƒáßøÏՏ?n’*üzmy4Ü1kVᢋ+`ØÛzX³šÿGÚ`·€8ñ­^µj8ó4…9£e4Q˜с†tq]S')$«Ò%Àؼ&`ˆøOˆҶÃRjª0L›fUC ~Ç4âÃCbÿmŠÆÑ̻g6@”Rxð)h¸KûÉõ!@-”³ÉBwžè|Åš•üá?
+Œ;Q~ÞzÜ`Çø­tӨxÆ:,_¾|/‡
hā÷0rs}KŠÔ½ R9÷ù<Dиdž±¢¦¦æv_ÕÄ3™ʜ”dJ~DËծñ6<`}6mZôٿö€ÁЌ	"àȦp0õ6‚¼—֯élT8«ªª*¥ž†}…‡ÆDšÉI‡Ÿ¢«ï½÷ްk4<
€ŽѸixltÇ02qÑ1—8ðà¦6Hï•%6Á6nØðoéª&nÆZ@¤•ƀQx ‘oð6’
C"’W\˜3Y¬óãfwešŽ.@]œÃ\è¯o¼q“
bŸ{õ•W~æW
–"Âw"Í$†D¤ÎM?C~„ÇۄÞ[•5ˆ*#Ñ
hþÑ6~ ‘Œ2
šMåhtH¸pxð:Øõ»wßk£¦`|å/ù߱±éíر£Õ(9ÄÚŒü(z¹Êo—ØìÝab§¢¤½¿õӝ
äÇ67ЀhGèCâê5hàf‹^70IehèxlîãÐ{¥‡·¶´LƸŸ¬æ4‘áH=Q€kaàÑ` 
ѶáÒÚèºdÒq
Bæmn5^8DÄ(ˆö .<˜€ƒ¢BØÕl;¼	xN"…90jkjFӫUƭÐÎöíÛo3€h¨©ñ¦ÁzDÚb×Xy톸ÄÞ@ï‹h ¼p6üKBָlò´fõœŒeèâÃY¥ 7¹~Ôi@‹á¥Ö`10ŠðÐoȆ7€Ž^.‘VÞ&DŽEö³!Ò4x&â\\@"e؆^Þ,z ¨)‘(¤c(0/Ì9-ð™»Qe1K[ç
ÁÐûžWØù)ÐišS.MM%Û$Ö}
h$Jå™A³nWݝ™çÆÜDáYÖ<ž<ثՄ›“GEò–Hõ¤Ì÷Œ˜l"J£àÒ. 	€F꘠£“ÓHƟÄáXœc}°NGsS›ÃüÑë	|ŠÁ3U‘ž‘ÄsgÏ‚kÙ0EÊ0äàDÓaM">ﲕ6ðUm¯*ž£­^…žçWԣ½Ícs4lE`„z;»@ӸL#=·ª—¦É€Œ7Á	—²)|}FÉ󃣍àÎ	€cGuuq¤†¡t€ƒïÐ俖A‚C¥êʌâiu
¯RAaüyN”γ‰wƎ4‚;'޽ƆÐþÉ×úÐeÚ]U1‡õr“LùýSƒ„k4¾æî­ñöD5·ãKÓE;Aø?I’61GÌ'Aƒu$nħsâÆQ¼*0´ny q/¿óõEº‰‹¨Ô}âæÐ^ÇHS˜» a6K}H«l`º‘ÃkMªÜZyú¾Û-âÄôâÏCpjkmhëº\÷ñǣ˜{–Aƒ€:_‰‚ì à÷ìS#EùåI…ŒÄ_œ?ßÌsÒzépÇzˆJF•5
ƒ¦Ò
FQ[¼JKmí: |:†<éLvàà€‰aócÆCp¢Ù¿¶¢=²Ø 59²Q¨ÌÝy0GÈR£Z²uÊãùÌ5iðoEÔ\%ò>Ð$n¼¥}ƒ|ðþûC1ÎxHÆD2ôè¥âH~:èî0Z@oÝuuwÒ
w[0Ð0*—M\E^ñµ¶6ëJOQһIÅvë°^^^n¾ãÏCZ—չýˆöHdéHZ¼Ϩ:¿›·$é÷µ‘8Ξ1K]ö¢‘Í=@ÆÜyvϵ8ÒÞ>=#öåлT?öm÷`²’ú¼˜JÏûÀæ͛oaTTTð߫£¾¾þÑíÆÈÁzîdgç|š¿N;ͧkØf°ÂÐdùr\¢Wé.ɢtDÄ<ìú]½ï­J‚·Û÷åvY2ïÏ/þÄ0­˜óÜÈÜ|¦HÔb¶U£¨G	I¿%úHƒ—ßÚHm¹øf‰íà~ÖÙ[[Z''T¿€Ã,uõϸž¨ä"§97XAӍ8Ó+€½ Æ!^DC¶s D~t/§RT*љ5	ê^Ã-S‚óæ€[s›”Kg¬Ìÿ¢_›]íy^P0]ߚ;©ñiT±¿ÈúWdúÜñ<¹7¢QdU*ds(=†ڑ†Í#ãL³ÙJn¿jüּ8Y8| 0ݽ‰jÌò Dòm8VòØãm[·þ²½­m¢H¢飂$
Ðɜä=õõ÷á†Yâg‰
|õžl÷P4A@Œg”"ƒÛb<'lX¶Àõ†U¼ô§}È)Ãiç·^˜1s0†^æâè†V<²lúQ±R—½ûî0ã†)̕Q@5}~€ÈæeÅ{¶o߾’P¬ܺõ~ª˜À0‚e;ÉÞOG#óµxºò“W]U]lˆMD, ã< "™Œs܀Zã89—ݨËçüè|{Ñùø.>wlò¼Ȝt$ˆ‚ÐÂÞ@[D:6ód¾H<W^a—¡÷êU«¯ðÇAP̗U·nbû-Š_"&„wÉ3Éð×è8¶UVš]Åџ¹|œµµµ£éC?\Î
û&9@óù¤1)®}7åŠpÓÁs¦EÎ(LX—qÓöFRâ0¼ñúë7«à%Qt
¤Ê:‡æñ±coüR¸Oµ!ç/[ºtHn¯–’’F}=>½¼;ŽݡÈÏåÂß
¸܅gÅO}ÜP
»JJJþRľòw¯÷-[¶ü*È!FÝÄïØÚ҈ʱ¥RRR—âð¤”z·¿…™”hĘþ’MІⲣ)))a¿HFÊ^$ý³a>|øð$€Ãd;{΍	”””¢.pýwœ˜² .]۪ç‘÷ÁURR2Ûčû¨WÞ	Ua¸œQm §‡²(JJJæҀÏEÿ°æâU€Š¸‡ˆ—KII‰ @¯Û]Ԇña2pàÓå0h()iW¢	³û<¢[CžSQªø“у†’’q™Ú-P"!ìZ$ߥh{05ÚSRRÐ`J´"4<ìòTÜæB%%%¥(û½2ÚÚÚ&‡
$Kº¤±ÿ@RXŽ/©’’‚™ª!—<( ÈPŽF„*)©»•,RCªû
‹6ŒtK¿§™%%¥ì-²L¹åóÃ(ã€7Çо2JRRR’œ’ÉаÌ=	™Z³³æv$›dI‡êì9²\JJJ'<q½MmòB¤{۔,Õ}íóñG
§ά‹›µ$¢bPJJJæVŽf‰CêÐ.£üß˔Š´sçÎÛ·æQ9ª–()i–«”ì[ë£_·¸b§9àÑ/]°(ùÃ*õ4^¦ѓ‹eUÇsxٔ”TMƒc£ßÆCtR“><8sQ_’$€¸ڝ7o]]Ý=R{1áânÒuIyVŸÜ'%%$Ž4{¯Ðû捝¨bŸÜ.@â,>¤5!©ö^íC8øè5VTIIóQhWf.<$"yüº¡[I®’’’GK—,‚š€dÍ֝’¹ºhíš5Ãã�¤àяpm£A77’ۂvèȊä'Ÿ>LÇ÷øºS•”@òh„ÔÐÐp·t{›Eä&)ì’ZßDg¾äAþ]ÖÈ9!ÝÆ$8lüúòõ#©—ÑK¥
%%•Bzt‰/rü{~0€Pú?þè)ÄH;¤IEND®B`‚‰PNG


IHDRµú7ê6IDATxc DýG‚
X )}ՀWA¨:’„02+T=ò9\	¦DW€FªLHd<•ÂCmr&?IEND®B`‚‰PNG


IHDR

Øâ,÷:IDATx^­ͱ
0ÄÀ_ô„ŒA**D•ÈåFP£ÀÔ0QÔÖ+©Ը½ÄþúA±P
''pð,¤þÉÓxIEND®B`‚‰PNG


IHDR

Øâ,÷:IDATx^­ͱ
0ÄÀ_æõHŒA**D•ÈåFP£ÀÔ0QÔÖ+©Ը½ÄþúA±P
''pð˦L¢IEND®B`‚‰PNG


IHDR

Øâ,÷:IDATx^­ͱ
0ÄÀ_6ñÞŒA**D•ÈåFP£ÀÔ0QÔÖ+©Ը½ÄþúA±P
''pð¾ùá/߸ÝIEND®B`‚‰PNG


IHDRJÅ'Ã!IDATxcˆû‘@ÈàùŸþü0Ð8@i¬¾€ý=IEND®B`‚‰PNG


IHDRJÅ'ÃIDAT•cˆüù?
þ¸@iÒ8Ý D•5sÙIEND®B`‚‰PNG


IHDRJÅ'ÃIDATxcpùÿ_ë?‚8rÈNd.áô'LU‘IEND®B`‚‰PNG


IHDRJÅ'ÃIDATxcø‡.ÿ±s\X0dB@ ñ&ù4K€IEND®B`‚‰PNG


IHDR¼ÒIDATxcX‚þ£‚·Ã[à-ÉZ0B*Z"<¾éƒIEND®B`‚‰PNG


IHDRt`8ÅIDATxcXBçj-Š%[$IEND®B`‚‰PNG


IHDRt`8ÅIDATxcXBçj-Š%[$IEND®B`‚‰PNG


IHDR˜IDAT(‘cXB"`¨›¾’$4ªaTè$
KHgq‰§IEND®B`‚‰PNG


IHDRWÝRøIDATxc¸t	ˆ	ÞIñK¢xIEND®B`‚‰PNG


IHDRWÝRøIDATxc¸t	ˆ	ÞIñK¢xIEND®B`‚‰PNG


IHDRWÝRøIDATxc¸t	ˆ	ÞIñK¢xIEND®B`‚‰PNG


IHDRWÝRøIDATxc¸t	ˆ	ÞIñK¢xIEND®B`‚‰PNG


IHDRWÝRøIDATxc¸t	ˆ	ÞIñK¢xIEND®B`‚‰PNG


IHDRWÝRøIDATxc¸t	ˆ	ÞIñK¢xIEND®B`‚‰PNG


IHDRWÝRøIDATxc¸t	ˆ	ÞIñK¢xIEND®B`‚‰PNG


IHDRWÝRøIDATxc¸t	ˆ	ÞIñK¢xIEND®B`‚‰PNG


IHDRWÝRøIDATxc¸t	ˆ	ÞIñK¢xIEND®B`‚‰PNG


IHDRWÝRøIDATxcøøˆRÅÙT'IEND®B`‚‰PNG


IHDRWÝRøIDATxcøøˆRÅÙT'IEND®B`‚‰PNG


IHDRWÝRøIDATxcøøˆRÅÙT'IEND®B`‚‰PNG


IHDRWÝRøIDATxcøøˆRÅÙT'IEND®B`‚‰PNG


IHDRWÝRøIDATxcøøˆRÅÙT'IEND®B`‚‰PNG


IHDRWÝRøIDATxcøøˆRÅÙT'IEND®B`‚‰PNG


IHDRWÝRøIDATxcøøˆRÅÙT'IEND®B`‚‰PNG


IHDRWÝRøIDATxcøøˆRÅÙT'IEND®B`‚‰PNG


IHDRWÝRøIDATxcøøˆRÅÙT'IEND®B`‚‰PNG


IHDRWÝRøIDATxc¨¨"¦áÛ);	IEND®B`‚‰PNG


IHDRWÝRøIDATxc¨¨"¦áÛ);	IEND®B`‚‰PNG


IHDRWÝRøIDATxc¨¨"¦áÛ);	IEND®B`‚‰PNG


IHDRWÝRøIDATxc¨¨"¦áÛ);	IEND®B`‚‰PNG


IHDRWÝRøIDATxc¨¨"¦áÛ);	IEND®B`‚‰PNG


IHDRWÝRøIDATxc¨¨"¦áÛ);	IEND®B`‚‰PNG


IHDRWÝRøIDATxc¨¨"¦áÛ);	IEND®B`‚‰PNG


IHDRWÝRøIDATxc¨¨"¦áÛ);	IEND®B`‚‰PNG


IHDRWÝRøIDATxc¨¨"¦áÛ);	IEND®B`‚‰PNG


IHDRWÝRøIDATxcøøˆRÅÙT'IEND®B`‚‰PNG


IHDRWÝRøIDATxcøøˆRÅÙT'IEND®B`‚‰PNG


IHDRWÝRøIDATxcøøˆRÅÙT'IEND®B`‚‰PNG


IHDRWÝRøIDATxcøøˆRÅÙT'IEND®B`‚‰PNG


IHDRWÝRøIDATxcøøˆRÅÙT'IEND®B`‚‰PNG


IHDRWÝRøIDATxcøøˆRÅÙT'IEND®B`‚‰PNG


IHDRWÝRøIDATxcøøˆRÅÙT'IEND®B`‚‰PNG


IHDRWÝRøIDATxcøøˆRÅÙT'IEND®B`‚‰PNG


IHDRWÝRøIDATxcøøˆRÅÙT'IEND®B`‚‰PNG


IHDRã!p
IDATxc‘aƒb~ ¿IEND®B`‚‰PNG


IHDRr¶
$IDATxc‘ü Æ&KÂÍBIEND®B`‚‰PNG


IHDRr¶
$IDATxc‘üÂ0Æ'Gª멮IEND®B`‚‰PNG


IHDRwSÞIDAT•c‘Bdâ‚9IEND®B`‚‰PNG


IHDR{@èÝ
IDAT•c‘"ă
V€IEND®B`‚‰PNG


IHDR{@èÝ
IDAT•c‘"ă
V€IEND®B`‚‰PNG


IHDRã!p
IDATxc‘aƒb~ ¿IEND®B`‚‰PNG


IHDRr¶
$IDAT•c‘ÜÄÿ@$Áÿ±hIEND®B`‚‰PNG


IHDRr¶
$IDATxc‘üÄûaŒÿ%ÁéN3nIEND®B`‚‰PNG


IHDR:~›U
IDAT•cøÌ|D?IEND®B`‚‰PNG


IHDRr¶
$IDATxcøÿÿÿK—.ûá {V
”á„ULIEND®B`‚‰PNG


IHDRr¶
$IDAT•c¸té²ßÿÿÿ0€ y
”éèxIEND®B`‚‰PNG


IHDR:~›U
IDAT•cøÌ|D?IEND®B`‚‰PNG


IHDR:~›U
IDAT•cøÌ|D?IEND®B`‚‰PNG


IHDR:~›U
IDAT•cøÌ|D?IEND®B`‚‰PNG


IHDRr¶
$IDAT•cøÿÿïg—/_ñ€J
•×=»IEND®B`‚‰PNG


IHDRr¶
$IDAT•cøÿÿÿ~ c¸|ùŠ?ˆ~"
•–UbIEND®B`‚‰PNG


IHDRr¶
$IDAT•ca ˆa®١§óÜIEND®B`‚‰PNG


IHDRr¶
$IDATxc‚± 0„
\¥7©É:IEND®B`‚‰PNG


IHDRr¶
$IDAT•cb``ˆa€1,¥#Ÿ¹àIEND®B`‚‰PNG


IHDRr¶
$IDATxca8ÚA=m½ÕIEND®B`‚‰PNG


IHDRr¶
$IDATxc‚± 8
ÙÓ qIEND®B`‚‰PNG


IHDRr¶
$IDATxcb``ˆ3ªÙֺIEND®B`‚‰PNG


IHDRr¶
$IDATxc‚0a
Ù0µäIEND®B`‚‰PNG


IHDRr¶
$IDATxc‚0""bAˆ¥t¯¸2IEND®B`‚‰PNG


IHDRr¶
$IDATxc‚01X¥»µ>IEND®B`‚‰PNG


IHDRr¶
$IDAT•c³a ða\‘ÝTá€IEND®B`‚‰PNG


IHDRr¶
$IDATxc_1[0„^c´?	IEND®B`‚‰PNG


IHDRr¶
$IDAT•c³e``ðe€¾cãv÷ýIEND®B`‚‰PNG


IHDRr¶
$IDATxc³a8díU©¼@IEND®B`‚‰PNG


IHDRr¶
$IDATxc_1[8‘{ʓÝIEND®B`‚‰PNG


IHDRr¶
$IDATxc³e``ð…3
v‘f(ãOIEND®B`‚‰PNG


IHDRr¶
$IDATxc_0³a ‘Ò àIEND®B`‚‰PNG


IHDRr¶
$IDATxc_0""b¶	Àc™2šôIEND®B`‚‰PNG


IHDRr¶
$IDATxc_0³1
xcW@
IEND®B`‚‰PNG


IHDRr¶
$IDAT•c+a hažcŸèÖIEND®B`‚‰PNG


IHDRr¶
$IDATxc‚±b0„v2ã6äIEND®B`‚‰PNG


IHDRr¶
$IDAT•c+f``h`€
:2:A‹IEND®B`‚‰PNG


IHDRr¶
$IDATxc+a8¸Å8 )IEND®B`‚‰PNG


IHDRr¶
$IDATxc‚±b8!csÿ.tIEND®B`‚‰PNG


IHDRr¶
$IDATxc+f``h€3©cuÉcIEND®B`‚‰PNG


IHDRr¶
$IDATxc‚0+a,c\á*nIEND®B`‚‰PNG


IHDRr¶
$IDATxc‚0""bŽ2W롞IEND®B`‚‰PNG


IHDRr¶
$IDATxc‚0+12%ê­IEND®B`‚‰PNG


IHDR°º¬KþIDATx^½ձÁPÇaρT¼ŠÑÈÐÍj"łxI#£ˆ/b0x%T]ÿ“T4Mªçê=†/éÒóKšæœBmæë˜ÂHçÝá*24˜€"ºÍáúöp~„ƒb°üáüo8Ÿ“€ʩŸhÁÓ@à	v2P”!7(Å+P†¹ï@B@e
Œ@	éQà ØPà$8SÀ\)pxùD{ÁÀú³dt)P@ p‡"ÈR 0ï"ËðßtI.;b\×ʹƒӁGŽ@�YïÇÏÒà}0ײEîÑO†ØÁ<¸DÏ[èCùیa#‰îº	IEND®B`‚‰PNG


IHDRàw=ø½IDATx^Õֽ
Â0@aOb"FaZ"–  HZ†¯̃' aÏn(,"ù
Н½§Dþ3›ӽĢLj+fÈ¥Á¼ eË[Ü IíÀ¢Ø!B4D+p†hVš¢´^;0ÿsà¡ý‹|
ŒŠA{™v)Ð(m´€&§p0Z‡Ý›Y[鸎hóÜÚNÄ&«yeNØÔ™…ûñk,̷%Ϗç‡LjëҌ7†¼Ø1ÎwIEND®B`‚‰PNG


IHDRàw=ø¾IDATx^µÕÏ	Â0ÅñL«£8€W«Kˆxh®.cVh&qL`<¨ê+XZ|‡Ï5_ȟ_Ìòx}þ(ÁZp0ó	Óe8Õ(ÁF öº#kM€X4¼:aƀF£´ê@Tî}à¦Dõõ!7êkZA=´j˜z^9*z’jØ
jèþ4®k0Ўç1yñÃøÃ[Áeâ¶lT<ùËÛâKŸ~‰"<Þ"p°(­ñ@¼ܭAÃÿIEND®B`‚‰PNG


IHDR@þ‹ÀèœIDATx^í}hdWÆ/ÀB X†¦M»Ým·Ý6íö
ÂÂÚht붵[kƒÕԵ©ÑÑÑѩÑÔÕÅmWWW«kG£‘±SӎMMnýXݺ²°®ϓž—.37÷¼w%´½<å—÷㜹ï{Ï=÷Ļâý3Ô-@-¨ 4ä9ªՠ	¨ŸŒB»Œý,™w©%J”hÚƒ€ŠÐåõz;”‡Ðߡý
ÿiò¡5è¨ßMXµLJšÐxD>#þoկLÄøéÿ"YÊÄR$1ÿӦæ]°üϓwÌ?ù‹æçih0Ÿ†¦³fì/:øŸ6±6
».öóGæ’QÃÄ4qü%~ßÄ_7öÈDPÎ0¾ÑR§øC'ò•ø¦ëç_÷ïzꂿ7ÿgÿÆɅµ‘CÏq˜Ì)¨uãäKø=ËþîOTý«ƿU2Ÿ{:wÍýߧ}ÿêûNÎ(xjÖ$£u‘Qhº'`?Q¢D‰ºLá©(oôºMáh:á_ûÑݣà' իƿíóš;úÙW§p½vñò¯úÐqÿÆOýfãšû—ÿqlç‘3Qí3þuúOû·Îúw}í¿þ¥7›7<öBȳF°VHíÙø{¿°²~ÝÇç"åïêûžÿ…—úµŠÿë	©UAkŒŸþïýâ_ÈRŒeã3ðÓ!ù˓gþoøä‹5üKü§Oäô5jþÉSü™¿säÃß)‘Ÿ?ÏÀ~sOûŒEüãé›Ož±Òg²w>õ±ÏÜ;ðÔ!ñŸü†ÿ_ý7E~#&̍éž:Îñ—øiŸñߚ}Ã>r¥~O]ý‘ï’!oâÿ«ÄO>¥òàì(àãÐ$“ٿ~âW	b3
ÍîÃ$líyüåy|îÒDLÞ^üçÛü§[/��çèïȳ‘š¿âޯ»òTÐßùðOçľBû ©ËÚD%J”h Û
‚֠]J~×4<ˆ"î§ Êð½ß`á`Ѿ„³×ûäÙ8 è÷ÁW íðÇÑÿÉRÐÔÓÑF”æé4íÃ&ù4•¡,ŠéföO@äÅþ<y£t¿7Ô+䗠c”U¿Î"7©ᱧÛåŸ×täï׬qâÿ¬±ß$/B޶µ‰ÿóÇÂ-¼å¿Ô?©?« _	æß⫁úIžLpü%þ`þêþø`ý*‚§ob§nØY+Ì-mT„èôuþBøjÿãœøßFc7}æ•ó&糖ÿ–ý…ÓÈUXýìÇ<*
ŽŸÔ©ßBµãÁzpÈC5xYW¼ ƒ¸™v>ôÝ\ܢð·|îOe8A&’v?öBÎJø×Jb?¢¶ƒiZöóŽ<uJºâ[¦—Ê
¾j!ìÐ%~W¥ <t€̻@‰õP1ø"äãî0¯äK,7OýžÅëV›]ù<x^|S,{w=ò37ûc³lœ¤ðdp×ìíxà.þ߀†!ÿöp7îêÿ"”#
T„f®Àâ=úäÄò¼æ{¸Yõö<^÷°rÆÝÈÿ¯ˆý4yÔò|YöP\;Ž¿åÿ24±fyhÞ(þ܋ÏznûÒ߼6u§ˆÏìñÿqӼa
\üIhò®üà1›ŸFüâ¿ä_â§øó°U¿.all~Š<>“ø³’áQ»2v!Œð‡¿=‚ùÃjȈeü«Áú}”Ímˆÿ`È2Ì?;kÙoW0ÆÅ>|¶ýÏZþ3×Eñ?¨ëù¹wGñsNÛâÿ°ÍÃNhýäœE£CVƏñÛõçpÍá殺(Ý`2<¿=XŠ«¿ֳ݉.<–µz‘ˆ†ØG'+|Wžƒ!I`·>äÚ|à"iÙwóŸÂÝGM–eÁKþ\tOß[»>ö¼øïªh
ê#³…J”(]Â÷â<ԫä}sñ>‰ǵDŠW
+Ü.|Ž<ìJñà5ÆÃöý:y,ÕGå³PËæQly­ŽÊýÇ5š×Zû¬ÂóíÂ@«xD&«=´Ç0Žö_’æ‡5ªmü̱°ù³Hÿ1~myŽÉÍO4y3ôͬÜÔÉwÈ??ãØ„hp…ïƒZh4íü³V¶³Ϲ%õó”õXq7šË`+!óGì7¬ú=hÛÀ‚÷:ÄOž
ä¢U3A¸	ñ𨲝}Æd×_æܩ~Ò>xú¯©Ÿä9¶¶ÿYϽ€Ï£l™娂¢Hc6x¨ìÈs˳AØ/	ƒn2ªÿ$Aìñ§a_â/*
@w3êøɣñ‘øµw¼g1¸
URò)hL;¼§•è0äCJ¾„ÂÂ}-ÜõõKãà 2y^Р4
”Æ>y*Çâå¸2[F±žzÈkíï@rå‹(,¼0þŒ‚Ïc«ƒä/£ñßاÿÃÒü¹ð(š|lGû¸6Òÿ§5öÉï@ó£ʿďæÃÕÿé·ü“<k[(O߸:xÍý§„Oa5iþ¯€’ü‡ð=°q€nÆÅÆÆj!öÊpÕo3>ƒ9¾nêÇhжxlV¿G#©®õK꯯¬´OÿãôiÛ\W‚æå9«‚gw_5ü²Ò~¬šDޝ‰}¥ÿµ˜ñǷ¯Ÿª “ÃOr
K•d””Ç[ªDG¡%(§äW®ô—œKì?Qñfõ‚×yÜâ¢eÜ	’¯çwÙ7öç!®\hí/@rçî¢%c¿±0:ó\½øQ̝ýÇêO,^ÆbmÐǯ?á5ù[^ÿ>nÎ_Ðø/M¿Û
o€?¥	ðp,–¦þ尟ênø¬­ÿϙúuZiÿrÕõw…€F<C£—ôükä׶ˆ/bærð«ZÿcÚ/Åäæyñº–Ç2pûïƒøFÃb¬«d„žӮÆÉã¬êşZśs¡ˆ9¥á×
_ÂwZiÿ,y~'ãð¼¦ÅáË(b*¹ãÿªÅoiþ´ãw™ü/)ùŠyÛ밆—=®(¨ÜsBæ!6ú×>ôc-ß7úäâƒÈـ’ϛú}>fý]˫ óÌw5&¿‹×à2îšâð…˜|1nüæ®em‹ò'|Kɗv>ü|œù³jaÛì»dLTò±¤îã‚4…¥xU1o
qN*ù7
ÿ’ª€›·†Š˜ÓñíëùBÜø±¤á/‰}¥ÿ-3~…˜ñÏluþ”öÏ~\9ºи‚÷°’‘IÄMà×OÌkù>¬:–ó}J>·þ
¯
`ÎÀ%%_3ü²’¯~Ek«8ö+1ý¯ɦ½-Êß|Ìñ«ÄÏÿ˱æÎ&á3\-?
]´œ‹«»¡]JvŽ{øj&VÄ4ü’9k¤†=]~ِš²­Ää—Pã5&ÏïD~A?ÏIaüJû+f9¿×¼-£çõþ7c6@ý8"e<7ß:ó²Tñ݋©¤R6¬Ô(>²~Dɟ6õwI5᠖yePµ	˜¼Y‚*ky,¡iùŒe¿ µ»­ý¬e?3¥}ß<Â,ň_ˏXþ—¶jþð­
4’ÿAhêøÖJ:aëäc9y¯OiVÃÌw©…1IkxóÁGN2
¾l!0§9ÿ†ð*ûÆÿVLÿyMPåÏðüNd|^x<ËƌH›‰?¦ÿqòNù)‡M±“à·) îãq-dÞ#JĽR¨aZþ ^£ç[sc¸n
wÜIžUð'±	IÞÈ(ö}Ô,>§۸ãÞù5xhAé¿ð
뭅¬†‡}­ÿ=PöÉ*샏ÿ6Ñʼn¿ÖÁþ(4A
~Ž\ⲁ…ݛÍ<jâ)¥<÷ƒ
S{ZæÄÔ*¾˜›Ù?…¤Xep'$o%plSŽ{Ÿ²ÂC5ÌmǽQäë¾ØÇހžü"ì÷*x‰¿®ð?cٯIþÈßÉnÅݨðMð©ñ/pþ(⾪؄»Ýò\±	¸öK`÷a%F½{
ålÿ»%â›x|kNÛqoòe.øþ^Ueñ)AN¬˜eîþgùmPƒ<î8Âø®ó2°cŸwJäˎöÓ³x2~W¾añyGû9¨Ž7äˆð‚£ý,´žñ‡_
êí°ò³LÿqÇ+ñó^†NÒV;^â—Õȶ¹Ž»@ž„Ëwð¿fñ3?mVa˜[ΑL»ñ·珝½2b‘:i?ׁ¯Ò>LÃ[xãR¬Pt˜±_ßÎ~š<ã„có5¦…Glô1݁—7ïü,Y‰cœs<ߋ¹”#÷›h"Gy‰Ÿss	þ;òÏr.Hü5æOkŸ<ìçïFg„ç9'°?¨·ÿúiðžcü%kþ
8°r>Ú8øãàûp ~œ2ï%Jç¥ay2'OŠÔ<ÜoÌ:uã”Hö0ü•æaJù3…v@«</ƒÅ_øˆ›ÓМù+ÂÏÑÿñBÓ/þϓßäзahÆh¼õ÷QNA]!Ïì'¡ªÅ7ȣP°À	Ÿjãÿ6è‹<Šà"›]£Eò\ù1Ëå•6ñ"ï>ïæÑ ÓVӲß^âæ6Ϡ!—"B[6_3þKóS%oíyèÆ#±ªÕÀþ³ó_!ñûsP—•úÂÏÄ>s½`ñóÂóѭøoæBxŽí/1w†¯Ëø“GœÓ<-ÕnáÅòŸsÅö¿*<l–ڜ³ÂïBÍâé=0þôgT˜€˜KòÒó?ա)¶ã—ü³A&/óggç_xŽ1óGû÷ØLDûäÿt(ÿ²ãžڗñ;åy2®ü$ØÐ§ÙyÁÿ“U˜DI¤”ë]‹ŠÃæ×޷ŽyÕsüSiì򯙕‹Š”ˁY8ÿ”Ï͚
~†…GV òøw¨ÿö£7›ÏC]xþ¹

ŢlÛïÆ!ZÒèµkb|,I³Ø
/…Ÿš‚<ðíâ@“¹.Íš]J§5èˆÓô±ÈY…Dìógái?…øƒöS˜3xi|¨2yÄfóô…ŸټÂûð78~vþè?³yæ\xþ.áKâÀ~7ø"¸–Ý0wäÙÙ<æD°i¥Nþ#6áǂ«ø•,û´i?ý)Ê^‹|Çücƒöá°sK?|,kÏ|ç÷XLGûàƒöùwûÂ8{üö×ìG°ߍøeþΡя̊}Œß°iIƕçc$‡7™%JôNtZ}9p£€ã2s7ŽÇß/ãƑϡ̃+BYòøwTþ0ŠâE0
Óø’ÇÊC”“¯óhDÖÁ\€h¿`ÙmžÐÄ<hÿ<óóÔO>äm#Þ}a…‚¶šdý3Ð$”ƣS/ìO
`UjÀت[ö›&ÛÁÓ~»üñ3Ɩ5±ÎۗLþ
o_=Œb®
³*¼ùlHòÂ猯5ˆcײølØüá˜`#hŽ'|3æ@þfžÿæÿvò²zÔÆòƒ°_ cXùe¨Ïڨ–ÿ2´bù¿¥Ë³ø_—ü5­Øv<pZ˜¨öéóq‡òbŸñïÃ\smB8ûhͬê@<p§ØǣP¢D‰þâ÷ϣ)Ǔ¾IEND®B`‚‰PNG


IHDRÄé…cÖIDATx^ÍV[h›eþ¤:7x¸X©èÅ@TŠ—2AÄÞhT„‚ ë@pG¼hËZ;7ë´iºvÖ#̡LXAˆmÚ)‹S·:ۛÑCuYãLº$Ƥ͹Iþï}ž_ûcl­•öb¼yyÏßáýÞ?Ꚁˆ(Ã0lnš¦-“æççժ195¹!›Í>Q.—_Er7ŠïƒÜýÓ·/ø666ª!	[<
݂UîS.ˆHô(*‚r $(djóB±XtOOOobܔJ-ÿE¿űÂ-•J¥_D]‘‘_ωû|—ìÞ)/y^”]ԩ§(`g_%SÉÇí<KÁétZ<•J=bTŒ¯$.Jóé&ýØñ­únw©ö+QM pÊÔÃnҏÀÂF’ÉäVµÀ&‘W€Ñð¨<×ïԷvlëۯ“»ºjåÐw¯ˡoAԩwÀN?úåRÙ7ª鈘R$|V¯;P#(bÞtðFyøý‡äï L=íô£?ã€L.—;¸(yOOòz½Ñ5ã<ã–ÓÍÚÑq3WiÞvØa%{ð½ÍR6JBS¦žvúџqâñ3>|jøN¸V¿…X<ö<ø/箜•m?ªoÀQ0	i]{<ðÎ}UE SoûПqg„b±Ø3èºê"ù|~?xÒ5òÏÛñH¸b+áS'ž”².AN™zÚéGƹFÞàwäk)•JÊÚO¡3zaÌîz…ÝÃ˵WMbb<D› Û6‚þªUÉÞ/÷PÌà軑SـBi­OÀXâ;`›²‹þ	&צ&_d£¿jV²c`;Å|>Uws¼¸F;Éa}U;Á.T&“9ãÜÝIùxüÕE./½ ¦\Ymw1^´D/O_މwW}\½G{ïÀ87Öݠ«ü÷ú|>µÑhô
LՏ|ñ'ÿóÅ;5ão„ÃᏐ®F-…3ߜ©K§ÓGyqc3£V!ÇJgWdT€ÊÜìÜg˜›ÕRhhh°øLt¦6•œ}×4ÌÂϩŸ¤Å×$Öî®3Ù=lSrNámNa{f•Š¥q÷ÿ秖ðx<÷øýþcùL>k˜ZÎG¾—#?¸eÚsÇÛeï©Ýâ†Ìï	î€G”Ëf²ݑHĚ¾CC^µ,ZÛZma``àF¿/Lϊ–44ÿåtYÇ1Ú'¯F¯¾688hèÿü¤Z1ÚÚÚ,^__ïpu¹^Æ×΅–ìÓZR(>M$}ccc{:Þì¨]ˆY¿~ýêþ±ÄãqÎ7¾)Sêlº&ðZ°¼¶Ë9IEND®B`‚‰PNG


IHDRnàMèEIDATx^…бŠÂ@àß.`‘ÖøÚX¨ÍmŒâ4g›W¹{G°s×Xî-ã0xó7Ëÿ\ õ	þ!"¨ëúº†Bôž0ˆϹ5֜sȘÀic¬vÚ{Ú’D‚ßÂòI"@‚ÈJฉzÂÀZׁaŒy"&´X`9,±p¢ *y2ÃüEæ˜9± vF¾€ºhïC袡0âoý¸mÿ%…{Ü~rÄD¶åÝ
#p·m‰´'
	²¦òˆVXá7Ã’¾XäåӚ]‰/Fï­u…)ÆÏõÝ5UgBÅ:ãã®3…Xº3_ŸÂ(ƒã&Œ¦tˆו®I$"P ‰8Dg{‚Ф-Û‚P‚Ô'aÀ	O…ØGy˜?$3Bç¸GIEND®B`‚‰PNG


IHDRnàMèÌIDATx^½Ô?ha‡ñç.¹\Z5=*IEO	èRpÈ$¸Hî¦s—€8ˆ A$ÄA»8¹œ‹ƒà°—£i‘–t„þA¡)‘‚-5Rܾ^—»€Ky¸í>üÞß;¼è¿;TB&Y,rXd0à_$“Ü×ÉýÝÎÇΟö÷kä0‡{kƗ+„yښÁÆL'ÖۋAäkª‡}Þ{x#˜Œnޫ
j·Ú-/¢ýnjb¦“c눯é©é©ý~Me­í1Ž5„´®BUm<ÕTѬvµVæ¤ŒS½9WÈqeõ{8dÓÖÏQ|sÓªËׯúîF5â7Èc$ÈPÀÝYvä¨÷ãɭÍO]!W¿)I&y&î6¢ª„_MÈ×óKØI²Œqvg¹.¢ê
DH¾æ(f21æܾê+Ð7m¯Ì?íu*B]q+™Äû,.!WšL¾¼Ó
â+H&6¥WµªPsðå™/Ghõ'I#ñœwKŽˆó´òˆv:1ÈS¼~ùý\sÐЬVó÷9ÃXê.ñœ#LpŽ”ÃÎã2Ž9Œdaĉ°"…Jbdba“ˑòó'wÓ_0Õ1IEND®B`‚‰PNG


IHDRÄé…c¯IDATx^ÍV]H›gþl¯FÙÕt°u–vÐÞ
F»Âhµwõbíí.ÖÖjéE/
uj•¹ʐ	›-ûq.vmaЈCÑd$[3âLŒ)U£K"FM4ß÷÷ÝyÞ~
N6¶‹x9ßßyŸ÷œç9'Ñ^“RjD¤éº^¸noo/jmm-òûýêÙ6ßøø®µµµkÒešæ€bÄ0Œ¾ï\]]ý889ù꿘™žV>îÌf2$„3X䕗
÷óü~,›ÍÖÅb1–ˆǷóz•O&“ïë†ñˆ7Y%Ѓƒ2P_/=••Ò}ú4<îÕs¼gKqv2éô»ˆÍÌlP^^®|<?l˜æ/ˆ\ñùäȥKâçĽíÛå7š&îòb/ùÏ	ïñÌ úi5™ܷuý}¾·r¹œ‹.—t;F6ÞðN4xô(
?/Æjk%{9xäˆì.)‘]è(/'|æêË`0øò߂¤R©V!e8§oÀV\,'NP*$ÁÆøÊ%ý~hl”={öP§´ÂÏ8>‘N§¯n*S»Ýþ¦nš>æ%Rt3=’ê?tHÆ=	caeu¢e¾5Ã* d„8ēÞn›í%"Ú²°°p•7ˆ-ÈÞýûJä<uŠú”ß3={÷Ê%DÄjЇB!7K8
*·n¡tˆ#ijççç³ßÂ)ÚØëþ›7UÀ`Y¥ž<!d€ø3{i©HñååÉÙPȥ%P:æqb¢® QÞï#æw#KЁ·¿WVBE —83,”J0x´{w(›ËÅQ:p1@}CçÎ$ɍûéúL ™D£A@¦ÞÚÚg$c6€­¨h=¡¾óÖÔ(yÿzæ@Ò$Ä®¬¹¹³Éù<“¯q¢ #h?‡ãäÊ™!CKn4TUE¨2±š³ó®`MMME,ßû ÑâD8ÊÊd*yVw°›9>²J§¸¸‡àÒâd‰÷»Ž
ÌåriÓSS7L.¿¥.ê޶MB5l&T5AUTTõA…P#T‰x’rvêéÓ6pâñx´ÏZZÞÎåóAaõ	týG¸„Œ@²âÈú}„~²Y}‚ø¼®ûêëߨôg ‰Ü !Rèxtp§„ÎNML(Ž,1(y;Ož$LL ęBèáp¸·+Ö6³ÞÞÞWx·ñF™%·[2/Ä%Q}ãà>€L¡"ö˜eªD6³‹ÁóÉT껾¾¾RmC6¯/%wò,ô$Ÿ~ôòeÙûl
>1­›ÂàNŒ\¼¨2@ŽÙ|þþŸss
 ¢¢bs€|&£|ݾovnî¶!„ŸC9r’K6\U%;{VÉ%Œñï	80QâdòÇH$òâúûµ-íNGGáÚír½g}eHéÕYûøãµÆk2åg³,–ñH8üIWW×NÄxGGµl5W®®ïvtìúclì6Kùs"jËd2͋‹‹×=X]]ýÚÿ��ªFDê゛M]744h/„ýä~ԫ§ÕñYIEND®B`‚