commit | author | age
|
73813a
|
1 |
<?php |
MC |
2 |
/** |
|
3 |
* sites_web_vhost_domain_plugin plugin |
|
4 |
* |
|
5 |
* @author Julio Montoya <gugli100@gmail.com> BeezNest 2010 |
|
6 |
*/ |
|
7 |
|
|
8 |
|
|
9 |
class sites_web_vhost_domain_plugin { |
|
10 |
|
|
11 |
var $plugin_name = 'sites_web_vhost_domain_plugin'; |
|
12 |
var $class_name = 'sites_web_vhost_domain_plugin'; |
|
13 |
|
|
14 |
// TODO: This function is a duplicate from the one in interface/web/sites/web_domain_edit.php |
|
15 |
// There should be a single "token replacement" function to be called from modules and |
|
16 |
// from the main code. |
|
17 |
// Returna a "3/2/1" path hash from a numeric id '123' |
|
18 |
function id_hash($id, $levels) { |
|
19 |
$hash = "" . $id % 10 ; |
|
20 |
$id /= 10 ; |
|
21 |
$levels -- ; |
|
22 |
while ( $levels > 0 ) { |
|
23 |
$hash .= "/" . $id % 10 ; |
|
24 |
$id /= 10 ; |
|
25 |
$levels-- ; |
|
26 |
} |
|
27 |
return $hash; |
|
28 |
} |
|
29 |
|
|
30 |
/* |
|
31 |
This function is called when the plugin is loaded |
|
32 |
*/ |
|
33 |
function onLoad() { |
|
34 |
global $app; |
|
35 |
//Register for the events |
|
36 |
$app->plugin->registerEvent('sites:web_vhost_domain:on_after_insert', 'sites_web_vhost_domain_plugin', 'sites_web_vhost_domain_edit'); |
|
37 |
$app->plugin->registerEvent('sites:web_vhost_domain:on_after_update', 'sites_web_vhost_domain_plugin', 'sites_web_vhost_domain_edit'); |
|
38 |
} |
|
39 |
|
|
40 |
/* |
|
41 |
Function to create the sites_web_domain rule and insert it into the custom rules |
|
42 |
*/ |
|
43 |
function sites_web_vhost_domain_edit($event_name, $page_form) { |
|
44 |
global $app, $conf; |
|
45 |
|
|
46 |
$vhostdomain_type = 'domain'; |
|
47 |
if($page_form->dataRecord['type'] == 'vhostalias') $vhostdomain_type = 'aliasdomain'; |
|
48 |
elseif($page_form->dataRecord['type'] == 'vhostsubdomain') $vhostdomain_type = 'subdomain'; |
|
49 |
|
|
50 |
// make sure that the record belongs to the clinet group and not the admin group when a dmin inserts it |
|
51 |
// also make sure that the user can not delete domain created by a admin |
|
52 |
if($_SESSION["s"]["user"]["typ"] == 'admin' && isset($page_form->dataRecord["client_group_id"])) { |
|
53 |
$client_group_id = $app->functions->intval($page_form->dataRecord["client_group_id"]); |
cc7a82
|
54 |
$app->db->query("UPDATE web_domain SET sys_groupid = ?, sys_perm_group = 'ru' WHERE domain_id = ?", $client_group_id, $page_form->id); |
73813a
|
55 |
} |
MC |
56 |
if($app->auth->has_clients($_SESSION['s']['user']['userid']) && isset($page_form->dataRecord["client_group_id"])) { |
|
57 |
$client_group_id = $app->functions->intval($page_form->dataRecord["client_group_id"]); |
cc7a82
|
58 |
$app->db->query("UPDATE web_domain SET sys_groupid = ?, sys_perm_group = 'riud' WHERE domain_id = ?", $client_group_id, $page_form->id); |
73813a
|
59 |
} |
MC |
60 |
// Get configuration for the web system |
|
61 |
$app->uses("getconf"); |
|
62 |
$web_config = $app->getconf->get_server_config($app->functions->intval($page_form->dataRecord['server_id']), 'web'); |
|
63 |
if(isset($app->tform) && is_object($app->tform)) $web_rec = $app->tform->getDataRecord($page_form->id); |
|
64 |
else $web_rec = $app->remoting_lib->getDataRecord($page_form->id); |
|
65 |
|
|
66 |
if($vhostdomain_type == 'domain') { |
|
67 |
$document_root = str_replace("[website_id]", $page_form->id, $web_config["website_path"]); |
|
68 |
$document_root = str_replace("[website_idhash_1]", $this->id_hash($page_form->id, 1), $document_root); |
|
69 |
$document_root = str_replace("[website_idhash_2]", $this->id_hash($page_form->id, 1), $document_root); |
|
70 |
$document_root = str_replace("[website_idhash_3]", $this->id_hash($page_form->id, 1), $document_root); |
|
71 |
$document_root = str_replace("[website_idhash_4]", $this->id_hash($page_form->id, 1), $document_root); |
|
72 |
|
|
73 |
// get the ID of the client |
|
74 |
if($_SESSION["s"]["user"]["typ"] != 'admin' && !$app->auth->has_clients($_SESSION['s']['user']['userid'])) { |
|
75 |
$client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]); |
cc7a82
|
76 |
$client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ?", $client_group_id); |
73813a
|
77 |
$client_id = $app->functions->intval($client["client_id"]); |
MC |
78 |
} elseif (isset($page_form->dataRecord["client_group_id"])) { |
|
79 |
$client_group_id = $page_form->dataRecord["client_group_id"]; |
cc7a82
|
80 |
$client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ?", $app->functions->intval(@$page_form->dataRecord["client_group_id"])); |
73813a
|
81 |
$client_id = $app->functions->intval($client["client_id"]); |
MC |
82 |
} else { |
ebbe63
|
83 |
$client_group_id = $page_form->dataRecord["client_group_id"]; |
cc7a82
|
84 |
$client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ?", $app->functions->intval($page_form->dataRecord["client_group_id"])); |
73813a
|
85 |
$client_id = $app->functions->intval($client["client_id"]); |
MC |
86 |
} |
|
87 |
|
0ba9a6
|
88 |
$tmp = $app->db->queryOneRecord("SELECT userid FROM sys_user WHERE default_group = ?", $client_group_id); |
ebbe63
|
89 |
$client_user_id = $app->functions->intval(($tmp['userid'] > 0)?$tmp['userid']:1); |
MC |
90 |
|
73813a
|
91 |
// Set the values for document_root, system_user and system_group |
cc7a82
|
92 |
$system_user = 'web'.$page_form->id; |
MC |
93 |
$system_group = 'client'.$client_id; |
73813a
|
94 |
|
MC |
95 |
$document_root = str_replace("[client_id]", $client_id, $document_root); |
|
96 |
$document_root = str_replace("[client_idhash_1]", $this->id_hash($client_id, 1), $document_root); |
|
97 |
$document_root = str_replace("[client_idhash_2]", $this->id_hash($client_id, 2), $document_root); |
|
98 |
$document_root = str_replace("[client_idhash_3]", $this->id_hash($client_id, 3), $document_root); |
|
99 |
$document_root = str_replace("[client_idhash_4]", $this->id_hash($client_id, 4), $document_root); |
|
100 |
|
|
101 |
if($event_name == 'sites:web_vhost_domain:on_after_update') { |
|
102 |
if(($_SESSION["s"]["user"]["typ"] == 'admin' || $app->auth->has_clients($_SESSION['s']['user']['userid'])) && isset($page_form->dataRecord["client_group_id"]) && $page_form->dataRecord["client_group_id"] != $page_form->oldDataRecord["sys_groupid"]) { |
|
103 |
|
cc7a82
|
104 |
$sql = "UPDATE web_domain SET system_user = ?, system_group = ?, document_root = ? WHERE domain_id = ?"; |
MC |
105 |
$app->db->query($sql, $system_user, $system_group, $document_root, $page_form->id); |
73813a
|
106 |
|
MC |
107 |
// Update the FTP user(s) too |
cc7a82
|
108 |
$records = $app->db->queryAllRecords("SELECT ftp_user_id FROM ftp_user WHERE parent_domain_id = ?", $page_form->id); |
73813a
|
109 |
foreach($records as $rec) { |
3a11d2
|
110 |
$app->db->datalogUpdate('ftp_user', array("sys_userid" => $web_rec['sys_userid'], "sys_groupid" => $web_rec['sys_groupid'], "uid" => $system_user, "gid" => $system_group, "dir" => $document_root), 'ftp_user_id', $app->functions->intval($rec['ftp_user_id'])); |
73813a
|
111 |
} |
MC |
112 |
unset($records); |
|
113 |
unset($rec); |
|
114 |
|
eb0b8f
|
115 |
// Update the webdav user(s) too |
cc7a82
|
116 |
$records = $app->db->queryAllRecords("SELECT webdav_user_id FROM webdav_user WHERE parent_domain_id = ?", $page_form->id); |
eb0b8f
|
117 |
foreach($records as $rec) { |
3a11d2
|
118 |
$app->db->datalogUpdate('webdav_user', array("sys_userid" => $web_rec['sys_userid'], "sys_groupid" => $web_rec['sys_groupid']), 'webdav_user_id', $app->functions->intval($rec['webdav_user_id'])); |
eb0b8f
|
119 |
} |
SC |
120 |
unset($records); |
|
121 |
unset($rec); |
|
122 |
|
|
123 |
// Update the web folder(s) too |
cc7a82
|
124 |
$records = $app->db->queryAllRecords("SELECT web_folder_id FROM web_folder WHERE parent_domain_id = ?", $page_form->id); |
eb0b8f
|
125 |
foreach($records as $rec) { |
3a11d2
|
126 |
$app->db->datalogUpdate('web_folder', array("sys_userid" => $web_rec['sys_userid'], "sys_groupid" => $web_rec['sys_groupid']), 'web_folder_id', $app->functions->intval($rec['web_folder_id'])); |
eb0b8f
|
127 |
} |
SC |
128 |
unset($records); |
|
129 |
unset($rec); |
|
130 |
|
|
131 |
//* Update all web folder users |
cc7a82
|
132 |
$records = $app->db->queryAllRecords("SELECT web_folder_user.web_folder_user_id FROM web_folder_user, web_folder WHERE web_folder_user.web_folder_id = web_folder.web_folder_id AND web_folder.parent_domain_id = ?", $page_form->id); |
eb0b8f
|
133 |
foreach($records as $rec) { |
3a11d2
|
134 |
$app->db->datalogUpdate('web_folder_user', array("sys_userid" => $web_rec['sys_userid'], "sys_groupid" => $web_rec['sys_groupid']), 'web_folder_user_id', $app->functions->intval($rec['web_folder_user_id'])); |
eb0b8f
|
135 |
} |
SC |
136 |
unset($records); |
|
137 |
unset($rec); |
|
138 |
|
73813a
|
139 |
// Update the Shell user(s) too |
cc7a82
|
140 |
$records = $app->db->queryAllRecords("SELECT shell_user_id FROM shell_user WHERE parent_domain_id = ?", $page_form->id); |
73813a
|
141 |
foreach($records as $rec) { |
3a11d2
|
142 |
$app->db->datalogUpdate('shell_user', array("sys_userid" => $web_rec['sys_userid'], "sys_groupid" => $web_rec['sys_groupid'], "puser" => $system_user, "pgroup" => $system_group, "dir" => $document_root), 'shell_user_id', $app->functions->intval($rec['shell_user_id'])); |
eb0b8f
|
143 |
} |
SC |
144 |
unset($records); |
|
145 |
unset($rec); |
|
146 |
|
|
147 |
// Update the cron(s) too |
cc7a82
|
148 |
$records = $app->db->queryAllRecords("SELECT id FROM cron WHERE parent_domain_id = ?", $page_form->id); |
eb0b8f
|
149 |
foreach($records as $rec) { |
3a11d2
|
150 |
$app->db->datalogUpdate('cron', array("sys_userid" => $web_rec['sys_userid'], "sys_groupid" => $web_rec['sys_groupid']), 'id', $app->functions->intval($rec['id'])); |
73813a
|
151 |
} |
MC |
152 |
unset($records); |
|
153 |
unset($rec); |
|
154 |
|
|
155 |
//* Update all subdomains and alias domains |
cc7a82
|
156 |
$records = $app->db->queryAllRecords("SELECT domain_id, `domain`, `type`, `web_folder` FROM web_domain WHERE parent_domain_id = ?", $page_form->id); |
73813a
|
157 |
foreach($records as $rec) { |
3a11d2
|
158 |
$update_columns = array("sys_userid" => $web_rec['sys_userid'], "sys_groupid" => $web_rec['sys_groupid']); |
73813a
|
159 |
if($rec['type'] == 'vhostsubdomain' || $rec['type'] == 'vhostalias') { |
MC |
160 |
$php_open_basedir = str_replace("[website_path]/web", $document_root.'/'.$rec['web_folder'], $web_config["php_open_basedir"]); |
|
161 |
$php_open_basedir = str_replace("[website_domain]/web", $rec['domain'].'/'.$rec['web_folder'], $php_open_basedir); |
|
162 |
$php_open_basedir = str_replace("[website_path]", $document_root, $php_open_basedir); |
3a11d2
|
163 |
$php_open_basedir = str_replace("[website_domain]", $rec['domain'], $php_open_basedir); |
73813a
|
164 |
|
3a11d2
|
165 |
$update_columns["document_root"] = $document_root; |
MC |
166 |
$update_columns["php_open_basedir"] = $php_open_basedir; |
73813a
|
167 |
} |
MC |
168 |
$app->db->datalogUpdate('web_domain', $update_columns, 'domain_id', $rec['domain_id']); |
|
169 |
} |
|
170 |
unset($records); |
|
171 |
unset($rec); |
|
172 |
|
|
173 |
//* Update all databases |
cc7a82
|
174 |
$records = $app->db->queryAllRecords("SELECT database_id FROM web_database WHERE parent_domain_id = ?", $page_form->id); |
73813a
|
175 |
foreach($records as $rec) { |
3a11d2
|
176 |
$app->db->datalogUpdate('web_database', array("sys_userid" => $web_rec['sys_userid'], "sys_groupid" => $web_rec['sys_groupid']), 'database_id', $app->functions->intval($rec['database_id'])); |
73813a
|
177 |
} |
eb0b8f
|
178 |
|
SC |
179 |
//* Update all database users |
cc7a82
|
180 |
$records = $app->db->queryAllRecords("SELECT web_database_user.database_user_id FROM web_database_user, web_database WHERE web_database_user.database_user_id IN (web_database.database_user_id, web_database.database_ro_user_id) AND web_database.parent_domain_id = ?", $page_form->id); |
eb0b8f
|
181 |
foreach($records as $rec) { |
3a11d2
|
182 |
$app->db->datalogUpdate('web_database_user', array("sys_userid" => $web_rec['sys_userid'], "sys_groupid" => $web_rec['sys_groupid']), 'database_user_id', $app->functions->intval($rec['database_user_id'])); |
eb0b8f
|
183 |
} |
SC |
184 |
unset($records); |
|
185 |
unset($rec); |
|
186 |
|
|
187 |
// Update APS instances |
cc7a82
|
188 |
$records = $app->db->queryAllRecords("SELECT instance_id FROM aps_instances_settings WHERE name = 'main_domain' AND value = ?", $page_form->oldDataRecord["domain"]); |
eb0b8f
|
189 |
if(is_array($records) && !empty($records)){ |
SC |
190 |
foreach($records as $rec){ |
3a11d2
|
191 |
$app->db->datalogUpdate('aps_instances', array("sys_userid" => $web_rec['sys_userid'], "sys_groupid" => $web_rec['sys_groupid'], "customer_id" => $client_id), 'id', $rec['instance_id']); |
eb0b8f
|
192 |
} |
SC |
193 |
} |
73813a
|
194 |
unset($records); |
MC |
195 |
unset($rec); |
|
196 |
|
|
197 |
} |
|
198 |
|
|
199 |
//* If the domain name has been changed, we will have to change all subdomains + APS instances |
|
200 |
if(!empty($page_form->dataRecord["domain"]) && !empty($page_form->oldDataRecord["domain"]) && $page_form->dataRecord["domain"] != $page_form->oldDataRecord["domain"]) { |
cc7a82
|
201 |
$records = $app->db->queryAllRecords("SELECT domain_id,domain FROM web_domain WHERE (type = 'subdomain' OR type = 'vhostsubdomain' OR type = 'vhostalias') AND domain LIKE ?", "%." . $page_form->oldDataRecord["domain"]); |
73813a
|
202 |
foreach($records as $rec) { |
3a11d2
|
203 |
$subdomain = str_replace($page_form->oldDataRecord["domain"], $page_form->dataRecord["domain"], $rec['domain']); |
MC |
204 |
$app->db->datalogUpdate('web_domain', array("domain" => $subdomain), 'domain_id', $rec['domain_id']); |
73813a
|
205 |
} |
MC |
206 |
unset($records); |
|
207 |
unset($rec); |
|
208 |
unset($subdomain); |
|
209 |
|
|
210 |
// Update APS instances |
cc7a82
|
211 |
$records = $app->db->queryAllRecords("SELECT id, instance_id FROM aps_instances_settings WHERE name = 'main_domain' AND value = ?", $page_form->oldDataRecord["domain"]); |
73813a
|
212 |
if(is_array($records) && !empty($records)){ |
MC |
213 |
foreach($records as $rec){ |
3a11d2
|
214 |
$app->db->datalogUpdate('aps_instances_settings', array("value" => $page_form->dataRecord["domain"]), 'id', $rec['id']); |
73813a
|
215 |
} |
MC |
216 |
} |
|
217 |
unset($records); |
|
218 |
unset($rec); |
|
219 |
} |
|
220 |
|
|
221 |
//* Set allow_override if empty |
|
222 |
if($web_rec['allow_override'] == '') { |
cc7a82
|
223 |
$sql = "UPDATE web_domain SET allow_override = ? WHERE domain_id = ?"; |
MC |
224 |
$app->db->query($sql, $web_config["htaccess_allow_override"], $page_form->id); |
73813a
|
225 |
} |
MC |
226 |
|
|
227 |
//* Set php_open_basedir if empty or domain or client has been changed |
|
228 |
if(empty($web_rec['php_open_basedir']) || |
|
229 |
(!empty($page_form->dataRecord["domain"]) && !empty($page_form->oldDataRecord["domain"]) && $page_form->dataRecord["domain"] != $page_form->oldDataRecord["domain"])) { |
|
230 |
$php_open_basedir = $web_rec['php_open_basedir']; |
2af58c
|
231 |
$php_open_basedir = str_replace($page_form->oldDataRecord['domain'], $web_rec['domain'], $php_open_basedir); |
cc7a82
|
232 |
$sql = "UPDATE web_domain SET php_open_basedir = ? WHERE domain_id = ?"; |
MC |
233 |
$app->db->query($sql, $php_open_basedir, $page_form->id); |
73813a
|
234 |
} |
MC |
235 |
if(empty($web_rec['php_open_basedir']) || |
|
236 |
(isset($page_form->dataRecord["client_group_id"]) && $page_form->dataRecord["client_group_id"] != $page_form->oldDataRecord["sys_groupid"])) { |
2af58c
|
237 |
$document_root = str_replace("[client_id]", $client_id, $document_root); |
73813a
|
238 |
$php_open_basedir = str_replace("[website_path]", $document_root, $web_config["php_open_basedir"]); |
2af58c
|
239 |
$php_open_basedir = str_replace("[website_domain]", $web_rec['domain'], $php_open_basedir); |
cc7a82
|
240 |
$sql = "UPDATE web_domain SET php_open_basedir = ? WHERE domain_id = ?"; |
MC |
241 |
$app->db->query($sql, $php_open_basedir, $page_form->id); |
73813a
|
242 |
} |
MC |
243 |
|
|
244 |
//* Change database backup options when web backup options have been changed |
|
245 |
if(isset($page_form->dataRecord['backup_interval']) && ($page_form->dataRecord['backup_interval'] != $page_form->oldDataRecord['backup_interval'] || $page_form->dataRecord['backup_copies'] != $page_form->oldDataRecord['backup_copies'])) { |
|
246 |
//* Update all databases |
2af58c
|
247 |
$backup_interval = $page_form->dataRecord['backup_interval']; |
73813a
|
248 |
$backup_copies = $app->functions->intval($page_form->dataRecord['backup_copies']); |
MC |
249 |
$records = $app->db->queryAllRecords("SELECT database_id FROM web_database WHERE parent_domain_id = ".$page_form->id); |
|
250 |
foreach($records as $rec) { |
2af58c
|
251 |
$app->db->datalogUpdate('web_database', array("backup_interval" => $backup_interval, "backup_copies" => $backup_copies), 'database_id', $rec['database_id']); |
73813a
|
252 |
} |
MC |
253 |
unset($records); |
|
254 |
unset($rec); |
|
255 |
unset($backup_copies); |
|
256 |
unset($backup_interval); |
|
257 |
} |
|
258 |
|
|
259 |
//* Change vhost subdomain and alias ip/ipv6 if domain ip/ipv6 has changed |
|
260 |
if(isset($page_form->dataRecord['ip_address']) && ($page_form->dataRecord['ip_address'] != $page_form->oldDataRecord['ip_address'] || $page_form->dataRecord['ipv6_address'] != $page_form->oldDataRecord['ipv6_address'])) { |
cc7a82
|
261 |
$records = $app->db->queryAllRecords("SELECT domain_id FROM web_domain WHERE (type = 'vhostsubdomain' OR type = 'vhostalias') AND parent_domain_id = ?", $page_form->id); |
73813a
|
262 |
foreach($records as $rec) { |
3a11d2
|
263 |
$app->db->datalogUpdate('web_domain', array("ip_address" => $web_rec['ip_address'], "ipv6_address" => $web_rec['ipv6_address']), 'domain_id', $rec['domain_id']); |
73813a
|
264 |
} |
MC |
265 |
unset($records); |
|
266 |
unset($rec); |
|
267 |
} |
|
268 |
} else { |
|
269 |
$php_open_basedir = str_replace("[website_path]", $document_root, $web_config["php_open_basedir"]); |
cc7a82
|
270 |
$php_open_basedir = str_replace("[website_domain]", $page_form->dataRecord['domain'], $php_open_basedir); |
MC |
271 |
$htaccess_allow_override = $web_config["htaccess_allow_override"]; |
|
272 |
|
|
273 |
$sql = "UPDATE web_domain SET system_user = ?, system_group = ?, document_root = ?, allow_override = ?, php_open_basedir = ? WHERE domain_id = ?"; |
|
274 |
$app->db->query($sql, $system_user, $system_group, $document_root, $htaccess_allow_override, $php_open_basedir, $page_form->id); |
73813a
|
275 |
} |
MC |
276 |
} else { |
363ccf
|
277 |
if(isset($page_form->dataRecord["parent_domain_id"]) && $page_form->dataRecord["parent_domain_id"] != $page_form->oldDataRecord["parent_domain_id"]) { |
cc7a82
|
278 |
$parent_domain = $app->db->queryOneRecord("SELECT * FROM `web_domain` WHERE `domain_id` = ?", $page_form->dataRecord['parent_domain_id']); |
73813a
|
279 |
|
363ccf
|
280 |
// Set the values for document_root, system_user and system_group |
cc7a82
|
281 |
$system_user = $parent_domain['system_user']; |
MC |
282 |
$system_group = $parent_domain['system_group']; |
|
283 |
$document_root = $parent_domain['document_root']; |
363ccf
|
284 |
$php_open_basedir = str_replace("[website_path]/web", $document_root.'/'.$page_form->dataRecord['web_folder'], $web_config["php_open_basedir"]); |
MC |
285 |
$php_open_basedir = str_replace("[website_domain]/web", $page_form->dataRecord['domain'].'/'.$page_form->dataRecord['web_folder'], $php_open_basedir); |
|
286 |
$php_open_basedir = str_replace("[website_path]", $document_root, $php_open_basedir); |
cc7a82
|
287 |
$php_open_basedir = str_replace("[website_domain]", $page_form->dataRecord['domain'], $php_open_basedir); |
MC |
288 |
$htaccess_allow_override = $parent_domain['allow_override']; |
|
289 |
$sql = "UPDATE web_domain SET sys_groupid = ?,system_user = ?, system_group = ?, document_root = ?, allow_override = ?, php_open_basedir = ? WHERE domain_id = ?"; |
|
290 |
$app->db->query($sql, $parent_domain['sys_groupid'], $system_user, $system_group, $document_root, $htaccess_allow_override, $php_open_basedir, $page_form->id); |
363ccf
|
291 |
} |
73813a
|
292 |
} |
MC |
293 |
} |
|
294 |
|
|
295 |
} |