diff options
Diffstat (limited to 'application')
41 files changed, 4939 insertions, 402 deletions
diff --git a/application/basilisk/base/content/aboutNetError.xhtml b/application/basilisk/base/content/aboutNetError.xhtml index f2de106c2..609725c9e 100644 --- a/application/basilisk/base/content/aboutNetError.xhtml +++ b/application/basilisk/base/content/aboutNetError.xhtml @@ -96,11 +96,6 @@ return (node.style.display = toggle[node.style.display]); } - function showCertificateErrorReporting() { - // Display error reporting UI - document.getElementById("certificateErrorReporting").style.display = "block"; - } - function showPrefChangeContainer() { const panel = document.getElementById("prefChangeContainer"); panel.style.display = "block"; @@ -286,21 +281,6 @@ learnMoreLink.href = "https://support.mozilla.org/kb/how-resolve-weak-crypto-error-messages-firefox"; } - var options = JSON.parse(evt.detail); - if (options && options.enabled) { - var checkbox = document.getElementById("automaticallyReportInFuture"); - showCertificateErrorReporting(); - if (options.automatic) { - // set the checkbox - checkbox.checked = true; - } - - checkbox.addEventListener("change", function(evt) { - var event = new CustomEvent("AboutNetErrorSetAutomatic", - {bubbles:true, detail:evt.target.checked}); - document.dispatchEvent(event); - }, false); - } const hasPrefStyleError = [ "interrupted", // This happens with subresources that are above the max tls "SSL_ERROR_PROTOCOL_VERSION_ALERT", @@ -370,25 +350,6 @@ document.getElementById("learnMoreContainer").style.display = "block"; - let checkbox = document.getElementById("automaticallyReportInFuture"); - checkbox.addEventListener("change", function({target: {checked}}) { - document.dispatchEvent(new CustomEvent("AboutNetErrorSetAutomatic", { - detail: checked, - bubbles: true - })); - }); - - addEventListener("AboutNetErrorOptions", function(event) { - var options = JSON.parse(event.detail); - if (options && options.enabled) { - // Display error reporting UI - document.getElementById("certificateErrorReporting").style.display = "block"; - - // set the checkbox - checkbox.checked = !!options.automatic; - } - }, true, true); - let event = new CustomEvent("AboutNetErrorLoad", {bubbles:true}); document.getElementById("advancedButton").dispatchEvent(event); @@ -631,10 +592,6 @@ <!-- Long Description (Note: See netError.dtd for used XHTML tags) --> <div id="errorLongDesc" /> - <div id="learnMoreContainer"> - <p><a href="https://support.mozilla.org/kb/what-does-your-connection-is-not-secure-mean" id="learnMoreLink" target="new">&errorReporting.learnMore;</a></p> - </div> - <div id="prefChangeContainer" class="button-container"> <p>&prefReset.longDesc;</p> <button id="prefResetButton" class="primary" autocomplete="off">&prefReset.label;</button> @@ -652,15 +609,6 @@ <button id="errorTryAgain" class="primary" autocomplete="off" onclick="retryThis(this);">&retry.label;</button> </div> - <!-- UI for option to report certificate errors to Mozilla. Removed on - init for other error types .--> - <div id="certificateErrorReporting"> - <p class="toggle-container-with-text"> - <input type="checkbox" id="automaticallyReportInFuture" /> - <label for="automaticallyReportInFuture" id="automaticallyReportInFuture">&errorReporting.automatic2;</label> - </p> - </div> - <div id="advancedPanelContainer"> <div id="weakCryptoAdvancedPanel" class="advanced-panel"> <div id="weakCryptoAdvancedDescription"> diff --git a/application/basilisk/base/content/browser.js b/application/basilisk/base/content/browser.js index 38c340eea..9ec7715fa 100644 --- a/application/basilisk/base/content/browser.js +++ b/application/basilisk/base/content/browser.js @@ -2749,8 +2749,6 @@ var BrowserOnClick = { mm.addMessageListener("Browser:OpenCaptivePortalPage", this); mm.addMessageListener("Browser:SiteBlockedError", this); mm.addMessageListener("Browser:EnableOnlineMode", this); - mm.addMessageListener("Browser:SendSSLErrorReport", this); - mm.addMessageListener("Browser:SetSSLErrorReportAuto", this); mm.addMessageListener("Browser:ResetSSLPreferences", this); mm.addMessageListener("Browser:SSLErrorReportTelemetry", this); mm.addMessageListener("Browser:OverrideWeakCrypto", this); @@ -2765,8 +2763,6 @@ var BrowserOnClick = { mm.removeMessageListener("Browser:CertExceptionError", this); mm.removeMessageListener("Browser:SiteBlockedError", this); mm.removeMessageListener("Browser:EnableOnlineMode", this); - mm.removeMessageListener("Browser:SendSSLErrorReport", this); - mm.removeMessageListener("Browser:SetSSLErrorReportAuto", this); mm.removeMessageListener("Browser:ResetSSLPreferences", this); mm.removeMessageListener("Browser:SSLErrorReportTelemetry", this); mm.removeMessageListener("Browser:OverrideWeakCrypto", this); @@ -2808,11 +2804,6 @@ var BrowserOnClick = { msg.target.reload(); } break; - case "Browser:SendSSLErrorReport": - this.onSSLErrorReport(msg.target, - msg.data.uri, - msg.data.securityInfo); - break; case "Browser:ResetSSLPreferences": for (let prefName of PREF_SSL_IMPACT) { Services.prefs.clearUserPref(prefName); @@ -2846,20 +2837,7 @@ var BrowserOnClick = { }, onSSLErrorReport: function(browser, uri, securityInfo) { - if (!Services.prefs.getBoolPref("security.ssl.errorReporting.enabled")) { - Cu.reportError("User requested certificate error report sending, but certificate error reporting is disabled"); - return; - } - - let serhelper = Cc["@mozilla.org/network/serialization-helper;1"] - .getService(Ci.nsISerializationHelper); - let transportSecurityInfo = serhelper.deserializeObject(securityInfo); - transportSecurityInfo.QueryInterface(Ci.nsITransportSecurityInfo) - - let errorReporter = Cc["@mozilla.org/securityreporter;1"] - .getService(Ci.nsISecurityReporter); - errorReporter.reportTLSError(transportSecurityInfo, - uri.host, uri.port); + Cu.reportError("User requested certificate error report sending, but certificate error reporting is disabled"); }, onCertError: function (browser, elementId, isTopFrame, location, securityInfoAsString) { diff --git a/application/basilisk/base/content/content.js b/application/basilisk/base/content/content.js index 5758cb023..88e58b501 100644 --- a/application/basilisk/base/content/content.js +++ b/application/basilisk/base/content/content.js @@ -385,18 +385,6 @@ var AboutNetAndCertErrorListener = { let ownerDoc = originalTarget.ownerDocument; ClickEventHandler.onCertError(originalTarget, ownerDoc); } - - let automatic = Services.prefs.getBoolPref("security.ssl.errorReporting.automatic"); - content.dispatchEvent(new content.CustomEvent("AboutNetErrorOptions", { - detail: JSON.stringify({ - enabled: Services.prefs.getBoolPref("security.ssl.errorReporting.enabled"), - changedCertPrefs: this.changedCertPrefs(), - automatic: automatic - }) - })); - - sendAsyncMessage("Browser:SSLErrorReportTelemetry", - {reportStatus: TLS_ERROR_REPORT_TELEMETRY_UI_SHOWN}); }, openCaptivePortalPage: function(evt) { @@ -408,22 +396,6 @@ var AboutNetAndCertErrorListener = { sendAsyncMessage("Browser:ResetSSLPreferences"); }, - onSetAutomatic: function(evt) { - sendAsyncMessage("Browser:SetSSLErrorReportAuto", { - automatic: evt.detail - }); - - // if we're enabling reports, send a report for this failure - if (evt.detail) { - let {host, port} = content.document.mozDocumentURIIfNotForErrorPages; - sendAsyncMessage("Browser:SendSSLErrorReport", { - uri: { host, port }, - securityInfo: getSerializedSecurityInfo(docShell), - }); - - } - }, - onOverride: function(evt) { let {host, port} = content.document.mozDocumentURIIfNotForErrorPages; sendAsyncMessage("Browser:OverrideWeakCrypto", { uri: {host, port} }); diff --git a/application/basilisk/base/content/newtab/alternativeDefaultSites.json b/application/basilisk/base/content/newtab/alternativeDefaultSites.json new file mode 100644 index 000000000..018d3edcc --- /dev/null +++ b/application/basilisk/base/content/newtab/alternativeDefaultSites.json @@ -0,0 +1,50 @@ +{ + "directory": [ + { + "bgColor": "#ffffff", + "directoryId": 10000000, + "imageURI": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAIX0lEQVR4nO1afXDbZh1+sxbWsbGvsrLbuBt36766sR3sOEgiuU4kx2vTpFGKm0SKsyyOlI8laUZTulLojQEHx4CyAaNnt72yrivklo1YSpxcW7YVbKXHgCvduCvroDt6o6OtLSWN1MRWX/5I4imyJMu2bPNHnrvfSZbf6P09z+/jfV+3ACxhCUsoAEouNWGlMRLri5GuZwUSe1Ug8bcFEjsjUPgHAoX/UyCxkyKJjQoU/iOhCd8WJSvW/8vpXFFsx7PGeaJsVaytul+g8KMiic+IFA7NTNB/rggk/jeRcu26RGFris3JEqIUtkFsdo2KFK6kI52pCSR2UmirZgY9YFmxeaYg1uyqFSj8lMXI5mofRb3rOwEAJcXmDS72ex8QvO43skjv3MeT2DtRX2150cgLzVUDIonF8xBh64KQ2FWRwncPejyFK4tYq/Nmoa1mPE/pnZ1ILe4TFxpdd+SdvOhxrhabXaeLTVjfsHfzSj5K4V8QKfyjnGs3P2UiCt/v/1LeyAsNlXebkbeRSOZ/Q+JCrBH/Yt7IX+qlbhS96dM+Y+dJLC6S+BWRwmazFizf5AEAQPRtHLEhukqMwo8KTfg2oamy8t+e0uvUczwDwDWxhopHBBLvElrc+wUSm/r/IN9a3ZtrbYqUe9eHTc7PZDLvoAcsi/lq2wQSO1M88k93r7ayjzdI76sxEv/5hdryT+foRknM696q9qMg5AEAQHx83WhWtU5i56PtG1E7fYkO+B4SKNd7AoWLBSEv9G3Asol8zOs+ddFTeWc+fDrXgq2MNmEP5+PdKZB/XR4RvRnWe8tjJ8+1ECsL4mA+EQ+vcCg8gHHuPjjZvc5S6guU6/3/POG5rdi+24IEv+KwEgFQ4QFU/rAKTu90pal5fCY60PlQsf22BefHwfUKD2YVfl6ACIAKfx2UX0QNBYj6arqL7bdtSIQBnYy+2iIAzg49Cid9bm3qv11sn21FggeHUwSILGQCgIljd8Kpreq+4Koqts+2QuGBmBL9FLsFSj+sgAKFnyq2v7ZCDoO7dKOvvc7fS3vcW4rts61I8OBxXdI6/UCJADgVvmGVHfMSAelgfUA6VBeQDqmv2nuzZ3rf6Y2r3SM7DB1RwmCnOsLaiGuenbWD/JwAcqI+IEPCL8H6gAwX7omADIn5z/Wqe0Iz1sgI3edSv6EjcR78OEk4jQiJCNhnlwD1ATlBmDqdCUHzcYRf3mXoSCIMXjdK95SeEAbfslUAk4iaEc1EsLnx0vNmAhw3q3mNAFvtFCBd2i8i4bdWAgYCDBkLwIMJw8antTDos12ARSTNM8JK5Amd8URAPmosQAS8Zdr41N/lIQOS0Z2/pkZe0iWoS35+rIY8rPfLvzcWgAdDljMgAr5tlwCEWgArjUxnnJXSmX8eMnQkPrH8OasCJMJgfyEE0KZxMrJ+i2WgyZq6gHTQ0BGFv+abujs//ab4gV0CqEvAar1n0gQXizj9PUNHEmHgTSFt1At4O3eCH+8D0tW2YUmoMkKvfyQzwC/vMHREegN8Tpe4zjIY55fD14+X9tgiwC8mV2ZrHS/LGOGXRd3y8aeKVee/3GrqjBIGMcMsmL/GJu6AW4+1QZRl/mKHADmipD4gz1jJHCIgw9oXJ+8zfVsi/ImXU7bDquvfI2ugZ7wHoiwDUY6BTrbTWRie+ti0d7rGrHTU5UD45StpX5iILPMZrQTD4Q0QG+2GKMckzcF28AXgaYiv7ZNesdokCb90PO0LP2TBpxQezKpFkPmb4Q/ebFlEHOWYZBY8FtriKwDXFDAHhLvr/bJi9TzQtPeycQNUI3HihkML5M9NfB4+caRTl/jHRsvtb333gTzzTUHDPonNZFkkfjVl7Zfr+MRtiMID+McICqtDvfrE2cWfHRxz2j321K155pxE84HLLWb7BK0odX75TEYTBI43hB1ch0HE554h7GJhKrkn/4wPMjfliXMSO4alcsIvx/UanZE17pcGMppkU2iL2zDt9QSZtwqu66/Okdbb88Qd7PydVFYfkGVthLWHHk1JyOteuHRjxpNh3JNjRtE3EgDlGIiwzLlqrq/MbvKtLwkewi/PalPc8PyQPDdIP8lqQvdw92qEZWbNyBqJgnD0VTTI7H74Je/1uRL/8mDr7VWjfYeJkecgdfC/6c8JavPL0+6fitn3JtdIzxbdqLPqiNMmwtAxR7BzZ+mgL2MnHGzHPQhL/wzlmCsLc64PbYPU4Xd1zwN6WdCwT/p61uQXsH6sL5TS/dOUgY4QCZRlxsuD9EDZsM/x4KDnk5ppSsqGfHehw3QjytHfQVj6HaP+U8F1wZbhMf1Dkerzpr3Sn4Ad/5/Yc2T7TQ6OOW2YBWZimAsVRzlaRoL0DMLRV/WW19SVh05+v5nbAxsPCPpZ4Jclwj95b87kF+BgO+5Bg8yFFHKZZkO68XqimoyvGd0FqUNnU/pA1yvTdbaRXwDCtj2CsszFjFLfSjZoRbEiqEqoqtE+6H2VT5LfvPfydtvJJ0V4jb537QhzxjLRdMSsimIhq5q538DNgSnbfqs0FoHrusUd6j2ScdTNyGZTNovfHa8Z6/fmnbwaTq5r+1wj0ziZrjlmvIKYP3ew9Hvk+NOPFpT8AjxHd6ypGOl607Z+YDUL5s4iChpkdq8b7b22KOTVQIPtGxet3bmQtVA6eKhnyBP6hvnPW8UAwvpq1nIdoeS6bpWY0fK3aMfJTCMc/csqtuf+YvNMi68Mt38WDTJPoSx9DGHpmaxLI8hcqBzpCiDB9ibnM87lxeaVLUrKg+1fRVimby3LPItw9G9Rlj6Bssw/EI4+i3DM+0iQPomy9JiD69hdztI7SoPtTWWvddry7w5LWIIx/gdCuvcjoZqlLQAAAABJRU5ErkJggg==", + "type": "affiliate", + "title": "Google", + "url": "https://www.google.com/" + }, + { + "bgColor": "#E62117", + "directoryId": 10000001, + "imageURI": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAACd0lEQVR4nO3av0tVYRzH8WOIBEVDUUIGCa32FwQ5OrS42NKeRUOTdGmoqUGiLVBqa5UG+7WUREGiEqhTDkVJEA2iYZBkxKvhHumo96o3uM9z0ucNZ7zn834+XO59znm+WZZIJBKJRCKRSGwCx3AWfbiIaxjEPYzgOd7gLWbwIb8WsFjjWrU9q3U+u1C4/0yeOZ47jOROg6jkrn25e3uji27NbzC9A9n/hWnVNbVut/hOTMZ1bSqT6Ky3+A58jOsXhE/o2Lj4FryILBaSF2gpFtAT2ygCPcUCHse2icDTtcW3YSW2TQRW0JahK7ZJRLoy9Ma2iEhvhoHYFhEZyDAU2yIiwxkeBgj6FSDjXxjN8CpA0A1cxucAWY0wkeFdgKBK/pe7H1fxNUDmTpjLMB8gqLJh631A9dF6IUD2Vsxn+BYgaF0BhSIO4WYgh1osZVgOEFSzgEIRh3EL3wO4FFnOAgVtWUChiKO4gx+BvJSqgEIRx3EXP5stVsoCCkWcxH1N3EeUuoBCEafwshlipS8AJzTxW1DaAnAEtzX5B7F0BeAgrmMphFhpClB9M3UFXwI5oQQFYB8u4H0gl3VE3QninOoxVyyWozwL4AxeB8jdjqWgT4M4jUcB8nbKfKj3AUN4gN8BshphLtQbobIyEeqdYFkZzTAc2yIiw+lcQDoZSmeDe/t0ON+gPIltE4Fnxa3pnp8QacFYbKOAjCnOCOUldKhOUO12Nk+JFUroxFRkwWYypd6cYKGEVvTbfZOil2w3KVqjjHZ047xqKRWbZ4XHVed2Z/2d5a0167vYgHC9z6/df9bWs8L9uXO3RmeFE4lEIpFIJPYKfwAcall+TY3q/wAAAABJRU5ErkJggg==", + "type": "affiliate", + "title": "YouTube", + "url": "https://www.youtube.com/" + }, + { + "directoryId": 10000002, + "imageURI": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAACT0lEQVR4nO3bzWsTQRgG8PlPHMVLqRVMoQiFehJyUBAFtRCFHspExaaSoFg8CMGPSg+R3kQhh3osIbOlMVrbGKtrsbYESTbB0gqNVGu1WCkWutnXg+ihQjqxi7Oz8w481533+V32iyGEEEIZ76Rho0SZ4ewOG+D3UMatXSx9nPwqb5ySPZC0dPMzhDJelD6IrDCjQijjtvRBJIWGeY3IHkJ2EED2ALKDALIHkB2lAJoujkIwnoNQwoQL96aha3AKQgkTTtyZhKM383D4+gQEoll/AQRiWbg1XILZ+VWwaw6IrE3bgZbejNoAe8+PwEC6DOsbm0Klt679lxQGCESzMD335Z+KKw+wrzcDpcVvOyqvNMCwubjj8soCnBx44Up5ZQGeFZf1BWi7/BhqjthtzpcAseRsQwVrjgNzS9/hZWUFJq3Pf6U5MqoWQHJ8Qbh8aqoKB688cWVfzwBMvP0kVN6srMCec+7t6xmAmfmvQgCRBzOu7usZgHJ1TQjgyI283gCHrj3VG6C9bwwBEAABEEAtgAPRR9A3VKibpdUfQgD9KWvba529+8pbAMF4TqicW+th/r3eAP0pS2+Anvtv9AY4dvu53gCtMfGfI74DWN+wG5rNdwDl6preAGOFj3oDJMcXvAfQHMlAKGHWTeWD2KPw1aFC3et0NPi9wDPvAq/fif0LDMZzru6LALKLIwACIAACIAACIAACIAACIAACIAACIAACIMD/BvDKwUkZAJRx2zNHZyUBFAntTp+WXV4iQCf5c3yecUsXAMq49bv8Txsl6ZCTabOAAAAAAElFTkSuQmCC", + "title": "Facebook", + "type": "affiliate", + "url": "https://www.facebook.com/" + }, + { + "bgColor": "#ffffff", + "directoryId": 10000003, + "imageURI": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAA/CAYAAABQHc7KAAAEyUlEQVRoge2abYhVRRjHf7veVqSFhIQwa7E3ojXNpSiNgl0S+tAHKUjohbQohUgqKKwMSXpbsATdqOgFU4zKpAzMioploxI/WFBZmhRlL/S2lbpsudvd24dzjve5c58558ycey9B84MB95x5/vM/d+bMzDNHCAQCgUAgEAgE/rf0AOd6lJmKVrdDfI8SfxawIKNcEscfa8TOzBFrlj6Aimd5XnmAbx01TD5xiL3IiH3Y8zm4DXgaGALGMip/DDwHDACXKQ9wA/AiMJyi8T3wAnCvEr841t9tiR2JY/uB443YC4BHgA3ApyntTxD90FuAlaaBU4EfLIHvKIZtnAT8ZtE5O6fGCiNuFJiTM7YNWKe0PQScmRV8ncX4+zkbT1hq0bkyZ/wyI+5ux/bPM+I/ACbnCSyhv8tloMvBQAnYr+h8mDP+PRHzGXCMQ9sA14j4ceAMl+A70HtvjaMJ22jqy4i70Kh/sWO7AO+K+Jdcg6cCh6k3/gfQ6aBTAr5UdN7OiHtL1H3NxXhMN9Fkl2jM89BgPXrv3eKoc71Fx2ZqvqhTJv+kKRkQGjs94gE4PTZgGt9DNMvmpQR8pehst9R/Q9TZ5OG7EzgkNK720DjKNvTeu9RRZ4miMUH9bnCeuH8EOMXD881C40egw0PjKL3oP8Cbjjq2FWGrUW+HuDfg6XmP0NA2W060GYKy97odtbQVoQzMiu+fL66PACd4+O0VGqPANA+NOm5CHwVPOeqUgH2Kzub4/uvi2gOeXrcU8GdlCtG7ZBr/C5juqHWtojMOXCX+HgaO8/B5YqyV6GjZpjf3oI+C+x11JgF7FZ1/xL/v9PS4WmgMempYsW2MfsdtYwTRsqT9mBXgANGIc6WD2lG60EMjk0fRTS931GkHPrdo3ejpbZHQ2B+30XC6iNZm0/Q3RBOcC7Yc4WRPb0NC43ZPjVxsRDe+yFHHHLJJWevhabaIP0z0ujaNWdQmGUn5yEPrPkVnBPe1+0kRv97DhzPb0UdBr6OObZv9kIOGnJzLRPlL0+lFN+6yPe5BH0kV4E/yD+PlIm6bQ/uF2Um98Qlgbs74V5V4WVbl0GgDvsB/BBbiCnTj2lG5yVyqvX+QaOSYOsNk7y8WiPo+c1Ah2tFPesbJTmFfEfX7qU2BZVmRoSPnkMU+D1EUW5L0WErMHKq9P0o149NeqZ+w7wq7qO77f02p11Qmo6/laWnoVlFvnbh+uaJTAW616Dwo6rjmIw3lLnTjminZ+38DM8Q92yv1HfUnOh3AL/H9I7hnpA1lKrXnb0nRkqSXxf0nFC3bK7XMqCdT6o2NeIiirEE3Lvfks6kesI6hf1m2nTt8TW2uIeeLhub8vsxAT5IOUB2+8qTm2RStlYqOnOV7xLXBRj5EUWxJ0hKic/2k98dJ367azh32Es0Tz4hrTcn5fZE9I8s+ajc6m20CgrUWrdVEK0yFJub8RRhEN56UMjk+TVO7xtuK6yFMS1hIuuk82+SETSk6h3A/hmsJ7egfPypEh555ej/hHOzZYktyfl9keiqLzzc+LUlqWc7vSyfRJ3Rpegw4zUOrj/ofoKU5vy/91Jp+vIDWLkPL/J9h/0mmAT9TXa58vvIkzKe6ydpQ3FogEAgEAoFAIBCI+Rf5q90lTPZHIwAAAABJRU5ErkJggg==", + "title": "Wikipedia", + "type": "affiliate", + "url": "https://www.wikipedia.org/" + }, + { + "bgColor": "#400090", + "directoryId": 10000004, + "imageURI": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAD3ElEQVR4nO3bS4xecxjH8WmLBVVEx63JBIkEISkhJqURpAsZQioWqpeNSxraYlKpSwiDIRY0aSakqgS9qHRBIhKxYdFFFxWXIGkilYZEUCKj4zLzsfi/LN55zpiZc/lr+/6Ss3nfc57ze77n9r88/y7swxaswgLM7jpMhTlYiNWtnPd1Ga9RfIVtuB+L0J3b/FSFeejDQ9iBvRhrTzYCUKTv8RFewlrcgAtxQsYk5+Ii3IQHsBm78ONkk5oKgIn0Mz7BO3gBA7gHS3EtLsXZre1UnITj2pI5vvV7D85BL67DCvRjEJvwHj7HcBXGqwJwyKoDILeB3OoAyG0gt8oAGMYj0qdnJ17DY3i2vK1CPYmn8Cq2YwgP4rfpBix7BwwE3+aZ2F0ybqQPMSM439NlgpYFMILzAlO9glZXCf2F+cF5LsafZQJX8Q4oujKbK4j9j4aC+EdhT9nAVb0Ebw8MduNABbF/wMlB/LUVxK4MwE84JTC5uoLYK4O48/BrBbEr/Qy+XnCbfloi5h7MCuJurcSxagGMYWFg9qr/SbxQVTeEiq7Ym9OI9UYQ52ipJ1iZ6mgJ3h0Y7zG17usvOC2I01+12ToAHBCMIGHdFGKsCo4/QwJTqerqC2wMEjgGX0zi2KLH6JU6jNYFYBSXBElc/R/HjaE3OO4y1bYs/1WdvcFd4hbilgmOie6cGa1Ytaju7vDSIKHTxc9yUYtvWZ0G6wawH8cGSa0J9r0t2G92K0ZtamJA5PEgsfaOTNHjMlC3uSYADKMnSG6B9GIr6uqehYN1m2tqSGxre4KtJDdhfcF/O5ow1hSAMVweJNmNOcHvlbb3J1KTg6K7MTO62m3Jz1LBQMdk1fSo8IpJALizSUNNA/jWBNPvOFGahG1MOeYFnpgAwHNNm8kB4CDODJI/F380bSbXzNAzAYD1OYzkAjAYABjKYaQDIMdJxQDqnFMsVC4A6wIAgzmMdADkOKkYwKM5jOQCcFcAYCqjxpUpF4Bovu+IB3BfDiO5AIzrFWJlDiO5ACzpABgP4I4cRnIBWBwAWJLDSC4AfR0A4wHcksNILgCLAgB9OYzkAnDFkQ5gDZbj3ta2XCp5bVydYuncBnKrAyC3gdzqAMhtILfqBDCCb6SZ3velatGXsUFa5NC+vdjatrf2/QAfSyUyv9dlsgyAEXyGt/G8VBl+PS7A3PaGTllJCy7n40Zp8GQD3sWXSgCaDIBRqcBxGx7GYmll57hixlySaojPx83SuqW3pLXC0wKwX7oF+3GloILjUJE03X6NtAh8J76LAOzFRtwqKGY63CStX14mLen5+m9Vgqdbrd+9cgAAAABJRU5ErkJggg==", + "title": "Yahoo!", + "type": "affiliate", + "url": "https://www.yahoo.com/" + }, + { + "directoryId": 10000005, + "imageURI": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAJdklEQVR4nO1ba1QTZwL9iCY8hCDxDUpYOIUDBOVZAlJ5NQXRFlEQ8YGiRaqESlhxeRQ3FAWURRC6FYglqBHTEaI8Eg+CRMRatfKwLNL6oqer1h57XEWYbwJK9sdKixiSmRCCbrnn3D8w351770wy3zd8ADCJSUxiPMHhcPS3bdv2/tq1a9MWL16MODs7t5iamt4zMjLq0dfX76VSqU8sLCzueHt7S+3t7QtjYmLWJyYmzp1o32NGSUmJd0BAQLmRkVEPAEBOhCQS6bm3t7c0MjIyHACgMyEB1AGCILTY2NgUOzu7fwGCoUfj/Pnz/x0XF/fXgoICXW3nIYTs7Owlpqam94CGgo+ktbX1j4mJiY7azIQbMTExu3V0dF6AcQo/RF1dXYggSIj2kuFAfHx8Lhjn4ODVElCxWOygpXjKkZWVxQZaDD9EOp3eXV9fb6yVkKOho6Njgb6+fp8ig9pgfHx8gjZyjgYdX1/fhtHMqSKJRHpOJpNl6o4HAMidnJxatJJUEWpraz3xmBxOExOT30JDQ/+elpZmD14+26uqqubExcVFzJs3T53H5uCJEydMtZN4BKKiovKJmA0KChLu3bt3zmh6Bw4c0F+3bl0BEU0AgLygoCByXAKqgq2tbSdek0FBQTV4dZlM5kW8ugAAOZPJ/IeGIuHH9evXp+no6DzHa7K+vt4Lr3ZiYuIOvLoAALmnp6dQQ7HwIzc31xqvQRsbmy5AYC6fnJzsjlcbACD38/M7p5lUBBEeHp5lbm7+E4lEUnonREdHpxPRLSwsNFWmN5Kurq5XNZNITfj4+EwtLCw0dXFxcebz+UFhYWFbmExm6qZNm/IjIiKyampqDIjonTp1ajp4mwrQNP70BfD5/D9PAcXFxQZcLteOwWCw9u/f/3FwcHC6paVlOfg/K4CUlpbmEB0dvSEkJCTLxsamwtnZuXXmzJmPAACDgEBYRXxjC8jJyfFYtmzZYWNj48dgjCGV8Y0qICsryyQiIiKVTqf/BMYxNHgTC8jPz/+ISqU+AVoKDt6kAnbs2MGeMmXKANByePAmFBAbG5utyJi2OKEFJCcnx+MxqYizZs361d/fvyw9PX0bg8FgZWRk2FZVVc1pampaQERnwgoQi8VLVK0DRpJMJstWrlx5hMPhvMflckmKdN+amSDRdbuenl5fRkaGnyrdt6KAsrKyD4iYpFKpTy9cuPAuHu23ogAmk9lIxGRCQsLneLVLS0tnEdHWegFisXgu0b8ANTc3W+LVT0pKsiSirfUCDh06tJyIQSsrq5tE9PPy8jyI6Gu9gMDAQA5Bg9VE9Hfu3BlFRJ/BYHSMPRUBsNnsfUQMksnkciL6q1ev5hHRNzQ07AHa3D9A9N19QEAA7lfiAAAdOp3eTUQfACBHEMR87MlwgmgBZmZm9wHOK1RUVLSFiPYQd+/eHaOheKrB4XCyiBrk8XguqnTb29vNDAwMeolqAwDkCxcuvKbBiMoREhLyKVGDy5cvr1Cm2d3dPd3Ly+sCUd3h3LNnT7xGg46GoqKiQHUMbt68uZjL5VJG6qWkpPjS6fS76miO4Ivm5maVd9qYUV5ePlPdtb+FhUV3cHBwkbm5efrGjRvz7O3tr2og+O90dHRslUqlUxX5lkq5U7HmJEtUsnTxwG0kEJ7b4Cer32ArlXIVHq8ULBarVpPGNcng4GDP4V6xloxArNq3oq+M9hTlUeSvsfwvPxMuoKGhwWO8N0RRKBSM6Bg6nf4jgiC0zk6Egl3czsYQhxsKQ48g4QIAAMDf3//0eIWn0WiPjh075jx79uyHeMfY2dl1IAgyFwAAZA1rjqE8ihw9rPscrXRp7xO5lckaN6X0t+dt7m/LiYanPI+iPPLgmApoa2t75+W7fY2GX7RoUcvx48fpAAAgEom88NwJLBbr65ycnGlD3gZuli15VhfC6JZy9Ubzj1W6to6pAAAAEAgEDsbGxv/RVHh3d/ezEomEOvwcqamp6crGsNns/NHeLg0HPPOhV98Pf2ynQRHG+ZcFDKpdAAAAFBcX+6qzF3gkly5dqjCIVCrVs7e3v6RozKpVqw6q8idrybCFonfrUB5FDqsWfzv0c1jh2IHyKHIotL0J+lsyY7CqJXmyO4hamw/Ly8vnhIeH51Op1KdEQtNotN9WrFjxpVAodFOmv337dkMmk1k9NI5CoWCZmZk7EQSZouj4bilfT/ZtUjhW4yNCDxv0ozyKHJaZ9Mq+S1sDAACdnQgF8o1RlEeRy5picsDA3dPv9QnMHqI88iAUudYNdJV4q1NEXFyc7q5duzZ4eXmdtLKyukUikV6ZL1Cp1CeOjo6tHh4eRVwudwWfzx/1MzoSXC53alRUVCaLxapjs9kBio55fC3bGPvm0wRUQL/3yjc9n9Yz0HX090zolTSP//2OPIjdEVkDAAB42nmYJjsbWjo0CEMcfoCNkXvR5lh3BAlT2LQqhIWFTZFIJFSJRELdunUrWR0NVXhc/zdj9MxHa6B4qRAemfHasx6rYUnQjn8uGD5G9k3CHpRHkcvqQk+8Joh1lX2AHl9wf+RkAWtYvx9eSvaWSn2Iz5w0jId1O6fJLn8Wila6iVCe/oCiZ3sff8YT7CLnE6BgJQoRhxtoqcmz3l8vK9629+xW6Sx4dnUmLJv55DXxo3MeQ8ThDKxlfS77Pm8F1pxkqegkmsItSZxu75nAhf1NMZFY47ov4MlFzejLz69ClhrB/vObc3uuZM5QpIf9fM4K5VHk/W25sSpP3tdaaArPrBSgJbovlM6m+LQeWO13HqtwO4i1Zn0CRZ5+2Hf7bB5cK8a9P6hbytfDOgqsMJErC7vyWRw87VUERR5X0VJDiGc2h/IocljL+rr3Klfpv9pg9xttsLOrVIcfDtltEQOtcP0CFZg/wGvmjysyvQ8VmP8ChTa3McThBiZya8NEbm3YSUYXFNrcRgXmv8Ay2jOUp0tMd9gdidWHFsiuH2QQCqUOuFwuSXY5ZT1a6dyullkNEiKMLky6NaYTeX2JrRXILqcslIkDk2GFYyP6lSE27oGPzHiKVTiJZdV+qf2dh50mJPRo6Jby9bBLycvRSpcCeNLpe7SEovw7Aw+/MpDBUx5XsNqAbHgp2buzc4KutDp4dHGXEVq3xh02fbwFq2Htg5WuQljlcwFWLOqAJ97p7hOYPewTmD2EQuu76Emn67DauxmtdEawap8ceH5TNFofznxQs5XQBstJTGISk1AX/wUPVWOeSpK50AAAAABJRU5ErkJggg==", + "title": "Amazon", + "type": "affiliate", + "url": "https://www.amazon.com/" + } + ] +} diff --git a/application/basilisk/base/content/newtab/grid.js b/application/basilisk/base/content/newtab/grid.js index 415a25933..b6f98fa17 100644 --- a/application/basilisk/base/content/newtab/grid.js +++ b/application/basilisk/base/content/newtab/grid.js @@ -9,6 +9,7 @@ */ const GRID_BOTTOM_EXTRA = 7; // title's line-height extends 7px past the margin const GRID_WIDTH_EXTRA = 1; // provide 1px buffer to allow for rounding error +const SPONSORED_TAG_BUFFER = 2; // 2px buffer to clip off top of sponsored tag /** * This singleton represents the grid that contains all sites. @@ -181,15 +182,18 @@ var gGrid = { // Create the site's inner HTML code. site.innerHTML = + '<span class="newtab-sponsored">' + newTabString("sponsored.button") + '</span>' + '<a class="newtab-link">' + ' <span class="newtab-thumbnail placeholder"/>' + ' <span class="newtab-thumbnail thumbnail"/>' + + ' <span class="newtab-thumbnail enhanced-content"/>' + ' <span class="newtab-title"/>' + '</a>' + '<input type="button" title="' + newTabString("pin") + '"' + ' class="newtab-control newtab-control-pin"/>' + '<input type="button" title="' + newTabString("block") + '"' + - ' class="newtab-control newtab-control-block"/>'; + ' class="newtab-control newtab-control-block"/>' + + '<span class="newtab-suggested"/>'; this._siteFragment = document.createDocumentFragment(); this._siteFragment.appendChild(site); @@ -270,6 +274,6 @@ var gGrid = { this._node.style.maxWidth = gGridPrefs.gridColumns * this._cellWidth + GRID_WIDTH_EXTRA + "px"; this._node.style.height = this._computeHeight() + "px"; - this._node.style.maxHeight = this._computeHeight(gridRows) + "px"; + this._node.style.maxHeight = this._computeHeight(gridRows) - SPONSORED_TAG_BUFFER + "px"; } }; diff --git a/application/basilisk/base/content/newtab/newTab.css b/application/basilisk/base/content/newtab/newTab.css index 64b3ed7ef..658ad2ed3 100644 --- a/application/basilisk/base/content/newtab/newTab.css +++ b/application/basilisk/base/content/newtab/newTab.css @@ -122,6 +122,10 @@ input[type=button] { pointer-events: none; } +body:not(.compact) #topsites-heading { + display: none; +} + /* * If you change the sizes here, make sure you * change the preferences: @@ -136,6 +140,12 @@ input[type=button] { width: 290px; } +body.compact .newtab-cell { + width: 110px; + height: 110px; + margin: 12px; +} + /* SITES */ .newtab-site { position: relative; @@ -165,13 +175,16 @@ input[type=button] { } /* TITLES */ -.newtab-title { +.newtab-sponsored, +.newtab-title, +.newtab-suggested { overflow: hidden; position: absolute; right: 0; text-align: center; } +.newtab-sponsored, .newtab-title { bottom: 0; white-space: nowrap; @@ -179,11 +192,103 @@ input[type=button] { vertical-align: middle; } +.newtab-suggested { + border: 1px solid transparent; + border-radius: 2px; + font-size: 12px; + height: 17px; + line-height: 17px; + margin-bottom: -1px; + padding: 2px 8px; + display: none; + margin-left: auto; + margin-right: auto; + left: 0; + top: 215px; + -moz-user-select: none; +} + +.newtab-suggested-bounds { + max-height: 34px; /* 34 / 17 = 2 lines maximum */ +} + .newtab-title { left: 0; padding: 0 4px; } +.newtab-sponsored { + background-color: #FFFFFF; + border: 1px solid #E2E2E2; + border-radius: 3px; + color: #4A4A4A; + cursor: pointer; + display: none; + font-family: Arial; + font-size: 9px; + height: 17px; + left: 0; + line-height: 6px; + padding: 4px; + right: auto; + top: -15px; +} + +.newtab-site[suggested=true] > .newtab-sponsored { + background-color: #E2E2E2; + border: none; +} + +.newtab-site > .newtab-sponsored:-moz-any(:hover, [active]) { + background-color: #4A90E2; + border: 0; + color: white; +} + +.newtab-site > .newtab-sponsored[active] { + background-color: #000000; +} + +.newtab-sponsored:dir(rtl) { + right: 0; + left: auto; +} + +.newtab-site:-moz-any([type=enhanced], [type=sponsored], [suggested]) .newtab-sponsored { + display: block; +} + +.newtab-site[suggested] .newtab-suggested { + display: table; +} + +.sponsored-explain, +.sponsored-explain a, +.suggested-explain, +.suggested-explain a { + color: white; +} + +.sponsored-explain, +.suggested-explain { + background-color: rgba(51, 51, 51, 0.95); + bottom: 30px; + line-height: 20px; + padding: 15px 10px; + position: absolute; + text-align: start; +} + +.sponsored-explain input, +.suggested-explain input { + background-size: 18px; + height: 18px; + opacity: 1; + pointer-events: none; + position: static; + width: 18px; +} + /* CONTROLS */ .newtab-control { position: absolute; @@ -228,6 +333,11 @@ input[type=button] { margin: 40px 0 15px; } +body.compact #newtab-search-container { + margin-top: 0; + margin-bottom: 80px; +} + #newtab-search-container[page-disabled] { opacity: 0; pointer-events: none; diff --git a/application/basilisk/base/content/newtab/newTab.inadjacent.json b/application/basilisk/base/content/newtab/newTab.inadjacent.json new file mode 100644 index 000000000..53fb542af --- /dev/null +++ b/application/basilisk/base/content/newtab/newTab.inadjacent.json @@ -0,0 +1,3209 @@ +{ + "domains": [ + "rp5slFCxq/e7hYhXJCd0vQ==", + "2rEimAJDNX5g8HPZehOrGg==", + "nvLEpj6ZZF3LWH3wUB6lKg==", + "9Cqd4Lm3VvXuJxz79Bbqyg==", + "vNRy4LR+7TOKTixqsr5ybw==", + "N4zSgsZCo6Z4XRwZ4fu8WQ==", + "jsDtRfVbMsFg3KkEl2UiZQ==", + "TckkKpiq0a6J6NTw7uOZqw==", + "9Or7IAYuuIgZA370w9rNIg==", + "ul8WvOjCkxTz9LjT4RqTHg==", + "ZGJrbwb5878Nsqm0z+A7nQ==", + "5iT64HTeeG5SIFXG7A9o3w==", + "YSeSEghPe1kV6g8ghFcNAA==", + "0jIUl1NDmJZQkDY12VDeIQ==", + "aos6UyDyIw0R1nTK5wTawA==", + "G1xxubsq65ugK06UT2DO5A==", + "lbhavoDrDPP/8m0onwo63w==", + "ObcLsjW0SkdvY0nkZmiTGQ==", + "FHZ5084LC0nTAzZlnSKN3Q==", + "cdEr+0Fv5iaVZzalZToseg==", + "Co8WbNYbCPTFPcHpeK3hRQ==", + "qXSzhCEhByLQq9N84tqV+Q==", + "h3ufhRk5IEFaNH11rIACtQ==", + "fQ1PJ/JwazIaYoy/zy49QQ==", + "zAJqfbn54Nsm2ddGtkb59A==", + "ixPM9T8ik/gWGZ7BRIcaig==", + "/E9pwA3E3hVAZoYq3FmCyw==", + "U6ygonI8CxpruhpGB2+Q6A==", + "Igi4voB8oVMVw6WUeDSjZg==", + "jtuHIJhwoTGzavFpM7ilNw==", + "eBvTV27n6Gs+ZsBkpVynvw==", + "sFbzw0AUOGG0NEzkaSxVDg==", + "yAkIS+Ezj6woEff9YvdO7Q==", + "IP1+BwG6q60QzDADi8j7oA==", + "Q/teQEBFepHtwZ7UHa2TEA==", + "B1vDep5a1Gok5Gnth39+LA==", + "cyEIyQ2MZaPGf+K1x9Bbkg==", + "aaM+oEJnF4/nwMWyXJU8rA==", + "qpDNIpxah8FUiqXm5IRaUg==", + "ZTeJ35gMPqIv2WWbeNyIEg==", + "nzoAGQAnC/Xgg5PmOgXqkA==", + "J5pJDuNi3cqQiyaRJAJk4g==", + "2vqN53BXhXzPrKYsh6QH1A==", + "QlrzHNYxCwCBMVENvbXjQA==", + "Ou2HGn43nmsL3RWSNvMdXw==", + "3qk9lsvGTMqVMAZW+xihfw==", + "RncMe42RB2bhmUbYtGVnKQ==", + "hzNXR6dqPq1+vf4Qh5ByWA==", + "sRq3S2ZRs3H39cEQHv4Vig==", + "B4ThUBTVJOUPyOsHxikHXA==", + "A2lU9GkAdSibLO1JJfFnIA==", + "ef3HNkSvuWQrAzkuty2iqg==", + "yKDiRM6bf2xc0QXIwHYuaA==", + "AdCk4ccJuhA0bIT/61J+RQ==", + "UXvAZ7ULCVz2f505K0Wkvg==", + "ueKWblrOwVJNgiOvkXKLBQ==", + "s8u/jPuBAxu1d18HfV5Z0g==", + "hUT0Uc5YMUdNZQEGLz4hJw==", + "6jo/phmMTrEXKrNRsionGQ==", + "s/Ea/3fkyJ9honzPJkgEQQ==", + "hgu2/Jf+WrQAHfO+asW2zw==", + "kiVuTNwZ1r2lqYEZxIHyiQ==", + "24T5KVrVE2mYwJ5Goj3xJw==", + "fiWBVlfj97GGjEvf/Q9Spg==", + "5VWdlvJe7eoXMGkTtHzCUg==", + "+cFQxKa5RWVtc1z00Jujew==", + "nVa+rLH5p+yXBksLwQsjRQ==", + "5tyI6bMdb3tMIi4ewvr/SQ==", + "S6Roj31yS5bZbSFcd3f4Hg==", + "uW1Zl8iuEF8ZT/gwCBEqwA==", + "YwL+FJgxlZ8JVig+9iP5Cw==", + "ThIYK/mQsp9cMf8+rws/4Q==", + "w0oSxOhRG6kE9B868aoYVQ==", + "DJUDGQ0J32dF1kfItyxALg==", + "34/ab69lPkuAKt6WBxJPpA==", + "25jH4C9apgqWZGZP15lM6Q==", + "GxvwleSaSwILD1pG9k9buA==", + "YRAMt2ArEINo83ms6AqJ0A==", + "15HyTJNoMYzi3XCkeU5Z7A==", + "/SqjXGD+TKC90uz1vsjqUw==", + "karhKOknkhtg/LSFo9BGRA==", + "+tD1d0t3vfJvc1hUAvTT4Q==", + "rkaKbtlnyVr53D0rexLqdQ==", + "fAugw4rtnXzzRXfC1wRgOQ==", + "RgxoepF/XOwIsGat5r5HpQ==", + "Y49/EnzVz3ugXCYxFjFN7g==", + "tHMyzBm/2wNDw7TeNeujbg==", + "LlqzYV4uZpiJy4ORWPSekA==", + "M3Huar7/ded9OGgDwJhZgw==", + "QkNNATSx/PJ1XjgZyTtkUQ==", + "skVw0v6Wx00sfHAScPK1Bw==", + "v1gsIvg+C68T9wixMzL2sQ==", + "hDL75EXhl7BaYnAxkoGwbw==", + "tReG97snx2ESpXbfllCL7Q==", + "EiZBXR15dT1TMrkgkzmkvw==", + "5hRHirfD90/sdp0ILJQU8A==", + "rabElvtYtG0jW6dxAOHofg==", + "JpxoTRKWN+SEeBQ453R1YQ==", + "Faz4Lm0cpjvF0IjVkHiZMg==", + "jGErFAIoXx+50KFpVIGZiA==", + "5GzBkduKpUX7u1uwtYIFug==", + "cRBe0J9/KWRX19N2vPkCiw==", + "t/7g8t4Kr3/+SCnOn3XFWQ==", + "sd08c6jUXs5/hxND0fBkPA==", + "nTxKpqIdnHNdpDk7Dx3TEg==", + "5l+RALcce+lTDnmXI+Wqqg==", + "pzJ4QmEBGRNiiX6z0xHh8g==", + "Vfl3YbqR6JRR7SIdsUA/vA==", + "cgfhOdB376a4GAcuACADvA==", + "inAefsQM6tiIhQCMtcPcyA==", + "FTSULGL8CMhmcc7Cyf/X8A==", + "9XSWpaZyHEy7V/tuw5uZEw==", + "+VtM1opKlgb/jrCwc4YjFA==", + "oF46xheuI/NUxUOnOttzvA==", + "Qy+lvhDbJCumr6kiPLd1oA==", + "swps7UEKpIbVBJ9SnPK3zQ==", + "b7wyIiJvJs+29QePxsdWtQ==", + "x3iDZxYyuHtG/9rNW5HMYg==", + "r1dx1g5UOksywvOaQTamfA==", + "KvVF3Si/fr4JQtr7jCJiog==", + "spvZ7hhtG5QY7JXs96lBUg==", + "ECL8mA5B6CswyDH6yJ4hVw==", + "7Uu+YsdS69dMSDYUr6vTag==", + "Rnm9pSvQRRbkHpOijraLZw==", + "aQJqpnXdzqNSFhMn3EJA2Q==", + "TctnXpd7Wd5ZXKMnOFHAQA==", + "+lPqG8l6mf2FWVGWflyF/g==", + "mPmnmL2oRRJmKYjQ6TfN3g==", + "fyXFcT5ZCawDBg74n1WSpg==", + "uq5Zrxq10pO1HoPxReT5og==", + "3eoCsOKXY8RDrHSdlXqmrA==", + "9nQv2BFG56xsHViN5UpHYw==", + "RtP/nJgy/ItyuDrpBbAotg==", + "5E/drRptfHmBhJ7qplujGg==", + "cUxyZvoqXbQ0a/0I9s6Zbg==", + "womzqSigwEF30V422YmxKw==", + "FPvZqDfN8dTFHLVOuYEbUA==", + "YZMXx+scKXp/v9GaJjb1bA==", + "bjURu5MRsNIZavG5HV0eZw==", + "iY0C9uSMEOn8ikT+J7+/Eg==", + "aXkD6BzsdkMEv7A+eYqQQQ==", + "dOcOfEDGHYG2kgmrglDkPw==", + "c7GjtY05Mh+cp6SNuWY3Ig==", + "lM1uY1oVncHXNzKs/cCEtQ==", + "7jXnQJkutLsi+r9aYmrMxw==", + "NgrugWWduj2qdWnEQf9dLA==", + "faYjmy/yn5iXdS28QCIdWw==", + "68XbaOvIZpCGb4G1gaKErA==", + "Yi67HkOLtGYXeL7WD4GPrA==", + "Puo8gXuUkwcoQViaXwkdSQ==", + "L202Et5aZh60Vl20LTKNFg==", + "4agAzQ5+dnTmLZEjsZs26g==", + "LegGM1ft8Y7Ka3CUxpObvg==", + "KRdILc1QDOpow5im/qY+Kw==", + "peMW+rpwmXrSwplVuB/gTA==", + "Pic1ncr+Zn6wv75zjAdzQA==", + "ilSPlWYbiPzIC13vQUBlOw==", + "GUlDufLoTalBqrG/h3mZ6w==", + "5twANNlT57T9BG4r2D9+Hw==", + "ENrnM8HlMi+5y8Hsu4Pn4A==", + "K/DzpLEbz1MpRjA6qyYn4Q==", + "yN1cHJRHDXoFxFZacL6wsw==", + "Rc6r+KqIePH+dnj1aNYCsQ==", + "8u/z5htgqXVU5Dqwd9whJQ==", + "jV575O42EYoqDNxCm9643Q==", + "xCxGo0h3lS8N6X+ivKfpjA==", + "us+2nfpj2gjI7s14Hw0gmA==", + "bp90A/rbESwVU7eh9xRTfQ==", + "5QtMXzbTafvKDQOWZP7M8w==", + "1gFCxPLjQlQGKmSGmHwmJQ==", + "m+/dnOIe6SaIFhfvg+ybDg==", + "9Dcg87+RPq9U+swRg4dH3Q==", + "mnjbL7WFmrWp0RUqS8AMGA==", + "/0e0E+NFmq8GeE5+y2Gekw==", + "y11mbpHHtka9Ep8cr2nEvQ==", + "GdmjRyliw+W21Q+dHO4CWA==", + "X65wWQTpkg756V/Nfn92kQ==", + "xj06KvacQOxRSofbhzBNgA==", + "nVDxVhaa2o38gd1XJgE3aw==", + "4IV+JOGXrltpkQamBRXMgA==", + "jIfp8LqaYXT88r/K3a8gNw==", + "vhT4dDtbMFVyevS6yCGy0g==", + "zMs7/x8hDt8xj2FFc5+6vA==", + "1J7u2N62JGb2VrnCRlJIrw==", + "3hJs9P/RRxB0CO4q0Icb+g==", + "ZpuVY1ZyoKD3hqosdsfT6Q==", + "6KIM7C7eWgxZtqZboiJvZQ==", + "vtb6fdqirkuUkqITAmXTlw==", + "C/rEVr22mw2u/1dwUx9VTg==", + "NrY4Q5C67haCWLK8HXHq9g==", + "X9qvEftCEFWX3gBU5hXy+Q==", + "0zgw7xNB3xVGaH48TyxaNQ==", + "g7J9Jy/PJrAGRgVdvA+bEg==", + "9zb+anAyZVBzuU9rW4cJtg==", + "6Zc5FzT/m0YIjxEPYA6zDQ==", + "R2YPNlvCbVK0EodTR7czIw==", + "gsI6EGgXMtDu+1u364A8mw==", + "Bg2wBFb1/xaxeEiHfBHX+A==", + "64aapfVI6dV3LpTK56KZlg==", + "HdgcJU0W3yVnH69VYStmug==", + "qTDCcv+LK3JPFB/++t66IQ==", + "P0HEIXMnAmbvq+QYREwFzw==", + "aaU7CAmtyE35jNKTkyXOkg==", + "r9G97WKDiQ48qJHP9LBRNg==", + "8mPgQhYVDn8KshDDvvf5SA==", + "GCQiiOLDguXLiYwuLcFPsA==", + "R2Use39If2C0FVBP7KDerA==", + "23C4eh3yBb5n/RNZeTyJkA==", + "2QQtKtBAm2AjJ5c0WQ6BQA==", + "Qc+XYy2qyWJ5VVwd2PExbw==", + "zJ7ScHNxr2leCDNNcuDApA==", + "vFtC0B2oe1gck28JOM1dyg==", + "bLEntCrCHFy9pg3T3gbBzg==", + "G3PmmPGHaWHpPW30xQgm3Q==", + "me61ST+JrXM5k3/a11gRAA==", + "+LJYVZl1iPrdMU3L5+nxZw==", + "CLPzjXKGGpJ0VrkSJp7wPQ==", + "Pc+u0MAzp4lndTz4m6oQ5w==", + "cwBNvZc0u4bGABo88YUsVQ==", + "q7m/EtZySBjZNBjQ5m1hKw==", + "8ZBiwr842ZMKphlqmNngHw==", + "LMCZqd3UoF/kHHwzTdj7Tw==", + "0ODJyWKJSfObo+FNdRQkkA==", + "ViweSJuNWbx5Lc49ETEs/A==", + "x+8rwkqKCv0juoT5m1A4eg==", + "pxuSWn1u+bHtRjyh2Z8veA==", + "GKzs8mlnQQc58CyOBTlfIg==", + "Owg8qCpjZa+PmbhZew6/sw==", + "YLz+HA6qIneP+4naavq44Q==", + "9ajIS45NTicqRANzRhDWFA==", + "DjeSrUoWW2QAZOAybeLGJg==", + "qxALQrqHoDq9d91nU0DckA==", + "yPIeWcW8+3HjDagegrN8bw==", + "ocpLRASvTgqfkY20YlVFHQ==", + "RuLeQHP1wHsxhdmYMcgtrQ==", + "3WwITQML938W9+MUM56a3A==", + "ZbLVNTQSVZQWTNgC4ZGfQg==", + "X6Ln4si8G5aKar52ZH/FEQ==", + "+gbitI/gpxebN/rK7qj8Fw==", + "7cnUHeaPO8txZGGWHL9tKg==", + "epY+dsm5EMoXnZCnO4WSHw==", + "nf8x+F03kOpMhsCSUWEhVg==", + "VE4sLM5bKlLdk85sslxiLQ==", + "Hs3vUOOs2TWQdQZHs+FaQQ==", + "hkOBNoHbno2iNR7t3/d4vg==", + "Ar9N1VYgE7riwmcrM3bA2Q==", + "SbMjjI8/P8B9a9H2G0wHEQ==", + "tU31r8zla146sqczdKXufg==", + "tFmWYH82I3zb+ymk5dhepA==", + "XHjrTLXkm/bBY/BewmJcCQ==", + "FV/D5uSco+Iz8L+5t7E8SA==", + "yKLLiqzxfrCsr6+Rm6kx1Q==", + "B6reUwMkQFaCHb9BYZExpw==", + "5jyuDp82Fux+B0+zlx8EXw==", + "WGKFTWJac8uehn3N59yHJw==", + "JQf9UmutPh3tAnu7FDk3nA==", + "hv5GrLEIjPb4bGOi8RSO0w==", + "p3V7NfveB6cNxFW7+XQNeQ==", + "DinJuuBX9OKsK5fUtcaTcQ==", + "UEMwF4kwgIGxGT4jrBhMPQ==", + "Y78dviyBS3Jq9zoRD5sZtQ==", + "zbjXhZaeyMfdTb2zxvmRMg==", + "kydoXVaNcx1peR5g6i588g==", + "M2suCoFHJ5fh9oKEpUG3xA==", + "/VnKh/NDv7y/bfO6CWsLaQ==", + "S+b37XhKRm8cDwRb1gSsKQ==", + "jz7QlwxCIzysP39Cgro8jg==", + "IjmLaf3stWDAwvjzNbJpQA==", + "cHSj5dpQ04h/WyefjABfmQ==", + "+gO0bg8LY+py2dLM1sM7Ag==", + "fSANOaHD0Koaqg7AoieY9A==", + "vqYHQ3MnHrAIAr1QHwfIag==", + "Uh1mvZNGehK1AaI4a1auKQ==", + "HCbHUfsTDl6+bxPjT57lrA==", + "S7Vjy/gOWp0HozPP1RUOZw==", + "KPh6TwYpspne4KZA6NyMbw==", + "cfh5VZFmIqJH/bKboDvtlA==", + "H1zH9I8RwfEy5DGz3z+dHw==", + "2ksediOVrh4asSBxKcudTg==", + "+jVN/3ASc2O44sX6ab8/cg==", + "uvKYnKE01D5r7kR9UQyo5A==", + "BB9PTlwKAWkExt3kKC/Wog==", + "yqQPU4jT9XvRABZgNQXjgg==", + "6v3eTZtPYBfKFSjfOo2UaA==", + "49z/15Nx9Og7dN9ebVqIzg==", + "VjclDY8HN4fSpB263jsEiQ==", + "vSKsa0JhLCe9QFZKkcj58Q==", + "PolhKCedOsplEcaX4hQ0YQ==", + "D0Qt9sRlMaPnOv1xaq+XUg==", + "gBgJF0PiGEfcUnXF0RO7/w==", + "sC11Rf/mau3FG5SnON4+vQ==", + "rKb3TBM4EPx/RErFOFVCnQ==", + "+n0K7OB2ItzhySZ4rhUrMg==", + "Epm0d/DvXkOFeM4hoPCBrg==", + "K8PVQhEJCEH1ghwOdztjRw==", + "xjA21QjNdThLW3VV7SCnrg==", + "nE72uQToQFVLOzcu/nMjww==", + "2Hc5oyl0AYRy2VzcDKy+VA==", + "Y7XpxIwsGK3Lm/7jX/rRmg==", + "MK7AqlJIGqK2+K5mCvMXRQ==", + "mXycPfF5zOvcj1p4hnikWw==", + "V1fvtnJ0L3sluj9nI5KzRw==", + "TahqPgS7kEg+y6Df0HBASw==", + "EKU3OVlT4b/8j3MTBqpMNg==", + "EdvIAKdRAXj7e42mMlFOGQ==", + "uPm+cF4Jq08S5pQhYFjU8A==", + "CnIwpRVC2URVfoiymnsdYQ==", + "wyx5mnUMgP5wjykjAfTO7w==", + "OwIGvTh8FPFqa4ijNkguAw==", + "4ID0PHTzIMZz2rQqDGBVfA==", + "rlXt6zKE7DswUl0oWGOQUQ==", + "4NP8EFFJyPcuQKnBSxzKgQ==", + "bJgsuw29cO2WozqsGZxl7w==", + "b3q8kjHJPj9DWrz3yNgwjQ==", + "QGYFMpkv37CS2wmyp42ppg==", + "Kzs+/IZJO8v4uIv9mlyJ2Q==", + "ZJY+hujfd58mTKTdsmHoQQ==", + "R8FxgXWKBpEVbnl41+tWEw==", + "+CvLiih/gf2ugXAF+LgWqw==", + "BDbfe/xa9Mz1lVD82ZYRGA==", + "Dz90OhYEjpaJ/pxwg1Qxhg==", + "MLHt6Ak288G0RGhCVaOeqA==", + "r0QffVKB9OD9yGsOtqzlhA==", + "hK8KhTFcR06onlIJjTji/Q==", + "wMum67lfk5E1ohUObJgrOg==", + "JKmZqz9cUnj6eTsWnFaB0A==", + "rtJdfki8fG6CB36CADp0QA==", + "cUyqCa7Oue934riyC17F8g==", + "y4Y4mSSTw/WrIdRpktc5Hw==", + "r36kVMpF+9J+sfI3GeGqow==", + "ydVj2odhergi+2zGUwK4/A==", + "J2NFyb8cXEpZyxWDthYQiA==", + "qYuo5vY8V3tZx41Kh9/4Dw==", + "jrfRznO0nAz6tZM1mHOKIA==", + "JSr/lqDej81xqUvd/O2s7w==", + "vHGjRRSlZHJIliCwIkCAmQ==", + "sQAxqWXeiu/Su0pnnXgI9A==", + "xPe76nHyHmald6kmMQsKdg==", + "50jASqzGm4VyHJbFv8qVRA==", + "uuiJ+yB7JLDh2ulthM0mjg==", + "TI90EuS/bHq/CAlX32UFXg==", + "JgxNrUlL8wutG04ogKFPvw==", + "aMa1yVA71/w6Uf1Szc9rMA==", + "k/Aou2Jmyh8Bu3k8/+ndsQ==", + "iANKiuMqWzrHSk9nbPe3bQ==", + "7GgNLBppgAKcgJCDSsRqOQ==", + "bzVeU2qM9zHuzf7cVIsSZw==", + "rkeLYwMZ1/pW2EmIibALfA==", + "91+Yms6Oy/rP0rVjha5z9w==", + "JgXSPXDqaS1G9NqmJXZG0A==", + "ZzduJxTnXLD9EPKMn1LI4Q==", + "6W79FmpUN1ByNtv5IEXY4w==", + "Y1Nm3omeWX2MXaCjDDYnWQ==", + "ejfikwrSPMqEHjZAk3DMkA==", + "WNfDNaWUOqABQ6c6kR+eyw==", + "4BkqgraeXY7yaI1FE07Evw==", + "AjHz9GkRTFPjrqBokCDzFw==", + "T/6gSz2HwWJDFIVrmcm8Ug==", + "VWy9lB5t4fNCp4O/4n8S4w==", + "/FdZzSprPnNDPwbhV1C0Cg==", + "LUWxfy4lfgB5wUrqCOUisw==", + "r1VGXWeqGeGbfKjigaAS+Q==", + "ztULoqHvCOE6qV7ocqa4/w==", + "QCpzCTReHxGm5lcLsgwPCA==", + "Hst3yfyTB7yBUinvVzYROQ==", + "gf1Ypna/Tt+TZ08Y+GcvGg==", + "3rbml1D0gfXnwOs5jRZ3gA==", + "2vm7g3rk1ACJOTCXkLB3zA==", + "11FE2kknwYi2Qu0JUKMn3A==", + "1b2uf+CdVjufqiVpUShvHw==", + "0a4SafpDIe8V4FlFWYkMHw==", + "7btpMFgeGkUsiTtsmNxGQA==", + "dUx1REyXKiDFAABooqrKEA==", + "knYKU74onR6NkGVjQLezZg==", + "Scto+9TWxj1eZgvNKo+a9A==", + "cvZT1pvNbIL8TWg+SoTZdA==", + "1nXByug2eKq0kR3H3VjnWQ==", + "tG+rpfJBXlyGXxTmkceiKA==", + "7W9aF7dxnL+E8lbS/F7brg==", + "8vr+ERVrM99dp+IGnCWDGQ==", + "oFNMOKbQXcydxnp8fUNOHw==", + "uJZGw3IY2nCcdVeWW1geNQ==", + "q6LG0VzO1oxiogAAU63hyg==", + "f0H/AFSx2KLZi9kVx5BAZg==", + "1RQZ2pWSxT+RKyhBigtSFg==", + "scCQPl0em2Zmv/RQYar60g==", + "A2ODff+ImIkreJtDPUVrlg==", + "vRgkZZGVN7YZrlml0vxrKA==", + "68jPYo3znYoU4uWI7FH3/g==", + "iJ2nT8w8LuK11IXYqBK+YA==", + "54XELlPm8gBvx8D5bN3aUg==", + "PTAm/jGkie7OlgVOvPKpaA==", + "v7BrkRmK0FfWSHunTRHQFQ==", + "dVh/XMTUIx1nYN4q1iH1bA==", + "TSGL3iQYUgVg/O9SBKP9EA==", + "wTO49YX/ePHMWtcoxUAHpw==", + "bMb1ia0rElr2ZpZVhva0Jw==", + "sNmW2b2Ud7dZi3qOF8O8EQ==", + "3djRJvkZk9O2bZeUTe+7xQ==", + "I9KNZC1tijiG1T72C4cVqQ==", + "sQzCwNDlRsSH7iB9cTbBcg==", + "mk1CKDah7EzDJEdhL22B7w==", + "lON3WM0uMJ30F8poBMvAjQ==", + "88PNi9+yn3Bp4/upgxtWGA==", + "C+Ssp+v1r+00+qiTy2d7kA==", + "11U5XEwfMI7avx014LfC8g==", + "xsf0m31Am0W9eLhopAkfnA==", + "d13Rj3NJdcat0K/kxlHLFw==", + "UP7NXAE0uxHRXUAWPhto0w==", + "ZKXxq9yr7NGBOHidht34uQ==", + "Fd2fYFs8vtjws2kx1gf6Rw==", + "ojf6uL85EuEYgLvHoGhUrw==", + "KjnL3x+56r3M2pDj1pPihA==", + "WdCWezJU4JK43EOZ9YHVdg==", + "/jH6imhTPZ/tHI4gYz2+HA==", + "+OLntmlsMBBYPREPnS6iVw==", + "5lfLJAk1L3QzGMML3fOuSw==", + "AZs3v4KJYxdi8T1gjVjI2Q==", + "7pkUY2UzSbGnwLvyRrbxfA==", + "BjfOelfc1IBgmUxMJFjlbQ==", + "TcGhAJHRr7eMwGeFgpFBhg==", + "Y7iDCWYrO1coopM3RZWIPg==", + "mnalaO6xJucSiZ0+99r3Cg==", + "plXHHzA8X9QGwWzlJxhLRw==", + "Zqd6+81TwYuiIgLrToFOTQ==", + "1Pmnur6TbZ9cmemvu0+dSA==", + "OaNpzwshdHUZMphQXa6i8w==", + "WKehT4nGF2T7aKuzABDMlA==", + "4LvQSicqsgxQFWauqlcEjw==", + "BMZB1FwvAuEqyrd0rZrEzw==", + "YfbfE3WyYOW7083Y8sGfwQ==", + "46FCwqh+eMkf+czjhjworw==", + "734u4Y1R3u7UNUnD+wWUoA==", + "yf06Slv9l3IZEjVqvxP2aA==", + "bIk7Fa6SW7X18hfDjTKowg==", + "DnF6TYSJxlc+cwdfevLYng==", + "ionqS0piAOY2LeSReAz4zg==", + "hlMumZ7RJFpILuKs09ABtw==", + "NjeDgQ1nzH1XGRnLNqCmSg==", + "o7y4zQXQAryST2cak4gVbw==", + "29EybnMEO95Ng4l/qK4NWQ==", + "udU65VtsvJspYmamiOsgXw==", + "v1AWe5qb5y3vSKFb7ADeEw==", + "wK6Srd83eLigZ11Q20XGrg==", + "GmC+0rNDMIR+YbUudoNUXw==", + "W4utAK3ws0zjiba/3i91YA==", + "MlKWxeEh8404vXenBLq4bw==", + "Gdf4VEDLBrKJNQ8qzDsIyw==", + "Z9bDWIgcq6XwMoU2ECDR5Q==", + "VIkS30v268x+M1GCcq/A8A==", + "iPwX3SbbG9ez9HoHsrHbKw==", + "yKrsKX4/1B1C0TyvciNz5w==", + "BophnnMszW5o+ywgb+3Qbw==", + "eJLrGwPRa6NgWiOrw1pA7w==", + "eV+RwWPiGEB+76bqvw+hbA==", + "oad5SwflzN0vfNcyEyF4EA==", + "Uw6Iw+TP9ZdZGm2b/DAmkg==", + "9qWLbRLXWIBJUXYjYhY2pg==", + "dxWv00FN/2Cgmgq9U3NVDQ==", + "AX1HxQKXD12Yv5HWi39aPQ==", + "J0NauydfKsACUUEpMhQg8A==", + "mxug34EekabLz0JynutfBg==", + "bNq/hj0Cjt4lkLQeVxDVdQ==", + "nW3zZshjZEoM8KVJoVfnuQ==", + "ghp8sWGKWw20S/z1tbTxFg==", + "S4rFuiKLFKZ+cL7ldiTwpg==", + "8ZqmPJDnQSOFXvNMRQYG2Q==", + "6XYqR2WvDzx4fWO7BIOTjA==", + "Uo+FIhw1mfjF6/M8cE1c/Q==", + "bsHIShcLS134C+dTxFQHyA==", + "19yQHaBemtlgo2QkU5M6jQ==", + "sWLcS+m4aWk31BiBF+vfJQ==", + "BlCgDd7EYDIqnoAiKOXX6Q==", + "MrxR3cJaDHp0t3jQNThEyg==", + "cMo6l1EQESx1rIo+R4Vogg==", + "VOvrzqiZ1EHw+ZzzTWtpsw==", + "1/ZheMsbojazxt31j/l3iA==", + "0QxPAqRF8inBuFEEzNmLjA==", + "UXUNYEOffgW3AdBs7zTMFA==", + "lOPJhHqCtMRFZfWMX/vFZQ==", + "rXSbbRABEf4Ymtda45w8Fw==", + "jfegbZSZWkDoPulFomVntA==", + "hfcH5Az2M7rp+EjtVpPwsg==", + "VsXEBIaMkVftkxt1kIh7TA==", + "M20iX2sUfw5SXaZLZYlTaA==", + "VUDsc9RMS1fSM43c+Jo9dQ==", + "itPtn+JaO4i7wz2wOPOmDQ==", + "rCxoo4TP/+fupXMuIM0sDA==", + "cSHSg9xJz/3F6kc+hKXkwg==", + "b4BoZmzVErvuynxirLxn0w==", + "e4B3HmWjW+6hQzcOLru6Xg==", + "lTE6u9G/RzvmbuAzq2J2/Q==", + "897ptlztTjr7yk+pk8MT0Q==", + "jd6IpPJwOJW1otHKtKZ5Gw==", + "b4aFwwcWMXsSdgS1AdFOXA==", + "FltEN+7NKvzt+XAktHpfHA==", + "ZyDh3vCQWzS5DI1zSasXWA==", + "kcJ1acgBv6FtUhV8KuWoow==", + "zgEyxj/sCs63O98sZS94Yw==", + "/kGxvyEokQsVz0xlKzCn2A==", + "cxqHS4UbPolcYUwMMzgoOA==", + "62RHCbpGU8Hb+Ubn+SCTBg==", + "ePlsM/iOMme2jEUYwi15ng==", + "0fN+eHlbRS6mVZBbH/B9FQ==", + "k0XIjxp2vFG7sTrKcfAihA==", + "0rfG4gRugAwVP0i3AGVxxg==", + "M98hjSxCwvZ27aBaJTGozQ==", + "kzGNkWh3fz27cZer4BspUQ==", + "3CJbrUdW68E3Drhe4ahUnQ==", + "NGApiVkDSwzO45GT57GDQw==", + "lMjip5hbCjkD9JQjuhewDg==", + "GrSbnecYAC3j5gtoKntL0A==", + "9dbn0Kzwr9adCEfBJh78uQ==", + "64QzHOYX0A9++FqRzZRHlQ==", + "YZt6HwCvdI5DRQqndA/hBQ==", + "6GXHGF62/+jZ7PfIBlMxZw==", + "PBULPuFXb6V3Di713n3Gug==", + "8Cm19vJW8ivhFPy0oQXVNA==", + "zDSQ3NJuUGkVOlvVCATRwA==", + "6QAtjOK9enNLRhcVa2iaTg==", + "v/PshI6JjkL9nojLlMNfhg==", + "yTgN5xFIdz1MzFS6xMl5uQ==", + "SCO9nQncEcyVXGCtx30Jdg==", + "7b0oo4+qphu6HRvJq6qkHQ==", + "ol9xhVTG9e1wNo50JdZbOA==", + "hIABph+vhtSF5kkZQtOCTA==", + "k+IBS52XdOe5/hLp28ufnA==", + "6HnWgYNKohqhoa1tnjjU3A==", + "HDxGhvdQwGh0aLRYEGFqnw==", + "LDuBcL5r3PUuzKKZ9x6Kfw==", + "HPvYV94ufwiNHEImu4OYvQ==", + "h2cnQQF2/R3Mq2hWdDdrTg==", + "nqpKfidczdgrNaAyPi7BOQ==", + "2ywo4t5PPSVUCWDwUlOVwQ==", + "jZMDIu95ITTjaUX0pk4V5g==", + "bA2kaTpeXflTElTnQRp6GQ==", + "lwYQm2ynA3ik2gE1m11IEg==", + "5ugVOraop5P5z5XLlYPJyQ==", + "l2NppPcweAtmA1V2CNdk2Q==", + "DbWQI3H2tcJsVJThszfHGA==", + "H6HPFAcdHFbQUNrYnB74dA==", + "H1NJEI+fvOQbI51kaNQQjQ==", + "53UccFNzMi9mKmdeD82vAw==", + "lffapwUUgaQOIqLz2QPbAg==", + "rSvhrHyIlnIBlfNJqemEbw==", + "BLJk9wA88z6e0IQNrWJIVw==", + "5m1ijXEW+4RTNGZsDA/rxQ==", + "GG8a3BlwGrYIwZH9j3cnPA==", + "HhBHt5lQauNl7EZXpsDHJA==", + "/XjB6c5fxFGcKVAQ4o+OMw==", + "+tuUmnRDRWVLA+1k0dcUvg==", + "SM7E98MyViSSS9G0Pwzwyw==", + "c5q/8n7Oeffv3B1snHM/lA==", + "kwlAQhR2jPMmfLTAwcmoxw==", + "0b/xj6fd0x+aB8EB0LC4SA==", + "S8jlvuYuankCnvIvMVMzmg==", + "kZkmDatUOdIqs7GzH3nI1A==", + "obW3kzv2KBvuckU7F+tfjA==", + "pa8nkpAAzDKUldWjIvYMYg==", + "m+eh+ZqS74w2q0vejBkjaw==", + "LcoJBEPTlSsQwfuoKQUxEw==", + "KO2XVYyNZadcQv8aCNn5JA==", + "uvzmRcvgepW6mZbMfYgcNw==", + "KhUT2buOXavGCpcDOcbOYg==", + "fo3JL+2kPgDWfP+CCrFlFw==", + "wIfvvLKC61gOpsddUFjVog==", + "SPHU6ES1WVm0Mu2LB+YjrA==", + "LWWfRqgtph1XrpxF4N64TA==", + "LCvz/h9hbouXCmdWDPGWqg==", + "PXC6ZpdMH0ATis/jGW12iA==", + "z920R8eahJPiTsifrPYdxA==", + "GIHKW6plyLra0BmMOurFgA==", + "k6OmSlaSZ5CB0i7SD9LczQ==", + "YZ39RIXpeLAhyMgmW2vfkQ==", + "bs2QG8yYWxPzhtyMqO6u3A==", + "pKaTI+TfcV3p/sxbd2e7YQ==", + "xWYecfzAtXT9WyQ8NYY/hw==", + "Fz8EI+ZpYlbcttSHs5PfpA==", + "wfwuxn+Vja1DNwiDwL2pcQ==", + "wux5Y8AipBnc5tJapTzgEQ==", + "U+oTpcjhc0E+6UjP11OE/Q==", + "yTVJKBn72RjakMBXDoBKHg==", + "0TxcYwG72dT7Tg+eG8pP1w==", + "imZ+mwiT22sW2M9alcUFfg==", + "CkDIoAFLlIRXra78bxT/ZA==", + "4qMSNAxichi3ori/pR+o0w==", + "zNLlWGW/aKBhUwQZ4DZWoQ==", + "D31ZticrjGWAO45l5hFh7A==", + "HdXg64DBy5WcL5fRRiUVOg==", + "yhI5jHlfFJxu4eV5VJO2zQ==", + "e9GqAEnk8XI5ix6kJuieNQ==", + "EC0+iUdSZvmIEzipXgj7Gg==", + "chwv4+xbEAa93PHg8q9zgQ==", + "B1VVUbl8pU0Phyl1RYrmBg==", + "A+DLpIlYyCb9DaarpLN76g==", + "wHA+D5cObfV3kGORCdEknw==", + "+Mp+JIyO0XC5urvMyi3wvQ==", + "vUE8Iw3NyWXURpXyoNJdaw==", + "ParhxI6RtLETBSwB0vwChQ==", + "NxSdT2+MUkQN49pyNO2bJw==", + "JSyhTcHLTfzHsPrxJyiVrA==", + "PAlx9+U+yQCAc5Fi0BOG0w==", + "W/0s1x3Qm+wN8DhROk6FrQ==", + "L3Jt5dHQpWQk74IAuDOL8g==", + "VWb8U4jF/Ic0+wpoXi/y/g==", + "1wBuHqS1ciup31WTfm3NPg==", + "BDNM1u/9mefjuW1YM2DuBg==", + "SDi5+FoP9bMyKYp+vVv1XA==", + "23d9B9Gz5kUOi1I//EYsSQ==", + "/a9O7kWeXa0le45ab3+nVw==", + "PcoVtZrS1x1Q+6nfm4f80w==", + "A6TLWhipfymkjPYq8kaoDQ==", + "lzUQ1o7JAbdJYpmEqi6KnQ==", + "/2jGyMekNu7U136K+2N3Jg==", + "ZItMIn1vhGqAlpDHclg0Ig==", + "Ee4A3lTMLQ7iDQ7b8QP8Qg==", + "bO55S58bqDiRWXSAIUGJKw==", + "zeHF6fdeqcOId3fRUGscRw==", + "BxsDnI8jXr4lBwDbyHaYXw==", + "ylA6sU7Kaf9fMNIx1+sIlw==", + "ZWXfE3uGU91WpPMGyknmqw==", + "f1+fHgR5rDPsCZOzqrHM7Q==", + "8VqeoQELbCs232+Mu+HblA==", + "beSrliUu0BOadCWmx+yZyA==", + "NQVQfN3nIg9ipHiFh4BvfQ==", + "4wnUAbPT3AHRJrPwTTEjyw==", + "/cdR1i5TuQvO+u3Ov3b0KQ==", + "wtyAZIfhomcHe9dLbYoSvA==", + "ulpDxLeQnIRPnq6oaah2AA==", + "pdPwUHauXOowaq9hpL2yFw==", + "1+A9FCGP3bZhk6gU3LQtNg==", + "raYifKqev8pASjjuV+UTKQ==", + "+OERSmo7OQUUjudkccSMOA==", + "FeRovookFQIsXmHXUJhGOw==", + "USCvrMEm/Wqeu9oX6FrgcQ==", + "kly/2kE4/7ffbO34WTgoGg==", + "IindlAnepkazs5DssBCPhA==", + "Bq82MoMcDjIo/exqd/6UoA==", + "ocvA1/NbyxM0hanwwY6EiA==", + "rtd6mqFgGe98mqO0pFGbSw==", + "nvLEpj6ZZF3LWH3wUB6lKg==", + "AGd0rcLnQ0n+meYyJur1Pw==", + "wI7JrSPQwYHpv2lRsQu9nQ==", + "OnmvXbyT2BYsSDJYZhLScA==", + "CmBf5qchS1V3C2mS6Rl4bw==", + "TafM7nTE5d+tBpRCsb8TjQ==", + "wxkb8evGEaGf/rg/1XUWiA==", + "y1J+o6DC2sETFsySgpDZyA==", + "SVLHWPCCH7GPVCF7QApPbw==", + "HMWOlMmzocOIiJ7yG1YaDQ==", + "DJmrmNRKARzsTCKSMLmcNA==", + "/XC/FmMIOdhMTPqmy4DfUA==", + "63OTPaKM0xCfJOy9EDto+Q==", + "PxReytUUn/BbxYTFMu1r2Q==", + "WjDqf1LyFyhdd8qkwWk+MA==", + "/DiUApY7cVp5W9o24rkgRA==", + "alJtvTAD7dH/zss/Ek1DMQ==", + "xLm/bJBonpTs0PwsF0DvRg==", + "eAOEgF5N80A/oDVnlZYRAw==", + "LqgzKxbI6WTMz0AMIDJR5w==", + "MJ1FuK8PXcmnBAG9meU84A==", + "JLq/DrW2f26NaRwfpDXIEA==", + "fsrX00onlGvfsuiCc35pGg==", + "tXVb5f90k9l3e1oK2NGXog==", + "1JRgSHnfAQFQtSkFTttkqQ==", + "B0TaUQ6dKhPfSc5V/MjLEQ==", + "nkbLVLvh3ClKED97+nH+7Q==", + "avFTp3rS6z5zxQUZQuaBHQ==", + "lNF8PvUIN02NattcGi5u4g==", + "bBEndaOStXBpAK79FrgHaw==", + "dM9up4vKQV5LeX82j//1jQ==", + "4WO6eT0Rh6sokb29zSJQnQ==", + "RHKCMAqrPjvUYt13BVcmvw==", + "Ju4YwtPw+MKzpbC0wJsZow==", + "tzV7ixFH37ze4zuLILTlfA==", + "oPlhC4ebXdkIDazeMSn1fQ==", + "5pje7qyz8BRsa8U4a4rmoA==", + "7E6V6/zSjbtqraG7Umj+Jw==", + "8QK7emHS6rAcAF5QQemW/A==", + "LhqRc9oewY4XaaXTcnXIHQ==", + "p/7qM5+Lwzw1/lIPY91YxQ==", + "fy54Milpa7KZH/zgrDmMXQ==", + "LyPXOoOPMieqINtX8C9Zag==", + "aD4QvtMlr8Lk/zZgZ6zIMg==", + "dsueq9eygFXILDC7ZpamuA==", + "+mJLK+6qq8xFv7O/mbILTw==", + "nHUpYmfV59fe3RWaXhPs3Q==", + "VbCoGr8apEcN7xfdaVwVXw==", + "/2Chaw2M9DzsadFFkCu6WQ==", + "rKAQxu80Q8g1EEhW5Wh8tg==", + "RJJqFMeiCZHdsqs72J17MQ==", + "GF2yvI9UWf1WY7V7HXmKPA==", + "JyIDGL1m/w+pQDOyyeYupA==", + "wR2Gxb07nkaPcZHlEjr8iA==", + "PbDVq2Iw1eeM8c2o/XYdTA==", + "BL3buzSCV78rCXNEhUhuKQ==", + "i42XumprV/aDT5R0HcmfIQ==", + "DuEKxykezAvyaFO2/5ZmKQ==", + "6ACvJNfryPSjGOK39ov8Qg==", + "YaUKOTyByjUvp1XaoLiW5Q==", + "jNcMS2zX1iSZN9uYnb2EIg==", + "VRnx+kd6VdxChwsfbo1oeQ==", + "4Qinl7cWmVeLJgah8bcNkw==", + "Fiy3hkcGZQjNKSQP9vRqyA==", + "HaSc7MZphCMysTy2JbTJkw==", + "VhYGC8KYe5Up+UJ2OTLKUw==", + "K2gk9zWGd0lJFRMQ1AjQ/Q==", + "NfxVYc3RNWZwzh2RmfXpiA==", + "JGeqHRQpf4No74aCs+YTfA==", + "7VHlLw20dWck+I8tCEZilA==", + "V5HKdaTHjA8IzvHNd9C51g==", + "9TalxEyFgy6hFCM73hgb7Q==", + "R/y6+JJP8rzz1KITJ4qWBw==", + "7bM/pn4G7g7Zl6Xf1r62Lg==", + "CHsFJfsvZkPWDXkA6ZMsDQ==", + "uXuPA/2KJbb7ZX+NymN3dw==", + "o+nYS4TqJc6XOiuUzEpC3A==", + "8N3mhHt29FZDHn1P2WH1wQ==", + "uZ2gUA74/7Q33tI2TcGQlg==", + "8B12CamjOGzJDnQ+RkUf4w==", + "9FdpxlIFu11qIPdO7WC5nw==", + "G+sGF13VXPH4Ih6XgFEXxg==", + "y+1I05LDAYJ09tKMs3zW6g==", + "gnkadeCgjdmLdlu/AjBZJg==", + "1I+UVx3krrD4NhzO7dgfHQ==", + "8LNNoHe6rEQyJ0ebl151Mw==", + "yOE90OHQdyOfrAgwDvn2gA==", + "ayBGGPEy++biljvGcwIjXA==", + "o/Y4U6rWfsUCXJ72p5CUGw==", + "5kvyy902llnYGQdn2Py04w==", + "6k2cuk0McTThSMW/QRHfjA==", + "2XrR2hjDEvx8MQpHk9dnjw==", + "fv/PW8oexJYWf5De30fdLQ==", + "861mBNvjIkVgkBiocCUj/Q==", + "NKGY0ANVZ0gnUtzVx1pKSw==", + "4DIPP/yWRgRuFqVeqIyxMQ==", + "cgSEbLqqvDsNUyeA3ryJ6Q==", + "xbBxUP9JyY0wDgHDipBHeg==", + "c3WVxyC5ZFtzGeQlH5Gw+w==", + "ZKeTDCboOgCptrjSfgu0xw==", + "DjHszpS8Dgocv3oQkW/VZQ==", + "Iqszlv4R49UevjGxIPMhIA==", + "uChFnF0oCwARhAOz/d47eA==", + "0egBaMnAf0CQEXf1pCIKnA==", + "FnVNxl5AFH1AieYru2ZG+A==", + "2Ct+pLXrK6Ku1f4qehjurQ==", + "x2nSgcTjA3oGgI8mMgiqjw==", + "AUGmvZkpkKBry5bHZn4DJA==", + "x8kRVzohTdhkryvYeMvkMw==", + "rXfWkabSPN+23Ei1bdxfmQ==", + "ElTNyMR4Rg8ApKrPw88WPg==", + "9jxA/t3TQx8dQ+FBsn/YCg==", + "I07W2eDQwe6DVsm1zHKM8A==", + "0p1jMr06OyBoXQuSLYN4aQ==", + "odGhKtO4bDW5R8SYiI5yCg==", + "5Q/Y2V0iSVTK8HE8JerEig==", + "Ily2MKoFI1zr5LxBy93EmQ==", + "8dUcSkd2qnX5lD9B+fUe+Q==", + "80UE+Ivby3nwplO/HA7cPw==", + "sS6QcitMPdvUBLiMXkWQkw==", + "5VY++KiWgo7jXSdFJsPN3A==", + "aY6B28XdPnuYnbOy9uSP8A==", + "ZfRlID+pC1Rr4IY14jolMw==", + "/YuQw7oAF08KDptxJEBS9g==", + "16d+fhFlgayu3ttKVV/pbg==", + "8dBIsHMEAk7aoArLZKDZtg==", + "wRqaDZVHHurp5whOQ1kDbQ==", + "lFUq6PGk9dBRtUuiEW7Cug==", + "FoJZ61VrU8i084pAuoWhDQ==", + "4mig4AMLUw+T/ect9p4CfA==", + "Po0lhBfiMaXhl+vYh1D8gA==", + "z9cd+Qj+ueX34Zf3997MNQ==", + "1dsKN1nG6upj7kKTKuJWsQ==", + "UtLYUlQJ02oKcjNR3l+ktg==", + "O538ibsrI4gkE5tfwjxjmg==", + "G736AX070whraDxChqUrqw==", + "THs1r8ZEPChSGrrhrNTlsA==", + "pVG1hL96/+hQ+58rJJy6/A==", + "1BjsijOzgHt/0i36ZGffoQ==", + "6rIWazDEWU5WPZHLkqznuQ==", + "cdWUm6uLNzR/knuj2x75eA==", + "nsnX3tKkN1elr18E31tXDw==", + "0fnruVOCxEczscBuv4yL9A==", + "SVuEYfQ9FGyVMo1672n0Yg==", + "ZRWyfXyXqAaOEjkzWl949Q==", + "S2MAIYeDQeJ1pl9vhtYtUg==", + "vsRNZx4thFFFPneubKq1Fw==", + "kuWGANwzNRpG4XmY7KjjNg==", + "i6r+mZfyhZyqlYv56o0H+w==", + "wqWqe0KRjZlUIrGgEOG9Mg==", + "t5wh9JGSkQO78QoQoEqvXA==", + "AGoVLd0QPcXnTedT5T95JQ==", + "aRrcmH+Ud3mF1vEXcpEm4w==", + "C65PZm8rZxJ6tTEb6d08Eg==", + "oAHVGBSJ2cf4dVnb/KEYmw==", + "BuDVDLl0OGdomEcr+73XhQ==", + "bLsStF0DDebpO+xulqGNtg==", + "xukOAM0QVsA72qEy0yku9A==", + "LpoayYsTO8WLFLCSh2kf2w==", + "LEVYAE54618FrlXkDN01Kw==", + "Jm862vBTCYbv/V4T1t46+Q==", + "X4kdXUuhcUqMSduqhfLpxA==", + "cLR0Ry4/N5swqga1R6QDMw==", + "0klouNfZRHFFpdHi4ZR2hA==", + "JGx8sTyvr4bLREIhSqpFkw==", + "ZiJ/kJ9GneF3TIEm08lfvQ==", + "hP7dSa8lLn9KTE/Z0s4GVQ==", + "600bwlyhcy754W1E6tuyYg==", + "U49SfOBeqQV9wzsNkboi8Q==", + "5DDb7fFJQEb3XTc3YyOTjg==", + "6uT7LZiWjLnnqnnSEW4e/Q==", + "tq5xUJt8GtjDIh1b48SthQ==", + "eJFIQh/TR7JriMzYiTw4Sg==", + "jdRzkUJrWxrqoyNH9paHfQ==", + "RKVDdE1AkILTFndYWi9wFg==", + "AEpTVUQhIEJGlXJB6rS26A==", + "PD+yHtJxZJ2XEvjIPIJHsQ==", + "dOS+mVCy3rFX9FvpkTxGXA==", + "lz+SeifYXxamOLs1FsFmSQ==", + "QTz21WkhpPjfK8YoBrpo+w==", + "9wUIeSgNN36SFxy8v2unVg==", + "ash1r2J6B0PUxJe8P0otVQ==", + "y7yS9x3yshVhMpDbQtfYOQ==", + "f07bdNVAe9x+cAMdF1bByQ==", + "N2KovXW14hN/6+iWa1Yv3g==", + "2DNbXVgesUa7PgYQ4zX5Lw==", + "WQznrwqvMhUlM3CzmbhAOQ==", + "FpWDTLTDmkUhH/Sgo+g1Gg==", + "OVHqwV8oQMC5KSMzd5VemA==", + "Bv4mNIC72KppYw/nHQxfpQ==", + "MI+HSMRh8KTW+Afiaxd/Fw==", + "10OltdxPXOvfatJuwPVKbQ==", + "y4/HohCJxtt+cT7nLJB08w==", + "RhcqXY4OsZlVVF7ZlkTeRw==", + "/mrqas0eDX+sFUNJvCQY8g==", + "ZIZx4MehWTVXPN9cVQBmyA==", + "z20AAnvj7WsfJeOu3vemlA==", + "dL6n/JsK+Iq6UTbQuo/GOw==", + "rMm9bHK69h0fcMkMdGgeeA==", + "ftsf2qztw3NC78ep/CZXWQ==", + "/n1RLTTVpygre1dl36PDwQ==", + "/FsJYFNe+7UvsSkiotNJEQ==", + "Yy2pPhITTmkEwoudXizHqQ==", + "lizovLQxu6L9sbafNQuShQ==", + "XV5MYe0Q7YMtoBD6/iMdSw==", + "5jHgQF4SfO/zy9xy9t+9dw==", + "16iT/jCcPDrJEfi2bE5F+Q==", + "syeBfQBUmkXNWCZ1GV8xSA==", + "sr3UXbMg5zzkRduFx/as7g==", + "xUXEE7OBBCudsQnuj5ycOA==", + "ojZY7Gi2QJXE/fp6Wy31iA==", + "RlNPyhgYOIn28R4vKCVtYA==", + "KOm8PTa+ICgDrgK9QxCJZw==", + "DJoy1NSZZw87oxWGlNHhfg==", + "jEdanvXKyZdZJG6mj/3FWw==", + "Omr+zPWVucPCSfkgOzLmSQ==", + "71w3aSvuh2mBLtdqJCN3wA==", + "xjTMO2mvtpvwQrounD4e8g==", + "Zz/5VMbw1TqwazReplvsEg==", + "hIjgi20+km+Ks23NJ4VQ6Q==", + "00TVKawojyqrJkC7YqT41Q==", + "YgVpC5d5V6K/BpOD663yQA==", + "wX70jKLKJApHnhyK0r6t3A==", + "lacCCRiWdquNm4YRO7FoKA==", + "cWdlhVZD7NWHUGte24tMjg==", + "t5U+VMsTtlWAAWSW+00SfQ==", + "AMfL0rH+g8c0VqOUSgNzQw==", + "0G93AxGPVwmr66ZOleM90A==", + "9tiibT8V9VwnPOErWGNT3w==", + "+dBv88reDrjEz6a2xX3Hzw==", + "xX6atcCApI08oVLjjLteLg==", + "+YrqTEJlJCv0A2RHQ8tr1A==", + "aqcOby9QyEbizPsgO3g0yw==", + "s/BZAhh1cTV3JCDUQsV8mA==", + "x9VwDdFPp/rJ+SF16ooWYg==", + "k/OVIllJvW6BefaLEPq7DA==", + "rIMXaCaozDvrdpvpWvyZOQ==", + "qQQwJ/aF87BbnLu3okXxaw==", + "TIWSM78m0RprwgPGK/e0JA==", + "r/b5px/UImGNjT/X5sYjuA==", + "7K8l6KoP0BH82/WMLntfrg==", + "gEHGeR2F82OgBeAlnYhRSw==", + "1/SGIab+NnizimUmNDC4wA==", + "WADmxH7R6B4LR+W6HqQQ6A==", + "pcoBh5ic7baSD4TZWb3BSw==", + "es/L9iW8wsyLeC5S4Q8t+g==", + "D175i+2bZ7aWa4quSSkQpA==", + "WQMffxULFKJ+bun6NrCURA==", + "82hTTe1Nr4N2g7zwgGjxkw==", + "oyYtf08AkWLR52bXm5+sKw==", + "8uP4HUnSodw88yoiWXOIcw==", + "x2NpqNnqRihktNzpxmepkQ==", + "x5zMDuW66467ofgL3spLUQ==", + "OMO4pqzfcbQ11YO4nkTXfg==", + "N4/mQFyhDpPzmihjFJJn6w==", + "NN/ymVQNa17JOTGr6ki3eQ==", + "htDbVu1xGhCRd8qoMlBoMg==", + "S47hklz3Ow+n5aY6+qsCoA==", + "ji+1YHlRvzevs3q5Uw1gfA==", + "3Y4w0nETru3SiSVUMcWXqw==", + "XfBOCJwi2dezYzLe316ivw==", + "kMUdiwM7WR8KGOucLK4Brw==", + "V/xG5QFyx1pihimKmAo8ZA==", + "sQskMBELEq86o1SJGQqfzg==", + "6+jhreeBLfw64tJ+Nhyipw==", + "8iYdEleTXGM+Wc85/7vU9w==", + "D7piVoB2NJlBxK5owyo4+g==", + "hDGa2yLwNvgBd/v6mxmQaQ==", + "WLsh3UF4WXdHwgnbKEwRlQ==", + "D5jaV+HtXkSpSxJPmaBDXg==", + "jCgdKXsBCgf7giUKnr6paQ==", + "XqW7UBTobbV4lt1yfh0LZw==", + "EbGG4X18upaiVQmPfwKytg==", + "dXDPnL1ggEoBqR13aaW9HA==", + "Vik8tGNxO0xfdV0pFmmFDw==", + "Swjn3YkWgj0uxbZ1Idtk+A==", + "JPxEncA4IkfBDvpjHsQzig==", + "F5FcNti7lUa9DyF2iEpBug==", + "HJYgUxFZ66fRT8Ka73RaUg==", + "Jbxl8Nw1vlHO9rtu0q/Fpg==", + "fmC+85h5WBuk8fDEUWPjtQ==", + "dZgMquvZmfLqP4EcFaWCiA==", + "XF/yncdoT4ruPeXCxEhl9Q==", + "QJEbr3+42P9yiAfrekKdRQ==", + "Sr9c0ReRpkDYGAiqSy683g==", + "Nr4zGo5VUrjXbI8Lr4YVWQ==", + "NDZWIhhixq7NT8baJUR4VQ==", + "GFRJoPcXlkKSvJRuBOAYHQ==", + "WHutPin+uUEqtrA7L8878A==", + "2rhjiY0O0Lo36wTHjmlNyw==", + "XsF7R12agx/KkRWl0TyXRA==", + "R6cO8GzYfOGTIi773jtkXw==", + "zrZWcqQsUE3ocWE0fG+SOA==", + "uNzpptKjihEfKRo5A1nWmw==", + "gICaI06E9scnisonpvqCsA==", + "TA9WjiLAFgJubLN4StPwLw==", + "sBpytpE38xz0zYeT+0qc2A==", + "Ej7W3+67kCIng3yulXGpRQ==", + "nR3ACzeVF5YcLX6Gj6AGyQ==", + "b0vZfEyuTja2JYMa20Rtbg==", + "f1h+Vp+xmdZsZIziHrB2+g==", + "WzjvUJ4jZAEK7sBqw+m07A==", + "OzMR5D2LriC5yrVd5hchnA==", + "cw1gBLtxH/m4H7dSM7yvFg==", + "CZbd+UoTz0Qu1kkCS3k8Xg==", + "WtT0QAERZSiIt2SFDiAizg==", + "QsquNcCZL9wv7oZFqm64vQ==", + "FXzaxi3nAXBc8WZfFElQeA==", + "Ml3mi1lGS1IspHp3dYYClg==", + "XGAXhUFjORwKmAq9gGEcRg==", + "wOhbpTzmFla8R0kI9OiHaA==", + "qoK2keBg3hdbn7Q24kkVXg==", + "ZAQHWU6RMg4IadOxuaukyw==", + "RiahBXX2JbPzt8baPiP/8g==", + "Qx6rVv9Xj8CBjqikWI9KFA==", + "ZRnR6i+5WKMRfs3BDRBCJg==", + "91LQuW6bMSxl10J/UDX23A==", + "0dIeIM5Zvm5nSVWLy94LWg==", + "Ja3ECL7ClwDrWMTdcSQ6Ug==", + "f6iLrMpxKhFxIlfRsFAuew==", + "iSeH0JFSGK73F470Rhtesw==", + "DwOTyyCoUfaSShHZx9u6xg==", + "rdeftHE7gwAT67wwhCmkYQ==", + "kUhyc3G8Zvx8+q5q5nVEhw==", + "W8bATujVUT80v2XGJTKXDg==", + "dMRx4Mf6LrN64tiJuyWmDw==", + "9cvHJmim9e0pOaoUEtiM6A==", + "RHToSGASrwEmvzjX6VPvNQ==", + "V7eji28JSg3vTi30BCS7gw==", + "4+htiqjEz9oq0YcI/ErBVg==", + "jKJn4czwUl/6wtZklcMsSg==", + "bvyB6OEwhwCIfJ6KRhjnRw==", + "59ipbMH7cKBsF9bNf4PLeQ==", + "M/cQja3uIk1im9++brbBOA==", + "AChOz8avRYsvxlbWcorQ3w==", + "FcKjlHKfQAGoovtpf+DxWQ==", + "y+cl1/Knb9MZPz8nBB0M+w==", + "b8BZV1NfBdLi70ir4vYvZg==", + "aFJuE/s+Kbge4ppn+wulkA==", + "CWBGcRFYwZ0va6115vV/oQ==", + "glnqaRfwm6NxivtB2nySzw==", + "mPk1IsU5DmDFA/Ym5+1ojw==", + "LGwcvetzQ3QqKjNh5vA8vw==", + "yctId8ltkl3+xqi9bj+RqA==", + "spJI3xFUlpCDqzg0XCxopA==", + "V8m51xgUgywRoV6BGKUrgg==", + "rgcXxjx3pDLotH7TTfAoZw==", + "/TSsi/AwKHtP6kQaeReI3w==", + "8dbyfox/isKLsnVjQNsEXg==", + "MOrAbuJTyGKPC6MgYJlx5Q==", + "uNWFZlP7DA96sf+LWiAhtQ==", + "hNHqznsrIVRSQdII6crkww==", + "GT6WUDXiheKAM7tPg3he9A==", + "JC8Q+8yOJ52NvtVeyHo68w==", + "HMQarkPWOUDIg5+5ja2dBQ==", + "nknBKPgb7US42v8A0fTl/w==", + "fDOUzPTU2ndpbH0vgkgrJQ==", + "GTNttXfMniNhrbhn92Aykg==", + "D2JcY4zWwqaCKebLM8lPiQ==", + "/c34NtdUZAHWIwGl3JM8Tw==", + "/G26n5Xoviqldr5sg/Jl3w==", + "GF0lY77rx1NQzAsZpFtXIQ==", + "BMOi5JmFUg5sCkbTTffXHw==", + "R+beucURp/H5jLs4kW6wmg==", + "xfYZ6qhWNBqqJ0PdWRjOwA==", + "Ahpi9+nl13kPTdzL+jgqMw==", + "oIU19xAvLJwQSZzIH577aA==", + "50xwiYvGQytEDyVgeeOnMg==", + "M0ESOGwJ4WZ4Ons1ljP0bQ==", + "fS471/rN4K2m10mUwGFuLg==", + "RrE3B3X/SJi3CqCUlTYwaw==", + "oDca3JEdRb4vONT9GUUsaQ==", + "pHo1O5zrCHCiLvopP2xaWw==", + "7sCJ4RxbxRqVnF4MBoKfuQ==", + "7R5rFaXCxM3moIUtoCfM2g==", + "4rrSL6N0wyucuxeRELfAmw==", + "9Gkw+hvsR/tFY1cO89topg==", + "aw4CzX8pYbPVMuNrGCEcWg==", + "KyLQxi5UP+qOiyZl0PoHNQ==", + "T1pMWdoNDpIsHF8nKuOn2A==", + "Qv6wWP4PpycDGxe7EZNSCw==", + "ZJc7GV0Yb6MrXkpDVIuc8g==", + "aXrbsro7KLV8s4I4NMi4Eg==", + "7k5rBuh8FbTTI4TP87wBPQ==", + "NRyFx6jqO/oo9ojvbYzsAg==", + "P7eMlOz9YUcJO+pJy0Kpkw==", + "jpjpNjL1IKzJdGqWujhxCw==", + "9k1u/5TgPmXrsx3/NsYUhg==", + "c1wbFbN7AdUERO/xVPJlgw==", + "Yw4ztKv6yqxK9U1L0noFXg==", + "GnJKlRzmgKN9vWyGfMq3aA==", + "91VcAVv7YDzkC1XtluPigw==", + "h1NNwMy0RjQmLloSw1hvdg==", + "pzC8Y0Vj9MPBy3YXR32z6w==", + "UTmTgvl+vGiCDQpLXyVgOg==", + "CzWhuxwYbNB/Ffj/uSCtbw==", + "VOB+9Bcfu8aHKGdNO0iMRw==", + "X2Tawm2Cra6H7WtXi1Z4Qw==", + "6cTETZ9iebhWl+4W5CB+YQ==", + "X4hrgqMIcApsjA9qOWBoCw==", + "1buQEv2YlH/ljTgH0uJEtw==", + "FH5Z60RXXUiDk+dSZBxD3g==", + "FI2WhaSMb3guFLe3e9il8Q==", + "O/EizzJSuFY8MpusBRn7Tg==", + "b6rrRA0W247O+FfvDHbVCQ==", + "ng1Q0A7ljho3TUWWYl46sw==", + "1Ym0lyBJ9aFjhJb/GdUPvQ==", + "+OXdvbTxHtSoLg7bZMho4w==", + "cuQslgfqD2VOMhAdnApHrA==", + "pCQmlnn3BxhsV2GwqjRhXg==", + "6PzjncEw2wHZg7SP7SQk9w==", + "nqtQI1bSM7DCO9P1jGV97Q==", + "O1ckWUwuhD44MswpaD6/rw==", + "RUmhye56tQu9xXs4SRJpOQ==", + "llujnWE17U8MIHmx4SbrSA==", + "UwqBVd4Wfias4ElOjk2BzQ==", + "kBAB2PSjXwqoQOXNrv80AA==", + "w1zN28mSrI/gqHsgs4ME3A==", + "301utVPZ93AnPLYbsiJggw==", + "qIFpKKwUmztsBpJgMaVvSg==", + "QmcURiMzmVeUNaYPSOtTTg==", + "x/MpsQvziUpW40nNUHDS5Q==", + "t1O9jSNjg4DTIv/Za4NbtA==", + "1B5gxGQSGzVKoNd5Ol4N7g==", + "81iQLU+YwxNwq4of6e9z7A==", + "x0eIHCvQLd2jdDaXwSWTYQ==", + "96ORaz1JRHY1Gk8H74+C2g==", + "bNDKcFu8T5Y6OoLSV+o/Sw==", + "WrJMOuXSLKKzgmIDALkyNw==", + "+gpHnUj2GWocP74t5XWz4w==", + "z5DveTu377UW8IHnsiUGZg==", + "irnD9K8bsT+up/JUrxPw6A==", + "ginkFyNVMwkZLE49AbfqfA==", + "2hEzujfG3mR5uQJXbvOPTQ==", + "E9yeifEZtpqlD0N3pomnGw==", + "OpC/sL320wl5anx6AVEL+A==", + "D7wN7b5u5PKkMaLJBP9Ksw==", + "83WGpQGWyt6mCV+emaomog==", + "X6ulLp4noBgefQTsbuIbYQ==", + "BH+rkZWQjTp7au6vtll/CQ==", + "Ex3x5HeDPhgO2S9jjCFy4g==", + "YNqIHCmBp/EbCgaPKJ7phw==", + "312g8iTB9oJgk/OqcgR7Cw==", + "LcF0OqPWrcpHby8RwXz1Yg==", + "gaEtlJtD6ZjF5Ftx0IFt0A==", + "bvbMJZMHScwjJALxEyGIyg==", + "StoXC7TBzyRViPzytAlzyQ==", + "XqFSbgvgZn0CpaZoZiRauQ==", + "AqHVaj3JcR44hnMzUPvVYg==", + "jTg9Y6EfpON4CRFOq0QovA==", + "q/siBRjx6wNu+OTvpFKDwA==", + "goSgZ8N5UbT5NMnW3PjIlQ==", + "9onh6QKp70glZk9cX3s34A==", + "o5XVEpdP4OXH0NEO4Yfc/A==", + "a5gZ5uuRrXEAjgaoh7PXAg==", + "PaROi5U16Tk35p0EKX5JpA==", + "dtnE401dC0zRWU0S/QOTAg==", + "7J3FoFGuTIW36q0PZkgBiw==", + "hiYg+aVzdBUDCG0CXz9kCw==", + "vhdFtKVH4bVatb4n8KzeXw==", + "DWKsPfKDAtfuwgmc2dKUNg==", + "M2JMnViESVHTZaru6LDM6w==", + "G/PA+kt0N+jXDVKjR/054A==", + "6rqK8sjLPJUIp7ohkEwfZg==", + "wajwXfWz2J+O+NVaj6j2UQ==", + "C4QEzQKGxyRi2rjwioHttA==", + "N/HgDydvaXuJvTCBhG/KtA==", + "6erpZS36qZRXeZ9RN9L+kw==", + "bbBsi6tXMVWyq3SDVTIXUg==", + "aySnrShOW4/xRSzl/dtSKQ==", + "rxfACPLtKXbYua18l3WlUw==", + "L4+C6I7ausPl6JbIbmozAg==", + "R3ijnutzvK6IKV3AKHQZSA==", + "leDlMcM+B1mDE8k5SWtUeg==", + "KGI/cXVz6v6CfL8H6akcUQ==", + "NtwqUO3SKZE/9MXLbTJo/g==", + "dJHKDkfMFJeoULg7U4wwDQ==", + "IEz72W2/W8xBx5aCobUFOQ==", + "wUYhs4j3W9nIywu1HIv2JA==", + "GzbeM7snhe+M+J7X+gAsQw==", + "3/1puZTGSrD9qNKPGaUZww==", + "eKQCVzLuzoCLcB4im8147A==", + "CCK+6Dr72G3WlNCzV7nmqw==", + "CJoZn5wdTXbhrWO5LkiW0g==", + "bJ1cZW7KsXmoLw0BcoppJg==", + "OlpA9HsF8MBh7b45WZSSlg==", + "JZRjdJLgZ+S0ieWVDj8IJg==", + "uhT12XY79CtbwhcSfAmAXQ==", + "isep9d+Q7DEUf0W7CJJYzw==", + "K9A87aMlJC8XB9LuFM913g==", + "uqe3rFveJ2JIkcZQ3ZMXHQ==", + "0e8hM3E5tnABRyy29A8yFw==", + "4iiCq+HhC+hPMldNQMt0NA==", + "X4o0OkTz0ec70mzgwRfltA==", + "1E3pMgAHOnHx3ALdNoHr8Q==", + "xNilc7UOu1kyP0+nK5MrLw==", + "DQlZWBgdTCoYB1tJrNS5YQ==", + "iruDC5MeywV4yA8o1tw/KQ==", + "z+1oDVy8GJ5u/UDF+bIQdA==", + "uExgqZkkJnZj252l5dKAGg==", + "ZgdpqFrVGiaHkh9o3rDszg==", + "5N2oi2pB69NxeNt08yPLhw==", + "G37U8XTFyshfCs7qzFxATg==", + "0ZEC3hy411LkOhKblvTcqg==", + "ITZ3P47ALS0JguFms6/cDA==", + "WWN44lbUnEdHmxSfMCZc6w==", + "r2f2MyT+ww1g9uEBzdYI1w==", + "ZvvxwDd0I6MsYd7aobjLUA==", + "uQs79rbD/wEakMUxqMI48A==", + "022B0oiRMx8Xb4Af98mTvQ==", + "afMd/Hr3rYz/l7a3CfdDjg==", + "xmsYnsJq78/f9xuKuQ2pBQ==", + "dFetwmFw+D6bPMAZodUMZQ==", + "TBQpcKq2huNC5OmI2wzRQw==", + "skrQRB9xbOsiSA19YgAdIQ==", + "anyANMnNkUqr3JuPJz5Qzw==", + "6QUGE2S8oFYx4T4nW56cCw==", + "rwtF86ZAbWyKI6kLn4+KBw==", + "6txm8z4/LGCH0cpaet/Hsg==", + "wdRyYjaM11VmqkkxV/5bsA==", + "+k5lDb+QdNc9iZ01hL5yBg==", + "k/pBSWE2BvUsvJhA9Zl5uw==", + "jQjyjWCEo9nWFjP4O8lehw==", + "R6Me6sSGP5xpNI8R0xGOWw==", + "9+hjTVMQUsvVKs7Tmp52tg==", + "VQIpquUqmeyt/q6OgxzduQ==", + "KXvdjZ3rRKn60djPTCENGA==", + "5HovoyHtul8lXh+z8ywq9A==", + "1+XWdu4qCqLLVjqkKz3nmA==", + "LCj4hI520tA685Sscq6uLw==", + "b53qqLnrTBthRXmmnuXWvw==", + "WTr3q/gDkmB4Zyj7Ly20+w==", + "FbxScyuRacAQkdQ034ShTA==", + "qaTdVEeZ6S8NMOxfm+wOMA==", + "ZNrjP1fLdQpGykFXoLBNPw==", + "/Bwpt5fllzDHq2Ul6v86fA==", + "/mFp3GFkGNLhx2CiDvJv4A==", + "RppDe/WGt1Ed6Vqg1+cCkQ==", + "6M6QapJ5xtMXfiD3bMaiLA==", + "Ghuj9hAyfehmYgebBktfgA==", + "GncGQgmWpI/fZyb/6zaFCg==", + "R1TCCfgltnXBvt5AiUnCtQ==", + "5NEP7Xt7ynj6xCzWzt21hQ==", + "4yEkKp2FYZ09mAhw2IcrrA==", + "y2Tn2gmhKs5WKc01ce74rg==", + "wnfYUctNK+UPwefX5y4/Rw==", + "BV1moliPL15M14xkL+H1zw==", + "80C9TB9/XT1gGFfQDJxRoA==", + "yL1DwlIIREPuyuCFULi0uw==", + "D09afzGpwCEH0EgZUSmIZA==", + "eCy/T+a8kXggn1L8SQwgvA==", + "+dIEf5FBrHpkjmwUmGS6eg==", + "kzXsrxWRnWhkA82LsLRYog==", + "Nf9fbRHm844KZ2sqUjNgkA==", + "XAq/C+XyR6m3uzzLlMWO5Q==", + "jiV+b/1EFMnHG6J0hHpzBg==", + "HK0yf7F97bkf1VYCrEFoWA==", + "Cz1G77hsDtAjpe0WzEgQog==", + "xdCCdP8SNBOK3IsX6PiPQA==", + "8snljTGo/uICl9q0Hxy7/A==", + "sLdxIKap0ZfC3GpUk3gjog==", + "IA1jmtfpYkz/E2wD0+27WA==", + "PPa7BDMpRdxJdBxkuWCxKA==", + "CuGIxWhRLN7AalafBZLCKQ==", + "MWcV03ULc0vSt/pFPYPvFA==", + "QVwuN66yPajcjiRnVk/V8g==", + "aLY2pCT0WfFO5EJyinLpPg==", + "dGrf9SWJ13+eWS6BtmKCNw==", + "YtZ8CYfnIpMd2FFA5fJ+1Q==", + "Umd+5fTcxa3mzRFDL9Z8Ww==", + "Al8+d/dlOA5BXsUc5GL8Tg==", + "/KYZdUWrkfxSsIrp46xxow==", + "kr8tw1+3NxoPExnAtTmfxg==", + "PwvPBc+4L73xK22S9kTrdA==", + "VWNDBOtjiiI4uVNntOlu/A==", + "lJFPmPWcDzDp5B2S8Ad8AA==", + "Mofqu40zMRrlcGRLS42eBw==", + "BuENxPg7JNrWXcCxBltOPg==", + "nmD7fEU4u7/4+W/pkC4/0Q==", + "axEl7xXt/bwlvxKhI7hx4g==", + "W04GeDh+Tk/I1S85KlozRA==", + "tVw8U1AsslIFmQs4H1xshg==", + "TSPFvkgw6uLsJh66Ou0H9w==", + "IYIbEaErHoFBn8sTT9ICIQ==", + "WBu0gJmmjVdVbjDmQOkU6w==", + "ZgjifTVKmxOieco81gnccQ==", + "ZrCnZB/U/vcqEtI1cSvnww==", + "2D6yhuABiaFFoXz0Lh0C+w==", + "SfwnYZCKP1iUJyU1yq4eKg==", + "tsiqwelcBAMU/HpLGBtMGw==", + "S9L29U2P5K8wNW+sWbiH7w==", + "sGLPmr568+SalaQr8SE/PA==", + "Hm6MG6BXbAGURVJKWRM6ZA==", + "euxzbIq4vfGYoY3s1QmLcw==", + "/FchS2nPezycB8Bcqc2dbg==", + "ZKvox7BaQg4/p5jIX69Umw==", + "HkbdaMuDTPBDnt3wAn5RpQ==", + "eddhS+FkXxiUnbPoCd5JJw==", + "Muf2Eafcf9G3U2ZvQ9OgtQ==", + "a7Pv1SOWYnkhIUC22dhdDA==", + "O839JUrR+JS30/nOp428QA==", + "2qK2ZEY9LgdKSTaLf6VnLA==", + "BTiGLT6XdZIpFBc91IJY6g==", + "EqYq2aVOrdX5r7hBqUJP7g==", + "SIuKH/Qediq0TyvqUF93HQ==", + "c5ymZKqx/td1MiS2ERiz9A==", + "rqucO37p86LpzehR/asCSQ==", + "1tpM0qgdo7JDFwvT0TD78g==", + "Ar1Eb/f/LtuIjXnnVPYQlA==", + "V8q+xz4ljszLZMrOMOngug==", + "P5WPQc5NOaK7WQiRtFabkw==", + "Xo8ZjXOIoXlBjFCGdlPuZw==", + "jTmPbq+wh30+yJ/dRXk1cA==", + "KSumhnbKxMXQDkZIpDSWmQ==", + "Kh/J1NpDBGoyDU+Mrnnxkg==", + "3BjLFon1Il0SsjxHE2A1LQ==", + "dml2gqLPsKpbIZ93zTXwCQ==", + "ZyoaR1cMiKAsElmYZqKjLA==", + "vnOJ3e9Zd4wPx8PX7QgZzQ==", + "2melaInV0wnhBpiI3da6/A==", + "mUek9NkXm8HiVhQ6YXiyzA==", + "RZTpYKxOAH9JgF1QFGN+hw==", + "a/Y6IAVFv0ykRs9WD+ming==", + "yhRi5M9Etuu9HSu4d24i3w==", + "+1gcqAqaRZwCj5BGiZp3CA==", + "o1zeXHJEKevURAAbUE/Vog==", + "cvOg7N4DmTM+ok1NBLyBiQ==", + "uPdjKJIGzN7pbGZDZdCGaA==", + "REnDNe9mGfqVGZt+GdsmjQ==", + "XqTK/2QuGWj50tGmiDxysA==", + "bL2FuwsPT7a7oserJQnPcw==", + "uO+uK1DntCxVRr1KttfUIw==", + "Xconi1dtldH90Wou9swggw==", + "HRF3WL/ue3/QlYyu7NUTrA==", + "5LuFDNKzMd2BzpWEIYO2Ww==", + "dNTU+/2DdZyGGTdc+3KMhQ==", + "H+NHjk/GJDh/GaNzMQSzjg==", + "/Ph/6l/lFNVqxAje1+PgFA==", + "4WRdAjiUmOQg2MahsunjAg==", + "j+lDhAnWAyso+1N8cm85hQ==", + "nFBXCPeiwxK9mLXPScXzTA==", + "vGKknndb4j6VTV8DxeT4fQ==", + "fdqt93OrpG13KAJ5cASvkg==", + "1MIn73MLroxXirrb+vyg2Q==", + "Q7teXmTHAC5qBy+t7ugf0w==", + "bWwtTFlhO3xEh/pdw0uWaQ==", + "Omi2ZB9kdR1HrVP2nueQkA==", + "+ZozWaPWw8ws1cE5DJACeg==", + "3FH4D31nKV13sC9RpRZFIg==", + "4kXlJNuT79XXf1HuuFOlHw==", + "36XDmX6j542q+Oei1/x0gw==", + "MqqDg9Iyt4k3vYVW5F+LDw==", + "cvrGmub2LoJ+FaM5HTPt9A==", + "uC2lzm7HaMAoczJO6Z/IhQ==", + "MnStiFQAr3QlaRZ02SYGaQ==", + "ZuayB6IpbeITokKGVi9R5w==", + "FtxpWdhEmC6MT61qQv4DGA==", + "KujFdhhgB9q4oJfjYMSsLg==", + "ZV8mEgJweIYk0/l0BFKetA==", + "gDLjxT7vm07arF4SRX5/Vg==", + "/MEOgAhwb7F0nBnV4tIRZA==", + "k2KP9oPMnHmFlZO6u6tgyw==", + "fbTm027Ms0/tEzbGnKZMDA==", + "HOi+vsGAae4vhr+lJ5ATnQ==", + "9Bet5waJF5/ZvsYaHUVEjQ==", + "Wd0dOs7eIMqW5wnILTQBtg==", + "z/e5M2lE9qh3bzB97jZCKA==", + "b16O4LF7sVqB7aLU2f3F1A==", + "lsBTMnse2BgPS6wvPbe7JA==", + "0nOg18ZJ/NicqVUz5Jr0Hg==", + "MFeXfNZy6Q9wBfZmPQy3xg==", + "ksOFI9C7IrDNk4OP6SpPgw==", + "NquRbPn8fFQhBrUCQeRRoQ==", + "ccmy4GVuX967KaQyycmO0w==", + "DY0IolKTYlW+jbKLPAlYjQ==", + "aJFbBhYtMbTyMFBFIz/dTA==", + "9pdeedz1UZUlv8jPfPeZ1g==", + "qZ2q5j2gH3O56xqxkNhlIA==", + "N7fHwb397tuQHtBz1P80ZQ==", + "uOkMpYy/7DYYoethJdixfQ==", + "E9ajQQMe02gyUiW3YLjO/A==", + "dFSavcNwGd8OaLUdWq3sng==", + "TAD0Lk95CD86vbwrcRogaQ==", + "jLI3XpVfjJ6IzrwOc4g9Pw==", + "CzP13PM/mNpJcJg8JD3s6w==", + "GSWncBq4nwomZCBoxCULww==", + "9k17UqdR1HzlF7OBAjpREA==", + "TrWS+reCJ0vbrDNT5HDR9w==", + "CXMKIdGvm60bgfsNc+Imvg==", + "6NP81geiL14BeQW6TpLnUA==", + "hW9DJA1YCxHmVUAF7rhSmQ==", + "8M0kSvjn5KN8bjsMdUqKZQ==", + "eS/vTdSlMUnpmnl1PbHjyw==", + "h2B0ty0GobQhDnFqmKOpKQ==", + "n7KL1Kv027TSxBVwzt9qeA==", + "yYmnM/WOgi+48Rw7foGyXA==", + "FhthAO5IkMyW4dFwpFS7RA==", + "81ZH3SO0NrOO+xoR/Ngw1g==", + "t7HaNlXL16fVwjgSXmeOAQ==", + "N+K1ibXAOyMWdfYctNDSZQ==", + "yQCLV9IoPyXEOaj3IdFMWw==", + "3+zsjCi7TnJhti//YXK35w==", + "600mjiWke4u0CDaSQKLOOg==", + "K4VS+DDkTdBblG93l2eNkA==", + "5KOgetfZR+O2wHQSKt41BQ==", + "kj5WqpRCjWAfjM7ULMcuPQ==", + "AxEjImKz4tMFieSo7m60Sg==", + "jp5Em/0Ml4Txr1ptTUQjpg==", + "jQVlDU+HjZ2OHSDBidxX5A==", + "4NHQwbb3zWq2klqbT/pG6g==", + "PeJS+mXnAA6jQ0WxybRQ8w==", + "l6Ssc04/CnsqUua9ELu2iQ==", + "nFPDZGZowr3XXLmDVpo7hg==", + "yYBIS9PZbKo7Gram7IXWPA==", + "/HU2+fBqfWTEuqINc0UZSA==", + "adT+OjEB2kqpeYi4kQ6FPg==", + "GW1Uaq622QamiiF24QUA0g==", + "rTwJggSxTbwIYdp07ly0LA==", + "4yrFNgqWq17zVCyffULocA==", + "vvh9vAIrXjIwLVkuJb5oDQ==", + "C7UaoIEXsVRxjeA0u99Qmw==", + "x1A74vg/hwwjAx6GrkU8zw==", + "7XRiYvytcwscemlxd9iXIQ==", + "64AA4jLHXc1Dp15aMaGVcA==", + "u/QxrP1NOM/bOJlJlsi/jQ==", + "5M3dFrAOemzQ0MAbA8bI5w==", + "wyqmQGB6vgRVrYtmB2vB7w==", + "8vLA9MOdmLTo3Qg+/2GzLA==", + "/u5W2Gab4GgCMIc4KTp2mg==", + "lhAOM81Ej6YZYBu45pQYgg==", + "MArbGuIAGnw4+fw6mZIxaw==", + "ZZImGypBWwYOAW43xDRWCQ==", + "L2IeUnATZHqOPcrnW2APbA==", + "bQKkL+/KUCsAXlwwIH0N3w==", + "f09F7+1LRolRL5nZTcfKGA==", + "hPnPQOhz4QKhZi02KD6C+A==", + "78b8sDBp28zUlYPV5UTnYw==", + "iVDd2Zk7vwmEh97LkOONpQ==", + "LHQETSI5zsejvDaPpsO29g==", + "Yjm5tSq1ejZn3aWqqysNvA==", + "gkrg0NR0iCaL7edq0vtewA==", + "Lo1xTCEWSxVuIGEbBEkVxA==", + "8GyPup4QAiolFJ9v80/Nkw==", + "3L3KEBHhgDwH615w4OvgZA==", + "hJSP7CostefBkJrwVEjKHA==", + "9oQ/SVNJ4Ye9lq8AaguGAQ==", + "n7Bns42aTungqxKkRfQ5OQ==", + "K5lhaAIZkGeP5rH2ebSJFw==", + "ZaPsR9X77SNt7dLjMJUh8A==", + "18ndtDM9UaNfBR1cr3SHdA==", + "0QbH4oI8IjZ9BRcqRyvvDQ==", + "J/eAtAPswMELIj8K2ai+Xg==", + "qenHZKKlTUiEFv6goKM/Mw==", + "vjrSYGUpeKOtJ2cNgLFg2g==", + "DA+3fjr7mgpwf6BZcExj0w==", + "rh7bzsTQ1UZjG7amysr0Gg==", + "tFMJRXfWE9g78O1uBUxeqQ==", + "e/nWuo5YalCAFKsoJmFyFA==", + "gqehq46BhFX2YLknuMv02w==", + "Uudn69Kcv2CGz2FbfJSSEA==", + "Otz/PgYOEZ1CQDW54FWJIQ==", + "IwfeA6d0cT4nDTCCRhK+pA==", + "jgNijyoj2JrQNSlUv4gk4A==", + "KzWdWPP2gH0DoMYV4ndJRg==", + "pv/m2mA/RJiEQu2Qyfv9RA==", + "ATmMzriwGLl+M3ppkfcZNA==", + "tVvWdA+JqH0HR2OlNVRoag==", + "n6QVaozMGniCO0PCwGQZ6w==", + "gU3gu8Y5CYVPqHrZmLYHbQ==", + "cBBOQn7ZjxDku0CUrxq2ng==", + "w+jzM0I5DRzoUiLS/9QIMQ==", + "MLlVniZ08FHAS5xe+ZKRaA==", + "wMyJLQJdmrC2TSeFkIuSvQ==", + "dG98w8MynOoX7aWmkvt+jg==", + "zm+z+OOyHhljV2TjA3U9zw==", + "Tk5MAqd1gyHpkYi8ErlbWg==", + "g6zSo8BvLuKqdmBFM1ejLA==", + "d0VAZLbLcDUgLgIfT1GmVQ==", + "SNPYH4r/J9vpciGN2ybP5Q==", + "XA2hUgq3GVPpxtRYiqnclg==", + "fVCRaPsTCKEVLkoF4y3zEw==", + "FpgdsQ2OG+bVEy3AeuLXFQ==", + "JquDByOmaQEpFb47ZJ4+JA==", + "e369ZIQjxMZJtopA//G55Q==", + "Nsd+DfRX6L54xs+iWeMjCQ==", + "+/UCpAhZhz368iGioEO8aQ==", + "e5l9ZiNWXglpw6nVCtO8JQ==", + "Cl1u5nGyXaoGyDmNdt38Bw==", + "6sNP0rzCCm3w976I2q2s/w==", + "qcpeZWUlPllQYZU6mHVwUw==", + "kzYddqiMsY3EYrpxve2/CQ==", + "3iC21ByW/YVL+pSyppanWw==", + "3HPOzIZxoaQAmWRy9OkoSg==", + "xsCZVhCk2qJmOqvUjK3Y8Q==", + "i2sSvrTh/RdLJX0uKhbrew==", + "7Y87wVJok20UfuwkGbXxLg==", + "ibsb1ncaLZXAYgGkMO7tjQ==", + "+VfRcTBQ80KSeJRdg0cDfw==", + "kgKWQJJQKLUuD2VYKIKvxA==", + "ARKIvf4+zRF8eCvUITWPng==", + "1fztTtQWNMIMSAc5Hr6jMQ==", + "md6zNd7ZBn3qArYqQz7/fw==", + "kvAaIJb+aRAfKK104dxFAA==", + "UIXytIHyVODxlrg+eQoARA==", + "Dk0L/lQizPEb3Qud6VHb1Q==", + "64YsV2qeDxk2Q6WK/h7OqA==", + "90dtIMq0ozJXezT2r79vMQ==", + "wy/Z8505o4sVovk4UuBp1A==", + "ytDXLDBqWiU1w3sTurYmaw==", + "9pk75mBzhmcdT+koHvgDlw==", + "DQeib845UqBMEl96sqsaSg==", + "UPYR575ASaBSZIR3aX1IgQ==", + "swsVVsPi/5aPFBGP+jmPIw==", + "1cj1Fpd3+UiBAOahEhsluA==", + "ifuJCv9ZA84Vz1FYAPsyEA==", + "uu+ncs63SdQIvG6z4r7Q3Q==", + "UvC1WADanMrhT+gPp/yVqA==", + "llOvGOUDVfX68jKnAlvVRA==", + "SusSOsWNoAerAIMBVWHtfA==", + "VznvTPAAwAev+yhl9oZT0w==", + "luR/kvHLwA6tSdLeTM4TzA==", + "PcdBtV8pfKU0YbDpsjPgwg==", + "5l6kDfjtZjkTZPJvNNOVFw==", + "4FBBtWPvqJ3dv4w25tRHiQ==", + "JJbzQ/trOeqQomsKXKwUpQ==", + "0bj069wXgEJbw7dpiPr8Tg==", + "tejpAZp7y32SO2+o4OGvwQ==", + "kq26VyDyJTH/eM6QvS2cMw==", + "+zBkeHF4P8vLzk1iO1Zn3Q==", + "BzkNYH03gF/mQY71RwO3VA==", + "RnxOYPSQdHS6fw4KkDJtrA==", + "65KhGKUBFQubRRIEdh9SwQ==", + "k1DPiH6NkOFXP/r3N12GyA==", + "DqzWt1gfyu/e7RQl5zWnuQ==", + "gnez1VrH+UHT8C/SB9qGdA==", + "vZtL0yWpSIA+9v8i23bZSg==", + "FNvQqYoe0s/SogpAB7Hr1Q==", + "6nwR+e9Qw0qp8qIwH9S/Mg==", + "BPT4PQxeQcsZsUQl33VGmg==", + "rOYeIcB+Rg5V6JG2k4zS2w==", + "Je1UESovkBa9T6wS0hevLw==", + "HFHMGgfOeO0UPrray1G+Zw==", + "NBmB/cQfS+ipERd7j9+oVg==", + "iIm8c9uDotr87Aij+4vnMw==", + "S3VQa6DH+BdlSrxT/g6B5g==", + "BwRA+tMtwEvth28IwpZx+w==", + "vg3jozLXEmAnmJwdfcEN0g==", + "gW0oKhtQQ7BxozxUWw5XvQ==", + "Q6vGRQiNwoyz7bDETGvi5g==", + "Ak3rlzEOds6ykivfg39xmw==", + "G4qzBI1sFP2faN+tlRL/Bw==", + "ND9l4JWcncRaSLATsq0LVw==", + "yQmNZnp/JZywbBiZs3gecA==", + "ZoNSxARrRiKZF5Wvpg7bew==", + "GhpJfRSWZigLg/azTssyVA==", + "QyyiJ5I/OZC50o89fa5EmQ==", + "4kj0S8XlmhHXoUP7dQItUw==", + "Dt8Q5ORzTmpPR2Wdk0k+Aw==", + "/hFhjFGJx2wRfz6hyrIpvA==", + "eFimq+LuHi42byKnBeqnZQ==", + "JrKGKAKdjfAaYeQH8Y2ZRQ==", + "JFFeXsFsMA59iNtZey7LAA==", + "91SdBFJEZ65M+ixGaprY/A==", + "+S+WXgVDSU1oGmCzGwuT3g==", + "1X14kHeKwGmLeYqpe60XEA==", + "4xojeUxTFmMLGm6jiMYh/Q==", + "+1e7jvUo8f2/2l0TFrQqfA==", + "8WU1vLKV1GhrL7oS9PpABg==", + "DYWCPUq/hpjr6puBE7KBHg==", + "birqO8GOwGEI97zYaHyAuw==", + "6e8boFcyc8iF0/tHVje4eQ==", + "FLvED9nB9FEl9LqPn7OOrA==", + "ji306HRiq965zb8EZD2uig==", + "AklOdt9/2//3ylUhWebHRw==", + "VGRCSrgGTkBNb8sve0fYnQ==", + "oqlkgrYe9aCOwHXddxuyag==", + "KXuFON8tMBizNkCC48ICLA==", + "9aKH1u5+4lgYhhLztQ4KWA==", + "3hVslsq98QCDIiO40JNOuA==", + "OOS6wQCJsXH8CsWEidB35A==", + "YXHQ3JI9+oca8pc/jMH6mA==", + "V9vkAanK+Pkc4FGAokJsTA==", + "OFLn4wun6lq484I7f6yEwg==", + "3WVBP9fyAiBPZAq3DpMwOQ==", + "5gGoDPTc/sOIDLngmlEq4A==", + "E2lvMXqHdTw0x+KCKVnblg==", + "f1Gs++Iilgq9GHukcnBG3w==", + "uIkVijg7RPi/1j7c18G1qA==", + "9T7gB0ZkdWB0VpbKIXiujQ==", + "KCJJfgLe00+tjSfP6EBcUg==", + "WbAdlac/PhYUq7J2+n5f+w==", + "GLnS9wDCje7TOMvBX9jJVA==", + "VAg/aU5nl72O+cdNuPRO4g==", + "kzTl7WH/JXsX1fqgnuTOgw==", + "1HDgfU7xU7LWO/BXsODZAQ==", + "D0W5F7gKMljoG5rlue1jrg==", + "9reBKZ1Rp6xcdH1pFQacjw==", + "SSKhl2L3Mvy93DcZulADtA==", + "hlu7os0KtAkpBTBV6D2jyQ==", + "sfte/o9vVNyida/yLvqADA==", + "gYGQBLo5TdMyXks0LsZhsQ==", + "dNq2InSVDGnYXjkxPNPRxA==", + "fiv0DJivQeqUkrzDNlluRw==", + "msstzxq++XO0AqNTmA7Bmg==", + "DCjgaGV5hgSVtFY5tcwkuA==", + "aMmrAzoRWLOMPHhBuxczKg==", + "qNOSm15bdkIDSc/iUr+UTQ==", + "2nSTEYzLK77h5Rgyti+ULQ==", + "BhKO1s1O693Fjy1LItR/Jw==", + "kRnBEH6ILR5GNSmjHYOclw==", + "R97chlspND/sE9/HMScXjQ==", + "1Oykse0jQVbuR3MvW5ot4A==", + "Dmyb+a7/QFsU4d2cVQsxDw==", + "W5now3RWSzzMDAxsHSl++Q==", + "IrDuBrVu1HWm0BthAHyOLQ==", + "V6zyoX6MERIybGhhULnZiw==", + "ZQSDYgpsimK+lYGdXBWE/w==", + "lV70RNlE++04G1KFB3BMXA==", + "QmSBVvdk0tqH9RAicXq2zA==", + "qNyy6Fc0b8oOMWqqaliZ/w==", + "xvipmmwKdYt4eoKvvRnjEg==", + "Q7Df6zGwvb4rC+EtIKfaSw==", + "n1M2dgFPpmaICP+JwxHUug==", + "1k8tL2xmGFVYMgKUcmDcEw==", + "fFvXa1dbMoOOoWZdHxPGjw==", + "UP9mmAKzeQqGhod7NCqzhg==", + "PMCWKgog/G+GFZcIruSONw==", + "dnvatwSEcl73ROwcZ4bbIQ==", + "hY82j+sUQQRpCi6CCGea5A==", + "QoUC9nyK1BAzoUVnBLV2zw==", + "+aF4ilbjQbLpAuFXQEYMWQ==", + "XTCcsVfEvqxnjc0K5PLcyw==", + "ML7ipnY/g8mA1PUIju1j8Q==", + "tOkYq1BZY152/7IJ6ZYKUg==", + "2bsIpvnGcFhTCSrK9EW1FQ==", + "Af9j1naGtnZf0u1LyYmK1w==", + "ZmblZauRqO5tGysY3/0kDw==", + "PF0lpolQQXlpc3qTLMBk8w==", + "emVLJVzha7ui5OFHPJzeRQ==", + "gR0sgItXIH8hE4FVs9Q07w==", + "PTW+fhZq/ErxHqpM0DZwHQ==", + "g0kHTNRI7x/lAsr92EEppw==", + "24H9q+E8pgCEdFS7JO5kzQ==", + "HtDXgMuF8PJ1haWk88S0Ew==", + "pulldyBt2sw6QDvTrCh6zw==", + "ehwc2vvwNUAI7MxU4MWQZw==", + "enj9VEzLbmeOyYugTmdGfQ==", + "auvG6kWMnhCMi7c7e9eHrw==", + "R36O31Pj8jn0AWSuqI7X2Q==", + "3AVYtcIv7A5mVbVnQMaCeA==", + "T9WoUJNwp8h4Yydixbx6nA==", + "t0WN8TwMLgi8UVEImoFXKg==", + "mS99D+CXhwyfVt8xJ+dJZA==", + "AFdelaqvxRj6T3YdLgCFyg==", + "Lu02ic/E94s42A14m7NGCA==", + "7w3b73nN/fIBvuLuGZDCYQ==", + "O209ftgvu0vSr0UZywRFXA==", + "MQvAr+OOfnYnr/Il/2Ubkg==", + "e5txnNRcGs2a9+mBFcF1Qg==", + "YA0kMTJ82PYuLA4pkn4rfw==", + "QIKjir/ppRyS63BwUcHWmw==", + "P3y5MoXrkRTSLhCdLlnc4A==", + "WY7mCUGvpXrC8gkBB46euw==", + "g0GbRp2hFVIdc7ct7Ky7ag==", + "Cv079ZF55RnbsDT27MOQIA==", + "cvMJ714elj/HUh89a9lzOQ==", + "9inw7xzbqAnZDKOl/MfCqA==", + "F58ktE4O0f7C9HdsXYm+lw==", + "CsPkyTZADMnKcgSuNu1qxg==", + "mAzsVkijuqihhmhNTTz65g==", + "FxnbKnuDct4OWcnFMT/a5w==", + "P5wS+xB8srW4a5KDp/JVkA==", + "ctJYJegZhG42i+vnPFWAWw==", + "OrqJKjRndcZ8OjE3cSQv7g==", + "aXqiibI6BpW3qilV6izHaQ==", + "BA18GEAOOyVXO2yZt2U35w==", + "saEpnDGBSZWqeXSJm34eOA==", + "CUEueo8QXRxkfVdfNIk/gg==", + "H0UMAUfHFQH92A2AXRCBKA==", + "CT9g8mKsIN/VeHLSTFJcNQ==", + "E4NtzxQruLcetC23zKVIng==", + "203EqmJI9Q4tWxTJaBdSzA==", + "Do3aqbRKtmlQI2fXtSZfxQ==", + "JaYQXntiyznQzrTlEeZMIw==", + "VK95g27ws2C6J2h/7rC2qA==", + "CQ0PPwgdG3N6Ohfwx1C8xA==", + "/MeHciFhvFzQsCIw39xIZA==", + "u5cUPxM6/spLIV8VidPrAA==", + "OwArFF1hpdBupCkanpwT+Q==", + "PdBgXFq5mBqNxgCiqaRnkw==", + "lC5EumoIcctvxYqwELqIqw==", + "xoPSM86Se+1hHX0y3hhdkw==", + "F5bs0GGWBx9eBwcJJpXbqg==", + "1mw6LfTiirFyfjejf8QNGA==", + "daBhAvmE9shDgmciDAC5eg==", + "AvdeYb9XNOUFWiiz+XGfng==", + "JJJkp1TpuDx5wrua2Wml7g==", + "3y5Xk65ShGvWFbQxcZaQAQ==", + "l6QHU5JsJExNoOnqxBPVbw==", + "X2YfnPXgF2VHVX95ZcBaxQ==", + "g6udffWh7qUnSIo1Ldn3eA==", + "V2P75JFB4Se9h7TCUMfeNA==", + "IUZ5aGpkJ9rLgSg6oAmMlw==", + "pyrUqiZ98gVXxlXQNXv5fA==", + "83ERX2XJV3ST4XwvN7YWCg==", + "eJDUejE/Ez/7kV+S74PDYg==", + "M9oqlPb63e0kZE0zWOm+JQ==", + "0rTYcuVYdilO7zEfKrxY3A==", + "rfPTskbnoh3hRJH6ZAzQRg==", + "QtD35QhE8sAccPrDnhtQmQ==", + "jpNUgFnanr9Sxvj2xbBXZw==", + "nykEOLL/o7h0cs0yvdeT2g==", + "wX2URK6eDDHeEOF3cgPgHA==", + "jqPQ0aOuvOJte/ghI1RVng==", + "nHTsDl0xeQPC5zNRnoa0Rw==", + "mNv2Q67zePjk/jbQuvkAFA==", + "HjlPM2FQWdILUXHalIhQ5w==", + "cHkOsVd80Rgwepeweq4S1g==", + "kTCHqcb3Cos51o8cL+MXcg==", + "nvmBgp0YlUrdZ05INsEE8Q==", + "kFrRjz7Cf2KvLtz9X6oD+w==", + "Tmx0suRHzlUK4FdBivwOwA==", + "bG+P+p34t/IJ1ubRiWg6IA==", + "uESeJe/nYrHCq4RQbrNpGA==", + "ehfPlu6YctzzpQmFiQDxGA==", + "ZH5Es/4lJ+D5KEkF1BVSGg==", + "HHxn4iIQ7m0tF1rSd+BZBg==", + "DQJRsUwO1fOuGlkgJavcwQ==", + "HITIVoFoWNg04NExe13dNA==", + "MeKXnEfxeuQu9t3r/qWvcw==", + "Y7OofF9eUvp7qlpgdrzvkg==", + "XSb71ae0v+yDxNF5HJXGbQ==", + "p8W1LgFuW6JSOKjHkx3+aA==", + "y2JOIoIiT9cV1VxplZPraQ==", + "MN94B0r5CNAF9sl3Kccdbw==", + "Q1pdQadt12anX1QRmU2Y/A==", + "JIC8R48jGVqro6wmG2KXIw==", + "eWgLAqJOU+fdn8raHb9HCw==", + "5CMadLqS2KWwwMCpzlDmLw==", + "H1y2iXVaQYwP0SakN6sa+Q==", + "CUCjG2UaEBmiYWQc6+AS1Q==", + "yV3IbbTWAbHMhMGVvgb/ZQ==", + "80PCwYh4llIKAplcDvMj4g==", + "fgdUFvQPb5h+Rqz8pzLsmw==", + "2SI4F7Vvde2yjzMLAwxOog==", + "kJdY3XEdJS/hyHdR+IN0GA==", + "IKgNa2oPaFVGYnOsL+GC5Q==", + "eXFOya6x5inTdGwJx/xtUQ==", + "uTA0XbiH3fTeVV7u5z0b3w==", + "onFcHOO1c3pDdfCb5N4WkQ==", + "Slu3z535ijcs5kzDnR7kfA==", + "SElc2+YVi3afE1eG1MI7dQ==", + "ND2hYtAIQGMxBF7o7+u7nQ==", + "Pv9FWQEDLKnG/9K9EIz4Gw==", + "6CjtF1S2Y6RCbhl7hMsD+g==", + "rs2QrN4qzAHCHhkcrAvIfA==", + "eTMPXa60OTGjSPmvR4IgGw==", + "pvXHwJ3dwf9GDzfDD9JI3g==", + "CRmAj3JcasAb4iZ9ZbNIbw==", + "rcY4Ot40678ByCfqvGOGdg==", + "l4ddTxbTCW5UmZW+KRmx6A==", + "NKRzJndo2uXNiNppVnqy1g==", + "0NrvBuyjcJ2q6yaHpz/FOA==", + "3YXp1PmMldUjBz3hC6ItbA==", + "CmVD6nh8b/04/6JV9SovlA==", + "HjyxyL0db2hGDq2ZjwOOhg==", + "4PBaoeEwUj79njftnYYqLg==", + "vFFzkWgGyw6OPADONtEojQ==", + "czBWiYsQtNFrksWwoQxlOw==", + "9iB7+VwXRbi6HLkWyh9/kg==", + "zwY6tCjjya/bgrYaCncaag==", + "mW6TCje9Zg2Ep7nzmDjSYQ==", + "5LJqHFRyIwQKA4HbtqAYQQ==", + "INNBBin5ePwTyhPIyndHHg==", + "dChBe9QR29ObPFu/9PusLg==", + "1dhq3ozNCx0o4dV1syLVDA==", + "nyaekSYTKzfSeSfPrB114Q==", + "TfNHjSTV8w6Pg6+FaGlxvA==", + "m/Lp4U75AQyk9c8cX14HJg==", + "uU1TX5DoDg6EcFKgFcn0GA==", + "B+TsxQZf0IiQrU8X9S4dsQ==", + "6b7ue29cBDsvmj1VSa5njw==", + "RvXWAFwM+mUAPW1MjPBaHA==", + "pdaY6kZ8+QqkMOInvvACNA==", + "7nr3zyWL+HHtJhRrCPhYZA==", + "BXGlq54wIH6R3OdYfSSDRw==", + "b06KGv5zDYsTxyTbQ9/eyA==", + "8ylI1AS3QJpAi3I/NLMYdg==", + "0fpe9E6m3eLp/5j5rLrz2Q==", + "Qrh7OEHjp80IW+YzQwzlJg==", + "lqhgbgEqROAdfzEnJ17eXA==", + "Dulw855DfgIwiK7hr3X8vg==", + "wsp+vmW8sEqXYVURd/gjHA==", + "VoPth5hDHhkQcrQTxHXbuw==", + "TgWe70YalDPyyUz6n88ujg==", + "9lLhHcrPWI4EsA4fHIIXuw==", + "UymZUnEEQWVnLDdRemv+Tw==", + "qnkFUlJ8QT322JuCI3LQgg==", + "/p/aCTIhi1bU0/liuO/a2Q==", + "hWoxz5HhE50oYBNRoPp1JQ==", + "88tB/HgUIUnqWXEX++b5Aw==", + "Z8T1b9RsUWf59D06MUrXCQ==", + "BZTzHJGhzhs3mCXHDqMjnQ==", + "XfY+QUriCAA1+3QAsswdgg==", + "TZ3ATPOFjNqFGSKY3vP2Hw==", + "cl4t9FXabQg7tbh1g7a0OA==", + "9SgfpAY0UhNC6sYGus9GgQ==", + "d/Wd3Ma1xYyoMByPQnA9Cw==", + "DDitrRSvovaiXe2nfAtp4g==", + "s+eHg5K9zZ2Jozu5Oya9ZQ==", + "z3L2BNjQOMOfTVBUxcpnRA==", + "v4xIYrfPGILEbD/LwVDDzA==", + "HoaBBw2aPCyhh0f5GxF+/Q==", + "i9IRqAqKjBTppsxtPB7rdw==", + "cWUg7AfqhiiEmBIu+ryImA==", + "E+02smwQGBIxv42LIF2Y4Q==", + "W4CfeVp9mXgk04flryL7iA==", + "9SUOfKtfKmkGICJnvbIDMg==", + "xweGAZf+Yb3TtwR/sGmGIA==", + "EJgedRYsZPc4cT9rlwaZhg==", + "wv4NC9CIpwuGf/nOQYe/oA==", + "ZXeMG5eqQpZO/SGKC4WQkA==", + "bzXXzQGZs8ustv0K4leklA==", + "RkQK9S1ezo+dFYHQP57qrw==", + "mrinv7KooPQPrLCNTRWCFg==", + "qIUJPanWmGzTD1XxvHp+6w==", + "Js7g8Dr6XsnGURA4UNF0Ug==", + "dpSTNOCPFHN5yGoMpl1EUA==", + "ugY8rTtJkN4CXWMVcRZiZw==", + "rqHKB91H3qVuQAm+Ym5cUA==", + "UjmDFO7uzjl4RZDPeMeNyg==", + "cu4ZluwohhfIYLkWp72pqA==", + "ZydKlOpn2ySBW0G3uAqwuw==", + "LWd0+N3M94n81qd346LfJQ==", + "VbHoWmtiiPdABvkbt+3XKQ==", + "J4MC9He6oqjOWsYQh9nl3Q==", + "ahAbmGJZvUOXrcK6OydNGQ==", + "Byhi4ymFqqH8uIeoMRvPug==", + "LSN9GmT6LUHlCAMFqpuPIA==", + "IAMInfSYb76GxDlAr1dsTg==", + "qYHdgFAXhF/XcW4lxqfvWQ==", + "26+yXbqI+fmIZsYl4UhUzw==", + "AwPTZpC28NJQhf5fNiJuLA==", + "SESKbGF35rjO64gktmLTWA==", + "YVlRQHQglkbj3J2nHiP/Hw==", + "DdaT4JLC7U0EkF50LzIj9w==", + "G0LChrb0OE5YFqsfTpIL1Q==", + "5Yrj6uevT8wHRyqqgnSfeg==", + "NmWmDxwK5FpKlZbo0Rt8RA==", + "iUsUCB0mfRsE9KPEQctIzw==", + "Tm4zk2Lmg8w4ITMI31NfTA==", + "Vu0E+IJXBnc25x4n41kQig==", + "6wkfN8hyKmKU6tG3YetCmw==", + "trjM81KANPZrg9iSThWx6Q==", + "iGuY4VxcotHvMFXuXum7KA==", + "ICPdBCdONUqPwD5BXU5lrw==", + "alqHQBz8V446EdzuVfeY5Q==", + "74FW/QYTzr/P1k6QwVHMcw==", + "avZp5K7zJvRvJvpLSldNAw==", + "TIKadc6FAaRWSQUg5OATgg==", + "PfkWkSbAxIt1Iso0znW0+Q==", + "Z+bsbVP91KrJvxrujBLrrQ==", + "mrxlFD3FBqpSZr1kuuwxGg==", + "nUgYO7/oVNSX8fJqP2dbdg==", + "tVhXk9Ff3wAg56FbdNtcFg==", + "DdiNGiOSoIZxrMrGNvqkXw==", + "CDsanJz7e3r/eQe+ZYFeVQ==", + "wVfSZYjMjbTsD2gaSbwuqQ==", + "6c0iuya20Ys8BsvoI4iQaQ==", + "qCPfJTR8ecTw6u6b1yHibA==", + "fZrj3wGQSt8RXv0ykJROcQ==", + "gR3B8usSEb0NLos51BmJQg==", + "vTAmgfq3GxL4+ubXpzwk5w==", + "jLkmUZ6fV56GfhC0nkh4GA==", + "3v09RHCPTLUztqapThYaHg==", + "nULSbtw2dXbfVjZh33pDiA==", + "IHhyR6+5sZXTH+/NrghIPg==", + "tnUtJ/DQX9WaVJyTgemsUA==", + "7xTKFcog69nTmMfr5qFUTA==", + "IshzWega6zr3979khNVFQQ==", + "Ng5v/B9Z10TTfsDFQ/XrXQ==", + "hnCUnoxofUiqQvrxl73M8w==", + "VPa7DG6v7KnzMvtJPb88LQ==", + "4LtQrahKXVtsbXrEzYU1zQ==", + "Ev/xjTi7akYBI7IeZJ4Igw==", + "41WEjhYUlG6jp2UPGj11eQ==", + "JvXTdChcE3AqMbFYTT3/wg==", + "2rOkEVl90EPqfHOF5q2FYw==", + "mjFBVRJ7TgnJx+Q74xllPg==", + "Uy4QI8D2y1bq/HDNItCtAw==", + "wMOE/pEKVIklE75xjt6b6w==", + "ZcuIvc8fDI+2uF0I0uLiVA==", + "CX/N/lHckmAtHKysYtGdZA==", + "j8to4gtSIRYpCogv2TESuQ==", + "iS9wumBV5ktCTefFzKYfkA==", + "ewPT4dM12nDWEDoRfiZZnA==", + "vWn9OPnrJgfPavg4D6T/HQ==", + "J/PNYu4y6ZMWFFXsAhaoow==", + "catI+QUNk3uJ+mUBY3bY8Q==", + "F8tEIT5EhcvLNRU5f0zlXQ==", + "zyA9f5J7mw5InjhcfeumAQ==", + "MlOOZOwcRGIkifaktEq0aQ==", + "Pt3i49uweYVgWze3OjkjJA==", + "sfIClgTMtZo9CM9MHaoqhQ==", + "HeQbUuBM9sqfXFXRBDISSw==", + "SFn78uklZfMtKoz2N0xDaQ==", + "H6j2nPbBaxHecXruxiWYkA==", + "fU32wmMeD44UsFSqFY0wBA==", + "hDILjSpTLqJpiSSSGu445A==", + "ieEAgvK9LsWh2t6DsQOpWA==", + "xfjBQk3CrNjhufdPIhr91A==", + "j+8/VARfbQSYhHzj0KPurQ==", + "/zFLRvi75UL8qvg+a6zqGg==", + "U0KmEI6e5zJkaI4YJyA5Ew==", + "uXvr6vi5kazZ9BCg2PWPJA==", + "jEqP0dyHKHiUjZ9dNNGTlQ==", + "1xWx5V3G9murZP7srljFmA==", + "OIwtfdq37eQ0qoXuB2j7Hw==", + "fUAy3f9bAglLvZWvkO2Lug==", + "duRFqmvqF93uf/vWn8aOmg==", + "ysRQ+7Aq7eVLOp88KnFVMA==", + "CkZUmKBAGu0FLpgPDrybpw==", + "TrLmfgwaNATh24eSrOT+pw==", + "83wtvSoSP9FVBsdWaiWfpA==", + "pUfWmRXo70yGkUD/x5oIvA==", + "PybPZhJErbRTuAafrrkb3g==", + "8hsfXqi4uiuL+bV1VrHqCw==", + "TVlHoi8J7sOZ2Ti7Dm92cQ==", + "za4rzveYVMFe3Gw531DQJQ==", + "JKphO0UYjFqcbPr6EeBuqg==", + "hqeSvwu8eqA072iidlJBAw==", + "bUF0JIfS4uKd3JZj2xotLQ==", + "hKOsXOBoFTl/K4xE+RNHDA==", + "JHBjKpCgSgrNNACZW1W+1w==", + "Rrq0ak9YexLqqbSD4SSXlw==", + "+NmjwjsPhGJh9bM10SFkLw==", + "xMIHeno2qj3V8q9H1xezeg==", + "TcFinyBrUoAEcLzWdFymow==", + "Rvchz/xjcY9uKiDAkRBMmA==", + "TYlnrwgyeZoRgOpBYneRAg==", + "PbnxuVerGwHyshkumqAARg==", + "iFtadcw8v6betKka9yaJfg==", + "7wgT9WIiMVcrj48PVAMIgw==", + "2HHqeGRMfzf3RXwVybx+ZQ==", + "tdgI9v7cqJsgCAeW1Fii1A==", + "4ZFYKa7ZgvHyZLS6WpM8gA==", + "gB8wkuIzvuDAIhDtNT1gyA==", + "g1ELwsk6hQ+RAY1BH640Pg==", + "UZoibx+y1YJy/uRSa9Oa2w==", + "yS/yMnJDHW0iaOsbj4oPTg==", + "JzW+yhrjXW1ivKu3mUXPXg==", + "/wIZAye9h1TUiZmDW0ZmYA==", + "YK+q7uJObkQZvOwQ9hplMg==", + "Rs8deApkoosIJSfX7NXtAA==", + "MsCloSmTFoBpm7XWYb+ueQ==", + "3ltw31yJuAl4VT6MieEXXw==", + "1+qmrbC8c7MJ6pxmDMcKuA==", + "AYxGETZs477n2sa1Ulu/RQ==", + "Q0TJZxpn3jk67L7N+YDaNA==", + "OGpsXRHlaN8BvZftxh1e7A==", + "UbABE6ECnjB+9YvblE9CYw==", + "kZ0D191c/uv4YMG15yVLDw==", + "QWURrsEgxbJ8MWcaRmOWqw==", + "xiFlcSfa/gnPiO+LwbixcQ==", + "Szko0IPE7RX2+mfsWczrMg==", + "Ugt8HVC/aUzyWpiHd0gCOQ==", + "8j9GVPiFdfIRm/+ho7hpoA==", + "KR401XBdgCrtVDSaXqPEiA==", + "d0NBFiwGlQNclKObRtGVMQ==", + "XEwOJG24eaEtAuBWtMxhwg==", + "0Y6iiZjCwPDwD/CwJzfioQ==", + "MvMbvZNKbXFe2XdN+HtnpQ==", + "fsoXIbq0T0nmSpW8b+bj+g==", + "Uje3Ild84sN41JEg3PEHDg==", + "i6ZYpFwsyWyMJNgqUMSV1A==", + "+P5q4YD1Rr5SX26Xr+tzlw==", + "z4oKy2wKH+sbNSgGjbdHGw==", + "XwKWd03sAz8MmvJEuN08xA==", + "Xv0mNYedaBc57RrcbHr9OA==", + "9oUawSwUGOmb0sDn3XS6og==", + "9RGIQ2qyevNbSSEF36xk/A==", + "q8YF9G2jqydAxSqwyyys5Q==", + "m5JIUETVXcRza4VL4xlJbg==", + "aRpdnrOyu5mWB1P5YMbvOA==", + "rM/BOovNgnvebKMxZQdk7g==", + "fQS0jnQMnHBn7+JZWkiE/g==", + "gAoV4BZYdW1Wm712YXOhWQ==", + "hCzsi1yDv9ja5/o7t94j9Q==", + "CoLvjQDQGldGDqRxfQo+WQ==", + "pfGcaa49SM3S6yJIPk/EJQ==", + "yYp4iuI5f/y/l1AEJxYolQ==", + "Jj4IrSVpqQnhFrzNvylSzA==", + "4jeOFKuKpCmMXUVJSh9y0g==", + "+NMUaQ7XPsAi0rk7tTT9wQ==", + "Jt4Eg6MJn8O4Ph/K2LeSUA==", + "CiiUeJ0LeWfm7+gmEmYXtg==", + "c5Tc7rTFXNJqYyc0ppW+Iw==", + "4KJZPCE9NKTfzFxl76GWjg==", + "aXs9qTEXLTkN956ch3pnOA==", + "f5Xo7F1uaiM760Qbt978iw==", + "wpZqFkKafFpLcykN2IISqg==", + "vIORTYSHFIXk5E2NyIvWcQ==", + "prOsOG0adI4o+oz50moipw==", + "blygTgAHZJ3NzyAT33Bfww==", + "rBt6L/KLT7eybxKt5wtFdg==", + "vMuaLvAntJB5o7lmt/kVXA==", + "iujlt9fXcUXEYc+T2s5UjA==", + "LyYPOZKm8bBegMr5NTSBfg==", + "ZtWvgitOSRDWq7LAKYYd4Q==", + "kh51WUI5TRnKhur6ZEpRTQ==", + "VzQ1NwNv9btxUzxwVqvHQg==", + "8fJLQeIHaTnJ8wGqUiKU6g==", + "vvEH5A39TTe1AOC11rRCLA==", + "dihDsG7+6aocG6M9BWrCzQ==", + "3jqsY8/xTWELmu/az3Daug==", + "mpOtwBvle+nyY6lUBwTemw==", + "E1CvxFbuu9AYW604mnpGTw==", + "1LPC0BzhJbepHTSAiZ3QTw==", + "XpGXh76RDgXC4qnTCsnNHA==", + "3Gg9N7vjAfQEYOtQKuF/Eg==", + "+WpF8+poKmHPUBB4UYh/ig==", + "UNt7CNMtltJWq8giDciGyA==", + "RIZYDgXqsIdTf9o2Tp/S7g==", + "0QCQORCYfLuSbq94Sbt0bQ==", + "hvsZ5JmVevK1zclFYmxHaw==", + "3+9nURtBK3FKn0J9DQDa3g==", + "jdVMQqApseHH3fd91NFhxg==", + "VX+cVXV8p9i5EBTMoiQOQQ==", + "I5qDndyelK4Njv4YrX7S6w==", + "rWliqgfZ3/uCRBOZ9sMmdA==", + "vwno3vugCvt6ooT3CD4qIQ==", + "cffrYrBX3UQhfX1TbAF+GQ==", + "nOiwBFnXxCBfPCHYITgqNg==", + "LQttmX92SI94+hDNVd8Gtw==", + "iCF+GWw9/YGQXsOOPAnPHQ==", + "nwtCsN1xEYaHvEOPzBv+qQ==", + "CQpJFrpOvcQhsTXIlJli+Q==", + "tYeIZjIm0tVEsYxH1iIiUQ==", + "iCnm5fPmSmxsIzuRK6osrA==", + "tX8X8KoxUQ8atFSCxgwE1Q==", + "hZlX6qOfwxW5SPfqtRqaMw==", + "2aIx9UdMxxZWvrfeJ+DcTw==", + "TlJizlASbPtShZhkPww4UA==", + "p+bx+/WQWALXEBCTnIMr4w==", + "4VR5LiXLew6Nyn91zH9L4w==", + "bfUD03N2PRDT+MZ+WFVtow==", + "cTvDd8okNUx0RCMer6O8sw==", + "49jZr/mEW6fvnyzskyN40w==", + "vHmQUl4WHXs1E/Shh+TeyA==", + "fgXfRuqFfAu8qxbTi4bmhA==", + "Wn+Vj4eiWx0WPUHr3nFbyA==", + "2SwIiUwT4vRZPrg7+vZqDA==", + "nkedTagkmf6YE4tEY+0fKw==", + "8nOTDhFyZ8YUA4b6M5p84w==", + "qnzWszsyJhYtx8wkMN6b1g==", + "ka7pMp8eSiv92WgAsz2vdA==", + "pGQEWJ38hb/ZYy2P1+FIuw==", + "cVhdRFuZaW/09CYPmtNv5g==", + "prCOYlboBnzmLEBG/OeVrQ==", + "oIWwTbkVS5DDL47mY9/1KQ==", + "PKtXc4x4DEjM45dnmPWzyg==", + "f9ywiGXsz+PuEsLTV3zIbQ==", + "6G2bD3Y7qbGmfPqH9TqLFA==", + "DMHmyn2U2n+UXxkqdvKpnA==", + "XOG1PYgqoG8gVLIbVLTQgg==", + "1FSrgkUXgZot2CsmbAtkPw==", + "BxFP+4o6PSlGN78eSVT1pA==", + "EZVQGsXTZvht1qedRLF8bQ==", + "eYAQWuWZX2346VMCD6s7/A==", + "jkUpkLoIXuu7aSH8ZghIAQ==", + "mXPtbPaoNAAlGmUMmJEWBQ==", + "HLesnV3DL+FhWF3h6RXe8g==", + "nDAsSla+9XfAlQSPsXtzPA==", + "RAECgYZmcF4WxcFcZ4A0Ww==", + "W+M4BcYNmjj7xAximDGWsA==", + "ueODvMv/f9ZD8O0aIHn4sg==", + "cszpMdGbsbe6BygqMlnC9Q==", + "siHwJx6EgeB1gBT9z/vTyw==", + "FN7oLGBQGHXXn5dLnr/ElA==", + "Tud+AMyuFkWYYZ73yoJGpQ==", + "TuaG3wRdM9BWKAxh2UmAsg==", + "8CjmgWQSAAGcXX9kz3kssw==", + "ays5/F7JANIgPHN0vp2dqQ==", + "PCOGl7GIqbizAKj/sZmlwQ==", + "rZKD8oJnIj5fSNGiccfcvA==", + "gFEnTI8os2BfRGqx9p5x8w==", + "5r1ZsGkrzNQEpgt/gENibw==", + "1YO9G8qAhLIu2rShvekedw==", + "6ZKmm7IW7IdWuVytLr68CQ==", + "mMfn8OaKBxtetweulho+xQ==", + "GQJxu1SoMBH14KPV/G/KrQ==", + "IYIP2UBRyWetVfYLRsi1SQ==", + "Jit0X0srSNFnn8Ymi1EY+g==", + "ARCWkHAnVgBOIkCDQ19ZuA==", + "qA0sTaeNPNIiQbjIe1bOgQ==", + "iGI9uqMoBBAjPszpxjZBWQ==", + "+L1FDsr5VQtuYc2Is5QGjw==", + "4XNUmgwxsqDYsNmPkgNQYQ==", + "Yig+Wh18VIqdsmwtwfoUQw==", + "uqp92lAqjec8UQYfyjaEZw==", + "QiozlNcQCbqXtwItWExqJQ==", + "JFHutgSe1/SlcYKIbNNYwQ==", + "Y26jxXvl79RcffH8O8b9Ew==", + "bQ7J5mebp38rfP/fuqQOsg==", + "HI4ZIE5s8ez8Rb+Mv39FxA==", + "OzH7jTcyeM7RPVFtBdakpQ==", + "HLxROy6fx/mLXFTDSX4eLA==", + "s5RUHVRNAoKMuPR/Jkfc2Q==", + "X9QAaNjgiOeAWSphrGtyVw==", + "ALJWKUImVE40MbEooqsrng==", + "9MDG0WeBPpjGJLEmUJgBWg==", + "9RXymE9kCkDvBzWGyMgIWA==", + "vFox1d3llOeBeCUZGvTy0A==", + "r3lQAYOYhwlLnDWQIunKqg==", + "2os5s7j7Tl46ZmoZJH8FjA==", + "O5N2yd+QQggPBinQ+zIhtQ==", + "ZygAjaN62XhW5smlLkks+Q==", + "AgDJsaW0LkpGE65Kxk5+IA==", + "omAjyj1l6gyQAlBGfdxJTw==", + "fY9VATklOvceDfHZDDk57A==", + "StpQm/cQF8cT0LFzKUhC5w==", + "CYJB3qy5GalPLAv1KGFEZA==", + "coGEgMVs2b314qrXMjNumQ==", + "DQQB/l55iPN9XcySieNX3A==", + "6dshA8knH5qqD+KmR/kdSQ==", + "qyRmvxh8p4j4f+61c10ZFQ==", + "apWEPWUvMC24Y+2vTSLXoA==", + "RzX2OfSFEd//LhZwRwzBVw==", + "NdULoUDGhIolzw1PyYKV0A==", + "5w/c9WkI/FA+4lOtdPxoww==", + "bV9r7j2kNJpDCEM5E2339Q==", + "vbyiKeDCQ4q9dDRI1Q0Ong==", + "9xIgKpZGqq0/OU6wM5ZSHw==", + "RYkDwwng6eeffPHxt8iD9A==", + "w5N/aHbtOIKzcvG3GlMjGA==", + "3P2aJxV8Trll2GH9ptElYA==", + "yteeQr3ub2lDXgLziZV+DQ==", + "yqtj8GfLaUHYv/BsdjxIVw==", + "NyF+4VRog7etp90B9FuEjA==", + "uwA6N5LptSXqIBkTO0Jd7Q==", + "6lVSzYUQ/r0ep4W2eCzFpg==", + "1d7RPHdZ9qzAbG3Vi9BdFA==", + "7br49X11xc2GxQLSpZWjKQ==", + "peMW+rpwmXrSwplVuB/gTA==", + "RqYpA5AY7mKPaSxoQfI1CA==", + "dqVw2q2nhCvTcW82MT7z0g==", + "5S5/asYfWjOwnzYpbK6JDw==", + "NvkR0inSzAdetpI4SOXGhw==", + "tIqwBotg052wGBL65DZ+yA==", + "S4RvORcJ3m6WhnAgV4YfYA==", + "UAqf4owQ+EmrE45hBcUMEw==", + "4aPU6053cfMLHgLwAZJRNg==", + "3Y6/HqS1trYc9Dh778sefg==", + "ck86G8HsbXflyrK7MBntLg==", + "GLmWLXURlUOJ+PMjpWEXVA==", + "jNJQ6otieHBYIXA9LjXprg==", + "AsAHrIkMgc3RRWnklY9lJw==", + "FCLQocqxxhJeleARZ6kSPg==", + "3Leu2Sc+YOntJFlrvhaXeg==", + "hSkY45CeB6Ilvh0Io4W6cg==", + "DwrNdmU5VFFf3TwCCcptPA==", + "u2WQlcMxOACy6VbJXK4FwA==", + "E9IlDyULLdeaVUzN6eky8g==", + "EXveRXjzsjh8zbbQY2pM9g==", + "5VO1inwXMvLDBQSOahT6rg==", + "HaHTsLzx7V3G1SFknXpGxA==", + "MMaegl2Md9s/wOx5o9564w==", + "mpWNaUH9kn4WY26DWNAh3Q==", + "w3G+qXXqqKi8F5s+qvkBUg==", + "wM8tnXO4PDlLVHspZFcjYw==", + "LFcpCtnSnsCPD2gT/RA+Zg==", + "bhVbgJ4Do4v56D9mBuR/EA==", + "yU3N0HMSP5etuHPNrVkZtg==", + "FzqIpOcTsckSNHExrl+9jg==", + "BYz52gYI/Z6AbYbjWefcEA==", + "h3vYYI9yhpSZV2MQMJtwFQ==", + "adJAjAFyR2ne1puEgRiH+g==", + "eDcyiPaB954q5cPXcuxAQw==", + "40gCrW4YWi+2lkqMSPKBPg==", + "ulLuTZqhEDkX0EJ3xwRP9A==", + "y4iBxAMn/KzMmaWShdYiIw==", + "ilBBNK/IV69xKTShvI94fQ==", + "0HN6MIGtkdzNPsrGs611xA==", + "twPn6wTGqI0aR//0wP3xtA==", + "3UNJ37f+gnNyYk9yLFeoYA==", + "4SdHWowXgCpCDL28jEFpAw==", + "Mr5mCtC53+wwmwujOU/fWw==", + "81pAhreEPxcKse+++h1qBg==", + "KmcGEE0pacQ/HDUgjlt7Pg==", + "Gt4/MMrLBErhbFjGbiNqQQ==", + "lf1fwA0YoWUZaEybE+LyMQ==", + "RIVYGO2smx9rmRoDVYMPXw==", + "rJ9qVn8/2nOxexWzqIHlcQ==", + "lfOLLyZNbsWQgHRhicr4ag==", + "wgH1GlUxWi6/yLLFzE76uQ==", + "Qg1ubGl+orphvT990e5ZPA==", + "Z5B+uOmPZbpbFWHpI9WhPw==", + "snGTzo540cCqgBjxrfNpKw==", + "ZqkmoGB0p5uT5J6XBGh7Tw==", + "uPi8TsGY3vQsMVo/nsbgVQ==", + "Y5XR8Igvau/h+c1pRgKayg==", + "ZmVpw1TUVuT13Zw/MNI5hQ==", + "60suecbWRfexSh7C67RENA==", + "kZ/mZZg9YSDmk2rCGChYAg==", + "OpL+vHwPasW30s2E1TYgpA==", + "ZVnErH1Si4u51QoT0OT7pA==", + "3pi3aNVq1QNJmu1j0iyL0g==", + "tb5+2dmYALJibez1W4zXgA==", + "jOPdd330tB6+7C29a9wn0Q==", + "5oD/aGqoakxaezq43x0Tvw==", + "HdB7Se47cWjPgpJN0pZuiA==", + "6WhHPWlqEUqXC52rHGRHjA==", + "WLwpjgr9KzevuogoHZaVUw==", + "E8yMPK7W0SIGTK6gIqhxiQ==", + "1/Hxu8M9N/oNwk8bCj4FNQ==", + "Uo1ebgsOxc3eDRds1ah3ag==", + "5pqqzC/YmRIMA9tMFPi7rg==", + "ri4AOITPdB1YHyXV+5S51g==", + "HfvsiCQN/3mT0FabCU5ygQ==", + "UQTQk5rrs6lEb1a+nkLwfg==", + "VH70dN82yPCRctmAHMfCig==", + "yD3Dd4ToRrl53k/2NSCJiw==", + "fO0+6TsjL+45p9mSsMRiIg==", + "fM5uYpkvJFArnYiQ3MrQnA==", + "V+QzdKh5gxTPp2yPC9ZNEg==", + "XHHEg/8KZioW/4/wgSEkbQ==", + "2abfl3N46tznOpr+94VONQ==", + "gxwbqZDHLbQVqXjaq42BCg==", + "WnHK5ZQDR6Da5cGODXeo0A==", + "SChDh/Np1HyTPWfICfE1uA==", + "yhexr/OFKfZl0o3lS70e4w==", + "N65PqIWiQeS082D6qpfrAg==", + "RM5CpIiB94Sqxi462G7caA==", + "CBAGa5l95f3hVzNi6MPWeQ==", + "OHJBT2SEv5b5NxBpiAf7oQ==", + "p48i7AfSSAyTdJSyHvOONw==", + "/SP6pOdYFzcAl2OL05z4uQ==", + "N8dXCawxSBX40fgRRSDqlQ==", + "bMWFvjM8eVezU1ZXKmdgqw==", + "Um1ftRBycvb+363a90Osog==", + "QAz7FA+jpz9GgLvwdoNTEQ==", + "qO4HlyHMK5ygX+6HbwQe8w==", + "UgvtdE2eBZBUCAJG/6c0og==", + "q5g3c8tnQTW2EjNfb2sukw==", + "gsC/mWD8KFblxB0JxNuqJw==", + "SVFbcjXbV7HRg+7jUrzpwg==", + "bz294kSG4egZnH2dJ8HwEg==", + "ybpTgPr3SjJ12Rj5lC/IMA==", + "yDrAd1ot38soBk7zKdnT8A==", + "BB/R8oQOcoE4j63Hrh8ifg==", + "GNrMvNXQkW7PydlyJa+f1w==", + "w0PKdssv+Zc5J/BbphoxpA==", + "D5ibbo8UJMfFZ48RffuhgQ==", + "MdvhC1cuXqni/0mtQlSOCw==", + "wQKL8Ga6JQkpZ7yymDkC3w==", + "o1uhaQg5/zfne84BFAINUQ==", + "Ft2wXUokFdUf6d2Y/lwriw==", + "sLJrshdEANp0qk2xOUtTnQ==", + "jx7rpxbm1NaUMcE2ktg5sA==", + "ZQ0ZnTsZKWxbRj7Tilh24Q==", + "KhrIIHfqXl9zGE9aGrkRVg==", + "jS0JuioLGAVaHdo/96JFoQ==", + "tr+U/vt+MIGXPRQYYWJfRg==", + "TXab/hqNGWaSK+fXAoB2bg==", + "0K4NBxqEa3RYpnrkrD/XjQ==", + "3oMTbWf7Bv83KRlfjNWQZA==", + "yLAhLNezvqVHmN1SfMRrPw==", + "ZYW30FfgwHmW6nAbUGmwzA==", + "CZNoTy26VUQirvYxSPc/5A==", + "CF1sAlhjDQY/KWOBnSSveA==", + "+CLf5witKkuOvPCulTlkqw==", + "1m1yD4L9A7Q1Ot+wCsrxJQ==", + "2E41e0MgM3WhFx2oasIQeA==", + "mDXHuOmI4ayjy2kLSHku1Q==", + "sCLMrLjEUQ6P1L8tz90Kxg==", + "zDUZCzQesFjO1JI3PwDjfg==", + "x/BIDm6TKMhqu/gtb3kGyw==", + "DEaZD/8aWV6+zkiLSVN/gA==", + "7dz+W494zwU5sg63v5flCg==", + "Y5iDQySR2c3MK7RPMCgSrw==", + "GglPoW5fvr4JSM3Zv99oiA==", + "myzvc+2MfxGD9uuvZYdnqQ==", + "V9G1we3DOIQGKXjjPqIppQ==", + "gYvdNJCDDQmNhtJ6NKSuTA==", + "rXtGpN17Onx8LnccJnXwJQ==", + "/a+bLXOq02sa/s8h7PhUTg==", + "htNVAogFakQkTX6GHoCVXg==", + "eshD40tvOA6bXb0Fs/cH3A==", + "K1CGbMfhlhIuS0YHLG30PQ==", + "aOeJZUIZM9YWjIEokFPnzQ==", + "r0hAwlS0mPZVfCSB+2G6uQ==", + "0q+erphtrB+6HBnnYg7O6w==", + "bkRdUHAksJZGzE1gugizYQ==", + "J8v2f6hWFu8oLuwhOeoQjA==", + "qkvEep4vvXhc2ZJ6R449Mg==", + "6HGeEPyTAu9oiKhNVLjQnA==", + "JoATsk/aJH0UcDchFMksWA==", + "QozQL0DTtr+PXNKifv6l6g==", + "HiAgt86AyznvbI2pnLalVQ==", + "lY+tivtsfvU0LJzBQ6itYQ==", + "EfXDc6h69aBPE6qsB+6+Ig==", + "gnAIpoCyl3mQytLFgBEgGA==", + "p2JPOX8yDQ0agG+tUyyT/g==", + "zeELfk015D5krExLKRUYtg==", + "wDiGoFEfIVEDyyc4VpwhWQ==", + "7Ephy+mklG2Y3MFdqmXqlA==", + "8ZFPMJJYVJHsfRpU4DigSg==", + "ocRh5LR1ZIN9Johnht8fhQ==", + "l5f3I6osM9oxLRAwnUnc5A==", + "yxCyBXqGWA735JEyljDP7Q==", + "qE/h/Z+6buZWf+cmPdhxog==", + "HCu4ZMrcLMZbPXbTlWuvvQ==", + "TDrq23VUdzEU/8L5i8jRJQ==", + "L+N/6geuokiLPPSDXM9Qkg==", + "v6jZicMNM3ysm3U5xu0HoQ==", + "b85nxzs8xiHxaqezuDVWvg==", + "ca+kx+kf7JuZ3pfYKDwFlg==", + "KlY5TGg0pR/57TVX+ik1KQ==", + "3jmCreW5ytSuGfmeLv7NfQ==", + "ucLMWnNDSqE4NOCGWvcGWw==", + "NSrzwNlB0bde3ph8k6ZQcQ==", + "nL4iEd3b5v4Y9fHWDs+Lrw==", + "W2x0SBzSIsTRgyWUCOZ/lg==", + "ifZM0gBm9g9L09YlL+vXBg==", + "4WcFEswYU/HHQPw77DYnyA==", + "TLJbasOoVO435E5NE5JDcA==", + "WyCFB4+6lVtlzu3ExHAGbQ==", + "BW0A06zoQw7S+YMGaegT7g==", + "qP1cCE4zsKGTPhjbcpczMw==", + "UVEZPoH9cysC+17MKHFraw==", + "eQ45Mvf5in9xKrP6/qjYbg==", + "fOARCnIg/foF/6tm7m9+3w==", + "lK2xe+OuPutp4os0ZAZx5w==", + "Tug3eh+28ttyf+U7jfpg5w==", + "ENFfP93LA257G6pXQkmIdg==", + "FuWspiqu5g8Eeli5Az+BkA==", + "kIGxCUxSlNgsKZ45Al1lWw==", + "RzeH+G3gvuK1z+nJGYqARQ==", + "0ofMbUCA3/v5L8lHnX4S5w==", + "VI8pgqBZeGWNaxkuqQVe7g==", + "x6lNRGgJcRxgKTlzhc1WPg==", + "La0gzdbDyXUq6YAXeKPuJA==", + "dAq8/1JSQf1f4QPLUitp0g==", + "WN7lFJfw4lSnTCcbmt5nsg==", + "2aDK0tGNgMLyxT+BQPDE8Q==", + "9W57pTzc572EvSURqwrRhw==", + "37Nkh06O979nt7xzspOFyQ==", + "4TQkMnRsXBobbtnBmfPKnA==", + "f/BjtP5fmFw2dRHgocbFlg==", + "9vEgJVJLEfed6wJ7hBUGgQ==", + "HRWYX2XOdsOqYzCcqkwIyw==", + "StDtLMlCI75g4XC59mESEQ==", + "99+SBN45LwKCPfrjUKRPmw==", + "HbT6W1Ssd3W7ApKzrmsbcg==", + "l8/KMItWaW3n4g1Yot/rcQ==", + "s7iW1M6gkAMp+D/3jHY58w==", + "GWwJ32SZqD5wldrXUdNTLA==", + "YhLEPsi/TNyeUJw69SPYzQ==", + "g0aTR8aJ0uVy3YvGYu5xrw==", + "m6get5wjq5j1i5abnpXuZQ==", + "ymtA8EMPMgmMcimWZZ0A1Q==", + "HEcOaEd9zCoOVbEmroSvJg==", + "F8l+Qd9TZgzV+r8G584lKA==", + "3yDD+xT8iRfUVdxcc7RxKw==", + "1eRUCdIJe3YGD5jOMbkkOg==", + "DO1/jfP/xBI9N0RJNqB2Rw==", + "SiSlasZ+6U2IZYogqr2UPg==", + "tBQDfy48FnIOZI04rxfdcA==", + "HEghmKg3GN60K7otpeNhaA==", + "mTLBkP+yGHsdk5g7zLjVUw==", + "RgtwfY5pTolKrUGT+6Pp6g==", + "EyIsYQxgFa4huyo/Lomv7g==", + "HwLSUie8bzH+pOJT3XQFyg==", + "7Tauesu7bgs5lJmQROVFiQ==", + "ojugpLIfzflgU2lonfdGxA==", + "ZqjnqxZE/BjOUY0CMdVl0g==", + "oQjugfjraFziga1BcwRLRA==", + "JXCYeWjFqcdSf6QwB54G+A==", + "TeBGJCqSqbzvljIh9viAqA==", + "1Gpj4TPXhdPEI4zfQFsOCg==", + "asouSfUjJa8yfMG7BBe+fA==", + "ccy3Ke2k4+evIw0agHlh3w==", + "CzSumIcYrZlxOUwUnLR2Zw==", + "9QFYrCXsGsInUb4SClS3cQ==", + "3RTtSaMp1TZegJo5gFtwwA==", + "aTWiWjyeSDVY/q8y9xc2zg==", + "UK+R+hAoVeZ4xvsoZjdWpw==", + "rHagXw+CkF3uEWPWDKXvog==", + "MfkyURTBfkNZwB+wZKjP4g==", + "Qf7JFJJuuacSzl6djUT2EQ==", + "K1RL+tLjICBvMupe7QppIQ==", + "R2OOV18CV/YpWL1xzr/VQg==", + "o+areESiXgSO0Lby56cBeg==", + "VPqyIomYm7HbK5biVDvlpw==", + "pw1jplCdTC+b0ThX0FXOjw==", + "gTnsH3IzALFscTZ1JkA9pw==", + "JYJvOZ4CHktLrYJyAbdOnA==", + "P8lUiLFoL100c9YSQWYqDA==", + "LATQEY7f47i77M6p11wjWA==", + "U9kE50Wq5/EHO03c5hE4Ug==", + "pFKzcRHSUBqSMtkEJvrR1Q==", + "vHVXsAMQqc0qp7HA5Q+YkA==", + "3XyoREdvhmSbyvAbgw2y/A==", + "qOEIUWtGm5vx/+fg4tuazg==", + "a6IszND1m+6w+W+CvseC7g==", + "KuNY8qAJBce+yUIluW8AYw==", + "5Wcq+6hgnWsQZ/bojERpUw==", + "l2ZB9TvT68rn8AAN4MdxWw==", + "h5HsEsObPuPFqREfynVblw==", + "fvm0IQfnbfZFETg9v3z/Fg==", + "QV0OG5bpjrjku4AzDvp9yw==", + "nMuMtK/Zkb3Xr34oFuX/Lg==", + "jMZKSMP2THqwpWqJNJRWdw==", + "fX4G68hFL7DmEmjbWlCBJQ==", + "ZlBNHAiYsfaEEiPQ1z+rCA==", + "ckugAisBNX18eQz+EnEjjw==", + "Dt6hvhPJu94CJpiyJ5uUkg==", + "eYE9No9sN5kUZ5ePEyS3+Q==", + "Tp52d1NndiC9w3crFqFm9g==", + "MBjMU/17AXBK0tqyARZP5w==", + "1EI9aa955ejNo1dJepcZJw==", + "FqWLkhWl0iiD/u2cp+XK9A==", + "j8nMH8mK/0Aae7ZkqyPgdg==", + "ZtmnX24AwYAXHb2ZDC6MeQ==", + "who8uUamlHWHXnBf7dwy4A==", + "CmkmWcMK4eqPBcRbdnQvhw==", + "61V74uIjaSfZM8au1dxr1A==", + "778O1hdVKHLG2q9dycUS0Q==", + "IdadoCPmSgHDHzn1zyf8Jw==", + "Z2rwGmVEMCY6nCfHO3qOzw==", + "Q3TpCE+wnmH/1h/EPWsBtQ==", + "HnVfyqgJ+1xSsN4deTXcIA==", + "XgPHx2+ULpm14IOZU2lrDg==", + "IbN736G1Px5bsYqE5gW1JQ==", + "nY/H7vThZ+dDxoPRyql+Cg==", + "wlWxtQDJ+siGhN2fJn3qtw==", + "MrbEUlTagbesBNg0OemHpw==", + "LJtRcR70ug6UHiuqbT6NGw==", + "hSNZWNKUtDtMo6otkXA/DA==", + "LawT9ZygiVtBk0XJ+KkQgQ==", + "DLzHkTjjuH6LpWHo2ITD0Q==", + "i8XXN7jcrmhnrOVDV8a2Hw==", + "ogcuGHUZJkmv+vCz567a2g==", + "rUp5Mfc57+A8Q29SPcvH/Q==", + "6706ncrH1OANFnaK6DUMqQ==", + "gK7dhke5ChQzlYc/bcIkcg==", + "t3Txxjq43e/CtQmfQTKwWg==", + "6ZMs9vCzK9lsbS6eyzZlIA==", + "uTHBqApdKOAgdwX3cjrCYQ==", + "zirOtGUXeRL22ezfotZfQg==", + "iK0dWKHjVVexuXvMWJV9pg==", + "uzEgwx1iAXAvWPKSVwYSeQ==", + "FHvI0IVNvih8tC7JgzvCOw==", + "jjNMPXbmpFNsCpWY0cv3eg==", + "/cJ0Nn5YbXeUpOHMfWXNHQ==", + "WkSJpxBa45XJRWWZFee7hw==", + "edlXkskLx287vOBZ9+gVYg==", + "+Pl0bSMBAdXpRIA+zE02JA==", + "3xw8+0/WU51Yz4TWIMK8mw==", + "GdTanUprpE3X/YjJDPpkhQ==", + "qnsBdl050y9cUaWxbCczRw==", + "pnJnBzAJlO4j3IRqcfmhkQ==", + "USq1iF90eUv41QBebs3bhw==", + "QH3lAwOYBAJ0Fd5pULAZqw==", + "gvvyX5ATi4q9NhnwxRxC8w==", + "7xDIG/80SnhgxAYPL9YJtg==", + "WVhfn2yJZ43qCTu0TVWJwA==", + "twjiDKJM7528oIu/el4Zbg==", + "6sBemZt4qY/TBwqk3YcLOQ==", + "m3XYojKO+I6PXlVRUQBC3w==", + "gUNP5w7ANJm257qjFxSJrA==", + "mMLhjdWNnZ8zts9q+a2v3g==", + "kjWYVC7Eok2w2YT4rrI+IA==", + "ZzT5b0dYQXkQHTXySpWEaA==", + "YzTV0esAxBFVls3e0qRsnA==", + "9xmtuClkFlpz/X5E9JBWBA==", + "nhAnHuCGXcYlqzOxrrEe1g==", + "cbBXgB1WQ/i8Xul0bYY2fg==", + "AkAes5oErTaJiGD2I4A1Pw==", + "Wx9jh/teM0LJHrvTScssyQ==", + "fU5ZZ1bIVsV+eXxOpGWo/Q==", + "k8eZxqwxiN/ievXdLSEL/w==", + "E2LR1aZ3DcdCBuVT7BhReA==", + "1eCHcz4swFH+uRhiilOinQ==", + "JipruVZx4ban3Zo5nNM37g==", + "IPLD9nT5EEYG9ioaSIYuuA==", + "pHozgRyMiEmyzThtJnY4MQ==", + "p0eNK7zJd7D/HEGaVOrtrQ==", + "dGjcKAOGBd4gIjJq7fL+qQ==", + "uMq8cDVWFD+tpn8aeP8Pqg==", + "gC7gUwGumN7GNlWwfIOjJQ==", + "It+K/RCYMOfNrDZxo7lbcA==", + "4CfEP8TeMKX33ktwgifGgA==", + "nxDGRpePV3H4NChn4eLwag==", + "300hoYyMR/mk1mfWJxS8/w==", + "DmxgZsQg+Qy1GP0fPkW3VA==", + "1vqRt79ukuvdJNyIlIag8Q==", + "RWI0HfpP7643OSEZR8kxzw==", + "zZtYkKU50PPEj6qSbO5/Sw==", + "UNRlg6+CYVOt68NwgufGNA==", + "kkbX+a00dfiTgbMI+aJpMg==", + "VIC7inSiqzM6v9VqtXDyCw==", + "l+x2QhxG8wb5AQbcRxXlmA==", + "GUiinC3vgBjbQC2ybMrMNQ==", + "6uMF5i0b/xsk55DlPumT7A==", + "aK9nybtiIBUvxgs1iQFgsw==", + "BLbTFLSb4mkxMaq4/B2khg==", + "mTAqtg6oi0iytHQCaSVUsA==", + "eBapvE+hdyFTsZ0y5yrahg==", + "lHN2dn2cUKJ8ocVL3vEhUQ==", + "Mj87ajJ/yR41XwAbFzJbcA==", + "FA+nK6mpFWdD0kLFcEdhxA==", + "FrTgaF5YZCNkyfR1kVzTLQ==", + "5eHStFN7wEmIE+uuRwIlPQ==", + "AyWlT+EGzIXc395zTlEU5Q==", + "I+wVQA+jpPTJ6xEsAlYucg==", + "Y1flEyZZAYxauMo4cmtJ1w==", + "1AeReq55UQotRQVKJ66pmg==", + "xzGzN5Hhbh0m/KezjNvXbQ==", + "meHzY9dIF7llDpFQo1gyMg==", + "RnOXOygwJFqrD+DlM3R5Ew==", + "JKg64m6mU7C/CkTwVn4ASg==", + "gGLz3Ss+amU7y6JF09jq7A==", + "Pu9pEf+Tek3J+3jmQNqrKw==", + "EATnlYm0p3h04cLAL95JgA==", + "o64LDtKq/Fulf1PkVfFcyg==", + "hUWqqG1QwYgGC5uXJpCvJw==", + "RfSwpO/ywQx4lfgeYlBr2w==", + "VaJc9vtYlqJbRPGb5Tf0ow==", + "9JKIJrlQjhNSC46H3Cstcw==", + "6Z9myGCF5ylWljgIYAmhqw==", + "9bAWYElyRN1oJ6eJwPtCtQ==", + "ohK6EftXOqBzIMI+5XnESw==", + "AVjwqrTBQH1VREuBlOyUOg==", + "G2UponGde3/Z+9b2m9abpQ==", + "DoiItHSms0B9gYmunVbRkQ==", + "vUC0HlTTHj6qNHwfviDtAw==", + "hq35Fjgvrcx6I9e6egWS4w==", + "sw+bmpzqsM4gEQtnqocQLQ==", + "ApiuEPWr8UjuRyJjsYZQBw==", + "VXu4ARjq7DS2IR/gT24Pfw==", + "3TbRZtFtsh9ez8hqZuTDeA==", + "CazLJMJjQMeHhYLwXW7YNg==", + "ROSt+NlEoiPFtpRqKtDUrQ==", + "IUwVHH6+8/0c+nOrjclOWA==", + "lkzFdvtBx5bV6xZO0cxK7g==", + "4ekt4m38G9m599xJCmhlug==", + "fzkmVWKhJsxyCwiqB/ULnQ==", + "LZAKplVoNjeQgfaHqkyEJA==", + "91vfsZ7Lx9x5gqWTOdM4sg==", + "MVoxyIA+emaulH8Oks8Weg==", + "oGH7SMLI2/qjd9Vnhi3s0A==", + "vmqfGJE6r4yDahtU/HLrxw==", + "Y5KKN7t/v9JSxG/m1GMPSA==", + "gXlb7bbRqHXusTE5deolGA==", + "/2c4oNniwhL3z5IOngfggg==", + "HgIFX42oUdRPu7sKAXhNWg==", + "A3dX2ShyL9+WOi6MNJBoYQ==", + "hN9bmMHfmnVBVr+7Ibd2Ng==", + "DB706G73NpBSRS8TKQOVZw==", + "JSyq2MIuObPnEgEUDyALjQ==", + "kSUectNPXpXNg+tIveTFRw==", + "XVVy3e6dTnO3HpgD6BtwQw==", + "td7nDgTDmKPSODRusMcupw==", + "Lt/pVD4TFRoiikmgAxEWEw==", + "mmRob7iyTkTLDu8ObmTPow==", + "Fd0c8f2eykUp9GYhqOcKoA==", + "18RKixTv12q3xoBLz6eKiA==", + "RClzwwKh51rbB4ekl99EZA==", + "oONlXCW4aAqGczQ/bUllBw==", + "foPAmiABJ3IXBoed2EgQXA==", + "wEJDulZafLuXCvcqBYioFQ==", + "K1RgR6HR5uDEQgZ32TAFgA==", + "SEIZhyguLoyH7So0p1KY0A==", + "ggIfX1J4dX3xQoHnHUI7VA==", + "HBRzLacCVYfwUVGzrefZYg==", + "aWZRql2IUPVe9hS3dxgVfQ==", + "Err1mbWJud80JNsDEmXcYg==", + "Z2MkqmpQXdlctCTCUDPyzw==", + "JnE6BK0vpWIhNkaeaYNUzw==", + "5dUry23poD+0wxZ3hH6WmA==", + "DwP0MQf71VsqvAbAMtC3QQ==", + "kHcBZXoxnFJ+GMwBZ/xhfQ==", + "SUAwMWLMml8uGqagz5oqhQ==", + "79uTykH43voFC3XhHHUzKg==", + "P5fucOJhtcRIoElFJS4ffg==", + "s8NpalwgPdHPla7Zi9FJ3w==", + "8cXqZub6rjgJXmh1CYJBOg==", + "tY916jrSySzrL+YTcVmYKQ==", + "DRiFNojs7wM8sfkWcmLnhQ==", + "wqUJ1Gq1Yz2cXFkbcCmzHQ==", + "0u+0WHr7WI6IlVBBgiRi6w==", + "GCYI9Dn1h3gOuueKc7pdKA==", + "nVDxVhaa2o38gd1XJgE3aw==", + "5I/heFSQG/UpWGx0uhAqGQ==", + "1PvTn90xwZJPoVfyT5/uIQ==", + "jHOoSl3ldFYr9YErEBnD3w==", + "swJhrPwllq5JORWiP5EkDA==", + "tj2rWvF2Fl+XIccctj8Mhw==", + "QvYZxsLdu+3nV/WhY1DsYg==", + "fKalNdhsyxTt1w08bv9fJA==", + "CHLHizLruvCrVi9chj9sXA==", + "sa2DECaqYH1z1/AFhpHi+g==", + "LbPp1oL0t3K2BAlIN+l8DA==", + "5SbwLDNT6sBOy6nONtUcTg==", + "AfVPdxD3FyfwwNrQnVNQ7A==", + "jt9Ocr9D8EwGRgrXVz//aQ==", + "KkwQL0DeUM3nPFfHb2ej+A==", + "WwraoO97OTalvavjUsqhxQ==", + "fAKFfwlCOyhtdBK6yNnsNg==", + "EqMlrz1to7HG4GIFTPaehQ==", + "YmjZJyNfHN5FaTL/HAm8ww==", + "L2D7G0btrwxl9V4dP3XM5Q==", + "oUqO4HrBvkpSL781qAC9+w==", + "c6Yhwy/q3j7skXq52l36Ww==", + "FWphIPZMumqnXr1glnbK4w==", + "AcKwfS8FRVqb72uSkDNY/Q==", + "uSIiF1r9F18avZczmlEuMQ==", + "XrFDomoH2qFjQ2jJ2yp9lA==", + "N2X7KWekNN+fMmwyXgKD5w==", + "IdmcpJXyVDajzeiGZixhSA==", + "Wf2olJCYZRGTTZxZoBePuQ==", + "oVlG+0rjrg2tdFImxIeVBA==", + "7w4PDRJxptG8HMe/ijL6cQ==", + "rueNryrchijjmWaA3kljYg==", + "ZybIEGf1Rn/26vlHmuMxhw==", + "yYVW07lOZHdgtX42xJONIA==", + "4ifNsmjYf1iOn2YpMfzihg==", + "KTjwL+qswa+Bid8xLdjMTg==", + "THfzE2G2NVKKfO+A2TjeFw==", + "QoqHzpHDHTwQD5UF30NruQ==", + "dTMoNd6DDr1Tu8tuZWLudw==", + "wOc4TbwQGUwOC1B3BEZ4OQ==", + "gfhkPuMvjoC3CGcnOvki3Q==", + "vljJciS+uuIvL7XXm5688g==", + "EGLOaMe6Nvzs/cmb7pNpbg==", + "oLWWIn/2AbKRHnddr2og9g==", + "7l0RMKbONGS/goW/M+gnMQ==", + "eFkXKRd2dwu/KWI5ZFpEzw==", + "jWsC7kdp2YmIZpfXGUimiA==", + "Jcxjli2tcIAjCe+5LyvqdQ==", + "MUkRa/PjeWMhbCTq43g6Aw==", + "g2nh2xENCFOpHZfdEXnoQA==", + "x6M66krXSi0EhppwmDmsxA==", + "26Wmdp6SkKN74W0/XPcnmA==", + "ycjv4XkS5O7zcF3sqq9MwQ==", + "gfnbviaVhKvv1UvlRGznww==", + "aIPde9CtyZrhbHLK740bfw==", + "0p8YbEMxeb73HbAfvPLQRw==", + "Is3uxoSNqoIo5I15z6Z2UQ==", + "NZtcY8fIpSKPso/KA6ZfzA==", + "iQ304I1hmLZktA1d1cuOJA==", + "0QB0OUW5x2JLHfrtmpZQ+w==", + "kgyUtd8MFe0tuuxDEUZA9w==", + "AcbG0e6xN8pZfYAv7QJe1Q==", + "bb/U8UynPHwczew/hxLQxw==", + "NuBYjwlxadAH+vLWYRZ3bg==", + "Ao1Zc0h5AdSHtYt1caWZnQ==", + "FL/j3GJBuXdAo54JYiWklQ==", + "E2v8Kk60qVpQ232YzjS2ow==", + "zVupSPz7cD0v/mD/eUIIjg==", + "sEeblUmISi1HK4omrWuPTA==", + "xQpYjaAmrQudWgsdu24J0A==", + "vCekQ2nOQKiN/q8Be/qwZg==", + "8g08gjG/QtvAYer32xgNAg==", + "miiOqnhtef1ODjFzMHnxjA==", + "sXlFMSTBFnq0STHj6cS/8w==", + "+SclwwY8R2RPrnX54Z+A6w==", + "g8TcogVxHpw7uhgNFt5VCQ==", + "9viAzLFGYYudBYFu7kFamg==", + "BAJ+/jbk2HyobezZyB9LiQ==", + "/DJgKE9ouibewuZ2QEnk6w==", + "fxg/vQq9WPpmQsqQ4RFYaA==", + "lM/EhwTsbivA7MDecaVTPw==", + "pVgjGg4TeTNhKimyOu3AAw==", + "gYnznEt9r97haD/j2Cko7g==", + "/ngbFuKIAVpdSwsA3VxvNw==", + "VCL3xfPVCL5RjihQM59fgg==", + "eDWsx4isnr2xPveBOGc7Hw==", + "FIOCTEbzb2+KMCnEdJ7jZw==", + "40HzgVKYnqIb6NJhpSIF0A==", + "ccK42Lm8Tsv73YMVZRwL6A==", + "MpAwWMt7bcs4eL7hCSLudQ==", + "zxsSqovedB3HT99jVblCnQ==", + "4erEA42TqGA9K4iFKkxMMA==", + "BaRwTrc5ulyKbW4+QqD0dw==", + "CT3ldhWpS1SEEmPtjejR/Q==", + "lkl6XkrTMUpXi46dPxTPxg==", + "3EhLkC9NqD3A6ApV6idmgg==", + "fsW2DaKYTCC7gswCT+ByQQ==", + "pW4gDKtVLj48gNz6V17QdA==", + "KjfL7YyVqmCJGBGDFdJ0gw==", + "bGGUhiG9SqJMHQWitXTcYQ==", + "8RtLlzkGEiisy1v9Xo0sbw==", + "R81DX/5a7DYKkS4CU+TL+w==", + "Tu6w6DtX2RJJ3Ym3o3QAWw==", + "nx/U4Tode5ILux4DSR+QMg==", + "mjQS8CpyGnsZIDOIEdYUxg==", + "wJpepvmtQQ3sz3tVFDnFqw==", + "a4rPqbDWiMivVzaRxvAj7g==", + "6o5g9JfKLKQ2vBPqKs6kjg==", + "UzPPFSXgeV7KW4CN5GIQXA==", + "NdVyHoTbBhX6Umz/9vbi0g==", + "Fzuq+Wg7clo6DTujNrxsSA==", + "XXFr0WUuGsH5nXPas7hR3Q==", + "JVSLiwurnCelNBiG2nflpQ==", + "NiawWuMBDo0Q3P2xK/vnLQ==", + "nNaGqigseHw30DaAhjBU3g==", + "+edqJYGvcy1AH2mEjJtSIg==", + "1WIi4I62GqkjDXOYqHWJfQ==", + "rwplpbNJz0ADUHTmzAj15Q==", + "iWNlSnwrtCmVF89B+DZqOQ==", + "tHDbi43e6k6uBgO0hA+Uiw==", + "fHNpW230mNib08aB7IM3XQ==", + "OChiB4BzcRE8Qxilu6TgJg==", + "d+ctfXU0j07rpRRzb5/HDA==", + "GDMqfhPQN0PxfJPnK1Bb9A==", + "bLd38ZNkVeuhf0joEAxnBQ==", + "nvUKoKfC6j8fz3gEDQrc/w==", + "fhcbn9xE/6zobqQ2niSBgA==", + "HGxe+5/kkh6R9GXzEOOFHA==", + "mPwCyD0yrIDonVi+fhXyEQ==", + "5PfGtbH9fmVuNnq83xIIgQ==", + "XePy/hhnQwHXFeXUQQ55Vg==", + "yfAaL0MMtSXPQ37pBdmHxQ==", + "NiQ/m4DZXUbpca9aZdzWAw==", + "uT6WRh5UpVdeABssoP2VTg==", + "oxoZP897lgMg/KLcZAtkAg==", + "oKt57TPe4PogmsGssc3Cbg==", + "RxmdoO8ak8y/HzMSIm+yBQ==", + "6leyDVmC5jglAa98NQ3+Hg==", + "+QosBAnSM2h4lsKuBlqEZw==", + "hy303iin+Wm7JA6MeelwiQ==", + "m9iuy4UtsjmyPzy6FTTZvw==", + "f6Ye5F0Lkn34uLVDCzogFQ==", + "iGykaF+h4p46HhrWqL8Ffg==", + "LPYFDbTEp5nGtG6uO8epSw==", + "t2vWMIh2BvfDSQaz5T1TZw==", + "OONAvFS/kmH7+vPhAGTNSg==", + "g/z9yk94XaeBRFj4hqPzdw==", + "2wesXiib76wM9sqRZ7JYwQ==", + "n7h9v2N1gOcvMuBEf8uThw==", + "ITYL3tDwddEdWSD6J6ULaA==", + "inrUwXyKikpOW0y2Kl1wGw==", + "iwKBOGDTFzV4aXgDGfyUkw==", + "+fcjH2kZKNj8quOytUk4nQ==", + "Srl4HivgHMxMOUHyM3jvNw==", + "qngzBJbiTB4fivrdnE5gOg==", + "G0MlFNCbRjXk4ekcPO/chQ==", + "t+bYn9UqrzKiuxAYGF7RLA==", + "RVD3Ij6sRwwxTUDAxwELtA==", + "RNdyt6ZRGvwYG5Ws3QTuEA==", + "9DRHdyX8ECKHUoEsGuqR4Q==", + "oMJLQTH1wW7LvOV0KRx/dw==", + "bjLZ7ot/X/vWSVx4EYwMCg==", + "+p8pofUlwn8vV6Rp6+sz9g==", + "cchuqe+CWCJpoakjHLvUfA==", + "NvurnIHin4O+wNP7MnrZ1w==", + "RBMv0IxXEO3o7MnV47Bzow==", + "xTizUioizbMQxD0T6fy/EQ==", + "ZCdad3AwhVArttapWFwT/Q==", + "Hy1nqC40l5ItxumkIC2LAA==", + "W/5ThNLu43uT1O+fg0Fzwg==", + "b3BQG9/9qDNC/bNSTBY/sQ==", + "neQoa8pvETr07blVMN3pgA==", + "oR8rvIZoeoaZ/ufpo0htfQ==", + "zEzWZ6l7EKoVUxvk/l78Mw==", + "IHyIeMad23fSDisblwyfpA==", + "m6srF+pMehggHB1tdoxlPg==", + "kggaIvN2tlbZdZRI8S5Apw==", + "2RFaMPlSbVuoEqKXgkIa5A==", + "//eHwmDOQRSrv+k9C/k3ZQ==", + "X/Gha4Ajjm/GStp/tv+Jvw==", + "+H0Rglt/HnhZwdty2hsDHg==", + "a1aL8zQ+ie3YPogE3hyFFg==", + "HxEU37uBMeiR5y8q/pM42g==", + "68nqDtXOuxF7DSw6muEZvg==", + "s5+78jS4hQYrFtxqTW3g1Q==", + "drfODfDI6GyMW7hzkmzQvA==", + "pT1raq2fChffFSIBX3fRiA==", + "sfowXUMdN2mCoBVrUzulZg==", + "AV/YJfdoDUdRcrXVwinhQg==", + "3AKEYQqpkfW7CZMFQZoxOw==", + "PHwJ5ZAqqftZ4ypr8H1qiQ==", + "AoN/pnK4KEUaGw4V9SFjpg==", + "soBA65OmZdfBGJkBmY/4Iw==", + "mSstwJq7IkJ0JBJ5T8xDKg==", + "h13Xuonj+0dD1xH86IhSyQ==", + "HK9xG03FjgCy8vSR+hx8+Q==", + "oFanDWdePmmZN0xqwpUukA==", + "zCRZgVsHbQZcVMHd9pGD3A==", + "EvSB+rCggob2RBeXyDQRvQ==", + "tXuu7YpZOuMLTv87NjKerA==", + "DJ+a37tCaGF5OgUhG+T0NA==", + "KkXlgPJPen6HLxbNn5llBw==", + "2W6lz1Z7PhkvObEAg2XKJw==", + "n+xYzfKmMoB3lWkdZ+D3rg==", + "CPDs+We/1wvsGdaiqxzeCQ==", + "2Wvk/kouEEOY0evUkQLhOQ==", + "ezsm4aFd6+DO9FUxz0A8Pg==", + "9sYLg75/hudZaBA3FrzKHw==", + "Pp1ZMxJ8yajdbfKM4HAQxA==", + "xiyRfVG0EfBA+rCk+tgWRQ==", + "/IarsLzJB8bf0AupJJ+/Eg==", + "LJeLdqmriyAQp+QjZGFkdQ==", + "IhHyHbHGyQS+VawxteLP0w==", + "nGzPc0kI/EduVjiK7bzM6Q==", + "m06wctjNc3o7iyBHDMZs2w==", + "mSJF9dJnxZ15lTC6ilbJ2A==", + "xdmY+qyoxxuRZa9kuNpDEg==", + "oNOI17POQCAkDwj6lJsYOA==", + "p73gSu4d+4T/ZNNkIv9Nlw==", + "vOJ55zFdgPPauPyFYBf01w==", + "4A+RHIw+aDzw0rSRYfbc7g==", + "/gi3UZmunVOIXhZSktZ8zQ==", + "a6vem8n6WmRZAalDrHNP0g==", + "kGeXrHEN6o7h5qJYcThCPw==", + "wrewZ0hoHODf7qmoGcOd7g==", + "Z0sjccxzKylgEiPCFBqPSA==", + "LKyOFgUKKGUU/PxpFYMILw==", + "L2RofFWDO0fVgSz4D2mtdw==", + "KI7tQFYW38zYHOzkKp9/lQ==", + "ewe/P3pJLYu/kMb5tpvVog==", + "IADk81pIu8NIL/+9Fi94pA==", + "0L0FVcH5Dlj3oL8+e9Na7g==", + "tdiTXKrkqxstDasT0D5BPA==", + "R906Kxp2VFVR3VD+o6Vxcw==", + "wc+8ohFWgOF4VlSYiZIGwQ==", + "wJKFMqh6MGctWfasjHrPEg==", + "UHpge5Bldt9oPGo2oxnYvQ==", + "vX7RIhatQeXAMr1+OjzhZw==", + "s2AKVTwrY65/SWqQxDGJQg==", + "Q4bfQslDSqU64MOQbBQEUw==", + "mVT74Eht+gAowINoMKV7IQ==", + "EuGWtIbyKToOe6DN3NkVpQ==", + "ALlGgVDO8So71ccX0D6u2g==", + "Rww3qkF3kWSd+AaMT0kfdw==", + "hlvtFGW8r0PkbUAYXEM+Hw==", + "Oc3BqTF3ZBW3xE0QsnFn/A==", + "3j0kFUZ6g+yeeEljx+WXGg==", + "8BLkvEkfnOizJq0OTCYGzw==", + "Lqel4GdU0ZkfoJVXI5WC/Q==", + "rvE64KQGkVkbl07y7JwBqw==", + "HbXv8InyZqFT7i3VrllBgg==", + "zwQ/3MzTJ9rfBmrANIh14w==", + "gglLMohmJDPRGMY1XKndjQ==", + "lyfqic/AbEJbCiw+wA01FA==", + "XqUO7ULEYhDOuT/I2J8BOA==", + "wPhJcp7U7IVX83szbIOOxQ==", + "1gA65t5FiBTEgMELTQFUPQ==", + "ll2M0QQzBsj5OFi02fv3Yg==", + "wt+qDLU38kzNU75ZYi3Hbw==", + "a4EYNljinYTx9vb1VvUA6A==", + "T6LA+daQqRI38iDKZTdg1A==", + "gwyVIrTk5o0YMKQq4lpJ+Q==", + "bPRX2zl+K1S0iWAWUn1DZw==", + "KQw25X4LnQ9is+qdqfxo0w==", + "6tfM6dx3R5TiVKaqYQjnCg==", + "OlwHO6Sg2zIwsCOCRu0HiQ==", + "mr1qjhliRfl87wPOrJbFQg==", + "8c+lvG5sZNimvx9NKNH3ug==", + "5Nk2Z94DhlIdfG5HNgvBbQ==", + "F50iXjRo1aSTr37GQQXuJA==", + "tfgO55QqUyayjDfQh+Zo1Q==", + "h7Fc+eT/GuC8iWI+YTD0UQ==", + "3TjntNWtpG7VqBt3729L6Q==", + "+DWs0vvFGt6d3mzdcsdsyA==", + "VJt2kPVBLEBpGpgvuv1oUw==", + "XLq/nWX8lQqjxsK9jlCqUg==", + "9s3ar9q32Y5A3tla5GW/2Q==", + "51yLpfEdvqXmtB6+q27/AQ==", + "AiMtfedwGcddA+XYNc+21g==", + "p/48hurJ1kh2FFPpyChzJg==", + "CRiL6zpjfznhGXhCIbz8pQ==", + "/jDVt9dRIn+o4IQ1DPwbsg==", + "UNdKik7Vy23LjjPzEdzNsg==", + "Koiog/hpN7ew5kgJbty34A==", + "4itEKfbRCJvqlgKnyEdIOQ==", + "zi04Yc01ZheuFAQc59E45A==", + "etRjRvfL/IwceY/IJ1tgzQ==", + "3sNJJIx1NnjYcgJhjOLJOg==", + "4yVqq66iHYQjiTSxGgX2oA==", + "Q8RVI/kRbKuXa8HAQD7zUA==", + "OERGn45uzfDfglzFFn6JAg==", + "JGEy6VP3sz3LHiyT2UwNHQ==", + "1zDfWw5LdG20ClNP1HYxgw==", + "TGB+FIzzKnouLh5bAiVOQg==", + "n5GA+pA9mO/f4RN9NL9lNg==", + "bUxQBaqKyvlSHcuRL9whjg==", + "tOdlnsE3L3XCBDJRmb/OqA==", + "XdkxmYYooeDKzy7PXVigBQ==", + "PMvG4NqJP76kMRAup6TSZA==", + "qpFJZqzkklby+u1UT3c1iA==", + "fW3QZyq5UixIA1mP6eWgqQ==", + "9nMltdrrBmM5ESBY2FRjGA==", + "1Vtrv6QUAfiYQjlLTpNovg==", + "ur9JDCVNwzSH4q4ngDlHNQ==", + "4u3eyKc+y3uRnkASrgBVUw==", + "XddlSluOH6VkR7spFIFmdQ==", + "NOmu8oZc6CcKLu+Wfz2YOQ==", + "3Ejtsqw3Iep/UQd0tXnSlg==", + "y/e3HSdg7T19FanRpJ7+7Q==", + "YodhkayN5wsgPZEYN7/KNA==", + "pZfn6IiG+V28fN8E2hawDQ==", + "jGHMJqbj6X1NdTDyWmXYAQ==", + "olTSlmirL9MFhKORiOKYkQ==", + "CrJDgdfzOea2M2hVedTrIg==", + "fpXijBOM3Ai1RkmHven5Ww==", + "eLYKLr4labZeLiRrDJ9mnA==", + "9vmJUS7WIVOlhMqwipAknQ==", + "G7J/za99BFbAZH+Q+/B8WA==", + "Hb+pdSavvJ9lUXkSVZW8Og==", + "gTB2zM3RPm27mUQRXc/YRg==", + "e5KCqQ/1GAyVMRNgQpYf6g==", + "1ApqwW7pE+XUB2Cs2M6y7g==", + "/wiA2ltAuWyBhIvQAYBTQw==", + "HFCQEiZf7/SNc+oNSkkwlA==", + "JFi6N1PlrpKaYECOnI7GFg==", + "E4ojRDwGsIiyuxBuXHsKBA==", + "+25t/2lo0FUEtWYK8LdQZQ==", + "up2MVDi9ve+s83/nwNtZ7Q==", + "cXpfd6Io6Glj2/QzrDMCvA==", + "DCvI9byhw0wOFwF1uP6xIQ==", + "PibGJQNw7VHPTgqeCzGUGA==", + "0ZRGz+oj2infCAkuKKuHiQ==", + "2QS/6OBA1T01NlIbfkTYJg==", + "P14k+fyz0TG9yIPdojp52w==", + "g5EzTJ0KA4sO3+Opss3LMg==", + "R5oOM58zdbVxFSDQnNWqeA==", + "Vg2E5qEDfC+QxZTZDCu9yQ==", + "YPgMthbpcBN2CMkugV60hQ==", + "gZWTFt5CuLqMz6OhWL+hqQ==", + "YrEP9z2WPQ8l7TY1qWncDA==", + "7p4NpnoNSQR7ISg+w+4yFg==", + "9L6yLO93sRN70+3qq3ObfA==", + "QH36wzyIhh6I56Vnx79hRA==", + "9DtM1vls4rFTdrSnQ7uWXw==", + "ZlOAnCLV1PkR0kb3E+Nfuw==", + "9UhKmKtr4vMzXTEn74BEhg==", + "Ndx5LDiVyyTz/Fh3oBTgvA==", + "mXZ4JeBwT2WJQL4a/Tm4jQ==", + "N9nD7BGEM7LDwWIMDB+rEQ==", + "dmAfbd9F0OJHRAhNMEkRsA==", + "jV/D2B11NLXZRH77sG9lBw==", + "1C50kisi9nvyVJNfq2hOEQ==", + "NMbAjbnuK7EkVeY3CQI5VA==", + "J1nYqJ7tIQK1+a/3sMXI/Q==", + "m416yrrAlv+YPClGvGh+qQ==", + "rLZII1R6EGus+tYCiUtm6g==", + "xktOghh1S9nIX6fXWnT+Ug==", + "FcFcn4qmPse5mJCX5yNlsA==", + "xAAipGfHTGTjp9Qk1MR8RQ==", + "RQOlmzHwQKFpafKPJj0D8w==", + "WRjYdKdtnd1G9e/vFXCt0g==", + "z0BU//aSjYHAkGGk3ZSGNg==", + "M55eersiJuN9v61r8DoAjQ==", + "l2mAbuFF3QBIUILDODiUHQ==", + "IhpXs1TK7itQ3uTzZPRP5Q==", + "t2EkpUsLOEOsrnep0nZSmA==", + "lMaO8Yf+6YNowGyhDkPhQA==", + "UbSFw5jtyLk5MealqJw++A==", + "5u2PdDcIY3RQgtchSGDCGg==", + "MQYM3BT77i35LG9HcqxY2Q==", + "8AfCSZC0uasVON9Y/0P2Pw==", + "evaWFoxZNQcRszIRnxqB+A==", + "+8PiQt6O7pJI/nIvQpDaAg==", + "eRwaYiog2DdlGQyaltCMJg==", + "JyUJEnU6hJu8x2NCnGrYFw==", + "l0E0U/CJsyCVSTsXW4Fp+w==", + "XV13yK0QypJXmgI+dj4KYw==", + "jrRH0aTUYCOpPLZwzwPRfQ==", + "N3YDSkBUqSmrmNvZZx4a1Q==", + "0yJ7TQYzcp3DXVSvwavr+w==", + "rhgtLQh0F9bRA6IllM7AGw==", + "IWZnTJ3Hb9qw9HAK/M9gTw==", + "izeyFvXOumNgVyLrbKW45g==", + "xYD8jrCDmuQna+p1ebnKDQ==", + "SOdpdrk2ayeyv0xWdNuy9g==", + "HYylUirJRqLm+dkp39fSOQ==", + "q4z6A4l3nhX3smTmXr+Sig==", + "Zyo0fzewcqXiKe2mAwKx5g==", + "LMEtzh0+J27+4zORfcjITw==", + "LoUv/f2lcWpjftzpdivMww==", + "mXBfDUt/sBW5OUZs2sihvw==", + "PggVPQL5YKqSU/1asihcrg==", + "mI0eT4Rlr7QerMIngcu/ng==", + "NmQrsmb8PVP05qnSulPe5Q==", + "TcyyXrSsQsnz0gJ36w4Dxw==", + "y4mfEDerrhaqApDdhP5vjA==", + "ynaj4XjU27b7XbqPyxI8Ig==", + "Ua6aO6HwM+rY4sPR19CNFA==", + "3go7bJ9WqH/PPUTjNP3q/Q==", + "n1ixvP7SfwYT3L2iWpJg6A==", + "W8y32OLHihfeV0XFw7LmOg==", + "uzkNhmo2d08tv5AmnyqkoQ==", + "hJ8leLNuJ6DK5V8scnDaZQ==", + "KodYHHN62zESrXUye7M01g==", + "H+yPRiooEh5J7lAJB4RZ7Q==", + "dZg5w8rFETMp9SgW7m0gfg==", + "LsmsPokAwWNCuC74MaqFCQ==", + "1QGhj9NONF2rC44UdO+Izw==", + "uwGivY3/C9WK+dirRPJZ4A==", + "rXGWY/Gq+ZEsmvBHUfFMmQ==", + "j4FBMnNfdBwx0VsDeTvhFg==", + "81nkjWtpBhqhvOp6K8dcWg==", + "dCDaYYrgASXPMGFRV0RCGg==", + "Kj1QI+s9261S3lTtPKd9eg==", + "LblwOqNiciHmt2NXjd89tg==", + "46piyANQVvvLqcoMq5G8tQ==", + "XJihma9zSRrXLC+T+VcFDA==", + "K3NBEG8jJTJbSrYSOC3FKw==", + "cT3PwwS6ALZA/na9NjtdzA==", + "wJ4uCrl4DPg70ltw1dZO3w==", + "JATLdpQm//SQnkyCfI5x7Q==", + "X1PaCfEDScclLtOTiF5JUw==", + "444F9T6Y7J67Y9sULG81qg==", + "8JVHFRwAd/SCLU0CRJYofg==", + "aLh1XEUrfR9W82gzusKcOg==", + "U+bB5NjFIuQr/Y5UpXHwxA==", + "Egs14xVbRWjfBBX7X5Z60g==", + "KSorNz/PLR/YYkxaj1fuqw==", + "RDgGGxTtcPvRg/5KRRlz4w==", + "5T39s5CtSrK5awMPUcEWJg==", + "+PUVXkoTqHxJHO18z4KMfw==", + "Bvk8NX4l6WktLcRDRKsK/A==", + "kNGIV3+jQmJlZDTXy1pnyA==", + "E3jMjAgXwvwR8PA53g4+PQ==", + "MbI04HlTGCoc/6WDejwtaQ==", + "aEnHUfn7UE/Euh6jsMuZ7g==", + "z4Bft++f72QeDh4PWGr/sw==", + "1lCcQWGDePPYco4vYrA5vw==", + "iu5csar0IQQBOTgw5OvJwQ==", + "raKMXnnX6PFFsbloDqyVzQ==", + "uPnL9tboMZo0Kl2fe24CmA==", + "8OFxXwnPmrogpNoueZlC4Q==", + "V6CRKrKezPwsRdbm0DJ2Yg==", + "xmGgK3W5y+oCd0K2u8XjZQ==", + "Ry3zgZ6KHrpNyb7+Tt2Pkw==", + "IwLbkL33z+LdTjaFYh93kg==", + "caepyBOAFu0MxbcXrGf6TA==", + "iIWxFdolLcnXqIjPMg+5kQ==", + "P430CeF2MDkuq11YdjvV8A==", + "yCu+DVU/ceMTOZ5h/7wQTg==", + "4mQVNv7FHj+/O6XFqWFt/Q==", + "OEJ40VmMDYzc2ESEMontRA==", + "D66Suu3tWBD+eurBpPXfjA==", + "RNK9G1hfuz3ETY/RmA9+aA==", + "BYpHADmEnzBsegdYTv8B5Q==", + "DBKrdpCE0awppxST4o/zzg==", + "KOmdvm+wJuZ/nT/o1+xOuw==", + "gDxqUdxxeXDYhJk9zcrNyA==", + "UPzS4LR3p/h0u69+7YemrQ==", + "hf9HFxWRNX2ucH8FLS7ytA==", + "ozVqYsmUueKifb4lDyVyrg==", + "TfHvdbl2M4deg65QKBTPng==", + "SzCGM8ypE58FLaR1+1ccxQ==", + "3nthUmLZ30HxQrzr2d7xFA==", + "1jBaRO8Bg5l6TH7qJ8EPiw==", + "eJlcN+gJnqAnctbWSIO9uA==", + "G8LFBop8u6IIng+gQuVg3w==", + "3JhnM6G4L06NHt31lR0zXA==", + "342VOUOxoLHUqtHANt83Hw==", + "hRxbdeniAVFgKUgB9Q3Y+g==", + "cFFE2R4GztNoftYkqalqUQ==", + "YmaksRzoU+OwlpiEaBDYaQ==", + "jon1y9yMEGfiIBjsDeeJdA==", + "oSnrpW4UmmVXtUGWqLq+tQ==", + "zaqyy3GaJ7cp8qDoLJWcTw==", + "luO1R8dUM9gy1E2lojRQoA==", + "YHM6NNHjmodv+G0mRLK7kw==", + "ZSmN8mmI9lDEHkJqBBg0Nw==", + "520wTzrysiRi2Td92Zq0HQ==", + "RAAw14BA1ws5Wu/rU7oegw==", + "vb6Agwzk4JG0Nn7qRPPFMQ==", + "joDXdLpXvRjOqkRiYaD/Sw==", + "dK2DU3t1ns+DWDwfBvH3SQ==", + "gZNJ1Qq6OcnwXqc+jXzMLQ==", + "R8ULpSNu9FcCwXZM0QedSg==", + "mc45FSMtzdw2PTcEBwHWPw==", + "d0qvm3bl38rRCpYdWqolCQ==", + "o9tdzmIu+3J/EYU4YWyTkA==", + "5eXpiczlRdmqMYSaodOUiQ==", + "KYuUNrkTvjUWQovw9dNakA==", + "02im2RooJQ/9UfUrh5LO+A==", + "kWPUUi7x9kKKa6nJ+FDR5Q==", + "6z8CRivao3IMyV4p4gMh7g==", + "SmRWEzqddY9ucGAP5jXjAg==", + "DJscTYNFPyPmTb57g/1w+Q==", + "uOHrw37yF9oLLVd16nUpeg==", + "HaIRV9SNPRTPDOSX9sK/bg==", + "K4yZNVoqHjXNhrZzz2gTew==", + "bTNRjJm+FfSQVfd56nNNqQ==", + "x5lyMArsv1MuJmEFlWCnNw==", + "cxpZ4bloGv734LBf4NpVhA==", + "kUudvRfA33uJDzHIShQd3Q==", + "3Wfj05vCLFAB9vII5AU9tw==", + "FUQySDFodnRhr+NUsWt0KA==", + "eC/RcoCVQBlXdE9WtcgXIw==", + "NoX8lkY+kd2GPuGjp+s0tQ==", + "EzjbinBHx3Wr08eXpH3HXA==", + "0VsaJHR0Ms8zegsCpAKoyg==", + "e2xLFVavnZIUUtxJx+qa1g==", + "Kt6BTG1zdeBZ3nlVk+BZKQ==", + "EUXQZwLgnDG+C8qxVoBNdw==", + "0SkC/4PtnX1bMYgD6r6CLA==", + "rzj6mjHCcMEouL66083BAg==", + "V5HEaY3v9agOhsbYOAZgJA==", + "tJt6VDdAPEemBUvnoc4viA==", + "g0lWrzEYMntVIahC7i0O2g==", + "zCpibjrZOA3FQ4lYt0WoVA==", + "4Xh/B3C16rrjbES+FM1W8g==", + "GHEdXgGWOeOa6RuPMF0xXg==", + "3kREs/qaMX0AwFXN0LO5ow==", + "GLDNTSwygNBmuFwCIm7HtA==", + "JBkbaBiorCtFq9M9lSUdMg==", + "rJCuanCy51ydVD4nInf9IQ==", + "OzFRv+PzPqTNmOnvZGoo5g==", + "7mxU5fJl/c6dXss9H3vGcQ==", + "9J53kk+InE3CKa7cPyCXMw==", + "x9TIZ9Ua++3BX+MpjgTuWA==", + "h0MH5NGFfChgmRJ3E/R3HQ==", + "25w3ZRUzCvJwAVHYCIO5uw==", + "1Wc8jQlDSB4Dp32wkL2odw==", + "ipPPjxpXHS1tcykXmrHPMQ==", + "r95wJtP5rsTExKMS7QhHcw==", + "TZT86wXfzFffjt0f95UF5w==", + "VpmBstwR7qPVqPgKYQTA3g==", + "3++dZXzZ6AFEz7hK+i5hww==", + "mAiD16zf+rCc7Qzxjd5buA==", + "1JI9bT92UzxI8txjhst9LQ==", + "TNyvLixb03aP2f8cDozzfA==", + "spHVvA/pc7nF9Q4ON020+w==", + "GA8k6GQ20DGduVoC+gieRA==", + "T7waQc3PvTFr0yWGKmFQdQ==", + "P0Pc8owrqt6spdf7FgBFSw==", + "DKApp/alXiaPSRNm3MfSuA==", + "UreSZCIdDgloih8KLeX7gg==", + "xJi0T+psHOXMivSOVpMWeQ==", + "cNsC9bH30eM1EZS6IdEdtQ==", + "XjjrIpsmATV/lyln4tPb+g==", + "qt5CsMts2aD4lw/4Q6bHYQ==", + "h+KRDKIvyVUBmRjv1LcCyg==", + "2j83jrPwPfYlpJJ2clEBYQ==", + "ZrCezGLz38xKmzAom6yCTQ==", + "SEGu+cSbeeeZg4xWwsSErQ==", + "Duz/8Ebbd0w6oHwOs0Wnwg==", + "Ci7sS7Yi1+IwAM3VMAB4ew==", + "DG2Qe2DqPs5MkZPOqX363Q==", + "v0Bvws1WYVoEgDt8xmVKew==", + "CtDj/h2Q/lRey20G8dzSgA==", + "WRoJMO0BCJyn5V6qnpUi4Q==", + "RQywrOLZEKw9+kG6qTzr3g==", + "mU4CqbAwpwqegxJaOz9ofQ==", + "aN5x46Gw1VihRalwCt1CGg==", + "U6VQghxOXsydh3Naa5Nz4A==", + "YA+zdEC+yEgFWRIgS1Eiqw==", + "oPcxgoismve6+jXyIKK6AQ==", + "PqLCd/pwc+q5GkL6MB0jTg==", + "fHL+fHtDxhALZFb9W/uHuw==", + "dhTevyxTYAuKbdLWhG47Kw==", + "VllbOAjeW3Dpbj5lp2OSmA==", + "3itfXtlLPRmPCSYaSvc39Q==", + "GNak/LFeoHWlTdLW1iU4eg==", + "HuDuxs2KiGqmeyY1s1PjpQ==", + "xs8J3cesq7lDhP/dNltqOw==", + "foXSDEUwMhfHWJSmSejsQg==", + "6fWom3YoKvW6NIg6y9o9CQ==", + "NhZbSq0CjDNOAIvBHBM9zA==", + "5w4FbRhWACP7k2WnNitiHg==", + "0UeRwDID2RBIikInqFI7uw==", + "/y/jHHEpUu5TR+R2o96kXA==", + "voO3krg4sdy4Iu+MZEr8+g==", + "hdzol5dk//Q6tCm4+OndIA==", + "Nc5kiwXCAyjpzt43G5RF1A==", + "3UBYBMejKInSbCHRoJJ7dg==", + "dRFCIbVu0Y8XbjG5i+UFCQ==", + "t8pjhdyNJirkvYgWIO/eKg==", + "FAXzjjIr8l1nsQFPpgxM/g==", + "SPGpjEJrpflv1hF0qsFlPw==", + "9Y1ZmfiHJd9vCiZ6KfO1xQ==", + "7Eqzyb+Kep+dIahYJWNNxQ==", + "9rL8nC/VbSqrvnUtH9WsxQ==", + "H4FZ5Wcnb40hQM1DMGGe8A==", + "AjoXWGb/l9xH/hscgEc6kQ==", + "6nzFl41uutgDdC30oOeCqg==", + "3jo1jRy3MybXtoLR+JIbJw==", + "mXdE08dv+OlIhlcqMBH2Gg==", + "Ifd7DI6o8N5gnyAKqZTlRw==", + "JNUvg/kxL3rdcZnD4IqUxw==", + "ry8B+sAHNeFIZHCCDynFyw==", + "TXaEd5lIKhzjcncfNcBgSg==", + "Mr3ehuDMUimOSn+FlkchdA==", + "cwiGhjmX9v8I7E/ekQ0h+g==", + "I/r5+1jnqumCPprKC/2BqA==", + "S4V3MfGYk8I4fd3WH09yYw==", + "A+crVyUeynAkEMYKbnFjZw==", + "vtyHcNQPcUTRuZcQvRUX4Q==", + "UNKx1ZVv3HNp21zrUSm6ew==", + "rsAlvGLv2D0swd6ol3WlvA==", + "2qwqb8ENAR2fpQnw55sPDw==", + "xBJJuYYnsTJOeFggZSKC4Q==", + "omvtZZKruPiEt6fV0YXTdg==", + "JZEgKUhUN+USJsvtF4HZOg==", + "euG/kpJ5elSDOGNbWWDfNQ==", + "DiiVmM6/WNcp0MUjSaFq6w==", + "QCNS8gAml1M2pJ+MxZsueg==", + "M6+pggFsHfM3alFxcMOFNQ==", + "YLoWpDTwXnszEQm8FA164Q==", + "N08oUZtlXbQvO9t3vXnGog==", + "jkjuJowWuOa4CLY+RZiErQ==", + "mPf+S+6oAoVIYEVveaiNFA==", + "R0iVyo5qreP/68uZlZphDA==", + "GYlqhQgp03B0mXpUhQ+ZCA==", + "lQNbmWD7PhwNGye+zbc3GQ==", + "cNeaOJEOzUSDdRmenPQyuw==", + "Gp66/Txv6ebv5bn85TuQtA==", + "xAda6DVkcvvqhI8vWZeGyA==", + "Ggk1Qa0lEdAgCXG6SmCkBA==", + "MYuO7ZURXtyaf56q7hH4Zw==", + "RUIdZRTgJBudWUZQFgiFaQ==", + "bgFJxLirUom2zT0h7LdOpw==", + "A2gaOpIlrS7TKVQgy9XMSw==", + "zevXp0lqqnXv9X6Bgmjtqg==", + "a5iuFqWAdFFsRgp7SFYwNg==", + "TxTy0TaDsWTcRH3wdBEQLQ==", + "jephVdKDeJIhXPrdMOJ4qA==", + "C4KdamfqUPuJ3RGFdpIEdw==", + "zl6l2Ioz1qovRUIWrSyxVA==", + "+gGaDxUe0UnNrf3PPg1qQQ==", + "1HgbrlaLMHS6Qj/0kkaJxg==", + "eGxTly6Pnu7eV/MKYMmuYw==", + "RAMKfnlrzNjpyh2BWt6JHg==", + "4pZQm9ogCZ/EAR9pjJm1eA==", + "l1zv3erwXIegQFd02NlCag==", + "uHGyRZchuA4ulmuD5LqquQ==", + "/vFu89tsV+lbcoiqM/XWog==", + "63SUgqfQimrmjvy/bEDQ0w==", + "JLHuf+FlChFDa9LYfTQ4Eg==", + "I+ZnPePTFX8ZODe14bxgyA==", + "CtoK1k3U82BkvzuPfQ4pjQ==", + "6nqQm4C7y+wZ+qX0kVjwmA==", + "+C3kBxRXIjqBk0EJxe3Xfg==", + "qVu748pIxEZtiywg4/4qhw==", + "07o+sKjjRCYkwy/ACyoYhg==", + "CiLF4dkbLURekBcQbwPUVA==", + "W/N5/nkp4iQIPYfAagVV7A==", + "3PJOphhEjw0E4arTfVVwdg==", + "YdMbARHwB+bSOd0PlTlXiA==", + "41hbx5Yr7UWxsV6+bWUYUA==", + "SqJHXD0MorNwHtHL9TbWLg==", + "pWKGUzm/muwOiBtzkRMnRg==", + "az9zZ7HTa4FJGRQMcamvEw==", + "zavAAN8C9Wo8oBLyztp63Q==", + "yBAnPmwrMJ8kpPP292S/Lw==", + "E6szQhjuUAz2e0h9ffQfEQ==", + "Fs3cQxQyS9kM4T8j5R7rWw==", + "GB5fRLZxnjRUfEe0SwcePQ==", + "+9OY8xkT9dM/rb2T6ACtOQ==", + "If2xFBD1p91iDD7ZrsfgjA==", + "QCFfoMhy8EleZAOpfRY88w==", + "NobWPk1Z6bHt5s9NHXt/pg==", + "nK6T4vV4384OIcqO5tQMhA==", + "Zov1EzK+VomiuwT1+ulQ8g==", + "pF98OKDvLUlnTzo7wmlpOw==", + "Wrq9YDsieAMC3Y2DSY5Rcg==" + ] +} diff --git a/application/basilisk/base/content/newtab/newTab.js b/application/basilisk/base/content/newtab/newTab.js index 1731edadc..bbd2ef39d 100644 --- a/application/basilisk/base/content/newtab/newTab.js +++ b/application/basilisk/base/content/newtab/newTab.js @@ -11,6 +11,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/PageThumbs.jsm"); Cu.import("resource://gre/modules/BackgroundPageThumbs.jsm"); +Cu.import("resource:///modules/DirectoryLinksProvider.jsm"); Cu.import("resource://gre/modules/NewTabUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Rect", diff --git a/application/basilisk/base/content/newtab/newTab.xhtml b/application/basilisk/base/content/newtab/newTab.xhtml index 7de1ff3d4..eef51b4b2 100644 --- a/application/basilisk/base/content/newtab/newTab.xhtml +++ b/application/basilisk/base/content/newtab/newTab.xhtml @@ -73,6 +73,7 @@ <div id="newtab-horizontal-margin"> <div class="newtab-side-margin"/> <div id="newtab-grid"> + <h1 id="topsites-heading"/> </div> <div class="newtab-side-margin"/> </div> diff --git a/application/basilisk/base/content/newtab/page.js b/application/basilisk/base/content/newtab/page.js index b92d3d5ce..f7626ced2 100644 --- a/application/basilisk/base/content/newtab/page.js +++ b/application/basilisk/base/content/newtab/page.js @@ -48,6 +48,11 @@ var gPage = { let enabled = gAllPages.enabled; this._updateAttributes(enabled); + // Update thumbnails to the new enhanced setting + if (aData == "browser.newtabpage.enhanced") { + this.update(); + } + // Initialize the whole page if we haven't done that, yet. if (enabled) { this._init(); @@ -74,7 +79,10 @@ var gPage = { update(reason = "") { // Update immediately if we're visible. if (!document.hidden) { - if (gGrid.ready) { + // Ignore updates where reason=links-changed as those signal that the + // provider's set of links changed. We don't want to update visible pages + // in that case, it is ok to wait until the user opens the next tab. + if (reason != "links-changed" && gGrid.ready) { gGrid.refresh(); } @@ -111,6 +119,10 @@ var gPage = { document.getElementById("newtab-search-submit").value = document.body.getAttribute("dir") == "ltr" ? "\u25B6" : "\u25C0"; + if (Services.prefs.getBoolPref("browser.newtabpage.compact")) { + document.body.classList.add("compact"); + } + // Initialize search. gSearch.init(); @@ -248,6 +260,8 @@ var gPage = { onPageVisibleAndLoaded() { // Send the index of the last visible tile. this.reportLastVisibleTileIndex(); + // Maybe tell the user they can undo an initial automigration + this.maybeShowAutoMigrationUndoNotification(); }, reportLastVisibleTileIndex() { @@ -273,5 +287,11 @@ var gPage = { } } } - } + + DirectoryLinksProvider.reportSitesAction(sites, "view", lastIndex); + }, + + maybeShowAutoMigrationUndoNotification() { + sendAsyncMessage("NewTab:MaybeShowAutoMigrationUndoNotification"); + }, }; diff --git a/application/basilisk/base/content/newtab/sites.js b/application/basilisk/base/content/newtab/sites.js index b952deca5..9d103ce9b 100644 --- a/application/basilisk/base/content/newtab/sites.js +++ b/application/basilisk/base/content/newtab/sites.js @@ -171,8 +171,11 @@ Site.prototype = { // first check for end time, as it may modify the link this._checkLinkEndTime(); // setup display variables + let enhanced = gAllPages.enhanced && DirectoryLinksProvider.getEnhancedLink(this.link); let url = this.url; - let title = this.link.type == "history" ? this.link.baseDomain : this.title; + let title = enhanced && enhanced.title ? enhanced.title : + this.link.type == "history" ? this.link.baseDomain : + this.title; let tooltip = (this.title == url ? this.title : this.title + "\n" + url); let link = this._querySelector(".newtab-link"); @@ -241,7 +244,8 @@ Site.prototype = { */ refreshThumbnail: function Site_refreshThumbnail() { // Only enhance tiles if that feature is turned on - let link = this.link; + let link = gAllPages.enhanced && DirectoryLinksProvider.getEnhancedLink(this.link) || + this.link; let thumbnail = this._querySelector(".newtab-thumbnail.thumbnail"); if (link.bgColor) { @@ -263,6 +267,16 @@ Site.prototype = { placeholder.style.backgroundColor = "hsl(" + hue + ",80%,40%)"; placeholder.textContent = link.baseDomain.substr(0,1).toUpperCase(); } + + if (link.enhancedImageURI) { + let enhanced = this._querySelector(".enhanced-content"); + enhanced.style.backgroundImage = 'url("' + link.enhancedImageURI + '")'; + + if (this.link.type != link.type) { + this.node.setAttribute("type", "enhanced"); + this.enhancedId = link.directoryId; + } + } }, _ignoreHoverEvents: function(element) { @@ -282,6 +296,13 @@ Site.prototype = { this._node.addEventListener("dragstart", this, false); this._node.addEventListener("dragend", this, false); this._node.addEventListener("mouseover", this, false); + + // Specially treat the sponsored icon & suggested explanation + // text to prevent regular hover effects + let sponsored = this._querySelector(".newtab-sponsored"); + let suggested = this._querySelector(".newtab-suggested"); + this._ignoreHoverEvents(sponsored); + this._ignoreHoverEvents(suggested); }, /** @@ -312,6 +333,31 @@ Site.prototype = { .add(aIndex); }, + _toggleLegalText: function(buttonClass, explanationTextClass) { + let button = this._querySelector(buttonClass); + if (button.hasAttribute("active")) { + let explain = this._querySelector(explanationTextClass); + explain.parentNode.removeChild(explain); + + button.removeAttribute("active"); + } + else { + let explain = document.createElementNS(HTML_NAMESPACE, "div"); + explain.className = explanationTextClass.slice(1); // Slice off the first character, '.' + this.node.appendChild(explain); + + let link = '<a href="' + TILES_EXPLAIN_LINK + '">' + + newTabString("learn.link") + "</a>"; + let type = (this.node.getAttribute("suggested") && this.node.getAttribute("type") == "affiliate") ? + "suggested" : this.node.getAttribute("type"); + let icon = '<input type="button" class="newtab-control newtab-' + + (type == "enhanced" ? "customize" : "control-block") + '"/>'; + explain.innerHTML = newTabString(type + (type == "sponsored" ? ".explain2" : ".explain"), [icon, link]); + + button.setAttribute("active", "true"); + } + }, + /** * Handles site click events. */ @@ -330,13 +376,31 @@ Site.prototype = { action = "click"; } } + // Handle sponsored explanation link click + else if (target.parentElement.classList.contains("sponsored-explain")) { + action = "sponsored_link"; + } + else if (target.parentElement.classList.contains("suggested-explain")) { + action = "suggested_link"; + } // Only handle primary clicks for the remaining targets else if (button == 0) { aEvent.preventDefault(); if (target.classList.contains("newtab-control-block")) { + // Notify DirectoryLinksProvider of suggested tile block, this may + // affect if and how suggested tiles are recommended and needs to + // be reported before pages are updated inside block() call + if (this.link.targetedSite) { + DirectoryLinksProvider.handleSuggestedTileBlock(); + } this.block(); action = "block"; } + else if (target.classList.contains("sponsored-explain") || + target.classList.contains("newtab-sponsored")) { + this._toggleLegalText(".newtab-sponsored", ".sponsored-explain"); + action = "sponsored"; + } else if (pinned && target.classList.contains("newtab-control-pin")) { this.unpin(); action = "unpin"; @@ -349,6 +413,11 @@ Site.prototype = { action = "pin"; } } + + // Report all link click actions + if (action) { + DirectoryLinksProvider.reportSitesAction(gGrid.sites, action, tileIndex); + } }, /** diff --git a/application/basilisk/base/jar.mn b/application/basilisk/base/jar.mn index 845237e3e..5ec92d79a 100644 --- a/application/basilisk/base/jar.mn +++ b/application/basilisk/base/jar.mn @@ -125,6 +125,8 @@ browser.jar: content/browser/newtab/newTab.xhtml (content/newtab/newTab.xhtml) * content/browser/newtab/newTab.js (content/newtab/newTab.js) content/browser/newtab/newTab.css (content/newtab/newTab.css) + content/browser/newtab/newTab.inadjacent.json (content/newtab/newTab.inadjacent.json) + content/browser/newtab/alternativeDefaultSites.json (content/newtab/alternativeDefaultSites.json) * content/browser/pageinfo/pageInfo.xul (content/pageinfo/pageInfo.xul) content/browser/pageinfo/pageInfo.js (content/pageinfo/pageInfo.js) content/browser/pageinfo/pageInfo.css (content/pageinfo/pageInfo.css) diff --git a/application/basilisk/components/nsBrowserGlue.js b/application/basilisk/components/nsBrowserGlue.js index 6138e151d..3258159b6 100644 --- a/application/basilisk/components/nsBrowserGlue.js +++ b/application/basilisk/components/nsBrowserGlue.js @@ -32,6 +32,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "AlertsService", "@mozilla.org/alerts-s ["ContentPrefServiceParent", "resource://gre/modules/ContentPrefServiceParent.jsm"], ["ContentSearch", "resource:///modules/ContentSearch.jsm"], ["DateTimePickerHelper", "resource://gre/modules/DateTimePickerHelper.jsm"], + ["DirectoryLinksProvider", "resource:///modules/DirectoryLinksProvider.jsm"], ["Feeds", "resource:///modules/Feeds.jsm"], ["FileUtils", "resource://gre/modules/FileUtils.jsm"], ["FormValidationHandler", "resource:///modules/FormValidationHandler.jsm"], @@ -656,7 +657,9 @@ BrowserGlue.prototype = { webrtcUI.init(); AboutHome.init(); + DirectoryLinksProvider.init(); NewTabUtils.init(); + NewTabUtils.links.addProvider(DirectoryLinksProvider); AboutNewTab.init(); NewTabMessages.init(); diff --git a/application/basilisk/configure.in b/application/basilisk/configure.in index 9638c1e4d..8527d218c 100644 --- a/application/basilisk/configure.in +++ b/application/basilisk/configure.in @@ -8,6 +8,9 @@ dnl Things we need to carry from confvars.sh AC_DEFINE(MOZ_PHOENIX) AC_SUBST(MOZ_PHOENIX) +AC_DEFINE(MOZ_AUSTRALIS) +AC_SUBST(MOZ_AUSTRALIS) + AC_DEFINE(MC_BASILISK) AC_SUBST(MC_BASILISK) diff --git a/application/basilisk/confvars.sh b/application/basilisk/confvars.sh index 0343034a4..48985f16a 100644 --- a/application/basilisk/confvars.sh +++ b/application/basilisk/confvars.sh @@ -6,6 +6,7 @@ MOZ_APP_BASENAME=Basilisk MOZ_APP_VENDOR=Moonchild MOZ_PHOENIX=1 +MOZ_AUSTRALIS=1 MC_BASILISK=1 MOZ_UPDATER=1 diff --git a/application/basilisk/installer/package-manifest.in b/application/basilisk/installer/package-manifest.in index 27dfc4e05..6f80a7882 100644 --- a/application/basilisk/installer/package-manifest.in +++ b/application/basilisk/installer/package-manifest.in @@ -297,7 +297,6 @@ @RESPATH@/components/toolkit_finalizationwitness.xpt @RESPATH@/components/toolkit_formautofill.xpt @RESPATH@/components/toolkit_osfile.xpt -@RESPATH@/components/toolkit_securityreporter.xpt @RESPATH@/components/toolkit_perfmonitoring.xpt @RESPATH@/components/toolkit_xulstore.xpt @RESPATH@/components/toolkitprofile.xpt @@ -584,10 +583,6 @@ @RESPATH@/components/PrivateBrowsing.manifest @RESPATH@/components/PrivateBrowsingTrackingProtectionWhitelist.js -; Security Reports -@RESPATH@/components/SecurityReporter.manifest -@RESPATH@/components/SecurityReporter.js - ; ANGLE GLES-on-D3D rendering library #ifdef MOZ_ANGLE_RENDERER @BINPATH@/libEGL.dll diff --git a/application/basilisk/locales/en-US/chrome/browser/baseMenuOverlay.dtd b/application/basilisk/locales/en-US/chrome/browser/baseMenuOverlay.dtd index 1079c3cef..0fbd9cc35 100644 --- a/application/basilisk/locales/en-US/chrome/browser/baseMenuOverlay.dtd +++ b/application/basilisk/locales/en-US/chrome/browser/baseMenuOverlay.dtd @@ -23,7 +23,7 @@ <!ENTITY helpKeyboardShortcuts.label "Keyboard Shortcuts"> <!ENTITY helpKeyboardShortcuts.accesskey "K"> -<!ENTITY helpSafeMode.label "Restart with Add-ons Disabledā¦"> +<!ENTITY helpSafeMode.label "Restart in Safe Modeā¦"> <!ENTITY helpSafeMode.accesskey "R"> <!ENTITY helpSafeMode.stop.label "Restart with Add-ons Enabled"> <!ENTITY helpSafeMode.stop.accesskey "R"> diff --git a/application/basilisk/locales/en-US/chrome/browser/browser.properties b/application/basilisk/locales/en-US/chrome/browser/browser.properties index 8f4036dcd..aa7a82e4f 100644 --- a/application/basilisk/locales/en-US/chrome/browser/browser.properties +++ b/application/basilisk/locales/en-US/chrome/browser/browser.properties @@ -413,8 +413,8 @@ extensions.{972ce4c6-7e08-4474-a285-3208198ce6fd}.name=Default extensions.{972ce4c6-7e08-4474-a285-3208198ce6fd}.description=The default theme. # safeModeRestart -safeModeRestartPromptTitle=Restart with Add-ons Disabled -safeModeRestartPromptMessage=Are you sure you want to disable all add-ons and restart? +safeModeRestartPromptTitle=Restart in Safe Mode +safeModeRestartPromptMessage=Are you sure you want to restart in Safe Mode? safeModeRestartButton=Restart # LOCALIZATION NOTE (browser.menu.showCharacterEncoding): Set to the string diff --git a/application/basilisk/locales/en-US/chrome/overrides/netError.dtd b/application/basilisk/locales/en-US/chrome/overrides/netError.dtd index 6c65c9345..872847458 100644 --- a/application/basilisk/locales/en-US/chrome/overrides/netError.dtd +++ b/application/basilisk/locales/en-US/chrome/overrides/netError.dtd @@ -178,9 +178,6 @@ was trying to connect. --> <!ENTITY securityOverride.exceptionButtonLabel "Add Exceptionā¦"> -<!ENTITY errorReporting.automatic2 "Report errors like this to help Mozilla identify and block malicious sites"> -<!ENTITY errorReporting.learnMore "Learn moreā¦"> - <!ENTITY remoteXUL.title "Remote XUL"> <!ENTITY remoteXUL.longDesc "<p><ul><li>Please contact the website owners to inform them of this problem.</li></ul></p>"> diff --git a/application/basilisk/modules/DirectoryLinksProvider.jsm b/application/basilisk/modules/DirectoryLinksProvider.jsm new file mode 100644 index 000000000..117564099 --- /dev/null +++ b/application/basilisk/modules/DirectoryLinksProvider.jsm @@ -0,0 +1,1255 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +this.EXPORTED_SYMBOLS = ["DirectoryLinksProvider"]; + +const Ci = Components.interfaces; +const Cc = Components.classes; +const Cu = Components.utils; +const ParserUtils = Cc["@mozilla.org/parserutils;1"].getService(Ci.nsIParserUtils); + +Cu.importGlobalProperties(["XMLHttpRequest"]); + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/Task.jsm"); +Cu.import("resource://gre/modules/Timer.jsm"); + +XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", + "resource://gre/modules/NetUtil.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "NewTabUtils", + "resource://gre/modules/NewTabUtils.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "OS", + "resource://gre/modules/osfile.jsm") +XPCOMUtils.defineLazyModuleGetter(this, "Promise", + "resource://gre/modules/Promise.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils", + "resource://gre/modules/UpdateUtils.jsm"); +XPCOMUtils.defineLazyServiceGetter(this, "eTLD", + "@mozilla.org/network/effective-tld-service;1", + "nsIEffectiveTLDService"); +XPCOMUtils.defineLazyGetter(this, "gTextDecoder", () => { + return new TextDecoder(); +}); +XPCOMUtils.defineLazyGetter(this, "gCryptoHash", function () { + return Cc["@mozilla.org/security/hash;1"].createInstance(Ci.nsICryptoHash); +}); +XPCOMUtils.defineLazyGetter(this, "gUnicodeConverter", function () { + let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"] + .createInstance(Ci.nsIScriptableUnicodeConverter); + converter.charset = 'utf8'; + return converter; +}); + + +// The filename where directory links are stored locally +const DIRECTORY_LINKS_FILE = "directoryLinks.json"; +const DIRECTORY_LINKS_TYPE = "application/json"; + +// The preference that tells whether to match the OS locale +const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS"; + +// The preference that tells what locale the user selected +const PREF_SELECTED_LOCALE = "general.useragent.locale"; + +// The preference that tells where to obtain directory links +const PREF_DIRECTORY_SOURCE = "browser.newtabpage.directory.source"; + +// The preference that tells where to send click/view pings +const PREF_DIRECTORY_PING = "browser.newtabpage.directory.ping"; + +// The preference that tells if newtab is enhanced +const PREF_NEWTAB_ENHANCED = "browser.newtabpage.enhanced"; + +// Only allow link urls that are http(s) +const ALLOWED_LINK_SCHEMES = new Set(["http", "https"]); + +// Only allow link image urls that are https or data +const ALLOWED_IMAGE_SCHEMES = new Set(["https", "data"]); + +// Only allow urls to Mozilla's CDN or empty (for data URIs) +const ALLOWED_URL_BASE = new Set(["mozilla.net", ""]); + +// The frecency of a directory link +const DIRECTORY_FRECENCY = 1000; + +// The frecency of a suggested link +const SUGGESTED_FRECENCY = Infinity; + +// The filename where frequency cap data stored locally +const FREQUENCY_CAP_FILE = "frequencyCap.json"; + +// Default settings for daily and total frequency caps +const DEFAULT_DAILY_FREQUENCY_CAP = 3; +const DEFAULT_TOTAL_FREQUENCY_CAP = 10; + +// Default timeDelta to prune unused frequency cap objects +// currently set to 10 days in milliseconds +const DEFAULT_PRUNE_TIME_DELTA = 10*24*60*60*1000; + +// The min number of visible (not blocked) history tiles to have before showing suggested tiles +const MIN_VISIBLE_HISTORY_TILES = 8; + +// The max number of visible (not blocked) history tiles to test for inadjacency +const MAX_VISIBLE_HISTORY_TILES = 15; + +// Allowed ping actions remotely stored as columns: case-insensitive [a-z0-9_] +const PING_ACTIONS = ["block", "click", "pin", "sponsored", "sponsored_link", "unpin", "view"]; + +// Location of inadjacent sites json +const INADJACENCY_SOURCE = "chrome://browser/content/newtab/newTab.inadjacent.json"; + +// Fake URL to keep track of last block of a suggested tile in the frequency cap object +const FAKE_SUGGESTED_BLOCK_URL = "ignore://suggested_block"; + +// Time before suggested tile is allowed to play again after block - default to 1 day +const AFTER_SUGGESTED_BLOCK_DECAY_TIME = 24*60*60*1000; + +/** + * Singleton that serves as the provider of directory links. + * Directory links are a hard-coded set of links shown if a user's link + * inventory is empty. + */ +var DirectoryLinksProvider = { + + __linksURL: null, + + _observers: new Set(), + + // links download deferred, resolved upon download completion + _downloadDeferred: null, + + // download default interval is 24 hours in milliseconds + _downloadIntervalMS: 86400000, + + /** + * A mapping from eTLD+1 to an enhanced link objects + */ + _enhancedLinks: new Map(), + + /** + * A mapping from site to a list of suggested link objects + */ + _suggestedLinks: new Map(), + + /** + * Frequency Cap object - maintains daily and total tile counts, and frequency cap settings + */ + _frequencyCaps: {}, + + /** + * A set of top sites that we can provide suggested links for + */ + _topSitesWithSuggestedLinks: new Set(), + + /** + * lookup Set of inadjacent domains + */ + _inadjacentSites: new Set(), + + /** + * This flag is set if there is a suggested tile configured to avoid + * inadjacent sites in new tab + */ + _avoidInadjacentSites: false, + + /** + * This flag is set if _avoidInadjacentSites is true and there is + * an inadjacent site in the new tab + */ + _newTabHasInadjacentSite: false, + + get _observedPrefs() { + return Object.freeze({ + enhanced: PREF_NEWTAB_ENHANCED, + linksURL: PREF_DIRECTORY_SOURCE, + matchOSLocale: PREF_MATCH_OS_LOCALE, + prefSelectedLocale: PREF_SELECTED_LOCALE, + }); + }, + + get _linksURL() { + if (!this.__linksURL) { + try { + this.__linksURL = Services.prefs.getCharPref(this._observedPrefs["linksURL"]); + this.__linksURLModified = Services.prefs.prefHasUserValue(this._observedPrefs["linksURL"]); + } + catch (e) { + Cu.reportError("Error fetching directory links url from prefs: " + e); + } + } + return this.__linksURL; + }, + + /** + * Gets the currently selected locale for display. + * @return the selected locale or "en-US" if none is selected + */ + get locale() { + let matchOS; + try { + matchOS = Services.prefs.getBoolPref(PREF_MATCH_OS_LOCALE); + } + catch (e) {} + + if (matchOS) { + return Services.locale.getLocaleComponentForUserAgent(); + } + + try { + let locale = Services.prefs.getComplexValue(PREF_SELECTED_LOCALE, + Ci.nsIPrefLocalizedString); + if (locale) { + return locale.data; + } + } + catch (e) {} + + try { + return Services.prefs.getCharPref(PREF_SELECTED_LOCALE); + } + catch (e) {} + + return "en-US"; + }, + + /** + * Set appropriate default ping behavior controlled by enhanced pref + */ + _setDefaultEnhanced: function DirectoryLinksProvider_setDefaultEnhanced() { + if (!Services.prefs.prefHasUserValue(PREF_NEWTAB_ENHANCED)) { + let enhanced = Services.prefs.getBoolPref(PREF_NEWTAB_ENHANCED); + try { + // Default to not enhanced if DNT is set to tell websites to not track + if (Services.prefs.getBoolPref("privacy.donottrackheader.enabled")) { + enhanced = false; + } + } + catch (ex) {} + Services.prefs.setBoolPref(PREF_NEWTAB_ENHANCED, enhanced); + } + }, + + observe: function DirectoryLinksProvider_observe(aSubject, aTopic, aData) { + if (aTopic == "nsPref:changed") { + switch (aData) { + // Re-set the default in case the user clears the pref + case this._observedPrefs.enhanced: + this._setDefaultEnhanced(); + break; + + case this._observedPrefs.linksURL: + delete this.__linksURL; + // fallthrough + + // Force directory download on changes to fetch related prefs + case this._observedPrefs.matchOSLocale: + case this._observedPrefs.prefSelectedLocale: + this._fetchAndCacheLinksIfNecessary(true); + break; + } + } + }, + + _addPrefsObserver: function DirectoryLinksProvider_addObserver() { + for (let pref in this._observedPrefs) { + let prefName = this._observedPrefs[pref]; + Services.prefs.addObserver(prefName, this, false); + } + }, + + _removePrefsObserver: function DirectoryLinksProvider_removeObserver() { + for (let pref in this._observedPrefs) { + let prefName = this._observedPrefs[pref]; + Services.prefs.removeObserver(prefName, this); + } + }, + + _cacheSuggestedLinks: function(link) { + // Don't cache links that don't have the expected 'frecent_sites' + if (!link.frecent_sites) { + return; + } + + for (let suggestedSite of link.frecent_sites) { + let suggestedMap = this._suggestedLinks.get(suggestedSite) || new Map(); + suggestedMap.set(link.url, link); + this._setupStartEndTime(link); + this._suggestedLinks.set(suggestedSite, suggestedMap); + } + }, + + _fetchAndCacheLinks: function DirectoryLinksProvider_fetchAndCacheLinks(uri) { + // Replace with the same display locale used for selecting links data + uri = uri.replace("%LOCALE%", this.locale); + uri = uri.replace("%CHANNEL%", UpdateUtils.UpdateChannel); + + return this._downloadJsonData(uri).then(json => { + return OS.File.writeAtomic(this._directoryFilePath, json, {tmpPath: this._directoryFilePath + ".tmp"}); + }); + }, + + /** + * Downloads a links with json content + * @param download uri + * @return promise resolved to json string, "{}" returned if status != 200 + */ + _downloadJsonData: function DirectoryLinksProvider__downloadJsonData(uri) { + let deferred = Promise.defer(); + let xmlHttp = this._newXHR(); + + xmlHttp.onload = function(aResponse) { + let json = this.responseText; + if (this.status && this.status != 200) { + json = "{}"; + } + deferred.resolve(json); + }; + + xmlHttp.onerror = function(e) { + deferred.reject("Fetching " + uri + " results in error code: " + e.target.status); + }; + + try { + xmlHttp.open("GET", uri); + // Override the type so XHR doesn't complain about not well-formed XML + xmlHttp.overrideMimeType(DIRECTORY_LINKS_TYPE); + // Set the appropriate request type for servers that require correct types + xmlHttp.setRequestHeader("Content-Type", DIRECTORY_LINKS_TYPE); + xmlHttp.send(); + } catch (e) { + deferred.reject("Error fetching " + uri); + Cu.reportError(e); + } + return deferred.promise; + }, + + /** + * Downloads directory links if needed + * @return promise resolved immediately if no download needed, or upon completion + */ + _fetchAndCacheLinksIfNecessary: function DirectoryLinksProvider_fetchAndCacheLinksIfNecessary(forceDownload=false) { + if (this._downloadDeferred) { + // fetching links already - just return the promise + return this._downloadDeferred.promise; + } + + if (forceDownload || this._needsDownload) { + this._downloadDeferred = Promise.defer(); + this._fetchAndCacheLinks(this._linksURL).then(() => { + // the new file was successfully downloaded and cached, so update a timestamp + this._lastDownloadMS = Date.now(); + this._downloadDeferred.resolve(); + this._downloadDeferred = null; + this._callObservers("onManyLinksChanged") + }, + error => { + this._downloadDeferred.resolve(); + this._downloadDeferred = null; + this._callObservers("onDownloadFail"); + }); + return this._downloadDeferred.promise; + } + + // download is not needed + return Promise.resolve(); + }, + + /** + * @return true if download is needed, false otherwise + */ + get _needsDownload () { + // fail if last download occured less then 24 hours ago + if ((Date.now() - this._lastDownloadMS) > this._downloadIntervalMS) { + return true; + } + return false; + }, + + /** + * Create a new XMLHttpRequest that is anonymous, i.e., doesn't send cookies + */ + _newXHR() { + return new XMLHttpRequest({mozAnon: true}); + }, + + /** + * Reads directory links file and parses its content + * @return a promise resolved to an object with keys 'directory' and 'suggested', + * each containing a valid list of links, + * or {'directory': [], 'suggested': []} if read or parse fails. + */ + _readDirectoryLinksFile: function DirectoryLinksProvider_readDirectoryLinksFile() { + let emptyOutput = {directory: [], suggested: [], enhanced: []}; + return OS.File.read(this._directoryFilePath).then(binaryData => { + let output; + try { + let json = gTextDecoder.decode(binaryData); + let linksObj = JSON.parse(json); + output = {directory: linksObj.directory || [], + suggested: linksObj.suggested || [], + enhanced: linksObj.enhanced || []}; + } + catch (e) { + Cu.reportError(e); + } + return output || emptyOutput; + }, + error => { + Cu.reportError(error); + return emptyOutput; + }); + }, + + /** + * Translates link.time_limits to UTC miliseconds and sets + * link.startTime and link.endTime properties in link object + */ + _setupStartEndTime: function DirectoryLinksProvider_setupStartEndTime(link) { + // set start/end limits. Use ISO_8601 format: '2014-01-10T20:20:20.600Z' + // (details here http://en.wikipedia.org/wiki/ISO_8601) + // Note that if timezone is missing, FX will interpret as local time + // meaning that the server can sepecify any time, but if the capmaign + // needs to start at same time across multiple timezones, the server + // omits timezone indicator + if (!link.time_limits) { + return; + } + + let parsedTime; + if (link.time_limits.start) { + parsedTime = Date.parse(link.time_limits.start); + if (parsedTime && !isNaN(parsedTime)) { + link.startTime = parsedTime; + } + } + if (link.time_limits.end) { + parsedTime = Date.parse(link.time_limits.end); + if (parsedTime && !isNaN(parsedTime)) { + link.endTime = parsedTime; + } + } + }, + + /* + * Handles campaign timeout + */ + _onCampaignTimeout: function DirectoryLinksProvider_onCampaignTimeout() { + // _campaignTimeoutID is invalid here, so just set it to null + this._campaignTimeoutID = null; + this._updateSuggestedTile(); + }, + + /* + * Clears capmpaign timeout + */ + _clearCampaignTimeout: function DirectoryLinksProvider_clearCampaignTimeout() { + if (this._campaignTimeoutID) { + clearTimeout(this._campaignTimeoutID); + this._campaignTimeoutID = null; + } + }, + + /** + * Setup capmpaign timeout to recompute suggested tiles upon + * reaching soonest start or end time for the campaign + * @param timeout in milliseconds + */ + _setupCampaignTimeCheck: function DirectoryLinksProvider_setupCampaignTimeCheck(timeout) { + // sanity check + if (!timeout || timeout <= 0) { + return; + } + this._clearCampaignTimeout(); + // setup next timeout + this._campaignTimeoutID = setTimeout(this._onCampaignTimeout.bind(this), timeout); + }, + + /** + * Test link for campaign time limits: checks if link falls within start/end time + * and returns an object containing a use flag and the timeoutDate milliseconds + * when the link has to be re-checked for campaign start-ready or end-reach + * @param link + * @return object {use: true or false, timeoutDate: milliseconds or null} + */ + _testLinkForCampaignTimeLimits: function DirectoryLinksProvider_testLinkForCampaignTimeLimits(link) { + let currentTime = Date.now(); + // test for start time first + if (link.startTime && link.startTime > currentTime) { + // not yet ready for start + return {use: false, timeoutDate: link.startTime}; + } + // otherwise check for end time + if (link.endTime) { + // passed end time + if (link.endTime <= currentTime) { + return {use: false}; + } + // otherwise link is still ok, but we need to set timeoutDate + return {use: true, timeoutDate: link.endTime}; + } + // if we are here, the link is ok and no timeoutDate needed + return {use: true}; + }, + + /** + * Handles block on suggested tile: updates fake block url with current timestamp + */ + handleSuggestedTileBlock: function DirectoryLinksProvider_handleSuggestedTileBlock() { + this._updateFrequencyCapSettings({url: FAKE_SUGGESTED_BLOCK_URL}); + this._writeFrequencyCapFile(); + this._updateSuggestedTile(); + }, + + /** + * Checks if suggested tile is being blocked for the rest of "decay time" + * @return True if blocked, false otherwise + */ + _isSuggestedTileBlocked: function DirectoryLinksProvider__isSuggestedTileBlocked() { + let capObject = this._frequencyCaps[FAKE_SUGGESTED_BLOCK_URL]; + if (!capObject || !capObject.lastUpdated) { + // user never blocked suggested tile or lastUpdated is missing + return false; + } + // otherwise, make sure that enough time passed after suggested tile was blocked + return (capObject.lastUpdated + AFTER_SUGGESTED_BLOCK_DECAY_TIME) > Date.now(); + }, + + /** + * Report some action on a newtab page (view, click) + * @param sites Array of sites shown on newtab page + * @param action String of the behavior to report + * @param triggeringSiteIndex optional Int index of the site triggering action + * @return download promise + */ + reportSitesAction: function DirectoryLinksProvider_reportSitesAction(sites, action, triggeringSiteIndex) { + // Check if the suggested tile was shown + if (action == "view") { + sites.slice(0, triggeringSiteIndex + 1).filter(s => s).forEach(site => { + let {targetedSite, url} = site.link; + if (targetedSite) { + this._addFrequencyCapView(url); + } + }); + } + // any click action on a suggested tile should stop that tile suggestion + // click/block - user either removed a tile or went to a landing page + // pin - tile turned into history tile, should no longer be suggested + // unpin - the tile was pinned before, should not matter + else { + // suggested tile has targetedSite, or frecent_sites if it was pinned + let {frecent_sites, targetedSite, url} = sites[triggeringSiteIndex].link; + if (frecent_sites || targetedSite) { + this._setFrequencyCapClick(url); + } + } + + let newtabEnhanced = false; + let pingEndPoint = ""; + try { + newtabEnhanced = Services.prefs.getBoolPref(PREF_NEWTAB_ENHANCED); + pingEndPoint = Services.prefs.getCharPref(PREF_DIRECTORY_PING); + } + catch (ex) {} + + // Bug 1240245 - We no longer send pings, but frequency capping and fetching + // tests depend on the following actions, so references to PING remain. + let invalidAction = PING_ACTIONS.indexOf(action) == -1; + if (!newtabEnhanced || pingEndPoint == "" || invalidAction) { + return Promise.resolve(); + } + + return Task.spawn(function* () { + // since we updated views/clicks we need write _frequencyCaps to disk + yield this._writeFrequencyCapFile(); + // Use this as an opportunity to potentially fetch new links + yield this._fetchAndCacheLinksIfNecessary(); + }.bind(this)); + }, + + /** + * Get the enhanced link object for a link (whether history or directory) + */ + getEnhancedLink: function DirectoryLinksProvider_getEnhancedLink(link) { + // Use the provided link if it's already enhanced + return link.enhancedImageURI && link ? link : + this._enhancedLinks.get(NewTabUtils.extractSite(link.url)); + }, + + /** + * Check if a url's scheme is in a Set of allowed schemes and if the base + * domain is allowed. + * @param url to check + * @param allowed Set of allowed schemes + * @param checkBase boolean to check the base domain + */ + isURLAllowed(url, allowed, checkBase) { + // Assume no url is an allowed url + if (!url) { + return true; + } + + let scheme = "", base = ""; + try { + // A malformed url will not be allowed + let uri = Services.io.newURI(url, null, null); + scheme = uri.scheme; + + // URIs without base domains will be allowed + base = Services.eTLD.getBaseDomain(uri); + } + catch (ex) {} + // Require a scheme match and the base only if desired + return allowed.has(scheme) && (!checkBase || ALLOWED_URL_BASE.has(base)); + }, + + _escapeChars(text) { + let charMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + + return text.replace(/[&<>"']/g, (character) => charMap[character]); + }, + + /** + * Gets the current set of directory links. + * @param aCallback The function that the array of links is passed to. + */ + getLinks: function DirectoryLinksProvider_getLinks(aCallback) { + this._readDirectoryLinksFile().then(rawLinks => { + // Reset the cache of suggested tiles and enhanced images for this new set of links + this._enhancedLinks.clear(); + this._suggestedLinks.clear(); + this._clearCampaignTimeout(); + this._avoidInadjacentSites = false; + + // Only check base domain for images when using the default pref + let checkBase = !this.__linksURLModified; + let validityFilter = function(link) { + // Make sure the link url is allowed and images too if they exist + return this.isURLAllowed(link.url, ALLOWED_LINK_SCHEMES, false) && + (!link.imageURI || + this.isURLAllowed(link.imageURI, ALLOWED_IMAGE_SCHEMES, checkBase)) && + (!link.enhancedImageURI || + this.isURLAllowed(link.enhancedImageURI, ALLOWED_IMAGE_SCHEMES, checkBase)); + }.bind(this); + + rawLinks.suggested.filter(validityFilter).forEach((link, position) => { + // Suggested sites must have an adgroup name. + if (!link.adgroup_name) { + return; + } + + let sanitizeFlags = ParserUtils.SanitizerCidEmbedsOnly | + ParserUtils.SanitizerDropForms | + ParserUtils.SanitizerDropNonCSSPresentation; + + link.explanation = this._escapeChars(link.explanation ? ParserUtils.convertToPlainText(link.explanation, sanitizeFlags, 0) : ""); + link.targetedName = this._escapeChars(ParserUtils.convertToPlainText(link.adgroup_name, sanitizeFlags, 0)); + link.lastVisitDate = rawLinks.suggested.length - position; + // check if link wants to avoid inadjacent sites + if (link.check_inadjacency) { + this._avoidInadjacentSites = true; + } + + // We cache suggested tiles here but do not push any of them in the links list yet. + // The decision for which suggested tile to include will be made separately. + this._cacheSuggestedLinks(link); + this._updateFrequencyCapSettings(link); + }); + + rawLinks.enhanced.filter(validityFilter).forEach((link, position) => { + link.lastVisitDate = rawLinks.enhanced.length - position; + + // Stash the enhanced image for the site + if (link.enhancedImageURI) { + this._enhancedLinks.set(NewTabUtils.extractSite(link.url), link); + } + }); + + let links = rawLinks.directory.filter(validityFilter).map((link, position) => { + link.lastVisitDate = rawLinks.directory.length - position; + link.frecency = DIRECTORY_FRECENCY; + return link; + }); + + // Allow for one link suggestion on top of the default directory links + this.maxNumLinks = links.length + 1; + + // prune frequency caps of outdated urls + this._pruneFrequencyCapUrls(); + // write frequency caps object to disk asynchronously + this._writeFrequencyCapFile(); + + return links; + }).catch(ex => { + Cu.reportError(ex); + return []; + }).then(links => { + aCallback(links); + this._populatePlacesLinks(); + }); + }, + + init: function DirectoryLinksProvider_init() { + this._setDefaultEnhanced(); + this._addPrefsObserver(); + // setup directory file path and last download timestamp + this._directoryFilePath = OS.Path.join(OS.Constants.Path.localProfileDir, DIRECTORY_LINKS_FILE); + this._lastDownloadMS = 0; + + // setup frequency cap file path + this._frequencyCapFilePath = OS.Path.join(OS.Constants.Path.localProfileDir, FREQUENCY_CAP_FILE); + // setup inadjacent sites URL + this._inadjacentSitesUrl = INADJACENCY_SOURCE; + + NewTabUtils.placesProvider.addObserver(this); + NewTabUtils.links.addObserver(this); + + return Task.spawn(function*() { + // get the last modified time of the links file if it exists + let doesFileExists = yield OS.File.exists(this._directoryFilePath); + if (doesFileExists) { + let fileInfo = yield OS.File.stat(this._directoryFilePath); + this._lastDownloadMS = Date.parse(fileInfo.lastModificationDate); + } + // read frequency cap file + yield this._readFrequencyCapFile(); + // fetch directory on startup without force + yield this._fetchAndCacheLinksIfNecessary(); + // fecth inadjacent sites on startup + yield this._loadInadjacentSites(); + }.bind(this)); + }, + + _handleManyLinksChanged: function() { + this._topSitesWithSuggestedLinks.clear(); + this._suggestedLinks.forEach((suggestedLinks, site) => { + if (NewTabUtils.isTopPlacesSite(site)) { + this._topSitesWithSuggestedLinks.add(site); + } + }); + this._updateSuggestedTile(); + }, + + /** + * Updates _topSitesWithSuggestedLinks based on the link that was changed. + * + * @return true if _topSitesWithSuggestedLinks was modified, false otherwise. + */ + _handleLinkChanged: function(aLink) { + let changedLinkSite = NewTabUtils.extractSite(aLink.url); + let linkStored = this._topSitesWithSuggestedLinks.has(changedLinkSite); + + if (!NewTabUtils.isTopPlacesSite(changedLinkSite) && linkStored) { + this._topSitesWithSuggestedLinks.delete(changedLinkSite); + return true; + } + + if (this._suggestedLinks.has(changedLinkSite) && + NewTabUtils.isTopPlacesSite(changedLinkSite) && !linkStored) { + this._topSitesWithSuggestedLinks.add(changedLinkSite); + return true; + } + + // always run _updateSuggestedTile if aLink is inadjacent + // and there are tiles configured to avoid it + if (this._avoidInadjacentSites && this._isInadjacentLink(aLink)) { + return true; + } + + return false; + }, + + _populatePlacesLinks: function () { + NewTabUtils.links.populateProviderCache(NewTabUtils.placesProvider, () => { + this._handleManyLinksChanged(); + }); + }, + + onDeleteURI: function(aProvider, aLink) { + let {url} = aLink; + // remove clicked flag for that url and + // call observer upon disk write completion + this._removeTileClick(url).then(() => { + this._callObservers("onDeleteURI", url); + }); + }, + + onClearHistory: function() { + // remove all clicked flags and call observers upon file write + this._removeAllTileClicks().then(() => { + this._callObservers("onClearHistory"); + }); + }, + + onLinkChanged: function (aProvider, aLink) { + // Make sure NewTabUtils.links handles the notification first. + setTimeout(() => { + if (this._handleLinkChanged(aLink) || this._shouldUpdateSuggestedTile()) { + this._updateSuggestedTile(); + } + }, 0); + }, + + onManyLinksChanged: function () { + // Make sure NewTabUtils.links handles the notification first. + setTimeout(() => { + this._handleManyLinksChanged(); + }, 0); + }, + + _getCurrentTopSiteCount: function() { + let visibleTopSiteCount = 0; + let newTabLinks = NewTabUtils.links.getLinks(); + for (let link of newTabLinks.slice(0, MIN_VISIBLE_HISTORY_TILES)) { + // compute visibleTopSiteCount for suggested tiles + if (link && (link.type == "history" || link.type == "enhanced")) { + visibleTopSiteCount++; + } + } + // since newTabLinks are available, set _newTabHasInadjacentSite here + // note that _shouldUpdateSuggestedTile is called by _updateSuggestedTile + this._newTabHasInadjacentSite = this._avoidInadjacentSites && this._checkForInadjacentSites(newTabLinks); + + return visibleTopSiteCount; + }, + + _shouldUpdateSuggestedTile: function() { + let sortedLinks = NewTabUtils.getProviderLinks(this); + + let mostFrecentLink = {}; + if (sortedLinks && sortedLinks.length) { + mostFrecentLink = sortedLinks[0] + } + + let currTopSiteCount = this._getCurrentTopSiteCount(); + if ((!mostFrecentLink.targetedSite && currTopSiteCount >= MIN_VISIBLE_HISTORY_TILES) || + (mostFrecentLink.targetedSite && currTopSiteCount < MIN_VISIBLE_HISTORY_TILES)) { + // If mostFrecentLink has a targetedSite then mostFrecentLink is a suggested link. + // If we have enough history links (8+) to show a suggested tile and we are not + // already showing one, then we should update (to *attempt* to add a suggested tile). + // OR if we don't have enough history to show a suggested tile (<8) and we are + // currently showing one, we should update (to remove it). + return true; + } + + return false; + }, + + /** + * Chooses and returns a suggested tile based on a user's top sites + * that we have an available suggested tile for. + * + * @return the chosen suggested tile, or undefined if there isn't one + */ + _updateSuggestedTile: function() { + let sortedLinks = NewTabUtils.getProviderLinks(this); + + if (!sortedLinks) { + // If NewTabUtils.links.resetCache() is called before getting here, + // sortedLinks may be undefined. + return undefined; + } + + // Delete the current suggested tile, if one exists. + let initialLength = sortedLinks.length; + if (initialLength) { + let mostFrecentLink = sortedLinks[0]; + if (mostFrecentLink.targetedSite) { + this._callObservers("onLinkChanged", { + url: mostFrecentLink.url, + frecency: SUGGESTED_FRECENCY, + lastVisitDate: mostFrecentLink.lastVisitDate, + type: mostFrecentLink.type, + }, 0, true); + } + } + + if (this._topSitesWithSuggestedLinks.size == 0 || + !this._shouldUpdateSuggestedTile() || + this._isSuggestedTileBlocked()) { + // There are no potential suggested links we can show or not + // enough history for a suggested tile, or suggested tile was + // recently blocked and wait time interval has not decayed yet + return undefined; + } + + // Create a flat list of all possible links we can show as suggested. + // Note that many top sites may map to the same suggested links, but we only + // want to count each suggested link once (based on url), thus possibleLinks is a map + // from url to suggestedLink. Thus, each link has an equal chance of being chosen at + // random from flattenedLinks if it appears only once. + let nextTimeout; + let possibleLinks = new Map(); + let targetedSites = new Map(); + this._topSitesWithSuggestedLinks.forEach(topSiteWithSuggestedLink => { + let suggestedLinksMap = this._suggestedLinks.get(topSiteWithSuggestedLink); + suggestedLinksMap.forEach((suggestedLink, url) => { + // Skip this link if we've shown it too many times already + if (!this._testFrequencyCapLimits(url)) { + return; + } + + // as we iterate suggestedLinks, check for campaign start/end + // time limits, and set nextTimeout to the closest timestamp + let {use, timeoutDate} = this._testLinkForCampaignTimeLimits(suggestedLink); + // update nextTimeout is necessary + if (timeoutDate && (!nextTimeout || nextTimeout > timeoutDate)) { + nextTimeout = timeoutDate; + } + // Skip link if it falls outside campaign time limits + if (!use) { + return; + } + + // Skip link if it avoids inadjacent sites and newtab has one + if (suggestedLink.check_inadjacency && this._newTabHasInadjacentSite) { + return; + } + + possibleLinks.set(url, suggestedLink); + + // Keep a map of URL to targeted sites. We later use this to show the user + // what site they visited to trigger this suggestion. + if (!targetedSites.get(url)) { + targetedSites.set(url, []); + } + targetedSites.get(url).push(topSiteWithSuggestedLink); + }) + }); + + // setup timeout check for starting or ending campaigns + if (nextTimeout) { + this._setupCampaignTimeCheck(nextTimeout - Date.now()); + } + + // We might have run out of possible links to show + let numLinks = possibleLinks.size; + if (numLinks == 0) { + return undefined; + } + + let flattenedLinks = [...possibleLinks.values()]; + + // Choose our suggested link at random + let suggestedIndex = Math.floor(Math.random() * numLinks); + let chosenSuggestedLink = flattenedLinks[suggestedIndex]; + + // Add the suggested link to the front with some extra values + this._callObservers("onLinkChanged", Object.assign({ + frecency: SUGGESTED_FRECENCY, + + // Choose the first site a user has visited as the target. In the future, + // this should be the site with the highest frecency. However, we currently + // store frecency by URL not by site. + targetedSite: targetedSites.get(chosenSuggestedLink.url).length ? + targetedSites.get(chosenSuggestedLink.url)[0] : null + }, chosenSuggestedLink)); + return chosenSuggestedLink; + }, + + /** + * Loads inadjacent sites + * @return a promise resolved when lookup Set for sites is built + */ + _loadInadjacentSites: function DirectoryLinksProvider_loadInadjacentSites() { + return this._downloadJsonData(this._inadjacentSitesUrl).then(jsonString => { + let jsonObject = {}; + try { + jsonObject = JSON.parse(jsonString); + } + catch (e) { + Cu.reportError(e); + } + + this._inadjacentSites = new Set(jsonObject.domains); + }); + }, + + /** + * Genegrates hash suitable for looking up inadjacent site + * @param value to hsh + * @return hased value, base64-ed + */ + _generateHash: function DirectoryLinksProvider_generateHash(value) { + let byteArr = gUnicodeConverter.convertToByteArray(value); + gCryptoHash.init(gCryptoHash.MD5); + gCryptoHash.update(byteArr, byteArr.length); + return gCryptoHash.finish(true); + }, + + /** + * Checks if link belongs to inadjacent domain + * @param link to check + * @return true for inadjacent domains, false otherwise + */ + _isInadjacentLink: function DirectoryLinksProvider_isInadjacentLink(link) { + let baseDomain = link.baseDomain || NewTabUtils.extractSite(link.url || ""); + if (!baseDomain) { + return false; + } + // check if hashed domain is inadjacent + return this._inadjacentSites.has(this._generateHash(baseDomain)); + }, + + /** + * Checks if new tab has inadjacent site + * @param new tab links (or nothing, in which case NewTabUtils.links.getLinks() is called + * @return true if new tab shows has inadjacent site + */ + _checkForInadjacentSites: function DirectoryLinksProvider_checkForInadjacentSites(newTabLink) { + let links = newTabLink || NewTabUtils.links.getLinks(); + for (let link of links.slice(0, MAX_VISIBLE_HISTORY_TILES)) { + // check links against inadjacent list - specifically include ALL link types + if (this._isInadjacentLink(link)) { + return true; + } + } + return false; + }, + + /** + * Reads json file, parses its content, and returns resulting object + * @param json file path + * @param json object to return in case file read or parse fails + * @return a promise resolved to a valid object or undefined upon error + */ + _readJsonFile: Task.async(function* (filePath, nullObject) { + let jsonObj; + try { + let binaryData = yield OS.File.read(filePath); + let json = gTextDecoder.decode(binaryData); + jsonObj = JSON.parse(json); + } + catch (e) {} + return jsonObj || nullObject; + }), + + /** + * Loads frequency cap object from file and parses its content + * @return a promise resolved upon load completion + * on error or non-exstent file _frequencyCaps is set to empty object + */ + _readFrequencyCapFile: Task.async(function* () { + // set _frequencyCaps object to file's content or empty object + this._frequencyCaps = yield this._readJsonFile(this._frequencyCapFilePath, {}); + }), + + /** + * Saves frequency cap object to file + * @return a promise resolved upon file i/o completion + */ + _writeFrequencyCapFile: function DirectoryLinksProvider_writeFrequencyCapFile() { + let json = JSON.stringify(this._frequencyCaps || {}); + return OS.File.writeAtomic(this._frequencyCapFilePath, json, {tmpPath: this._frequencyCapFilePath + ".tmp"}); + }, + + /** + * Clears frequency cap object and writes empty json to file + * @return a promise resolved upon file i/o completion + */ + _clearFrequencyCap: function DirectoryLinksProvider_clearFrequencyCap() { + this._frequencyCaps = {}; + return this._writeFrequencyCapFile(); + }, + + /** + * updates frequency cap configuration for a link + */ + _updateFrequencyCapSettings: function DirectoryLinksProvider_updateFrequencyCapSettings(link) { + let capsObject = this._frequencyCaps[link.url]; + if (!capsObject) { + // create an object with empty counts + capsObject = { + dailyViews: 0, + totalViews: 0, + lastShownDate: 0, + }; + this._frequencyCaps[link.url] = capsObject; + } + // set last updated timestamp + capsObject.lastUpdated = Date.now(); + // check for link configuration + if (link.frequency_caps) { + capsObject.dailyCap = link.frequency_caps.daily || DEFAULT_DAILY_FREQUENCY_CAP; + capsObject.totalCap = link.frequency_caps.total || DEFAULT_TOTAL_FREQUENCY_CAP; + } + else { + // fallback to defaults + capsObject.dailyCap = DEFAULT_DAILY_FREQUENCY_CAP; + capsObject.totalCap = DEFAULT_TOTAL_FREQUENCY_CAP; + } + }, + + /** + * Prunes frequency cap objects for outdated links + * @param timeDetla milliseconds + * all cap objects with lastUpdated less than (now() - timeDelta) + * will be removed. This is done to remove frequency cap objects + * for unused tile urls + */ + _pruneFrequencyCapUrls: function DirectoryLinksProvider_pruneFrequencyCapUrls(timeDelta = DEFAULT_PRUNE_TIME_DELTA) { + let timeThreshold = Date.now() - timeDelta; + Object.keys(this._frequencyCaps).forEach(url => { + // remove url if it is not ignorable and wasn't updated for a while + if (!url.startsWith("ignore") && this._frequencyCaps[url].lastUpdated <= timeThreshold) { + delete this._frequencyCaps[url]; + } + }); + }, + + /** + * Checks if supplied timestamp happened today + * @param timestamp in milliseconds + * @return true if the timestamp was made today, false otherwise + */ + _wasToday: function DirectoryLinksProvider_wasToday(timestamp) { + let showOn = new Date(timestamp); + let today = new Date(); + // call timestamps identical if both day and month are same + return showOn.getDate() == today.getDate() && + showOn.getMonth() == today.getMonth() && + showOn.getYear() == today.getYear(); + }, + + /** + * adds some number of views for a url + * @param url String url of the suggested link + */ + _addFrequencyCapView: function DirectoryLinksProvider_addFrequencyCapView(url) { + let capObject = this._frequencyCaps[url]; + // sanity check + if (!capObject) { + return; + } + + // if the day is new: reset the daily counter and lastShownDate + if (!this._wasToday(capObject.lastShownDate)) { + capObject.dailyViews = 0; + // update lastShownDate + capObject.lastShownDate = Date.now(); + } + + // bump both daily and total counters + capObject.totalViews++; + capObject.dailyViews++; + + // if any of the caps is reached - update suggested tiles + if (capObject.totalViews >= capObject.totalCap || + capObject.dailyViews >= capObject.dailyCap) { + this._updateSuggestedTile(); + } + }, + + /** + * Sets clicked flag for link url + * @param url String url of the suggested link + */ + _setFrequencyCapClick(url) { + let capObject = this._frequencyCaps[url]; + // sanity check + if (!capObject) { + return; + } + capObject.clicked = true; + // and update suggested tiles, since current tile became invalid + this._updateSuggestedTile(); + }, + + /** + * Tests frequency cap limits for link url + * @param url String url of the suggested link + * @return true if link is viewable, false otherwise + */ + _testFrequencyCapLimits: function DirectoryLinksProvider_testFrequencyCapLimits(url) { + let capObject = this._frequencyCaps[url]; + // sanity check: if url is missing - do not show this tile + if (!capObject) { + return false; + } + + // check for clicked set or total views reached + if (capObject.clicked || capObject.totalViews >= capObject.totalCap) { + return false; + } + + // otherwise check if link is over daily views limit + if (this._wasToday(capObject.lastShownDate) && + capObject.dailyViews >= capObject.dailyCap) { + return false; + } + + // we passed all cap tests: return true + return true; + }, + + /** + * Removes clicked flag from frequency cap entry for tile landing url + * @param url String url of the suggested link + * @return promise resolved upon disk write completion + */ + _removeTileClick: function DirectoryLinksProvider_removeTileClick(url = "") { + // remove trailing slash, to accomodate Places sending site urls ending with '/' + let noTrailingSlashUrl = url.replace(/\/$/, ""); + let capObject = this._frequencyCaps[url] || this._frequencyCaps[noTrailingSlashUrl]; + // return resolved promise if capObject is not found + if (!capObject) { + return Promise.resolve(); + } + // otherwise remove clicked flag + delete capObject.clicked; + return this._writeFrequencyCapFile(); + }, + + /** + * Removes all clicked flags from frequency cap object + * @return promise resolved upon disk write completion + */ + _removeAllTileClicks: function DirectoryLinksProvider_removeAllTileClicks() { + Object.keys(this._frequencyCaps).forEach(url => { + delete this._frequencyCaps[url].clicked; + }); + return this._writeFrequencyCapFile(); + }, + + /** + * Return the object to its pre-init state + */ + reset: function DirectoryLinksProvider_reset() { + delete this.__linksURL; + this._removePrefsObserver(); + this._removeObservers(); + }, + + addObserver: function DirectoryLinksProvider_addObserver(aObserver) { + this._observers.add(aObserver); + }, + + removeObserver: function DirectoryLinksProvider_removeObserver(aObserver) { + this._observers.delete(aObserver); + }, + + _callObservers(methodName, ...args) { + for (let obs of this._observers) { + if (typeof(obs[methodName]) == "function") { + try { + obs[methodName](this, ...args); + } catch (err) { + Cu.reportError(err); + } + } + } + }, + + _removeObservers: function() { + this._observers.clear(); + } +}; diff --git a/application/basilisk/modules/moz.build b/application/basilisk/modules/moz.build index cd8f2ce62..d043d4799 100644 --- a/application/basilisk/modules/moz.build +++ b/application/basilisk/modules/moz.build @@ -16,6 +16,7 @@ EXTRA_JS_MODULES += [ 'ContentObservers.jsm', 'ContentSearch.jsm', 'ContentWebRTC.jsm', + 'DirectoryLinksProvider.jsm', 'E10SUtils.jsm', 'Feeds.jsm', 'FormSubmitObserver.jsm', diff --git a/application/palemoon/base/content/newtab/grid.js b/application/palemoon/base/content/newtab/grid.js index be5a57c4b..db3d319c3 100644 --- a/application/palemoon/base/content/newtab/grid.js +++ b/application/palemoon/base/content/newtab/grid.js @@ -5,12 +5,6 @@ #endif /** - * Define various fixed dimensions - */ -const GRID_BOTTOM_EXTRA = 7; // title's line-height extends 7px past the margin -const GRID_WIDTH_EXTRA = 1; // provide 1px buffer to allow for rounding error - -/** * This singleton represents the grid that contains all sites. */ var gGrid = { @@ -35,7 +29,14 @@ var gGrid = { /** * All sites contained in the grid's cells. Sites may be empty. */ - get sites() { return [for (cell of this.cells) cell.site]; }, + get sites() { + // return [for (cell of this.cells) cell.site]; + let aSites = []; + for (let cell of this.cells) { + aSites.push(cell.site); + } + return aSites; + }, // Tells whether the grid has already been initialized. get ready() { return !!this._ready; }, @@ -55,20 +56,7 @@ var gGrid = { gLinks.populateCache(() => { this._refreshGrid(); this._ready = true; - - // If fetching links took longer than loading the page itself then - // we need to resize the grid as that was blocked until now. - // We also want to resize now if the page was already loaded when - // initializing the grid (the user toggled the page). - this._resizeGrid(); - - addEventListener("resize", this); }); - - // Resize the grid as soon as the page loads. - if (!this.isDocumentLoaded) { - addEventListener("load", this); - } }, /** @@ -87,12 +75,7 @@ var gGrid = { * Handles all grid events. */ handleEvent: function Grid_handleEvent(aEvent) { - switch (aEvent.type) { - case "load": - case "resize": - this._resizeGrid(); - break; - } + // Any specific events should go here. }, /** @@ -110,31 +93,37 @@ var gGrid = { }, /** - * Renders and resizes the gird. _resizeGrid() call is needed to ensure - * that scrollbar disappears when the bottom row becomes empty following - * the block action, or tile display is turmed off via cog menu + * Renders the grid. */ - refresh() { this._refreshGrid(); - this._resizeGrid(); }, /** * Renders the grid, including cells and sites. */ _refreshGrid() { + let row = document.createElementNS(HTML_NAMESPACE, "div"); + row.classList.add("newtab-row"); let cell = document.createElementNS(HTML_NAMESPACE, "div"); cell.classList.add("newtab-cell"); - // Creates all the cells up to the maximum - let fragment = document.createDocumentFragment(); - for (let i = 0; i < gGridPrefs.gridColumns * gGridPrefs.gridRows; i++) { - fragment.appendChild(cell.cloneNode(true)); + // Clear the grid + this._node.innerHTML = ""; + + // Creates the structure of one row + for (let i = 0; i < gGridPrefs.gridColumns; i++) { + row.appendChild(cell.cloneNode(true)); } - // Create cells. - let cells = Array.from(fragment.childNodes, (cell) => new Cell(this, cell)); + // Creates the grid + for (let j = 0; j < gGridPrefs.gridRows; j++) { + this._node.appendChild(row.cloneNode(true)); + } + + // Create cell array. + let cellElements = this.node.querySelectorAll(".newtab-cell"); + let cells = Array.from(cellElements, (cell) => new Cell(this, cell)); // Fetch links. let links = gLinks.getLinks(); @@ -152,20 +141,6 @@ var gGrid = { } this._cells = cells; - while (this._gridDefaultContent.nextSibling) { - this._gridDefaultContent.nextSibling.remove(); - } - this._node.appendChild(fragment); - }, - - /** - * Calculate the height for a number of rows up to the maximum rows - * @param rows Number of rows defaulting to the max - */ - _computeHeight: function Grid_computeHeight(aRows) { - let {gridRows} = gGridPrefs; - aRows = aRows === undefined ? gridRows : Math.min(gridRows, aRows); - return aRows * this._cellHeight + GRID_BOTTOM_EXTRA; }, /** @@ -199,74 +174,6 @@ var gGrid = { _isHistoricalTile: function Grid_isHistoricalTile(aPos) { let site = this.sites[aPos]; return site && (site.isPinned() || site.link && site.link.type == "history"); - }, - - /** - * Make sure the correct number of rows and columns are visible - */ - _resizeGrid: function Grid_resizeGrid() { - // If we're somehow called before the page has finished loading, - // let's bail out to avoid caching zero heights and widths. - // We'll be called again when DOMContentLoaded fires. - // Same goes for the grid if that's not ready yet. - if (!this.isDocumentLoaded || !this._ready) { - return; - } - - // Save the cell's computed height/width including margin and border - if (this._cellHeight === undefined) { - let refCell = document.querySelector(".newtab-cell"); - let style = getComputedStyle(refCell); - this._cellHeight = refCell.offsetHeight + - parseFloat(style.marginTop) + parseFloat(style.marginBottom); - this._cellWidth = refCell.offsetWidth + - parseFloat(style.marginLeft) + parseFloat(style.marginRight); - } - - let searchContainer = document.querySelector("#searchContainer"); - // Save search-container margin height - if (this._searchContainerMargin === undefined) { - let style = getComputedStyle(searchContainer); - this._searchContainerMargin = parseFloat(style.marginBottom) + - parseFloat(style.marginTop); - } - - // Find the number of rows we can place into view port - let availHeight = document.documentElement.clientHeight - - searchContainer.offsetHeight - this._searchContainerMargin; - let visibleRows = Math.floor(availHeight / this._cellHeight); - - // Find the number of columns that fit into view port - let maxGridWidth = gGridPrefs.gridColumns * this._cellWidth + GRID_WIDTH_EXTRA; - // available width is current grid width, but no greater than maxGridWidth - let availWidth = Math.min(document.querySelector("#newtab-grid").clientWidth, - maxGridWidth); - // finally get the number of columns we can fit into view port - let gridColumns = Math.floor(availWidth / this._cellWidth); - // walk sites backwords until a pinned or history tile is found or visibleRows reached - let tileIndex = Math.min(gGridPrefs.gridRows * gridColumns, this.sites.length) - 1; - while (tileIndex >= visibleRows * gridColumns) { - if (this._isHistoricalTile(tileIndex)) { - break; - } - tileIndex--; - } - - // Compute the actual number of grid rows we will display (potentially - // with a scroll bar). tileIndex now points to a historical tile with - // heighest index or to the last index of the visible row, if none found - // Dividing tileIndex by number of tiles in a column gives the rows - let gridRows = Math.floor(tileIndex / gridColumns) + 1; - - // we need to set grid width, for otherwise the scrollbar may shrink - // the grid when shown and cause grid layout to be different from - // what being computed above. This, in turn, may cause scrollbar shown - // for directory tiles, and introduce jitter when grid width is aligned - // exactly on the column boundary - this._node.style.width = gridColumns * this._cellWidth + "px"; - this._node.style.maxWidth = gGridPrefs.gridColumns * this._cellWidth + - GRID_WIDTH_EXTRA + "px"; - this._node.style.height = this._computeHeight() + "px"; - this._node.style.maxHeight = this._computeHeight(gridRows) + "px"; } + }; diff --git a/application/palemoon/base/content/newtab/newTab.css b/application/palemoon/base/content/newtab/newTab.css index a5431cf65..fe745d2fd 100644 --- a/application/palemoon/base/content/newtab/newTab.css +++ b/application/palemoon/base/content/newtab/newTab.css @@ -42,6 +42,18 @@ input[type=button] { pointer-events: none; } +/* TOGGLE */ +#newtab-toggle { + position: absolute; + top: 12px; + right: 12px; +} + +#newtab-toggle:-moz-locale-dir(rtl) { + left: 12px; + right: auto; +} + /* MARGINS */ #newtab-vertical-margin { display: -moz-box; @@ -69,33 +81,38 @@ input[type=button] { #newtab-horizontal-margin { display: -moz-box; - -moz-box-flex: 1; -} - -#newtab-margin-top, -#newtab-margin-bottom { - display: -moz-box; - position: relative; + -moz-box-flex: 5; } #newtab-margin-top { + min-height: 10px; + max-height: 30px; + display: -moz-box; -moz-box-flex: 1; + -moz-box-align: center; + -moz-box-pack: center; } #newtab-margin-bottom { - -moz-box-flex: 2; + min-height: 40px; + max-height: 80px; + -moz-box-flex: 1; } .newtab-side-margin { - min-width: 10px; + min-width: 40px; + max-width: 300px; -moz-box-flex: 1; } /* GRID */ #newtab-grid { + display: -moz-box; -moz-box-flex: 5; - overflow: hidden; - transition: 300ms ease-out; + -moz-box-orient: vertical; + min-width: 600px; + min-height: 400px; + transition: 175ms ease-out; transition-property: opacity; } @@ -108,25 +125,30 @@ input[type=button] { pointer-events: none; } +/* ROWS */ +.newtab-row { + display: -moz-box; + -moz-box-orient: horizontal; + -moz-box-direction: normal; + -moz-box-flex: 1; +} + /* - * If you change the sizes here, make sure you - * change the preferences: + * Thumbnail image sizes are determined in the preferences: * toolkit.pageThumbs.minWidth * toolkit.pageThumbs.minHeight */ /* CELLS */ .newtab-cell { display: -moz-box; - height: 180px; - margin: 15px 10px 30px; - width: 250px; + -moz-box-flex: 1; } /* SITES */ .newtab-site { position: relative; -moz-box-flex: 1; - transition: 200ms ease-out; + transition: 150ms ease-out; transition-property: top, left, opacity; } @@ -211,7 +233,7 @@ input[type=button] { display: -moz-box; position: relative; -moz-box-pack: center; - margin: 40px 0 15px; + margin: 10px 0 15px; } #searchContainer[page-disabled] { diff --git a/application/palemoon/base/content/newtab/newTab.xhtml b/application/palemoon/base/content/newtab/newTab.xhtml index eac62c987..de000e723 100644 --- a/application/palemoon/base/content/newtab/newTab.xhtml +++ b/application/palemoon/base/content/newtab/newTab.xhtml @@ -54,6 +54,7 @@ </div> <div id="newtab-margin-bottom"/> + <input id="newtab-toggle" type="button"/> </div> </body> <script type="text/javascript;version=1.8" src="chrome://browser/content/newtab/newTab.js"/> diff --git a/application/palemoon/base/content/newtab/page.js b/application/palemoon/base/content/newtab/page.js index cbd6750b6..7117d4527 100644 --- a/application/palemoon/base/content/newtab/page.js +++ b/application/palemoon/base/content/newtab/page.js @@ -21,6 +21,10 @@ var gPage = { // Listen for 'unload' to unregister this page. addEventListener("unload", this, false); + + // Listen for toggle button clicks. + let button = document.getElementById("newtab-toggle"); + button.addEventListener("click", e => this.toggleEnabled(e)); // XXX bug 991111 - Not all click events are correctly triggered when // listening from xhtml nodes -- in particular middle clicks on sites, so @@ -277,6 +281,11 @@ var gPage = { } }, + toggleEnabled: function(aEvent) { + gAllPages.enabled = !gAllPages.enabled; + event.stopPropagation(); + }, + maybeShowAutoMigrationUndoNotification() { // sendAsyncMessage("NewTab:MaybeShowAutoMigrationUndoNotification"); }, diff --git a/application/palemoon/base/content/palemoon.xhtml b/application/palemoon/base/content/palemoon.xhtml new file mode 100644 index 000000000..96757052c --- /dev/null +++ b/application/palemoon/base/content/palemoon.xhtml @@ -0,0 +1,66 @@ +<!DOCTYPE html +[ + <!ENTITY % mozillaDTD SYSTEM "chrome://browser/locale/palemoon.dtd" > + %mozillaDTD; + <!ENTITY % directionDTD SYSTEM "chrome://global/locale/global.dtd" > + %directionDTD; +]> + +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta charset='utf-8' /> + <title>&chronicles.title.55.2;</title> + +<style type="text/css"> +html { + background: #333399 radial-gradient( circle at 75% 25%, #6666b0 0%, #333399 40%, #111177 80%) center center / cover no-repeat; + color: white; + font-style: italic; + text-rendering: optimizeLegibility; + min-height: 100%; +} + +#moztext { + margin-top: 15%; + font-size: 1.1em; + font-family: serif; + text-align: center; + line-height: 1.5; +} + +#from { + font-size: 1.95em; + font-family: serif; + text-align: right; +} + +em { + font-size: 1.3em; + line-height: 0; +} + +a { + text-decoration: none; + color: white; +} +</style> +</head> + +<body dir="&locale.dir;"> + +<section> + <p id="moztext"> + &chronicles.quote.55.2; + </p> + + <p id="from"> + &chronicles.from.55.2; + </p> +</section> + +</body> +</html> diff --git a/application/palemoon/base/content/sanitize.js b/application/palemoon/base/content/sanitize.js index 74372a4af..0c85fa215 100644 --- a/application/palemoon/base/content/sanitize.js +++ b/application/palemoon/base/content/sanitize.js @@ -11,7 +11,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "FormHistory", XPCOMUtils.defineLazyModuleGetter(this, "Downloads", "resource://gre/modules/Downloads.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Promise", - "resource:///modules/promise.js"); + "resource://gre/modules/Promise.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "console", diff --git a/application/palemoon/base/content/utilityOverlay.js b/application/palemoon/base/content/utilityOverlay.js index c45297e0b..63488e209 100644 --- a/application/palemoon/base/content/utilityOverlay.js +++ b/application/palemoon/base/content/utilityOverlay.js @@ -250,6 +250,10 @@ function openLinkIn(url, where, params) { aRelatedToCurrent = false; } + // We can only do this after we're sure of what |w| will be the rest of this function. + // Note that if |w| is null we might have no current browser (we'll open a new window). + var aCurrentBrowser = params.currentBrowser || (w && w.gBrowser.selectedBrowser); + if (!w || where == "window") { // This propagates to window.arguments. // Strip referrer data when opening a new private window, to prevent diff --git a/application/palemoon/base/jar.mn b/application/palemoon/base/jar.mn index 246cf9017..d8c3f4b21 100644 --- a/application/palemoon/base/jar.mn +++ b/application/palemoon/base/jar.mn @@ -69,6 +69,7 @@ browser.jar: content/browser/padlock_classic_https.png (content/padlock_classic_https.png) content/browser/padlock_classic_low.png (content/padlock_classic_low.png) content/browser/padlock_classic_broken.png (content/padlock_classic_broken.png) + content/browser/palemoon.xhtml (content/palemoon.xhtml) content/browser/newtab/newTab.xhtml (content/newtab/newTab.xhtml) * content/browser/newtab/newTab.js (content/newtab/newTab.js) content/browser/newtab/newTab.css (content/newtab/newTab.css) diff --git a/application/palemoon/components/about/AboutRedirector.cpp b/application/palemoon/components/about/AboutRedirector.cpp index 7e4c634f7..508202c7d 100644 --- a/application/palemoon/components/about/AboutRedirector.cpp +++ b/application/palemoon/components/about/AboutRedirector.cpp @@ -57,7 +57,7 @@ static RedirEntry kRedirMap[] = { nsIAboutModule::ALLOW_SCRIPT }, { - "palemoon", "chrome://global/content/memoriam.xhtml", + "palemoon", "chrome://browser/content/palemoon.xhtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::HIDE_FROM_ABOUTABOUT }, diff --git a/application/palemoon/config/version.txt b/application/palemoon/config/version.txt index 87265bad0..d292f6343 100644 --- a/application/palemoon/config/version.txt +++ b/application/palemoon/config/version.txt @@ -1 +1 @@ -28.0.0b1
\ No newline at end of file +28.0.0b2
\ No newline at end of file diff --git a/application/palemoon/locales/Makefile.in b/application/palemoon/locales/Makefile.in index 5720a76df..c81329a9a 100644 --- a/application/palemoon/locales/Makefile.in +++ b/application/palemoon/locales/Makefile.in @@ -124,6 +124,9 @@ libs-%: @$(MAKE) -C ../../../services/sync/locales AB_CD=$* XPI_NAME=locale-$* @$(MAKE) -C ../../../extensions/spellcheck/locales AB_CD=$* XPI_NAME=locale-$* @$(MAKE) -C ../../../intl/locales AB_CD=$* XPI_NAME=locale-$* +ifdef MOZ_DEVTOOLS + @$(MAKE) -C ../../../devtools/client/locales AB_CD=$* XPI_NAME=locale-$* +endif @$(MAKE) libs AB_CD=$* XPI_NAME=locale-$* PREF_DIR=$(PREF_DIR) @$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales AB_CD=$* XPI_NAME=locale-$* diff --git a/application/palemoon/locales/en-US/chrome/browser/palemoon.dtd b/application/palemoon/locales/en-US/chrome/browser/palemoon.dtd new file mode 100644 index 000000000..038d8eb75 --- /dev/null +++ b/application/palemoon/locales/en-US/chrome/browser/palemoon.dtd @@ -0,0 +1,14 @@ +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + +<!ENTITY chronicles.title.55.2 +'The Chronicles of the Pale Moon, 55:2'> + +<!ENTITY chronicles.quote.55.2 +'And so, our focus was drawn through time and space to the <em>emerging dragon</em> who would not abandon hope.<br/> +Its resilience, stubbornness and spirit unbroken, and searching for long hours to find those willing to <em>join</em> its cause.<br/> +The old nest abandoned, the death throes of the Beast ignored, and more determined than ever to find glory in the future.'> + +<!ENTITY chronicles.from.55.2 +'from <strong>The Chronicles of the Pale Moon,</strong> 55:2'> diff --git a/application/palemoon/locales/en-US/chrome/overrides/netError.dtd b/application/palemoon/locales/en-US/chrome/overrides/netError.dtd index c97bd1b59..04bfe9925 100644 --- a/application/palemoon/locales/en-US/chrome/overrides/netError.dtd +++ b/application/palemoon/locales/en-US/chrome/overrides/netError.dtd @@ -226,16 +226,6 @@ functionality specific to firefox. --> <button id='exceptionDialogButton'>&securityOverride.exceptionButtonLabel;</button> "> -<!ENTITY errorReporting.title "Report this error"> -<!ENTITY errorReporting.longDesc "Reporting the address and certificate information for <span id='hostname'></span> will help us identify and block malicious sites. Thanks for helping create a safer web!"> -<!ENTITY errorReporting.automatic "Automatically report errors in the future"> -<!ENTITY errorReporting.automatic2 "Report errors like this to help Mozilla identify and block malicious sites"> -<!ENTITY errorReporting.learnMore "Learn moreā¦"> -<!ENTITY errorReporting.sending "Sending report"> -<!ENTITY errorReporting.sent "Report sent"> -<!ENTITY errorReporting.report "Report"> -<!ENTITY errorReporting.tryAgain "Try again"> - <!ENTITY remoteXUL.title "Remote XUL"> <!ENTITY remoteXUL.longDesc "<p><ul><li>Please contact the website owners to inform them of this problem.</li></ul></p>"> diff --git a/application/palemoon/locales/jar.mn b/application/palemoon/locales/jar.mn index 046cb0ac7..8d88e16fd 100644 --- a/application/palemoon/locales/jar.mn +++ b/application/palemoon/locales/jar.mn @@ -28,6 +28,7 @@ locale/browser/openLocation.properties (%chrome/browser/openLocation.properties) locale/browser/pageInfo.dtd (%chrome/browser/pageInfo.dtd) locale/browser/pageInfo.properties (%chrome/browser/pageInfo.properties) + locale/browser/palemoon.dtd (%chrome/browser/palemoon.dtd) locale/browser/quitDialog.properties (%chrome/browser/quitDialog.properties) locale/browser/safeMode.dtd (%chrome/browser/safeMode.dtd) locale/browser/sanitize.dtd (%chrome/browser/sanitize.dtd) diff --git a/application/palemoon/modules/moz.build b/application/palemoon/modules/moz.build index 67fd22338..8032930b2 100644 --- a/application/palemoon/modules/moz.build +++ b/application/palemoon/modules/moz.build @@ -5,9 +5,6 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. -# XXX: Include this until we convert browser/ to use toolkit promises directly -EXTRA_JS_MODULES += [ 'promise.js' ] - EXTRA_JS_MODULES += [ 'AutoCompletePopup.jsm', 'BrowserNewTabPreloader.jsm', diff --git a/application/palemoon/modules/promise.js b/application/palemoon/modules/promise.js deleted file mode 100644 index 74065c8db..000000000 --- a/application/palemoon/modules/promise.js +++ /dev/null @@ -1,118 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -'use strict'; - -/* - * Uses `Promise.jsm` as a core implementation, with additional sugar - * from previous implementation, with inspiration from `Q` and `when` - * - * https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm - * https://github.com/cujojs/when - * https://github.com/kriskowal/q - */ -const PROMISE_URI = 'resource://gre/modules/Promise.jsm'; - -getEnvironment.call(this, function ({ require, exports, module, Cu }) { - -const Promise = Cu.import(PROMISE_URI, {}).Promise; -const { Debugging, defer, resolve, all, reject, race } = Promise; - -module.metadata = { - 'stability': 'unstable' -}; - -var promised = (function() { - // Note: Define shortcuts and utility functions here in order to avoid - // slower property accesses and unnecessary closure creations on each - // call of this popular function. - - var call = Function.call; - var concat = Array.prototype.concat; - - // Utility function that does following: - // execute([ f, self, args...]) => f.apply(self, args) - function execute (args) call.apply(call, args) - - // Utility function that takes promise of `a` array and maybe promise `b` - // as arguments and returns promise for `a.concat(b)`. - function promisedConcat(promises, unknown) { - return promises.then(function (values) { - return resolve(unknown) - .then(function (value) values.concat([value])); - }); - } - - return function promised(f, prototype) { - /** - Returns a wrapped `f`, which when called returns a promise that resolves to - `f(...)` passing all the given arguments to it, which by the way may be - promises. Optionally second `prototype` argument may be provided to be used - a prototype for a returned promise. - - ## Example - - var promise = promised(Array)(1, promise(2), promise(3)) - promise.then(console.log) // => [ 1, 2, 3 ] - **/ - - return function promised(...args) { - // create array of [ f, this, args... ] - return [f, this, ...args]. - // reduce it via `promisedConcat` to get promised array of fulfillments - reduce(promisedConcat, resolve([], prototype)). - // finally map that to promise of `f.apply(this, args...)` - then(execute); - }; - }; -})(); - -exports.promised = promised; -exports.all = all; -exports.defer = defer; -exports.resolve = resolve; -exports.reject = reject; -exports.race = race; -exports.Promise = Promise; -exports.Debugging = Debugging; -}); - -function getEnvironment (callback) { - let Cu, _exports, _module, _require; - - // CommonJS / SDK - if (typeof(require) === 'function') { - Cu = require('chrome').Cu; - _exports = exports; - _module = module; - _require = require; - } - // JSM - else if (String(this).indexOf('BackstagePass') >= 0) { - Cu = this['Components'].utils; - _exports = this.Promise = {}; - _module = { uri: __URI__, id: 'promise/core' }; - _require = uri => { - let imports = {}; - Cu.import(uri, imports); - return imports; - }; - this.EXPORTED_SYMBOLS = ['Promise']; - // mozIJSSubScriptLoader.loadSubscript - } else if (~String(this).indexOf('Sandbox')) { - Cu = this['Components'].utils; - _exports = this; - _module = { id: 'promise/core' }; - _require = uri => {}; - } - - callback({ - Cu: Cu, - exports: _exports, - module: _module, - require: _require - }); -} - diff --git a/application/palemoon/themes/linux/browser.css b/application/palemoon/themes/linux/browser.css index 9a08ea4d8..7d353685d 100644 --- a/application/palemoon/themes/linux/browser.css +++ b/application/palemoon/themes/linux/browser.css @@ -1571,6 +1571,12 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action- background-color: Window; } +.browserContainer > findbar { + background-color: -moz-dialog; + color: -moz-DialogText; + text-shadow: none; +} + /* Throbber */ #navigator-throbber { width: 16px; diff --git a/application/palemoon/themes/osx/browser.css b/application/palemoon/themes/osx/browser.css index 485ed9115..a8e86ff5c 100644 --- a/application/palemoon/themes/osx/browser.css +++ b/application/palemoon/themes/osx/browser.css @@ -1348,6 +1348,12 @@ richlistitem[type~="action"][actiontype="switchtab"][selected="true"] > .ac-url- -moz-padding-start: 0px; } +.browserContainer > findbar { + background-color: -moz-dialog; + color: -moz-DialogText; + text-shadow: none; +} + /* ::::: throbber ::::: */ #navigator-throbber { diff --git a/application/palemoon/themes/shared/newtab/newTab.css.inc b/application/palemoon/themes/shared/newtab/newTab.css.inc index 4ffd32d50..3341ba7e5 100644 --- a/application/palemoon/themes/shared/newtab/newTab.css.inc +++ b/application/palemoon/themes/shared/newtab/newTab.css.inc @@ -105,7 +105,7 @@ body { .newtab-site:hover, .newtab-site[dragged] { - box-shadow: 0 3px 10px rgba(8,20,37,.6); + box-shadow: 0 3px 6px 1px rgba(8,20,37,.6); } .newtab-site[dragged] { diff --git a/application/palemoon/themes/windows/browser.css b/application/palemoon/themes/windows/browser.css index 099382a5a..5c044fdd4 100644 --- a/application/palemoon/themes/windows/browser.css +++ b/application/palemoon/themes/windows/browser.css @@ -1788,6 +1788,12 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action- -moz-padding-start: 0px; } +.browserContainer > findbar { + background-color: -moz-dialog; + color: -moz-DialogText; + text-shadow: none; +} + /* ::::: throbber ::::: */ #navigator-throbber { @@ -3416,7 +3422,13 @@ toolbar[brighttext] #addonbar-closebutton { border-radius: var(--toolbarbutton-border-radius); color: black; } - + + :-moz-any(#toolbar-menubar, #TabsToolbar[tabsontop=true], #nav-bar[tabsontop=false]) .toolbarbutton-1 > .toolbarbutton-menu-dropmarker:not(:-moz-lwtheme), + :-moz-any(#toolbar-menubar, #TabsToolbar[tabsontop=true], #nav-bar[tabsontop=false]) .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:not(:-moz-lwtheme), + #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child .toolbarbutton-1 > .toolbarbutton-menu-dropmarker:not(:-moz-lwtheme), + #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:not(:-moz-lwtheme) { + list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow-inverted.png"); + } } /* ==== Windows 8/10 (flat color) styling ==== */ @@ -3454,6 +3466,10 @@ toolbar[brighttext] #addonbar-closebutton { border-right-style: none !important; } + #main-menubar > menu:not(:-moz-lwtheme) { + color: inherit; + } + :-moz-any(#toolbar-menubar, #nav-bar[tabsontop=false]) :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme), :-moz-any(#toolbar-menubar, #nav-bar[tabsontop=false]) :-moz-any(@primaryToolbarButtons@) > toolbarbutton > .toolbarbutton-icon:not(:-moz-lwtheme), #TabsToolbar[tabsontop=true] :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#new-tab-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme), @@ -3462,13 +3478,6 @@ toolbar[brighttext] #addonbar-closebutton { #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child :-moz-any(@primaryToolbarButtons@) > toolbarbutton > .toolbarbutton-icon:not(:-moz-lwtheme) { list-style-image: var(--toolbarbutton-glass-image); } - - :-moz-any(#toolbar-menubar, #TabsToolbar[tabsontop=true], #nav-bar[tabsontop=false]) .toolbarbutton-1 > .toolbarbutton-menu-dropmarker:not(:-moz-lwtheme), - :-moz-any(#toolbar-menubar, #TabsToolbar[tabsontop=true], #nav-bar[tabsontop=false]) .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:not(:-moz-lwtheme), - #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child .toolbarbutton-1 > .toolbarbutton-menu-dropmarker:not(:-moz-lwtheme), - #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:not(:-moz-lwtheme) { - list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow-inverted.png"); - } /* Show toolbar borders on vista through win8, but not on win10 and later: */ @media (-moz-os-version: windows-vista), |