@@ -53,7 +53,7 @@ discard block |
||
53 | 53 | Logger::log('Configuration saved successful'); |
54 | 54 | Security::getInstance()->setFlash("callback_message", _("Usuario agregado correctamente")); |
55 | 55 | Security::getInstance()->setFlash("callback_route", $this->getRoute("admin"), true); |
56 | - } else { |
|
56 | + }else { |
|
57 | 57 | throw new ConfigException(_('Error al guardar los administradores, prueba a cambiar los permisos')); |
58 | 58 | } |
59 | 59 | } |
@@ -74,9 +74,9 @@ discard block |
||
74 | 74 | */ |
75 | 75 | public function adminLogin($route = null) |
76 | 76 | { |
77 | - if($this->isAdmin()) { |
|
77 | + if ($this->isAdmin()) { |
|
78 | 78 | return $this->redirect('admin'); |
79 | - } else { |
|
79 | + }else { |
|
80 | 80 | return Admin::staticAdminLogon($route); |
81 | 81 | } |
82 | 82 | } |
@@ -108,7 +108,7 @@ discard block |
||
108 | 108 | $cookies = array( |
109 | 109 | array( |
110 | 110 | "name" => Security::getInstance()->getHash(), |
111 | - "value" => base64_encode($form->getFieldValue("user") . ":" . $form->getFieldValue("pass")), |
|
111 | + "value" => base64_encode($form->getFieldValue("user").":".$form->getFieldValue("pass")), |
|
112 | 112 | "expire" => time() + 3600, |
113 | 113 | "http" => true, |
114 | 114 | ) |
@@ -119,7 +119,7 @@ discard block |
||
119 | 119 | 'status_message' => _("Acceso permitido... redirigiendo!!"), |
120 | 120 | 'delay' => 1, |
121 | 121 | ); |
122 | - } else { |
|
122 | + }else { |
|
123 | 123 | $form->setError("user", _("El usuario no tiene acceso a la web")); |
124 | 124 | } |
125 | 125 | } |
@@ -14,7 +14,7 @@ discard block |
||
14 | 14 | * @package PSFS\controller |
15 | 15 | * @domain ROOT |
16 | 16 | */ |
17 | -class Admin extends AuthAdminController{ |
|
17 | +class Admin extends AuthAdminController { |
|
18 | 18 | |
19 | 19 | const DOMAIN = 'ROOT'; |
20 | 20 | |
@@ -44,9 +44,9 @@ discard block |
||
44 | 44 | * @throws \PSFS\base\exception\FormException |
45 | 45 | */ |
46 | 46 | public static function staticAdminLogon($route = null) { |
47 | - if('login' !== Config::getInstance()->get('admin_login')) { |
|
47 | + if ('login' !== Config::getInstance()->get('admin_login')) { |
|
48 | 48 | return AdminServices::getInstance()->setAdminHeaders(); |
49 | - } else { |
|
49 | + }else { |
|
50 | 50 | $form = new LoginForm(); |
51 | 51 | $form->setData(array("route" => $route)); |
52 | 52 | $form->build(); |
@@ -4,16 +4,16 @@ discard block |
||
4 | 4 | |
5 | 5 | if (!defined('SOURCE_DIR')) define('SOURCE_DIR', __DIR__); |
6 | 6 | if (preg_match('/vendor/', SOURCE_DIR)) { |
7 | - if (!defined('BASE_DIR')) define('BASE_DIR', SOURCE_DIR . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..'); |
|
8 | - if (!defined('CORE_DIR')) define('CORE_DIR', BASE_DIR . DIRECTORY_SEPARATOR . 'src'); |
|
9 | -} else { |
|
10 | - if (!defined('BASE_DIR')) define('BASE_DIR', SOURCE_DIR . DIRECTORY_SEPARATOR . '..'); |
|
11 | - if (!defined('CORE_DIR')) define('CORE_DIR', BASE_DIR . DIRECTORY_SEPARATOR . 'modules'); |
|
7 | + if (!defined('BASE_DIR')) define('BASE_DIR', SOURCE_DIR.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'..'); |
|
8 | + if (!defined('CORE_DIR')) define('CORE_DIR', BASE_DIR.DIRECTORY_SEPARATOR.'src'); |
|
9 | +}else { |
|
10 | + if (!defined('BASE_DIR')) define('BASE_DIR', SOURCE_DIR.DIRECTORY_SEPARATOR.'..'); |
|
11 | + if (!defined('CORE_DIR')) define('CORE_DIR', BASE_DIR.DIRECTORY_SEPARATOR.'modules'); |
|
12 | 12 | } |
13 | -if (!defined('LOG_DIR')) define('LOG_DIR', BASE_DIR . DIRECTORY_SEPARATOR . 'logs'); |
|
14 | -if (!defined('CACHE_DIR')) define('CACHE_DIR', BASE_DIR . DIRECTORY_SEPARATOR . 'cache'); |
|
15 | -if (!defined('CONFIG_DIR')) define('CONFIG_DIR', BASE_DIR . DIRECTORY_SEPARATOR . 'config'); |
|
16 | -if (!defined('WEB_DIR')) define('WEB_DIR', BASE_DIR . DIRECTORY_SEPARATOR . 'html'); |
|
13 | +if (!defined('LOG_DIR')) define('LOG_DIR', BASE_DIR.DIRECTORY_SEPARATOR.'logs'); |
|
14 | +if (!defined('CACHE_DIR')) define('CACHE_DIR', BASE_DIR.DIRECTORY_SEPARATOR.'cache'); |
|
15 | +if (!defined('CONFIG_DIR')) define('CONFIG_DIR', BASE_DIR.DIRECTORY_SEPARATOR.'config'); |
|
16 | +if (!defined('WEB_DIR')) define('WEB_DIR', BASE_DIR.DIRECTORY_SEPARATOR.'html'); |
|
17 | 17 | |
18 | 18 | //Cargamos en memoria la función de desarrollo PRE |
19 | 19 | if (!function_exists('pre')) { |
@@ -22,7 +22,7 @@ discard block |
||
22 | 22 | $html = '<pre style="padding:10px;margin:0;display:block;background: #EEE; box-shadow: inset 0 0 3px 3px #DDD; color: #666; text-shadow: 1px 1px 1px #CCC;border-radius: 5px;">'; |
23 | 23 | $html .= (is_null($var)) ? '<b>NULL</b>' : print_r($var, TRUE); |
24 | 24 | $html .= '</pre>'; |
25 | - if(class_exists('\\PSFS\\Dispatcher')) { |
|
25 | + if (class_exists('\\PSFS\\Dispatcher')) { |
|
26 | 26 | $html .= '<pre>['.round(\PSFS\Dispatcher::getInstance()->getMem('MBytes'), 3).'Mb - '.round(\PSFS\Dispatcher::getInstance()->getTs(), 3).'s]</pre>'; |
27 | 27 | } |
28 | 28 | ob_start(); |
@@ -30,7 +30,7 @@ discard block |
||
30 | 30 | ob_flush(); |
31 | 31 | ob_end_clean(); |
32 | 32 | if ($die) { |
33 | - if(class_exists('\\PSFS\\base\\Logger')) { |
|
33 | + if (class_exists('\\PSFS\\base\\Logger')) { |
|
34 | 34 | \PSFS\base\Logger::log('Execution finished via pre', LOG_WARNING); |
35 | 35 | } |
36 | 36 | die; |
@@ -1,19 +1,39 @@ |
||
1 | 1 | <?php |
2 | -if (defined('PSFS_BOOTSTRAP_LOADED')) return; |
|
2 | +if (defined('PSFS_BOOTSTRAP_LOADED')) { |
|
3 | + return; |
|
4 | +} |
|
3 | 5 | use Symfony\Component\Finder\Finder; |
4 | 6 | |
5 | -if (!defined('SOURCE_DIR')) define('SOURCE_DIR', __DIR__); |
|
7 | +if (!defined('SOURCE_DIR')) { |
|
8 | + define('SOURCE_DIR', __DIR__); |
|
9 | +} |
|
6 | 10 | if (preg_match('/vendor/', SOURCE_DIR)) { |
7 | - if (!defined('BASE_DIR')) define('BASE_DIR', SOURCE_DIR . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..'); |
|
8 | - if (!defined('CORE_DIR')) define('CORE_DIR', BASE_DIR . DIRECTORY_SEPARATOR . 'src'); |
|
9 | -} else { |
|
10 | - if (!defined('BASE_DIR')) define('BASE_DIR', SOURCE_DIR . DIRECTORY_SEPARATOR . '..'); |
|
11 | - if (!defined('CORE_DIR')) define('CORE_DIR', BASE_DIR . DIRECTORY_SEPARATOR . 'modules'); |
|
11 | + if (!defined('BASE_DIR')) { |
|
12 | + define('BASE_DIR', SOURCE_DIR . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..'); |
|
13 | + } |
|
14 | + if (!defined('CORE_DIR')) { |
|
15 | + define('CORE_DIR', BASE_DIR . DIRECTORY_SEPARATOR . 'src'); |
|
16 | + } |
|
17 | + } else { |
|
18 | + if (!defined('BASE_DIR')) { |
|
19 | + define('BASE_DIR', SOURCE_DIR . DIRECTORY_SEPARATOR . '..'); |
|
20 | + } |
|
21 | + if (!defined('CORE_DIR')) { |
|
22 | + define('CORE_DIR', BASE_DIR . DIRECTORY_SEPARATOR . 'modules'); |
|
23 | + } |
|
24 | + } |
|
25 | +if (!defined('LOG_DIR')) { |
|
26 | + define('LOG_DIR', BASE_DIR . DIRECTORY_SEPARATOR . 'logs'); |
|
27 | +} |
|
28 | +if (!defined('CACHE_DIR')) { |
|
29 | + define('CACHE_DIR', BASE_DIR . DIRECTORY_SEPARATOR . 'cache'); |
|
30 | +} |
|
31 | +if (!defined('CONFIG_DIR')) { |
|
32 | + define('CONFIG_DIR', BASE_DIR . DIRECTORY_SEPARATOR . 'config'); |
|
33 | +} |
|
34 | +if (!defined('WEB_DIR')) { |
|
35 | + define('WEB_DIR', BASE_DIR . DIRECTORY_SEPARATOR . 'html'); |
|
12 | 36 | } |
13 | -if (!defined('LOG_DIR')) define('LOG_DIR', BASE_DIR . DIRECTORY_SEPARATOR . 'logs'); |
|
14 | -if (!defined('CACHE_DIR')) define('CACHE_DIR', BASE_DIR . DIRECTORY_SEPARATOR . 'cache'); |
|
15 | -if (!defined('CONFIG_DIR')) define('CONFIG_DIR', BASE_DIR . DIRECTORY_SEPARATOR . 'config'); |
|
16 | -if (!defined('WEB_DIR')) define('WEB_DIR', BASE_DIR . DIRECTORY_SEPARATOR . 'html'); |
|
17 | 37 | |
18 | 38 | //Cargamos en memoria la función de desarrollo PRE |
19 | 39 | if (!function_exists('pre')) { |
@@ -127,7 +127,7 @@ discard block |
||
127 | 127 | $this->setStatusHeader(); |
128 | 128 | $this->setAuthHeaders(); |
129 | 129 | $this->setCookieHeaders($cookies); |
130 | - header('Content-type: ' . $contentType); |
|
130 | + header('Content-type: '.$contentType); |
|
131 | 131 | |
132 | 132 | } |
133 | 133 | |
@@ -143,14 +143,14 @@ discard block |
||
143 | 143 | Logger::log('Start output response'); |
144 | 144 | ob_start(); |
145 | 145 | $this->setReponseHeaders($contentType, $cookies); |
146 | - header('Content-length: ' . strlen($output)); |
|
146 | + header('Content-length: '.strlen($output)); |
|
147 | 147 | |
148 | 148 | $cache = Cache::needCache(); |
149 | 149 | if (false !== $cache && $this->status_code === Template::STATUS_OK && $this->debug === false) { |
150 | 150 | Logger::log('Saving output response into cache'); |
151 | 151 | $cacheName = $this->cache->getRequestCacheHash(); |
152 | - $this->cache->storeData("json" . DIRECTORY_SEPARATOR . $cacheName, $output); |
|
153 | - $this->cache->storeData("json" . DIRECTORY_SEPARATOR . $cacheName . ".headers", headers_list(), Cache::JSON); |
|
152 | + $this->cache->storeData("json".DIRECTORY_SEPARATOR.$cacheName, $output); |
|
153 | + $this->cache->storeData("json".DIRECTORY_SEPARATOR.$cacheName.".headers", headers_list(), Cache::JSON); |
|
154 | 154 | } |
155 | 155 | echo $output; |
156 | 156 | |
@@ -167,11 +167,11 @@ discard block |
||
167 | 167 | { |
168 | 168 | Logger::log('Close template render'); |
169 | 169 | Security::getInstance()->setSessionKey("lastRequest", array( |
170 | - "url" => Request::getInstance()->getRootUrl() . Request::requestUri(), |
|
170 | + "url" => Request::getInstance()->getRootUrl().Request::requestUri(), |
|
171 | 171 | "ts" => microtime(true), |
172 | 172 | )); |
173 | 173 | Security::getInstance()->updateSession(); |
174 | - Logger::log('End request: ' . Request::requestUri(), LOG_INFO); |
|
174 | + Logger::log('End request: '.Request::requestUri(), LOG_INFO); |
|
175 | 175 | exit; |
176 | 176 | } |
177 | 177 | |
@@ -220,7 +220,7 @@ discard block |
||
220 | 220 | $dump = ''; |
221 | 221 | try { |
222 | 222 | $dump = $this->tpl->render($tpl, $vars); |
223 | - } catch (\Exception $e) { |
|
223 | + }catch (\Exception $e) { |
|
224 | 224 | Logger::log($e->getMessage(), LOG_ERR); |
225 | 225 | } |
226 | 226 | return $dump; |
@@ -334,7 +334,7 @@ discard block |
||
334 | 334 | public function regenerateTemplates() |
335 | 335 | { |
336 | 336 | $this->generateTemplatesCache(); |
337 | - $domains = Cache::getInstance()->getDataFromFile(CONFIG_DIR . DIRECTORY_SEPARATOR . "domains.json", Cache::JSON, true); |
|
337 | + $domains = Cache::getInstance()->getDataFromFile(CONFIG_DIR.DIRECTORY_SEPARATOR."domains.json", Cache::JSON, true); |
|
338 | 338 | $translations = []; |
339 | 339 | if (is_array($domains)) { |
340 | 340 | $translations = $this->parsePathTranslations($domains); |
@@ -356,8 +356,8 @@ discard block |
||
356 | 356 | // force compilation |
357 | 357 | if ($file->isFile()) { |
358 | 358 | try { |
359 | - $this->tpl->loadTemplate(str_replace($tplDir . '/', '', $file)); |
|
360 | - } catch (\Exception $e) { |
|
359 | + $this->tpl->loadTemplate(str_replace($tplDir.'/', '', $file)); |
|
360 | + }catch (\Exception $e) { |
|
361 | 361 | Logger::log($e->getMessage(), LOG_ERR); |
362 | 362 | throw $e; |
363 | 363 | } |
@@ -428,7 +428,7 @@ discard block |
||
428 | 428 | unset($_SERVER["PHP_AUTH_USER"]); |
429 | 429 | unset($_SERVER["PHP_AUTH_PW"]); |
430 | 430 | header_remove("Authorization"); |
431 | - } else { |
|
431 | + }else { |
|
432 | 432 | header('Authorization:'); |
433 | 433 | } |
434 | 434 | } |
@@ -455,9 +455,9 @@ discard block |
||
455 | 455 | Logger::log('Adding debug headers to render response'); |
456 | 456 | $vars["__DEBUG__"]["includes"] = get_included_files(); |
457 | 457 | $vars["__DEBUG__"]["trace"] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); |
458 | - header('X-PSFS-DEBUG-TS: ' . Dispatcher::getInstance()->getTs() . ' s'); |
|
459 | - header('X-PSFS-DEBUG-MEM: ' . Dispatcher::getInstance()->getMem('MBytes') . ' MBytes'); |
|
460 | - header('X-PSFS-DEBUG-FILES: ' . count(get_included_files()) . ' files opened'); |
|
458 | + header('X-PSFS-DEBUG-TS: '.Dispatcher::getInstance()->getTs().' s'); |
|
459 | + header('X-PSFS-DEBUG-MEM: '.Dispatcher::getInstance()->getMem('MBytes').' MBytes'); |
|
460 | + header('X-PSFS-DEBUG-FILES: '.count(get_included_files()).' files opened'); |
|
461 | 461 | } |
462 | 462 | |
463 | 463 | return $vars; |
@@ -499,7 +499,7 @@ discard block |
||
499 | 499 | $this->cache = Cache::getInstance(); |
500 | 500 | $loader = new \Twig_Loader_Filesystem(Config::getInstance()->getTemplatePath()); |
501 | 501 | $this->tpl = new \Twig_Environment($loader, array( |
502 | - 'cache' => Config::getInstance()->getCachePath() . DIRECTORY_SEPARATOR . 'twig', |
|
502 | + 'cache' => Config::getInstance()->getCachePath().DIRECTORY_SEPARATOR.'twig', |
|
503 | 503 | 'debug' => (bool)$this->debug, |
504 | 504 | 'auto_reload' => TRUE, |
505 | 505 | )); |
@@ -35,8 +35,8 @@ discard block |
||
35 | 35 | public function render($template, array $vars = array(), $cookies = array(), $domain = null) |
36 | 36 | { |
37 | 37 | $vars['__menu__'] = $this->getMenu(); |
38 | - $domain = (null ===$domain) ? $this->getDomain() : $domain; |
|
39 | - $this->tpl->render($domain . $template, $vars, $cookies); |
|
38 | + $domain = (null === $domain) ? $this->getDomain() : $domain; |
|
39 | + $this->tpl->render($domain.$template, $vars, $cookies); |
|
40 | 40 | } |
41 | 41 | |
42 | 42 | /** |
@@ -67,7 +67,7 @@ discard block |
||
67 | 67 | { |
68 | 68 | $vars['__menu__'] = $this->getMenu(); |
69 | 69 | $domain = $domain ?: $this->getDomain(); |
70 | - return $this->tpl->dump($domain . $template, $vars); |
|
70 | + return $this->tpl->dump($domain.$template, $vars); |
|
71 | 71 | } |
72 | 72 | |
73 | 73 | /** |
@@ -96,15 +96,15 @@ discard block |
||
96 | 96 | ///////////////////////////////////////////////////////////// |
97 | 97 | // Date in the past sets the value to already have been expired. |
98 | 98 | header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); |
99 | - header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); |
|
99 | + header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); |
|
100 | 100 | header('Cache-Control: no-store, no-cache, must-revalidate'); // HTTP/1.1 |
101 | 101 | header('Cache-Control: pre-check=0, post-check=0, max-age=0'); // HTTP/1.1 |
102 | 102 | header("Pragma: no-cache"); |
103 | 103 | header("Expires: 0"); |
104 | 104 | header('Content-Transfer-Encoding: none'); |
105 | - header("Content-type: " . $content); |
|
106 | - header("Content-length: " . strlen($data)); |
|
107 | - header('Content-Disposition: attachment; filename="' . $filename . '"'); |
|
105 | + header("Content-type: ".$content); |
|
106 | + header("Content-length: ".strlen($data)); |
|
107 | + header('Content-Disposition: attachment; filename="'.$filename.'"'); |
|
108 | 108 | echo $data; |
109 | 109 | ob_flush(); |
110 | 110 | ob_end_clean(); |
@@ -30,14 +30,14 @@ discard block |
||
30 | 30 | try { |
31 | 31 | $reflectionClass = new \ReflectionClass($this); |
32 | 32 | $properties = $reflectionClass->getProperties(\ReflectionProperty::IS_PUBLIC); |
33 | - if(count($properties) > 0) { |
|
33 | + if (count($properties) > 0) { |
|
34 | 34 | /** @var \ReflectionProperty $property */ |
35 | - foreach($properties as $property) { |
|
35 | + foreach ($properties as $property) { |
|
36 | 36 | $dto[$property->getName()] = $property->getValue($this); |
37 | 37 | } |
38 | 38 | } |
39 | - } catch(\Exception $e) { |
|
40 | - Logger::log(get_class($this) . ': ' . $e->getMessage(), LOG_ERR); |
|
39 | + }catch (\Exception $e) { |
|
40 | + Logger::log(get_class($this).': '.$e->getMessage(), LOG_ERR); |
|
41 | 41 | } |
42 | 42 | return $dto; |
43 | 43 | } |
@@ -57,9 +57,9 @@ discard block |
||
57 | 57 | */ |
58 | 58 | public function fromArray(array $object = array()) |
59 | 59 | { |
60 | - if(count($object) > 0) { |
|
61 | - foreach($object as $key => $value) { |
|
62 | - if(property_exists($this, $key)) { |
|
60 | + if (count($object) > 0) { |
|
61 | + foreach ($object as $key => $value) { |
|
62 | + if (property_exists($this, $key)) { |
|
63 | 63 | $this->$key = $value; |
64 | 64 | } |
65 | 65 | } |
@@ -33,10 +33,10 @@ |
||
33 | 33 | */ |
34 | 34 | private static function __init($instance) { |
35 | 35 | $loaded = false; |
36 | - if(method_exists($instance, 'isLoaded')) { |
|
36 | + if (method_exists($instance, 'isLoaded')) { |
|
37 | 37 | $loaded = $instance->isLoaded(); |
38 | 38 | } |
39 | - if(false === $loaded && method_exists($instance, "init")) { |
|
39 | + if (false === $loaded && method_exists($instance, "init")) { |
|
40 | 40 | $instance->init(); |
41 | 41 | } |
42 | 42 | } |
@@ -54,13 +54,13 @@ discard block |
||
54 | 54 | */ |
55 | 55 | public static function constructInyectableInstance($variable, $singleton, $classNameSpace, $calledClass) |
56 | 56 | { |
57 | - Logger::log('Create inyectable instance for ' . $classNameSpace); |
|
57 | + Logger::log('Create inyectable instance for '.$classNameSpace); |
|
58 | 58 | $reflector = new \ReflectionClass($calledClass); |
59 | 59 | $property = $reflector->getProperty($variable); |
60 | 60 | $varInstanceType = (null === $classNameSpace) ? InjectorHelper::extractVarType($property->getDocComment()) : $classNameSpace; |
61 | 61 | if (true === $singleton && method_exists($varInstanceType, "getInstance")) { |
62 | 62 | $instance = $varInstanceType::getInstance(); |
63 | - } else { |
|
63 | + }else { |
|
64 | 64 | $instance = new $varInstanceType(); |
65 | 65 | } |
66 | 66 | return $instance; |
@@ -74,7 +74,7 @@ discard block |
||
74 | 74 | public static function getClassProperties($class) |
75 | 75 | { |
76 | 76 | $properties = []; |
77 | - Logger::log('Extracting annotations properties from class ' . $class); |
|
77 | + Logger::log('Extracting annotations properties from class '.$class); |
|
78 | 78 | $selfReflector = new \ReflectionClass($class); |
79 | 79 | if (false !== $selfReflector->getParentClass()) { |
80 | 80 | $properties = self::getClassProperties($selfReflector->getParentClass()->getName()); |
@@ -23,7 +23,7 @@ |
||
23 | 23 | && (preg_match('/^\/(admin|setup\-admin)/i', $route) || NULL !== Config::getInstance()->get('restricted')) |
24 | 24 | ) { |
25 | 25 | |
26 | - if(!file_exists(CONFIG_DIR . DIRECTORY_SEPARATOR . 'admins.json')) { |
|
26 | + if (!file_exists(CONFIG_DIR.DIRECTORY_SEPARATOR.'admins.json')) { |
|
27 | 27 | //Si no hay fichero de usuarios redirigimos directamente al gestor |
28 | 28 | return UserController::getInstance()->adminers(); |
29 | 29 | } |