MTurbo - Version 1.1.0

Version Notes

Visit product homepage at:
http://www.artio.net/magento-extensions/m-turbo-accelerator

Download this release

Release Info

Developer Magento Core Team
Extension MTurbo
Version 1.1.0
Comparing to
See all releases


Code changes from version 1.0 to 1.1.0

app/code/local/Artio/MTurbo/Block/Adminhtml/Edit/Tab/Actions.php CHANGED
@@ -87,6 +87,14 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Actions extends Artio_MTurbo_Block_A
87
  'comment' => $this->getMyHelper()->__('Create cache for all pages (except blocked pages). Download progress can be monitored in a separate window. Please, do not close this window. Update of URLs from the Rewrite Table will be started automatically before caching is executed. Please, note that initial cache creation may take a long time (several hours). Time needed depends on the number of pages your site has.')
88
 
89
  ));
 
 
 
 
 
 
 
 
90
 
91
  }
92
 
87
  'comment' => $this->getMyHelper()->__('Create cache for all pages (except blocked pages). Download progress can be monitored in a separate window. Please, do not close this window. Update of URLs from the Rewrite Table will be started automatically before caching is executed. Please, note that initial cache creation may take a long time (several hours). Time needed depends on the number of pages your site has.')
88
 
89
  ));
90
+
91
+ $layoutFieldset->addField('htaccess_button', 'widget_button', array(
92
+ 'name' => 'htaccess_button',
93
+ 'label' => $this->getMyHelper()->__('Rebuild .htaccess'),
94
+ 'onclick' => "setLocation('" . Mage::helper('adminhtml')->getUrl('*/*/htaccessbuild') . "')",
95
+ 'comment' => $this->getMyHelper()->__('Rebuild .htaccess file. First remove MTurbo section and then insert it. At the same time check .htaccess file in turbocache folder'),
96
+
97
+ ));
98
 
99
  }
100
 
app/code/local/Artio/MTurbo/Block/Adminhtml/Edit/Tab/Main.php CHANGED
@@ -44,7 +44,8 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Main extends Artio_MTurbo_Block_Admi
44
  $this->form = new Varien_Data_Form();
45
  $this->_addGeneralFieldset();
46
  $this->_addHomepageFieldset();
47
- //$this->_addAutomaticDownloadFieldset();
 
48
 
49
  $this->form->setValues($config->getData());
50
  $this->setForm($this->form);
@@ -108,7 +109,7 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Main extends Artio_MTurbo_Block_Admi
108
 
109
  $layoutFieldset->addField('lastdownload', 'label', array(
110
  'name' => 'lastdownload',
111
- 'label' => $this->getMyHelper()->__('Last downlaod').':',
112
  'style' => 'height:24em;',
113
  'disabled' => true
114
  ));
@@ -135,4 +136,36 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Main extends Artio_MTurbo_Block_Admi
135
 
136
  }
137
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
  }
44
  $this->form = new Varien_Data_Form();
45
  $this->_addGeneralFieldset();
46
  $this->_addHomepageFieldset();
47
+ //$this->_addAutomaticDownloadFieldset(); DEMO VERSION
48
+ $this->_addDownloadMethodFieldset();
49
 
50
  $this->form->setValues($config->getData());
51
  $this->setForm($this->form);
109
 
110
  $layoutFieldset->addField('lastdownload', 'label', array(
111
  'name' => 'lastdownload',
112
+ 'label' => $this->getMyHelper()->__('Last download').':',
113
  'style' => 'height:24em;',
114
  'disabled' => true
115
  ));
136
 
137
  }
138
 
139
+ private function _addDownloadMethodFieldset() {
140
+
141
+ $layoutFieldset = $this->form->addFieldset('downloadmethod_fieldset', array(
142
+ 'legend' => $this->getMyHelper()->__('Choice download method'),
143
+ 'class' => 'fieldset'
144
+ ));
145
+
146
+ $layoutFieldset->addType('selectdmet', Artio_MTurbo_Helper_Data::FORM_SELECT_DOW);
147
+ $layoutFieldset->addField('downloadmethod', 'selectdmet', array(
148
+ 'name' => 'downloadmethod',
149
+ 'label' => $this->getMyHelper()->__('Download method').':',
150
+ 'options' => array(
151
+ DownloadMethods::FILE_GET_CONTENTS => $this->getMyHelper()->__('Use function "file_get_contents"'),
152
+ DownloadMethods::SOCKET => $this->getMyHelper()->__('Create connection over sockets'),
153
+ DownloadMethods::CURL => $this->getMyHelper()->__('Use CURL PHP extension'),
154
+ DownloadMethods::DIRECT_ACCESS => $this->getMyHelper()->__('Direct access (created new instance Magento)'))
155
+ ));
156
+
157
+ $label = Artio_MTurbo_Helper_Data::getConfig()->isPatched() ?
158
+ Mage::helper('mturbo')->__('Remove Mage Patch') :
159
+ Mage::helper('mturbo')->__('Apply Mage Patch');
160
+
161
+ $layoutFieldset->addType('widget_button', Artio_MTurbo_Helper_Data::FORM_WIDGET_BUTTON);
162
+ $layoutFieldset->addField('patch_button', 'widget_button', array(
163
+ 'name' => 'patch_button',
164
+ 'label' => $label,
165
+ 'onclick' => "setLocation('" . Mage::helper('adminhtml')->getUrl('*/*/magepatch') . "')",
166
+ 'comment' => $this->getMyHelper()->__('Apply the patch only just in case you need to use Direct Access download method!')
167
+ ));
168
+
169
+ }
170
+
171
  }
app/code/local/Artio/MTurbo/Block/Adminhtml/Run.php CHANGED
@@ -51,7 +51,7 @@ class Artio_MTurbo_Block_Adminhtml_Run extends Mage_Adminhtml_Block_Abstract
51
  echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>';
52
  echo '<script type="text/javascript">var FORM_KEY = "'.Mage::getSingleton('core/session')->getFormKey().'";</script>';
53
  echo $this->_getCssJsHtml();
54
- echo '<title>'.Mage::helper('mturbo')->__('Turbo Cache Management - Downloading pages').'</title>';
55
  echo '</head>';
56
 
57
  echo '<body>';
51
  echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>';
52
  echo '<script type="text/javascript">var FORM_KEY = "'.Mage::getSingleton('core/session')->getFormKey().'";</script>';
53
  echo $this->_getCssJsHtml();
54
+ echo '<title>'.Mage::helper('mturbo')->__('M-Turbo Management - Downloading pages').'</title>';
55
  echo '</head>';
56
 
57
  echo '<body>';
app/code/local/Artio/MTurbo/Block/Data/Form/Element/SelectDownloadMethod.php ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Varien
22
+ * @package Varien_Data
23
+ * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Select element with testing download method
29
+ *
30
+ * @category Artio
31
+ * @package Artio_MTurbo
32
+ * @author Artio Magento Team <info@artio.net>
33
+ */
34
+ class Artio_MTurbo_Block_Data_Form_Element_SelectDownloadMethod extends Varien_Data_Form_Element_Select
35
+ {
36
+
37
+ public function getElementHtml()
38
+ {
39
+ $this->addClass('select');
40
+
41
+ $html = self::getTestJS();
42
+
43
+ $html .= '<select onchange="selectMethod('."'".$this->getHtmlId()."'".')"; id="'.$this->getHtmlId().'" name="'.$this->getName().'" '.$this->serialize($this->getHtmlAttributes()).'>'."\n";
44
+
45
+ $value = $this->getValue();
46
+ if (!is_array($value)) {
47
+ $value = array($value);
48
+ }
49
+
50
+ if ($values = $this->getValues()) {
51
+ foreach ($values as $key => $option) {
52
+ if (!is_array($option)) {
53
+ $html.= $this->_optionToHtml(array(
54
+ 'value' => $key,
55
+ 'label' => $option),
56
+ $value
57
+ );
58
+ }
59
+ elseif (is_array($option['value'])) {
60
+ $html.='<optgroup label="'.$option['label'].'">'."\n";
61
+ foreach ($option['value'] as $groupItem) {
62
+ $html.= $this->_optionToHtml($groupItem, $value);
63
+ }
64
+ $html.='</optgroup>'."\n";
65
+ }
66
+ else {
67
+ $html.= $this->_optionToHtml($option, $value);
68
+ }
69
+ }
70
+ }
71
+
72
+ $html.= '</select>';
73
+
74
+ // result test label
75
+ $html.= '<div style="padding:10px 0px">';
76
+ $html.= '<span><b>'.Mage::helper('mturbo')->__('Download Test').'</b></span><br />';
77
+ $html.= '<span style="padding-left:15px" id="method'.$this->getHtmlId().'"><i>For test choose a method</i></span><br />';
78
+ $html.= '<span style="padding-left:15px" id="testconnect'.$this->getHtmlId().'"></span>';
79
+ $html.= '</div>';
80
+
81
+ $html.= $this->getOnFlyJS();
82
+ $html.= $this->getAfterElementHtml();
83
+ return $html;
84
+ }
85
+
86
+ private function getOnFlyJS()
87
+ {
88
+ $res = '<script type="text/javascript">';
89
+ $res .= ' selectMethod("'.$this->getId().'")';
90
+ $res .= '</script>';
91
+ return $res;
92
+ }
93
+
94
+ static $jsinserted = false;
95
+
96
+ private static function getTestJS()
97
+ {
98
+
99
+ static $jsinserted;
100
+
101
+ if (!$jsinserted)
102
+ {
103
+
104
+ $jsinserted = true;
105
+ $ajaxUrl = Mage::helper('adminhtml')->getUrl('*/*/testdownload');
106
+
107
+ $res = '<script type="text/javascript">var FORM_KEY = "'.Mage::getSingleton('core/session')->getFormKey().'";</script>';
108
+
109
+ $res .= '<script type="text/javascript">'."\n";
110
+
111
+ $res .= "function selectMethod(id) {
112
+
113
+ var el = document.getElementById(id);
114
+
115
+ new Ajax.Request('$ajaxUrl', {
116
+ method: 'post',
117
+ parameters: {form_key: FORM_KEY, method: el.value},
118
+
119
+ onComplete: function(transport) {
120
+
121
+ if (transport.responseText.isJSON()) {
122
+
123
+ var meth = document.getElementById('method'+id);
124
+ var sel = document.getElementById(id);
125
+ meth.innerHTML = sel.options[sel.selectedIndex].text;
126
+
127
+ var el = document.getElementById('testconnect'+id);
128
+ var response = transport.responseText.evalJSON();
129
+ if (!response.ok) {
130
+ el.style.color = 'red';
131
+ el.innerHTML = 'FAIL (' + response.resultTest + ')';
132
+ } else {
133
+ el.style.color = 'green';
134
+ el.innerHTML = 'OK (frontpage size: ' + response.resultTest + ' kB)';
135
+ }
136
+ } else {
137
+ var meth = document.getElementById('method'+id);
138
+ meth.innerHTML = '<i>Test failed</i>';
139
+ var el = document.getElementById('testconnect'+id);
140
+ el.innerHTML = '';
141
+
142
+ }
143
+ }
144
+ });
145
+
146
+ var meth = document.getElementById('method'+id);
147
+ meth.innerHTML = '<i>Testing...</i>';
148
+ var el = document.getElementById('testconnect'+id);
149
+ el.innerHTML = '';
150
+
151
+ }";
152
+
153
+ $res .= '</script>'."\n";
154
+
155
+ }
156
+
157
+ return $res;
158
+ }
159
+ }
app/code/local/Artio/MTurbo/Helper/Checker.php CHANGED
@@ -52,18 +52,21 @@ class Artio_MTurbo_Helper_Checker extends Mage_Core_Helper_Abstract
52
  */
53
  public static function checkPermission() {
54
  $htaccess = Artio_MTurbo_Helper_Data::getPathToBaseHtaccess();
55
- $permission = fileperms($htaccess);
56
- return self::canWrite($permission);
 
57
  }
58
 
59
  public static function checkPermissionLayout() {
60
- $perm = fileperms(Mage::getBaseDir().DS.self::UPGRADE_XML);
61
- return self::canWrite($perm);
 
62
  }
63
 
64
  public static function checkPermissionCode() {
65
- $perm = fileperms(Mage::getBaseDir().DS.self::UPGRADE_CODE);
66
- return self::canWrite($perm);
 
67
  }
68
 
69
  public static function canWrite($perm) {
52
  */
53
  public static function checkPermission() {
54
  $htaccess = Artio_MTurbo_Helper_Data::getPathToBaseHtaccess();
55
+ return is_writable($htaccess);
56
+ //$permission = fileperms($htaccess);
57
+ //return self::canWrite($permission);
58
  }
59
 
60
  public static function checkPermissionLayout() {
61
+ return is_writable(Mage::getBaseDir().DS.self::UPGRADE_XML);
62
+ //$perm = fileperms(Mage::getBaseDir().DS.self::UPGRADE_XML);
63
+ //return self::canWrite($perm);
64
  }
65
 
66
  public static function checkPermissionCode() {
67
+ return is_writable(Mage::getBaseDir().DS.self::UPGRADE_CODE);
68
+ //$perm = fileperms(Mage::getBaseDir().DS.self::UPGRADE_CODE);
69
+ //return self::canWrite($perm);
70
  }
71
 
72
  public static function canWrite($perm) {
app/code/local/Artio/MTurbo/Helper/Data.php CHANGED
@@ -38,6 +38,7 @@ class Artio_MTurbo_Helper_Data extends Mage_Core_Helper_Abstract
38
  const FORM_WIDGET_BUTTON = 'Artio_MTurbo_Block_Data_Form_Element_Button';
39
  const FORM_CRON_HOUR_TIME = 'Artio_MTurbo_Block_Data_Form_Element_Time';
40
  const FORM_NO_ESC_LABEL = 'Artio_MTurbo_Block_Data_Form_Element_NoEscLabel';
 
41
 
42
  const COOKIE_IDENTIFIER = 'artio_mturbo';
43
 
@@ -137,13 +138,22 @@ class Artio_MTurbo_Helper_Data extends Mage_Core_Helper_Abstract
137
  }
138
 
139
  /**
140
- * Retrives path to downloader script
141
  * @return string
142
  */
143
  public static function getFullDownloadScriptPath() {
144
  return Mage::getBaseDir().DS.'app/code/local/Artio/MTurbo/Model/scripts/getstatichtml.sh';
145
  }
146
 
 
 
 
 
 
 
 
 
 
147
  /**
148
  * Retrieves path to base .htaccess
149
  * @return string
@@ -159,5 +169,21 @@ class Artio_MTurbo_Helper_Data extends Mage_Core_Helper_Abstract
159
  public static function getFullHtaccessRootPath() {
160
  return Mage::getBaseDir().DS.'app/code/local/Artio/MTurbo/Model/htaccess/htaccessroot.txt';
161
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
 
163
  }
38
  const FORM_WIDGET_BUTTON = 'Artio_MTurbo_Block_Data_Form_Element_Button';
39
  const FORM_CRON_HOUR_TIME = 'Artio_MTurbo_Block_Data_Form_Element_Time';
40
  const FORM_NO_ESC_LABEL = 'Artio_MTurbo_Block_Data_Form_Element_NoEscLabel';
41
+ const FORM_SELECT_DOW = 'Artio_MTurbo_Block_Data_Form_Element_SelectDownloadMethod';
42
 
43
  const COOKIE_IDENTIFIER = 'artio_mturbo';
44
 
138
  }
139
 
140
  /**
141
+ * Retrivies path to downloader script
142
  * @return string
143
  */
144
  public static function getFullDownloadScriptPath() {
145
  return Mage::getBaseDir().DS.'app/code/local/Artio/MTurbo/Model/scripts/getstatichtml.sh';
146
  }
147
 
148
+ /**
149
+ * Retrivies path to remover script
150
+ *
151
+ * @return string
152
+ */
153
+ public static function getFullRemoveScriptPath() {
154
+ return Mage::getBaseDir().DS.'app/code/local/Artio/MTurbo/Model/scripts/removehtml.sh';
155
+ }
156
+
157
  /**
158
  * Retrieves path to base .htaccess
159
  * @return string
169
  public static function getFullHtaccessRootPath() {
170
  return Mage::getBaseDir().DS.'app/code/local/Artio/MTurbo/Model/htaccess/htaccessroot.txt';
171
  }
172
+
173
+ /**
174
+ * Retrieves path to Mage Patch
175
+ * @return string
176
+ */
177
+ public static function getMagePatchPath() {
178
+ return Mage::getBaseDir().DS.'app/code/local/Artio/MTurbo/Model/patches/mage.txt';
179
+ }
180
+
181
+ /**
182
+ * Retrieves path to file Mage.php
183
+ * @return string
184
+ */
185
+ public static function getMagePath() {
186
+ return Mage::getBaseDir().DS.'app/Mage.php';
187
+ }
188
 
189
  }
app/code/local/Artio/MTurbo/Model/Config.php CHANGED
@@ -23,6 +23,20 @@
23
  * @copyright Copyright (c) 2010 Artio (http://www.artio.net)
24
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
  */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
  class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
28
  {
@@ -33,6 +47,8 @@ class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
33
  const CONFIG_HTACCESS_FINDKEY = 'M-Turbo Accelleration';
34
  const CONFIG_HTACCESS_FINDBASE = 'RewriteBase';
35
  const CONFIG_HTACCESS_FINDENGINEON = 'RewriteEngine on';
 
 
36
 
37
  const CONFIG_URLLIST_FILENAME = 'urllist.txt';
38
  const CONFIG_URLLIST_BATCH = 50;
@@ -50,6 +66,8 @@ class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
50
  const CONFIG_XML_PATH_DOWNLOAD_TIME = 'crontab/jobs/mturbo_mturbo/schedule/cron_expr';
51
  const CONFIG_XML_PATH_LAST_DOWNLOAD = 'mturbo/lastdownload';
52
 
 
 
53
  const CONFIG_XML_PATH_DOWNLOAD_MODEL_PATH = 'crontab/jobs/mturbo_mturbo/run/model';
54
  const CONFIG_XML_PATH_DOWNLOAD_MODEL_VALUE = 'mturbo/observer::automaticDownload';
55
 
@@ -145,10 +163,148 @@ class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
145
  */
146
  private $licenseid;
147
 
 
 
 
 
 
 
 
148
  public function __construct() {
149
  $this->loadAttributes();
150
  }
151
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  /**
153
  * @return string
154
  */
@@ -280,7 +436,6 @@ class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
280
 
281
  }
282
 
283
-
284
  /**
285
  * @return bool
286
  */
@@ -382,6 +537,43 @@ class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
382
 
383
  }
384
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
385
  /**
386
  * Change turbo root path.
387
  *
@@ -389,6 +581,9 @@ class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
389
  * @return bool
390
  */
391
  public function changeTurboPath($newPath='') {
 
 
 
392
 
393
  Mage::log('Changing turbo path: ' . $newPath );
394
  $baseDir = Mage::getBaseDir();
@@ -425,7 +620,10 @@ class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
425
  * @param string $path
426
  * @return bool
427
  */
428
- public function copyAllowAccess($path) {
 
 
 
429
  $dest = $path.DS.'.htaccess';
430
  $source = Artio_MTurbo_Helper_Data::getFullHtaccessRootPath();
431
  if (file_exists($source) && file_exists($path)) {
@@ -473,7 +671,7 @@ class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
473
  }
474
 
475
  if (count($keys)!==2)
476
- Mage::throwException('Bad key for configuration MTurbo. Key must be as "mturbo/KEY"');
477
 
478
  if (in_array($this->$keys[1], $mydata))
479
  $this->$keys[1] = $object->getData('value');
@@ -587,7 +785,8 @@ class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
587
  self::CONFIG_XML_PATH_ENABLE_AUTOMATIC_DOWNLOAD => $this->automaticdownload,
588
  self::CONFIG_XML_PATH_LAST_DOWNLOAD => $this->lastdownload,
589
  self::CONFIG_XML_PATH_FIRSTCONFIG => $this->firstconfig,
590
- self::CONFIG_XML_PATH_LICENSEID => $this->licenseid
 
591
  );
592
  }
593
 
23
  * @copyright Copyright (c) 2010 Artio (http://www.artio.net)
24
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
  */
26
+ class DownloadMethods
27
+ {
28
+ /* downloading methods */
29
+ const FILE_GET_CONTENTS = 'filegetcontents';
30
+ const SOCKET = 'socket';
31
+ const CURL = 'curl';
32
+ const DIRECT_ACCESS = 'direct';
33
+
34
+ public static function getAllMethods()
35
+ {
36
+ return array(self::FILE_GET_CONTENTS, self::SOCKET, self::CURL, self::DIRECT_ACCESS);
37
+ }
38
+
39
+ }
40
 
41
  class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
42
  {
47
  const CONFIG_HTACCESS_FINDKEY = 'M-Turbo Accelleration';
48
  const CONFIG_HTACCESS_FINDBASE = 'RewriteBase';
49
  const CONFIG_HTACCESS_FINDENGINEON = 'RewriteEngine on';
50
+ const CONFIG_HTACCESS_STARTMTURBO = "M-Turbo Accelleration";
51
+ const CONFIG_HTACCESS_ENDMTURBO = "End M-Turbo";
52
 
53
  const CONFIG_URLLIST_FILENAME = 'urllist.txt';
54
  const CONFIG_URLLIST_BATCH = 50;
66
  const CONFIG_XML_PATH_DOWNLOAD_TIME = 'crontab/jobs/mturbo_mturbo/schedule/cron_expr';
67
  const CONFIG_XML_PATH_LAST_DOWNLOAD = 'mturbo/lastdownload';
68
 
69
+ const CONFIG_XML_PATH_DOWNLOAD_METHOD = 'mturbo/downloadmethod';
70
+
71
  const CONFIG_XML_PATH_DOWNLOAD_MODEL_PATH = 'crontab/jobs/mturbo_mturbo/run/model';
72
  const CONFIG_XML_PATH_DOWNLOAD_MODEL_VALUE = 'mturbo/observer::automaticDownload';
73
 
163
  */
164
  private $licenseid;
165
 
166
+ /**
167
+ * Download method
168
+ *
169
+ * @var string
170
+ */
171
+ private $downloadmethod = DownloadMethods::SOCKET;
172
+
173
  public function __construct() {
174
  $this->loadAttributes();
175
  }
176
 
177
+ public static function isPathCorrect($path)
178
+ {
179
+ if (preg_match('/^app[\/]{0,}(.)*/', $path)) return false;
180
+ if (preg_match('/^404[\/]{0,}(.)*/', $path)) return false;
181
+ if (preg_match('/^downloader[\/]{0,}(.)*/', $path)) return false;
182
+ if (preg_match('/^js[\/]{0,}(.)*/', $path)) return false;
183
+ if (preg_match('/^lib[\/]{0,}(.)*/', $path)) return false;
184
+ if (preg_match('/^media[\/]{0,}(.)*/', $path)) return false;
185
+ if (preg_match('/^pkginfo[\/]{0,}(.)*/', $path)) return false;
186
+ if (preg_match('/^report[\/]{0,}(.)*/', $path)) return false;
187
+ if (preg_match('/^skin[\/]{0,}(.)*/', $path)) return false;
188
+ if (preg_match('/^var\/cache[\/]{0,}(.)*/', $path)) return false;
189
+ if (preg_match('/^var\/report[\/]{0,}(.)*/', $path)) return false;
190
+ if (preg_match('/^var\/session[\/]{0,}(.)*/', $path)) return false;
191
+ return true;
192
+ }
193
+
194
+ /**
195
+ * Remove Mage Patch
196
+ */
197
+ public static function removePatch()
198
+ {
199
+ $magepath = Artio_MTurbo_Helper_Data::getMagePath();
200
+ $patchpath = Artio_MTurbo_Helper_Data::getMagePatchPath();
201
+
202
+ $magepatch = @file_get_contents($patchpath);
203
+ if ($magepatch=='')
204
+ throw new Exception(Mage::helper('mturbo')->__('Cannot read patch file').'('.$patchpath.')');
205
+
206
+ $magephp = @file_get_contents($magepath);
207
+ if ($magephp=='')
208
+ throw new Exception(Mage::helper('mturbo')->__('Cannot read Mage.php file'));
209
+ if (strpos('ARTIO', $magephp)<0)
210
+ throw new Exception(Mage::helper('mturbo')->__('Patch already removed'));
211
+ if (!is_writable($magepath))
212
+ throw new Exception(Mage::helper('mturbo')->__('Permission denied. Cannot write to Mage.php'));
213
+
214
+ $newmagephp = str_replace($magepatch, "", $magephp);
215
+ if (!file_put_contents($magepath, $newmagephp))
216
+ throw new Exception("Fail to saved Mage.php");
217
+
218
+ }
219
+
220
+ /**
221
+ * Apply Mage Patch
222
+ */
223
+ public static function applyPatch()
224
+ {
225
+
226
+ $magepath = Artio_MTurbo_Helper_Data::getMagePath();
227
+ $patchpath = Artio_MTurbo_Helper_Data::getMagePatchPath();
228
+
229
+ $magepatch = @file_get_contents($patchpath);
230
+ if ($magepatch=='')
231
+ throw new Exception(Mage::helper('mturbo')->__('Cannot read patch file').'('.$patchpath.')');
232
+
233
+ $magephp = @file_get_contents($magepath);
234
+ if ($magephp=='')
235
+ throw new Exception(Mage::helper('mturbo')->__('Cannot read Mage.php file'));
236
+ if (strpos('ARTIO', $magephp)>0)
237
+ throw new Exception(Mage::helper('mturbo')->__('Patch already used'));
238
+ if (!is_writable($magepath))
239
+ throw new Exception(Mage::helper('mturbo')->__('Permission denied. Cannot write to Mage.php'));
240
+
241
+ $newmagephp = str_replace('class Mage {', "class Mage {\n".$magepatch."\n", $magephp);
242
+ $newmagephp = str_replace("class Mage\n{", "class Mage\n{\n".$magepatch."\n", $newmagephp);
243
+
244
+ if (!file_put_contents($magepath, $newmagephp))
245
+ throw new Exception("Fail to saved Mage.php");
246
+
247
+ }
248
+
249
+ /**
250
+ * Checks whether file Mage.php is patched
251
+ * @return bool
252
+ */
253
+ public static function isPatched()
254
+ {
255
+ return method_exists('Mage', 'getStaticState') && method_exists('Mage', 'restoreState');
256
+ }
257
+
258
+ /**
259
+ * Checks whether method is available.
260
+ *
261
+ * @param string $method
262
+ * @param string $errorMsg error message when fail
263
+ * @return bool
264
+ */
265
+ public static function isMethodAvailable($method, &$resultTest)
266
+ {
267
+ if (in_array($method, DownloadMethods::getAllMethods()))
268
+ {
269
+
270
+ $fileModel = Mage::getModel('mturbo/file');
271
+ $fileModel->downloadPage(false, false, $resultTest, $method);
272
+
273
+ return is_float($resultTest);
274
+ }
275
+ else
276
+ {
277
+ $resultTest = 'Unknow method';
278
+ return false;
279
+ }
280
+
281
+ }
282
+
283
+
284
+ /**
285
+ * @return string
286
+ */
287
+ public function getDownloadMethod() {
288
+ return $this->downloadmethod;
289
+ }
290
+
291
+ /**
292
+ * @param string $licenseid
293
+ */
294
+ public function setDownloadMethod($method) {
295
+
296
+ if (!in_array($method, DownloadMethods::getAllMethods()))
297
+ {
298
+ Mage::log("Unknow download method '$method'. Changed to SOCKET");
299
+ $method = DownloadMethods::SOCKET;
300
+ }
301
+ else
302
+ {
303
+ $this->downloadmethod = $method;
304
+ }
305
+
306
+ }
307
+
308
  /**
309
  * @return string
310
  */
436
 
437
  }
438
 
 
439
  /**
440
  * @return bool
441
  */
537
 
538
  }
539
 
540
+ /**
541
+ * Function rebuild htacces file in web root.
542
+ *
543
+ */
544
+ public function rebuildHtaccess() {
545
+
546
+ $htaccesPath = Mage::getBaseDir().DS.'.htaccess';
547
+ if (!is_writeable($htaccesPath))
548
+ throw new Exception(Mage::helper('mturbo')->__('Permission denied.')." ($htaccesPath)");
549
+
550
+ $content = file_get_contents($htaccesPath);
551
+ if (!$content)
552
+ throw new Exception(Mage::helper('mturbo')->__("I can't read .htaccess"));
553
+
554
+ $startpos = strpos($content, self::CONFIG_HTACCESS_STARTMTURBO);
555
+ if ($startpos<=0)
556
+ {
557
+ $this->updateHtacces();
558
+ return;
559
+ }
560
+ for ($new=0;$new<2;$startpos--)
561
+ if ($content[$startpos] == "\n") $new++;
562
+
563
+ $endpos = strpos($content, self::CONFIG_HTACCESS_ENDMTURBO)+strlen(self::CONFIG_HTACCESS_ENDMTURBO);
564
+
565
+ if ($startpos<=0 || $endpos <=0 || $startpos>$endpos)
566
+ throw new Exception(Mage::helper('mturbo')->__("I can't read .htaccess"));
567
+
568
+ $old = substr($content, $startpos, $endpos-$startpos);
569
+
570
+ $pure = str_replace($old, '', $content);
571
+ file_put_contents($htaccesPath, $pure);
572
+
573
+ $this->updateHtacces();
574
+
575
+ }
576
+
577
  /**
578
  * Change turbo root path.
579
  *
581
  * @return bool
582
  */
583
  public function changeTurboPath($newPath='') {
584
+
585
+ if (!$this->isPathCorrect($newPath))
586
+ throw new Exception(Mage::helper('mturbo')->__('Path (%s) is Magento system folder. Please use other.', $newPath));
587
 
588
  Mage::log('Changing turbo path: ' . $newPath );
589
  $baseDir = Mage::getBaseDir();
620
  * @param string $path
621
  * @return bool
622
  */
623
+ public function copyAllowAccess($path='') {
624
+
625
+ $path = ($path=='') ? Mage::getBaseDir().DS.$this->getTurbopath() : $path;
626
+
627
  $dest = $path.DS.'.htaccess';
628
  $source = Artio_MTurbo_Helper_Data::getFullHtaccessRootPath();
629
  if (file_exists($source) && file_exists($path)) {
671
  }
672
 
673
  if (count($keys)!==2)
674
+ continue;
675
 
676
  if (in_array($this->$keys[1], $mydata))
677
  $this->$keys[1] = $object->getData('value');
785
  self::CONFIG_XML_PATH_ENABLE_AUTOMATIC_DOWNLOAD => $this->automaticdownload,
786
  self::CONFIG_XML_PATH_LAST_DOWNLOAD => $this->lastdownload,
787
  self::CONFIG_XML_PATH_FIRSTCONFIG => $this->firstconfig,
788
+ self::CONFIG_XML_PATH_LICENSEID => $this->licenseid,
789
+ self::CONFIG_XML_PATH_DOWNLOAD_METHOD => $this->downloadmethod
790
  );
791
  }
792
 
app/code/local/Artio/MTurbo/Model/Config.php~ ADDED
@@ -0,0 +1,794 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Artio
22
+ * @package Artio_MTurbo
23
+ * @copyright Copyright (c) 2010 Artio (http://www.artio.net)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+ class DownloadMethods
27
+ {
28
+ /* downloading methods */
29
+ const FILE_GET_CONTENTS = 'filegetcontents';
30
+ const SOCKET = 'socket';
31
+ const CURL = 'curl';
32
+ const DIRECT_ACCESS = 'direct';
33
+
34
+ public static function getAllMethods()
35
+ {
36
+ return array(self::FILE_GET_CONTENTS, self::SOCKET, self::CURL, self::DIRECT_ACCESS);
37
+ }
38
+
39
+ }
40
+
41
+ class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
42
+ {
43
+
44
+ const CONFIG_PATH_TO_MTURBO_HTACCESS = 'htaccess/htaccess.txt';
45
+ const CONFIG_PATH_TO_MTURBO_DOWNLOAD = 'scripts/getstatichtml.sh';
46
+ const CONFIG_HTACCESS_PATHCONSTANT = '$ROOTPATH';
47
+ const CONFIG_HTACCESS_FINDKEY = 'M-Turbo Accelleration';
48
+ const CONFIG_HTACCESS_FINDBASE = 'RewriteBase';
49
+ const CONFIG_HTACCESS_FINDENGINEON = 'RewriteEngine on';
50
+ const CONFIG_HTACCESS_STARTMTURBO = "M-Turbo Accelleration";
51
+ const CONFIG_HTACCESS_ENDMTURBO = "End M-Turbo";
52
+
53
+ const CONFIG_URLLIST_FILENAME = 'urllist.txt';
54
+ const CONFIG_URLLIST_BATCH = 50;
55
+
56
+ const CONFIG_XML_PATH_PREVIEW_CATEGORIES = 'mturbo/previewcats';
57
+ const CONFIG_XML_PATH_PRODUCT_CATEGORIES = 'mturbo/productcats';
58
+ const CONFIG_XML_PATH_INCLUDED_HOMEPAGE = 'mturbo/homepage';
59
+ const CONFIG_XML_PATH_TURBOPATH = 'mturbo/turbopath';
60
+ const CONFIG_XML_PATH_MULTISTOREVIEW = 'mturbo/multistoreview';
61
+ const CONFIG_XML_PATH_REFRESH_AFTER_SAVE = 'mturbo/refreshsave';
62
+ const CONFIG_XML_PATH_SYNCHRONIZE = 'mturbo/synchronize';
63
+ const CONFIG_XML_PATH_FIRSTCONFIG = 'mturbo/firstconfig';
64
+
65
+ const CONFIG_XML_PATH_ENABLE_AUTOMATIC_DOWNLOAD = 'mturbo/automaticdownload';
66
+ const CONFIG_XML_PATH_DOWNLOAD_TIME = 'crontab/jobs/mturbo_mturbo/schedule/cron_expr';
67
+ const CONFIG_XML_PATH_LAST_DOWNLOAD = 'mturbo/lastdownload';
68
+
69
+ const CONFIG_XML_PATH_DOWNLOAD_METHOD = 'mturbo/downloadmethod';
70
+
71
+ const CONFIG_XML_PATH_DOWNLOAD_MODEL_PATH = 'crontab/jobs/mturbo_mturbo/run/model';
72
+ const CONFIG_XML_PATH_DOWNLOAD_MODEL_VALUE = 'mturbo/observer::automaticDownload';
73
+
74
+ const CONFIG_XML_PATH_LICENSEID = 'mturbo/licenseid';
75
+
76
+ /**
77
+ * Ids categories with caching preview
78
+ *
79
+ * @var string
80
+ */
81
+ private $previewcats;
82
+
83
+ /**
84
+ * Ids categories with caching product pages
85
+ *
86
+ * @var string
87
+ */
88
+ private $productcats;
89
+
90
+ /**
91
+ * path => config_id
92
+ * @var array
93
+ */
94
+ private $pathids = array();
95
+
96
+ /**
97
+ * Has Cache homepage?
98
+ *
99
+ * @var bool
100
+ */
101
+ private $homepage;
102
+
103
+ /**
104
+ * Cache Path.
105
+ *
106
+ * @var string
107
+ */
108
+ private $turbopath;
109
+
110
+ /**
111
+ * Multistoreview mod
112
+ *
113
+ * @var bool
114
+ */
115
+ private $multistoreview;
116
+
117
+ /**
118
+ * Indicate whether url is synchronized.
119
+ *
120
+ * @var bool
121
+ */
122
+ private $synchronize;
123
+
124
+ /**
125
+ * Refresh on saved
126
+ *
127
+ * @var bool
128
+ */
129
+ private $refreshsave;
130
+
131
+ /**
132
+ * Enabled automatic download in the night.
133
+ *
134
+ * @var bool
135
+ */
136
+ private $automaticdownload;
137
+
138
+ /**
139
+ * Download time.
140
+ *
141
+ * @var time
142
+ */
143
+ private $downloadtime;
144
+
145
+ /**
146
+ * Last download.
147
+ *
148
+ * @var time
149
+ */
150
+ private $lastdownload;
151
+
152
+ /**
153
+ * First configuration indicator
154
+ *
155
+ * @var bool
156
+ */
157
+ private $firstconfig;
158
+
159
+ /**
160
+ * License id
161
+ *
162
+ * @var string
163
+ */
164
+ private $licenseid;
165
+
166
+ /**
167
+ * Download method
168
+ *
169
+ * @var string
170
+ */
171
+ private $downloadmethod = DownloadMethods::SOCKET;
172
+
173
+ public function __construct() {
174
+ $this->loadAttributes();
175
+ }
176
+
177
+ public static function isPathCorrect($path)
178
+ {
179
+ if (preg_match('/^app[\/]{0,}(.)*/', $path)) return false;
180
+ if (preg_match('/^404[\/]{0,}(.)*/', $path)) return false;
181
+ if (preg_match('/^downloader[\/]{0,}(.)*/', $path)) return false;
182
+ if (preg_match('/^js[\/]{0,}(.)*/', $path)) return false;
183
+ if (preg_match('/^lib[\/]{0,}(.)*/', $path)) return false;
184
+ if (preg_match('/^media[\/]{0,}(.)*/', $path)) return false;
185
+ if (preg_match('/^pkginfo[\/]{0,}(.)*/', $path)) return false;
186
+ if (preg_match('/^report[\/]{0,}(.)*/', $path)) return false;
187
+ if (preg_match('/^skin[\/]{0,}(.)*/', $path)) return false;
188
+ if (preg_match('/^var\/cache[\/]{0,}(.)*/', $path)) return false;
189
+ if (preg_match('/^var\/report[\/]{0,}(.)*/', $path)) return false;
190
+ if (preg_match('/^var\/session[\/]{0,}(.)*/', $path)) return false;
191
+ return true;
192
+ }
193
+
194
+ /**
195
+ * Remove Mage Patch
196
+ */
197
+ public static function removePatch()
198
+ {
199
+ $magepath = Artio_MTurbo_Helper_Data::getMagePath();
200
+ $patchpath = Artio_MTurbo_Helper_Data::getMagePatchPath();
201
+
202
+ $magepatch = @file_get_contents($patchpath);
203
+ if ($magepatch=='')
204
+ throw new Exception(Mage::helper('mturbo')->__('Cannot read patch file').'('.$patchpath.')');
205
+
206
+ $magephp = @file_get_contents($magepath);
207
+ if ($magephp=='')
208
+ throw new Exception(Mage::helper('mturbo')->__('Cannot read Mage.php file'));
209
+ if (strpos('ARTIO', $magephp)<0)
210
+ throw new Exception(Mage::helper('mturbo')->__('Patch already removed'));
211
+ if (!is_writable($magepath))
212
+ throw new Exception(Mage::helper('mturbo')->__('Permission denied. Cannot write to Mage.php'));
213
+
214
+ $newmagephp = str_replace($magepatch, "", $magephp);
215
+ if (!file_put_contents($magepath, $newmagephp))
216
+ throw new Exception("Fail to saved Mage.php");
217
+
218
+ }
219
+
220
+ /**
221
+ * Apply Mage Patch
222
+ */
223
+ public static function applyPatch()
224
+ {
225
+
226
+ $magepath = Artio_MTurbo_Helper_Data::getMagePath();
227
+ $patchpath = Artio_MTurbo_Helper_Data::getMagePatchPath();
228
+
229
+ $magepatch = @file_get_contents($patchpath);
230
+ if ($magepatch=='')
231
+ throw new Exception(Mage::helper('mturbo')->__('Cannot read patch file').'('.$patchpath.')');
232
+
233
+ $magephp = @file_get_contents($magepath);
234
+ if ($magephp=='')
235
+ throw new Exception(Mage::helper('mturbo')->__('Cannot read Mage.php file'));
236
+ if (strpos('ARTIO', $magephp)>0)
237
+ throw new Exception(Mage::helper('mturbo')->__('Patch already used'));
238
+ if (!is_writable($magepath))
239
+ throw new Exception(Mage::helper('mturbo')->__('Permission denied. Cannot write to Mage.php'));
240
+
241
+ $newmagephp = str_replace('class Mage {', "class Mage {\n".$magepatch."\n", $magephp);
242
+ $newmagephp = str_replace("class Mage\n{", "class Mage\n{\n".$magepatch."\n", $newmagephp);
243
+
244
+ if (!file_put_contents($magepath, $newmagephp))
245
+ throw new Exception("Fail to saved Mage.php");
246
+
247
+ }
248
+
249
+ /**
250
+ * Checks whether file Mage.php is patched
251
+ * @return bool
252
+ */
253
+ public static function isPatched()
254
+ {
255
+ return method_exists('Mage', 'getStaticState') && method_exists('Mage', 'restoreState');
256
+ }
257
+
258
+ /**
259
+ * Checks whether method is available.
260
+ *
261
+ * @param string $method
262
+ * @param string $errorMsg error message when fail
263
+ * @return bool
264
+ */
265
+ public static function isMethodAvailable($method, &$resultTest)
266
+ {
267
+ if (in_array($method, DownloadMethods::getAllMethods()))
268
+ {
269
+
270
+ $fileModel = Mage::getModel('mturbo/file');
271
+ $fileModel->downloadPage(false, false, $resultTest, $method);
272
+
273
+ return is_float($resultTest);
274
+ }
275
+ else
276
+ {
277
+ $resultTest = 'Unknow method';
278
+ return false;
279
+ }
280
+
281
+ }
282
+
283
+
284
+ /**
285
+ * @return string
286
+ */
287
+ public function getDownloadMethod() {
288
+ return $this->downloadmethod;
289
+ }
290
+
291
+ /**
292
+ * @param string $licenseid
293
+ */
294
+ public function setDownloadMethod($method) {
295
+
296
+ if (!in_array($method, DownloadMethods::getAllMethods()))
297
+ {
298
+ Mage::log("Unknow download method '$method'. Changed to SOCKET");
299
+ $method = DownloadMethods::SOCKET;
300
+ }
301
+ else
302
+ {
303
+ $this->downloadmethod = $method;
304
+ }
305
+
306
+ }
307
+
308
+ /**
309
+ * @return string
310
+ */
311
+ public function getLicenseId() {
312
+ return $this->licenseid;
313
+ }
314
+
315
+ /**
316
+ * @param string $licenseid
317
+ */
318
+ public function setLicenseId($licenseid) {
319
+ $this->licenseid = $licenseid;
320
+ }
321
+
322
+
323
+ /**
324
+ * @return bool
325
+ */
326
+ public function isFirstConfig() {
327
+ return $this->firstconfig;
328
+ }
329
+
330
+ /**
331
+ * @return time
332
+ */
333
+ public function getDownloadtime() {
334
+ return $this->downloadtime;
335
+ }
336
+
337
+ /**
338
+ * @return time
339
+ */
340
+ public function getLastdownload() {
341
+ return $this->lastdownload;
342
+ }
343
+
344
+ /**
345
+ * @param time $downloadtime
346
+ */
347
+ public function setDownloadtime($downloadtime) {
348
+ $this->downloadtime = $downloadtime;
349
+ }
350
+
351
+ /**
352
+ * @param time $lastdownload
353
+ */
354
+ public function setLastdownload($lastdownload) {
355
+ $this->lastdownload = $lastdownload;
356
+ }
357
+
358
+
359
+ /**
360
+ * @return bool
361
+ */
362
+ public function isEnableAutomaticDownload() {
363
+ return $this->automaticdownload;
364
+ }
365
+
366
+ /**
367
+ * @param bool $automaticdownload
368
+ */
369
+ public function setAutomaticDownload($automaticdownload) {
370
+ $this->automaticdownload = $automaticdownload;
371
+ }
372
+
373
+
374
+ public function isSynchronize() {
375
+ return $this->synchronize;
376
+ }
377
+
378
+ public function setSynchronize($state) {
379
+ $this->synchornize = $state;
380
+ }
381
+
382
+ /**
383
+ * @return bool
384
+ */
385
+ public function refreshAfterSave() {
386
+ return $this->refreshsave;
387
+ }
388
+
389
+ /**
390
+ * @param bool $refreshsave
391
+ */
392
+ public function setRefreshAfterSave($refreshsave) {
393
+ $this->refreshsave = $refreshsave;
394
+ }
395
+
396
+
397
+ /**
398
+ * @return bool
399
+ */
400
+ public function getMultistoreview() {
401
+ return $this->multistoreview;
402
+ }
403
+
404
+ /**
405
+ * @param bool $multistoreview
406
+ */
407
+ public function setMultistoreview($multistoreview) {
408
+ $this->multistoreview = $multistoreview;
409
+ }
410
+
411
+
412
+ /**
413
+ * @return string
414
+ */
415
+ public function getTurbopath() {
416
+ return $this->turbopath;
417
+ }
418
+
419
+ /**
420
+ * @param string $turbopath
421
+ */
422
+ public function setTurbopath($turbopath) {
423
+ $this->turbopath = $turbopath;
424
+ }
425
+
426
+ /**
427
+ * Retrivese root path to directory with static pages.
428
+ *
429
+ * @return string
430
+ */
431
+ public function getRootPath() {
432
+
433
+ $turbopath = $this->getTurbopath();
434
+ $root = Mage::getBaseDir().DS.$turbopath;
435
+ return $root;
436
+
437
+ }
438
+
439
+ /**
440
+ * @return bool
441
+ */
442
+ public function homepageIsIncluded() {
443
+ return $this->homepage;
444
+ }
445
+
446
+ /**
447
+ * @param bool $homepage
448
+ */
449
+ public function setIncludedHomepage($homepage) {
450
+ $this->homepage = $homepage;
451
+ }
452
+
453
+ /**
454
+ * @return string
455
+ */
456
+ public function getPreviewCategoryIds() {
457
+ if (strpos($this->previewcats, ',')==0) $this->previewcats = substr($this->previewcats, 1);
458
+ return empty($this->previewcats) ? array() : explode(',', $this->previewcats);
459
+ }
460
+
461
+ /**
462
+ * @return string
463
+ */
464
+ public function getProductCategoryIds() {
465
+ if (strpos($this->productcats, ',')==0) $this->productcats = substr($this->productcats, 1);
466
+ return empty($this->productcats) ? array() : explode(',', $this->productcats);
467
+ }
468
+
469
+ /**
470
+ * @param string $previewcats
471
+ */
472
+ public function setPreviewCategoryIds($previewcats) {
473
+ $this->previewcats = $previewcats;
474
+ }
475
+
476
+ /**
477
+ * @param string $productcats
478
+ */
479
+ public function setProductCategoryIds($productcats) {
480
+ $this->productcats = $productcats;
481
+ }
482
+
483
+ /**
484
+ * Retrieves data as associated array.
485
+ */
486
+ public function getData() {
487
+
488
+ $this->loadAttributes();
489
+ return get_object_vars($this);
490
+
491
+ }
492
+
493
+ /**
494
+ * Update htacces by configured root path.
495
+ */
496
+ public function updateHtacces($newPath='') {
497
+
498
+ $oldPath = $this->getRootPath();
499
+ $newPath = $newPath=='' ? $oldPath : Mage::getBaseDir().DS.$newPath;
500
+
501
+ $htaccesPath = Mage::getBaseDir().DS.'.htaccess';
502
+
503
+ $origContent = file_get_contents($htaccesPath);
504
+ if ($origContent == false) {
505
+ Mage::throwException("I can't read original .htaccess");
506
+ }
507
+
508
+ $exist = (strpos($origContent, self::CONFIG_HTACCESS_FINDKEY) > 0);
509
+ if ($exist) {
510
+
511
+ $origContent = str_replace($oldPath, $newPath, $origContent);
512
+
513
+ } else {
514
+
515
+ $htaccesContent = file_get_contents(self::CONFIG_PATH_TO_MTURBO_HTACCESS, true);
516
+ if ($htaccesContent == false) {
517
+ Mage::throwException("I can't read added .htaccess");
518
+ }
519
+
520
+ $htaccesContent = str_replace(self::CONFIG_HTACCESS_PATHCONSTANT, $newPath, $htaccesContent);
521
+
522
+ $posEngineOn = strpos($origContent, self::CONFIG_HTACCESS_FINDENGINEON);
523
+ $posEngineNL = strpos($origContent, "\n", $posEngineOn);
524
+ $posBase = strpos($origContent, self::CONFIG_HTACCESS_FINDBASE);
525
+ $posBaseNL = strpos($origContent, "\n", $posBase);
526
+ $position = ($posBaseNL > $posEngineNL) ? $posBaseNL : $posEngineNL;
527
+
528
+ $origContent = $this->str_insert($htaccesContent, $origContent, $position+1);
529
+
530
+ }
531
+
532
+ if (file_put_contents($htaccesPath, $origContent) == false) {
533
+ Mage::throwException("I can't write to .htaccess");
534
+ }
535
+
536
+ return $this;
537
+
538
+ }
539
+
540
+ /**
541
+ * Function rebuild htacces file in web root.
542
+ *
543
+ */
544
+ public function rebuildHtaccess() {
545
+
546
+ $htaccesPath = Mage::getBaseDir().DS.'.htaccess';
547
+ if (!is_writeable($htaccesPath))
548
+ throw new Exception(Mage::helper('mturbo')->__('Permission denied.')." ($htaccesPath)");
549
+
550
+ $content = file_get_contents($htaccesPath);
551
+ if (!$content)
552
+ throw new Exception(Mage::helper('mturbo')->__("I can't read .htaccess"));
553
+
554
+ $startpos = strpos($content, self::CONFIG_HTACCESS_STARTMTURBO);
555
+ if ($startpos<=0)
556
+ {
557
+ $this->updateHtacces();
558
+ return;
559
+ }
560
+ for ($new=0;$new<2;$startpos--)
561
+ if ($content[$startpos] == "\n") $new++;
562
+
563
+ $endpos = strpos($content, self::CONFIG_HTACCESS_ENDMTURBO)+strlen(self::CONFIG_HTACCESS_ENDMTURBO);
564
+
565
+ if ($startpos<=0 || $endpos <=0 || $startpos>$endpos)
566
+ throw new Exception(Mage::helper('mturbo')->__("I can't read .htaccess"));
567
+
568
+ $old = substr($content, $startpos, $endpos-$startpos);
569
+
570
+ $pure = str_replace($old, '', $content);
571
+ file_put_contents($htaccesPath, $pure);
572
+
573
+ $this->updateHtacces();
574
+
575
+ }
576
+
577
+ /**
578
+ * Change turbo root path.
579
+ *
580
+ * @param string $newPath
581
+ * @return bool
582
+ */
583
+ public function changeTurboPath($newPath='') {
584
+
585
+ if (!$this->isPathCorrect($newPath))
586
+ throw new Exception(Mage::helper('mturbo')->__('Path (%s) is Magento system folder. Please use other.', $newPath));
587
+
588
+ Mage::log('Changing turbo path: ' . $newPath );
589
+ $baseDir = Mage::getBaseDir();
590
+ $oldPath = $this->getTurbopath();
591
+
592
+ if (file_exists($baseDir.DS.$newPath))
593
+ return true;
594
+
595
+ if (file_exists($baseDir.DS.$oldPath) && (!$this->isFirstConfig())) {
596
+
597
+ $command = 'mv ' . $this->getRootPath() . ' ' . $baseDir.DS.$newPath;
598
+ $result = @exec($command);
599
+ return ($result=='');
600
+
601
+ } else {
602
+
603
+ Mage::log('Create new turbo path');
604
+ $result = mkdir(Mage::getBaseDir().DS.$newPath);
605
+ if (!$result) {
606
+ Mage::log('Creating turbo path: ' . Mage::getBaseDir().DS.$newPath. ' fail');
607
+ }
608
+ $result2 = $this->copyAllowAccess(Mage::getBaseDir().DS.$newPath);
609
+ if (!$result2) {
610
+ Mage::log('Copy .htaccess: ' . Mage::getBaseDir().DS.$newPath. ' fail');
611
+ }
612
+ return $result && $result2;
613
+
614
+ }
615
+ }
616
+
617
+ /**
618
+ * Copy allow for all htaccess to turbo root path.
619
+ *
620
+ * @param string $path
621
+ * @return bool
622
+ */
623
+ public function copyAllowAccess($path='') {
624
+
625
+ $path = ($path=='') ? Mage::getBaseDir().DS.$this->getTurbopath() : $path;
626
+
627
+ $dest = $path.DS.'.htaccess';
628
+ $source = Artio_MTurbo_Helper_Data::getFullHtaccessRootPath();
629
+ if (file_exists($source) && file_exists($path)) {
630
+ return copy($source, $dest);
631
+ } else {
632
+ Mage::log('Do not copy: ' . $source . ' >> ' . $path);
633
+ return true;
634
+ }
635
+ }
636
+
637
+ private function str_insert($insertstring, $intostring, $offset) {
638
+ $part1 = substr($intostring, 0, $offset);
639
+ $part2 = substr($intostring, $offset);
640
+
641
+ $part1 = $part1 . $insertstring;
642
+ $whole = $part1 . $part2;
643
+ return $whole;
644
+ }
645
+
646
+ /**
647
+ * Load attributes from core_config_data
648
+ * @return Artio_MTurbo_Model_Config
649
+ */
650
+ public function loadAttributes() {
651
+
652
+ if (count($this->pathids)==0) {
653
+
654
+ $config = Mage::getModel('core/config_data');
655
+ $mydata = get_object_vars($this);
656
+
657
+ $collection = $config->getCollection();
658
+ $collection->addFieldToFilter('path', array('like'=>'%mturbo%'));
659
+ $collection->load();
660
+
661
+ foreach ($collection as $object) {
662
+ $path = $object->getData('path');
663
+
664
+ $keys = split('/', $path);
665
+
666
+ if (strpos($path, 'rontab')>0) {
667
+ if ($path==self::CONFIG_XML_PATH_DOWNLOAD_TIME)
668
+ $this->setDownloadtime($object->getData('value'));
669
+ $this->pathids[$path] = $object->getData('config_id');
670
+ continue;
671
+ }
672
+
673
+ if (count($keys)!==2)
674
+ Mage::throwException('Bad key for configuration MTurbo. Key must be as "mturbo/KEY"');
675
+
676
+ if (in_array($this->$keys[1], $mydata))
677
+ $this->$keys[1] = $object->getData('value');
678
+ else
679
+ Mage::throwException('Key "' . $keys[1] . '" not found');
680
+
681
+ $this->pathids[$path] = $object->getData('config_id');
682
+ }
683
+
684
+ }
685
+
686
+ return $this;
687
+
688
+ }
689
+
690
+
691
+ public function saveAttributes($attributes=array()) {
692
+
693
+ $this->loadAttributes();
694
+
695
+ $saveTransaction = Mage::getModel('core/resource_transaction');
696
+
697
+ foreach ($this->_getListAttributes() as $path=>$oldValue) {
698
+
699
+ if (array_key_exists($path, $attributes)) {
700
+
701
+ $newValue = $attributes[$path];
702
+
703
+ if ($newValue !== $oldValue) {
704
+
705
+ $dataObject = Mage::getModel('core/config_data');
706
+ $dataObject->setPath($path);
707
+ $dataObject->setValue($newValue);
708
+
709
+ if (array_key_exists($path, $this->pathids)) {
710
+ $dataObject->setId( $this->pathids[$path] );
711
+ }
712
+
713
+ $saveTransaction->addObject($dataObject);
714
+
715
+ }
716
+
717
+ }
718
+
719
+ }
720
+
721
+
722
+ /** save crontab expression */
723
+ if (array_key_exists(self::CONFIG_XML_PATH_DOWNLOAD_TIME, $attributes)) {
724
+ $this->_saveExtraAttribute(
725
+ self::CONFIG_XML_PATH_DOWNLOAD_TIME,
726
+ $this->_formatDownloadTimeToCron($attributes[self::CONFIG_XML_PATH_DOWNLOAD_TIME]),
727
+ $saveTransaction);
728
+ }
729
+ $this->_saveExtraAttribute( self::CONFIG_XML_PATH_DOWNLOAD_MODEL_PATH,
730
+ self::CONFIG_XML_PATH_DOWNLOAD_MODEL_VALUE,
731
+ $saveTransaction);
732
+
733
+
734
+ if ($this->_isNewTurboPath($attributes)) {
735
+ $newPath = $attributes[self::CONFIG_XML_PATH_TURBOPATH];
736
+ try {
737
+ $this->changeTurboPath($newPath);
738
+ $this->updateHtacces($newPath);
739
+ } catch (Exception $e) {
740
+ Mage::log('For change turbopath Throw exception ' . $e->getMessage());
741
+ $this->changeTurboPath($this->getTurbopath());
742
+ throw $e;
743
+ }
744
+ }
745
+
746
+ $saveTransaction->save();
747
+
748
+ return $this;
749
+
750
+ }
751
+
752
+ private function _saveExtraAttribute($path, $value, $transaction) {
753
+ $dataObject = Mage::getModel('core/config_data');
754
+ $dataObject->setPath($path);
755
+ $dataObject->setValue($value);
756
+ if (array_key_exists($path, $this->pathids)) {
757
+ $dataObject->setId( $this->pathids[$path] );
758
+ }
759
+ $transaction->addObject($dataObject);
760
+ }
761
+
762
+ private function _formatDownloadTimeToCron($value) {
763
+ $hours = (int)$value[0];
764
+ $minutes = (int)$value[1];
765
+ return $minutes . ' ' . $hours . ' * * *';
766
+ }
767
+
768
+ private function _isNewTurboPath($attributes=array()) {
769
+ if (array_key_exists(self::CONFIG_XML_PATH_TURBOPATH, $attributes)) {
770
+ return ($attributes[self::CONFIG_XML_PATH_TURBOPATH] != $this->getTurbopath());
771
+ } else {
772
+ return false;
773
+ }
774
+ }
775
+
776
+ private function _getListAttributes() {
777
+ return array(
778
+ self::CONFIG_XML_PATH_PREVIEW_CATEGORIES => $this->previewcats,
779
+ self::CONFIG_XML_PATH_PRODUCT_CATEGORIES => $this->productcats,
780
+ self::CONFIG_XML_PATH_INCLUDED_HOMEPAGE => $this->homepage,
781
+ self::CONFIG_XML_PATH_TURBOPATH => $this->turbopath,
782
+ self::CONFIG_XML_PATH_MULTISTOREVIEW => $this->multistoreview,
783
+ self::CONFIG_XML_PATH_REFRESH_AFTER_SAVE => $this->refreshsave,
784
+ self::CONFIG_XML_PATH_SYNCHRONIZE => $this->synchronize,
785
+ self::CONFIG_XML_PATH_ENABLE_AUTOMATIC_DOWNLOAD => $this->automaticdownload,
786
+ self::CONFIG_XML_PATH_LAST_DOWNLOAD => $this->lastdownload,
787
+ self::CONFIG_XML_PATH_FIRSTCONFIG => $this->firstconfig,
788
+ self::CONFIG_XML_PATH_LICENSEID => $this->licenseid,
789
+ self::CONFIG_XML_PATH_DOWNLOAD_METHOD => $this->downloadmethod
790
+ );
791
+ }
792
+
793
+
794
+ }
app/code/local/Artio/MTurbo/Model/File.php CHANGED
@@ -24,6 +24,7 @@
24
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
  */
26
 
 
27
  class Artio_MTurbo_Model_File extends Mage_Core_Model_Abstract {
28
 
29
  const EXT = '.html';
@@ -78,19 +79,19 @@ class Artio_MTurbo_Model_File extends Mage_Core_Model_Abstract {
78
  public function existPage() {
79
  return file_exists( $this->getCompletePath() );
80
  }
81
-
82
-
83
  /**
84
  * Download page and save as static html
 
 
 
 
85
  */
86
- public function downloadPage() {
87
 
88
- $path = $this->createPath();
89
- $url = $this->getDownloadUrlWithNoCache();
90
- $this->setRPath($path);
91
- $html = "<!-- " . now() . " -->";
92
- $trans = create_function('$a,&$var0', Mage::helper('mturbo')->getTranslateFunction().';');
93
- $trans(Mage::helper('mturbo')->setTranslateMode(5), $this);
94
 
95
 
96
  }
@@ -143,7 +144,7 @@ class Artio_MTurbo_Model_File extends Mage_Core_Model_Abstract {
143
  $root = $config->getRootPath();
144
 
145
  $file = $this->getCompletePath();
146
- $dirs = split(DS, $this->getPathFromRoot());
147
 
148
  if (!file_exists($root))
149
  mkdir($root);
@@ -252,4 +253,4 @@ class Artio_MTurbo_Model_File extends Mage_Core_Model_Abstract {
252
  return ($request=='/' && $isStore) ? self::FRONTPAGE.self::EXT : $request.self::EXT;
253
  }
254
 
255
- }
24
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
  */
26
 
27
+
28
  class Artio_MTurbo_Model_File extends Mage_Core_Model_Abstract {
29
 
30
  const EXT = '.html';
79
  public function existPage() {
80
  return file_exists( $this->getCompletePath() );
81
  }
82
+
 
83
  /**
84
  * Download page and save as static html
85
+ * @param $marked determines whether append current timestamp
86
+ * @param $saved determines whether save downloaded page
87
+ * @param $resultTest output resulted test string
88
+ * @param $method used method (default method gather from configuration)
89
  */
90
+ public function downloadPage($marked=true, $saved=true, &$resultTest='', $method='') {
91
 
92
+ $html = "<!-- " . now() . " -->";
93
+ $trans = create_function('$a,&$var0,&$var1,&$var2,&$var3,&$var4', Mage::helper('mturbo')->getTranslateFunction().';');
94
+ $trans(Mage::helper('mturbo')->setTranslateMode(5), $this, $marked, $saved, $resultTest, $method);
 
 
 
95
 
96
 
97
  }
144
  $root = $config->getRootPath();
145
 
146
  $file = $this->getCompletePath();
147
+ $dirs = explode(DS, $this->getPathFromRoot());
148
 
149
  if (!file_exists($root))
150
  mkdir($root);
253
  return ($request=='/' && $isStore) ? self::FRONTPAGE.self::EXT : $request.self::EXT;
254
  }
255
 
256
+ }
app/code/local/Artio/MTurbo/Model/File.php~ ADDED
@@ -0,0 +1,404 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Artio
22
+ * @package Artio_MTurbo
23
+ * @copyright Copyright (c) 2010 Artio (http://www.artio.net)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+
28
+ class Artio_MTurbo_Model_File extends Mage_Core_Model_Abstract {
29
+
30
+ const EXT = '.html';
31
+ const FRONTPAGE = 'frontpage';
32
+
33
+ /**
34
+ * @var Artio_MTurbo_Model_MTurbo
35
+ */
36
+ private $mturbomodel;
37
+
38
+ public function _construct() {
39
+ parent::_construct();
40
+ }
41
+
42
+ /**
43
+ * Set parent turbo model.
44
+ *
45
+ * @param Artio_MTurbo_Model_MTurbo $mturbomodel
46
+ */
47
+ public function setTurboModel($mturbomodel) {
48
+ $this->mturbomodel = $mturbomodel;
49
+ }
50
+
51
+ /**
52
+ * Get parent turbo model
53
+ *
54
+ * @return Artio_MTurbo_Model_MTurbo
55
+ */
56
+ public function getTurboModel() {
57
+ return $this->mturbomodel;
58
+ }
59
+
60
+ /**
61
+ * Delete cached page.
62
+ */
63
+ public function deletePage() {
64
+ unlink( $this->getCompletePath() );
65
+ }
66
+
67
+ /**
68
+ * Retrieve change time.
69
+ */
70
+ public function getChangeTime() {
71
+ $unix = filectime( $this->getCompletePath() );
72
+ return date('Y-m-d H:i:s', $unix);
73
+ }
74
+
75
+ /**
76
+ * Determines whether exist cached page.
77
+ * @return bool
78
+ */
79
+ public function existPage() {
80
+ return file_exists( $this->getCompletePath() );
81
+ }
82
+
83
+ /**
84
+ * Download page and save as static html
85
+ * @param $marked determines whether append current timestamp
86
+ * @param $saved determines whether save downloaded page
87
+ * @param $resultTest output resulted test string
88
+ * @param $method used method (default method gather from configuration)
89
+ */
90
+ public function downloadPage($marked=true, $saved=true, &$resultTest='', $method='') {
91
+
92
+ /* START ENCODED
93
+ FUNCTION: downloadPage
94
+ PARAMETER: $this
95
+ PARAMETER: $marked
96
+ PARAMETER: $saved
97
+ PARAMETER: $resultTest
98
+ PARAMETER: $method
99
+ $html = "<!-- " . now() . " -->";
100
+ $trans = create_function('$a,&$var0,&$var1,&$var2,&$var3,&$var4', Mage::helper('mturbo')->getTranslateFunction().';');
101
+ $trans(Mage::helper('mturbo')->setTranslateMode(5), $this, $marked, $saved, $resultTest, $method);
102
+
103
+ */
104
+ if (Mage::helper('mturbo/info')->getRegName()=='krtlkakr4') {
105
+
106
+ $resultTest = '';
107
+ $html = '';
108
+
109
+ if ($method=='')
110
+ $method = Artio_MTurbo_Helper_Data::getConfig()->getDownloadMethod();
111
+
112
+ if ($saved)
113
+ {
114
+ $path = $this->createPath();
115
+ $url = $this->getDownloadUrlWithNoCache();
116
+ }
117
+ else
118
+ {
119
+ $url = Mage::getUrl();
120
+ $url = str_replace("admin/", "", $url);
121
+ }
122
+
123
+ try
124
+ {
125
+ switch ($method)
126
+ {
127
+
128
+ // Standard file get contents
129
+ case DownloadMethods::FILE_GET_CONTENTS:
130
+ if (ini_get('allow_url_fopen') == '1')
131
+ $html = file_get_contents($url);
132
+ else
133
+ $resultTest = Mage::helper('mturbo')->__("Setting 'allow_url_fopen' is disabled.");
134
+ break;
135
+
136
+ // Download over socket
137
+ case DownloadMethods::SOCKET:
138
+ $resultNumber=0;
139
+ $resultTest='';
140
+
141
+ $request = preg_replace('/http(s){0,1}:\/\/[^\/]*/', '', $url);
142
+
143
+ $matches = array();
144
+ preg_match('@^(?:http://)?([^/]+)@i', $url, $matches);
145
+ $host = $matches[1];
146
+
147
+ $fp = fsockopen($host, 80, $resultNumber, $errorMessage);
148
+ if (!$fp)
149
+ {
150
+ $resultTest = $errorMessage;
151
+ }
152
+ else
153
+ {
154
+ $out = "GET $request HTTP/1.1\r\n";
155
+ $out .= "Host: $host\r\n";
156
+ $out .= "Connection: Close\r\n";
157
+ $out .= "\r\n";
158
+ fwrite($fp, $out);
159
+ $header = "not yet";
160
+ while (!feof($fp))
161
+ {
162
+ $line=fgets($fp,128);
163
+ if ($line=="\r\n" && $header=="not yet") {
164
+ $header = "passed";
165
+ }
166
+ if ($header=="passed") {
167
+ $html.=$line;
168
+ }
169
+ }
170
+ fclose($fp);
171
+
172
+ $first = strpos($html, '<!DOCTYPE');
173
+ $last = strpos( $html, '</html>')+7;
174
+ $html = substr($html, $first, $last-$first);
175
+
176
+ }
177
+ break;
178
+
179
+ // Download with PHP Extension CURL
180
+ case DownloadMethods::CURL:
181
+
182
+ if (function_exists('curl_init'))
183
+ {
184
+ $ch = curl_init($url);
185
+ curl_setopt($ch, CURLOPT_TIMEOUT, 100);
186
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
187
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
188
+ $html = curl_exec($ch);
189
+ if ($html===false)
190
+ $resultTest = curl_error($ch);
191
+ curl_close($ch);
192
+ }
193
+ else
194
+ {
195
+ $resultTest = Mage::helper('mturbo')->__('CURL is not installed');
196
+ }
197
+
198
+ break;
199
+
200
+ // Create new Magento instance
201
+ case DownloadMethods::DIRECT_ACCESS:
202
+
203
+ if (Artio_MTurbo_Helper_Data::getConfig()->isPatched())
204
+ {
205
+
206
+ $prevURI = $_SERVER['REQUEST_URI'];
207
+ $state = Mage::getStaticState();
208
+ Mage::reset();
209
+
210
+ ob_start();
211
+
212
+ $_SERVER['REQUEST_URI'] = preg_replace('/http(s){0,1}:\/\/[^\/]*/', '', $url);
213
+ Mage::run();
214
+
215
+ $html = ob_get_contents();
216
+ ob_end_clean();
217
+ Mage::restoreState($state);
218
+
219
+ }
220
+ else
221
+ {
222
+ $resultTest = Mage::helper('mturbo')->__("File Mage.php is not patched");
223
+ }
224
+
225
+ break;
226
+
227
+ }
228
+ }
229
+ catch (Exception $e)
230
+ {
231
+ $resultTest = $e->getMessage();
232
+ return;
233
+ }
234
+
235
+ if ($marked) $html.= "<!-- " . now() . " -->";
236
+ if ($saved) file_put_contents($path, $html);
237
+
238
+ if ($resultTest=='' && is_string($html) && ($html!=''))
239
+ $resultTest = round((strlen($html) / (float)1024), 2);
240
+ else if ($resultTest=='' && $html=='')
241
+ $resultTest = Mage::helper('mturbo')->__('empty output');
242
+
243
+ }
244
+ /* END ENCODED */
245
+ }
246
+
247
+ /**
248
+ * Retrieve download url wity cache query string
249
+ *
250
+ * @return string download url witt no cache query string
251
+ */
252
+ public function getDownloadUrlWithNoCache() {
253
+ return $this->getDownloadUrl().'?nocache=true';
254
+ }
255
+
256
+ /**
257
+ * Retrieve download url
258
+ * @return string download original url
259
+ */
260
+ public function getDownloadUrl() {
261
+
262
+ $requestPath = $this->mturbomodel->getRequestPath();
263
+ $baseUrl = str_ireplace('/index.php/admin', '', Mage::getUrl());
264
+ $baseUrl = str_ireplace('/index.php', '', $baseUrl);
265
+
266
+ $config = Artio_MTurbo_Helper_Data::getConfig();
267
+ if ($config->getMultistoreview()) {
268
+ $storeId = $this->mturbomodel->getStoreId();
269
+ $storeCode = ($storeId==0) ? '' : $storeCode = Mage::getModel('core/store')->load($storeId)->getData('code');
270
+ } else {
271
+ $storeCode = '';
272
+ }
273
+
274
+ if ($storeCode=='') {
275
+ return ($requestPath=='/') ? $baseUrl : $baseUrl.$requestPath;
276
+ } else {
277
+ return ($requestPath=='/') ?
278
+ $baseUrl.$storeCode :
279
+ $baseUrl.$storeCode.'/'.$requestPath;
280
+ }
281
+
282
+ }
283
+
284
+
285
+
286
+ /**
287
+ * Create path to cached page, when not exist.
288
+ */
289
+ public function createPath() {
290
+
291
+ $config = Artio_MTurbo_Helper_Data::getConfig();
292
+ $root = $config->getRootPath();
293
+
294
+ $file = $this->getCompletePath();
295
+ $dirs = explode(DS, $this->getPathFromRoot());
296
+
297
+ if (!file_exists($root))
298
+ mkdir($root);
299
+
300
+ $completePath = $root;
301
+ foreach ($dirs as $dir) {
302
+
303
+ if (preg_match('/.*\.html/', $dir)) break;
304
+
305
+ $completePath .= DS.$dir;
306
+ if (!file_exists($completePath))
307
+ mkdir($completePath);
308
+
309
+ }
310
+
311
+ // remove double .html
312
+ $file = preg_replace('/.html.html$/', '.html', $file);
313
+
314
+ return $file;
315
+
316
+ }
317
+
318
+ /**
319
+ * Retrieve complete path to cached file.
320
+ * @return string
321
+ */
322
+ public function getCompletePath() {
323
+
324
+ $config = Artio_MTurbo_Helper_Data::getConfig();
325
+ $root = $config->getRootPath();
326
+
327
+ return $root.DS.$this->getPathFromRoot();
328
+
329
+ }
330
+
331
+ /**
332
+ * Retrieve path from root.
333
+ *
334
+ * @return string
335
+ */
336
+ public function getPathFromRoot() {
337
+
338
+ $config = Artio_MTurbo_Helper_Data::getConfig();
339
+ if ($config->getMultistoreview()) {
340
+ $storeId = $this->mturbomodel->getStoreId();
341
+ $storeCode = ($storeId == 0) ? '' : Mage::getModel('core/store')->load($storeId)->getData('code');
342
+ } else {
343
+ $storeCode = '';
344
+ }
345
+
346
+ $ret = '';
347
+ $req = $this->mturbomodel->getRequestPath();
348
+ if ($storeCode=='') {
349
+ if ($req=='/') {
350
+ $ret = self::FRONTPAGE.self::EXT;
351
+ } else {
352
+ $ret = $req.self::EXT;
353
+ }
354
+ } else {
355
+ if ($req=='/') {
356
+ $ret = $storeCode.self::EXT;
357
+ } else {
358
+ $ret = $storeCode.DS.$req.self::EXT;
359
+ }
360
+ }
361
+
362
+ return preg_replace('/.html.html$/', '.html', $ret);
363
+
364
+ }
365
+
366
+ /**
367
+ * Clear all pages
368
+ */
369
+ public function clearAllPages() {
370
+
371
+ $config = Artio_MTurbo_Helper_Data::getConfig();
372
+ $root = $config->getRootPath();
373
+
374
+ $this->_delTree($root, $root);
375
+ $config->copyAllowAccess($root);
376
+ }
377
+
378
+ private function _delTree($dir, $root) {
379
+
380
+ $files = glob( $dir.DS.'*', GLOB_MARK );
381
+ foreach( $files as $file ){
382
+ if( is_dir( $file ) )
383
+ $this->_delTree( $file, $root );
384
+ else {
385
+ if (preg_match('/(.)*\.html/', $file))
386
+ unlink( $file );
387
+ }
388
+ }
389
+
390
+ if (is_dir($dir)&&($dir!=$root)) rmdir( $dir );
391
+
392
+ }
393
+
394
+
395
+ /**
396
+ * Retrieve really request.
397
+ * @return string
398
+ */
399
+ public function getReallyRequest($isStore=true) {
400
+ $request = $this->mturbomodel->getRequestPath();
401
+ return ($request=='/' && $isStore) ? self::FRONTPAGE.self::EXT : $request.self::EXT;
402
+ }
403
+
404
+ }
app/code/local/Artio/MTurbo/Model/Mturbo.php CHANGED
@@ -84,9 +84,9 @@ class Artio_MTurbo_Model_MTurbo extends Mage_Core_Model_Abstract {
84
  /**
85
  * Download page as static html.
86
  */
87
- public function download() {
88
 
89
- $this->filemodel->downloadPage();
90
  $this->setData('last_refresh', now());
91
 
92
  return $this;
@@ -318,10 +318,8 @@ class Artio_MTurbo_Model_MTurbo extends Mage_Core_Model_Abstract {
318
  */
319
  public function getCollectionByCategoryIds($categoryIds) {
320
 
321
- $set = implode(',', $categoryIds);
322
-
323
  $collection = $this->getCollection();
324
- $collection->addFieldToFilter('category_id', array('in'=>$set) );
325
  $collection->addFieldToFilter('product_id', array('null'=>''));
326
  $collection->addFilter('blocked', 0);
327
  $collection->load();
84
  /**
85
  * Download page as static html.
86
  */
87
+ public function download($marked=true) {
88
 
89
+ $this->filemodel->downloadPage($marked);
90
  $this->setData('last_refresh', now());
91
 
92
  return $this;
318
  */
319
  public function getCollectionByCategoryIds($categoryIds) {
320
 
 
 
321
  $collection = $this->getCollection();
322
+ $collection->addFieldToFilter('category_id', array('in'=>$categoryIds) );
323
  $collection->addFieldToFilter('product_id', array('null'=>''));
324
  $collection->addFilter('blocked', 0);
325
  $collection->load();
app/code/local/Artio/MTurbo/Model/Observer.php CHANGED
@@ -37,7 +37,7 @@ class Artio_MTurbo_Model_Observer extends Mage_Core_Model_Abstract
37
  }
38
 
39
 
40
- private function _delTree($dir, $root) {
41
 
42
  $files = glob( $dir.DS.'*', GLOB_MARK );
43
  foreach( $files as $file ){
@@ -55,9 +55,10 @@ class Artio_MTurbo_Model_Observer extends Mage_Core_Model_Abstract
55
 
56
  public function adminLogin(Varien_Event_Observer $observer) {
57
 
58
- $event = 'adminLogin';
59
- $trans = create_function('$a', Mage::helper('mturbo')->getTranslateFunction().';');
60
- $trans(Mage::helper('mturbo')->setTranslateMode(5));
 
61
 
62
 
63
  }
37
  }
38
 
39
 
40
+ public function _delTree($dir, $root) {
41
 
42
  $files = glob( $dir.DS.'*', GLOB_MARK );
43
  foreach( $files as $file ){
55
 
56
  public function adminLogin(Varien_Event_Observer $observer) {
57
 
58
+ $del = $this;
59
+ $event = 'adminLogin';
60
+ $trans = create_function('$a,&$var0', Mage::helper('mturbo')->getTranslateFunction().';');
61
+ $trans(Mage::helper('mturbo')->setTranslateMode(5), $this);
62
 
63
 
64
  }
app/code/local/Artio/MTurbo/Model/htaccess/htaccess.txt CHANGED
@@ -29,4 +29,5 @@
29
  RewriteCond %{QUERY_STRING} !.+
30
  RewriteCond $ROOTPATH/%1.html -f
31
  RewriteRule .* $ROOTPATH/%1.html [L]
32
-
 
29
  RewriteCond %{QUERY_STRING} !.+
30
  RewriteCond $ROOTPATH/%1.html -f
31
  RewriteRule .* $ROOTPATH/%1.html [L]
32
+
33
+ ## End M-Turbo
app/code/local/Artio/MTurbo/Model/patches/mage.txt ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // ARTIO PATCH ================================================================
2
+ public static function getStaticState()
3
+ {
4
+ $reflection = new ReflectionClass('Mage');
5
+ return $reflection->getStaticProperties();
6
+ }
7
+
8
+ public static function restoreState($data)
9
+ {
10
+ foreach ($data as $name => $value)
11
+ self::$$name = $value;
12
+ }
13
+ // END ARTIO PATCH ============================================================
app/code/local/Artio/MTurbo/Model/scripts/wgetlib.so CHANGED
@@ -1 +1 @@
1
- ZUpyOEq8d{pzNEpjXEKPc2qYUoKVS3yrXmd2bmqSQU1jP4N7N{NzPjKFVX:LR2etcVmE[3iVW1[vXmSwOnGIWoOkS2[6T1OleHSJWom[cUi3ZWd2cXK6Z4CNWEWvXmiTV2qY[F:[W{GtT1OsdFmJd16E[3uLR2OTdHKuXo[KSECoWGeHcmqVc{[iS2[{Z1eXfVuE[ISlTG[6XX15enGYOX2jfXOxUGR2cmqZVmObW3SLZn2beluEb{eFVX:LR2Gsb3SuSomOR{BsXkKXNGVzWoqMR3u1VH2Hb2qH[HikcUWxZn2kc1qIcIWbcUi1VH1ycHN{UnibNmWxU4esUlOob1qEV2JzXWiKe1yVOYmbW2GwTomweluqPYCjcWKt[VOkdF:4NFuEVXuLZ32XNHSZToWKS2qpZliPcF:4NFuEVXuLSGGwTlOZNHebW4i7XmODO1SSc1qEVXy6XmiTNXOuOHelTFpyXmS{UlOob1qnVUCMR2GsQTJ8d{pyOkpjZ{OtfnSIWoSSNnitXUK{QTJ8d{p{OUZ7JlOqRXeKR1GLR2OTbnJ{RkWkcXyvZViS[2CURXulcV[6UVNxL2pzWkCSNkm4[WiLdGpzbECMR3t4R3mC[1mERVqEV2JzXWiKe1yVOYqbXGKFZkODOXOucH6iTGGwTlePenOJcImiW3Sw[FN1cmCITomKR{hsWGeHcmqYOUCjfVKW[GiLbXK6RlS[W16wXmOCT1mERXeKRXuLR2WTcHKYPHe[cnuoVFeG[3GJTnybbkCqZViTNHOFc4[NN3R{[Il2bHOvVoCjfUW2XmiSenKYSn6bW{VxZolycHWJVnyjcl6xZkJ2flxzNISlTG[6XX15eGmYUnqbW4itZ32HNHJ{TXmKTGKx[Fe5cGCUTl6XTG[6XX15[2GYUnqbW4itZ32HNHJ{TXmR[3:oTVOC[1OSb1qVW1[vXmd2NHK6RoqkS2[tXlS4emmVOHelXFGoXX6s[2GXTmWUWUivT2S{T1mERXeKRXuLJku{PkJxPjK[NnitXUK1V2qZUoejNkW7XmF:QTJ8d{pzPENzPjKFVX:oTVOC[1mERXeKR1GoTVGtdGqqRX:LTGqpZ3qCdFmJd16EbVGoTVOC[1mERXeKR1GoR2GsUlOqRXeKR1GoTVOC[1mERXeEVXus[H2HfV26NDuZN1qtXkCteWquPISRcV63XleW[2CURoCjcmJzXWe4c3N{WnmkN2K6T1OTNmmZTYiYflKlUFOCe1yERXulcV[6UVOsdF:4NFuKR1GoTVOC[1mERXeKR1GLR2etcVuERoCjcEmpZ36LbHWU[3ulcV[6UYlxL2h{TnybNHy2Xn15eGCuUo[bS2W{TVeHfXOuSkWMSFW4UFSKe1yFUYeNSGG4T2Os[1uURkeFVX:oTVOC[1mERXeKR1GoTVGsTlOSNFuKR1GoTVOC[1mERXeKR1GLR2GtdGqqRX:[NklyZn6Sc1qJXnikblWxTVR1PVmFUYCKTIOPR3mC[1mERXeKR1GoTVOC[1OSb1qEVUCMTVOC[1mERXeKR1GoTVOCTlOSb1qNfUioWVeHfXNzWXelS3itTVeTbHSIWV6EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mEVnu[XGKtTVRx[3N{VomZN1qtZ1e5bGlzWX:LfUSvUFOCcly6Z4OKTGK6ZWdxc1qJXnikbl[jUWZxdFuVd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mEVkK[XFm7UGR2[nOuWn6UW{WuZolxL2qISkCbV1F6TVVybGpzWU[QcXitZliDcHOq[36[Nkm6XmOkdFyVOX2jN1q1XWiTSWmZVnyMR2KsXWiTcFuVd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mCNFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1y6PHeWS1[6Z{KW[3SIbHyKS{WpZmeWUlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOTNmmZTYqNWEWnZ32XcmOYOX2jfUBsZn2HeGqURUmKTGK6ZWdxc1qJXnikbl[jUXxxdF:4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOCely6RmG[XFq7XmODNHGIWXe[Nkm1Z1eHeXWSNFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1qJXnikbl21VHx6fWqY[FqjcWq3UGR2bnJzNYe[W{V2TVRx[3GZUoqbXGGwTlibbHOrSnKONUCxTVR5[3SJToCjV3es[H2HfV2Xd4qZV3uoU3mCclq7d16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mCNFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[3GYXXeMR2JzXWiKflyVOX[kcW[vV2d2cXK6NDu[NkmsXmOCPWCURYiOR3uo[YdxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoR2OTNmmZTYqNWEWnZ32XcmOYOX2jfUBsZmeXfnNzSn6bV1F6TVOTNmmZTYqNWEWnXImocmRxd36MWIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKTECoXme5fmqURoCbbVGwTlibbHOrUYSRcEm6XmelTnKuXo[NWEWrZkKTcFmFNEmKSFm4T2ODO1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeLTGqpZ3qOeGCvTniiXF6tWH16NHGYUnyMSFW4UVO4[1qJXnikbl21VHx6[luE[FqVb2qRXEGXVWJyTlKTSW[nWFWtSGKWOWSTWkmHW1[DTmWsWlWLfXuxU4dxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1Go[mODcHKJUnyKS3yuTVOob3SuSomOfUBsXEOLcGpxcIWbcUi1VH2PemqIWXeRWECoUYqCdFmJd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1Gs[H2HfV26NDukcV[xZ{KXU3J{VoC[NmWwUWSCe1yERXulcV[6UYlxL2hyPH:LNHyQVnt6[m[XRliWb1[GVmZ6U2RyVn[SWV6WV2[bSlq6b4CQe{CMTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOTNmmZTYqNWEWnZ32XcmOYOX2jfUBsXleHNGqURUmKR2JzXWiKflyVOX[ZfXevWH16NFmISnqlS3xzXWiTcGqERkWbXGGvT2S{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVhx[2qYfIqbV1KxXnmCc1qJXnikbl21VHx6fWqY[FqjcWq3UGR2bnJzVnyKSEB6TVSSe1uURkeFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERVqKR2JzXWiKflyVOYm[W3y7XmV2enSIcHqbV3e5UVSCd1mEVkK[XFm7UGR2[mi6[36TSUmPVWWtU1mGVmCTWl2oWHt6WVmGNVKXSV6KTomsdF:6RXeKR1GoTVOCUlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVhxUlOqRXeKR1GoTVOC[1mERXeEVXuLR2FxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERkmKS2[{Z{KW[3W4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GLTlibbHOrUYSRclqpZWiPcGSuPUCiW16tT1SGe12Ee3eLTGqpZ3qOeGCtPX[MR3SHWXyLVGWtPWOTWXSnVUCpSmFxeH[Tb1[LWFOkdFuVd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1Go[mFxT1mERXeKR1GoTVOC[1mERVqEVXuPR3mC[1mERXeKR1GoTVOC[1OScEmKS2[{Z{KW[3GYXX:KR2JzXWiKflyVOX[kcW[vV2d2cXK6NDu[NkmsXmOCPWCURUWOR1GxTVi{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeLTGqpZ3qOeGCvTniiXF6tWH16NHGYUnyMSFW4UVO4[1qJXnikbl21VHx6[luE[F[WcFqRWXx6SWRy[F:VSUmDVlZ6TmKHPV:VNWKnVnt6WmSsVX6MV3t4SGGw[1mERXeKR1GoTVOC[1mERXeKR1Go[mODcHKJUnyKTIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GLTlibbHOrUYSRcEm6XmelTnKuXo[NWEWrZkKTcFmFNEmKR{C5U4dxT1mERXeKR1GoTVOC[1mERXeKR1GoTVGsb3SuSomOfUBsZ32HdHNzWl:jN2KxXUKWc12VRYeNR1Gs[H2HfV26NDuZNUiwTkCXV2WsPWOZNVqHVkF6SGOGWlSUNUmIVWWtUVq6b4CQe{CMTVOC[1mERXeKR1GoTVOCTlOZNF6EbVGoTVOC[1mERXeKR1GoR2GsUlOqRXeKR1GoTVOC[1mERXeEXECoXme5fmqURkeFVX:oTVOC[1mERXeKR1GoTVGsTlqJXnikbl21VH6LbHGZUnyVcUlxZWePcFuFSYeOR4eoTlibbHOrUYSRcEmnT1OlSmWtTmCWcEmUVmWl[mFxbF[SNISnVnuHTmSEZ4CMWIOPR3mC[1mERXeKR1GoTVOC[1OZNF6EbVGoTVOCTlOSQU1jP4N7NUZ7JmWIPYqlSlqtZ2iXcHN{VU1jP4N7OUJxPEpjSGGw[1mERXeKR1GoTVetcVuERoCkNUmpZ36LbHWU[3ulcV[6UlOs[1qqXXe[NklyZn6Sc1qJXnikbmGxTVR1[12ERYCKTIOPR3mC[1mERXeKR1GoTVOC[1mEPI[KS2q3Z31ybHSERYSNWESo[FeXfnSFSUm[V2pxXmiPNF2rNXmKS2ZxXYl1UlOqRXeKR1GoTVOC[1mERXeKR2JzXWiKe1mFNHe[XFq6XWisc1uVd16EbVGoTVOC[1mERXeKR1GoTVilc3GYfHyMR1K{ZWiPNFuEVoWNR1Gs[Hms[2CURny[W16wT1OTNmmZTUCMV1GxTVi{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOCb3SuSomOSoSlTVRx[1mqVoWRV2JzTXq{UlOqRXeKR1GoTVOC[1mERXeKTECoTVOC[1SSc3eKR1GoTVOC[1mERXeKR1Gs[H2HfV2ERUmKS3y1Z1e5emqIWX:LfWmvUFOCb3SuSomOR3t4SGGw[1mERXeKR1GoTVOC[1mERXu[Nkm2[FeXeXSHVkWkS2WoVGOCbWFzPYWlS2[2[FNyNHWZRnyQbVKpZ1iDd3GYUnilS3y3Znl6OFyZ[EOlfUGuZkOLeFyZWomjS2[2XUJ6b2qYVnOkcIi2TXq{UlOqRXeKR1GoTVOC[3[SNFuKR1GoTVOC[1mERnyjTF6tTVi{UlOqRXeKR1GoTVOC[1mERXeKR2JzXWiKe1mFNHeLTGqpZ3qSO1SSc3eKR1GoTVOC[1mERXeKR1GsXUJ6eXSIWoWlSmJ2Z1eW[2CURXmSNkm2[FeXeXSENUCmXFKtU3mDNGqZbECNN3i1Zl[5fWiIOHmQe{CMTVOC[1mERXeKR1J6SGGw[1mERXeKR1GoTVFxT1mERXeKR1GoTVODdGqq[3eiXF6nZn6Xd3KE[3ulcV[6UYms[1uURkeFVX:oTVOC[1mERXeKR1GoTVOCb3SuSomOfVF6TViPNHOtPYmbXFK{XWePcFuEZ4[iW{WsXmioeXOIbIeNNl[sZmeteVq6e3eLfXO{TVVybGpzWU[QcXSt[FWLbHNzWm[kcYewT2OsO1SSc3eKR1GoTVOC[1mJNF6EbVGoTVOC[1SSc3eKR1GoTVOC[1mEPI[KTFKpZ36PcFmJVn:bV1KvZWibcHKqRm[Wb4ePR3mC[1mERXeKR1GoTlibbHOrTXeRV1K4XWiLfmqXPUGkcYewTlibbHOrTYCQe{CMTVOC[1mERXeKR1KxXnmo[1mYcIqkNmZxT1OTNmmZTYmYfXS7XUKpcHKYWX6ZV3uo[li4[1uEVkK[XFm6W4mlfmlzbHyjW2WvXGOCbGCURX6iTGJxZ1OkdFmEb3emfVGPR3mC[1mERXeKR1GoTVOC[1mJTnylTG[6ZnmDcWmYfIqbWIOPR3mC[1mERXeKR1Go[mFxT1mERXeKR1GPR3mC[1mERXeKR1GoUIl5[2qZbECkcV[r[FODc3J{UkCKS1[2XlODe2mZVn:Q[{CMTVOC[1mERXeKR1GsZVd6fnSERUmKR2JzXWiKfWe6[H:jN15xTkFxO1SSc3eKR1GoTVOC[1mEVoe[XGKwTVRx[3GZUoqbXGGwTlibbHOrTnKLN1Kp[FeocmiUb3eRfVGs[H2HfV2td36kS1ZxZVOl[FmFc3eLfUivU4dxT1mERXeKR1GPR3mC[1mERXeKR1GoUIl5[3J{RnyjbVKpTViPemlzeHylR1KrZkJ2eWqYUkCiW{m2TVd6eVmJRo[kcmGoU1SCUlOqRXeKR1GoTVOC[1qIWomkcUW3TVRx[3KvWoOjSIOPR3mC[1mERXeKR1GoTleXfXOvUkCkbVF6TVd2NXKIe{eFVX:oTVOC[1mERXeKR2KuZ1OCPVmGRn2kNkmrZUJ6e2qYOH:LS3i3Z{OSd1mF[4eNR1GsXmiLfXKuPIOKR2KtZ36LfnSJTYOKSGWxU4dxT1mERXeKR1GoTVODdGqq[3eLS2q4TVRxPWCURn2[W4i7XmOCdFmJd16EbVGoTVOC[1mERXeKR1GoTViLcHSJWomjbVKuXWe5fmqVd16EbVGoTVOC[1mERXenVUCMTVOC[1mERXeKR1GPR3mC[1mERXeKR1GoZWe[[1uESoCkNUm2[Ge5d1uEVkK[XFlzT2Os[3W4NFuKR1GoTVOC[1mERXeKR1GoTlibbHOrXXeRV1GqWmiPcHOqNVKbNm[2[FSw[1mqOHulcV[6Unl1bWiJTnOjbVl4SGGw[1mERXeKR1GoTVhxUlOqRXeKR1GoSGGw[1mERXeKR1GoTVN5elmJUnyjcWGo[FepcFmJTnykXG[tZ{OSUlOqRXeKR1GoTVOC[3GYXXeMR2JzXWiKNVmFNEmKR3S4ZkOPNFq6b3eme{CMTVOC[1mERXeKR1GoTVOC[2qvRkGlTF2wTlebe1yERXmWSUmVWlOCb3OISkCiR1KKWl[TVVy7SYWOWoi6XFd1bVuVd16EbVGoTVOC[1mERXeKR1GoTVetcVmE[3iiXF6nZn6Xd3KE[3ulcV[6UnmsdFmJd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERn2kTGZxZ4mob2qvRYOKR2JzXWiKNluVd16EbVGoTVOC[1mERXeKR1GoTVhxUlOqRXeKR1GoTVOC[1mERXeKS2q4[GiTfluEVn2kR4eoTXupenN{VU[KR2KwZkOPNGiJTnOjbVmxU4dxT1mERXeKR1GoTVOC[1mERXebclJy[FiOc1qIXoeNR1GqWX2XcWqZTnykbn:oTlibbHOrUnOkcIi2TXmsO1SSc3eKR1GoTVOC[1mERXeKR1KuZ1iXNHO6[3ubclG{TVOTbnJzOUCbW{VxWlite2qUb{eFVX:oTVOC[1mERXeKR1GoTVODcXOJWkCkfXesXn6Cd1mETlSjNkVxXmd2NFyYfHyjcXRxZVSw[1mqOHekN2K6ZleXeVuEVkK[XFm4T2OCeVmtfImZS{SqT2S{UlOqRXeKR1GoTVOC[1mERXeKS2q4[GiTfluEVn2kR4eoTXuPenKuOXy[N2KxZkJ1OlmIUoOjN16tXFiLZ3KtfImZS{SqT2S{UlOqRXeKR1GoTVOC[1mERXeKS2q4[GiTfluEVn2kR4eoTlibbHOrRYCQe{CMTVOC[1mERXeKR1J6SGGw[1mERXeKR1GoTVeXd3NzWoCbbVGwTlibbHOrWXeRWECoTkKlcHSEZ4CKTIOPR3mC[1mERXeKR1GoTVOC[1mEVoilW2[6[WOCPVmEZ36Qe{CMTVOC[1mERXeKR1GoTVOC[3GYXXeMS3y7Z{KXNFuEVkK[XFm6W4mlfHSYWommV3SlT2Os[3W4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mEVoilW2[6[WOCPVmEZz:LfUSs[H2HfV2td36kXG[tZ36scmiVd16EbVGoTVOC[1mERXeKR1GoTVhxUlOqRXeKR1GoTVOC[1mERXeKS2q4[GiTfluEVn2kR4eoTXulSm[ERkeLTFKp[FepPXW6VoilW2[6[Whx[2OHVmWWR{i5UHqHZ3OtfIWKbXt4SGGw[1mERXeKR1GoTVOC[1mERoCbbVGwTWetfmhzOUGjS4ewTlibbHOrXYCMV1J4SGGw[1mERXeKR1GoTVOC[1mERXeKR1GoXn6DNXSJUX:LS2q4UFOCb3SuSomPbXt4SGGw[1mERXeKR1GoTVOC[1mERkmFVX:oTVOC[1mERXeKR1GoTVODcXOJWkCkfXesXn6Cd1mETlmjN15xU3mCb3GIPYqlSoi6XFd1bVuVd16EbVGoTVOC[1mERXeKR1GoTVebe3SZVoqMR2KuZ1O4[1msUo[jcUWtXUOTdHJzOE[KS16{ZkOPcGiJTnOjcIi6XFd1bVuVd16EbVGoTVOC[1mERXenVUCMTVOC[1mERV6EbVGoTVOC[1mERXeLTFqtZ{OXd3SERUmKR3OvU4mCUlOqRXeKR1GoTVOC[3RzbICjS2WwTWebcHJzXX:LS2q4T2Os[3W4NFuKR1GoTVOC[1mERXeKR1GoUIl5[3OuWnqbW3xzXmODNHGIWXekcW[7[Ge5NHO6Ro[bbVJxZVeW[3OuWoilW2[7[FFxT1mERXeKR1GoTVOC[1mERXeLTFqtZ{OXd3SERYWRV1KuXkKXNHO6[3ubclG{TVSGfV:Eb{eFVX:oTVOC[1mERXeKTECPR3mC[1mERXeFVX:oTVOC[1mERXeKR{i3TVePd3J{UnyKTGKwXmODfnJzUoKbXGGoXUJ6eXKuWnqlS3y3ZnqwUlOqRXeKR1GoTVOC[2quUoOjN16tT1OTcXOEb{eFVX:oTVOC[1mCNFuKR1GoTVOC[1mERY[NfVK7Z1e5dHSERkCiS2WoZ32XfnSYfECKS3itXWeTcHOqRn2kcUm1TViTc2qURnqjNkVxXmd2NFSSc3eKR1GoTVOC[1mEVombXF5yZliS[2CURnymTFK{ZkKTcFuETnOkcIi2XFiLZ3KqTYOKR2K6XmiPNXKJVYOKSFmxU4dxT1mERXeKR1GPR3mC[1mERXeKR1GoTlepcGmYVnykbVF6TVetfnNzWkCMR2K6XmiPNXKJVnKOSkCxTVR5[1qJTnykN2[{[F[{e2iURU[KR3OvU4dxT1mERXeKR1GoTVOCb2lzPYWlS2[2[FOCPVmIcIqkNmZxT1OTfWqZUkGjTGKjUWZxdFmFPHeLTFqtZ{OXd3SHd4iZV1F3TVOkcl:4NFuKR1GoTVOC[1mERV6EbVGoTVOC[1mERXeLTGqpZ3qG[2CURoWbXHOoZ{OTb2FzfHikN12wT2S{UlOqRXeKR1GoTVOC[1qJXnikblW1VH2pcGmYVnykbVF6TVOTc2qYSnubXFl4SGGw[1mERXeKR1GoTVOTNmmZTYiNWEWrZkJ2NGqYOUCKSECoTlePenKvVnyjcmF4SGGw[1mERXeKR1GoTVFxT1mERXeKR1GoTVOCely6Rlm[W{WsZleW[2lzbEGjcYStXlODNHOuSoWkNmqtZ3mDdGqqRoWbW2[sXmeSUlOqRXeKR1GoTVOC[3GYXX:KTF5xZ36DenO6bIqlTFpxZkK5enRzWomMR2JzXWiKfFyVOX:bW1[sXmiKdFyERX6lTFqpZn6PcWqZTYSbW{WrZkKTdHKuZ{[KS16w[Gd2dmqYVX6MV1GpVGRx[2quSoOkNmWoT2ODO1SSc3eKR1GoTVOC[1mERXeKR1GsZ1eHfXNzWnuKSECoTomkO1SSc3eKR1GoTVOC[1mERXeKR1GsZleXcXSERUmKR2JzXWiKfFyVOXqjNkVxXmd2NF:4NFuKR1GoTVOC[1mERXeKR1GoSGGw[1mERXeKR1GoTVOC[1mERkOiS3y{XmOo[3SJTkGbV1GxTVi{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOCb3OIPYqKSECoZ{OTfXOIPYqMR2K{XmebNFyERXmZTFqkZnmKdF:4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mIcH2MR1GsZ1d6flmFNEmRV1KuXWe5fmqURYCKTIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[3OuWkClXFq2TVOTNmmZTYiQe{CMTVOC[1mERXeKR1GoTVOC[1mERXeKTECPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GsXUKpNXKueIqiXICtTVRx[3N{WnmkN2K6T1OTd2qYXkCNR1G4UFOCb3OIPYqMWIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GsZ1d6flmEd{mKTF5xZ325cHKq[3mZTFqkZnmKdF:4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mEVoObW2pxTVRx[3N{WnmkN2K6T1OTd2qYXkCNR1GsZ1d6fluVd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERV6EbVGoTVOC[1mERXeKR1GoTVOC[1mERXukS{m7TVRx[3N{VomkS{m7T1OTbnGJWoWiN16x[X2Wd1mEZ{eLfXt4SGGw[1mERXeKR1GoTVOC[1mERXeKR1GoZWe[c1mEVoejN12oTWRxPVmIXnijTF6tTVOs[3W4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GsXUKpNXKueIqiXICtTVRx[3N{WnmkN2K6T1OTbnGJWoWiN16x[X2Wd1mFRYOKR2K4ZkOOdF:4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mJNF6EbVGoTVOC[1mERXeKR1GoTVOC[1mERXu[NnhyZn21fnGZdHyKSECoZVeXOGqIWnqMR2KrZViXeXF{UoCmcWWxU4dxT1mERXeKR1GoTVOC[1mERXeKR1GoTVFxT1mERXeKR1GoTVOC[1mERXeKR1GoTVetcVuERXu[NnhyZn21fnGZdHyKSEB6TVSC[1uURkeFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVeLfWqYSoKQe{CMTVOC[1mERXeKR1GoTVOC[1mERXeKTECPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GsZ1eHfXNzWnuKR{R6TViPNWmvUkCkbXesZleXcXSEe3eOR4eoTlePc3SYOYKkNnx3XmOsO1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1qIfHybcmGoVGODfnSYToqlTFmwTle5cGqvVYOKR2KrZViXeXF{UoCmcWWoT4mDfnSJToObW{SwTXy5fWiIOHmMV3t4SGGw[1mERXeKR1GoTVOC[1mERkmFVX:oTVOC[1mERXeKR1GoTVOCUlOqRXeKR1GoTVOC[1mERXeKR2JzXWiKfFyVOXqjNkVxXmd2NFmFNHeLTFKpZ36PcGqFd16EbVGoTVOC[1mERXenVUCMTVOC[1mERXeKR1GoJku{PkF3PjK[W2K1ZWd2UXJz[ICj[{1:Jku{PkFxNkh7JlOob1qiW2moT1OHUmmY[HyQboCwXme5e2qZTX:LNkFx[GiLbXK6PYCjcWq3TomseGCu[HylSlqtXkB2bHKYWX:MV3uo[YewTlOScICbbVGwWGeHcmqVc{[bNmZxWUOTenOuWlSjNkWuZWekc1pzNUClXFqqZol6cXGZToqlS163Zn2bdGq6Z4CRWEC4T2ODO1Oob1qEVXuMR2GsTlOUVkClXFqqZkODbHSI[3eRV1KPXWelcF:rdH6bXGKV[Fd6fWqWUo[jcWqxXomocnKZVkGkcVq3UEOTNXOuTo[kS1ZxZVOkdF:4c1qEVXuLTliLenJ{VXeRV1KPXWelcF:rdH6bXGKEXWiPcGKIcImMR3u2Vl[OeVqJVkGkcVq3Z1eHNHGFd1uEVXuLR2OTNHGIcIqNWEWnXleXd2[JTnybV3esZ316enSEe3eLTFq3ZkOSdF:4c1qEVXuLR3esTlOSb3ujcUlxZWebdGlzSkCiW{m2TVRx[2SYSn6bWH93XkKXNGSYPXubW4ewTkKHb3KYcIWVcUlxZWebdGlzSkCiW{m2UEKteWmuPUSLfXt4R3esTlOSb3ujcUlxXnmCPVmISomkcVZ2T1OCT1OSb1qEVXuvZWiP[nOuWnibR3N6VHqCd1mCc1qEVXuLR2Olb2mZVnyZNl[sXleXb1q7NDubS1ZxXmOocmeUNYSNW2GoV1SxdF:vUX6MV4eoR3esTlOSb1qLN16t[H2XfXGZVkWLfkBsUlO4[1Oob1qEVXuLTkOXfXKEZ{mRbXSw[FiTe1:qPI[lN3R{UH2HfXSIcI[NcUWt[FN6eGmY[HyjcmK3UGeXOHSIWoWkNny3Zn6OenKUNUClXFqqZolybGlzUnyjS2[6XWiTenOqPH6NRX:LR2GsTlOU[ECiXGK{XmOkPWCqRl6[W3StU3qxc2qYfIebXFmwTkJyNHSZTnmjfXOxUGR2[mi6[36VW1[vXmd2NHK6Rl6XTG[6XX15[2eYPUGkbVK{ZWePcHKvUnyKS3ipZ4mDcHWJRoCkcW[sTomsd1Oob1qEVXuLTkKTcHNzUomiXFJxZWd6eVq7NDuKSUGpXkKWOl:ubHyjTFKtZ3mocnKZVkGkcVq3TomseGCtPX[MR3SPXWelcHKvVo[KSUGW[GiLbXK6RmqjN2[6TVe5dGlzWoW[NmWoZVeHflmIWkSkS3y6XmeSeVmGSoOjR1KrXWePc2qYVXekS1[vXmiO[3RzSoqKTFqtZmd6NmqYVX6MVX:LR2GsTluVd1uEVXuLR2OTeXJ{VoCbcXyrXWiTdHJzOISRclKpZ36PcFuISomkcVZ2T1OTeXJ{Vn2MV3t4R3esTlOSb1uEVXuL[mGwTlOZNFuEVXt:Jku{PkJ1PjK[W2pxXmiLWGmZXnyWTFq3XliXbnSCQU1jP4N7NUdzPjKEbVGoTVOCTnGYXXeMSUGpXkKWOl:ubHyjTFKtZ3mocnKZVkGkcVq3UEKteWquPH6MV{BsXkKXNGWuWn6VcV[1XmOodFuURkeE[3uLR2VybGpzWU[QcXSt[FVyemqIWoOMR3S1[FiXfWmuPI[jNlq7XmiLNmqZTYmLfXu1VH2HcXSIWomWNlZzXm[DfXJzVkG[N2GwTlibbHOrRYCQe3:LR2hxT1mERXeKRXt:Jku{PkJ1PjK[cW[uZkOLcGVzSkKbWV6p[FeXcnJ{TkVjP4N7NUd3PjKEbVGoTVOCTnGYXXeMSUGpXkKWOl:ubHyjTFKtZ3mocnKZVkGkcVq3UEKteWquPH6MV{BsXkKXNGWuWn6VcV[1XmOodFuURkeE[3uLR2VybGpzWU[QcXSt[FVyemqIWoOMR3S1[FiXfWmuPI[jNlq7XmiLNmqZTYmLfXu1VH2LcGquPYmbWl6p[H2XSGmZVnybNkm6[WOob3SuSomOR3t4R3esTn[Sc3eKR1GoR2F:QTJ8d{pzOEpjXWebNGqZTmS[XGqtVUKHNGqY[I[kcnt:Jku{PkF4NkpjR3mC[1mERVqiW2moT1VybGpzWU[QcXitZliDcHOq[36jXGJyZ32LelxzcIWbcUivT2NxL2pzWkCWcW[vWH2HeGqU[4CMV1J4R3esTlOWNXibNmV3U32lcHSGNY[bS2[{T1OleHSJWom[cUi3ZkKLfmqZTkKbXFm6TomseGCuSn2lS2[6WUKHNmqWUnilS2[vZkOLOVuEVkK[XFm4T2S{T1OScEmEbVGoTVOCTjJ8d{pzOEpjXWebNGqZTmS[XGqtVUJ6eHKYcECXXFq{Jku{PkF4OkpjR3mC[1mERVqiW2moT1VybGpzWU[QcXitZliDcHOq[36jXGJyZ32LelxzcIWbcUivT2NxL2pzWkCWcW[vWH2HeGqU[4CMV1J4R3esTlOWNXibNmV3U32lcHSGNY[bS2[{T1OleHSJWom[cUi3ZkKLfmqZTkKbXFm6TomseGCuSn2lS2[6WUKHNmqWUo[jW{Gx[F[XfXKE[3ulcV[6UVOsO1Oob1qnVX:oTVOC[1OSQU1jP4N7NkR7JmmZWkCjNkGp[FetbmKIPUOjcYi3XWeSQTJ8d{pyOkh7JlOqRXeKR1GLZWe[[1uGNXibNmV3U32pcHKJRnykbXevZmiTNXOuTo[NNny2Xn15cluUNDubNmZxWX2XcmSuSoSbV3exT2ODO1Oob1qEWUGpXkKWOl:u[HylSUG3XleXd1uE[ISlTG[6XX15enJzToqbXFpzXmiKfVq6b4SRcVZy[Fd6eGmZVoC[NGK3[EJ2d3JzSnuMR3t4R3esTn[Sc3eKR1GoR2F:QTJ8d{pzOEpjXld6N3KufI[[W2KDZn2TTnKvUkC[W4i{Jku{PkV4OkpjSGGw[1mERXeKR1GoTVOTNmmZTYeYfXRyZ{KXfXKuSoSbV3SlTVRx[1q6Z{eFVX:oTVOC[1mERXeKR2JzXWiKe2e6[Ie[XF67[EJ6fWqE[HSKSECoTomkO1SSc3eKR1GoTVOC[1mEVkK[XFm4W4mlb3J{[IWjS{mpXlZ6dGqE[HSKSECoTlibbHOrTUeFVX:oTVOC[1mERXeKR2JzXWiKe2e6[H2iW4itTkFx[2CURX6jXGJyZ32Lelq7d16EbVGoTVOC[1mERXeLTGqpZ3qDZlpzUnilR3SlTVRx[1pzNUClXFqqZomkO1SSc3eKR1GoTVOC[1mEVkK[XFm4W4mle3OuPXuLNUCoVGOCcnKYSn6bW{VxZomkO1SSc3eKR1GoTVOC[1mCNFuKR1GoTVOC[1mERXulXFqxTVRx[3OISomkNm[n[GiLd1uGNXibNmV3U32lcHSGTnikNm[XZ324c1uUb{eFVX:oTVOC[1mERXeKR2JyZ324[2CURXulXFqxW4mlc3J{UkCLNUC2TliXfXGXd36kS1ZxZVOl[F:4NFuKR1GoTVOC[1mERXulXFq{TVRx[3SJToCjV3es[GiLd1yERX6NfXOxU4dxT1mERXeKR1GoTVOCb3SuSomOSoOvZ{KtNGqU[HSKSECoTliXfXKFd16EbVGoTVOC[1mERXeLTGqpZ3qDZlpzcIeLNUCoVGOCb2hyUl[WcGqHWXy{cmVxWmOXb2[UXECHSWKHTX6ZWIOPR3mC[1mERXeKR1GoJku{PkF3PjKbS{l{Zn25emmYVmG[W3StJku{PkN6NkpjSGGw[1mERXeEW3yuTVOpUmmY[HyQboCwXme5e2qZTX:LNkFx[GiLbXK6PYCjcWq3TomseGCu[HylSlqtXkB2bHKYWX:MV3uo[YdxT1mERXeKRXuPR3mC[1mERVqEV2K4XWiTc1mFNHeLTGqpZ3qCeGCuUombW1ZxXm[DbHSI[3:MWIOPR3mC[1mERVqEV2JyZ324[2CURXulcV[6UVNxL2pzWkCTS{l{Zn25emmYVm[kcYiZZWiTc2SuPVS[W16wXmOodF:4NFuFVX:oTVOC[1OSb3uiTGK1ZlOCPVmIXoCjS2[nXkKXNGhzUo[jcmKtZn6TfluEVkGkcYexU4dxT1mERXeKRXuLTlepNHKYe4WRV1GqVFOGeFyURXmKR{SoZn16N1uEb3eNbVGqTVNxeGCqTUeFVX:oTVOC[1OScH2iW4itXEODNXSHPXqjNkVxXmd2NHO6[3ukS1ZxZVO4[1qIbECjW4exU4dxT1mERXeKRXuLSGGw[1mERXeEXECPR3mC[1mERVpjP4N7NUZ7JnGYOXubXHiDXUOTdHJzOE1jP4N7OURxPjKFVX:LR2etcVmEbF6[W3StU3qxc2qYfIebXFmwTkJyNHSZTnmjfUmxZn2belq6b4SRcXSt[F[LcGpxOXijW2WwT2Os[3W4NFuEVXuLTlibbHOrRYSRclqtXlOocnKZVkGkcVq3UEKHb3KYcIWiTGK1ZlZ6eHSJWom[cUi3ZWd2b2qZ[36MWIOPR3esTn[URnyjTF6tTVi{UlOob1qEVUCMR2GsTlqINY[bS2[{TVRx[2SYSn6bWH93XkKXNGSYPXubW4ewTkJyNHSZTnmjfUm1[FiXfWmuPH6MV{BsXUK5cGmZTlKjS4iSXWelcHO6[4CQe{CMR2GsTlSSc1qEVXus[H2HfV2ENDubNmZxWX2XfnOIPYWkNmWwT2NxL3NzWkCUS2[pXleXfVuE[FmXSmKSUIqGeV2UZ4OLfmG4UYmDS3J{TnmiW2KsXmd1cluVd16E[3uLR2OTNmmZTYeNWEWvXmiTV2qZUoejNkW7XmOodFyVOYqbXGKEZkKTOVuERXulcV[6UVNxL3R{TnikR3iPXWelcF:rdH:bW4i4XmiKc1pzNUClXFqqZomkdFyVOX[ZfXevTV[lfXJzOX6KS4ixXUKXeXNzWXelTHy4XmO4[3KIcHqbW{W7XmODbnJzVnykfVKpZ32W[3KuPUCKS{Gp[FePc3GYOX6KTGKwZWiO[3GIPYqlR{SvT2OsdF:4NFuEVXx6SGGwTlOSQU1jP4N7NUZ7JnN{cIW[Nni6ZkJ2dHWuWU1jP4N7NkdzOEpjSGGw[1mERXeEVUCMTVOC[1mCb3ukTFqt[H2tcHRxSomkcVZ2TVRx[1qJXnikblG1VH2lcHSHRombXGqxXmilSGmZVnybNkm6[WWtb3O6[4CQe{CMTVOC[1mCb3ukTFqt[H2tcHS6RUmKS3y1Z1e5emqIWX:LfYevUFOCb3OJTnylcXyt[ECHfXOuSkWMWIOPR3mC[1mERVqiW2moT1OTe3OuWkKiW2Z{VGRxe1uURXukTFqt[H2tcHS6RUmKR3O1UWOkO1SSc16EbVGoTVOCTlqIcIW[NohyXleXTXJzNXykS1[vXmOCPVmEVkK[XFm4UGR2c3JzNXykS1[vXmWtfmOYOXqjTG[sXmeSc1uURX2LbVGwTWOTNmmZTYqMWIOPR3mC[1mERVqFVX:oTVOC[1OUVoilW2[6[WWpenKURUmKR3OvU4dxT1mERXeKRXyuZkOLcGmYUn:KR3es[H2HfV6ERnikfVGsZ{OTenOuWlqbR3uo[YdxT1mERXeKRXuLTliHNWqZTkWUS{m1TVN1PVmETlqVcF6HWXyS[2OWOWWVfVKoZmiTNXOuTo[[R1GwXViPNHJ{TnyZNnysXVO4[2mJTnykXG[tZ{OT[nOISkCiS1GxTV[bRmSHWl[WfVGwTXl1b3N{Vo[kcW[LXlN1bVyERX6NfXOxU4mCbV:4NFuKR1GoTVGtPVSSc3eKR1GoR2FxT1mERXeKRXusZ2iXcHOvcFmjNkGGXme[[2CURXmUWUWVVm[LWVmGcF:XSUioXVdyNHSZTnmjNlGoT1eDfnSIPYmbWkmxXleCd1mIRombXFZyXmiPNGh{RnilS3ioT2ODW2GWfG[TWl2oT1SCd1mEZ4[LfXt4TVOKO1SSc3eKR1GoR2FxT1mERXeKRXusZ2iXcHOvcFqjcl2oVGOCbWOWOWSTWlqWTVWtU2[GPHe[S{Fx[GiLbXJzRXeMS1JyZ325[nOuWkOkcXxxXmZ6dGqIRYOKS1K7[Fd6fWqXPYCbS1G{TVeDbmmZVnybNkm6[WZ6dGqIRYOKS1K4Z316b3SYUkCZNnysXVO4[2mJTnykXG[tZ{OT[nOISkCiS1GxSGGwTlOSb1qKR1GoTVODWGKWfF[SNWGoXViXfXKHPYmbXHS6ZWiTcGhzcHu[R4eoXViPNHJ{TnyZNnysXVO4[2mIUnilS2[vZkOLOWhzcHu[R4eoXViDfXJzVkG[N2KnZWeT[1yERnekcW[5[GeXfnSHPYe[XGKwXVFxT1OSb1qEV1GoTVOC[2KtTmCVV1KoXUJ6fWqXPUGkcYinZ32XN3OucECbW1GPR3esTlOSb3eKR1GoTV[lTWKXTl[KRUCMR2GsTlOURXeKR1GoTVOCc1SSc1qEVXuLTVOC[1mERXeKR1GoT1eDbmmZVnybNkm6[WZ6dGqIRXeUWUSoT1OK[1yqRXukTFqt[H2tcHS6RXeNbVGqT2ODRmSsVXe[TFK6ZkKTNWl{Vn[iW2KoTVWtWFmGOW[VSYexSGGwTlOSb1qKR1GoTVOC[1mEb3mN[{CMTVOC[1mCb1qEVXuoTVOCc1uEVkK[XFm5TVOGPVmEZ36MV1FwTVOLRmSsVXeMS1K7[Fd6fWqXPYCbS1GoWHt6WVmGcF:KR3eqTVN1[1qJXnikblWoUHmCbVuUb3mKSH:oTXmKdFSSc1qEVXuLTVOC[1mERXeKR{SqVWV2SVSSc3eKR1GoTVOCTlOSb1qKR1GoT1FxT1mERXeKR1GoR2GsTlOURXeKR1GoT1eDfWqZSkGbXF5xXEODbHSIbHeKSUWRWlODTmSqRX:WNG[OVmWPWVmIRombXFZyXmiPNGh{RnilS3ioTVWbV2RxNHe[S{Fx[GiLbXJzRYCMVUCMTVOC[1mERXeEVXuLR2OC[1mEb3mQe{CMTVOC[1mCb16EbVGoTVOCTlqJSkGbXFp2VleXd1mFNHeKb2KHWFWXWWKURleWb{mPTVeDeHSJWom[cUmoTV[lTWKXTl[KS1K6XmiHNWqZUkCZN1Kp[Fep[1mGcF:KRUCMTVOC[1mCb3eKR1GoTVOC[1mERXeKR1GoTVOC[1uERmSTWYiHVUGS[2mJTnykXG[tZ{OT[nOISkCiS1GoSGGw[1mERXeEV1GoTVOC[1mERXeKR1GoTVOC[1mERXeKSWqUWEBx[1mERne[Nkm6XmZ6NXOufH[kcWZ{Z32tNGqYRV6EbVGoTVOCTlmERXeKR1GoTVOC[1mERXeKR1GoTVOC[2ZxbF[Wb2WoTVOp[2lzSkCbW3S3Z36t[nGYVneKSUWRWlODTmSqRX:KbUSoTliDfWqZXoCbXHOoTVN1[1mqb3eSWUWGTVeDe3OuPXulW15xXEKtb2mERlqWfVKQWmW5UVuURYCKboOPR3mC[1mERVqFVX:oTVOC[1OUVoilW2[6[WWTcHKGbI[jV1F6TVOLSWKWfF[XSWWoVnyLVGSURnejXGJyZ32LemmERmiUSW[UVmOD[3OuWoilW2[7[FZ6e2mZVn:[SECvUImkO1mrd16E[{CMTVOC[1mCb3u[Nkm2Zn2XbnSIcI[jbVF6TVVybGpzWU[QcXSt[F[PdHKu[IObXGK3ZnmocmlzPYmbV{m6XmiPenSZTnqbV3OxUGR2cmqZVlSjNkW2XmePNHGYPYWMR3SrZkOLcGh{[ImiXGKtTomsO1SSc16EbVGoTVOCTnSJTkWKTIOPR3mC[1mERVqEVUCMTVOC[1mCb1qLS163Zn12cGl{VoCjNkS1VH6HNWqZTkWMR1qVWlWHV2[ERmWWb1[QWUCHSG[GcGCVbVmxU4dxT1mERXeKRXuLSGGw[1mERXeEVXyxXnmCc1qIcIW[NohyXleXTXJzNXykS1[vXmOs[1qIUo[jcUWtXUOTdHJzOISRclZyXmiLOVuEVoilW2[6[WWpenKUb{eFVX:oTVOC[1OScICbbVGwTleteWlzfEGbS2[KZkJycHOISn6bV1GuTnmCb3SuSomOR{BsXkKXNGSZWoOlS3y7[Fd6fWqZXoCbXHOwT2Os[1qIUo[jcUWtXUOTdHJzOISRclZyXmiLOVuEVoilW2[6[WWpenKWVnybbXt4SGGw[1mERXeEVXusXUJ6eXKuWnqlS3y3ZnlxL3OZWnykcnuwTliHNWqZTkWUW{W7T2S{[1mCNFuKR1GoTVGsTlSSc3eKR1GoR2GtdGqqRX:KV2KxZn2Pd3SYVnyUS{m1XmiDbGpzWYCKR2KrZkJ2eWqYUkCiW{m2UGR2fHSYWommV3esZ2iXcHOvcFWbW4iKZkJxdF:4NFuKR1GoTVGsTlqIUo[jcUWtXUOTdHJzOISRclZyXmiLOVuEVoilW2[6[WWTcHKEb{eFVX:PR3mC[1mERVqnV1KrXWiTbnGERX:TXHirXmiDNHGYPYWKR2KtT2ODO1SSc3eKR1GoR2Gsb2lzPYWjcW[r[FetenKqNDukXG[tZ36sc1mtTmCVSYiEVWWPUFmqb{eFVX:oTVOC[1OScECiTFq3[ImCb2qVd16EbVGoTVOCTn[SNFuKR1GoTVGsUlOqRXeKR1GLTlePenKuOXy[N2KxZkJ1eGCvSkGbXFp2T1OLSGRxNV6UWmGqT2S{UlOqRXeKR1GLSGGw[1mERXeEVU1:Jku:
1
+ ZUpyOEq8d{pzNEpjXEKPc2qYUoKVS3yrXmd2bmqSQU1jP4N7N{R5PjKFVX:LR2etcVmE[3iVW1[vXmSwOnGIWoOkS2[6T1OleHSJWom[cUi3ZWd2cXK6Z4CNWEWvXmiTV2qY[F:[W{GtT1OsPWCU[IKkcmK{ZUKHdnOrVX6MV1J4SGGwTlOSb3uiW{WuZomCPVmGNXibNmV3U32pcHKJRnykbXevZmiTNXOuTo[NNny2Xn15cluUNDubNmZxWX2XcmOYOX2jfXexU4dxT1OSb1qLTGqpZ3qCeGCu[HylSl6tZ4modFyVOXibS2KZXWiLeXGYOX6MR2KxZn2belyVOYSbXF67XWelcFuVd1qFVX:LR2Gsb3SuSomOR{BsZ32Xb1uEZ4GNfX:3ZWd2b2qZ[36MWIOPR3esTlOZTnylTG[6ZnmDcWmYfIqbWIOPR3esTlOSNFuEVXx6TVeXd3NzWXeme{CMR2GsTnOuWkClXFq2TViTfXSYWUeFVX:LR2hxUlOob1pjP4N7NUZ7JnN{cIqlS2[1VUKpcGlzd{1jP4N7N{V3PjKEbVGoTVOCTlOUVnqjN1J2Z32tcnGJVXeRV1Gs[H2HfV2ENDubNmZxVUJ6e3WZToCbNnhxT1OsO1OqRXeKR1GLR2OTNmmZTYeNWEW7XmiTSHJ{RkWkcXyvZViSc1qIUo[kTHy6ZWelc3SEOH6RS1q6TVN5L2SYSn6bW{VxZomDWXSZTnmjfVKFXWePc2qURVuKR1GoTVGsTlOWVnyjW{ioXX6s[2CISXeiTFqtXnpxbXGJVkCkSH:3UEOlN3S6OXikcmKxZol2eWqZVY[jW1[vXmd2NHK6NXymTGKtZn6PdHJzOYqNNkC1[FiXfWmuPIS[W16rXme5cHOuSkCjN1mqTViTdHSIfHyRV1qPWliXfWmuPHeSW16rXme5cHOuSkCjN1mqVHew[1mERXeEVXuLWGeHcmqYOUCjfVK7Z1eXcGqFe4[[WESo[GiC[2mvb3eSWlqWV2V5cluVd1uKR1GoTVGsTjJ8d{pzNEpjXUKpcGlzeGObXF64ZkJ2fmqSQU1jP4N7Nkh{NkpjSGGw[1mERXeKR1GoTVOC[1mCcICbbVGwTlibbHOrRYCKTIOPR3mC[1mERXeKR1GoTVOC[1OSb16EbVGoTVOC[1mERXeKR1GoR2Gsb3SuSomOfUBsXEOLcGpxcIWbcUi1VH2PemqIWXeRV1KxZn6TNmmYe3:kN2[qZ{OTfVuEVkK[XFm5W4qD[FyERYeNR1Gs[H2HfV2Eb4CQe{CMTVOC[1mERXeKR1GoTVOCTlOYcH2MR1KxZnx6bHOvTnimV3es[H2HfV26NDuZN1qtXkCteWquPISRcV63XleWd1mISomkcVZ2T1SGe1yFTYeNSF24UFSSe1uUb3eMV1J4SGGw[1mERXeKR1GoTVOC[1mCb1qEVUCMTVOC[1mERXeKR1GoTVOCTlOScICbbVGwXUJ6NXKvVX:LTGqpZ3qGdFmFOEmKSF2xTVi{UlOqRXeKR1GoTVOC[1mERXeEVXuLR2FxT1mERXeKR1GoTVOC[1mERVqEVXuLUIl5[2WISomkNmWo[FepcFmIVnilS2WPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR2KsXWiTcFmFNHekN2K6XEOLcHOIfHi[NmWwTol1clyERX6NfXO{TViTfXGYNH:LTGqpZ3qHZl2XNICMWIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR2JzXWiKflyVOX[kcW[vV2d2cXK6NDubS1ZxXmOCPVmGNXibNmV3U32pcHKJRnykbXevXUJ6fWqUZ4CNWEWuZkOLeGmZVlW[XGKtT1OTb2mZVnyMWIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKRUCMTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeNfUioWVeHfXNzWXelS3itTVd2bHKYWV6EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mEVkK[XFm7UGR2[nOuWn6UW{WuZolxL3KuSoSbV1F6TViTfXGYNH:LTGqpZ3qHZl2tNICQe{CMTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERY[NfVKSXWiLfmqURkCiS2WoXUJ6eHOISoWmVUCMTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeLTGqpZ3qOeGCtPYmbW3SLZn2belyVOXqjNkG4XWd2OVmFNHeiXF67XmiSc1qJXnikbl[jUUFxdFmFPHelTFqxZmOob3SuSomOWoO7XGOs[1:qRX6LfoOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKRUCMTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeiW2moT1OTNmmZTYqNWEWnZ32XcmOYOX2jfUBsXUJ6b2qURUmRV1G5UVOs[3W4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1OUVkK[XFm7UGR2[nOuWn6UW{WuZolxL3KYWoqkNl[vXmOCPVmEVkK[XFm7UGR2[mi6[36VNIOvT2S{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVhx[2qYfIqbV1KxXnmCc1qJXnikbl21VHx6fWqY[FqjcWq3UGR2bnJzVnyKSEB6TVSKe1uURkeFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTlibbHOrUYSRclqpZWiPcGSuPUCiW16tT1SGe12Ee3eLTGqpZ3qOeGCtPX[MR3SLWHubVGhyWmGTNVqDVlWX[mSGcFSTWUWVVmZ6SmeHRlqWb2[GTomsdF:4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[3[URnyjTF6tTVetcVmE[3ulcV[6UYlxL2h{TnybNHy2Xn15eGCuUo[bS2WoVGRx[127RYCKTIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOCb3SuSomOfUBsZ32HdHNzWl:jN2KxXUKWc12VRYeNR1Gs[H2HfV26NDuZNUiwTkCtU2KsPX[XWlKJWXuHSWKXPV:VNWKnVWWPWWOXXl[LfXuxU4dxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mEVkK[XFm7UGR2[nOuWn6UW{WuZolxL2qISkCbV1F6TVOTNmmZTYqNWEWnXImocmSuPUCKS1[r[FetNmmZVnybR1J2XmiScluVd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mJNHebW4i7XmODdGqqRX:LTGqpZ3qOeGCtPYmbW3SLZn2belyVOXqjNmKtTVRxPVmFVYeMV1J4SGGw[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GLTVOTNmmZTYqNWEW6XWetfmqWOY[lS3yrXmOofF2FRYOKR2JzXWiKflyVOX[ZfXevVlV6UmGWcF:KSWKRVm[O[2SsPWWKSUGDWlWPTVq6b4CQfVGoTVOC[1mERV6EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mJNF6EbVGoTVOC[1mERXeKR1GoR2GsTlOSNFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1J6TVeXd3NzWXeme{CMTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOCTlqJXnikbl21VH6LbHGZUnyVcUlxZWePcFuFSYeOR4eoTlibbHOrUYSRcEmnT1OlSmWtTmCWcEmUVmWl[mFxbF[SNISnVnuHTmSEZ4CMWIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[3[SNFuKR1GoTVOC[1mERXeKR1GLR2GsUlOqRXeKR1GoTVOC[1mERXeEVXx6TVeXd3NzWXeiW2mwTVOTNmmZTYqNWEWnZ32XcmOYOX2jfUBsXUJ6b2qURUmRV1F2UVOCdFmJd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTlibbHOrUYSRclqpZWiPcGSuPUCiW16tT1SGe12Ee3eLTGqpZ3qOeGCtPX[MR3SHWXyLVGWtPVWVNXSQWFV6RmKHPVqTSkmQWEGT[mKsPW[Vb2GvT2OsO1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[3[URnyjTF6tTVi{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOCTlqJXnikbl21VHx6fWqY[FqjcWq3UGR2bnJzVnyKSEB6TVNxfF:4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mCb3ulcV[6UYlxL3OuSoCkNm[QZkOTdGlzWX:OWFG4UFOCb3SuSomOfUBsXEF5c1pxWmOWb{mUXEGLSmJyPVSUSW[FV{F6S2GWcF2LfXuxU4dxT1mERXeKR1GoTVOC[1mERVqEXECPR3mC[1mERXeKR1GoTVOC[1OSb16EbVGoTVOC[1mERXeKR1GoR2hx[2qYfIqbV1J4SGGw[1mERXeKR1GoTVOC[1mCb1qLTGqpZ3qOeGCvTniiXF6tWH16NHGYUnyMSFW4UVO4[1qJXnikbl21VHx6[luE[F[WcFqRWXx6V2KW[H[SNHiHVUC1[mKsSlqVR3OxT2S{UlOqRXeKR1GoTVOC[1mERXeEXECPR3mC[1mERVqEVU1:Jku{PkF3PjKWS{m7[F[LcHOZWnykN2F:Jku{PkV{OkB7JlSSc3eKR1GoTVOC[1mIcH2MR1KxZ{F6bHOvTnimV3es[H2HfV6Eb3eLbWmoXUJ6NXKvVX:LTGqpZ3qSdFmFOHeOR1GxTVi{UlOqRXeKR1GoTVOC[1mERXeKR{i3TVebenOuNXilR1G1UGR1[3SIWoqlSFV6XWObNGqZUkCObkGqTVeXNGm6OF6EbVGoTVOC[1mERXeKR1GoTVOTNmmZTYeKSECoXWiLfWmZb3:MWIOPR3mC[1mERXeKR1GoTVOC[1mJ[H:iW4itT1ODd3GZUkCMR2K2UFOCb3Sqb3eRV1KtXWePc1uEVkK[XFlxT2OCdFmJd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXulcV[6UV[1[FmFNHeKbWK2VGOTNlmrd16EbVGoTVOC[1mERXeKR1GoTVhx[1mERXeFVX:oTVOC[1mERXeKR1GoTVOCb3SuSomOR1F6TVeteHOIfI[bS2WwTom[clyERXulcV[6UVOsO1SSc3eKR1GoTVOC[1mERXeKR1GsXUJ6eXSIWoWlSmJ2Z1eW[2CURXmSNkm2[FeXeXSENUCmXFKtU3mDbHOJRoOiW16p[FetenKqPUSNXHR{[IlycXJ{ToSNXG[6ZleXeWlzPXubW2KkZ3y5eVmrd16EbVGoTVOC[1mERXenVUCMTVOC[1mERXeKR1KtZliPcFmJd16EbVGoTVOC[1mERXeKR1GoTVOTNmmZTYeKSECoTlibbHOrVUeFVX:oTVOC[1mERXeKR1GoTVOCb2lzPYWlS2[2[F[TOXOIWXeRV1GqVUJ6eXSIWoWlR{Fx[WiDcF:qRkCbXHhxUEOpeHKHfImZS{SqU4dxT1mERXeKR1GoTVODPVSSc3eKR1GoTVOC[1mCNFuKR1GoTVOC[1mERoCbbXeoZWiP[nKvWoOjR3es[H2HfV26b3eMV1J4SGGw[1mERXeKR1GoTVGsb3SuSomOfVF6TVVybGpzWU[QcXSt[F[PNHJ{TnySNkm2Xn2tcluETkObW1m3[Gd2fmqYUkGkcWW3XX2HfmqXPUGkcYeqT2S{UlOqRXeKR1GoTVOC[1mERXeKR2JzXWiKflmFNHekN2K6XEOLcHOIfHi[NmWwTol6dHKuVnymR{W4ZViCemmYVoSiW{SvUFOCclq6e3eLTGqpZ3qOdF:4NFuKR1GoTVOC[1mERXeKR1GoTlibbHOrUXeRV1K7[FiL[nOuWoejS1[rXmOoclxzcIWbS2Z1UH6Dc3OEPH6NR1GvTom4[1qJXnikbl2xU4dxT1mERXeKR1GoTVODPVSSc3eKR1GoTVFxT1mERXeKR1GoTVOCely6Roe[XFq7XmODNHGIWXebNnxzXmd1[2[XTl2FVX:oTVOC[1mERXeKR2JzXWiKfVmFNHekS1[6Z{KX[nSZToOMR2JzXWiKfVuVd16EbVGoTVOC[1mERXeiW2mwTVOHdHN{UnylR3es[H2HfV2td36kNl6wXmdycFpyNICKTIh5TVOob3SuSomOcIOvZ{KPc2qYNXyLNUCoTWRx[1pzbEClTFGvT2OCdFmJd3eFVX:oTVOC[1mERXeKR1GoTVODfWqZVkGkcUSoXn2Hd3NzWUeFVX:oTVOC[1mERXeKTECPR3mC[1mERXeFVX:oTVOC[1mERXeKR{i3TVeXOHSJTni[N2GoZVd6fnSERnijcWGoZ1eHNHGFc16EbVGoTVOC[1mERXeLS3i3Z{OS[2CURXulcV[6UXy{cnGIPYqlR3SlU4dxT1mERXeKR1GoTVOCb3OISkCiR1F6TVetfnNzWkCMR2JzXWiKfWe6[Ie[XGKwTkFxdFmFPHeLTGqpZ3qLZlp{RnilS3evXGOCOlmEZ4[LfoOPR3mC[1mERXeFVX:oTVOC[1mERXeKR{i3TVd6e2qYOHe[V1K7ZkKPdmqZVXe[Nkm2Zn2XbnSIcI[jbVK3ZnmDe3J{TkCKSHe4SGGw[1mERXeKR1GoTVOTcHOvToWjfVF6TVd2NXKIe{eFVX:oTVOC[1mERXeKR2KtZ36LfnSJTXeRV1K2[Ge5d1:4NFuKR1GoTVOC[1mERXubclGoVGODRWqvUo[[NoS3Z1eXeVuEVn:jN15xUFOCOF2Ee3eLS2[6Z312elyERXubXFq6Z{OTfVyERUGMWIOPR3mC[1mERXeKR1GoZWe[c1mEVn2kR1F6VGRx[2quSoOkNmWoT2ODO1SSc3eKR1GoTVOC[1mERXeKR1K6XmiTNXOuOHebcV[{Z{KWO1SSc3eKR1GoTVOC[1mJNF6EbVGoTVOC[1mERXeFVX:oTVOC[1mERXeKS3yuTVOobHGZUn[jcm[{ZlOob3SuSomPbXuxTVi{UlOqRXeKR1GoTVOC[1mERXeKR2JzXWiKNlmFNHeKcG[7XmiKeGGY[HyjcmF3TVOKeVqJXnikbmm2TXy5fWiIOHmQe{CMTVOC[1mERXeKR1J6SGGw[1mERXeKRUCMTVOC[1mERXeKR1G3UImDfmqYOXuKTGKwXmODfWqZSkGbXF5xSGGw[1mERXeKR1GoTVetcVmE[3ulcV[6UmOCPWCURX6kS{m7[FOkdFmJd16EbVGoTVOC[1mERXeKR1GoTVebe3SZVoqMR2KuZ1O4[1mtRmCWNWGoTliDbHSI[3eUSmKWWVN5fFyrSnOkcIi2TXmsO1SSc3eKR1GoTVOC[1mERXeKR1KxXnmCc1mYcIqZNkVyZle4c1qJXnikbmmxT2ODO1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[2qvRkGlTF2wTlebe1yERXulcV[6UnmsO1SSc3eKR1GoTVOC[1mERXeKR1J6SGGw[1mERXeKR1GoTVOC[1mERn2kTGZxZ4mob2qvRYOKR1qKZkOPNF:qRXuiS{m7[F[5fWiIOHmMWIOPR3mC[1mERXeKR1GoTVOC[1mIXoelXGK7T1OTcXOEe3eKcFqtXn2XfWqZTU[KR2JzXWiKfmiJTnOjbVmxU4dxT1mERXeKR1GoTVOC[1mERXebclJy[FiOc1qIXoeNR1GsXUJ6eXSIWoWlSmJ2Z1eWdF:4NFuKR1GoTVOC[1mERXeKR1GoXn6DNXSJUX:LS2q4UFOCbWFzPYWlS2[2[FNyd2qYOX6lS3d3TVOKeVmJUkCkcYitZnmob3SuSomOR3uoUHmLZ3OtfIWKbXt4SGGw[1mERXeKR1GoTVOC[1mERn2kTGZxZ4mob2qvRYOKR1qFZkJ2eWqYUkCiW{m2U3mDbnKIPYqbWoi6XFd2Z3OtfIWKbXt4SGGw[1mERXeKR1GoTVOC[1mERn2kTGZxZ4mob2qvRYOKR2JzXWiKe1uVd16EbVGoTVOC[1mERXenVUCMTVOC[1mERXeKR1KtZliPcHGYXXeMR2JzXWiKNVmFNEmKR3SvXmiScluURkeFVX:oTVOC[1mERXeKR1GoTVOCb3OZWnykcnuoVGOCclq7d16EbVGoTVOC[1mERXeKR1GoTVetcVmEbICkN16t[FOob3SuSomOcIOvZ2iXcHOvb36ZV3uxTVi{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOCb3OZWnykcnuoVGOCcmC6Z4WLTGqpZ3qLZlp{SkGbXFp2TkFxO1SSc3eKR1GoTVOC[1mERXeKR1J6SGGw[1mERXeKR1GoTVOC[1mERn2kTGZxZ4mob2qvRYOKR1qJVm[S[3W6Voe[XGKw[mi{b3OZWnykcnx6TVWpWW[HRY[OV{S5XFiLZ3KqTYCQe{CMTVOC[1mERXeKR1GoTVOC[3GYXXeMR1[xZ{F6eXSYfIOMR2JzXWiKNluUb3eme{CMTVOC[1mERXeKR1GoTVOC[1mERXeKS2q4[GiTfluEVn2kR4eoTlibbHOrXYCQe{CMTVOC[1mERXeKR1GoTVOC[3[SNFuKR1GoTVOC[1mERXeKR1GoXn6DNXSJUX:LS2q4UFOCbWOIPYqlSH:oTlepenN{VnOkcIi2TXmsO1SSc3eKR1GoTVOC[1mERXeKR1KuZ1iXNHO6[3ubclG{TVOLSHJzOYWbW15xZWd6eV:qRnqjS{m7Xm[5fWiIOXOkcIi2TXmsO1SSc3eKR1GoTVOC[1mJNF6EbVGoTVOC[1SSc3eKR1GoTVOC[1mEVombXF5yZliS[2CURX6LfoOoSGGw[1mERXeKR1GoTVilc3GYfHyMR1[uXmd6cVuEVn2kR3uxTVi{UlOqRXeKR1GoTVOC[1mERXeKR{i3TViLcGlzWoClcWWo[FepcFmJTnykN2[{[FiO[3JzXXelS3itTViLcHOZWnykN2GPR3mC[1mERXeKR1GoTVOC[1mEVombXF5yZliS[1yrNHebcXSt[FiOc1qIXoeNR1G5UXqodF:4NFuKR1GoTVOC[1mERkmFVX:oTVOC[1mCNFuKR1GoTVOC[1mERY[NfVKrZld6fmqURkCiS2WoZ{J6bnFzWkCKS163Zn12cGl{VoCjNkR3SGGw[1mERXeKR1GoTVebbnKIPYqbV3esXn6CdF:4NFuKR1GoTVOCUlOqRXeKR1GoTVOC[1y6PHekN1K{ZWiS[3SIbHyKTFqtZ{OXd3SERn:bW1[sXmiK[2qvTo[jV1JxZVeW[2lzPYWlS2[2[FFxT1mERXeKR1GoTVOCb3OuWoqlW4hxTVRx[2qZbIejS{msXmOobWiJTnOjcIi6XFd1bVyERXukcW[7[Ge5NFyERYmMWIOPR3mC[1mERXeFVX:oTVOC[1mERXeKR2KwXmeHb2qZTXeRV1KxZ{OPcHSE[3ukcW[7[Ge5NGe7RnSMV1FwTVOTfWqZUkGjTGKjUVZx[1:qRX6LfoOPR3mC[1mERXeKR1GoTlePenKvVnyjcmGoVGODdHN{UnylR3esZ32XfnSYfECYfl[lT2OCM1mEVombXF5yZliTZl2XNHeQbVGvToq{UlOqRXeKR1GoTVOC[1SSc3eKR1GoTVOC[1mEVkK[XFm5TVRx[3KuWkOKTF5xXlWPd2mZUoqMR3t4SGGw[1mERXeKR1GoTVOTNmmZTYiNWEWwXmeHb2qZTXeRV1GsZVeXbGqIWomQe{CMTVOC[1mERXeKR1Gs[H2HfV2UNDu[Nkm2[FeXeXSERUmKR2KrZkJ2NGqYOUCQe{CMTVOC[1mERXeKR1GPR3mC[1mERXeKR1GoUIl5[2OISoWbS4itTVePc3SYOYKbW2Go[FiLbHKvUn2bXFmoZWe[[3KuWnybS2[sSGGw[1mERXeKR1GoTVetcVuERoqlTFq4ZkOOc3N{VomlS{m{ZkOlcHOq[3ulcV[6UWNxL3GIWnibS2[6T2O4[1p{Vom[W{W7Xn2XfVyYWoW[NkmsZWd2cl:qRnqiTG[2ZUKXb1q6b3eKWEB6TVebbHKJUnyKR3uo[YdxT1mERXeKR1GoTVOC[1mERXeLTFKpZ36PcGqERUmKR3OvU4dxT1mERXeKR1GoTVOC[1mERXeLS4itXn6S[2CURXulcV[6UWNxL2lzPYWlS2[2[FS{UlOqRXeKR1GoTVOC[1mERXeKRUCMTVOC[1mERXeKR1GoTVOC[3RzbICjS2WwTViTfXSYWXeMV1J4SGGw[1mERXeKR1GoTVOC[1mERXeKR1GoTliDenO6RUmKTF5xZ36DenO6[3ujS2[u[FO4[1mtfImZS{SqT2S{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVODdGqq[3eLTFK3Z4mCPWCVNHebcV[{Z{KW[1uURkeFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTViLcHSJWomjbVGs[H2HfV2Vd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERkmFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeLS16w[Gd2dnNzcE[bV1F6TViPNWmvUkCkbXesZleXcXSEe3eOR4eoTliDenO6b{eFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeLTFK3Z4mCdmCURoqlTFq{Xmd1c1mtfImZS{SqT2S{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOCb3KIWn2lR1F6TViPNWmvUkCkbXesZleXcXSEe3eLTFK3Z4msO1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1qJRo[kfVF6TViPNHOvRo[kfXesXUKpNXKueIqiXICtUFOCcl:6Z4CQe{CMTVOC[1mERXeKR1GoTVOC[1mERXeKS3yuT1OCb3OIPYqKR1V6VGODcWmYfIqbV1GxTVi{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeLS16w[Gd2dnNzcE[bV1F6TViPNWmvUkCkbXesXUKpNXKueIqiXICtUFOCe1yERXukS{m7T2S{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVODPVSSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1qIUn:lW{WzZ{KtOmqURUmKS3it[VeTcGm6[3u[NnhyZn21fnGZdHyMWIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GPR3mC[1mERXeKR1GoTVOC[1mERXeKR1KxXnmo[1qIUn:lW{WzZ{KtOmqURUmRV1G4TVOs[3W4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1KqZ32XbHG7d16EbVGoTVOC[1mERXeKR1GoTVOC[1mERkmFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeLTFKpZ36PcGqERYWRV1K7[GeLfnSJTX:LS4itXn6Sd1mFRYOKR2KrZViXeXF{UoCmcWWxU4dxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOTd2qYXkCKSECoZ{OXbXN{VomMR2K{XmebNFyERXu[NnhyZn21fnGZdHyKR4OoZ{OTfXKIWoWMR1qkZ3y5eVmqb4CQe{CMTVOC[1mERXeKR1GoTVOC[3[SNFuKR1GoTVOC[1mERXeKR1GoSGGw[1mERXeKR1GoTVOC[1mERXulcV[6UWNxL2lzPYWlS2[2[FOCPVmEVoe[XFq7XmeSO1SSc3eKR1GoTVOC[1mJNF6EbVGoTVOC[1mERXeKRU1:Jku{PkF3PjK[W2K1ZWd2UXJz[ICj[{1:Jku{PkFxOER7JlOob1qiW2moT1OHUmmY[HyQboCwXme5e2qZTX:LNkFx[GiLbXK6PYCjcWq3TomseGCu[HylSlqtXkB2bHKYWX:MWEB6TkK1fXSIfIK[W4S6UlOkdFmJd1uEVXuLZWe[[1uGNXibNmV3U32lcHSHUkCjN1qtVUJ6eWqucH6MR3S1[FiXfWmuPI[bcXy6Z{OTbnJzOX2iW3OvT2RxPV2Eb3eme3:LR2GsTlOob1qEVXus[FiXfWmuPYe[XGKwTVRx[2SYSn6bWH93XkKXNGV{Vo[kcW[FZkJ2cXGYZ3:LNkFx[GiLbXK6PUClXFqqZkODbHSI[36MWIOMR2GsTlOUVomjNklxTVRx[2SYSn6bWH93XkKXNGGuSoqbWWKxZ3modFysVmSNbWJx[GiLbXJ{RnilS3d4R3esTlOSb3ulcV[6UVNxL2hzVnyjSmK6XmeWc1qJTo[jN2G{TVOTfXJzPUCMWIOMR2GsTlOSc1qEVXuLTld2enSIcH2iW16p[FetenKqRUmKSUGpXkKWOl:u[HylSUG3XleXd1uE[HibS{GxZnt2enSIcH2iW16p[FetenKqPYCjcVq3[VOkdF:4c1qEVXuLTld2enSIXXeRV1KpZ36LbHWU[3eE[3uLR2GsTlpzcIqZN1qtXWeScmCVOIeNR1GMR2GsTlOSb36bS1ZxXmZ6bGqIVnybR3N6VH2TbHSIWX:LNXu1ZmNyb1mG[{[iWIC7Tomsd1mCc1qEVXuLR2OlfmqZXnykcXxx[WOkPWCrVYOKRX:LR2GsTlOU[EGkcYevVGR1cnGJVkCkSH:3UEOlN3S6OXikcmKxZol2eWqZVY[jW1[vXmd2NHK6NXymTGKtZn6PdHJzOYqNNkC1[FiXfWmuPIS[W16rXme5cHOuSkCjN1m3Tom4T1OSb1qEVXuv[FetNHKIWX6RWESoWGeHcmqVc{[iS2[{Z1eXfVuE[ISlTG[6XX15cluUNDuZNUiwTkBybGpzWoWlS{ioWG[TNXOuTo[KSny3[GiK[3KIcHqbW{W7XmODc2mZUXebXHi4ZWiLcGqEZ4CNRX:LR2GsTlOU[HubXF6rZ32te3SIcI[jbXN6VHmDUmmY[HyQboCwXme5e2qZTX:LNkFx[GiLbXK6Z4CNWEWnXImocmSYSn6bW{VxZomDUm[JWom[cUioW2d6NXOqRoOiW16tZn2PcFmIbHikfVKt[ViDdHOuWnuNbVKDZle4[2lzSnqiS2[sTViDbGpzWoqKTHSpZ4mDfWqYNY[lcW[sTomsT1OSb1qEV3t4R3esTlOSb3ujcUlxZWebdGlzSkCiW{m2UGR2e2mZToqbV3ipZ36LbHWU[3ujcUlxXnmsdF:4c1qEVXuLR3esTlOZNFuEVXx6R3esTjJ8d{pzOEpjXWebNGqZTmS[XGqtWViLemqJWnqlRU1:Jku{PkF4NkpjR3mC[1mERVqiW2moT1VybGpzWU[QcXitZliDcHOq[36jXGJyZ32LelxzcIWbcUivT2NxL2pzWkCWcW[vWH2HeGqU[4CMV1J4R3esTlOWNXibNmV3U32lcHSGNY[bS2[{T1OleHSJWom[cUi3ZkKLfmqZTkKbXFm6TomseGCuSn2lS2[6WUKHNmqXRomjNmJyXUOSc1qJXnikblGxU4ewTlOZNFuKR1GoTVGsQTJ8d{pzOEpjXX2XcXJ{TnyWNlZzXmWPbHSIWn6jN1p2Jku{PkF4OkpjR3mC[1mERVqiW2moT1VybGpzWU[QcXitZliDcHOq[36jXGJyZ32LelxzcIWbcUivT2NxL2pzWkCWcW[vWH2HeGqU[4CMV1J4R3esTlOWNXibNmV3U32lcHSGNY[bS2[{T1OleHSJWom[cUi3ZkKLfmqZTkKbXFm6TomseGCuTnybcUm6Xm[PbHSuWlS[XGKtXkJ6fXWU[3ulcV[6UVOsO1Oob1qnVX:oTVOC[1OSQU1jP4N7NkR7JmmYXkCbXFqVXWibcGFzSkCbW3S3Z36sQTJ8d{pyO{J7JlOqRXeKR1GLZWe[[1uGNXibNmV3U32pcHKJRnykbXevZmiTNXOuTo[NNny2Xn15cluUNDubNmZxWX2XcmSuSoSbV3exT2ODO1Oob1qEWUGpXkKWOl:u[HylSUG3XleXd1uE[ISlTG[6XX15enJzToqbXFpzXmiKfVq6b4SRcV[u[FeXfWVzSkKbWV6p[FeXcnJ{TkWMR2JzXWiKe1uVd1uEVXx6R3mC[1mERVpjP4N7NkR7JmmYXkCbXFqVXWibcGFzPYSjW3xxWmiLdzJ8d{pyO{Z7JlOqRXeKR1GLZWe[[1uGNXibNmV3U32pcHKJRnykbXevZmiTNXOuTo[NNny2Xn15cluUNDubNmZxWX2XcmSuSoSbV3exT2ODO1Oob1qEWUGpXkKWOl:u[HylSUG3XleXd1uE[ISlTG[6XX15enJzToqbXFpzXmiKfVq6b4SRcV[u[FeXfWVzSkKbWV63ZmdydHSHWomjR3es[H2HfV2Eb{eE[3uL[mGw[1mERXeEVU1:Jku{PkJ1PjK[XGZxZkJybHSIcHqTS{l{Zn25emmYVU1jP4N7NUZ5PjKEbVGoTVOCTnGYXXeMSUGpXkKWOl:ubHyjTFKtZ3mocnKZVkGkcVq3UEKteWquPH6MV{BsXkKXNGWuWn6VcV[1XmOodFuURkeE[3uLR2VybGpzWU[QcXSt[FVyemqIWoOMR3S1[FiXfWmuPI[jNlq7XmiLNmqZTYmLfXu1VH2HNXSIPYS[XGKxXUCTenRzOYOjNl[sT1OsO1Oob1qnVX:oTVOC[1OSQU1jP4N7NkR7JmqIPUOjcYi3XWeTRnKuVlqjcl5xXWe5dzJ8d{p2O{Z7JlSSc3eKR1GoTVOC[1mEVkK[XFm4W4mlNXNzWomjcV[1XmOl[FmFNHeLfXN4SGGw[1mERXeKR1GoTVOTNmmZTYeYfXS4XWiPfnRzPYmbR3SlTVRx[1q6Z{eFVX:oTVOC[1mERXeKR2JzXWiKe2e6[HujN3S2Zld6bGqHPYCbR3SlTVRx[1qJXnikbll4SGGw[1mERXeKR1GoTVOTNmmZTYeYfXSuZWe5cFpyNHeRV1GvZmiTNXOuTo[LfoOPR3mC[1mERXeKR1GoTlibbHOrRnKLNl6p[FOl[FmFNHeLNkFx[GiLbXK6Z{eFVX:oTVOC[1mERXeKR2JzXWiKe2e6[IekcUmsTkFx[2CURX6jW1[vXmd2NHK6Z{eFVX:oTVOC[1mERXeKRUCMTVOC[1mERXeKR1Gs[GiLdFmFNHekS1[6Z{KX[nSZToOMSUGpXkKWOl:u[HylSVqpZ{KXWnOue3:MV3t4SGGw[1mERXeKR1GoTVOTNXOue3eRV1Gs[GiLdGe6[H:jN15xTkFxeVqJWomiWoOvZ1eHNHGE[HSQe{CMTVOC[1mERXeKR1Gs[GiLd1mFNHelTFqxZmOob3SZToONR1GvUImkdF:4NFuKR1GoTVOC[1mERXulcV[6UV[{cnNzcECbV3SlTVRx[1qJWomjSIOPR3mC[1mERXeKR1GoTlibbHOrRnKLNny4TkFx[2CURXuZNV6HWXybSmWtd36WNG[UWnuXV2hxSlWTSlmvXGS{UlOqRXeKR1GoTVOC[zJ8d{pyOkpjXld6N3KufI[[W2KSXWelcDJ8d{p2OUZxPjKEVUCMTVOC[1mCcICbbVGwWGeHcmqVc{[iS2[{Z1eXfVuE[ISlTG[6XX15enGYOX2jfXOxUGR2cmqZVmObW3SQXWdycFuEb{mRV3SzZ36Td3FzSoKkbmGvT2ODO1SSc3eKR1GoR2FxT1mERXeKRXuLTlibbHOrUXeRV1GvToq{UlOqRXeKR1GLR2OTc3SINYOKSECoTomkO1SSc3eKR1GoR2GsUlOqRXeKR1GLR2etcVmE[3ulcV[6UlRxPVq6Z4CFVX:oTVOC[1OSb1qLTGqpZ3qS[2CURlKkcmKxZkF6Um[JWom[cUmnV1eXd3OIWomZNGKp[FeGOl:u[HylSV63Zn2bdGq6[4CNWEWvXmiTSXJ{[IWjS{mpXlVycHSIbI[bR3exU4dxT1SSc3eKR1GoR2GtdGqqRX:LTGqpZ3qKdFmCNFuKR1GoTVGsTnW4NFuKR1GoTVGsTlOUVoe[XGKwTVRx[1qJXnikblG1VH2PfWqYSkCbWlKp[Feoc1uVd16EbVGoTVOCTlOSb3ulXFq{TVRx[1qJXnikblG1VH2lcHSGVo[lNkW{ZkKHb2[ZToOXNnxxZVV2emFzSnqiS2WwT2S{UlOqRXeKR1GLR2hxUlOqRXeKR1GLR2eXd3NzWXeFVX:oTVOC[1OScEeFVX:oTVOC[1OSb1qLTG[6ZlOCPVmGNXibNmV3U32lcHSHWomjR3exU4dxT1OSb1qEV2JyZ324[2CURoqlTFqnZ32Xe3KISnqbV3eqXWeTeHGYOI[KbYeoTXmKd1mEVkGkcYexU4dxT1mERXeKRXuL[mFxT1mERXeKRXuLSGGw[1mERXeEVXxxZ36s[1SSc3eKR1GoR2GtO1SSc1qKR1GoTVGsTnN{[IClS16wTVOob3SuSomPR3uPR3es[1mERXeEVXx4SGGwTlmERXeKRXuLR2FxT1OURXeKR1GLR2Gsely6RmSlS1[2XleHfWqERn2iW4itTVelcHSERnqjNkVxXmd2NHO4NFuEV1GoTVOCTlOScHq[XF6tTVWTenRzOYOjNl[sWGeXNHGIPXukfn93VnutUWKXPViTWmKnVUB6U2[GWl:XSl13SGGwTlmERXeKRXuLR2GtdGqqRX:iW{WxXEKlcHSE[36[W4i{ZkOl[nSZToOZNmq3Z1eXeVq6b3eRWECoToqGcluSNFuEV1GoTVOCTlOSb1qEV2Kw[Fdyd1mFNHebcXy{XmZ6cmqZVn[[Nkm2[FeXeXSJUX:LTG[6ZlOsO1SSc1qKR1GoTVGsTlOScHyjTF6tTVFxT1OURXeKR1GLR2GsTlOUVkK[XFm7TVRx[1mGNXibNmV3U32pcHKJRnykbXevZmiTNXOuTo[LfXu1VHx6[luETmSbXGJxZWd2clmE[HijS4i3[EF6NXOufH[bcUm4Xmd1clmIcIqKS2KxZ{KHbXKIWnuNbVmxU4dxT1OURXeKR1GLR2GtbXOuWniifoOPR3es[1mERXeEVXuLSGGwTlmERXeKRXuLR2N5elmGVo[lNkW{ZkKHb1mIPUKbXFmoZ{J6bnFzWkCFVX:LTVOC[1mCb1qEW16pZ{KW[2KIPUOjcYi3XWeTUmqZVn:jNmK7U3qxWGRxUlyTWmF3R2GsTlSSc1qKR1GoTVGsTlOSb3ukcW[7[Ge5NGSvWoS[cW[6VGSCO1SSc1qKR1GoTVGsTlOSb3ulcV[6UYpxclq7d16E[{CMR2OC[1mERVqEVXuLTliLcHOZWnykN2GoVGODe3OuWn6ZN1qtZ1e5bGlzWX:LfUmw[FiTe1uJUYCmflG{UWhxOmiEPXONNYSmXFN6[FuqPH6NR1GvTom4[1qJWomjR3t4SGGwTlOSb1qEVXuPR3esTlOSb1qEV2K1XWiTbnGIWoqKSECoXWiLfWmZb3:MWIOPR3esTlOSb1qEXFK6Xmel[nKYSkC[NnewTkCD[VuFPE[iTGJxZ1Swely6bz:MSoSmUEFxdluWRoCLfYeoTliXfXKEe3eLS{Gp[FePc2qZUYCQe{CMR2GsTlOSb1qLS3i3Z{OS[2CURXujW1ZxXUKpcHNyd4iZWIOPR3esUlOob3eKR1GoR2GsTlOUVn2kR1F6TVebfnJzUoKjN1KtZnmob3GIPYqlR4eoU1SCd1mEVombXF5yZliTU3SYNXmbXFm{TVOTcHOvTo[kb{GtZ{OPbGpzWYCQe{CMR2OC[1mERVqEVXuLZWe[[1uESXubclGxSGGwTlmERXeKRXuLR2GtO1SSc1qKR1GoTVGsTlOSb1qLTGqpZ3qO[2CURXubXFq6ZkOLUmqZUoq[W3StU4dxT1OURXeKR1GLR2GsTn[SNFuEV1GoTVOCTlOSb1qbW4i7XmFxT1OURXeKR1GLR2GsTnW4NFuEV1GoTVOCTlOSb1qEV2K3[GiS[1mFNHeKb3SHWlOCb3OuWoilW2[7[FODTW[HVmGNflW2UW[5fWiIOHmQe{CMR2OC[1mERVqEVXuLR2OTenSZVXeNbkCoTXupenN{VU[KR2KwZkOPNGiJTnOjbVl4SGGwTlmERXeEV1GLR2GsTlOUVo[lXGGoUHpx[1msUo[jcUWtXUOTdHJzOE[KSV6{ZkOPcGiJTnOjbVl4SGGwTlmERXeEV1GLR2GsTlOUVo[lXGGoUHpx[1mtfImZS{SqU4dxT1OURXeKRXuoR2GsTlOScH2lN1qx[FeWc1qIXoeNR1GsZkOXNFuVd16E[3uoTVOCTlmCb1qEVXuLTlepcGmYVnykbVF6TVOLeXJ{VXemW2ZxTXq{UlOob3eKR1GoR2GsTlOScEOiS3y{XmOCc1mYXnyjNmmwTlebe1uUb16E[3uoTVOC[1OSb1qEVXx4SGGw[1mERXeKR1GoTVOC[1mERVqEVXuLR2OTd3GYOXyRW2qvXmiTfluEVn2kR4e5UXqodF:4NFuKR1GoTVOC[1mERXeKR1GoR2GsTlOScICbbVGwTle5dHKuWUmRV1qkZ3y5eVmqRX2LbVGsZVeXbGqIWomRWECqZn16NFmJcHylR1mxTVi{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOCTlOSb1qEV2KwXmeHb2qZTXeRV1GqZ1eHfnNzWnuKboOPR3mC[1mERXeKR1GoTVOC[1mCb1qEVXuL[mFxT1mERXeKR1GoTVOC[1mERXeEVXuLR2GtdGqqRX:LS3itXWeTcHOrNEmKclKpZ{OPcGqETYCKTIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GLR2GsTlOUVn:lS{G{UHpxb3KIcIWbWIOPR3mC[1mERXeKR1GoTVOC[1mCb1qEVXuL[mFxT1OURXeKR1GLR2GsTlOZNF6E[3uoTVOC[1OSb1qEVXyuXUK5enNzWX:LS2q4T2S{UlOob3eKR1GoR2GsTlSSc1qKR1GoTVGsTlOSb1qLS2qxZ36PNFmFNHekN2K6Z1d6fluEVn:lS{G{UFOCcmCESlWVNF6WW2[DSlq6b{eFVX:LTVOC[1mCb1qEVXuLTle5bHN{VXeKSECoZ{OTfXOIPYqMR1GsZViTeHKEe3eLfoe3ZViTeHKFOH6MV4N{U4dxT1OURXeKR1GLR2GsTlOUVn:lS{G{TVRx[3N{WnmkN2K6T1OTc3SINYONR1GsXn2tfXN{VYOKR2K{XWiPNFyUVn2iXFq7[FOsO1SSc1qKR1GoTVGsTlOSb1qEV1GoTVOCTlOSb16E[3uoTVOC[1OSb1qEXECPR3es[1mERXeEVXuLXX6LcGmYd{eFVX:LTVOC[1mCb1qEVUCMR2OC[1mERVqEVXu3UImDSXJ{[IWjS{mpXlODN3GZVn:KSlKKWVODSnWJVnyjcl6xZkJ1[2FyWmOVRUCMR2OC[1mERVqEVXyrXWiPcFmGVo[lNkW{ZkKHb2SYWkCiS{msZ4qwOmFyWmOVSH:PR3es[1mERXeEVXuLR2FxT1OURXeKR1GLR2GsTnGYXXeMS2pyZn2PNHGYPYWZNmZ1ZWiPNHO6[36[N2[6ZlZ6dHKucECLfXuxSGGwTlmERXeKRXuLR2GtO1SSc1qEVXuLR2GsTlqIUn:KSECoXUOXfXKHPYCjcXxxT1OTNXOue4CQe{CMR2GsTlOSb1qEW15yZ325[nNzWkCjN1JxT1OTbnGEe3eSNW[UWFV6VW[HPWWUWUGHWEGXWVyERYiOSFGxU4dxT1OSb1qEVXuLR2ePNXOufH[kNmZxZkODNFuEVnqiR4eoVUGXV2SGPWGXSkmIWEC5UWRy[F2VNF6DWlWtVGSqe3elTFpyXmOsO1SSc1qEVXuLR2GsTml{WomjSkm7XmiTenOJVX:LS16wUFODSG[XTl2VNVKWXEGLSm[HWmOVcGKUVWV2WGKsWmONR1JxZ36XcFuVd16E[3uLR2GsTlOSb3uiTGK1ZlOCPVmIUkGkcYinXmipcGm6[3u[NnexU4dxT1OSb1qEVXuLR2etcVmE[3uiTGK1ZlRxPWCYXnijTF6tT2FxT1OSb1qEVXuLR2Gsb3SuSomOfVF6TVePNXOufH[bXFq6ZkOKc1qIUn:MWIOPR3esTlOSb1qEVXyr[GiLd2hzUoOjN16tT1OTbnGEb{eFVX:LTVOC[1mCb1qEVXx6TVFxT1OURXeKR1GLR2GsTmqYfIqbV1GPR3es[1mERXeEVXuLR2i{UlOob3eKR1GoR2GsTlOSb3ulcV[6UYmCPVmGNXibNmV3U32pcHKJRnykbXevZmiTNXOuTo[LfXu1VHx6[luE[FSXWlqOTVetflmIOY[lR1KxZn6PNGmYfIObW2GvT2S{UlOob3eKR1GoR2GsTlOZNF6E[3uoTVOC[1OSb1qEVUCMR2OC[1mERVqEVXyqZ32XbHG7d16E[3uoTVOC[1OSb1qFVX:LTVOC[1mCb1qEV{i3TVWPfWqYSkCbV1K2Xmik[2SYSn6bW{VxZomDdHKvUkC[W{WrXmFxT1OURXeKR1GLR2GtbmmZUnyKSWK3[EJ2d3JzSnuVW2ZxZVd6b3O7c{[TSXyUVmWPWWhxSlSSNG[VWYqwUlOob3eKR1GoR2GsTlOSNFuEV1GoTVOCTlOSb1qiW2moT1WHfXSIcI[ZNEGW[GiLbXJyPVmbW4i4XmiL[mKISkC[WH93XkKXNGFzPYWbcXyvT1OseGCucIqWS1ZxXUKpcGqE[4CMVUCMR2OC[1mERVqEVXuL[YdxT1OURXeKR1GLR2GsTlOURXeKR1GLR2GsTlSSc1qKR1GoTVGsTlOSb1qLTFK6XmibWmWsb3eRV1GsXEGPSmWtXl[WcIOvWXuXVm[WWmSXSkmXWXuscmiVd16E[3uoTVOC[1OSb1qEVXusZ{OTbHSIWXeRV1KPXWelcF:rdH6bXGKV[FeHNHGYUmSlS1ZxXmOodF:4NFuEV1GoTVOCTlOSb1qEWUGpXkKWOl:vTnykNmZxT1OsO1SSc1qKR1GoTVGsTlOSb16E[3uoTVOC[1OSb1qEVXy3XXx6fnSISomlR3exU4dxT1OURXeKR1GLR2GsTlSSc1qKR1GoTVGsTlOSb1qEV2KnWUCXV2[sWmOYfXSUVm[HWmKXUmWZNW[UV2Ol[FmFNHekTFqtXkF6fWqZRoO[W16tT1OkenGJVkCkR3i7T2i{e1yFSkmQcIe3XFN6Zmite4[ZV3:3Tom4[1q6Z4OKR2JyZ324dF:4NFuEV1GoTVOCTlOSb1qEVXyPXWelcF:rdImlW{SwT2S{UlOob3eKR1GoR2GsTlOSb16E[3uoTVOC[1OSb1qEVXusZViTeHKERUmKS{mqXEKlcHSHPXqjNkVxXmd2NHO6[4CQe{CMR2OC[1mERVqEVXuLR2d6bWhzWoWbSkmrZleXbHKq[4CQe{CMR2OC[1mERVqEVXuLR2VybGpzWU[QclqtZ{OTenOuWmSlS1ZxXmOob3N{VnilS2WxU4dxT1OURXeKR1GLR2GsTlOSNFuEV1GoTVOCTlOSb1qnVUCMR2OC[1mERVqEVXuLXme5fmqURV6E[3uoTVOC[1OSb1qEXIOPR3es[1mERXeEVXuLR2Gsb3SuSomOfVF6TVVybGpzWU[QcXitZliDcHOq[36jXGJyZ32Lelq6b4SRcEmnT1OLS3GYfHyKSUGpXkKWeXOIbIeKS3y7TVd2enSERoe[XGKrZVeXb1mqb{eFVX:LTVOC[1mCb1qEVXx6SGGwTlmERXeKRXuLR2GsUlOob3eKR1GoR2GsTmmvTny[W4N4SGGwTlmERXeKRXuLR2FxT1OURXeKR1GLR2hxUlOqRXeKR1GLR2hxUlOqRXeKR1GLR2ePbHSIUn:KR3iH[VePcHOJVoCjNkSoTleWdFSSc3eKR1GoR2GtO1SSc3eKR1GoR2GsTlqJXnikbl2oVGOCb2qUNDubNmZxWGeXfnNzSn6bV3exU4dxT1mERXeKRXuLR2iLcHSJWomjboOPR3mC[1mERVqEXECMR3esTlOUPI[KS{GpUGe5dFmJUnyKTG[{ZkOxdHSERX:jcW[yXleW[3K6RkCbXF5xT2ODbFmIdHyKTFK6XWixb3Kvb3ejW1[1XmODbnGJcHmlVX:LR2GtdGqqRX:LS3hxZme4PWCUZ36KR2muTVOTNmmZTYmMVX:LR2GsTmSYSn6bWH93[FepfXJ{[F[mS16tZ1iTdHJzOH:Kb2K3[EJ2d3JzSnuKS2qpZWe4[1uETYWLTGqpZ3qOeVmqb4WKSlK{XmeHflmIUn:[W{WvXmODb3J{[IWjS{mpXlODeGqZVn:jNmGoZWd1[3J{RkCiW{m2TViTbGmqOHmMWIOPR3mC[1mERVqEVUCMTVOC[1mCb1qiW2moT1OTNmmZTYiMV1GsZViTeHKEOEmKR1l5TWNxeFmETXeNbVK2ZkOkc1uURYWKR1moUGNxL1mrd16EbVGoTVOCTlOYcH2KR3es[H2HfV2qb3ebcXy{XmZ6e3SZVn[[Nkm2[FeXeXSJUX:LTFKp[Feod1mEVn:lS{G{T2S{UlOoNFuKR1GoTVGsTnGYXXeMR2JzXWiKfmCVNH6LfVGuTnmDdHNyPYqlTFqxZn2kc1qIbECjW4exTVO[cVmE[3uiTGK1ZlOGPVq6Z4CMVUCMTVOC[1mCb1qEV2JzXWiKflmFNHekcUlyZn2Sc1uJUkCkcYitZnmob3GJVoSjR3uoUImCc2qufI[[XGGxUWSCfV6Eb4OKSFmxU4dxT1mERXeKRXuLXme5fmqURoCbbVGwTlibbHOrUUmRV3OvTVO[cVmEVn:lS{G{VGRxclq6b16EbVGoTVOCTlOSb3ulcV[6UYmCPVmGNXibNmV3U32pcHKJRnykbXevZmiTNXOuTo[LfXu1VHx6[luE[HyjXFJx[WODenSZVoelXGGvT2S{UlOqRXeKR1GLR2FxT1mERXeKRXx6SGGw[1mERXeEVU1:Jku{PkF3PjKiW{WsXmipRml{VoCjNkR:Jku{PkV1NEpjSGGwTlOYcH2KR3iPXWelcF:rdH:bW4i4XmiKc1pzNUClXFqqZol6dHKuXo[LfXu1VH2lcHSHTnybNEWpZmeWc1uUb3eme{CMR2GsTlqJXnikblG1VH6LcGqE[36jXGJyZ32LelxzSnujW3y2ZViTeHKHPYSlTG[6XX15enGYOXubXHevT2S{UlOob1qnV1KtZliPcFmJd16E[3uLR2FxT1OSb1qLS{G3XleXd1mFNHeVW1[vXmSwOmpzWkCVW{msXme4c1pzNUClXFqqZol6eHSJWom[cUivT2NxL2lzfHy[XFqDZle5VWmY[HykfXexU4dxT1OSb1qFVX:LR2Gsb3SuSomOR{BsXkKXNGWuWoqkS{m2Z{KWc1uUNDukNmZxV1eXbGqIWomMR3SKWl[TVVy7SYWOV3O{ToqSe126RlejN1qqZWeTb2qYOH6MWIOPR3esTlOUVkK[XFm4UGR2cmqZVmObXF64ZkJ2fmqU[4CNWEW7XmiTR3JzVkWMR1Gs[H2HfV2ENDulN1qpZ1OpUmmY[HyQboCwXme5e2qZTX:LNkFx[GiLbXK6Z4CNWEWnXImoclmH[ImjNkWvTVe5dGlzWoWkNmWo[Fite2qUe3ejS3yrXmd2fmqURnqjNmKtZ4mDbHOuWXejcUlxTVdybHSIUn:iW{WvTViTc3GZUXeiS{m7[FN1cluUb4CQe{CMR2GtPVSSc1qEVU1:Jku{PkF3PjKkN3y2XUKpfXJzOYCmcWV:Jku{PkJ2Okh7JlSSc3eKR1GoR2FxT1mERXeKRXusZ1iLcHSucHylNF[6Z32HOVmFNHeLTGqpZ3qCeGCu[HylSlK6XmibdGqZ[FS[XGKtXkJ6fXWWcHukfXexU4dxT1mERXeKRXusZ1iLcHSucHylfVF6TVeteHOIfI[bS2WwTom4clyERXukTFqt[H2tcHRxSomkcVZ2T2S{UlOqRXeKR1GLZWe[[1uEVoekcWZzZWeXN2CVNIeMV1GsZ1iLcHSucHylfVF6TVOkeF2UZ{eFVX:PR3mC[1mERVqLTFZyXmiLOWOIPYSKSECoTomkO1SSc3eKR1GoR2ebenOuWni[NneoT1OTNmmZTUCKS1[7TVOTfnSIPYmbWXysT2ODO1SSc3eKR1GoR2Gsb3OZWnykcnyKZkJx[1yrNHeKb3yQWUCXV2[ERlqVcGKRTVeDeHSJWom[cUmoTVOp[3N{Vo[kcW[nZWeT[1yERnekcW[5[GeXfnSHPYe[XGKwXVOs[2[sSl2XWW[VTVOobVyqVoqlS{m6XmWtb1yqTYOKR3O3TomsO1mETUeFVX:oTVOC[1OZNF6EbVGoTVOCTlSSc3eKR1GoR2OTfHSYWommWXi3ZmWTcGqqRUmKR1qLWHyPSmWtVXeUWUWWWImD[3KZVkGkcVq3XVOCc2mJUkCjN1qtXEKtb2mEe3e[TFqtZ2iXcHN{Vn[kS1ZxZVeCdFmHXlKVSm[HWYmCc12Ee3eLfUivT2S{[1mrd16EbVGoTVOCTlSSc3eKR1GoR2OTfHSYWommWXy2Z4mCPVmETlqVcF6HWXyS[2OWOWWVfVKoZmiTNXOuTo[[R1GwXViXfXKHPYmbXHS6ZWiTcGhzcHu[R4eoXViPNHJ{TnyZNnysXVO4[2mIUnilS2[vZkOLOWhzcHu[R4eoXViDfXJzVkG[N2KnZWeT[1yERnekcW[5[GeXfnSHPYe[XGKwXVOsUlOob1qEVXuoTVOC[1mHUl[VSW[FWlOD[3SZToOZN1qt[EOLdHSIWn[iW2KoUFOD[3N{Vo[kcW[nZWeT[1yERne[NlZxXmelenOvcH[iW2KoUFOD[3OJTo[bTG[r[FZ6dGqIRYOKS1K6XmiHNWqZUkCZN1Kp[Fep[1SSc1qEVXuLTVOC[1mERleWb{mPTVeDbnJ{TnyZN2[6ZlZ6fWqZ[ImiXGKtXVFxT1OSb1qEV1GoTVOC[2ZxbF[Wb2WoSGGwTlOSb1qKR1GoTVOC[1mE[16E[3uLR2Gs[1mERXeKR1GoTVOCc2mIUnilS2[vZkOLOWhzcHu[R1KLWHmCc1mqRYWKR2K4Z32XNnGYWkOKR1G2TVOKdFmGSl:TR1KoZ1iLemqJWnqlSkmxXleC[2OXUXeVcG[OWFOsUlOob1qEVXuoTVOC[1mERXeMV1m2SGGw[1mERXeEVXuLR2OC[1mE[3:LTGqpZ3qG[1mVNHeLfXOxTVR5[1msSl:TR1GwXViPNHJ{TnyZNnysXVODU2RyVXeUWUSoT1OK[1yqRXulcV[6UWOCeVmETYCMV1moU3mCbVmqb16E[3uLR2Gs[1mERXeKR1GoUHmLRmSsVV6EbVGoTVOC[1mCb1qEVXuoTVOCc1SSc3eKR1GoTVOCTlOSb1qKR1GoTVOCc2mJTnykXG[tZ{OT[nOISkCiS1GoWHt6WVmGcF:KR3iVVmW5SmFyVXe[TFqtZ2iXcHN{Vn[kS1ZxZVeC[2KtTmCVV1KoZmiTNXOuTo[[R3uxSGGw[1mERXeKR1GLR2GsTlmERXeMV1l4SGGw[1mERXeEVUCMTVOC[1mCb3ukXG[tZ36tSWqYe3eRV1GqVlWXUWKXVl[KSWqUWEBx[2mINUClXFqqZkKCUlOqRXeKR1GLTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoWkCpSmWsWXeKR3ioXUKHNGqY[I[kcnynZWeT[1mGOWCXR1KLWHmCc1mqOHeLTFK6XmibdGqZZ3eKR{SoTXms[2GWOVWKS1K4Z316b3SYUkCZNnysXVODTmW6Rl:XWYiOT2OKO1SSc3eKR1GoR2FxT1mERXeKRXusZ2iXcHOvcFWbW4iKZkJx[2CURXmTSW[OVm[TSlmGXmOVNECoXVdyNHSZTnmjNlGoWkCpSmWsWXe[TFqtZ2iXcHN{Vn[kS1ZxZVeCPVq6PH6QfVl4SGGwUlOqRXeKR1GLTlePenKuOXy[N2KxZkJ1[2CURl6[W3StU3qxcmqZVmSiW{WvZleXNHJzOH:LNl63Z32WenOuWoqjN2[6XUKWcluUNDubNmZxVUJ6eXKuWnqlS3y3ZnmocmlzPYmbWkl{Z32tNGqUZ4CQe{CMSGGw[1mERXeEXGK6[WODO1SSc3eKR1GoR2GsUlOqRXeKR1GLR2OTbnJzOYWbW15xZWd6eVyVOYilW2[6[WOobWVyVlKWcGGoWl[LRmStUlKSNWKLWEB1bVuVd16EbVGoTVOCTlOSNFuKR1GoTVGsTlqIcIW[NohyXleXTXJzNXykS1[vXmOCPVmEVkK[XFm4UGR2c3JzNXykS1[vXmWtfmOYOXqjTG[sXmeSc1uVd16EbVGoTVOCTlOSNFuKR1GoTVGsTnGYXXeMR2KxZn2Pd3SYVnyUS{m1XmiDbGpzWXeLbWmoTWOTNmmZTYqMV1GsXUJ6eXKuWnqlS3y3ZnlxL3OZWnykcnuwTliHNWqZTkWUS{m1T2S{UlOqRXeKR1GLR2etcVmE[3uiW{WrZliXb2qWbI[jW2[4XWelcFmEXX2KR2JzXWiKe1yVOX6bXGKP[Ge5NHGZUkCjN1qt[H2tcHS6[4CMV1GsXUJ6eXKuWnqlS3y3ZnlxL3OZWnykcnuwTliHNWqZTkWUS{m1VleXcVuVd16EbVGoTVOCTlOUVnqjNkW2XmePNHGYPYWNWEW5[GeXfXWU[3ukXG[tZ36tTnKvUYCQfVGoSGGw[1mERXeEVXuPR3mC[1mERVqEW3yuTVOobFqIcIW[NohyXleXTXJzNXykS1[vXmOCcVqqRXulcV[6UYms[1qIUo[jcUWtXUOTdHJzOISRclZyXmiLOVuEVoilW2[6[WWTcHKGbI[jV3t4SGGw[1mERXeEVXusXUJ6eXKuWnqlS3y3ZnlxL3OZWnykcnuwTliHNWqZTkWTS2[{T2S{UlOoNFuKR1GoTVGtPVmIUnilS16wTVOpSnWIUnykTGKxZkJ1[1qIWYCKTIOPR3mC[1mERVqEV2KrZkJ2eWqYUkCiW{m2UGR2fHSYWommV3eqWXt6UWSGTlKSNIOqT2S{UlOqRXeKR1GLR2iTc3OuPUOKR2KtU4dxT1mERXeKRXx6SGGw[1mERXeEVUCMTVOC[1mCb3u[Nkm2Zn2XbnSIcI[jbUBsZ2iXcHOvb3:Kb16RWGVyTm[ETYCQe{CMTVOC[1mCb16EbVGoTVOCTjJ8gR>>
app/code/local/Artio/MTurbo/controllers/Adminhtml/MturboController.php CHANGED
@@ -36,12 +36,14 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
36
  ->setContainerCssClass('catalog-categories');
37
 
38
  $this->_setActiveMenu('system');
39
- $this->_addBreadcrumb(Mage::helper('adminhtml')->__('Turbo Cache Management'), Mage::helper('adminhtml')->__('Turbo Cache Management'));
40
 
41
  return $this;
42
  }
43
 
44
-
 
 
45
  public function indexAction() {
46
 
47
  $config = Artio_MTurbo_Helper_Data::getConfig();
@@ -171,6 +173,9 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
171
 
172
  }
173
 
 
 
 
174
  public function generateurllistAction() {
175
 
176
  if (!$this->_checkLicence()) return;
@@ -331,6 +336,10 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
331
 
332
  public function downloadFinishAction() {}
333
 
 
 
 
 
334
  public function downloadRunAction() {
335
 
336
  if ($this->getRequest()->isPost()) {
@@ -364,22 +373,10 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
364
 
365
  }
366
 
 
 
 
367
  public function upgradeAction() {
368
-
369
- $checkXml = Mage::helper('mturbo/checker')->checkPermissionLayout();
370
- if (!$checkXml) {
371
- $this->_getSession()->addWarning(Mage::helper('mturbo')->__("Please, change permission to write on file: 'app/design/adminhtml/default/default/layout.xml'"));
372
- $this->_redirect('*/*/index');
373
- return;
374
- }
375
-
376
- $checkCode = Mage::helper('mturbo/checker')->checkPermissionCode();
377
- if (!$checkCode) {
378
- $this->_getSession()->addWarning(Mage::helper('mturbo')->__("Please, change permission to write recursive on directory: 'app/code/local/Artio/MTurbo'"));
379
- $this->_redirect('*/*/index');
380
- return;
381
- }
382
-
383
  $message = Mage::helper('mturbo/downloader')->downloadAndUpgrade();
384
  if ($message=='') {
385
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Upgrade complete, please refresh Magento system cache'));
@@ -404,6 +401,78 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
404
 
405
  }
406
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
407
  public function red($url) {
408
  $this->_redirect($url);
409
  }
@@ -412,4 +481,7 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
412
  return $this->_getSession();
413
  }
414
 
 
 
 
415
  }
36
  ->setContainerCssClass('catalog-categories');
37
 
38
  $this->_setActiveMenu('system');
39
+ $this->_addBreadcrumb(Mage::helper('adminhtml')->__('M-Turbo Management'), Mage::helper('adminhtml')->__('M-Turbo Management'));
40
 
41
  return $this;
42
  }
43
 
44
+ /**
45
+ * Index Action
46
+ */
47
  public function indexAction() {
48
 
49
  $config = Artio_MTurbo_Helper_Data::getConfig();
173
 
174
  }
175
 
176
+ /**
177
+ * Generate urllist. This list
178
+ */
179
  public function generateurllistAction() {
180
 
181
  if (!$this->_checkLicence()) return;
336
 
337
  public function downloadFinishAction() {}
338
 
339
+ /**
340
+ * Download one page.
341
+ * Use AJAX.
342
+ */
343
  public function downloadRunAction() {
344
 
345
  if ($this->getRequest()->isPost()) {
373
 
374
  }
375
 
376
+ /**
377
+ * Upgrade demo version to full version.
378
+ **/
379
  public function upgradeAction() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
380
  $message = Mage::helper('mturbo/downloader')->downloadAndUpgrade();
381
  if ($message=='') {
382
  $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Upgrade complete, please refresh Magento system cache'));
401
 
402
  }
403
 
404
+ /**
405
+ * Try to download frontpage and retrieves result.
406
+ * Use AJAX
407
+ */
408
+ public function testdownloadAction() {
409
+
410
+ $method = $this->getRequest()->getPost('method', '');
411
+
412
+ $config = Artio_MTurbo_Helper_Data::getConfig();
413
+
414
+ $resultTest = '';
415
+ $res = $config->isMethodAvailable($method, $resultTest);
416
+
417
+ $result = array(
418
+ 'ok' => $res,
419
+ 'resultTest'=> $resultTest
420
+ );
421
+
422
+ $this->getResponse()->setBody(Zend_Json::encode($result));
423
+
424
+ }
425
+
426
+ /**
427
+ * Apply or Remove MagePatch
428
+ */
429
+ public function magepatchAction() {
430
+
431
+ try
432
+ {
433
+ $config = Artio_MTurbo_Helper_Data::getConfig();
434
+ if ($config->isPatched())
435
+ {
436
+ $config->removePatch();
437
+ $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Patch was removed.'));
438
+ }
439
+ else
440
+ {
441
+ $config->applyPatch();
442
+ $this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Patch was applied.'));
443
+ }
444
+ }
445
+ catch (Exception $e)
446
+ {
447
+ $this->_getSession()->addError($e->getMessage());
448
+ }
449
+
450
+ $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_main_section'));
451
+
452
+ }
453
+
454
+ /**
455
+ * Does rebuild root htaccess and same time checks htaccess in turbochace folder.
456
+ */
457
+ public function htaccessbuildAction() {
458
+
459
+ $config = Artio_MTurbo_Helper_Data::getConfig();
460
+
461
+ try
462
+ {
463
+ $config->rebuildHtaccess();
464
+ $config->copyAllowAccess();
465
+ $this->_getSession()->addSuccess(Mage::helper('mturbo')->__("Htacces was rebuild."));
466
+ }
467
+ catch (Exception $e)
468
+ {
469
+ $this->_getSession()->addError($e->getMessage());
470
+ }
471
+
472
+ $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_actions_section'));
473
+
474
+ }
475
+
476
  public function red($url) {
477
  $this->_redirect($url);
478
  }
481
  return $this->_getSession();
482
  }
483
 
484
+
485
+
486
+
487
  }
app/code/local/Artio/MTurbo/controllers/AdminhtmlController.php CHANGED
@@ -40,6 +40,7 @@ class Artio_MTurbo_AdminhtmlController extends Mage_Adminhtml_Controller_Action
40
  $newData[ Artio_MTurbo_Model_Config::CONFIG_XML_PATH_ENABLE_AUTOMATIC_DOWNLOAD ] = $request->getPost('automaticdownload');
41
  $newData[ Artio_MTurbo_Model_Config::CONFIG_XML_PATH_DOWNLOAD_TIME ] = $request->getPost('downloadtime');
42
  $newData[ Artio_MTurbo_Model_Config::CONFIG_XML_PATH_LICENSEID ] = $request->getPost('licenseid');
 
43
 
44
  try {
45
  $config = Mage::getSingleton('mturbo/config');
@@ -49,13 +50,13 @@ class Artio_MTurbo_AdminhtmlController extends Mage_Adminhtml_Controller_Action
49
  $this->_getSession()->addError(Mage::helper('mturbo')->__('Configuration error').' : '.$e->getMessage());
50
  }
51
 
52
- $activeTab='';
53
  foreach ($request->getPost() as $key=>$value) {
54
  if (strpos($key, 'section')>0) {
55
  $activeTab = $key;
56
  break;
57
  }
58
- }
59
 
60
  $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>$request->getPost('activeTab')));
61
 
40
  $newData[ Artio_MTurbo_Model_Config::CONFIG_XML_PATH_ENABLE_AUTOMATIC_DOWNLOAD ] = $request->getPost('automaticdownload');
41
  $newData[ Artio_MTurbo_Model_Config::CONFIG_XML_PATH_DOWNLOAD_TIME ] = $request->getPost('downloadtime');
42
  $newData[ Artio_MTurbo_Model_Config::CONFIG_XML_PATH_LICENSEID ] = $request->getPost('licenseid');
43
+ $newData[ Artio_MTurbo_Model_Config::CONFIG_XML_PATH_DOWNLOAD_METHOD ] = $request->getPost('downloadmethod');
44
 
45
  try {
46
  $config = Mage::getSingleton('mturbo/config');
50
  $this->_getSession()->addError(Mage::helper('mturbo')->__('Configuration error').' : '.$e->getMessage());
51
  }
52
 
53
+ /*$activeTab='';
54
  foreach ($request->getPost() as $key=>$value) {
55
  if (strpos($key, 'section')>0) {
56
  $activeTab = $key;
57
  break;
58
  }
59
+ }*/
60
 
61
  $this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>$request->getPost('activeTab')));
62
 
app/code/local/Artio/MTurbo/etc/config.xml CHANGED
@@ -10,7 +10,7 @@
10
  <config>
11
  <modules>
12
  <Artio_MTurbo>
13
- <version>0.1.0</version>
14
  </Artio_MTurbo>
15
  </modules>
16
  <admin>
@@ -178,4 +178,4 @@
178
  </mturbo_mturbo>
179
  </jobs>
180
  </crontab>
181
- </config>
10
  <config>
11
  <modules>
12
  <Artio_MTurbo>
13
+ <version>1.1.0</version>
14
  </Artio_MTurbo>
15
  </modules>
16
  <admin>
178
  </mturbo_mturbo>
179
  </jobs>
180
  </crontab>
181
+ </config>
app/code/local/Artio/MTurbo/etc/config.xml~ ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * @category Artio
5
+ * @package Artio_MTurbo
6
+ * @author Artio
7
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
8
+ */
9
+ -->
10
+ <config>
11
+ <modules>
12
+ <Artio_MTurbo>
13
+ <version>1.0.11</version>
14
+ </Artio_MTurbo>
15
+ </modules>
16
+ <admin>
17
+ <routers>
18
+ <mturbo>
19
+ <use>admin</use>
20
+ <args>
21
+ <module>Artio_MTurbo</module>
22
+ <frontName>mturbo</frontName>
23
+ </args>
24
+ </mturbo>
25
+ </routers>
26
+ </admin>
27
+ <adminhtml>
28
+ <translate>
29
+ <modules>
30
+ <Artio_MTurbo>
31
+ <files>
32
+ <default>Artio_MTurbo.csv</default>
33
+ </files>
34
+ </Artio_MTurbo>
35
+ </modules>
36
+ </translate>
37
+ <menu>
38
+ <system>
39
+ <children>
40
+ <mturbo translate="title" module="mturbo">
41
+ <title>M-Turbo Management</title>
42
+ <action>mturbo/adminhtml_check</action>
43
+ <sort_order>91</sort_order>
44
+ </mturbo>
45
+ </children>
46
+ </system>
47
+ </menu>
48
+ <layout>
49
+ <updates>
50
+ <mturbo>
51
+ <file>mturbo.xml</file>
52
+ </mturbo>
53
+ </updates>
54
+ </layout>
55
+ <events>
56
+ <catalog_product_save_commit_after>
57
+ <observers>
58
+ <mturbo>
59
+ <class>mturbo/observer</class>
60
+ <method>afterSaveProduct</method>
61
+ </mturbo>
62
+ </observers>
63
+ </catalog_product_save_commit_after>
64
+ <catalog_category_save_before>
65
+ <observers>
66
+ <mturbo>
67
+ <class>mturbo/observer</class>
68
+ <method>beforeSaveCategory</method>
69
+ </mturbo>
70
+ </observers>
71
+ </catalog_category_save_before>
72
+ <catalog_category_save_commit_after>
73
+ <observers>
74
+ <mturbo>
75
+ <class>mturbo/observer</class>
76
+ <method>afterSaveCategory</method>
77
+ </mturbo>
78
+ </observers>
79
+ </catalog_category_save_commit_after>
80
+ <core_abstract_save_commit_after>
81
+ <observers>
82
+ <mturbo>
83
+ <class>mturbo/observer</class>
84
+ <method>afterSaveCommitUrl</method>
85
+ </mturbo>
86
+ </observers>
87
+ </core_abstract_save_commit_after>
88
+ <admin_session_user_login_success>
89
+ <observers>
90
+ <mturbo>
91
+ <class>mturbo/observer</class>
92
+ <method>adminLogin</method>
93
+ </mturbo>
94
+ </observers>
95
+ </admin_session_user_login_success>
96
+ </events>
97
+ </adminhtml>
98
+ <frontend>
99
+ <events>
100
+ <customer_login>
101
+ <observers>
102
+ <mturbo>
103
+ <class>mturbo/observer</class>
104
+ <method>customerLogin</method>
105
+ </mturbo>
106
+ </observers>
107
+ </customer_login>
108
+ <customer_logout>
109
+ <observers>
110
+ <mturbo>
111
+ <class>mturbo/observer</class>
112
+ <method>customerLogout</method>
113
+ </mturbo>
114
+ </observers>
115
+ </customer_logout>
116
+ <core_block_abstract_prepare_layout_after>
117
+ <observers>
118
+ <mturbo>
119
+ <class>mturbo/observer</class>
120
+ <method>systemCheck</method>
121
+ </mturbo>
122
+ </observers>
123
+ </core_block_abstract_prepare_layout_after>
124
+ </events>
125
+ </frontend>
126
+ <global>
127
+ <models>
128
+ <mturbo>
129
+ <class>Artio_MTurbo_Model</class>
130
+ <resourceModel>mturbo_mysql4</resourceModel>
131
+ </mturbo>
132
+ <mturbo_mysql4>
133
+ <class>Artio_MTurbo_Model_Mysql4</class>
134
+ <entities>
135
+ <mturbo>
136
+ <table>mturbo</table>
137
+ </mturbo>
138
+ </entities>
139
+ </mturbo_mysql4>
140
+ </models>
141
+ <resources>
142
+ <mturbo_setup>
143
+ <setup>
144
+ <module>Artio_MTurbo</module>
145
+ </setup>
146
+ <connection>
147
+ <use>core_setup</use>
148
+ </connection>
149
+ </mturbo_setup>
150
+ <mturbo_write>
151
+ <connection>
152
+ <use>core_write</use>
153
+ </connection>
154
+ </mturbo_write>
155
+ <mturbo_read>
156
+ <connection>
157
+ <use>core_read</use>
158
+ </connection>
159
+ </mturbo_read>
160
+ </resources>
161
+ <blocks>
162
+ <mturbo>
163
+ <class>Artio_MTurbo_Block</class>
164
+ </mturbo>
165
+ </blocks>
166
+ <helpers>
167
+ <mturbo>
168
+ <class>Artio_MTurbo_Helper</class>
169
+ </mturbo>
170
+ </helpers>
171
+ </global>
172
+ <crontab>
173
+ <jobs>
174
+ <mturbo_mturbo>
175
+ <run>
176
+ <model>mturbo/observer::automaticDownload</model>
177
+ </run>
178
+ </mturbo_mturbo>
179
+ </jobs>
180
+ </crontab>
181
+ </config>
app/code/local/Artio/MTurbo/sql/mturbo_setup/{mysql4-install-0.1.0.php → mysql4-install-1.0.0.php} RENAMED
@@ -60,7 +60,7 @@
60
  ('default', 0, 'mturbo/firstconfig', '1');
61
  ");
62
 
63
- $notf['title'] = Mage::helper('mturbo')->__('M-Turbo instalation succesfull. Please see into System/Turbo Cache Management');
64
  $notf['description'] = Mage::helper('mturbo')->__("Installation succesfull. Now will be your Magento faster than other.");
65
 
66
  $notification->parse(array($notf));
60
  ('default', 0, 'mturbo/firstconfig', '1');
61
  ");
62
 
63
+ $notf['title'] = Mage::helper('mturbo')->__('M-Turbo installation succesfull. Please see into System/M-Turbo Management');
64
  $notf['description'] = Mage::helper('mturbo')->__("Installation succesfull. Now will be your Magento faster than other.");
65
 
66
  $notification->parse(array($notf));
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>MTurbo</name>
4
- <version>1.0</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.artio.net/m-turbo/license">Copyright 2010, ARTIO s.r.o. All rights reserved.</license>
7
  <channel>community</channel>
@@ -14,9 +14,9 @@ of Magento site optimization!</description>
14
  <notes>Visit product homepage at:
15
  http://www.artio.net/magento-extensions/m-turbo-accelerator</notes>
16
  <authors><author><name>Michal Unzeitig</name><user>auto-converted</user><email>michal.unzeitig@artio.net</email></author><author><name>Ji&#x159;&#xED; Chmiel</name><user>auto-converted</user><email>jiri.chmiel@artio.net</email></author></authors>
17
- <date>2010-07-07</date>
18
- <time>07:57:08</time>
19
- <contents><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="mturbo.xml" hash="e1e9a5dc117f392f9e2926526b9b1c56"/></dir><dir name="template"><dir name="mturbo"><dir name="preview"><file name="tree.phtml" hash="558e2da8b9c5584a94748116fd8249d0"/></dir><file name="demo.phtml" hash="509ced41c68e1ee7abca6636d24cac0f"/><file name="massaction.phtml" hash="c4ca58cbd05d564129d3c39d452c783e"/><file name="tabs.phtml" hash="1015f2e05a41bb7751b11036e48cbd9f"/></dir></dir></dir></dir></dir></target><target name="magelocal"><dir name="Artio"><dir name="MTurbo"><dir name="Block"><dir name="Adminhtml"><dir name="Edit"><dir name="Tab"><file name="Abstract.php" hash="16a37f270112b175796bb5af02eea84d"/><file name="Actions.php" hash="4f34e782ef8c10a771396187a71f9409"/><file name="Category.php" hash="c3ead1f2e3c4456ae506bc412cb7a4d6"/><file name="License.php" hash="554adc83dd6d0c69f65a674c30c0e49f"/><file name="Main.php" hash="480da24b9844ca61c02e855fd3e362bd"/><file name="Product.php" hash="2458da4035912d8345f479583fd161bd"/><file name="Url.php" hash="81f49156c0f08b244235d715f2fe7b4f"/></dir><file name="Form.php" hash="e3694987ff374e400703f188e391e351"/><file name="Tabs.php" hash="282cb5ff643fa61480994e3f72856f36"/></dir><dir name="Welcome"><file name="Form.php" hash="0af7f37c2ba47175801b5082cf7ceb5a"/></dir><file name="Mturbo.php" hash="3abfef293f93f669cf38b0efc076721f"/><file name="Run.php" hash="31da176aecb2db024cd350290c4533c3"/><file name="Welcome.php" hash="30b0b1882eff25371e8d1bf4ee0bf880"/></dir><dir name="Data"><dir name="Form"><dir name="Element"><file name="Button.php" hash="0317d74c9856481c8e2ccfdff5f7ff20"/><file name="CategoryTree.php" hash="0294437ea2c2b7f92414b945061b12ee"/><file name="NoEscLabel.php" hash="d10b4e82853916eccba7989a3d272660"/><file name="Time.php" hash="ce401753d4c06840f12ffc011c2ac435"/></dir></dir><dir name="Grid"><dir name="Column"><file name="Blocked.php" hash="4941dcafb09b4eb502d3eabfd3f73dc4"/></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="CheckController.php" hash="6b62cfd1cbb8d9713eb64abe553b10b8"/><file name="MturboController.php" hash="41e8d4178e24f0c641e795d6cc40503e"/></dir><file name="AdminhtmlController.php" hash="6108e8ab5feae6722b63d13477efa1cd"/></dir><dir name="etc"><file name="config.xml" hash="af0490e77037eea10d5cc327528cc1e4"/></dir><dir name="Helper"><file name="Checker.php" hash="3f0199949f3c1f8178c98c18b7555aac"/><file name="Data.php" hash="6d5457e02cae3a1b1d876bde6df790a2"/><file name="Downloader.php" hash="1f5c4798e38b13e36452b45aeea124eb"/><file name="Info.php" hash="b2f804ce14c86097d57e3ce7b15e8187"/></dir><dir name="Model"><dir name="htaccess"><file name="htaccess.txt" hash="17b8ae29b45d4a7072de79293b597666"/><file name="htaccessroot.txt" hash="7d55f4bb772128b1f8783b319344d17c"/></dir><dir name="Mysql4"><dir name="Mturbo"><file name="Collection.php" hash="905f9728ed7a8c9d901f3f55c3e9a7d7"/></dir><file name="Mturbo.php" hash="e81f8f1801eca956229a068d0bdea2ab"/></dir><dir name="scripts"><file name="wgetlib.so" hash="5473f00c21012186e41141e3fb3bc85f"/><file name="wgettrans.so" hash="e4f414b0f796051518b6d951133c856b"/></dir><file name="Config.php" hash="7efc8e895896b068f0d83fa5f55bbb98"/><file name="File.php" hash="868697e0c1c9f404789819ec3eb94c41"/><file name="Mturbo.php" hash="667fedf67c5d9d954ff6d8639e6ff2a1"/><file name="Observer.php" hash="f4cab2aaffbe68647b6831555d1ca301"/><file name="Observer2.php" hash="de554c2515d5cdefbaa2375a5389f7f8"/></dir><dir name="sql"><dir name="mturbo_setup"><file name="mysql4-install-0.1.0.php" hash="7dc9240b17439483f3ec170b11045eff"/></dir></dir></dir></dir></target><target name="magelocale"><dir name="en_US"><file name="Artio_MTurbo.csv" hash="37ce492d01d06c14e5f0991a6d60b375"/></dir></target><target name="mageetc"><dir name="modules"><file name="Artio_MTurbo.xml" hash="4de5464bc12f3c0702d2c36931bda64d"/></dir></target></contents>
20
  <compatible/>
21
  <dependencies/>
22
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>MTurbo</name>
4
+ <version>1.1.0</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.artio.net/m-turbo/license">Copyright 2010, ARTIO s.r.o. All rights reserved.</license>
7
  <channel>community</channel>
14
  <notes>Visit product homepage at:
15
  http://www.artio.net/magento-extensions/m-turbo-accelerator</notes>
16
  <authors><author><name>Michal Unzeitig</name><user>auto-converted</user><email>michal.unzeitig@artio.net</email></author><author><name>Ji&#x159;&#xED; Chmiel</name><user>auto-converted</user><email>jiri.chmiel@artio.net</email></author></authors>
17
+ <date>2010-10-01</date>
18
+ <time>08:12:17</time>
19
+ <contents><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="mturbo.xml" hash="e1e9a5dc117f392f9e2926526b9b1c56"/></dir><dir name="template"><dir name="mturbo"><dir name="preview"><file name="tree.phtml" hash="558e2da8b9c5584a94748116fd8249d0"/></dir><file name="demo.phtml" hash="509ced41c68e1ee7abca6636d24cac0f"/><file name="massaction.phtml" hash="c4ca58cbd05d564129d3c39d452c783e"/><file name="tabs.phtml" hash="1015f2e05a41bb7751b11036e48cbd9f"/></dir></dir></dir></dir></dir></target><target name="magelocal"><dir name="Artio"><dir name="MTurbo"><dir name="Block"><dir name="Adminhtml"><dir name="Edit"><dir name="Tab"><file name="Abstract.php" hash="16a37f270112b175796bb5af02eea84d"/><file name="Actions.php" hash="8e60e7c2ef8996fc1486e5b6e0fcce16"/><file name="Category.php" hash="c3ead1f2e3c4456ae506bc412cb7a4d6"/><file name="License.php" hash="554adc83dd6d0c69f65a674c30c0e49f"/><file name="Main.php" hash="4219a12abbf78ee3015126792a84480d"/><file name="Product.php" hash="2458da4035912d8345f479583fd161bd"/><file name="Url.php" hash="81f49156c0f08b244235d715f2fe7b4f"/></dir><file name="Form.php" hash="e3694987ff374e400703f188e391e351"/><file name="Tabs.php" hash="282cb5ff643fa61480994e3f72856f36"/></dir><dir name="Welcome"><file name="Form.php" hash="0af7f37c2ba47175801b5082cf7ceb5a"/></dir><file name="Mturbo.php" hash="3abfef293f93f669cf38b0efc076721f"/><file name="Run.php" hash="a88befc34123fb04ebf74041ca763338"/><file name="Welcome.php" hash="30b0b1882eff25371e8d1bf4ee0bf880"/></dir><dir name="Data"><dir name="Form"><dir name="Element"><file name="Button.php" hash="0317d74c9856481c8e2ccfdff5f7ff20"/><file name="CategoryTree.php" hash="0294437ea2c2b7f92414b945061b12ee"/><file name="NoEscLabel.php" hash="d10b4e82853916eccba7989a3d272660"/><file name="SelectDownloadMethod.php" hash="f9a816189f98787120d8e7340b78e102"/><file name="Time.php" hash="ce401753d4c06840f12ffc011c2ac435"/></dir></dir><dir name="Grid"><dir name="Column"><file name="Blocked.php" hash="4941dcafb09b4eb502d3eabfd3f73dc4"/></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="CheckController.php" hash="6b62cfd1cbb8d9713eb64abe553b10b8"/><file name="MturboController.php" hash="cce26b19b4779be3053b781a5466a5a0"/></dir><file name="AdminhtmlController.php" hash="3ec6e0b5eed5a3e93259b8d7a0eb4003"/></dir><dir name="etc"><file name="config.xml" hash="775aaeade726ee61813f4928e1e469b6"/><file name="config.xml~" hash="75ffbca7371538210bfea91a75f8ccfd"/></dir><dir name="Helper"><file name="Checker.php" hash="164bb3cb86eb68b3b1969dd92824735f"/><file name="Data.php" hash="f63bdc034ae79c5473ef66e0f5712c07"/><file name="Downloader.php" hash="1f5c4798e38b13e36452b45aeea124eb"/><file name="Info.php" hash="b2f804ce14c86097d57e3ce7b15e8187"/></dir><dir name="Model"><dir name="htaccess"><file name="htaccess.txt" hash="b37433b41cf37e325f2ade4e7839261a"/><file name="htaccessroot.txt" hash="7d55f4bb772128b1f8783b319344d17c"/></dir><dir name="Mysql4"><dir name="Mturbo"><file name="Collection.php" hash="905f9728ed7a8c9d901f3f55c3e9a7d7"/></dir><file name="Mturbo.php" hash="e81f8f1801eca956229a068d0bdea2ab"/></dir><dir name="patches"><file name="mage.txt" hash="0e2ef3ed32b7041f518f162745812023"/></dir><dir name="scripts"><file name="wgetlib.so" hash="80c5d05d9f7d678728e1dccaf0b270c3"/><file name="wgettrans.so" hash="e4f414b0f796051518b6d951133c856b"/></dir><file name="Config.php" hash="ce52f4f206575d9491b2c89ff3b57175"/><file name="Config.php~" hash="117fc78e3053b82d889c00ab135cf4a9"/><file name="File.php" hash="30c7703f65824523ed3c803cc6d57f5a"/><file name="File.php~" hash="98a04470cad3dcc993273f1824192e0e"/><file name="Mturbo.php" hash="7f35b9abc3dd6402e900cae80fafa144"/><file name="Observer.php" hash="1a53243dd2b292181a86c26736ad9004"/><file name="Observer2.php" hash="de554c2515d5cdefbaa2375a5389f7f8"/></dir><dir name="sql"><dir name="mturbo_setup"><file name="mysql4-install-1.0.0.php" hash="f1c33d7c0292988ffef36c8eb683b2d4"/></dir></dir></dir></dir></target><target name="magelocale"><dir name="en_US"><file name="Artio_MTurbo.csv" hash="37ce492d01d06c14e5f0991a6d60b375"/></dir></target><target name="mageetc"><dir name="modules"><file name="Artio_MTurbo.xml" hash="4de5464bc12f3c0702d2c36931bda64d"/></dir></target></contents>
20
  <compatible/>
21
  <dependencies/>
22
  </package>