Completed
Pull Request — release-2.1 (#3761)
by Rick
07:38
created
Sources/Subs-MembersOnline.php 1 patch
Braces   +30 added lines, -23 removed lines patch added patch discarded remove patch
@@ -13,8 +13,9 @@  discard block
 block discarded – undo
13 13
  * @version 2.1 Beta 3
14 14
  */
15 15
 
16
-if (!defined('SMF'))
16
+if (!defined('SMF')) {
17 17
 	die('No direct access...');
18
+}
18 19
 
19 20
 /**
20 21
  * Retrieve a list and several other statistics of the users currently online.
@@ -45,12 +46,14 @@  discard block
 block discarded – undo
45 46
 	}
46 47
 
47 48
 	// Not allowed sort method? Bang! Error!
48
-	elseif (!in_array($membersOnlineOptions['sort'], $allowed_sort_options))
49
-		trigger_error('Sort method for getMembersOnlineStats() function is not allowed', E_USER_NOTICE);
49
+	elseif (!in_array($membersOnlineOptions['sort'], $allowed_sort_options)) {
50
+			trigger_error('Sort method for getMembersOnlineStats() function is not allowed', E_USER_NOTICE);
51
+	}
50 52
 
51 53
 	// Get it from the cache and send it back.
52
-	if (($temp = cache_get_data('membersOnlineStats-' . $membersOnlineOptions['sort'], 240)) !== null)
53
-		return $temp;
54
+	if (($temp = cache_get_data('membersOnlineStats-' . $membersOnlineOptions['sort'], 240)) !== null) {
55
+			return $temp;
56
+	}
54 57
 
55 58
 	// Initialize the array that'll be returned later on.
56 59
 	$membersOnlineStats = array(
@@ -67,8 +70,9 @@  discard block
 block discarded – undo
67 70
 	// Get any spiders if enabled.
68 71
 	$spiders = array();
69 72
 	$spider_finds = array();
70
-	if (!empty($modSettings['show_spider_online']) && ($modSettings['show_spider_online'] < 3 || allowedTo('admin_forum')) && !empty($modSettings['spider_name_cache']))
71
-		$spiders = smf_json_decode($modSettings['spider_name_cache'], true);
73
+	if (!empty($modSettings['show_spider_online']) && ($modSettings['show_spider_online'] < 3 || allowedTo('admin_forum')) && !empty($modSettings['spider_name_cache'])) {
74
+			$spiders = smf_json_decode($modSettings['spider_name_cache'], true);
75
+	}
72 76
 
73 77
 	// Load the users online right now.
74 78
 	$request = $smcFunc['db_query']('', '
@@ -96,9 +100,7 @@  discard block
 block discarded – undo
96 100
 			$membersOnlineStats['num_guests']++;
97 101
 
98 102
 			continue;
99
-		}
100
-
101
-		elseif (empty($row['show_online']) && empty($membersOnlineOptions['show_hidden']))
103
+		} elseif (empty($row['show_online']) && empty($membersOnlineOptions['show_hidden']))
102 104
 		{
103 105
 			// Just increase the stats and don't add this hidden user to any list.
104 106
 			$membersOnlineStats['num_users_hidden']++;
@@ -106,10 +108,11 @@  discard block
 block discarded – undo
106 108
 		}
107 109
 
108 110
 		// Some basic color coding...
109
-		if (!empty($row['online_color']))
110
-			$link = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '" style="color: ' . $row['online_color'] . ';">' . $row['real_name'] . '</a>';
111
-		else
112
-			$link = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>';
111
+		if (!empty($row['online_color'])) {
112
+					$link = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '" style="color: ' . $row['online_color'] . ';">' . $row['real_name'] . '</a>';
113
+		} else {
114
+					$link = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>';
115
+		}
113 116
 
114 117
 		// Buddies get counted and highlighted.
115 118
 		$is_buddy = in_array($row['id_member'], $user_info['buddies']);
@@ -136,12 +139,13 @@  discard block
 block discarded – undo
136 139
 		$membersOnlineStats['list_users_online'][$row[$membersOnlineOptions['sort']] . '_' . $row['member_name']] = empty($row['show_online']) ? '<em>' . $link . '</em>' : $link;
137 140
 
138 141
 		// Store all distinct (primary) membergroups that are shown.
139
-		if (!isset($membersOnlineStats['online_groups'][$row['id_group']]))
140
-			$membersOnlineStats['online_groups'][$row['id_group']] = array(
142
+		if (!isset($membersOnlineStats['online_groups'][$row['id_group']])) {
143
+					$membersOnlineStats['online_groups'][$row['id_group']] = array(
141 144
 				'id' => $row['id_group'],
142 145
 				'name' => $row['group_name'],
143 146
 				'color' => $row['online_color']
144 147
 			);
148
+		}
145 149
 	}
146 150
 	$smcFunc['db_free_result']($request);
147 151
 
@@ -204,11 +208,12 @@  discard block
 block discarded – undo
204 208
 	$settingsToUpdate = array();
205 209
 
206 210
 	// More members on now than ever were?  Update it!
207
-	if (!isset($modSettings['mostOnline']) || $total_users_online >= $modSettings['mostOnline'])
208
-		$settingsToUpdate = array(
211
+	if (!isset($modSettings['mostOnline']) || $total_users_online >= $modSettings['mostOnline']) {
212
+			$settingsToUpdate = array(
209 213
 			'mostOnline' => $total_users_online,
210 214
 			'mostDate' => time()
211 215
 		);
216
+	}
212 217
 
213 218
 	$date = strftime('%Y-%m-%d', forum_time(false));
214 219
 
@@ -240,8 +245,9 @@  discard block
 block discarded – undo
240 245
 		{
241 246
 			list ($modSettings['mostOnlineToday']) = $smcFunc['db_fetch_row']($request);
242 247
 
243
-			if ($total_users_online > $modSettings['mostOnlineToday'])
244
-				trackStats(array('most_on' => $total_users_online));
248
+			if ($total_users_online > $modSettings['mostOnlineToday']) {
249
+							trackStats(array('most_on' => $total_users_online));
250
+			}
245 251
 
246 252
 			$total_users_online = max($total_users_online, $modSettings['mostOnlineToday']);
247 253
 		}
@@ -258,8 +264,9 @@  discard block
 block discarded – undo
258 264
 		$settingsToUpdate['mostOnlineToday'] = $total_users_online;
259 265
 	}
260 266
 
261
-	if (!empty($settingsToUpdate))
262
-		updateSettings($settingsToUpdate);
263
-}
267
+	if (!empty($settingsToUpdate)) {
268
+			updateSettings($settingsToUpdate);
269
+	}
270
+	}
264 271
 
265 272
 ?>
266 273
\ No newline at end of file
Please login to merge, or discard this patch.
Sources/Subs-Notify.php 1 patch
Braces   +17 added lines, -11 removed lines patch added patch discarded remove patch
@@ -11,8 +11,9 @@  discard block
 block discarded – undo
11 11
  * @version 2.1 Beta 3
12 12
  */
13 13
 
14
-if (!defined('SMF'))
14
+if (!defined('SMF')) {
15 15
 	die('No direct access...');
16
+}
16 17
 
17 18
 /**
18 19
  * Fetches the list of preferences (or a single/subset of preferences) for
@@ -30,8 +31,9 @@  discard block
 block discarded – undo
30 31
 	// We want this as an array whether it is or not.
31 32
 	$members = is_array($members) ? $members : (array) $members;
32 33
 
33
-	if (!empty($prefs))
34
-		$prefs = is_array($prefs) ? $prefs : (array) $prefs;
34
+	if (!empty($prefs)) {
35
+			$prefs = is_array($prefs) ? $prefs : (array) $prefs;
36
+	}
35 37
 
36 38
 	$result = array();
37 39
 
@@ -56,9 +58,10 @@  discard block
 block discarded – undo
56 58
 	// We may want to keep the default values separate from a given user's. Or we might not.
57 59
 	if ($process_default && isset($result[0]))
58 60
 	{
59
-		foreach ($members as $member)
60
-			if (!isset($result[$member]))
61
+		foreach ($members as $member) {
62
+					if (!isset($result[$member]))
61 63
 				$result[$member] = $result[0];
64
+		}
62 65
 
63 66
 		unset ($result[0]);
64 67
 	}
@@ -76,12 +79,14 @@  discard block
 block discarded – undo
76 79
 {
77 80
 	global $smcFunc;
78 81
 
79
-	if (empty($prefs) || !is_int($memID))
80
-		return;
82
+	if (empty($prefs) || !is_int($memID)) {
83
+			return;
84
+	}
81 85
 
82 86
 	$update_rows = array();
83
-	foreach ($prefs as $k => $v)
84
-		$update_rows[] = array($memID, $k, $v);
87
+	foreach ($prefs as $k => $v) {
88
+			$update_rows[] = array($memID, $k, $v);
89
+	}
85 90
 
86 91
 	$smcFunc['db_insert']('replace',
87 92
 		'{db_prefix}user_alerts_prefs',
@@ -101,8 +106,9 @@  discard block
 block discarded – undo
101 106
 {
102 107
 	global $smcFunc;
103 108
 
104
-	if (empty($prefs) || empty($memID))
105
-		return;
109
+	if (empty($prefs) || empty($memID)) {
110
+			return;
111
+	}
106 112
 
107 113
 	$smcFunc['db_query']('', '
108 114
 		DELETE FROM {db_prefix}user_alerts_prefs
Please login to merge, or discard this patch.
Sources/RepairBoards.php 2 patches
Spacing   +37 added lines, -37 removed lines patch added patch discarded remove patch
@@ -232,7 +232,7 @@  discard block
 block discarded – undo
232 232
 					LEFT JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
233 233
 				WHERE t.id_topic IS NULL
234 234
 				GROUP BY m.id_topic, m.id_board',
235
-			'fix_processing' => function ($row) use ($smcFunc)
235
+			'fix_processing' => function($row) use ($smcFunc)
236 236
 			{
237 237
 				global $salvageBoardID;
238 238
 
@@ -319,7 +319,7 @@  discard block
 block discarded – undo
319 319
 			// Remove all topics that have zero messages in the messages table.
320 320
 			'fix_collect' => array(
321 321
 				'index' => 'id_topic',
322
-				'process' => function ($topics) use ($smcFunc)
322
+				'process' => function($topics) use ($smcFunc)
323 323
 				{
324 324
 					$smcFunc['db_query']('', '
325 325
 						DELETE FROM {db_prefix}topics
@@ -357,21 +357,21 @@  discard block
 block discarded – undo
357 357
 				  AND p.id_poll IS NULL
358 358
 				GROUP BY o.id_poll
359 359
 				  ',
360
-			'fix_processing' => function ($row) use ($smcFunc, $txt)
360
+			'fix_processing' => function($row) use ($smcFunc, $txt)
361 361
 			{
362 362
 				global $salvageBoardID;
363 363
 
364 364
 				$row['poster_name'] = !empty($row['poster_name']) ? $row['poster_name'] : $txt['guest'];
365 365
 				$row['id_poster'] = !empty($row['id_poster']) ? $row['id_poster'] : 0;
366 366
 
367
-				if(empty($row['id_board']))
367
+				if (empty($row['id_board']))
368 368
 				{
369 369
 					// Only if we don't have a reasonable idea of where to put it.
370 370
 					createSalvageArea();
371
-					$row['id_board'] = (int)$salvageBoardID;
371
+					$row['id_board'] = (int) $salvageBoardID;
372 372
 				}
373 373
 
374
-				if(empty($row['id_topic'])) {
374
+				if (empty($row['id_topic'])) {
375 375
 					$smcFunc['db_insert']('',
376 376
 						'{db_prefix}messages',
377 377
 						array(
@@ -495,7 +495,7 @@  discard block
 block discarded – undo
495 495
 					LEFT JOIN {db_prefix}topics AS t ON (t.id_poll = p.id_poll)
496 496
 				WHERE p.id_poll BETWEEN {STEP_LOW} AND {STEP_HIGH}
497 497
 					AND t.id_poll IS NULL',
498
-			'fix_processing' => function ($row) use ($smcFunc, $txt)
498
+			'fix_processing' => function($row) use ($smcFunc, $txt)
499 499
 			{
500 500
 				global $salvageBoardID;
501 501
 
@@ -610,7 +610,7 @@  discard block
 block discarded – undo
610 610
 				WHERE t.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
611 611
 				GROUP BY t.id_topic, t.id_first_msg, t.id_last_msg, t.approved, mf.approved
612 612
 				ORDER BY t.id_topic',
613
-			'fix_processing' => function ($row) use ($smcFunc)
613
+			'fix_processing' => function($row) use ($smcFunc)
614 614
 			{
615 615
 				$row['firstmsg_approved'] = (int) $row['firstmsg_approved'];
616 616
 				$row['myid_first_msg'] = (int) $row['myid_first_msg'];
@@ -639,7 +639,7 @@  discard block
 block discarded – undo
639 639
 					)
640 640
 				);
641 641
 			},
642
-			'message_function' => function ($row) use ($txt, &$context)
642
+			'message_function' => function($row) use ($txt, &$context)
643 643
 			{
644 644
 				// A pretend error?
645 645
 				if ($row['myid_first_msg'] == $row['myid_first_msg'] && $row['myid_first_msg'] == $row['myid_first_msg'] && $row['approved'] == $row['firstmsg_approved'])
@@ -673,7 +673,7 @@  discard block
 block discarded – undo
673 673
 				WHERE t.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
674 674
 				GROUP BY t.id_topic, t.num_replies, mf.approved
675 675
 				ORDER BY t.id_topic',
676
-			'fix_processing' => function ($row)
676
+			'fix_processing' => function($row)
677 677
 		{
678 678
 
679 679
 				global $smcFunc;
@@ -694,7 +694,7 @@  discard block
 block discarded – undo
694 694
 				);
695 695
 
696 696
 		},
697
-			'message_function' => function ($row)
697
+			'message_function' => function($row)
698 698
 		{
699 699
 
700 700
 				global $txt, $context;
@@ -727,7 +727,7 @@  discard block
 block discarded – undo
727 727
 				GROUP BY t.id_topic, t.unapproved_posts
728 728
 				HAVING unapproved_posts != COUNT(mu.id_msg)
729 729
 				ORDER BY t.id_topic',
730
-			'fix_processing' => function ($row)
730
+			'fix_processing' => function($row)
731 731
 		{
732 732
 
733 733
 				global $smcFunc;
@@ -769,7 +769,7 @@  discard block
 block discarded – undo
769 769
 				WHERE b.id_board IS NULL
770 770
 					AND t.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
771 771
 				GROUP BY t.id_board',
772
-			'fix_processing' => function ($row)
772
+			'fix_processing' => function($row)
773 773
 		{
774 774
 
775 775
 				global $smcFunc, $salvageCatID, $txt;
@@ -818,7 +818,7 @@  discard block
 block discarded – undo
818 818
 				ORDER BY b.id_cat, b.id_board',
819 819
 			'fix_collect' => array(
820 820
 				'index' => 'id_cat',
821
-				'process' => function ($cats)
821
+				'process' => function($cats)
822 822
 				{
823 823
 					global $smcFunc, $salvageCatID;
824 824
 					createSalvageArea();
@@ -854,7 +854,7 @@  discard block
 block discarded – undo
854 854
 			// Last step-make sure all non-guest posters still exist.
855 855
 			'fix_collect' => array(
856 856
 				'index' => 'id_msg',
857
-				'process' => function ($msgs)
857
+				'process' => function($msgs)
858 858
 		{
859 859
 
860 860
 					global $smcFunc;
@@ -883,7 +883,7 @@  discard block
 block discarded – undo
883 883
 				ORDER BY b.id_parent, b.id_board',
884 884
 			'fix_collect' => array(
885 885
 				'index' => 'id_parent',
886
-				'process' => function ($parents)
886
+				'process' => function($parents)
887 887
 				{
888 888
 					global $smcFunc, $salvageBoardID, $salvageCatID;
889 889
 					createSalvageArea();
@@ -917,7 +917,7 @@  discard block
 block discarded – undo
917 917
 					AND p.id_poll IS NULL',
918 918
 			'fix_collect' => array(
919 919
 				'index' => 'id_poll',
920
-				'process' => function ($polls)
920
+				'process' => function($polls)
921 921
 		{
922 922
 
923 923
 					global $smcFunc;
@@ -951,7 +951,7 @@  discard block
 block discarded – undo
951 951
 				ORDER BY cal.id_topic',
952 952
 			'fix_collect' => array(
953 953
 				'index' => 'id_topic',
954
-				'process' => function ($events)
954
+				'process' => function($events)
955 955
 		{
956 956
 
957 957
 					global $smcFunc;
@@ -983,7 +983,7 @@  discard block
 block discarded – undo
983 983
 					AND lt.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}',
984 984
 			'fix_collect' => array(
985 985
 				'index' => 'id_topic',
986
-				'process' => function ($topics)
986
+				'process' => function($topics)
987 987
 		{
988 988
 
989 989
 					global $smcFunc;
@@ -1015,7 +1015,7 @@  discard block
 block discarded – undo
1015 1015
 				GROUP BY lt.id_member',
1016 1016
 			'fix_collect' => array(
1017 1017
 				'index' => 'id_member',
1018
-				'process' => function ($members)
1018
+				'process' => function($members)
1019 1019
 		{
1020 1020
 
1021 1021
 					global $smcFunc;
@@ -1047,7 +1047,7 @@  discard block
 block discarded – undo
1047 1047
 				GROUP BY lb.id_board',
1048 1048
 			'fix_collect' => array(
1049 1049
 				'index' => 'id_board',
1050
-				'process' => function ($boards)
1050
+				'process' => function($boards)
1051 1051
 		{
1052 1052
 
1053 1053
 					global $smcFunc;
@@ -1079,7 +1079,7 @@  discard block
 block discarded – undo
1079 1079
 				GROUP BY lb.id_member',
1080 1080
 			'fix_collect' => array(
1081 1081
 				'index' => 'id_member',
1082
-				'process' => function ($members) use ($smcFunc)
1082
+				'process' => function($members) use ($smcFunc)
1083 1083
 				{
1084 1084
 					$smcFunc['db_query']('', '
1085 1085
 						DELETE FROM {db_prefix}log_boards
@@ -1108,7 +1108,7 @@  discard block
 block discarded – undo
1108 1108
 				GROUP BY lmr.id_board',
1109 1109
 			'fix_collect' => array(
1110 1110
 				'index' => 'id_board',
1111
-				'process' => function ($boards) use ($smcFunc)
1111
+				'process' => function($boards) use ($smcFunc)
1112 1112
 				{
1113 1113
 					$smcFunc['db_query']('', '
1114 1114
 						DELETE FROM {db_prefix}log_mark_read
@@ -1137,7 +1137,7 @@  discard block
 block discarded – undo
1137 1137
 				GROUP BY lmr.id_member',
1138 1138
 			'fix_collect' => array(
1139 1139
 				'index' => 'id_member',
1140
-				'process' => function ($members) use ($smcFunc)
1140
+				'process' => function($members) use ($smcFunc)
1141 1141
 				{
1142 1142
 					$smcFunc['db_query']('', '
1143 1143
 						DELETE FROM {db_prefix}log_mark_read
@@ -1166,7 +1166,7 @@  discard block
 block discarded – undo
1166 1166
 				GROUP BY pmr.id_pm',
1167 1167
 			'fix_collect' => array(
1168 1168
 				'index' => 'id_pm',
1169
-				'process' => function ($pms) use ($smcFunc)
1169
+				'process' => function($pms) use ($smcFunc)
1170 1170
 				{
1171 1171
 					$smcFunc['db_query']('', '
1172 1172
 						DELETE FROM {db_prefix}pm_recipients
@@ -1196,7 +1196,7 @@  discard block
 block discarded – undo
1196 1196
 				GROUP BY pmr.id_member',
1197 1197
 			'fix_collect' => array(
1198 1198
 				'index' => 'id_member',
1199
-				'process' => function ($members)
1199
+				'process' => function($members)
1200 1200
 		{
1201 1201
 
1202 1202
 					global $smcFunc;
@@ -1228,7 +1228,7 @@  discard block
 block discarded – undo
1228 1228
 					AND mem.id_member IS NULL',
1229 1229
 			'fix_collect' => array(
1230 1230
 				'index' => 'id_pm',
1231
-				'process' => function ($guestMessages)
1231
+				'process' => function($guestMessages)
1232 1232
 		{
1233 1233
 
1234 1234
 					global $smcFunc;
@@ -1260,7 +1260,7 @@  discard block
 block discarded – undo
1260 1260
 				GROUP BY ln.id_member',
1261 1261
 			'fix_collect' => array(
1262 1262
 				'index' => 'id_member',
1263
-				'process' => function ($members) use ($smcFunc)
1263
+				'process' => function($members) use ($smcFunc)
1264 1264
 				{
1265 1265
 					$smcFunc['db_query']('', '
1266 1266
 						DELETE FROM {db_prefix}log_notify
@@ -1287,7 +1287,7 @@  discard block
 block discarded – undo
1287 1287
 					LEFT JOIN {db_prefix}log_search_subjects AS lss ON (lss.id_topic = t.id_topic)
1288 1288
 				WHERE t.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
1289 1289
 					AND lss.id_topic IS NULL',
1290
-			'fix_full_processing' => function ($result)
1290
+			'fix_full_processing' => function($result)
1291 1291
 		{
1292 1292
 
1293 1293
 				global $smcFunc;
@@ -1319,7 +1319,7 @@  discard block
 block discarded – undo
1319 1319
 					);
1320 1320
 
1321 1321
 		},
1322
-			'message_function' => function ($row)
1322
+			'message_function' => function($row)
1323 1323
 		{
1324 1324
 
1325 1325
 				global $txt, $context;
@@ -1349,7 +1349,7 @@  discard block
 block discarded – undo
1349 1349
 					AND t.id_topic IS NULL',
1350 1350
 			'fix_collect' => array(
1351 1351
 				'index' => 'id_topic',
1352
-				'process' => function ($deleteTopics)
1352
+				'process' => function($deleteTopics)
1353 1353
 		{
1354 1354
 
1355 1355
 					global $smcFunc;
@@ -1381,7 +1381,7 @@  discard block
 block discarded – undo
1381 1381
 					AND mem.id_member IS NULL',
1382 1382
 			'fix_collect' => array(
1383 1383
 				'index' => 'id_member',
1384
-				'process' => function ($members)
1384
+				'process' => function($members)
1385 1385
 		{
1386 1386
 
1387 1387
 					global $smcFunc;
@@ -1412,7 +1412,7 @@  discard block
 block discarded – undo
1412 1412
 					AND p.id_poll IS NULL',
1413 1413
 			'fix_collect' => array(
1414 1414
 				'index' => 'id_poll',
1415
-				'process' => function ($polls)
1415
+				'process' => function($polls)
1416 1416
 		{
1417 1417
 
1418 1418
 					global $smcFunc;
@@ -1443,7 +1443,7 @@  discard block
 block discarded – undo
1443 1443
 					AND lrc.id_report IS NULL',
1444 1444
 			'fix_collect' => array(
1445 1445
 				'index' => 'id_report',
1446
-				'process' => function ($reports)
1446
+				'process' => function($reports)
1447 1447
 		{
1448 1448
 
1449 1449
 					global $smcFunc;
@@ -1474,7 +1474,7 @@  discard block
 block discarded – undo
1474 1474
 					AND lr.id_report IS NULL',
1475 1475
 			'fix_collect' => array(
1476 1476
 				'index' => 'id_report',
1477
-				'process' => function ($reports)
1477
+				'process' => function($reports)
1478 1478
 				{
1479 1479
 					global $smcFunc;
1480 1480
 					$smcFunc['db_query']('', '
@@ -1504,7 +1504,7 @@  discard block
 block discarded – undo
1504 1504
 				GROUP BY lgr.id_member',
1505 1505
 			'fix_collect' => array(
1506 1506
 				'index' => 'id_member',
1507
-				'process' => function ($members)
1507
+				'process' => function($members)
1508 1508
 				{
1509 1509
 					global $smcFunc;
1510 1510
 					$smcFunc['db_query']('', '
@@ -1534,7 +1534,7 @@  discard block
 block discarded – undo
1534 1534
 				GROUP BY lgr.id_group',
1535 1535
 			'fix_collect' => array(
1536 1536
 				'index' => 'id_group',
1537
-				'process' => function ($groups)
1537
+				'process' => function($groups)
1538 1538
 				{
1539 1539
 					global $smcFunc;
1540 1540
 					$smcFunc['db_query']('', '
Please login to merge, or discard this patch.
Braces   +119 added lines, -85 removed lines patch added patch discarded remove patch
@@ -13,8 +13,9 @@  discard block
 block discarded – undo
13 13
  * @version 2.1 Beta 3
14 14
  */
15 15
 
16
-if (!defined('SMF'))
16
+if (!defined('SMF')) {
17 17
 	die('No direct access...');
18
+}
18 19
 
19 20
 /**
20 21
  * Finds or repairs errors in the database to fix possible problems.
@@ -50,8 +51,9 @@  discard block
 block discarded – undo
50 51
 	);
51 52
 
52 53
 	// Start displaying errors without fixing them.
53
-	if (isset($_GET['fixErrors']))
54
-		checkSession('get');
54
+	if (isset($_GET['fixErrors'])) {
55
+			checkSession('get');
56
+	}
55 57
 
56 58
 	// Will want this.
57 59
 	loadForumTests();
@@ -69,11 +71,11 @@  discard block
 block discarded – undo
69 71
 			$_SESSION['repairboards_to_fix'] = $context['to_fix'];
70 72
 			$_SESSION['repairboards_to_fix2'] = null;
71 73
 
72
-			if (empty($context['repair_errors']))
73
-				$context['repair_errors'][] = '???';
74
+			if (empty($context['repair_errors'])) {
75
+							$context['repair_errors'][] = '???';
76
+			}
74 77
 		}
75
-	}
76
-	else
78
+	} else
77 79
 	{
78 80
 		$context['error_search'] = false;
79 81
 		$context['to_fix'] = isset($_SESSION['repairboards_to_fix']) ? $_SESSION['repairboards_to_fix'] : array();
@@ -120,16 +122,19 @@  discard block
 block discarded – undo
120 122
 
121 123
 	// More time, I need more time!
122 124
 	@set_time_limit(600);
123
-	if (function_exists('apache_reset_timeout'))
124
-		@apache_reset_timeout();
125
+	if (function_exists('apache_reset_timeout')) {
126
+			@apache_reset_timeout();
127
+	}
125 128
 
126 129
 	// Errr, wait.  How much time has this taken already?
127
-	if (!$force && time() - array_sum(explode(' ', $time_start)) < 3)
128
-		return;
130
+	if (!$force && time() - array_sum(explode(' ', $time_start)) < 3) {
131
+			return;
132
+	}
129 133
 
130 134
 	// Restore the query cache if interested.
131
-	if (!empty($db_temp_cache))
132
-		$db_cache = $db_temp_cache;
135
+	if (!empty($db_temp_cache)) {
136
+			$db_cache = $db_temp_cache;
137
+	}
133 138
 
134 139
 	$context['continue_get_data'] = '?action=admin;area=repairboards' . (isset($_GET['fixErrors']) ? ';fixErrors' : '') . ';step=' . $_GET['step'] . ';substep=' . $_GET['substep'] . ';' . $context['session_var'] . '=' . $context['session_id'];
135 140
 	$context['page_title'] = $txt['not_done_title'];
@@ -138,10 +143,11 @@  discard block
 block discarded – undo
138 143
 	$context['sub_template'] = 'not_done';
139 144
 
140 145
 	// Change these two if more steps are added!
141
-	if (empty($max_substep))
142
-		$context['continue_percent'] = round(($_GET['step'] * 100) / $context['total_steps']);
143
-	else
144
-		$context['continue_percent'] = round((($_GET['step'] + ($_GET['substep'] / $max_substep)) * 100) / $context['total_steps']);
146
+	if (empty($max_substep)) {
147
+			$context['continue_percent'] = round(($_GET['step'] * 100) / $context['total_steps']);
148
+	} else {
149
+			$context['continue_percent'] = round((($_GET['step'] + ($_GET['substep'] / $max_substep)) * 100) / $context['total_steps']);
150
+	}
145 151
 
146 152
 	// Never more than 100%!
147 153
 	$context['continue_percent'] = min($context['continue_percent'], 100);
@@ -617,8 +623,9 @@  discard block
 block discarded – undo
617 623
 				$row['myid_last_msg'] = (int) $row['myid_last_msg'];
618 624
 
619 625
 				// Not really a problem?
620
-				if ($row['myid_first_msg'] == $row['myid_first_msg'] && $row['myid_first_msg'] == $row['myid_first_msg'] && $row['approved'] == $row['firstmsg_approved'])
621
-					return false;
626
+				if ($row['myid_first_msg'] == $row['myid_first_msg'] && $row['myid_first_msg'] == $row['myid_first_msg'] && $row['approved'] == $row['firstmsg_approved']) {
627
+									return false;
628
+				}
622 629
 
623 630
 				$memberStartedID = (int) getMsgMemberID($row['myid_first_msg']);
624 631
 				$memberUpdatedID = (int) getMsgMemberID($row['myid_last_msg']);
@@ -642,15 +649,19 @@  discard block
 block discarded – undo
642 649
 			'message_function' => function ($row) use ($txt, &$context)
643 650
 			{
644 651
 				// A pretend error?
645
-				if ($row['myid_first_msg'] == $row['myid_first_msg'] && $row['myid_first_msg'] == $row['myid_first_msg'] && $row['approved'] == $row['firstmsg_approved'])
646
-					return false;
652
+				if ($row['myid_first_msg'] == $row['myid_first_msg'] && $row['myid_first_msg'] == $row['myid_first_msg'] && $row['approved'] == $row['firstmsg_approved']) {
653
+									return false;
654
+				}
647 655
 
648
-				if ($row['id_first_msg'] != $row['myid_first_msg'])
649
-					$context['repair_errors'][] = sprintf($txt['repair_stats_topics_1'], $row['id_topic'], $row['id_first_msg']);
650
-				if ($row['id_last_msg'] != $row['myid_last_msg'])
651
-					$context['repair_errors'][] = sprintf($txt['repair_stats_topics_2'], $row['id_topic'], $row['id_last_msg']);
652
-				if ($row['approved'] != $row['firstmsg_approved'])
653
-					$context['repair_errors'][] = sprintf($txt['repair_stats_topics_5'], $row['id_topic']);
656
+				if ($row['id_first_msg'] != $row['myid_first_msg']) {
657
+									$context['repair_errors'][] = sprintf($txt['repair_stats_topics_1'], $row['id_topic'], $row['id_first_msg']);
658
+				}
659
+				if ($row['id_last_msg'] != $row['myid_last_msg']) {
660
+									$context['repair_errors'][] = sprintf($txt['repair_stats_topics_2'], $row['id_topic'], $row['id_last_msg']);
661
+				}
662
+				if ($row['approved'] != $row['firstmsg_approved']) {
663
+									$context['repair_errors'][] = sprintf($txt['repair_stats_topics_5'], $row['id_topic']);
664
+				}
654 665
 
655 666
 				return true;
656 667
 			},
@@ -680,8 +691,9 @@  discard block
 block discarded – undo
680 691
 				$row['my_num_replies'] = (int) $row['my_num_replies'];
681 692
 
682 693
 				// Not really a problem?
683
-				if ($row['my_num_replies'] == $row['num_replies'])
684
-					return false;
694
+				if ($row['my_num_replies'] == $row['num_replies']) {
695
+									return false;
696
+				}
685 697
 
686 698
 				$smcFunc['db_query']('', '
687 699
 					UPDATE {db_prefix}topics
@@ -700,11 +712,13 @@  discard block
 block discarded – undo
700 712
 				global $txt, $context;
701 713
 
702 714
 				// Just joking?
703
-				if ($row['my_num_replies'] == $row['num_replies'])
704
-					return false;
715
+				if ($row['my_num_replies'] == $row['num_replies']) {
716
+									return false;
717
+				}
705 718
 
706
-				if ($row['num_replies'] != $row['my_num_replies'])
707
-					$context['repair_errors'][] = sprintf($txt['repair_stats_topics_3'], $row['id_topic'], $row['num_replies']);
719
+				if ($row['num_replies'] != $row['my_num_replies']) {
720
+									$context['repair_errors'][] = sprintf($txt['repair_stats_topics_3'], $row['id_topic'], $row['num_replies']);
721
+				}
708 722
 
709 723
 				return true;
710 724
 
@@ -1295,8 +1309,9 @@  discard block
 block discarded – undo
1295 1309
 				$inserts = array();
1296 1310
 				while ($row = $smcFunc['db_fetch_assoc']($result))
1297 1311
 				{
1298
-					foreach (text2words($row['subject']) as $word)
1299
-						$inserts[] = array($word, $row['id_topic']);
1312
+					foreach (text2words($row['subject']) as $word) {
1313
+											$inserts[] = array($word, $row['id_topic']);
1314
+					}
1300 1315
 					if (count($inserts) > 500)
1301 1316
 					{
1302 1317
 						$smcFunc['db_insert']('ignore',
@@ -1310,13 +1325,14 @@  discard block
 block discarded – undo
1310 1325
 
1311 1326
 				}
1312 1327
 
1313
-				if (!empty($inserts))
1314
-					$smcFunc['db_insert']('ignore',
1328
+				if (!empty($inserts)) {
1329
+									$smcFunc['db_insert']('ignore',
1315 1330
 						'{db_prefix}log_search_subjects',
1316 1331
 						array('word' => 'string', 'id_topic' => 'int'),
1317 1332
 						$inserts,
1318 1333
 						array('word', 'id_topic')
1319 1334
 					);
1335
+				}
1320 1336
 
1321 1337
 		},
1322 1338
 			'message_function' => function ($row)
@@ -1586,8 +1602,9 @@  discard block
 block discarded – undo
1586 1602
 		$current_step++;
1587 1603
 
1588 1604
 		// Already done this?
1589
-		if ($_GET['step'] > $current_step)
1590
-			continue;
1605
+		if ($_GET['step'] > $current_step) {
1606
+					continue;
1607
+		}
1591 1608
 
1592 1609
 		// If we're fixing it but it ain't broke why try?
1593 1610
 		if ($do_fix && !in_array($error_type, $to_fix))
@@ -1616,14 +1633,16 @@  discard block
 block discarded – undo
1616 1633
 		while (!$done)
1617 1634
 		{
1618 1635
 			// Make sure there's at least one ID to test.
1619
-			if (isset($test['substeps']) && empty($step_max))
1620
-				break;
1636
+			if (isset($test['substeps']) && empty($step_max)) {
1637
+							break;
1638
+			}
1621 1639
 
1622 1640
 			// What is the testing query (Changes if we are testing or fixing)
1623
-			if (!$do_fix)
1624
-				$test_query = 'check_query';
1625
-			else
1626
-				$test_query = isset($test['fix_query']) ? 'fix_query' : 'check_query';
1641
+			if (!$do_fix) {
1642
+							$test_query = 'check_query';
1643
+			} else {
1644
+							$test_query = isset($test['fix_query']) ? 'fix_query' : 'check_query';
1645
+			}
1627 1646
 
1628 1647
 			// Do the test...
1629 1648
 			$request = $smcFunc['db_query']('',
@@ -1634,10 +1653,11 @@  discard block
 block discarded – undo
1634 1653
 			$needs_fix = false;
1635 1654
 
1636 1655
 			// Does it need a fix?
1637
-			if (!empty($test['check_type']) && $test['check_type'] == 'count')
1638
-				list ($needs_fix) = $smcFunc['db_fetch_row']($request);
1639
-			else
1640
-				$needs_fix = $smcFunc['db_num_rows']($request);
1656
+			if (!empty($test['check_type']) && $test['check_type'] == 'count') {
1657
+							list ($needs_fix) = $smcFunc['db_fetch_row']($request);
1658
+			} else {
1659
+							$needs_fix = $smcFunc['db_num_rows']($request);
1660
+			}
1641 1661
 
1642 1662
 			$total_queries++;
1643 1663
 
@@ -1649,8 +1669,9 @@  discard block
 block discarded – undo
1649 1669
 					// Assume need to fix.
1650 1670
 					$found_errors = true;
1651 1671
 
1652
-					if (isset($test['message']))
1653
-						$context['repair_errors'][] = $txt[$test['message']];
1672
+					if (isset($test['message'])) {
1673
+											$context['repair_errors'][] = $txt[$test['message']];
1674
+					}
1654 1675
 
1655 1676
 					// One per row!
1656 1677
 					elseif (isset($test['messages']))
@@ -1660,10 +1681,11 @@  discard block
 block discarded – undo
1660 1681
 							$variables = $test['messages'];
1661 1682
 							foreach ($variables as $k => $v)
1662 1683
 							{
1663
-								if ($k == 0 && isset($txt[$v]))
1664
-									$variables[$k] = $txt[$v];
1665
-								elseif ($k > 0 && isset($row[$v]))
1666
-									$variables[$k] = $row[$v];
1684
+								if ($k == 0 && isset($txt[$v])) {
1685
+																	$variables[$k] = $txt[$v];
1686
+								} elseif ($k > 0 && isset($row[$v])) {
1687
+																	$variables[$k] = $row[$v];
1688
+								}
1667 1689
 							}
1668 1690
 							$context['repair_errors'][] = call_user_func_array('sprintf', $variables);
1669 1691
 						}
@@ -1674,13 +1696,15 @@  discard block
 block discarded – undo
1674 1696
 					{
1675 1697
 						// Find out if there are actually errors.
1676 1698
 						$found_errors = false;
1677
-						while ($row = $smcFunc['db_fetch_assoc']($request))
1678
-							$found_errors |= $test['message_function']($row);
1699
+						while ($row = $smcFunc['db_fetch_assoc']($request)) {
1700
+													$found_errors |= $test['message_function']($row);
1701
+						}
1679 1702
 					}
1680 1703
 
1681 1704
 					// Actually have something to fix?
1682
-					if ($found_errors)
1683
-						$to_fix[] = $error_type;
1705
+					if ($found_errors) {
1706
+											$to_fix[] = $error_type;
1707
+					}
1684 1708
 				}
1685 1709
 
1686 1710
 				// We want to fix, we need to fix - so work out what exactly to do!
@@ -1690,8 +1714,9 @@  discard block
 block discarded – undo
1690 1714
 					if (isset($test['fix_collect']))
1691 1715
 					{
1692 1716
 						$ids = array();
1693
-						while ($row = $smcFunc['db_fetch_assoc']($request))
1694
-							$ids[] = $row[$test['fix_collect']['index']];
1717
+						while ($row = $smcFunc['db_fetch_assoc']($request)) {
1718
+													$ids[] = $row[$test['fix_collect']['index']];
1719
+						}
1695 1720
 						if (!empty($ids))
1696 1721
 						{
1697 1722
 							// Fix it!
@@ -1700,30 +1725,34 @@  discard block
 block discarded – undo
1700 1725
 					}
1701 1726
 
1702 1727
 					// Simply executing a fix it query?
1703
-					elseif (isset($test['fix_it_query']))
1704
-						$smcFunc['db_query']('',
1728
+					elseif (isset($test['fix_it_query'])) {
1729
+											$smcFunc['db_query']('',
1705 1730
 							$test['fix_it_query'],
1706 1731
 							array(
1707 1732
 							)
1708 1733
 						);
1734
+					}
1709 1735
 
1710 1736
 					// Do we have some processing to do?
1711 1737
 					elseif (isset($test['fix_processing']))
1712 1738
 					{
1713
-						while ($row = $smcFunc['db_fetch_assoc']($request))
1714
-							$test['fix_processing']($row);
1739
+						while ($row = $smcFunc['db_fetch_assoc']($request)) {
1740
+													$test['fix_processing']($row);
1741
+						}
1715 1742
 					}
1716 1743
 
1717 1744
 					// What about the full set of processing?
1718
-					elseif (isset($test['fix_full_processing']))
1719
-						$test['fix_full_processing']($request);
1745
+					elseif (isset($test['fix_full_processing'])) {
1746
+											$test['fix_full_processing']($request);
1747
+					}
1720 1748
 
1721 1749
 					// Do we have other things we need to fix as a result?
1722 1750
 					if (!empty($test['force_fix']))
1723 1751
 					{
1724
-						foreach ($test['force_fix'] as $item)
1725
-							if (!in_array($item, $to_fix))
1752
+						foreach ($test['force_fix'] as $item) {
1753
+													if (!in_array($item, $to_fix))
1726 1754
 								$to_fix[] = $item;
1755
+						}
1727 1756
 					}
1728 1757
 				}
1729 1758
 			}
@@ -1741,16 +1770,17 @@  discard block
 block discarded – undo
1741 1770
 				if ($_GET['substep'] <= $step_max)
1742 1771
 				{
1743 1772
 					pauseRepairProcess($to_fix, $error_type, $step_max);
1773
+				} else {
1774
+									$done = true;
1744 1775
 				}
1745
-				else
1746
-					$done = true;
1776
+			} else {
1777
+							$done = true;
1747 1778
 			}
1748
-			else
1749
-				$done = true;
1750 1779
 
1751 1780
 			// Don't allow more than 1000 queries at a time.
1752
-			if ($total_queries >= 1000)
1753
-				pauseRepairProcess($to_fix, $error_type, $step_max, true);
1781
+			if ($total_queries >= 1000) {
1782
+							pauseRepairProcess($to_fix, $error_type, $step_max, true);
1783
+			}
1754 1784
 		}
1755 1785
 
1756 1786
 		// Keep going.
@@ -1763,8 +1793,9 @@  discard block
 block discarded – undo
1763 1793
 		if ($do_fix)
1764 1794
 		{
1765 1795
 			$key = array_search($error_type, $to_fix);
1766
-			if ($key !== false && isset($to_fix[$key]))
1767
-				unset($to_fix[$key]);
1796
+			if ($key !== false && isset($to_fix[$key])) {
1797
+							unset($to_fix[$key]);
1798
+			}
1768 1799
 		}
1769 1800
 
1770 1801
 		// Are we done?
@@ -1787,10 +1818,11 @@  discard block
 block discarded – undo
1787 1818
 	static $createOnce = false;
1788 1819
 
1789 1820
 	// Have we already created it?
1790
-	if ($createOnce)
1791
-		return;
1792
-	else
1793
-		$createOnce = true;
1821
+	if ($createOnce) {
1822
+			return;
1823
+	} else {
1824
+			$createOnce = true;
1825
+	}
1794 1826
 
1795 1827
 	// Back to the forum's default language.
1796 1828
 	loadLanguage('Admin', $language);
@@ -1805,8 +1837,9 @@  discard block
 block discarded – undo
1805 1837
 			'cat_name' => $txt['salvaged_category_name'],
1806 1838
 		)
1807 1839
 	);
1808
-	if ($smcFunc['db_num_rows']($result) != 0)
1809
-		list ($salvageCatID) = $smcFunc['db_fetch_row']($result);
1840
+	if ($smcFunc['db_num_rows']($result) != 0) {
1841
+			list ($salvageCatID) = $smcFunc['db_fetch_row']($result);
1842
+	}
1810 1843
 	$smcFunc['db_free_result']($result);
1811 1844
 
1812 1845
 	if (empty($salvageCatID))
@@ -1839,8 +1872,9 @@  discard block
 block discarded – undo
1839 1872
 			'board_name' => $txt['salvaged_board_name'],
1840 1873
 		)
1841 1874
 	);
1842
-	if ($smcFunc['db_num_rows']($result) != 0)
1843
-		list ($salvageBoardID) = $smcFunc['db_fetch_row']($result);
1875
+	if ($smcFunc['db_num_rows']($result) != 0) {
1876
+			list ($salvageBoardID) = $smcFunc['db_fetch_row']($result);
1877
+	}
1844 1878
 	$smcFunc['db_free_result']($result);
1845 1879
 
1846 1880
 	if (empty($salvageBoardID))
Please login to merge, or discard this patch.
Sources/minify/src/CSS.php 2 patches
Indentation   +412 added lines, -412 removed lines patch added patch discarded remove patch
@@ -17,97 +17,97 @@  discard block
 block discarded – undo
17 17
  */
18 18
 class CSS extends Minify
19 19
 {
20
-    /**
21
-     * @var int
22
-     */
23
-    protected $maxImportSize = 5;
24
-
25
-    /**
26
-     * @var string[]
27
-     */
28
-    protected $importExtensions = array(
29
-        'gif' => 'data:image/gif',
30
-        'png' => 'data:image/png',
31
-        'jpe' => 'data:image/jpeg',
32
-        'jpg' => 'data:image/jpeg',
33
-        'jpeg' => 'data:image/jpeg',
34
-        'svg' => 'data:image/svg+xml',
35
-        'woff' => 'data:application/x-font-woff',
36
-        'tif' => 'image/tiff',
37
-        'tiff' => 'image/tiff',
38
-        'xbm' => 'image/x-xbitmap',
39
-    );
40
-
41
-    /**
42
-     * Set the maximum size if files to be imported.
43
-     *
44
-     * Files larger than this size (in kB) will not be imported into the CSS.
45
-     * Importing files into the CSS as data-uri will save you some connections,
46
-     * but we should only import relatively small decorative images so that our
47
-     * CSS file doesn't get too bulky.
48
-     *
49
-     * @param int $size Size in kB
50
-     */
51
-    public function setMaxImportSize($size)
52
-    {
53
-        $this->maxImportSize = $size;
54
-    }
55
-
56
-    /**
57
-     * Set the type of extensions to be imported into the CSS (to save network
58
-     * connections).
59
-     * Keys of the array should be the file extensions & respective values
60
-     * should be the data type.
61
-     *
62
-     * @param string[] $extensions Array of file extensions
63
-     */
64
-    public function setImportExtensions(array $extensions)
65
-    {
66
-        $this->importExtensions = $extensions;
67
-    }
68
-
69
-    /**
70
-     * Move any import statements to the top.
71
-     *
72
-     * @param string $content Nearly finished CSS content
73
-     *
74
-     * @return string
75
-     */
76
-    protected function moveImportsToTop($content)
77
-    {
78
-        if (preg_match_all('/@import[^;]+;/', $content, $matches)) {
79
-
80
-            // remove from content
81
-            foreach ($matches[0] as $import) {
82
-                $content = str_replace($import, '', $content);
83
-            }
84
-
85
-            // add to top
86
-            $content = implode('', $matches[0]).$content;
87
-        };
88
-
89
-        return $content;
90
-    }
91
-
92
-    /**
93
-     * Combine CSS from import statements.
94
-     *
95
-     * @import's will be loaded and their content merged into the original file,
96
-     * to save HTTP requests.
97
-     *
98
-     * @param string   $source  The file to combine imports for.
99
-     * @param string   $content The CSS content to combine imports for.
100
-     * @param string[] $parents Parent paths, for circular reference checks.
101
-     *
102
-     * @return string
103
-     *
104
-     * @throws FileImportException
105
-     */
106
-    protected function combineImports($source, $content, $parents)
107
-    {
108
-        $importRegexes = array(
109
-            // @import url(xxx)
110
-            '/
20
+	/**
21
+	 * @var int
22
+	 */
23
+	protected $maxImportSize = 5;
24
+
25
+	/**
26
+	 * @var string[]
27
+	 */
28
+	protected $importExtensions = array(
29
+		'gif' => 'data:image/gif',
30
+		'png' => 'data:image/png',
31
+		'jpe' => 'data:image/jpeg',
32
+		'jpg' => 'data:image/jpeg',
33
+		'jpeg' => 'data:image/jpeg',
34
+		'svg' => 'data:image/svg+xml',
35
+		'woff' => 'data:application/x-font-woff',
36
+		'tif' => 'image/tiff',
37
+		'tiff' => 'image/tiff',
38
+		'xbm' => 'image/x-xbitmap',
39
+	);
40
+
41
+	/**
42
+	 * Set the maximum size if files to be imported.
43
+	 *
44
+	 * Files larger than this size (in kB) will not be imported into the CSS.
45
+	 * Importing files into the CSS as data-uri will save you some connections,
46
+	 * but we should only import relatively small decorative images so that our
47
+	 * CSS file doesn't get too bulky.
48
+	 *
49
+	 * @param int $size Size in kB
50
+	 */
51
+	public function setMaxImportSize($size)
52
+	{
53
+		$this->maxImportSize = $size;
54
+	}
55
+
56
+	/**
57
+	 * Set the type of extensions to be imported into the CSS (to save network
58
+	 * connections).
59
+	 * Keys of the array should be the file extensions & respective values
60
+	 * should be the data type.
61
+	 *
62
+	 * @param string[] $extensions Array of file extensions
63
+	 */
64
+	public function setImportExtensions(array $extensions)
65
+	{
66
+		$this->importExtensions = $extensions;
67
+	}
68
+
69
+	/**
70
+	 * Move any import statements to the top.
71
+	 *
72
+	 * @param string $content Nearly finished CSS content
73
+	 *
74
+	 * @return string
75
+	 */
76
+	protected function moveImportsToTop($content)
77
+	{
78
+		if (preg_match_all('/@import[^;]+;/', $content, $matches)) {
79
+
80
+			// remove from content
81
+			foreach ($matches[0] as $import) {
82
+				$content = str_replace($import, '', $content);
83
+			}
84
+
85
+			// add to top
86
+			$content = implode('', $matches[0]).$content;
87
+		};
88
+
89
+		return $content;
90
+	}
91
+
92
+	/**
93
+	 * Combine CSS from import statements.
94
+	 *
95
+	 * @import's will be loaded and their content merged into the original file,
96
+	 * to save HTTP requests.
97
+	 *
98
+	 * @param string   $source  The file to combine imports for.
99
+	 * @param string   $content The CSS content to combine imports for.
100
+	 * @param string[] $parents Parent paths, for circular reference checks.
101
+	 *
102
+	 * @return string
103
+	 *
104
+	 * @throws FileImportException
105
+	 */
106
+	protected function combineImports($source, $content, $parents)
107
+	{
108
+		$importRegexes = array(
109
+			// @import url(xxx)
110
+			'/
111 111
             # import statement
112 112
             @import
113 113
 
@@ -152,8 +152,8 @@  discard block
 block discarded – undo
152 152
 
153 153
             /ix',
154 154
 
155
-            // @import 'xxx'
156
-            '/
155
+			// @import 'xxx'
156
+			'/
157 157
 
158 158
             # import statement
159 159
             @import
@@ -192,172 +192,172 @@  discard block
 block discarded – undo
192 192
             ;?
193 193
 
194 194
             /ix',
195
-        );
196
-
197
-        // find all relative imports in css
198
-        $matches = array();
199
-        foreach ($importRegexes as $importRegex) {
200
-            if (preg_match_all($importRegex, $content, $regexMatches, PREG_SET_ORDER)) {
201
-                $matches = array_merge($matches, $regexMatches);
202
-            }
203
-        }
204
-
205
-        $search = array();
206
-        $replace = array();
207
-
208
-        // loop the matches
209
-        foreach ($matches as $match) {
210
-            // get the path for the file that will be imported
211
-            $importPath = dirname($source).'/'.$match['path'];
212
-
213
-            // only replace the import with the content if we can grab the
214
-            // content of the file
215
-            if ($this->canImportFile($importPath)) {
216
-                // check if current file was not imported previously in the same
217
-                // import chain.
218
-                if (in_array($importPath, $parents)) {
219
-                    throw new FileImportException('Failed to import file "'.$importPath.'": circular reference detected.');
220
-                }
221
-
222
-                // grab referenced file & minify it (which may include importing
223
-                // yet other @import statements recursively)
224
-                $minifier = new static($importPath);
225
-                $importContent = $minifier->execute($source, $parents);
226
-
227
-                // check if this is only valid for certain media
228
-                if (!empty($match['media'])) {
229
-                    $importContent = '@media '.$match['media'].'{'.$importContent.'}';
230
-                }
231
-
232
-                // add to replacement array
233
-                $search[] = $match[0];
234
-                $replace[] = $importContent;
235
-            }
236
-        }
237
-
238
-        // replace the import statements
239
-        $content = str_replace($search, $replace, $content);
240
-
241
-        return $content;
242
-    }
243
-
244
-    /**
245
-     * Import files into the CSS, base64-ized.
246
-     *
247
-     * @url(image.jpg) images will be loaded and their content merged into the
248
-     * original file, to save HTTP requests.
249
-     *
250
-     * @param string $source  The file to import files for.
251
-     * @param string $content The CSS content to import files for.
252
-     *
253
-     * @return string
254
-     */
255
-    protected function importFiles($source, $content)
256
-    {
257
-        $extensions = array_keys($this->importExtensions);
258
-        $regex = '/url\((["\']?)((?!["\']?data:).*?\.('.implode('|', $extensions).'))\\1\)/i';
259
-        if ($extensions && preg_match_all($regex, $content, $matches, PREG_SET_ORDER)) {
260
-            $search = array();
261
-            $replace = array();
262
-
263
-            // loop the matches
264
-            foreach ($matches as $match) {
265
-                // get the path for the file that will be imported
266
-                $path = $match[2];
267
-                $path = dirname($source).'/'.$path;
268
-                $extension = $match[3];
269
-
270
-                // only replace the import with the content if we're able to get
271
-                // the content of the file, and it's relatively small
272
-                if ($this->canImportFile($path) && $this->canImportBySize($path)) {
273
-                    // grab content && base64-ize
274
-                    $importContent = $this->load($path);
275
-                    $importContent = base64_encode($importContent);
276
-
277
-                    // build replacement
278
-                    $search[] = $match[0];
279
-                    $replace[] = 'url('.$this->importExtensions[$extension].';base64,'.$importContent.')';
280
-                }
281
-            }
282
-
283
-            // replace the import statements
284
-            $content = str_replace($search, $replace, $content);
285
-        }
286
-
287
-        return $content;
288
-    }
289
-
290
-    /**
291
-     * Minify the data.
292
-     * Perform CSS optimizations.
293
-     *
294
-     * @param string[optional] $path    Path to write the data to.
295
-     * @param string[]         $parents Parent paths, for circular reference checks.
296
-     *
297
-     * @return string The minified data.
298
-     */
299
-    public function execute($path = null, $parents = array())
300
-    {
301
-        $content = '';
302
-
303
-        // loop css data (raw data and files)
304
-        foreach ($this->data as $source => $css) {
305
-            /*
195
+		);
196
+
197
+		// find all relative imports in css
198
+		$matches = array();
199
+		foreach ($importRegexes as $importRegex) {
200
+			if (preg_match_all($importRegex, $content, $regexMatches, PREG_SET_ORDER)) {
201
+				$matches = array_merge($matches, $regexMatches);
202
+			}
203
+		}
204
+
205
+		$search = array();
206
+		$replace = array();
207
+
208
+		// loop the matches
209
+		foreach ($matches as $match) {
210
+			// get the path for the file that will be imported
211
+			$importPath = dirname($source).'/'.$match['path'];
212
+
213
+			// only replace the import with the content if we can grab the
214
+			// content of the file
215
+			if ($this->canImportFile($importPath)) {
216
+				// check if current file was not imported previously in the same
217
+				// import chain.
218
+				if (in_array($importPath, $parents)) {
219
+					throw new FileImportException('Failed to import file "'.$importPath.'": circular reference detected.');
220
+				}
221
+
222
+				// grab referenced file & minify it (which may include importing
223
+				// yet other @import statements recursively)
224
+				$minifier = new static($importPath);
225
+				$importContent = $minifier->execute($source, $parents);
226
+
227
+				// check if this is only valid for certain media
228
+				if (!empty($match['media'])) {
229
+					$importContent = '@media '.$match['media'].'{'.$importContent.'}';
230
+				}
231
+
232
+				// add to replacement array
233
+				$search[] = $match[0];
234
+				$replace[] = $importContent;
235
+			}
236
+		}
237
+
238
+		// replace the import statements
239
+		$content = str_replace($search, $replace, $content);
240
+
241
+		return $content;
242
+	}
243
+
244
+	/**
245
+	 * Import files into the CSS, base64-ized.
246
+	 *
247
+	 * @url(image.jpg) images will be loaded and their content merged into the
248
+	 * original file, to save HTTP requests.
249
+	 *
250
+	 * @param string $source  The file to import files for.
251
+	 * @param string $content The CSS content to import files for.
252
+	 *
253
+	 * @return string
254
+	 */
255
+	protected function importFiles($source, $content)
256
+	{
257
+		$extensions = array_keys($this->importExtensions);
258
+		$regex = '/url\((["\']?)((?!["\']?data:).*?\.('.implode('|', $extensions).'))\\1\)/i';
259
+		if ($extensions && preg_match_all($regex, $content, $matches, PREG_SET_ORDER)) {
260
+			$search = array();
261
+			$replace = array();
262
+
263
+			// loop the matches
264
+			foreach ($matches as $match) {
265
+				// get the path for the file that will be imported
266
+				$path = $match[2];
267
+				$path = dirname($source).'/'.$path;
268
+				$extension = $match[3];
269
+
270
+				// only replace the import with the content if we're able to get
271
+				// the content of the file, and it's relatively small
272
+				if ($this->canImportFile($path) && $this->canImportBySize($path)) {
273
+					// grab content && base64-ize
274
+					$importContent = $this->load($path);
275
+					$importContent = base64_encode($importContent);
276
+
277
+					// build replacement
278
+					$search[] = $match[0];
279
+					$replace[] = 'url('.$this->importExtensions[$extension].';base64,'.$importContent.')';
280
+				}
281
+			}
282
+
283
+			// replace the import statements
284
+			$content = str_replace($search, $replace, $content);
285
+		}
286
+
287
+		return $content;
288
+	}
289
+
290
+	/**
291
+	 * Minify the data.
292
+	 * Perform CSS optimizations.
293
+	 *
294
+	 * @param string[optional] $path    Path to write the data to.
295
+	 * @param string[]         $parents Parent paths, for circular reference checks.
296
+	 *
297
+	 * @return string The minified data.
298
+	 */
299
+	public function execute($path = null, $parents = array())
300
+	{
301
+		$content = '';
302
+
303
+		// loop css data (raw data and files)
304
+		foreach ($this->data as $source => $css) {
305
+			/*
306 306
              * Let's first take out strings & comments, since we can't just remove
307 307
              * whitespace anywhere. If whitespace occurs inside a string, we should
308 308
              * leave it alone. E.g.:
309 309
              * p { content: "a   test" }
310 310
              */
311
-            $this->extractStrings();
312
-            $this->stripComments();
313
-            $css = $this->replace($css);
311
+			$this->extractStrings();
312
+			$this->stripComments();
313
+			$css = $this->replace($css);
314 314
 
315
-            $css = $this->stripWhitespace($css);
316
-            $css = $this->shortenHex($css);
317
-            $css = $this->shortenZeroes($css);
318
-            $css = $this->stripEmptyTags($css);
315
+			$css = $this->stripWhitespace($css);
316
+			$css = $this->shortenHex($css);
317
+			$css = $this->shortenZeroes($css);
318
+			$css = $this->stripEmptyTags($css);
319 319
 
320
-            // restore the string we've extracted earlier
321
-            $css = $this->restoreExtractedData($css);
320
+			// restore the string we've extracted earlier
321
+			$css = $this->restoreExtractedData($css);
322 322
 
323
-            $source = is_int($source) ? '' : $source;
324
-            $parents = $source ? array_merge($parents, array($source)) : $parents;
325
-            $css = $this->combineImports($source, $css, $parents);
326
-            $css = $this->importFiles($source, $css);
323
+			$source = is_int($source) ? '' : $source;
324
+			$parents = $source ? array_merge($parents, array($source)) : $parents;
325
+			$css = $this->combineImports($source, $css, $parents);
326
+			$css = $this->importFiles($source, $css);
327 327
 
328
-            /*
328
+			/*
329 329
              * If we'll save to a new path, we'll have to fix the relative paths
330 330
              * to be relative no longer to the source file, but to the new path.
331 331
              * If we don't write to a file, fall back to same path so no
332 332
              * conversion happens (because we still want it to go through most
333 333
              * of the move code...)
334 334
              */
335
-            $converter = new Converter($source, $path ?: $source);
336
-            $css = $this->move($converter, $css);
337
-
338
-            // combine css
339
-            $content .= $css;
340
-        }
341
-
342
-        $content = $this->moveImportsToTop($content);
343
-
344
-        return $content;
345
-    }
346
-
347
-    /**
348
-     * Moving a css file should update all relative urls.
349
-     * Relative references (e.g. ../images/image.gif) in a certain css file,
350
-     * will have to be updated when a file is being saved at another location
351
-     * (e.g. ../../images/image.gif, if the new CSS file is 1 folder deeper).
352
-     *
353
-     * @param Converter $converter Relative path converter
354
-     * @param string    $content   The CSS content to update relative urls for.
355
-     *
356
-     * @return string
357
-     */
358
-    protected function move(Converter $converter, $content)
359
-    {
360
-        /*
335
+			$converter = new Converter($source, $path ?: $source);
336
+			$css = $this->move($converter, $css);
337
+
338
+			// combine css
339
+			$content .= $css;
340
+		}
341
+
342
+		$content = $this->moveImportsToTop($content);
343
+
344
+		return $content;
345
+	}
346
+
347
+	/**
348
+	 * Moving a css file should update all relative urls.
349
+	 * Relative references (e.g. ../images/image.gif) in a certain css file,
350
+	 * will have to be updated when a file is being saved at another location
351
+	 * (e.g. ../../images/image.gif, if the new CSS file is 1 folder deeper).
352
+	 *
353
+	 * @param Converter $converter Relative path converter
354
+	 * @param string    $content   The CSS content to update relative urls for.
355
+	 *
356
+	 * @return string
357
+	 */
358
+	protected function move(Converter $converter, $content)
359
+	{
360
+		/*
361 361
          * Relative path references will usually be enclosed by url(). @import
362 362
          * is an exception, where url() is not necessary around the path (but is
363 363
          * allowed).
@@ -368,9 +368,9 @@  discard block
 block discarded – undo
368 368
          * recent PCRE version. That's why I'm doing 2 separate regular
369 369
          * expressions & combining the matches after executing of both.
370 370
          */
371
-        $relativeRegexes = array(
372
-            // url(xxx)
373
-            '/
371
+		$relativeRegexes = array(
372
+			// url(xxx)
373
+			'/
374 374
             # open url()
375 375
             url\(
376 376
 
@@ -402,8 +402,8 @@  discard block
 block discarded – undo
402 402
 
403 403
             /ix',
404 404
 
405
-            // @import "xxx"
406
-            '/
405
+			// @import "xxx"
406
+			'/
407 407
             # import statement
408 408
             @import
409 409
 
@@ -432,167 +432,167 @@  discard block
 block discarded – undo
432 432
                 (?P=quotes)
433 433
 
434 434
             /ix',
435
-        );
436
-
437
-        // find all relative urls in css
438
-        $matches = array();
439
-        foreach ($relativeRegexes as $relativeRegex) {
440
-            if (preg_match_all($relativeRegex, $content, $regexMatches, PREG_SET_ORDER)) {
441
-                $matches = array_merge($matches, $regexMatches);
442
-            }
443
-        }
444
-
445
-        $search = array();
446
-        $replace = array();
447
-
448
-        // loop all urls
449
-        foreach ($matches as $match) {
450
-            // determine if it's a url() or an @import match
451
-            $type = (strpos($match[0], '@import') === 0 ? 'import' : 'url');
452
-
453
-            // attempting to interpret GET-params makes no sense, so let's discard them for awhile
454
-            $params = strrchr($match['path'], '?');
455
-            $url = $params ? substr($match['path'], 0, -strlen($params)) : $match['path'];
456
-
457
-            // fix relative url
458
-            $url = $converter->convert($url);
459
-
460
-            // now that the path has been converted, re-apply GET-params
461
-            $url .= $params;
462
-
463
-            // build replacement
464
-            $search[] = $match[0];
465
-            if ($type == 'url') {
466
-                $replace[] = 'url('.$url.')';
467
-            } elseif ($type == 'import') {
468
-                $replace[] = '@import "'.$url.'"';
469
-            }
470
-        }
471
-
472
-        // replace urls
473
-        $content = str_replace($search, $replace, $content);
474
-
475
-        return $content;
476
-    }
477
-
478
-    /**
479
-     * Shorthand hex color codes.
480
-     * #FF0000 -> #F00.
481
-     *
482
-     * @param string $content The CSS content to shorten the hex color codes for.
483
-     *
484
-     * @return string
485
-     */
486
-    protected function shortenHex($content)
487
-    {
488
-        $content = preg_replace('/(?<![\'"])#([0-9a-z])\\1([0-9a-z])\\2([0-9a-z])\\3(?![\'"])/i', '#$1$2$3', $content);
489
-
490
-        return $content;
491
-    }
492
-
493
-    /**
494
-     * Shorthand 0 values to plain 0, instead of e.g. -0em.
495
-     *
496
-     * @param string $content The CSS content to shorten the zero values for.
497
-     *
498
-     * @return string
499
-     */
500
-    protected function shortenZeroes($content)
501
-    {
502
-        // reusable bits of code throughout these regexes:
503
-        // before & after are used to make sure we don't match lose unintended
504
-        // 0-like values (e.g. in #000, or in http://url/1.0)
505
-        // units can be stripped from 0 values, or used to recognize non 0
506
-        // values (where wa may be able to strip a .0 suffix)
507
-        $before = '(?<=[:(, ])';
508
-        $after = '(?=[ ,);}])';
509
-        $units = '(em|ex|%|px|cm|mm|in|pt|pc|ch|rem|vh|vw|vmin|vmax|vm)';
510
-
511
-        // strip units after zeroes (0px -> 0)
512
-        // NOTE: it should be safe to remove all units for a 0 value, but in
513
-        // practice, Webkit (especially Safari) seems to stumble over at least
514
-        // 0%, potentially other units as well. Only stripping 'px' for now.
515
-        // @see https://github.com/matthiasmullie/minify/issues/60
516
-        $content = preg_replace('/'.$before.'(-?0*(\.0+)?)(?<=0)px'.$after.'/', '\\1', $content);
517
-
518
-        // strip 0-digits (.0 -> 0)
519
-        $content = preg_replace('/'.$before.'\.0+'.$units.'?'.$after.'/', '0\\1', $content);
520
-        // strip trailing 0: 50.10 -> 50.1, 50.10px -> 50.1px
521
-        $content = preg_replace('/'.$before.'(-?[0-9]+\.[0-9]+)0+'.$units.'?'.$after.'/', '\\1\\2', $content);
522
-        // strip trailing 0: 50.00 -> 50, 50.00px -> 50px
523
-        $content = preg_replace('/'.$before.'(-?[0-9]+)\.0+'.$units.'?'.$after.'/', '\\1\\2', $content);
524
-        // strip leading 0: 0.1 -> .1, 01.1 -> 1.1
525
-        $content = preg_replace('/'.$before.'(-?)0+([0-9]*\.[0-9]+)'.$units.'?'.$after.'/', '\\1\\2\\3', $content);
526
-
527
-        // strip negative zeroes (-0 -> 0) & truncate zeroes (00 -> 0)
528
-        $content = preg_replace('/'.$before.'-?0+'.$units.'?'.$after.'/', '0\\1', $content);
529
-
530
-        return $content;
531
-    }
532
-
533
-    /**
534
-     * Strip comments from source code.
535
-     *
536
-     * @param string $content
537
-     *
538
-     * @return string
539
-     */
540
-    protected function stripEmptyTags($content)
541
-    {
542
-        return preg_replace('/(^|\})[^\{\}]+\{\s*\}/', '\\1', $content);
543
-    }
544
-
545
-    /**
546
-     * Strip comments from source code.
547
-     */
548
-    protected function stripComments()
549
-    {
550
-        $this->registerPattern('/\/\*.*?\*\//s', '');
551
-    }
552
-
553
-    /**
554
-     * Strip whitespace.
555
-     *
556
-     * @param string $content The CSS content to strip the whitespace for.
557
-     *
558
-     * @return string
559
-     */
560
-    protected function stripWhitespace($content)
561
-    {
562
-        // remove leading & trailing whitespace
563
-        $content = preg_replace('/^\s*/m', '', $content);
564
-        $content = preg_replace('/\s*$/m', '', $content);
565
-
566
-        // replace newlines with a single space
567
-        $content = preg_replace('/\s+/', ' ', $content);
568
-
569
-        // remove whitespace around meta characters
570
-        // inspired by stackoverflow.com/questions/15195750/minify-compress-css-with-regex
571
-        $content = preg_replace('/\s*([\*$~^|]?+=|[{};,>~]|!important\b)\s*/', '$1', $content);
572
-        $content = preg_replace('/([\[(:])\s+/', '$1', $content);
573
-        $content = preg_replace('/\s+([\]\)])/', '$1', $content);
574
-        $content = preg_replace('/\s+(:)(?![^\}]*\{)/', '$1', $content);
575
-
576
-        // whitespace around + and - can only be stripped in selectors, like
577
-        // :nth-child(3+2n), not in things like calc(3px + 2px) or shorthands
578
-        // like 3px -2px
579
-        $content = preg_replace('/\s*([+-])\s*(?=[^}]*{)/', '$1', $content);
580
-
581
-        // remove semicolon/whitespace followed by closing bracket
582
-        $content = str_replace(';}', '}', $content);
583
-
584
-        return trim($content);
585
-    }
586
-
587
-    /**
588
-     * Check if file is small enough to be imported.
589
-     *
590
-     * @param string $path The path to the file.
591
-     *
592
-     * @return bool
593
-     */
594
-    protected function canImportBySize($path)
595
-    {
596
-        return ($size = @filesize($path)) && $size <= $this->maxImportSize * 1024;
597
-    }
435
+		);
436
+
437
+		// find all relative urls in css
438
+		$matches = array();
439
+		foreach ($relativeRegexes as $relativeRegex) {
440
+			if (preg_match_all($relativeRegex, $content, $regexMatches, PREG_SET_ORDER)) {
441
+				$matches = array_merge($matches, $regexMatches);
442
+			}
443
+		}
444
+
445
+		$search = array();
446
+		$replace = array();
447
+
448
+		// loop all urls
449
+		foreach ($matches as $match) {
450
+			// determine if it's a url() or an @import match
451
+			$type = (strpos($match[0], '@import') === 0 ? 'import' : 'url');
452
+
453
+			// attempting to interpret GET-params makes no sense, so let's discard them for awhile
454
+			$params = strrchr($match['path'], '?');
455
+			$url = $params ? substr($match['path'], 0, -strlen($params)) : $match['path'];
456
+
457
+			// fix relative url
458
+			$url = $converter->convert($url);
459
+
460
+			// now that the path has been converted, re-apply GET-params
461
+			$url .= $params;
462
+
463
+			// build replacement
464
+			$search[] = $match[0];
465
+			if ($type == 'url') {
466
+				$replace[] = 'url('.$url.')';
467
+			} elseif ($type == 'import') {
468
+				$replace[] = '@import "'.$url.'"';
469
+			}
470
+		}
471
+
472
+		// replace urls
473
+		$content = str_replace($search, $replace, $content);
474
+
475
+		return $content;
476
+	}
477
+
478
+	/**
479
+	 * Shorthand hex color codes.
480
+	 * #FF0000 -> #F00.
481
+	 *
482
+	 * @param string $content The CSS content to shorten the hex color codes for.
483
+	 *
484
+	 * @return string
485
+	 */
486
+	protected function shortenHex($content)
487
+	{
488
+		$content = preg_replace('/(?<![\'"])#([0-9a-z])\\1([0-9a-z])\\2([0-9a-z])\\3(?![\'"])/i', '#$1$2$3', $content);
489
+
490
+		return $content;
491
+	}
492
+
493
+	/**
494
+	 * Shorthand 0 values to plain 0, instead of e.g. -0em.
495
+	 *
496
+	 * @param string $content The CSS content to shorten the zero values for.
497
+	 *
498
+	 * @return string
499
+	 */
500
+	protected function shortenZeroes($content)
501
+	{
502
+		// reusable bits of code throughout these regexes:
503
+		// before & after are used to make sure we don't match lose unintended
504
+		// 0-like values (e.g. in #000, or in http://url/1.0)
505
+		// units can be stripped from 0 values, or used to recognize non 0
506
+		// values (where wa may be able to strip a .0 suffix)
507
+		$before = '(?<=[:(, ])';
508
+		$after = '(?=[ ,);}])';
509
+		$units = '(em|ex|%|px|cm|mm|in|pt|pc|ch|rem|vh|vw|vmin|vmax|vm)';
510
+
511
+		// strip units after zeroes (0px -> 0)
512
+		// NOTE: it should be safe to remove all units for a 0 value, but in
513
+		// practice, Webkit (especially Safari) seems to stumble over at least
514
+		// 0%, potentially other units as well. Only stripping 'px' for now.
515
+		// @see https://github.com/matthiasmullie/minify/issues/60
516
+		$content = preg_replace('/'.$before.'(-?0*(\.0+)?)(?<=0)px'.$after.'/', '\\1', $content);
517
+
518
+		// strip 0-digits (.0 -> 0)
519
+		$content = preg_replace('/'.$before.'\.0+'.$units.'?'.$after.'/', '0\\1', $content);
520
+		// strip trailing 0: 50.10 -> 50.1, 50.10px -> 50.1px
521
+		$content = preg_replace('/'.$before.'(-?[0-9]+\.[0-9]+)0+'.$units.'?'.$after.'/', '\\1\\2', $content);
522
+		// strip trailing 0: 50.00 -> 50, 50.00px -> 50px
523
+		$content = preg_replace('/'.$before.'(-?[0-9]+)\.0+'.$units.'?'.$after.'/', '\\1\\2', $content);
524
+		// strip leading 0: 0.1 -> .1, 01.1 -> 1.1
525
+		$content = preg_replace('/'.$before.'(-?)0+([0-9]*\.[0-9]+)'.$units.'?'.$after.'/', '\\1\\2\\3', $content);
526
+
527
+		// strip negative zeroes (-0 -> 0) & truncate zeroes (00 -> 0)
528
+		$content = preg_replace('/'.$before.'-?0+'.$units.'?'.$after.'/', '0\\1', $content);
529
+
530
+		return $content;
531
+	}
532
+
533
+	/**
534
+	 * Strip comments from source code.
535
+	 *
536
+	 * @param string $content
537
+	 *
538
+	 * @return string
539
+	 */
540
+	protected function stripEmptyTags($content)
541
+	{
542
+		return preg_replace('/(^|\})[^\{\}]+\{\s*\}/', '\\1', $content);
543
+	}
544
+
545
+	/**
546
+	 * Strip comments from source code.
547
+	 */
548
+	protected function stripComments()
549
+	{
550
+		$this->registerPattern('/\/\*.*?\*\//s', '');
551
+	}
552
+
553
+	/**
554
+	 * Strip whitespace.
555
+	 *
556
+	 * @param string $content The CSS content to strip the whitespace for.
557
+	 *
558
+	 * @return string
559
+	 */
560
+	protected function stripWhitespace($content)
561
+	{
562
+		// remove leading & trailing whitespace
563
+		$content = preg_replace('/^\s*/m', '', $content);
564
+		$content = preg_replace('/\s*$/m', '', $content);
565
+
566
+		// replace newlines with a single space
567
+		$content = preg_replace('/\s+/', ' ', $content);
568
+
569
+		// remove whitespace around meta characters
570
+		// inspired by stackoverflow.com/questions/15195750/minify-compress-css-with-regex
571
+		$content = preg_replace('/\s*([\*$~^|]?+=|[{};,>~]|!important\b)\s*/', '$1', $content);
572
+		$content = preg_replace('/([\[(:])\s+/', '$1', $content);
573
+		$content = preg_replace('/\s+([\]\)])/', '$1', $content);
574
+		$content = preg_replace('/\s+(:)(?![^\}]*\{)/', '$1', $content);
575
+
576
+		// whitespace around + and - can only be stripped in selectors, like
577
+		// :nth-child(3+2n), not in things like calc(3px + 2px) or shorthands
578
+		// like 3px -2px
579
+		$content = preg_replace('/\s*([+-])\s*(?=[^}]*{)/', '$1', $content);
580
+
581
+		// remove semicolon/whitespace followed by closing bracket
582
+		$content = str_replace(';}', '}', $content);
583
+
584
+		return trim($content);
585
+	}
586
+
587
+	/**
588
+	 * Check if file is small enough to be imported.
589
+	 *
590
+	 * @param string $path The path to the file.
591
+	 *
592
+	 * @return bool
593
+	 */
594
+	protected function canImportBySize($path)
595
+	{
596
+		return ($size = @filesize($path)) && $size <= $this->maxImportSize * 1024;
597
+	}
598 598
 }
Please login to merge, or discard this patch.
Spacing   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -83,7 +83,7 @@  discard block
 block discarded – undo
83 83
             }
84 84
 
85 85
             // add to top
86
-            $content = implode('', $matches[0]).$content;
86
+            $content = implode('', $matches[0]) . $content;
87 87
         };
88 88
 
89 89
         return $content;
@@ -208,7 +208,7 @@  discard block
 block discarded – undo
208 208
         // loop the matches
209 209
         foreach ($matches as $match) {
210 210
             // get the path for the file that will be imported
211
-            $importPath = dirname($source).'/'.$match['path'];
211
+            $importPath = dirname($source) . '/' . $match['path'];
212 212
 
213 213
             // only replace the import with the content if we can grab the
214 214
             // content of the file
@@ -216,7 +216,7 @@  discard block
 block discarded – undo
216 216
                 // check if current file was not imported previously in the same
217 217
                 // import chain.
218 218
                 if (in_array($importPath, $parents)) {
219
-                    throw new FileImportException('Failed to import file "'.$importPath.'": circular reference detected.');
219
+                    throw new FileImportException('Failed to import file "' . $importPath . '": circular reference detected.');
220 220
                 }
221 221
 
222 222
                 // grab referenced file & minify it (which may include importing
@@ -226,7 +226,7 @@  discard block
 block discarded – undo
226 226
 
227 227
                 // check if this is only valid for certain media
228 228
                 if (!empty($match['media'])) {
229
-                    $importContent = '@media '.$match['media'].'{'.$importContent.'}';
229
+                    $importContent = '@media ' . $match['media'] . '{' . $importContent . '}';
230 230
                 }
231 231
 
232 232
                 // add to replacement array
@@ -255,7 +255,7 @@  discard block
 block discarded – undo
255 255
     protected function importFiles($source, $content)
256 256
     {
257 257
         $extensions = array_keys($this->importExtensions);
258
-        $regex = '/url\((["\']?)((?!["\']?data:).*?\.('.implode('|', $extensions).'))\\1\)/i';
258
+        $regex = '/url\((["\']?)((?!["\']?data:).*?\.(' . implode('|', $extensions) . '))\\1\)/i';
259 259
         if ($extensions && preg_match_all($regex, $content, $matches, PREG_SET_ORDER)) {
260 260
             $search = array();
261 261
             $replace = array();
@@ -264,7 +264,7 @@  discard block
 block discarded – undo
264 264
             foreach ($matches as $match) {
265 265
                 // get the path for the file that will be imported
266 266
                 $path = $match[2];
267
-                $path = dirname($source).'/'.$path;
267
+                $path = dirname($source) . '/' . $path;
268 268
                 $extension = $match[3];
269 269
 
270 270
                 // only replace the import with the content if we're able to get
@@ -276,7 +276,7 @@  discard block
 block discarded – undo
276 276
 
277 277
                     // build replacement
278 278
                     $search[] = $match[0];
279
-                    $replace[] = 'url('.$this->importExtensions[$extension].';base64,'.$importContent.')';
279
+                    $replace[] = 'url(' . $this->importExtensions[$extension] . ';base64,' . $importContent . ')';
280 280
                 }
281 281
             }
282 282
 
@@ -463,9 +463,9 @@  discard block
 block discarded – undo
463 463
             // build replacement
464 464
             $search[] = $match[0];
465 465
             if ($type == 'url') {
466
-                $replace[] = 'url('.$url.')';
466
+                $replace[] = 'url(' . $url . ')';
467 467
             } elseif ($type == 'import') {
468
-                $replace[] = '@import "'.$url.'"';
468
+                $replace[] = '@import "' . $url . '"';
469 469
             }
470 470
         }
471 471
 
@@ -513,19 +513,19 @@  discard block
 block discarded – undo
513 513
         // practice, Webkit (especially Safari) seems to stumble over at least
514 514
         // 0%, potentially other units as well. Only stripping 'px' for now.
515 515
         // @see https://github.com/matthiasmullie/minify/issues/60
516
-        $content = preg_replace('/'.$before.'(-?0*(\.0+)?)(?<=0)px'.$after.'/', '\\1', $content);
516
+        $content = preg_replace('/' . $before . '(-?0*(\.0+)?)(?<=0)px' . $after . '/', '\\1', $content);
517 517
 
518 518
         // strip 0-digits (.0 -> 0)
519
-        $content = preg_replace('/'.$before.'\.0+'.$units.'?'.$after.'/', '0\\1', $content);
519
+        $content = preg_replace('/' . $before . '\.0+' . $units . '?' . $after . '/', '0\\1', $content);
520 520
         // strip trailing 0: 50.10 -> 50.1, 50.10px -> 50.1px
521
-        $content = preg_replace('/'.$before.'(-?[0-9]+\.[0-9]+)0+'.$units.'?'.$after.'/', '\\1\\2', $content);
521
+        $content = preg_replace('/' . $before . '(-?[0-9]+\.[0-9]+)0+' . $units . '?' . $after . '/', '\\1\\2', $content);
522 522
         // strip trailing 0: 50.00 -> 50, 50.00px -> 50px
523
-        $content = preg_replace('/'.$before.'(-?[0-9]+)\.0+'.$units.'?'.$after.'/', '\\1\\2', $content);
523
+        $content = preg_replace('/' . $before . '(-?[0-9]+)\.0+' . $units . '?' . $after . '/', '\\1\\2', $content);
524 524
         // strip leading 0: 0.1 -> .1, 01.1 -> 1.1
525
-        $content = preg_replace('/'.$before.'(-?)0+([0-9]*\.[0-9]+)'.$units.'?'.$after.'/', '\\1\\2\\3', $content);
525
+        $content = preg_replace('/' . $before . '(-?)0+([0-9]*\.[0-9]+)' . $units . '?' . $after . '/', '\\1\\2\\3', $content);
526 526
 
527 527
         // strip negative zeroes (-0 -> 0) & truncate zeroes (00 -> 0)
528
-        $content = preg_replace('/'.$before.'-?0+'.$units.'?'.$after.'/', '0\\1', $content);
528
+        $content = preg_replace('/' . $before . '-?0+' . $units . '?' . $after . '/', '0\\1', $content);
529 529
 
530 530
         return $content;
531 531
     }
Please login to merge, or discard this patch.
Sources/minify/src/Converter.php 2 patches
Indentation   +169 added lines, -169 removed lines patch added patch discarded remove patch
@@ -18,178 +18,178 @@
 block discarded – undo
18 18
  */
19 19
 class Converter
20 20
 {
21
-    /**
22
-     * @var string
23
-     */
24
-    protected $from;
25
-
26
-    /**
27
-     * @var string
28
-     */
29
-    protected $to;
30
-
31
-    /**
32
-     * @param string $from The original base path (directory, not file!)
33
-     * @param string $to   The new base path (directory, not file!)
34
-     */
35
-    public function __construct($from, $to)
36
-    {
37
-        $shared = $this->shared($from, $to);
38
-        if ($shared === '') {
39
-            // when both paths have nothing in common, one of them is probably
40
-            // absolute while the other is relative
41
-            $cwd = getcwd();
42
-            $from = strpos($from, $cwd) === 0 ? $from : $cwd.'/'.$from;
43
-            $to = strpos($to, $cwd) === 0 ? $to : $cwd.'/'.$to;
44
-
45
-            // or traveling the tree via `..`
46
-            // attempt to resolve path, or assume it's fine if it doesn't exist
47
-            $from = realpath($from) ?: $from;
48
-            $to = realpath($to) ?: $to;
49
-        }
50
-
51
-        $from = $this->normalize($from);
52
-        $to = $this->normalize($to);
53
-
54
-        $from = $this->dirname($from);
55
-        $to = $this->dirname($to);
56
-
57
-        $this->from = $from;
58
-        $this->to = $to;
59
-    }
60
-
61
-    /**
62
-     * Normalize path.
63
-     *
64
-     * @param string $path
65
-     *
66
-     * @return string
67
-     */
68
-    protected function normalize($path)
69
-    {
70
-        // deal with different operating systems' directory structure
71
-        $path = rtrim(str_replace(DIRECTORY_SEPARATOR, '/', $path), '/');
72
-
73
-        /*
21
+	/**
22
+	 * @var string
23
+	 */
24
+	protected $from;
25
+
26
+	/**
27
+	 * @var string
28
+	 */
29
+	protected $to;
30
+
31
+	/**
32
+	 * @param string $from The original base path (directory, not file!)
33
+	 * @param string $to   The new base path (directory, not file!)
34
+	 */
35
+	public function __construct($from, $to)
36
+	{
37
+		$shared = $this->shared($from, $to);
38
+		if ($shared === '') {
39
+			// when both paths have nothing in common, one of them is probably
40
+			// absolute while the other is relative
41
+			$cwd = getcwd();
42
+			$from = strpos($from, $cwd) === 0 ? $from : $cwd.'/'.$from;
43
+			$to = strpos($to, $cwd) === 0 ? $to : $cwd.'/'.$to;
44
+
45
+			// or traveling the tree via `..`
46
+			// attempt to resolve path, or assume it's fine if it doesn't exist
47
+			$from = realpath($from) ?: $from;
48
+			$to = realpath($to) ?: $to;
49
+		}
50
+
51
+		$from = $this->normalize($from);
52
+		$to = $this->normalize($to);
53
+
54
+		$from = $this->dirname($from);
55
+		$to = $this->dirname($to);
56
+
57
+		$this->from = $from;
58
+		$this->to = $to;
59
+	}
60
+
61
+	/**
62
+	 * Normalize path.
63
+	 *
64
+	 * @param string $path
65
+	 *
66
+	 * @return string
67
+	 */
68
+	protected function normalize($path)
69
+	{
70
+		// deal with different operating systems' directory structure
71
+		$path = rtrim(str_replace(DIRECTORY_SEPARATOR, '/', $path), '/');
72
+
73
+		/*
74 74
          * Example:
75 75
          *     /home/forkcms/frontend/cache/compiled_templates/../../core/layout/css/../images/img.gif
76 76
          * to
77 77
          *     /home/forkcms/frontend/core/layout/images/img.gif
78 78
          */
79
-        do {
80
-            $path = preg_replace('/[^\/]+(?<!\.\.)\/\.\.\//', '', $path, -1, $count);
81
-        } while ($count);
82
-
83
-        return $path;
84
-    }
85
-
86
-    /**
87
-     * Figure out the shared path of 2 locations.
88
-     *
89
-     * Example:
90
-     *     /home/forkcms/frontend/core/layout/images/img.gif
91
-     * and
92
-     *     /home/forkcms/frontend/cache/minified_css
93
-     * share
94
-     *     /home/forkcms/frontend
95
-     *
96
-     * @param string $path1
97
-     * @param string $path2
98
-     *
99
-     * @return string
100
-     */
101
-    protected function shared($path1, $path2)
102
-    {
103
-        // $path could theoretically be empty (e.g. no path is given), in which
104
-        // case it shouldn't expand to array(''), which would compare to one's
105
-        // root /
106
-        $path1 = $path1 ? explode('/', $path1) : array();
107
-        $path2 = $path2 ? explode('/', $path2) : array();
108
-
109
-        $shared = array();
110
-
111
-        // compare paths & strip identical ancestors
112
-        foreach ($path1 as $i => $chunk) {
113
-            if (isset($path2[$i]) && $path1[$i] == $path2[$i]) {
114
-                $shared[] = $chunk;
115
-            } else {
116
-                break;
117
-            }
118
-        }
119
-
120
-        return implode('/', $shared);
121
-    }
122
-
123
-    /**
124
-     * Convert paths relative from 1 file to another.
125
-     *
126
-     * E.g.
127
-     *     ../images/img.gif relative to /home/forkcms/frontend/core/layout/css
128
-     * should become:
129
-     *     ../../core/layout/images/img.gif relative to
130
-     *     /home/forkcms/frontend/cache/minified_css
131
-     *
132
-     * @param string $path The relative path that needs to be converted.
133
-     *
134
-     * @return string The new relative path.
135
-     */
136
-    public function convert($path)
137
-    {
138
-        // quit early if conversion makes no sense
139
-        if ($this->from === $this->to) {
140
-            return $path;
141
-        }
142
-
143
-        $path = $this->normalize($path);
144
-        // if we're not dealing with a relative path, just return absolute
145
-        if (strpos($path, '/') === 0) {
146
-            return $path;
147
-        }
148
-
149
-        // normalize paths
150
-        $path = $this->normalize($this->from.'/'.$path);
151
-
152
-        // strip shared ancestor paths
153
-        $shared = $this->shared($path, $this->to);
154
-        $path = mb_substr($path, mb_strlen($shared));
155
-        $to = mb_substr($this->to, mb_strlen($shared));
156
-
157
-        // add .. for every directory that needs to be traversed to new path
158
-        $to = str_repeat('../', mb_substr_count($to, '/'));
159
-
160
-        return $to.ltrim($path, '/');
161
-    }
162
-
163
-    /**
164
-     * Attempt to get the directory name from a path.
165
-     *
166
-     * @param string $path
167
-     *
168
-     * @return string
169
-     */
170
-    public function dirname($path)
171
-    {
172
-        if (is_file($path)) {
173
-            return dirname($path);
174
-        }
175
-
176
-        if (is_dir($path)) {
177
-            return rtrim($path, '/');
178
-        }
179
-
180
-        // no known file/dir, start making assumptions
181
-
182
-        // ends in / = dir
183
-        if (mb_substr($path, -1) === '/') {
184
-            return rtrim($path, '/');
185
-        }
186
-
187
-        // has a dot in the name, likely a file
188
-        if (preg_match('/.*\..*$/', basename($path)) !== 0) {
189
-            return dirname($path);
190
-        }
191
-
192
-        // you're on your own here!
193
-        return $path;
194
-    }
79
+		do {
80
+			$path = preg_replace('/[^\/]+(?<!\.\.)\/\.\.\//', '', $path, -1, $count);
81
+		} while ($count);
82
+
83
+		return $path;
84
+	}
85
+
86
+	/**
87
+	 * Figure out the shared path of 2 locations.
88
+	 *
89
+	 * Example:
90
+	 *     /home/forkcms/frontend/core/layout/images/img.gif
91
+	 * and
92
+	 *     /home/forkcms/frontend/cache/minified_css
93
+	 * share
94
+	 *     /home/forkcms/frontend
95
+	 *
96
+	 * @param string $path1
97
+	 * @param string $path2
98
+	 *
99
+	 * @return string
100
+	 */
101
+	protected function shared($path1, $path2)
102
+	{
103
+		// $path could theoretically be empty (e.g. no path is given), in which
104
+		// case it shouldn't expand to array(''), which would compare to one's
105
+		// root /
106
+		$path1 = $path1 ? explode('/', $path1) : array();
107
+		$path2 = $path2 ? explode('/', $path2) : array();
108
+
109
+		$shared = array();
110
+
111
+		// compare paths & strip identical ancestors
112
+		foreach ($path1 as $i => $chunk) {
113
+			if (isset($path2[$i]) && $path1[$i] == $path2[$i]) {
114
+				$shared[] = $chunk;
115
+			} else {
116
+				break;
117
+			}
118
+		}
119
+
120
+		return implode('/', $shared);
121
+	}
122
+
123
+	/**
124
+	 * Convert paths relative from 1 file to another.
125
+	 *
126
+	 * E.g.
127
+	 *     ../images/img.gif relative to /home/forkcms/frontend/core/layout/css
128
+	 * should become:
129
+	 *     ../../core/layout/images/img.gif relative to
130
+	 *     /home/forkcms/frontend/cache/minified_css
131
+	 *
132
+	 * @param string $path The relative path that needs to be converted.
133
+	 *
134
+	 * @return string The new relative path.
135
+	 */
136
+	public function convert($path)
137
+	{
138
+		// quit early if conversion makes no sense
139
+		if ($this->from === $this->to) {
140
+			return $path;
141
+		}
142
+
143
+		$path = $this->normalize($path);
144
+		// if we're not dealing with a relative path, just return absolute
145
+		if (strpos($path, '/') === 0) {
146
+			return $path;
147
+		}
148
+
149
+		// normalize paths
150
+		$path = $this->normalize($this->from.'/'.$path);
151
+
152
+		// strip shared ancestor paths
153
+		$shared = $this->shared($path, $this->to);
154
+		$path = mb_substr($path, mb_strlen($shared));
155
+		$to = mb_substr($this->to, mb_strlen($shared));
156
+
157
+		// add .. for every directory that needs to be traversed to new path
158
+		$to = str_repeat('../', mb_substr_count($to, '/'));
159
+
160
+		return $to.ltrim($path, '/');
161
+	}
162
+
163
+	/**
164
+	 * Attempt to get the directory name from a path.
165
+	 *
166
+	 * @param string $path
167
+	 *
168
+	 * @return string
169
+	 */
170
+	public function dirname($path)
171
+	{
172
+		if (is_file($path)) {
173
+			return dirname($path);
174
+		}
175
+
176
+		if (is_dir($path)) {
177
+			return rtrim($path, '/');
178
+		}
179
+
180
+		// no known file/dir, start making assumptions
181
+
182
+		// ends in / = dir
183
+		if (mb_substr($path, -1) === '/') {
184
+			return rtrim($path, '/');
185
+		}
186
+
187
+		// has a dot in the name, likely a file
188
+		if (preg_match('/.*\..*$/', basename($path)) !== 0) {
189
+			return dirname($path);
190
+		}
191
+
192
+		// you're on your own here!
193
+		return $path;
194
+	}
195 195
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -39,8 +39,8 @@  discard block
 block discarded – undo
39 39
             // when both paths have nothing in common, one of them is probably
40 40
             // absolute while the other is relative
41 41
             $cwd = getcwd();
42
-            $from = strpos($from, $cwd) === 0 ? $from : $cwd.'/'.$from;
43
-            $to = strpos($to, $cwd) === 0 ? $to : $cwd.'/'.$to;
42
+            $from = strpos($from, $cwd) === 0 ? $from : $cwd . '/' . $from;
43
+            $to = strpos($to, $cwd) === 0 ? $to : $cwd . '/' . $to;
44 44
 
45 45
             // or traveling the tree via `..`
46 46
             // attempt to resolve path, or assume it's fine if it doesn't exist
@@ -147,7 +147,7 @@  discard block
 block discarded – undo
147 147
         }
148 148
 
149 149
         // normalize paths
150
-        $path = $this->normalize($this->from.'/'.$path);
150
+        $path = $this->normalize($this->from . '/' . $path);
151 151
 
152 152
         // strip shared ancestor paths
153 153
         $shared = $this->shared($path, $this->to);
@@ -157,7 +157,7 @@  discard block
 block discarded – undo
157 157
         // add .. for every directory that needs to be traversed to new path
158 158
         $to = str_repeat('../', mb_substr_count($to, '/'));
159 159
 
160
-        return $to.ltrim($path, '/');
160
+        return $to . ltrim($path, '/');
161 161
     }
162 162
 
163 163
     /**
Please login to merge, or discard this patch.
Sources/minify/src/JS.php 2 patches
Indentation   +397 added lines, -397 removed lines patch added patch discarded remove patch
@@ -14,122 +14,122 @@  discard block
 block discarded – undo
14 14
  */
15 15
 class JS extends Minify
16 16
 {
17
-    /**
18
-     * Var-matching regex based on http://stackoverflow.com/a/9337047/802993.
19
-     *
20
-     * Note that regular expressions using that bit must have the PCRE_UTF8
21
-     * pattern modifier (/u) set.
22
-     *
23
-     * @var string
24
-     */
25
-    const REGEX_VARIABLE = '\b[$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\x{02c1}\x{02c6}-\x{02d1}\x{02e0}-\x{02e4}\x{02ec}\x{02ee}\x{0370}-\x{0374}\x{0376}\x{0377}\x{037a}-\x{037d}\x{0386}\x{0388}-\x{038a}\x{038c}\x{038e}-\x{03a1}\x{03a3}-\x{03f5}\x{03f7}-\x{0481}\x{048a}-\x{0527}\x{0531}-\x{0556}\x{0559}\x{0561}-\x{0587}\x{05d0}-\x{05ea}\x{05f0}-\x{05f2}\x{0620}-\x{064a}\x{066e}\x{066f}\x{0671}-\x{06d3}\x{06d5}\x{06e5}\x{06e6}\x{06ee}\x{06ef}\x{06fa}-\x{06fc}\x{06ff}\x{0710}\x{0712}-\x{072f}\x{074d}-\x{07a5}\x{07b1}\x{07ca}-\x{07ea}\x{07f4}\x{07f5}\x{07fa}\x{0800}-\x{0815}\x{081a}\x{0824}\x{0828}\x{0840}-\x{0858}\x{08a0}\x{08a2}-\x{08ac}\x{0904}-\x{0939}\x{093d}\x{0950}\x{0958}-\x{0961}\x{0971}-\x{0977}\x{0979}-\x{097f}\x{0985}-\x{098c}\x{098f}\x{0990}\x{0993}-\x{09a8}\x{09aa}-\x{09b0}\x{09b2}\x{09b6}-\x{09b9}\x{09bd}\x{09ce}\x{09dc}\x{09dd}\x{09df}-\x{09e1}\x{09f0}\x{09f1}\x{0a05}-\x{0a0a}\x{0a0f}\x{0a10}\x{0a13}-\x{0a28}\x{0a2a}-\x{0a30}\x{0a32}\x{0a33}\x{0a35}\x{0a36}\x{0a38}\x{0a39}\x{0a59}-\x{0a5c}\x{0a5e}\x{0a72}-\x{0a74}\x{0a85}-\x{0a8d}\x{0a8f}-\x{0a91}\x{0a93}-\x{0aa8}\x{0aaa}-\x{0ab0}\x{0ab2}\x{0ab3}\x{0ab5}-\x{0ab9}\x{0abd}\x{0ad0}\x{0ae0}\x{0ae1}\x{0b05}-\x{0b0c}\x{0b0f}\x{0b10}\x{0b13}-\x{0b28}\x{0b2a}-\x{0b30}\x{0b32}\x{0b33}\x{0b35}-\x{0b39}\x{0b3d}\x{0b5c}\x{0b5d}\x{0b5f}-\x{0b61}\x{0b71}\x{0b83}\x{0b85}-\x{0b8a}\x{0b8e}-\x{0b90}\x{0b92}-\x{0b95}\x{0b99}\x{0b9a}\x{0b9c}\x{0b9e}\x{0b9f}\x{0ba3}\x{0ba4}\x{0ba8}-\x{0baa}\x{0bae}-\x{0bb9}\x{0bd0}\x{0c05}-\x{0c0c}\x{0c0e}-\x{0c10}\x{0c12}-\x{0c28}\x{0c2a}-\x{0c33}\x{0c35}-\x{0c39}\x{0c3d}\x{0c58}\x{0c59}\x{0c60}\x{0c61}\x{0c85}-\x{0c8c}\x{0c8e}-\x{0c90}\x{0c92}-\x{0ca8}\x{0caa}-\x{0cb3}\x{0cb5}-\x{0cb9}\x{0cbd}\x{0cde}\x{0ce0}\x{0ce1}\x{0cf1}\x{0cf2}\x{0d05}-\x{0d0c}\x{0d0e}-\x{0d10}\x{0d12}-\x{0d3a}\x{0d3d}\x{0d4e}\x{0d60}\x{0d61}\x{0d7a}-\x{0d7f}\x{0d85}-\x{0d96}\x{0d9a}-\x{0db1}\x{0db3}-\x{0dbb}\x{0dbd}\x{0dc0}-\x{0dc6}\x{0e01}-\x{0e30}\x{0e32}\x{0e33}\x{0e40}-\x{0e46}\x{0e81}\x{0e82}\x{0e84}\x{0e87}\x{0e88}\x{0e8a}\x{0e8d}\x{0e94}-\x{0e97}\x{0e99}-\x{0e9f}\x{0ea1}-\x{0ea3}\x{0ea5}\x{0ea7}\x{0eaa}\x{0eab}\x{0ead}-\x{0eb0}\x{0eb2}\x{0eb3}\x{0ebd}\x{0ec0}-\x{0ec4}\x{0ec6}\x{0edc}-\x{0edf}\x{0f00}\x{0f40}-\x{0f47}\x{0f49}-\x{0f6c}\x{0f88}-\x{0f8c}\x{1000}-\x{102a}\x{103f}\x{1050}-\x{1055}\x{105a}-\x{105d}\x{1061}\x{1065}\x{1066}\x{106e}-\x{1070}\x{1075}-\x{1081}\x{108e}\x{10a0}-\x{10c5}\x{10c7}\x{10cd}\x{10d0}-\x{10fa}\x{10fc}-\x{1248}\x{124a}-\x{124d}\x{1250}-\x{1256}\x{1258}\x{125a}-\x{125d}\x{1260}-\x{1288}\x{128a}-\x{128d}\x{1290}-\x{12b0}\x{12b2}-\x{12b5}\x{12b8}-\x{12be}\x{12c0}\x{12c2}-\x{12c5}\x{12c8}-\x{12d6}\x{12d8}-\x{1310}\x{1312}-\x{1315}\x{1318}-\x{135a}\x{1380}-\x{138f}\x{13a0}-\x{13f4}\x{1401}-\x{166c}\x{166f}-\x{167f}\x{1681}-\x{169a}\x{16a0}-\x{16ea}\x{16ee}-\x{16f0}\x{1700}-\x{170c}\x{170e}-\x{1711}\x{1720}-\x{1731}\x{1740}-\x{1751}\x{1760}-\x{176c}\x{176e}-\x{1770}\x{1780}-\x{17b3}\x{17d7}\x{17dc}\x{1820}-\x{1877}\x{1880}-\x{18a8}\x{18aa}\x{18b0}-\x{18f5}\x{1900}-\x{191c}\x{1950}-\x{196d}\x{1970}-\x{1974}\x{1980}-\x{19ab}\x{19c1}-\x{19c7}\x{1a00}-\x{1a16}\x{1a20}-\x{1a54}\x{1aa7}\x{1b05}-\x{1b33}\x{1b45}-\x{1b4b}\x{1b83}-\x{1ba0}\x{1bae}\x{1baf}\x{1bba}-\x{1be5}\x{1c00}-\x{1c23}\x{1c4d}-\x{1c4f}\x{1c5a}-\x{1c7d}\x{1ce9}-\x{1cec}\x{1cee}-\x{1cf1}\x{1cf5}\x{1cf6}\x{1d00}-\x{1dbf}\x{1e00}-\x{1f15}\x{1f18}-\x{1f1d}\x{1f20}-\x{1f45}\x{1f48}-\x{1f4d}\x{1f50}-\x{1f57}\x{1f59}\x{1f5b}\x{1f5d}\x{1f5f}-\x{1f7d}\x{1f80}-\x{1fb4}\x{1fb6}-\x{1fbc}\x{1fbe}\x{1fc2}-\x{1fc4}\x{1fc6}-\x{1fcc}\x{1fd0}-\x{1fd3}\x{1fd6}-\x{1fdb}\x{1fe0}-\x{1fec}\x{1ff2}-\x{1ff4}\x{1ff6}-\x{1ffc}\x{2071}\x{207f}\x{2090}-\x{209c}\x{2102}\x{2107}\x{210a}-\x{2113}\x{2115}\x{2119}-\x{211d}\x{2124}\x{2126}\x{2128}\x{212a}-\x{212d}\x{212f}-\x{2139}\x{213c}-\x{213f}\x{2145}-\x{2149}\x{214e}\x{2160}-\x{2188}\x{2c00}-\x{2c2e}\x{2c30}-\x{2c5e}\x{2c60}-\x{2ce4}\x{2ceb}-\x{2cee}\x{2cf2}\x{2cf3}\x{2d00}-\x{2d25}\x{2d27}\x{2d2d}\x{2d30}-\x{2d67}\x{2d6f}\x{2d80}-\x{2d96}\x{2da0}-\x{2da6}\x{2da8}-\x{2dae}\x{2db0}-\x{2db6}\x{2db8}-\x{2dbe}\x{2dc0}-\x{2dc6}\x{2dc8}-\x{2dce}\x{2dd0}-\x{2dd6}\x{2dd8}-\x{2dde}\x{2e2f}\x{3005}-\x{3007}\x{3021}-\x{3029}\x{3031}-\x{3035}\x{3038}-\x{303c}\x{3041}-\x{3096}\x{309d}-\x{309f}\x{30a1}-\x{30fa}\x{30fc}-\x{30ff}\x{3105}-\x{312d}\x{3131}-\x{318e}\x{31a0}-\x{31ba}\x{31f0}-\x{31ff}\x{3400}-\x{4db5}\x{4e00}-\x{9fcc}\x{a000}-\x{a48c}\x{a4d0}-\x{a4fd}\x{a500}-\x{a60c}\x{a610}-\x{a61f}\x{a62a}\x{a62b}\x{a640}-\x{a66e}\x{a67f}-\x{a697}\x{a6a0}-\x{a6ef}\x{a717}-\x{a71f}\x{a722}-\x{a788}\x{a78b}-\x{a78e}\x{a790}-\x{a793}\x{a7a0}-\x{a7aa}\x{a7f8}-\x{a801}\x{a803}-\x{a805}\x{a807}-\x{a80a}\x{a80c}-\x{a822}\x{a840}-\x{a873}\x{a882}-\x{a8b3}\x{a8f2}-\x{a8f7}\x{a8fb}\x{a90a}-\x{a925}\x{a930}-\x{a946}\x{a960}-\x{a97c}\x{a984}-\x{a9b2}\x{a9cf}\x{aa00}-\x{aa28}\x{aa40}-\x{aa42}\x{aa44}-\x{aa4b}\x{aa60}-\x{aa76}\x{aa7a}\x{aa80}-\x{aaaf}\x{aab1}\x{aab5}\x{aab6}\x{aab9}-\x{aabd}\x{aac0}\x{aac2}\x{aadb}-\x{aadd}\x{aae0}-\x{aaea}\x{aaf2}-\x{aaf4}\x{ab01}-\x{ab06}\x{ab09}-\x{ab0e}\x{ab11}-\x{ab16}\x{ab20}-\x{ab26}\x{ab28}-\x{ab2e}\x{abc0}-\x{abe2}\x{ac00}-\x{d7a3}\x{d7b0}-\x{d7c6}\x{d7cb}-\x{d7fb}\x{f900}-\x{fa6d}\x{fa70}-\x{fad9}\x{fb00}-\x{fb06}\x{fb13}-\x{fb17}\x{fb1d}\x{fb1f}-\x{fb28}\x{fb2a}-\x{fb36}\x{fb38}-\x{fb3c}\x{fb3e}\x{fb40}\x{fb41}\x{fb43}\x{fb44}\x{fb46}-\x{fbb1}\x{fbd3}-\x{fd3d}\x{fd50}-\x{fd8f}\x{fd92}-\x{fdc7}\x{fdf0}-\x{fdfb}\x{fe70}-\x{fe74}\x{fe76}-\x{fefc}\x{ff21}-\x{ff3a}\x{ff41}-\x{ff5a}\x{ff66}-\x{ffbe}\x{ffc2}-\x{ffc7}\x{ffca}-\x{ffcf}\x{ffd2}-\x{ffd7}\x{ffda}-\x{ffdc}][$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\x{02c1}\x{02c6}-\x{02d1}\x{02e0}-\x{02e4}\x{02ec}\x{02ee}\x{0370}-\x{0374}\x{0376}\x{0377}\x{037a}-\x{037d}\x{0386}\x{0388}-\x{038a}\x{038c}\x{038e}-\x{03a1}\x{03a3}-\x{03f5}\x{03f7}-\x{0481}\x{048a}-\x{0527}\x{0531}-\x{0556}\x{0559}\x{0561}-\x{0587}\x{05d0}-\x{05ea}\x{05f0}-\x{05f2}\x{0620}-\x{064a}\x{066e}\x{066f}\x{0671}-\x{06d3}\x{06d5}\x{06e5}\x{06e6}\x{06ee}\x{06ef}\x{06fa}-\x{06fc}\x{06ff}\x{0710}\x{0712}-\x{072f}\x{074d}-\x{07a5}\x{07b1}\x{07ca}-\x{07ea}\x{07f4}\x{07f5}\x{07fa}\x{0800}-\x{0815}\x{081a}\x{0824}\x{0828}\x{0840}-\x{0858}\x{08a0}\x{08a2}-\x{08ac}\x{0904}-\x{0939}\x{093d}\x{0950}\x{0958}-\x{0961}\x{0971}-\x{0977}\x{0979}-\x{097f}\x{0985}-\x{098c}\x{098f}\x{0990}\x{0993}-\x{09a8}\x{09aa}-\x{09b0}\x{09b2}\x{09b6}-\x{09b9}\x{09bd}\x{09ce}\x{09dc}\x{09dd}\x{09df}-\x{09e1}\x{09f0}\x{09f1}\x{0a05}-\x{0a0a}\x{0a0f}\x{0a10}\x{0a13}-\x{0a28}\x{0a2a}-\x{0a30}\x{0a32}\x{0a33}\x{0a35}\x{0a36}\x{0a38}\x{0a39}\x{0a59}-\x{0a5c}\x{0a5e}\x{0a72}-\x{0a74}\x{0a85}-\x{0a8d}\x{0a8f}-\x{0a91}\x{0a93}-\x{0aa8}\x{0aaa}-\x{0ab0}\x{0ab2}\x{0ab3}\x{0ab5}-\x{0ab9}\x{0abd}\x{0ad0}\x{0ae0}\x{0ae1}\x{0b05}-\x{0b0c}\x{0b0f}\x{0b10}\x{0b13}-\x{0b28}\x{0b2a}-\x{0b30}\x{0b32}\x{0b33}\x{0b35}-\x{0b39}\x{0b3d}\x{0b5c}\x{0b5d}\x{0b5f}-\x{0b61}\x{0b71}\x{0b83}\x{0b85}-\x{0b8a}\x{0b8e}-\x{0b90}\x{0b92}-\x{0b95}\x{0b99}\x{0b9a}\x{0b9c}\x{0b9e}\x{0b9f}\x{0ba3}\x{0ba4}\x{0ba8}-\x{0baa}\x{0bae}-\x{0bb9}\x{0bd0}\x{0c05}-\x{0c0c}\x{0c0e}-\x{0c10}\x{0c12}-\x{0c28}\x{0c2a}-\x{0c33}\x{0c35}-\x{0c39}\x{0c3d}\x{0c58}\x{0c59}\x{0c60}\x{0c61}\x{0c85}-\x{0c8c}\x{0c8e}-\x{0c90}\x{0c92}-\x{0ca8}\x{0caa}-\x{0cb3}\x{0cb5}-\x{0cb9}\x{0cbd}\x{0cde}\x{0ce0}\x{0ce1}\x{0cf1}\x{0cf2}\x{0d05}-\x{0d0c}\x{0d0e}-\x{0d10}\x{0d12}-\x{0d3a}\x{0d3d}\x{0d4e}\x{0d60}\x{0d61}\x{0d7a}-\x{0d7f}\x{0d85}-\x{0d96}\x{0d9a}-\x{0db1}\x{0db3}-\x{0dbb}\x{0dbd}\x{0dc0}-\x{0dc6}\x{0e01}-\x{0e30}\x{0e32}\x{0e33}\x{0e40}-\x{0e46}\x{0e81}\x{0e82}\x{0e84}\x{0e87}\x{0e88}\x{0e8a}\x{0e8d}\x{0e94}-\x{0e97}\x{0e99}-\x{0e9f}\x{0ea1}-\x{0ea3}\x{0ea5}\x{0ea7}\x{0eaa}\x{0eab}\x{0ead}-\x{0eb0}\x{0eb2}\x{0eb3}\x{0ebd}\x{0ec0}-\x{0ec4}\x{0ec6}\x{0edc}-\x{0edf}\x{0f00}\x{0f40}-\x{0f47}\x{0f49}-\x{0f6c}\x{0f88}-\x{0f8c}\x{1000}-\x{102a}\x{103f}\x{1050}-\x{1055}\x{105a}-\x{105d}\x{1061}\x{1065}\x{1066}\x{106e}-\x{1070}\x{1075}-\x{1081}\x{108e}\x{10a0}-\x{10c5}\x{10c7}\x{10cd}\x{10d0}-\x{10fa}\x{10fc}-\x{1248}\x{124a}-\x{124d}\x{1250}-\x{1256}\x{1258}\x{125a}-\x{125d}\x{1260}-\x{1288}\x{128a}-\x{128d}\x{1290}-\x{12b0}\x{12b2}-\x{12b5}\x{12b8}-\x{12be}\x{12c0}\x{12c2}-\x{12c5}\x{12c8}-\x{12d6}\x{12d8}-\x{1310}\x{1312}-\x{1315}\x{1318}-\x{135a}\x{1380}-\x{138f}\x{13a0}-\x{13f4}\x{1401}-\x{166c}\x{166f}-\x{167f}\x{1681}-\x{169a}\x{16a0}-\x{16ea}\x{16ee}-\x{16f0}\x{1700}-\x{170c}\x{170e}-\x{1711}\x{1720}-\x{1731}\x{1740}-\x{1751}\x{1760}-\x{176c}\x{176e}-\x{1770}\x{1780}-\x{17b3}\x{17d7}\x{17dc}\x{1820}-\x{1877}\x{1880}-\x{18a8}\x{18aa}\x{18b0}-\x{18f5}\x{1900}-\x{191c}\x{1950}-\x{196d}\x{1970}-\x{1974}\x{1980}-\x{19ab}\x{19c1}-\x{19c7}\x{1a00}-\x{1a16}\x{1a20}-\x{1a54}\x{1aa7}\x{1b05}-\x{1b33}\x{1b45}-\x{1b4b}\x{1b83}-\x{1ba0}\x{1bae}\x{1baf}\x{1bba}-\x{1be5}\x{1c00}-\x{1c23}\x{1c4d}-\x{1c4f}\x{1c5a}-\x{1c7d}\x{1ce9}-\x{1cec}\x{1cee}-\x{1cf1}\x{1cf5}\x{1cf6}\x{1d00}-\x{1dbf}\x{1e00}-\x{1f15}\x{1f18}-\x{1f1d}\x{1f20}-\x{1f45}\x{1f48}-\x{1f4d}\x{1f50}-\x{1f57}\x{1f59}\x{1f5b}\x{1f5d}\x{1f5f}-\x{1f7d}\x{1f80}-\x{1fb4}\x{1fb6}-\x{1fbc}\x{1fbe}\x{1fc2}-\x{1fc4}\x{1fc6}-\x{1fcc}\x{1fd0}-\x{1fd3}\x{1fd6}-\x{1fdb}\x{1fe0}-\x{1fec}\x{1ff2}-\x{1ff4}\x{1ff6}-\x{1ffc}\x{2071}\x{207f}\x{2090}-\x{209c}\x{2102}\x{2107}\x{210a}-\x{2113}\x{2115}\x{2119}-\x{211d}\x{2124}\x{2126}\x{2128}\x{212a}-\x{212d}\x{212f}-\x{2139}\x{213c}-\x{213f}\x{2145}-\x{2149}\x{214e}\x{2160}-\x{2188}\x{2c00}-\x{2c2e}\x{2c30}-\x{2c5e}\x{2c60}-\x{2ce4}\x{2ceb}-\x{2cee}\x{2cf2}\x{2cf3}\x{2d00}-\x{2d25}\x{2d27}\x{2d2d}\x{2d30}-\x{2d67}\x{2d6f}\x{2d80}-\x{2d96}\x{2da0}-\x{2da6}\x{2da8}-\x{2dae}\x{2db0}-\x{2db6}\x{2db8}-\x{2dbe}\x{2dc0}-\x{2dc6}\x{2dc8}-\x{2dce}\x{2dd0}-\x{2dd6}\x{2dd8}-\x{2dde}\x{2e2f}\x{3005}-\x{3007}\x{3021}-\x{3029}\x{3031}-\x{3035}\x{3038}-\x{303c}\x{3041}-\x{3096}\x{309d}-\x{309f}\x{30a1}-\x{30fa}\x{30fc}-\x{30ff}\x{3105}-\x{312d}\x{3131}-\x{318e}\x{31a0}-\x{31ba}\x{31f0}-\x{31ff}\x{3400}-\x{4db5}\x{4e00}-\x{9fcc}\x{a000}-\x{a48c}\x{a4d0}-\x{a4fd}\x{a500}-\x{a60c}\x{a610}-\x{a61f}\x{a62a}\x{a62b}\x{a640}-\x{a66e}\x{a67f}-\x{a697}\x{a6a0}-\x{a6ef}\x{a717}-\x{a71f}\x{a722}-\x{a788}\x{a78b}-\x{a78e}\x{a790}-\x{a793}\x{a7a0}-\x{a7aa}\x{a7f8}-\x{a801}\x{a803}-\x{a805}\x{a807}-\x{a80a}\x{a80c}-\x{a822}\x{a840}-\x{a873}\x{a882}-\x{a8b3}\x{a8f2}-\x{a8f7}\x{a8fb}\x{a90a}-\x{a925}\x{a930}-\x{a946}\x{a960}-\x{a97c}\x{a984}-\x{a9b2}\x{a9cf}\x{aa00}-\x{aa28}\x{aa40}-\x{aa42}\x{aa44}-\x{aa4b}\x{aa60}-\x{aa76}\x{aa7a}\x{aa80}-\x{aaaf}\x{aab1}\x{aab5}\x{aab6}\x{aab9}-\x{aabd}\x{aac0}\x{aac2}\x{aadb}-\x{aadd}\x{aae0}-\x{aaea}\x{aaf2}-\x{aaf4}\x{ab01}-\x{ab06}\x{ab09}-\x{ab0e}\x{ab11}-\x{ab16}\x{ab20}-\x{ab26}\x{ab28}-\x{ab2e}\x{abc0}-\x{abe2}\x{ac00}-\x{d7a3}\x{d7b0}-\x{d7c6}\x{d7cb}-\x{d7fb}\x{f900}-\x{fa6d}\x{fa70}-\x{fad9}\x{fb00}-\x{fb06}\x{fb13}-\x{fb17}\x{fb1d}\x{fb1f}-\x{fb28}\x{fb2a}-\x{fb36}\x{fb38}-\x{fb3c}\x{fb3e}\x{fb40}\x{fb41}\x{fb43}\x{fb44}\x{fb46}-\x{fbb1}\x{fbd3}-\x{fd3d}\x{fd50}-\x{fd8f}\x{fd92}-\x{fdc7}\x{fdf0}-\x{fdfb}\x{fe70}-\x{fe74}\x{fe76}-\x{fefc}\x{ff21}-\x{ff3a}\x{ff41}-\x{ff5a}\x{ff66}-\x{ffbe}\x{ffc2}-\x{ffc7}\x{ffca}-\x{ffcf}\x{ffd2}-\x{ffd7}\x{ffda}-\x{ffdc}0-9\x{0300}-\x{036f}\x{0483}-\x{0487}\x{0591}-\x{05bd}\x{05bf}\x{05c1}\x{05c2}\x{05c4}\x{05c5}\x{05c7}\x{0610}-\x{061a}\x{064b}-\x{0669}\x{0670}\x{06d6}-\x{06dc}\x{06df}-\x{06e4}\x{06e7}\x{06e8}\x{06ea}-\x{06ed}\x{06f0}-\x{06f9}\x{0711}\x{0730}-\x{074a}\x{07a6}-\x{07b0}\x{07c0}-\x{07c9}\x{07eb}-\x{07f3}\x{0816}-\x{0819}\x{081b}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082d}\x{0859}-\x{085b}\x{08e4}-\x{08fe}\x{0900}-\x{0903}\x{093a}-\x{093c}\x{093e}-\x{094f}\x{0951}-\x{0957}\x{0962}\x{0963}\x{0966}-\x{096f}\x{0981}-\x{0983}\x{09bc}\x{09be}-\x{09c4}\x{09c7}\x{09c8}\x{09cb}-\x{09cd}\x{09d7}\x{09e2}\x{09e3}\x{09e6}-\x{09ef}\x{0a01}-\x{0a03}\x{0a3c}\x{0a3e}-\x{0a42}\x{0a47}\x{0a48}\x{0a4b}-\x{0a4d}\x{0a51}\x{0a66}-\x{0a71}\x{0a75}\x{0a81}-\x{0a83}\x{0abc}\x{0abe}-\x{0ac5}\x{0ac7}-\x{0ac9}\x{0acb}-\x{0acd}\x{0ae2}\x{0ae3}\x{0ae6}-\x{0aef}\x{0b01}-\x{0b03}\x{0b3c}\x{0b3e}-\x{0b44}\x{0b47}\x{0b48}\x{0b4b}-\x{0b4d}\x{0b56}\x{0b57}\x{0b62}\x{0b63}\x{0b66}-\x{0b6f}\x{0b82}\x{0bbe}-\x{0bc2}\x{0bc6}-\x{0bc8}\x{0bca}-\x{0bcd}\x{0bd7}\x{0be6}-\x{0bef}\x{0c01}-\x{0c03}\x{0c3e}-\x{0c44}\x{0c46}-\x{0c48}\x{0c4a}-\x{0c4d}\x{0c55}\x{0c56}\x{0c62}\x{0c63}\x{0c66}-\x{0c6f}\x{0c82}\x{0c83}\x{0cbc}\x{0cbe}-\x{0cc4}\x{0cc6}-\x{0cc8}\x{0cca}-\x{0ccd}\x{0cd5}\x{0cd6}\x{0ce2}\x{0ce3}\x{0ce6}-\x{0cef}\x{0d02}\x{0d03}\x{0d3e}-\x{0d44}\x{0d46}-\x{0d48}\x{0d4a}-\x{0d4d}\x{0d57}\x{0d62}\x{0d63}\x{0d66}-\x{0d6f}\x{0d82}\x{0d83}\x{0dca}\x{0dcf}-\x{0dd4}\x{0dd6}\x{0dd8}-\x{0ddf}\x{0df2}\x{0df3}\x{0e31}\x{0e34}-\x{0e3a}\x{0e47}-\x{0e4e}\x{0e50}-\x{0e59}\x{0eb1}\x{0eb4}-\x{0eb9}\x{0ebb}\x{0ebc}\x{0ec8}-\x{0ecd}\x{0ed0}-\x{0ed9}\x{0f18}\x{0f19}\x{0f20}-\x{0f29}\x{0f35}\x{0f37}\x{0f39}\x{0f3e}\x{0f3f}\x{0f71}-\x{0f84}\x{0f86}\x{0f87}\x{0f8d}-\x{0f97}\x{0f99}-\x{0fbc}\x{0fc6}\x{102b}-\x{103e}\x{1040}-\x{1049}\x{1056}-\x{1059}\x{105e}-\x{1060}\x{1062}-\x{1064}\x{1067}-\x{106d}\x{1071}-\x{1074}\x{1082}-\x{108d}\x{108f}-\x{109d}\x{135d}-\x{135f}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}\x{1753}\x{1772}\x{1773}\x{17b4}-\x{17d3}\x{17dd}\x{17e0}-\x{17e9}\x{180b}-\x{180d}\x{1810}-\x{1819}\x{18a9}\x{1920}-\x{192b}\x{1930}-\x{193b}\x{1946}-\x{194f}\x{19b0}-\x{19c0}\x{19c8}\x{19c9}\x{19d0}-\x{19d9}\x{1a17}-\x{1a1b}\x{1a55}-\x{1a5e}\x{1a60}-\x{1a7c}\x{1a7f}-\x{1a89}\x{1a90}-\x{1a99}\x{1b00}-\x{1b04}\x{1b34}-\x{1b44}\x{1b50}-\x{1b59}\x{1b6b}-\x{1b73}\x{1b80}-\x{1b82}\x{1ba1}-\x{1bad}\x{1bb0}-\x{1bb9}\x{1be6}-\x{1bf3}\x{1c24}-\x{1c37}\x{1c40}-\x{1c49}\x{1c50}-\x{1c59}\x{1cd0}-\x{1cd2}\x{1cd4}-\x{1ce8}\x{1ced}\x{1cf2}-\x{1cf4}\x{1dc0}-\x{1de6}\x{1dfc}-\x{1dff}\x{200c}\x{200d}\x{203f}\x{2040}\x{2054}\x{20d0}-\x{20dc}\x{20e1}\x{20e5}-\x{20f0}\x{2cef}-\x{2cf1}\x{2d7f}\x{2de0}-\x{2dff}\x{302a}-\x{302f}\x{3099}\x{309a}\x{a620}-\x{a629}\x{a66f}\x{a674}-\x{a67d}\x{a69f}\x{a6f0}\x{a6f1}\x{a802}\x{a806}\x{a80b}\x{a823}-\x{a827}\x{a880}\x{a881}\x{a8b4}-\x{a8c4}\x{a8d0}-\x{a8d9}\x{a8e0}-\x{a8f1}\x{a900}-\x{a909}\x{a926}-\x{a92d}\x{a947}-\x{a953}\x{a980}-\x{a983}\x{a9b3}-\x{a9c0}\x{a9d0}-\x{a9d9}\x{aa29}-\x{aa36}\x{aa43}\x{aa4c}\x{aa4d}\x{aa50}-\x{aa59}\x{aa7b}\x{aab0}\x{aab2}-\x{aab4}\x{aab7}\x{aab8}\x{aabe}\x{aabf}\x{aac1}\x{aaeb}-\x{aaef}\x{aaf5}\x{aaf6}\x{abe3}-\x{abea}\x{abec}\x{abed}\x{abf0}-\x{abf9}\x{fb1e}\x{fe00}-\x{fe0f}\x{fe20}-\x{fe26}\x{fe33}\x{fe34}\x{fe4d}-\x{fe4f}\x{ff10}-\x{ff19}\x{ff3f}]*\b';
26
-
27
-    /**
28
-     * Full list of JavaScript reserved words.
29
-     * Will be loaded from /data/js/keywords_reserved.txt.
30
-     *
31
-     * @see https://mathiasbynens.be/notes/reserved-keywords
32
-     *
33
-     * @var string[]
34
-     */
35
-    protected $keywordsReserved = array();
36
-
37
-    /**
38
-     * List of JavaScript reserved words that accept a <variable, value, ...>
39
-     * after them. Some end of lines are not the end of a statement, like with
40
-     * these keywords.
41
-     *
42
-     * E.g.: we shouldn't insert a ; after this else
43
-     * else
44
-     *     console.log('this is quite fine')
45
-     *
46
-     * Will be loaded from /data/js/keywords_before.txt
47
-     *
48
-     * @var string[]
49
-     */
50
-    protected $keywordsBefore = array();
51
-
52
-    /**
53
-     * List of JavaScript reserved words that accept a <variable, value, ...>
54
-     * before them. Some end of lines are not the end of a statement, like when
55
-     * continued by one of these keywords on the newline.
56
-     *
57
-     * E.g.: we shouldn't insert a ; before this instanceof
58
-     * variable
59
-     *     instanceof String
60
-     *
61
-     * Will be loaded from /data/js/keywords_after.txt
62
-     *
63
-     * @var string[]
64
-     */
65
-    protected $keywordsAfter = array();
66
-
67
-    /**
68
-     * List of JavaScript operators that accept a <variable, value, ...> after
69
-     * them. Some end of lines are not the end of a statement, like with these
70
-     * operators.
71
-     *
72
-     * Note: Most operators are fine, we've only removed !, ++ and --.
73
-     * There can't be a newline separating ! and whatever it is negating.
74
-     * ++ & -- have to be joined with the value they're in-/decrementing.
75
-     *
76
-     * Will be loaded from /data/js/operators_before.txt
77
-     *
78
-     * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
79
-     *
80
-     * @var string[]
81
-     */
82
-    protected $operatorsBefore = array();
83
-
84
-    /**
85
-     * List of JavaScript operators that accept a <variable, value, ...> before
86
-     * them. Some end of lines are not the end of a statement, like when
87
-     * continued by one of these operators on the newline.
88
-     *
89
-     * Note: Most operators are fine, we've only removed ), ], ++ and --.
90
-     * ++ & -- have to be joined with the value they're in-/decrementing.
91
-     * ) & ] are "special" in that they have lots or usecases. () for example
92
-     * is used for function calls, for grouping, in if () and for (), ...
93
-     *
94
-     * Will be loaded from /data/js/operators_after.txt
95
-     *
96
-     * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
97
-     *
98
-     * @var string[]
99
-     */
100
-    protected $operatorsAfter = array();
101
-
102
-    /**
103
-     * {@inheritdoc}
104
-     */
105
-    public function __construct()
106
-    {
107
-        call_user_func_array(array('parent', '__construct'), func_get_args());
108
-
109
-        $dataDir = __DIR__.'/../data/js/';
110
-        $options = FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES;
111
-        $this->keywordsReserved = file($dataDir.'keywords_reserved.txt', $options);
112
-        $this->keywordsBefore = file($dataDir.'keywords_before.txt', $options);
113
-        $this->keywordsAfter = file($dataDir.'keywords_after.txt', $options);
114
-        $this->operatorsBefore = file($dataDir.'operators_before.txt', $options);
115
-        $this->operatorsAfter = file($dataDir.'operators_after.txt', $options);
116
-    }
117
-
118
-    /**
119
-     * Minify the data.
120
-     * Perform JS optimizations.
121
-     *
122
-     * @param string[optional] $path Path to write the data to.
123
-     *
124
-     * @return string The minified data.
125
-     */
126
-    public function execute($path = null)
127
-    {
128
-        $content = '';
129
-
130
-        // loop files
131
-        foreach ($this->data as $source => $js) {
132
-            /*
17
+	/**
18
+	 * Var-matching regex based on http://stackoverflow.com/a/9337047/802993.
19
+	 *
20
+	 * Note that regular expressions using that bit must have the PCRE_UTF8
21
+	 * pattern modifier (/u) set.
22
+	 *
23
+	 * @var string
24
+	 */
25
+	const REGEX_VARIABLE = '\b[$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\x{02c1}\x{02c6}-\x{02d1}\x{02e0}-\x{02e4}\x{02ec}\x{02ee}\x{0370}-\x{0374}\x{0376}\x{0377}\x{037a}-\x{037d}\x{0386}\x{0388}-\x{038a}\x{038c}\x{038e}-\x{03a1}\x{03a3}-\x{03f5}\x{03f7}-\x{0481}\x{048a}-\x{0527}\x{0531}-\x{0556}\x{0559}\x{0561}-\x{0587}\x{05d0}-\x{05ea}\x{05f0}-\x{05f2}\x{0620}-\x{064a}\x{066e}\x{066f}\x{0671}-\x{06d3}\x{06d5}\x{06e5}\x{06e6}\x{06ee}\x{06ef}\x{06fa}-\x{06fc}\x{06ff}\x{0710}\x{0712}-\x{072f}\x{074d}-\x{07a5}\x{07b1}\x{07ca}-\x{07ea}\x{07f4}\x{07f5}\x{07fa}\x{0800}-\x{0815}\x{081a}\x{0824}\x{0828}\x{0840}-\x{0858}\x{08a0}\x{08a2}-\x{08ac}\x{0904}-\x{0939}\x{093d}\x{0950}\x{0958}-\x{0961}\x{0971}-\x{0977}\x{0979}-\x{097f}\x{0985}-\x{098c}\x{098f}\x{0990}\x{0993}-\x{09a8}\x{09aa}-\x{09b0}\x{09b2}\x{09b6}-\x{09b9}\x{09bd}\x{09ce}\x{09dc}\x{09dd}\x{09df}-\x{09e1}\x{09f0}\x{09f1}\x{0a05}-\x{0a0a}\x{0a0f}\x{0a10}\x{0a13}-\x{0a28}\x{0a2a}-\x{0a30}\x{0a32}\x{0a33}\x{0a35}\x{0a36}\x{0a38}\x{0a39}\x{0a59}-\x{0a5c}\x{0a5e}\x{0a72}-\x{0a74}\x{0a85}-\x{0a8d}\x{0a8f}-\x{0a91}\x{0a93}-\x{0aa8}\x{0aaa}-\x{0ab0}\x{0ab2}\x{0ab3}\x{0ab5}-\x{0ab9}\x{0abd}\x{0ad0}\x{0ae0}\x{0ae1}\x{0b05}-\x{0b0c}\x{0b0f}\x{0b10}\x{0b13}-\x{0b28}\x{0b2a}-\x{0b30}\x{0b32}\x{0b33}\x{0b35}-\x{0b39}\x{0b3d}\x{0b5c}\x{0b5d}\x{0b5f}-\x{0b61}\x{0b71}\x{0b83}\x{0b85}-\x{0b8a}\x{0b8e}-\x{0b90}\x{0b92}-\x{0b95}\x{0b99}\x{0b9a}\x{0b9c}\x{0b9e}\x{0b9f}\x{0ba3}\x{0ba4}\x{0ba8}-\x{0baa}\x{0bae}-\x{0bb9}\x{0bd0}\x{0c05}-\x{0c0c}\x{0c0e}-\x{0c10}\x{0c12}-\x{0c28}\x{0c2a}-\x{0c33}\x{0c35}-\x{0c39}\x{0c3d}\x{0c58}\x{0c59}\x{0c60}\x{0c61}\x{0c85}-\x{0c8c}\x{0c8e}-\x{0c90}\x{0c92}-\x{0ca8}\x{0caa}-\x{0cb3}\x{0cb5}-\x{0cb9}\x{0cbd}\x{0cde}\x{0ce0}\x{0ce1}\x{0cf1}\x{0cf2}\x{0d05}-\x{0d0c}\x{0d0e}-\x{0d10}\x{0d12}-\x{0d3a}\x{0d3d}\x{0d4e}\x{0d60}\x{0d61}\x{0d7a}-\x{0d7f}\x{0d85}-\x{0d96}\x{0d9a}-\x{0db1}\x{0db3}-\x{0dbb}\x{0dbd}\x{0dc0}-\x{0dc6}\x{0e01}-\x{0e30}\x{0e32}\x{0e33}\x{0e40}-\x{0e46}\x{0e81}\x{0e82}\x{0e84}\x{0e87}\x{0e88}\x{0e8a}\x{0e8d}\x{0e94}-\x{0e97}\x{0e99}-\x{0e9f}\x{0ea1}-\x{0ea3}\x{0ea5}\x{0ea7}\x{0eaa}\x{0eab}\x{0ead}-\x{0eb0}\x{0eb2}\x{0eb3}\x{0ebd}\x{0ec0}-\x{0ec4}\x{0ec6}\x{0edc}-\x{0edf}\x{0f00}\x{0f40}-\x{0f47}\x{0f49}-\x{0f6c}\x{0f88}-\x{0f8c}\x{1000}-\x{102a}\x{103f}\x{1050}-\x{1055}\x{105a}-\x{105d}\x{1061}\x{1065}\x{1066}\x{106e}-\x{1070}\x{1075}-\x{1081}\x{108e}\x{10a0}-\x{10c5}\x{10c7}\x{10cd}\x{10d0}-\x{10fa}\x{10fc}-\x{1248}\x{124a}-\x{124d}\x{1250}-\x{1256}\x{1258}\x{125a}-\x{125d}\x{1260}-\x{1288}\x{128a}-\x{128d}\x{1290}-\x{12b0}\x{12b2}-\x{12b5}\x{12b8}-\x{12be}\x{12c0}\x{12c2}-\x{12c5}\x{12c8}-\x{12d6}\x{12d8}-\x{1310}\x{1312}-\x{1315}\x{1318}-\x{135a}\x{1380}-\x{138f}\x{13a0}-\x{13f4}\x{1401}-\x{166c}\x{166f}-\x{167f}\x{1681}-\x{169a}\x{16a0}-\x{16ea}\x{16ee}-\x{16f0}\x{1700}-\x{170c}\x{170e}-\x{1711}\x{1720}-\x{1731}\x{1740}-\x{1751}\x{1760}-\x{176c}\x{176e}-\x{1770}\x{1780}-\x{17b3}\x{17d7}\x{17dc}\x{1820}-\x{1877}\x{1880}-\x{18a8}\x{18aa}\x{18b0}-\x{18f5}\x{1900}-\x{191c}\x{1950}-\x{196d}\x{1970}-\x{1974}\x{1980}-\x{19ab}\x{19c1}-\x{19c7}\x{1a00}-\x{1a16}\x{1a20}-\x{1a54}\x{1aa7}\x{1b05}-\x{1b33}\x{1b45}-\x{1b4b}\x{1b83}-\x{1ba0}\x{1bae}\x{1baf}\x{1bba}-\x{1be5}\x{1c00}-\x{1c23}\x{1c4d}-\x{1c4f}\x{1c5a}-\x{1c7d}\x{1ce9}-\x{1cec}\x{1cee}-\x{1cf1}\x{1cf5}\x{1cf6}\x{1d00}-\x{1dbf}\x{1e00}-\x{1f15}\x{1f18}-\x{1f1d}\x{1f20}-\x{1f45}\x{1f48}-\x{1f4d}\x{1f50}-\x{1f57}\x{1f59}\x{1f5b}\x{1f5d}\x{1f5f}-\x{1f7d}\x{1f80}-\x{1fb4}\x{1fb6}-\x{1fbc}\x{1fbe}\x{1fc2}-\x{1fc4}\x{1fc6}-\x{1fcc}\x{1fd0}-\x{1fd3}\x{1fd6}-\x{1fdb}\x{1fe0}-\x{1fec}\x{1ff2}-\x{1ff4}\x{1ff6}-\x{1ffc}\x{2071}\x{207f}\x{2090}-\x{209c}\x{2102}\x{2107}\x{210a}-\x{2113}\x{2115}\x{2119}-\x{211d}\x{2124}\x{2126}\x{2128}\x{212a}-\x{212d}\x{212f}-\x{2139}\x{213c}-\x{213f}\x{2145}-\x{2149}\x{214e}\x{2160}-\x{2188}\x{2c00}-\x{2c2e}\x{2c30}-\x{2c5e}\x{2c60}-\x{2ce4}\x{2ceb}-\x{2cee}\x{2cf2}\x{2cf3}\x{2d00}-\x{2d25}\x{2d27}\x{2d2d}\x{2d30}-\x{2d67}\x{2d6f}\x{2d80}-\x{2d96}\x{2da0}-\x{2da6}\x{2da8}-\x{2dae}\x{2db0}-\x{2db6}\x{2db8}-\x{2dbe}\x{2dc0}-\x{2dc6}\x{2dc8}-\x{2dce}\x{2dd0}-\x{2dd6}\x{2dd8}-\x{2dde}\x{2e2f}\x{3005}-\x{3007}\x{3021}-\x{3029}\x{3031}-\x{3035}\x{3038}-\x{303c}\x{3041}-\x{3096}\x{309d}-\x{309f}\x{30a1}-\x{30fa}\x{30fc}-\x{30ff}\x{3105}-\x{312d}\x{3131}-\x{318e}\x{31a0}-\x{31ba}\x{31f0}-\x{31ff}\x{3400}-\x{4db5}\x{4e00}-\x{9fcc}\x{a000}-\x{a48c}\x{a4d0}-\x{a4fd}\x{a500}-\x{a60c}\x{a610}-\x{a61f}\x{a62a}\x{a62b}\x{a640}-\x{a66e}\x{a67f}-\x{a697}\x{a6a0}-\x{a6ef}\x{a717}-\x{a71f}\x{a722}-\x{a788}\x{a78b}-\x{a78e}\x{a790}-\x{a793}\x{a7a0}-\x{a7aa}\x{a7f8}-\x{a801}\x{a803}-\x{a805}\x{a807}-\x{a80a}\x{a80c}-\x{a822}\x{a840}-\x{a873}\x{a882}-\x{a8b3}\x{a8f2}-\x{a8f7}\x{a8fb}\x{a90a}-\x{a925}\x{a930}-\x{a946}\x{a960}-\x{a97c}\x{a984}-\x{a9b2}\x{a9cf}\x{aa00}-\x{aa28}\x{aa40}-\x{aa42}\x{aa44}-\x{aa4b}\x{aa60}-\x{aa76}\x{aa7a}\x{aa80}-\x{aaaf}\x{aab1}\x{aab5}\x{aab6}\x{aab9}-\x{aabd}\x{aac0}\x{aac2}\x{aadb}-\x{aadd}\x{aae0}-\x{aaea}\x{aaf2}-\x{aaf4}\x{ab01}-\x{ab06}\x{ab09}-\x{ab0e}\x{ab11}-\x{ab16}\x{ab20}-\x{ab26}\x{ab28}-\x{ab2e}\x{abc0}-\x{abe2}\x{ac00}-\x{d7a3}\x{d7b0}-\x{d7c6}\x{d7cb}-\x{d7fb}\x{f900}-\x{fa6d}\x{fa70}-\x{fad9}\x{fb00}-\x{fb06}\x{fb13}-\x{fb17}\x{fb1d}\x{fb1f}-\x{fb28}\x{fb2a}-\x{fb36}\x{fb38}-\x{fb3c}\x{fb3e}\x{fb40}\x{fb41}\x{fb43}\x{fb44}\x{fb46}-\x{fbb1}\x{fbd3}-\x{fd3d}\x{fd50}-\x{fd8f}\x{fd92}-\x{fdc7}\x{fdf0}-\x{fdfb}\x{fe70}-\x{fe74}\x{fe76}-\x{fefc}\x{ff21}-\x{ff3a}\x{ff41}-\x{ff5a}\x{ff66}-\x{ffbe}\x{ffc2}-\x{ffc7}\x{ffca}-\x{ffcf}\x{ffd2}-\x{ffd7}\x{ffda}-\x{ffdc}][$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\x{02c1}\x{02c6}-\x{02d1}\x{02e0}-\x{02e4}\x{02ec}\x{02ee}\x{0370}-\x{0374}\x{0376}\x{0377}\x{037a}-\x{037d}\x{0386}\x{0388}-\x{038a}\x{038c}\x{038e}-\x{03a1}\x{03a3}-\x{03f5}\x{03f7}-\x{0481}\x{048a}-\x{0527}\x{0531}-\x{0556}\x{0559}\x{0561}-\x{0587}\x{05d0}-\x{05ea}\x{05f0}-\x{05f2}\x{0620}-\x{064a}\x{066e}\x{066f}\x{0671}-\x{06d3}\x{06d5}\x{06e5}\x{06e6}\x{06ee}\x{06ef}\x{06fa}-\x{06fc}\x{06ff}\x{0710}\x{0712}-\x{072f}\x{074d}-\x{07a5}\x{07b1}\x{07ca}-\x{07ea}\x{07f4}\x{07f5}\x{07fa}\x{0800}-\x{0815}\x{081a}\x{0824}\x{0828}\x{0840}-\x{0858}\x{08a0}\x{08a2}-\x{08ac}\x{0904}-\x{0939}\x{093d}\x{0950}\x{0958}-\x{0961}\x{0971}-\x{0977}\x{0979}-\x{097f}\x{0985}-\x{098c}\x{098f}\x{0990}\x{0993}-\x{09a8}\x{09aa}-\x{09b0}\x{09b2}\x{09b6}-\x{09b9}\x{09bd}\x{09ce}\x{09dc}\x{09dd}\x{09df}-\x{09e1}\x{09f0}\x{09f1}\x{0a05}-\x{0a0a}\x{0a0f}\x{0a10}\x{0a13}-\x{0a28}\x{0a2a}-\x{0a30}\x{0a32}\x{0a33}\x{0a35}\x{0a36}\x{0a38}\x{0a39}\x{0a59}-\x{0a5c}\x{0a5e}\x{0a72}-\x{0a74}\x{0a85}-\x{0a8d}\x{0a8f}-\x{0a91}\x{0a93}-\x{0aa8}\x{0aaa}-\x{0ab0}\x{0ab2}\x{0ab3}\x{0ab5}-\x{0ab9}\x{0abd}\x{0ad0}\x{0ae0}\x{0ae1}\x{0b05}-\x{0b0c}\x{0b0f}\x{0b10}\x{0b13}-\x{0b28}\x{0b2a}-\x{0b30}\x{0b32}\x{0b33}\x{0b35}-\x{0b39}\x{0b3d}\x{0b5c}\x{0b5d}\x{0b5f}-\x{0b61}\x{0b71}\x{0b83}\x{0b85}-\x{0b8a}\x{0b8e}-\x{0b90}\x{0b92}-\x{0b95}\x{0b99}\x{0b9a}\x{0b9c}\x{0b9e}\x{0b9f}\x{0ba3}\x{0ba4}\x{0ba8}-\x{0baa}\x{0bae}-\x{0bb9}\x{0bd0}\x{0c05}-\x{0c0c}\x{0c0e}-\x{0c10}\x{0c12}-\x{0c28}\x{0c2a}-\x{0c33}\x{0c35}-\x{0c39}\x{0c3d}\x{0c58}\x{0c59}\x{0c60}\x{0c61}\x{0c85}-\x{0c8c}\x{0c8e}-\x{0c90}\x{0c92}-\x{0ca8}\x{0caa}-\x{0cb3}\x{0cb5}-\x{0cb9}\x{0cbd}\x{0cde}\x{0ce0}\x{0ce1}\x{0cf1}\x{0cf2}\x{0d05}-\x{0d0c}\x{0d0e}-\x{0d10}\x{0d12}-\x{0d3a}\x{0d3d}\x{0d4e}\x{0d60}\x{0d61}\x{0d7a}-\x{0d7f}\x{0d85}-\x{0d96}\x{0d9a}-\x{0db1}\x{0db3}-\x{0dbb}\x{0dbd}\x{0dc0}-\x{0dc6}\x{0e01}-\x{0e30}\x{0e32}\x{0e33}\x{0e40}-\x{0e46}\x{0e81}\x{0e82}\x{0e84}\x{0e87}\x{0e88}\x{0e8a}\x{0e8d}\x{0e94}-\x{0e97}\x{0e99}-\x{0e9f}\x{0ea1}-\x{0ea3}\x{0ea5}\x{0ea7}\x{0eaa}\x{0eab}\x{0ead}-\x{0eb0}\x{0eb2}\x{0eb3}\x{0ebd}\x{0ec0}-\x{0ec4}\x{0ec6}\x{0edc}-\x{0edf}\x{0f00}\x{0f40}-\x{0f47}\x{0f49}-\x{0f6c}\x{0f88}-\x{0f8c}\x{1000}-\x{102a}\x{103f}\x{1050}-\x{1055}\x{105a}-\x{105d}\x{1061}\x{1065}\x{1066}\x{106e}-\x{1070}\x{1075}-\x{1081}\x{108e}\x{10a0}-\x{10c5}\x{10c7}\x{10cd}\x{10d0}-\x{10fa}\x{10fc}-\x{1248}\x{124a}-\x{124d}\x{1250}-\x{1256}\x{1258}\x{125a}-\x{125d}\x{1260}-\x{1288}\x{128a}-\x{128d}\x{1290}-\x{12b0}\x{12b2}-\x{12b5}\x{12b8}-\x{12be}\x{12c0}\x{12c2}-\x{12c5}\x{12c8}-\x{12d6}\x{12d8}-\x{1310}\x{1312}-\x{1315}\x{1318}-\x{135a}\x{1380}-\x{138f}\x{13a0}-\x{13f4}\x{1401}-\x{166c}\x{166f}-\x{167f}\x{1681}-\x{169a}\x{16a0}-\x{16ea}\x{16ee}-\x{16f0}\x{1700}-\x{170c}\x{170e}-\x{1711}\x{1720}-\x{1731}\x{1740}-\x{1751}\x{1760}-\x{176c}\x{176e}-\x{1770}\x{1780}-\x{17b3}\x{17d7}\x{17dc}\x{1820}-\x{1877}\x{1880}-\x{18a8}\x{18aa}\x{18b0}-\x{18f5}\x{1900}-\x{191c}\x{1950}-\x{196d}\x{1970}-\x{1974}\x{1980}-\x{19ab}\x{19c1}-\x{19c7}\x{1a00}-\x{1a16}\x{1a20}-\x{1a54}\x{1aa7}\x{1b05}-\x{1b33}\x{1b45}-\x{1b4b}\x{1b83}-\x{1ba0}\x{1bae}\x{1baf}\x{1bba}-\x{1be5}\x{1c00}-\x{1c23}\x{1c4d}-\x{1c4f}\x{1c5a}-\x{1c7d}\x{1ce9}-\x{1cec}\x{1cee}-\x{1cf1}\x{1cf5}\x{1cf6}\x{1d00}-\x{1dbf}\x{1e00}-\x{1f15}\x{1f18}-\x{1f1d}\x{1f20}-\x{1f45}\x{1f48}-\x{1f4d}\x{1f50}-\x{1f57}\x{1f59}\x{1f5b}\x{1f5d}\x{1f5f}-\x{1f7d}\x{1f80}-\x{1fb4}\x{1fb6}-\x{1fbc}\x{1fbe}\x{1fc2}-\x{1fc4}\x{1fc6}-\x{1fcc}\x{1fd0}-\x{1fd3}\x{1fd6}-\x{1fdb}\x{1fe0}-\x{1fec}\x{1ff2}-\x{1ff4}\x{1ff6}-\x{1ffc}\x{2071}\x{207f}\x{2090}-\x{209c}\x{2102}\x{2107}\x{210a}-\x{2113}\x{2115}\x{2119}-\x{211d}\x{2124}\x{2126}\x{2128}\x{212a}-\x{212d}\x{212f}-\x{2139}\x{213c}-\x{213f}\x{2145}-\x{2149}\x{214e}\x{2160}-\x{2188}\x{2c00}-\x{2c2e}\x{2c30}-\x{2c5e}\x{2c60}-\x{2ce4}\x{2ceb}-\x{2cee}\x{2cf2}\x{2cf3}\x{2d00}-\x{2d25}\x{2d27}\x{2d2d}\x{2d30}-\x{2d67}\x{2d6f}\x{2d80}-\x{2d96}\x{2da0}-\x{2da6}\x{2da8}-\x{2dae}\x{2db0}-\x{2db6}\x{2db8}-\x{2dbe}\x{2dc0}-\x{2dc6}\x{2dc8}-\x{2dce}\x{2dd0}-\x{2dd6}\x{2dd8}-\x{2dde}\x{2e2f}\x{3005}-\x{3007}\x{3021}-\x{3029}\x{3031}-\x{3035}\x{3038}-\x{303c}\x{3041}-\x{3096}\x{309d}-\x{309f}\x{30a1}-\x{30fa}\x{30fc}-\x{30ff}\x{3105}-\x{312d}\x{3131}-\x{318e}\x{31a0}-\x{31ba}\x{31f0}-\x{31ff}\x{3400}-\x{4db5}\x{4e00}-\x{9fcc}\x{a000}-\x{a48c}\x{a4d0}-\x{a4fd}\x{a500}-\x{a60c}\x{a610}-\x{a61f}\x{a62a}\x{a62b}\x{a640}-\x{a66e}\x{a67f}-\x{a697}\x{a6a0}-\x{a6ef}\x{a717}-\x{a71f}\x{a722}-\x{a788}\x{a78b}-\x{a78e}\x{a790}-\x{a793}\x{a7a0}-\x{a7aa}\x{a7f8}-\x{a801}\x{a803}-\x{a805}\x{a807}-\x{a80a}\x{a80c}-\x{a822}\x{a840}-\x{a873}\x{a882}-\x{a8b3}\x{a8f2}-\x{a8f7}\x{a8fb}\x{a90a}-\x{a925}\x{a930}-\x{a946}\x{a960}-\x{a97c}\x{a984}-\x{a9b2}\x{a9cf}\x{aa00}-\x{aa28}\x{aa40}-\x{aa42}\x{aa44}-\x{aa4b}\x{aa60}-\x{aa76}\x{aa7a}\x{aa80}-\x{aaaf}\x{aab1}\x{aab5}\x{aab6}\x{aab9}-\x{aabd}\x{aac0}\x{aac2}\x{aadb}-\x{aadd}\x{aae0}-\x{aaea}\x{aaf2}-\x{aaf4}\x{ab01}-\x{ab06}\x{ab09}-\x{ab0e}\x{ab11}-\x{ab16}\x{ab20}-\x{ab26}\x{ab28}-\x{ab2e}\x{abc0}-\x{abe2}\x{ac00}-\x{d7a3}\x{d7b0}-\x{d7c6}\x{d7cb}-\x{d7fb}\x{f900}-\x{fa6d}\x{fa70}-\x{fad9}\x{fb00}-\x{fb06}\x{fb13}-\x{fb17}\x{fb1d}\x{fb1f}-\x{fb28}\x{fb2a}-\x{fb36}\x{fb38}-\x{fb3c}\x{fb3e}\x{fb40}\x{fb41}\x{fb43}\x{fb44}\x{fb46}-\x{fbb1}\x{fbd3}-\x{fd3d}\x{fd50}-\x{fd8f}\x{fd92}-\x{fdc7}\x{fdf0}-\x{fdfb}\x{fe70}-\x{fe74}\x{fe76}-\x{fefc}\x{ff21}-\x{ff3a}\x{ff41}-\x{ff5a}\x{ff66}-\x{ffbe}\x{ffc2}-\x{ffc7}\x{ffca}-\x{ffcf}\x{ffd2}-\x{ffd7}\x{ffda}-\x{ffdc}0-9\x{0300}-\x{036f}\x{0483}-\x{0487}\x{0591}-\x{05bd}\x{05bf}\x{05c1}\x{05c2}\x{05c4}\x{05c5}\x{05c7}\x{0610}-\x{061a}\x{064b}-\x{0669}\x{0670}\x{06d6}-\x{06dc}\x{06df}-\x{06e4}\x{06e7}\x{06e8}\x{06ea}-\x{06ed}\x{06f0}-\x{06f9}\x{0711}\x{0730}-\x{074a}\x{07a6}-\x{07b0}\x{07c0}-\x{07c9}\x{07eb}-\x{07f3}\x{0816}-\x{0819}\x{081b}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082d}\x{0859}-\x{085b}\x{08e4}-\x{08fe}\x{0900}-\x{0903}\x{093a}-\x{093c}\x{093e}-\x{094f}\x{0951}-\x{0957}\x{0962}\x{0963}\x{0966}-\x{096f}\x{0981}-\x{0983}\x{09bc}\x{09be}-\x{09c4}\x{09c7}\x{09c8}\x{09cb}-\x{09cd}\x{09d7}\x{09e2}\x{09e3}\x{09e6}-\x{09ef}\x{0a01}-\x{0a03}\x{0a3c}\x{0a3e}-\x{0a42}\x{0a47}\x{0a48}\x{0a4b}-\x{0a4d}\x{0a51}\x{0a66}-\x{0a71}\x{0a75}\x{0a81}-\x{0a83}\x{0abc}\x{0abe}-\x{0ac5}\x{0ac7}-\x{0ac9}\x{0acb}-\x{0acd}\x{0ae2}\x{0ae3}\x{0ae6}-\x{0aef}\x{0b01}-\x{0b03}\x{0b3c}\x{0b3e}-\x{0b44}\x{0b47}\x{0b48}\x{0b4b}-\x{0b4d}\x{0b56}\x{0b57}\x{0b62}\x{0b63}\x{0b66}-\x{0b6f}\x{0b82}\x{0bbe}-\x{0bc2}\x{0bc6}-\x{0bc8}\x{0bca}-\x{0bcd}\x{0bd7}\x{0be6}-\x{0bef}\x{0c01}-\x{0c03}\x{0c3e}-\x{0c44}\x{0c46}-\x{0c48}\x{0c4a}-\x{0c4d}\x{0c55}\x{0c56}\x{0c62}\x{0c63}\x{0c66}-\x{0c6f}\x{0c82}\x{0c83}\x{0cbc}\x{0cbe}-\x{0cc4}\x{0cc6}-\x{0cc8}\x{0cca}-\x{0ccd}\x{0cd5}\x{0cd6}\x{0ce2}\x{0ce3}\x{0ce6}-\x{0cef}\x{0d02}\x{0d03}\x{0d3e}-\x{0d44}\x{0d46}-\x{0d48}\x{0d4a}-\x{0d4d}\x{0d57}\x{0d62}\x{0d63}\x{0d66}-\x{0d6f}\x{0d82}\x{0d83}\x{0dca}\x{0dcf}-\x{0dd4}\x{0dd6}\x{0dd8}-\x{0ddf}\x{0df2}\x{0df3}\x{0e31}\x{0e34}-\x{0e3a}\x{0e47}-\x{0e4e}\x{0e50}-\x{0e59}\x{0eb1}\x{0eb4}-\x{0eb9}\x{0ebb}\x{0ebc}\x{0ec8}-\x{0ecd}\x{0ed0}-\x{0ed9}\x{0f18}\x{0f19}\x{0f20}-\x{0f29}\x{0f35}\x{0f37}\x{0f39}\x{0f3e}\x{0f3f}\x{0f71}-\x{0f84}\x{0f86}\x{0f87}\x{0f8d}-\x{0f97}\x{0f99}-\x{0fbc}\x{0fc6}\x{102b}-\x{103e}\x{1040}-\x{1049}\x{1056}-\x{1059}\x{105e}-\x{1060}\x{1062}-\x{1064}\x{1067}-\x{106d}\x{1071}-\x{1074}\x{1082}-\x{108d}\x{108f}-\x{109d}\x{135d}-\x{135f}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}\x{1753}\x{1772}\x{1773}\x{17b4}-\x{17d3}\x{17dd}\x{17e0}-\x{17e9}\x{180b}-\x{180d}\x{1810}-\x{1819}\x{18a9}\x{1920}-\x{192b}\x{1930}-\x{193b}\x{1946}-\x{194f}\x{19b0}-\x{19c0}\x{19c8}\x{19c9}\x{19d0}-\x{19d9}\x{1a17}-\x{1a1b}\x{1a55}-\x{1a5e}\x{1a60}-\x{1a7c}\x{1a7f}-\x{1a89}\x{1a90}-\x{1a99}\x{1b00}-\x{1b04}\x{1b34}-\x{1b44}\x{1b50}-\x{1b59}\x{1b6b}-\x{1b73}\x{1b80}-\x{1b82}\x{1ba1}-\x{1bad}\x{1bb0}-\x{1bb9}\x{1be6}-\x{1bf3}\x{1c24}-\x{1c37}\x{1c40}-\x{1c49}\x{1c50}-\x{1c59}\x{1cd0}-\x{1cd2}\x{1cd4}-\x{1ce8}\x{1ced}\x{1cf2}-\x{1cf4}\x{1dc0}-\x{1de6}\x{1dfc}-\x{1dff}\x{200c}\x{200d}\x{203f}\x{2040}\x{2054}\x{20d0}-\x{20dc}\x{20e1}\x{20e5}-\x{20f0}\x{2cef}-\x{2cf1}\x{2d7f}\x{2de0}-\x{2dff}\x{302a}-\x{302f}\x{3099}\x{309a}\x{a620}-\x{a629}\x{a66f}\x{a674}-\x{a67d}\x{a69f}\x{a6f0}\x{a6f1}\x{a802}\x{a806}\x{a80b}\x{a823}-\x{a827}\x{a880}\x{a881}\x{a8b4}-\x{a8c4}\x{a8d0}-\x{a8d9}\x{a8e0}-\x{a8f1}\x{a900}-\x{a909}\x{a926}-\x{a92d}\x{a947}-\x{a953}\x{a980}-\x{a983}\x{a9b3}-\x{a9c0}\x{a9d0}-\x{a9d9}\x{aa29}-\x{aa36}\x{aa43}\x{aa4c}\x{aa4d}\x{aa50}-\x{aa59}\x{aa7b}\x{aab0}\x{aab2}-\x{aab4}\x{aab7}\x{aab8}\x{aabe}\x{aabf}\x{aac1}\x{aaeb}-\x{aaef}\x{aaf5}\x{aaf6}\x{abe3}-\x{abea}\x{abec}\x{abed}\x{abf0}-\x{abf9}\x{fb1e}\x{fe00}-\x{fe0f}\x{fe20}-\x{fe26}\x{fe33}\x{fe34}\x{fe4d}-\x{fe4f}\x{ff10}-\x{ff19}\x{ff3f}]*\b';
26
+
27
+	/**
28
+	 * Full list of JavaScript reserved words.
29
+	 * Will be loaded from /data/js/keywords_reserved.txt.
30
+	 *
31
+	 * @see https://mathiasbynens.be/notes/reserved-keywords
32
+	 *
33
+	 * @var string[]
34
+	 */
35
+	protected $keywordsReserved = array();
36
+
37
+	/**
38
+	 * List of JavaScript reserved words that accept a <variable, value, ...>
39
+	 * after them. Some end of lines are not the end of a statement, like with
40
+	 * these keywords.
41
+	 *
42
+	 * E.g.: we shouldn't insert a ; after this else
43
+	 * else
44
+	 *     console.log('this is quite fine')
45
+	 *
46
+	 * Will be loaded from /data/js/keywords_before.txt
47
+	 *
48
+	 * @var string[]
49
+	 */
50
+	protected $keywordsBefore = array();
51
+
52
+	/**
53
+	 * List of JavaScript reserved words that accept a <variable, value, ...>
54
+	 * before them. Some end of lines are not the end of a statement, like when
55
+	 * continued by one of these keywords on the newline.
56
+	 *
57
+	 * E.g.: we shouldn't insert a ; before this instanceof
58
+	 * variable
59
+	 *     instanceof String
60
+	 *
61
+	 * Will be loaded from /data/js/keywords_after.txt
62
+	 *
63
+	 * @var string[]
64
+	 */
65
+	protected $keywordsAfter = array();
66
+
67
+	/**
68
+	 * List of JavaScript operators that accept a <variable, value, ...> after
69
+	 * them. Some end of lines are not the end of a statement, like with these
70
+	 * operators.
71
+	 *
72
+	 * Note: Most operators are fine, we've only removed !, ++ and --.
73
+	 * There can't be a newline separating ! and whatever it is negating.
74
+	 * ++ & -- have to be joined with the value they're in-/decrementing.
75
+	 *
76
+	 * Will be loaded from /data/js/operators_before.txt
77
+	 *
78
+	 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
79
+	 *
80
+	 * @var string[]
81
+	 */
82
+	protected $operatorsBefore = array();
83
+
84
+	/**
85
+	 * List of JavaScript operators that accept a <variable, value, ...> before
86
+	 * them. Some end of lines are not the end of a statement, like when
87
+	 * continued by one of these operators on the newline.
88
+	 *
89
+	 * Note: Most operators are fine, we've only removed ), ], ++ and --.
90
+	 * ++ & -- have to be joined with the value they're in-/decrementing.
91
+	 * ) & ] are "special" in that they have lots or usecases. () for example
92
+	 * is used for function calls, for grouping, in if () and for (), ...
93
+	 *
94
+	 * Will be loaded from /data/js/operators_after.txt
95
+	 *
96
+	 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
97
+	 *
98
+	 * @var string[]
99
+	 */
100
+	protected $operatorsAfter = array();
101
+
102
+	/**
103
+	 * {@inheritdoc}
104
+	 */
105
+	public function __construct()
106
+	{
107
+		call_user_func_array(array('parent', '__construct'), func_get_args());
108
+
109
+		$dataDir = __DIR__.'/../data/js/';
110
+		$options = FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES;
111
+		$this->keywordsReserved = file($dataDir.'keywords_reserved.txt', $options);
112
+		$this->keywordsBefore = file($dataDir.'keywords_before.txt', $options);
113
+		$this->keywordsAfter = file($dataDir.'keywords_after.txt', $options);
114
+		$this->operatorsBefore = file($dataDir.'operators_before.txt', $options);
115
+		$this->operatorsAfter = file($dataDir.'operators_after.txt', $options);
116
+	}
117
+
118
+	/**
119
+	 * Minify the data.
120
+	 * Perform JS optimizations.
121
+	 *
122
+	 * @param string[optional] $path Path to write the data to.
123
+	 *
124
+	 * @return string The minified data.
125
+	 */
126
+	public function execute($path = null)
127
+	{
128
+		$content = '';
129
+
130
+		// loop files
131
+		foreach ($this->data as $source => $js) {
132
+			/*
133 133
              * Combine js: separating the scripts by a ;
134 134
              * I'm also adding a newline: it will be eaten when whitespace is
135 135
              * stripped, but we need to make sure we're not just appending
@@ -137,10 +137,10 @@  discard block
 block discarded – undo
137 137
              * singe-line comment on the last line (in which case it would also
138 138
              * be seen as part of that comment)
139 139
              */
140
-            $content .= $js."\n;";
141
-        }
140
+			$content .= $js."\n;";
141
+		}
142 142
 
143
-        /*
143
+		/*
144 144
          * Let's first take out strings, comments and regular expressions.
145 145
          * All of these can contain JS code-like characters, and we should make
146 146
          * sure any further magic ignores anything inside of these.
@@ -151,159 +151,159 @@  discard block
 block discarded – undo
151 151
          * Comments will be removed altogether, strings and regular expressions
152 152
          * will be replaced by placeholder text, which we'll restore later.
153 153
          */
154
-        $this->extractStrings('\'"`');
155
-        $this->stripComments();
156
-        $this->extractRegex();
157
-        $content = $this->replace($content);
154
+		$this->extractStrings('\'"`');
155
+		$this->stripComments();
156
+		$this->extractRegex();
157
+		$content = $this->replace($content);
158 158
 
159
-        $content = $this->stripWhitespace($content);
160
-        $content = $this->propertyNotation($content);
161
-        $content = $this->shortenBools($content);
159
+		$content = $this->stripWhitespace($content);
160
+		$content = $this->propertyNotation($content);
161
+		$content = $this->shortenBools($content);
162 162
 
163
-        /*
163
+		/*
164 164
          * Earlier, we extracted strings & regular expressions and replaced them
165 165
          * with placeholder text. This will restore them.
166 166
          */
167
-        $content = $this->restoreExtractedData($content);
168
-
169
-        return $content;
170
-    }
171
-
172
-    /**
173
-     * Strip comments from source code.
174
-     */
175
-    protected function stripComments()
176
-    {
177
-        // single-line comments
178
-        $this->registerPattern('/\/\/.*$/m', '');
179
-
180
-        // multi-line comments
181
-        $this->registerPattern('/\/\*.*?\*\//s', '');
182
-    }
183
-
184
-    /**
185
-     * JS can have /-delimited regular expressions, like: /ab+c/.match(string).
186
-     *
187
-     * The content inside the regex can contain characters that may be confused
188
-     * for JS code: e.g. it could contain whitespace it needs to match & we
189
-     * don't want to strip whitespace in there.
190
-     *
191
-     * The regex can be pretty simple: we don't have to care about comments,
192
-     * (which also use slashes) because stripComments() will have stripped those
193
-     * already.
194
-     *
195
-     * This method will replace all string content with simple REGEX#
196
-     * placeholder text, so we've rid all regular expressions from characters
197
-     * that may be misinterpreted. Original regex content will be saved in
198
-     * $this->extracted and after doing all other minifying, we can restore the
199
-     * original content via restoreRegex()
200
-     */
201
-    protected function extractRegex()
202
-    {
203
-        // PHP only supports $this inside anonymous functions since 5.4
204
-        $minifier = $this;
205
-        $callback = function ($match) use ($minifier) {
206
-            $count = count($minifier->extracted);
207
-            $placeholder = '/'.$count.'/';
208
-            $minifier->extracted[$placeholder] = $match[1];
209
-
210
-            return $placeholder;
211
-        };
212
-
213
-        // it's a regex if we can find an opening and (not escaped) closing /,
214
-        // include \n because it may be there for a reason
215
-        // (https://github.com/matthiasmullie/minify/issues/56)
216
-        $pattern = '(\/.*?(?<!\\\\)(\\\\\\\\)*+\/\n?)';
217
-
218
-        // / can't be preceded by variable, value, or similar because then
219
-        // it's going to be division
220
-        // checking for that is complex, so we'll do inverse:
221
-        // * at the beginning of the file, it's not division, but regex
222
-        $this->registerPattern('/^\s*\K'.$pattern.'/', $callback);
223
-        // * following another operator, it's not division, but regex
224
-        $operators = $this->getOperatorsForRegex($this->operatorsBefore, '/');
225
-        $operators += $this->getKeywordsForRegex($this->keywordsReserved, '/');
226
-        $this->registerPattern('/(?:'.implode('|', $operators).')\s*\K'.$pattern.'/', $callback);
227
-    }
228
-
229
-    /**
230
-     * Strip whitespace.
231
-     *
232
-     * We won't strip *all* whitespace, but as much as possible. The thing that
233
-     * we'll preserve are newlines we're unsure about.
234
-     * JavaScript doesn't require statements to be terminated with a semicolon.
235
-     * It will automatically fix missing semicolons with ASI (automatic semi-
236
-     * colon insertion) at the end of line causing errors (without semicolon.)
237
-     *
238
-     * Because it's sometimes hard to tell if a newline is part of a statement
239
-     * that should be terminated or not, we'll just leave some of them alone.
240
-     *
241
-     * @param string $content The content to strip the whitespace for.
242
-     *
243
-     * @return string
244
-     */
245
-    protected function stripWhitespace($content)
246
-    {
247
-        // uniform line endings, make them all line feed
248
-        $content = str_replace(array("\r\n", "\r"), "\n", $content);
249
-
250
-        // collapse all non-line feed whitespace into a single space
251
-        $content = preg_replace('/[^\S\n]+/', ' ', $content);
252
-
253
-        // strip leading & trailing whitespace
254
-        $content = str_replace(array(" \n", "\n "), "\n", $content);
255
-
256
-        // collapse consecutive line feeds into just 1
257
-        $content = preg_replace('/\n+/', "\n", $content);
258
-
259
-        $before = $this->getOperatorsForRegex($this->operatorsBefore, '/');
260
-        $after = $this->getOperatorsForRegex($this->operatorsAfter, '/');
261
-        $operators = $before + $after;
262
-
263
-        // strip whitespace that ends in (or next line begin with) an operator
264
-        // that allows statements to be broken up over multiple lines
265
-        unset($before['+'], $before['-'], $after['+'], $after['-']);
266
-        $content = preg_replace(
267
-            array(
268
-                '/('.implode('|', $before).')\s+/',
269
-                '/\s+('.implode('|', $after).')/',
270
-            ), '\\1', $content
271
-        );
272
-
273
-        // make sure + and - can't be mistaken for, or joined into ++ and --
274
-        $content = preg_replace(
275
-            array(
276
-                '/(?<![\+\-])\s*([\+\-])(?![\+\-])/',
277
-                '/(?<![\+\-])([\+\-])\s*(?![\+\-])/',
278
-            ), '\\1', $content
279
-        );
280
-
281
-        /*
167
+		$content = $this->restoreExtractedData($content);
168
+
169
+		return $content;
170
+	}
171
+
172
+	/**
173
+	 * Strip comments from source code.
174
+	 */
175
+	protected function stripComments()
176
+	{
177
+		// single-line comments
178
+		$this->registerPattern('/\/\/.*$/m', '');
179
+
180
+		// multi-line comments
181
+		$this->registerPattern('/\/\*.*?\*\//s', '');
182
+	}
183
+
184
+	/**
185
+	 * JS can have /-delimited regular expressions, like: /ab+c/.match(string).
186
+	 *
187
+	 * The content inside the regex can contain characters that may be confused
188
+	 * for JS code: e.g. it could contain whitespace it needs to match & we
189
+	 * don't want to strip whitespace in there.
190
+	 *
191
+	 * The regex can be pretty simple: we don't have to care about comments,
192
+	 * (which also use slashes) because stripComments() will have stripped those
193
+	 * already.
194
+	 *
195
+	 * This method will replace all string content with simple REGEX#
196
+	 * placeholder text, so we've rid all regular expressions from characters
197
+	 * that may be misinterpreted. Original regex content will be saved in
198
+	 * $this->extracted and after doing all other minifying, we can restore the
199
+	 * original content via restoreRegex()
200
+	 */
201
+	protected function extractRegex()
202
+	{
203
+		// PHP only supports $this inside anonymous functions since 5.4
204
+		$minifier = $this;
205
+		$callback = function ($match) use ($minifier) {
206
+			$count = count($minifier->extracted);
207
+			$placeholder = '/'.$count.'/';
208
+			$minifier->extracted[$placeholder] = $match[1];
209
+
210
+			return $placeholder;
211
+		};
212
+
213
+		// it's a regex if we can find an opening and (not escaped) closing /,
214
+		// include \n because it may be there for a reason
215
+		// (https://github.com/matthiasmullie/minify/issues/56)
216
+		$pattern = '(\/.*?(?<!\\\\)(\\\\\\\\)*+\/\n?)';
217
+
218
+		// / can't be preceded by variable, value, or similar because then
219
+		// it's going to be division
220
+		// checking for that is complex, so we'll do inverse:
221
+		// * at the beginning of the file, it's not division, but regex
222
+		$this->registerPattern('/^\s*\K'.$pattern.'/', $callback);
223
+		// * following another operator, it's not division, but regex
224
+		$operators = $this->getOperatorsForRegex($this->operatorsBefore, '/');
225
+		$operators += $this->getKeywordsForRegex($this->keywordsReserved, '/');
226
+		$this->registerPattern('/(?:'.implode('|', $operators).')\s*\K'.$pattern.'/', $callback);
227
+	}
228
+
229
+	/**
230
+	 * Strip whitespace.
231
+	 *
232
+	 * We won't strip *all* whitespace, but as much as possible. The thing that
233
+	 * we'll preserve are newlines we're unsure about.
234
+	 * JavaScript doesn't require statements to be terminated with a semicolon.
235
+	 * It will automatically fix missing semicolons with ASI (automatic semi-
236
+	 * colon insertion) at the end of line causing errors (without semicolon.)
237
+	 *
238
+	 * Because it's sometimes hard to tell if a newline is part of a statement
239
+	 * that should be terminated or not, we'll just leave some of them alone.
240
+	 *
241
+	 * @param string $content The content to strip the whitespace for.
242
+	 *
243
+	 * @return string
244
+	 */
245
+	protected function stripWhitespace($content)
246
+	{
247
+		// uniform line endings, make them all line feed
248
+		$content = str_replace(array("\r\n", "\r"), "\n", $content);
249
+
250
+		// collapse all non-line feed whitespace into a single space
251
+		$content = preg_replace('/[^\S\n]+/', ' ', $content);
252
+
253
+		// strip leading & trailing whitespace
254
+		$content = str_replace(array(" \n", "\n "), "\n", $content);
255
+
256
+		// collapse consecutive line feeds into just 1
257
+		$content = preg_replace('/\n+/', "\n", $content);
258
+
259
+		$before = $this->getOperatorsForRegex($this->operatorsBefore, '/');
260
+		$after = $this->getOperatorsForRegex($this->operatorsAfter, '/');
261
+		$operators = $before + $after;
262
+
263
+		// strip whitespace that ends in (or next line begin with) an operator
264
+		// that allows statements to be broken up over multiple lines
265
+		unset($before['+'], $before['-'], $after['+'], $after['-']);
266
+		$content = preg_replace(
267
+			array(
268
+				'/('.implode('|', $before).')\s+/',
269
+				'/\s+('.implode('|', $after).')/',
270
+			), '\\1', $content
271
+		);
272
+
273
+		// make sure + and - can't be mistaken for, or joined into ++ and --
274
+		$content = preg_replace(
275
+			array(
276
+				'/(?<![\+\-])\s*([\+\-])(?![\+\-])/',
277
+				'/(?<![\+\-])([\+\-])\s*(?![\+\-])/',
278
+			), '\\1', $content
279
+		);
280
+
281
+		/*
282 282
          * We didn't strip whitespace after a couple of operators because they
283 283
          * could be used in different contexts and we can't be sure it's ok to
284 284
          * strip the newlines. However, we can safely strip any non-line feed
285 285
          * whitespace that follows them.
286 286
          */
287
-        $content = preg_replace('/([\}\)\]])[^\S\n]+(?!'.implode('|', $operators).')/', '\\1', $content);
287
+		$content = preg_replace('/([\}\)\]])[^\S\n]+(?!'.implode('|', $operators).')/', '\\1', $content);
288 288
 
289
-        // collapse whitespace around reserved words into single space
290
-        $before = $this->getKeywordsForRegex($this->keywordsBefore, '/');
291
-        $after = $this->getKeywordsForRegex($this->keywordsAfter, '/');
292
-        $content = preg_replace('/(^|[;\}\s])\K('.implode('|', $before).')\s+/', '\\2 ', $content);
293
-        $content = preg_replace('/\s+('.implode('|', $after).')(?=([;\{\s]|$))/', ' \\1', $content);
289
+		// collapse whitespace around reserved words into single space
290
+		$before = $this->getKeywordsForRegex($this->keywordsBefore, '/');
291
+		$after = $this->getKeywordsForRegex($this->keywordsAfter, '/');
292
+		$content = preg_replace('/(^|[;\}\s])\K('.implode('|', $before).')\s+/', '\\2 ', $content);
293
+		$content = preg_replace('/\s+('.implode('|', $after).')(?=([;\{\s]|$))/', ' \\1', $content);
294 294
 
295
-        /*
295
+		/*
296 296
          * Get rid of double semicolons, except where they can be used like:
297 297
          * "for(v=1,_=b;;)", "for(v=1;;v++)" or "for(;;ja||(ja=true))".
298 298
          * I'll safeguard these double semicolons inside for-loops by
299 299
          * temporarily replacing them with an invalid condition: they won't have
300 300
          * a double semicolon and will be easy to spot to restore afterwards.
301 301
          */
302
-        $content = preg_replace('/\bfor\(([^;]*);;([^;]*)\)/', 'for(\\1;-;\\2)', $content);
303
-        $content = preg_replace('/;+/', ';', $content);
304
-        $content = preg_replace('/\bfor\(([^;]*);-;([^;]*)\)/', 'for(\\1;;\\2)', $content);
302
+		$content = preg_replace('/\bfor\(([^;]*);;([^;]*)\)/', 'for(\\1;-;\\2)', $content);
303
+		$content = preg_replace('/;+/', ';', $content);
304
+		$content = preg_replace('/\bfor\(([^;]*);-;([^;]*)\)/', 'for(\\1;;\\2)', $content);
305 305
 
306
-        /*
306
+		/*
307 307
          * Next, we'll be removing all semicolons where ASI kicks in.
308 308
          * for-loops however, can have an empty body (ending in only a
309 309
          * semicolon), like: `for(i=1;i<3;i++);`
@@ -313,9 +313,9 @@  discard block
 block discarded – undo
313 313
          * I'm going to double that semicolon (if any) so after the next line,
314 314
          * which strips semicolons here & there, we're still left with this one.
315 315
          */
316
-        $content = preg_replace('/(for\([^;]*;[^;]*;[^;\{]*\));(\}|$)/s', '\\1;;\\2', $content);
316
+		$content = preg_replace('/(for\([^;]*;[^;]*;[^;\{]*\));(\}|$)/s', '\\1;;\\2', $content);
317 317
 
318
-        /*
318
+		/*
319 319
          * We also can't strip empty else-statements. Even though they're
320 320
          * useless and probably shouldn't be in the code in the first place, we
321 321
          * shouldn't be stripping the `;` that follows it as it breaks the code.
@@ -323,114 +323,114 @@  discard block
 block discarded – undo
323 323
          *
324 324
          * @see https://github.com/matthiasmullie/minify/issues/91
325 325
          */
326
-        $content = preg_replace('/else;/s', '', $content);
326
+		$content = preg_replace('/else;/s', '', $content);
327 327
 
328
-        /*
328
+		/*
329 329
          * We also don't really want to terminate statements followed by closing
330 330
          * curly braces (which we've ignored completely up until now) or end-of-
331 331
          * script: ASI will kick in here & we're all about minifying.
332 332
          * Semicolons at beginning of the file don't make any sense either.
333 333
          */
334
-        $content = preg_replace('/;(\}|$)/s', '\\1', $content);
335
-        $content = ltrim($content, ';');
336
-
337
-        // get rid of remaining whitespace af beginning/end
338
-        return trim($content);
339
-    }
340
-
341
-    /**
342
-     * We'll strip whitespace around certain operators with regular expressions.
343
-     * This will prepare the given array by escaping all characters.
344
-     *
345
-     * @param string[] $operators
346
-     * @param string   $delimiter
347
-     *
348
-     * @return string[]
349
-     */
350
-    protected function getOperatorsForRegex(array $operators, $delimiter = '/')
351
-    {
352
-        // escape operators for use in regex
353
-        $delimiter = array_fill(0, count($operators), $delimiter);
354
-        $escaped = array_map('preg_quote', $operators, $delimiter);
355
-
356
-        $operators = array_combine($operators, $escaped);
357
-
358
-        // ignore + & - for now, they'll get special treatment
359
-        unset($operators['+'], $operators['-']);
360
-
361
-        // dot can not just immediately follow a number; it can be confused for
362
-        // decimal point, or calling a method on it, e.g. 42 .toString()
363
-        $operators['.'] = '(?<![0-9]\s)\.';
364
-
365
-        // don't confuse = with other assignment shortcuts (e.g. +=)
366
-        $chars = preg_quote('+-*\=<>%&|');
367
-        $operators['='] = '(?<!['.$chars.'])\=';
368
-
369
-        return $operators;
370
-    }
371
-
372
-    /**
373
-     * We'll strip whitespace around certain keywords with regular expressions.
374
-     * This will prepare the given array by escaping all characters.
375
-     *
376
-     * @param string[] $keywords
377
-     * @param string   $delimiter
378
-     *
379
-     * @return string[]
380
-     */
381
-    protected function getKeywordsForRegex(array $keywords, $delimiter = '/')
382
-    {
383
-        // escape keywords for use in regex
384
-        $delimiter = array_fill(0, count($keywords), $delimiter);
385
-        $escaped = array_map('preg_quote', $keywords, $delimiter);
386
-
387
-        // add word boundaries
388
-        array_walk($keywords, function ($value) {
389
-            return '\b'.$value.'\b';
390
-        });
391
-
392
-        $keywords = array_combine($keywords, $escaped);
393
-
394
-        return $keywords;
395
-    }
396
-
397
-    /**
398
-     * Replaces all occurrences of array['key'] by array.key.
399
-     *
400
-     * @param string $content
401
-     *
402
-     * @return string
403
-     */
404
-    protected function propertyNotation($content)
405
-    {
406
-        // PHP only supports $this inside anonymous functions since 5.4
407
-        $minifier = $this;
408
-        $keywords = $this->keywordsReserved;
409
-        $callback = function ($match) use ($minifier, $keywords) {
410
-            $property = trim($minifier->extracted[$match[1]], '\'"');
411
-
412
-            /*
334
+		$content = preg_replace('/;(\}|$)/s', '\\1', $content);
335
+		$content = ltrim($content, ';');
336
+
337
+		// get rid of remaining whitespace af beginning/end
338
+		return trim($content);
339
+	}
340
+
341
+	/**
342
+	 * We'll strip whitespace around certain operators with regular expressions.
343
+	 * This will prepare the given array by escaping all characters.
344
+	 *
345
+	 * @param string[] $operators
346
+	 * @param string   $delimiter
347
+	 *
348
+	 * @return string[]
349
+	 */
350
+	protected function getOperatorsForRegex(array $operators, $delimiter = '/')
351
+	{
352
+		// escape operators for use in regex
353
+		$delimiter = array_fill(0, count($operators), $delimiter);
354
+		$escaped = array_map('preg_quote', $operators, $delimiter);
355
+
356
+		$operators = array_combine($operators, $escaped);
357
+
358
+		// ignore + & - for now, they'll get special treatment
359
+		unset($operators['+'], $operators['-']);
360
+
361
+		// dot can not just immediately follow a number; it can be confused for
362
+		// decimal point, or calling a method on it, e.g. 42 .toString()
363
+		$operators['.'] = '(?<![0-9]\s)\.';
364
+
365
+		// don't confuse = with other assignment shortcuts (e.g. +=)
366
+		$chars = preg_quote('+-*\=<>%&|');
367
+		$operators['='] = '(?<!['.$chars.'])\=';
368
+
369
+		return $operators;
370
+	}
371
+
372
+	/**
373
+	 * We'll strip whitespace around certain keywords with regular expressions.
374
+	 * This will prepare the given array by escaping all characters.
375
+	 *
376
+	 * @param string[] $keywords
377
+	 * @param string   $delimiter
378
+	 *
379
+	 * @return string[]
380
+	 */
381
+	protected function getKeywordsForRegex(array $keywords, $delimiter = '/')
382
+	{
383
+		// escape keywords for use in regex
384
+		$delimiter = array_fill(0, count($keywords), $delimiter);
385
+		$escaped = array_map('preg_quote', $keywords, $delimiter);
386
+
387
+		// add word boundaries
388
+		array_walk($keywords, function ($value) {
389
+			return '\b'.$value.'\b';
390
+		});
391
+
392
+		$keywords = array_combine($keywords, $escaped);
393
+
394
+		return $keywords;
395
+	}
396
+
397
+	/**
398
+	 * Replaces all occurrences of array['key'] by array.key.
399
+	 *
400
+	 * @param string $content
401
+	 *
402
+	 * @return string
403
+	 */
404
+	protected function propertyNotation($content)
405
+	{
406
+		// PHP only supports $this inside anonymous functions since 5.4
407
+		$minifier = $this;
408
+		$keywords = $this->keywordsReserved;
409
+		$callback = function ($match) use ($minifier, $keywords) {
410
+			$property = trim($minifier->extracted[$match[1]], '\'"');
411
+
412
+			/*
413 413
              * Check if the property is a reserved keyword. In this context (as
414 414
              * property of an object literal/array) it shouldn't matter, but IE8
415 415
              * freaks out with "Expected identifier".
416 416
              */
417
-            if (in_array($property, $keywords)) {
418
-                return $match[0];
419
-            }
417
+			if (in_array($property, $keywords)) {
418
+				return $match[0];
419
+			}
420 420
 
421
-            /*
421
+			/*
422 422
              * See if the property is in a variable-like format (e.g.
423 423
              * array['key-here'] can't be replaced by array.key-here since '-'
424 424
              * is not a valid character there.
425 425
              */
426
-            if (!preg_match('/^'.$minifier::REGEX_VARIABLE.'$/u', $property)) {
427
-                return $match[0];
428
-            }
426
+			if (!preg_match('/^'.$minifier::REGEX_VARIABLE.'$/u', $property)) {
427
+				return $match[0];
428
+			}
429 429
 
430
-            return '.'.$property;
431
-        };
430
+			return '.'.$property;
431
+		};
432 432
 
433
-        /*
433
+		/*
434 434
          * Figure out if previous character is a variable name (of the array
435 435
          * we want to use property notation on) - this is to make sure
436 436
          * standalone ['value'] arrays aren't confused for keys-of-an-array.
@@ -438,61 +438,61 @@  discard block
 block discarded – undo
438 438
          * regex implementation doesn't allow unfixed-length look-behind
439 439
          * assertions.
440 440
          */
441
-        preg_match('/(\[[^\]]+\])[^\]]*$/', static::REGEX_VARIABLE, $previousChar);
442
-        $previousChar = $previousChar[1];
441
+		preg_match('/(\[[^\]]+\])[^\]]*$/', static::REGEX_VARIABLE, $previousChar);
442
+		$previousChar = $previousChar[1];
443 443
 
444
-        /*
444
+		/*
445 445
          * Make sure word preceding the ['value'] is not a keyword, e.g.
446 446
          * return['x']. Because -again- PHP's regex implementation doesn't allow
447 447
          * unfixed-length look-behind assertions, I'm just going to do a lot of
448 448
          * separate look-behind assertions, one for each keyword.
449 449
          */
450
-        $keywords = $this->getKeywordsForRegex($keywords);
451
-        $keywords = '(?<!'.implode(')(?<!', $keywords).')';
452
-
453
-        return preg_replace_callback('/(?<='.$previousChar.'|\])'.$keywords.'\[(([\'"])[0-9]+\\2)\]/u', $callback, $content);
454
-    }
455
-
456
-    /**
457
-     * Replaces true & false by !0 and !1.
458
-     *
459
-     * @param string $content
460
-     *
461
-     * @return string
462
-     */
463
-    protected function shortenBools($content)
464
-    {
465
-        $content = preg_replace('/\btrue\b/', '!0', $content);
466
-        $content = preg_replace('/\bfalse\b/', '!1', $content);
467
-
468
-        // for(;;) is exactly the same as while(true)
469
-        $content = preg_replace('/\bwhile\(!0\){/', 'for(;;){', $content);
470
-
471
-        // now make sure we didn't turn any do ... while(true) into do ... for(;;)
472
-        preg_match_all('/\bdo\b/', $content, $dos, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
473
-
474
-        // go backward to make sure positional offsets aren't altered when $content changes
475
-        $dos = array_reverse($dos);
476
-        foreach ($dos as $do) {
477
-            $offsetDo = $do[0][1];
478
-
479
-            // find all `while` (now `for`) following `do`: one of those must be
480
-            // associated with the `do` and be turned back into `while`
481
-            preg_match_all('/\bfor\(;;\)/', $content, $whiles, PREG_OFFSET_CAPTURE | PREG_SET_ORDER, $offsetDo);
482
-            foreach ($whiles as $while) {
483
-                $offsetWhile = $while[0][1];
484
-
485
-                $open = substr_count($content, '{', $offsetDo, $offsetWhile - $offsetDo);
486
-                $close = substr_count($content, '}', $offsetDo, $offsetWhile - $offsetDo);
487
-                if ($open === $close) {
488
-                    // only restore `while` if amount of `{` and `}` are the same;
489
-                    // otherwise, that `for` isn't associated with this `do`
490
-                    $content = substr_replace($content, 'while(!0)', $offsetWhile, strlen('for(;;)'));
491
-                    break;
492
-                }
493
-            }
494
-        }
495
-
496
-        return $content;
497
-    }
450
+		$keywords = $this->getKeywordsForRegex($keywords);
451
+		$keywords = '(?<!'.implode(')(?<!', $keywords).')';
452
+
453
+		return preg_replace_callback('/(?<='.$previousChar.'|\])'.$keywords.'\[(([\'"])[0-9]+\\2)\]/u', $callback, $content);
454
+	}
455
+
456
+	/**
457
+	 * Replaces true & false by !0 and !1.
458
+	 *
459
+	 * @param string $content
460
+	 *
461
+	 * @return string
462
+	 */
463
+	protected function shortenBools($content)
464
+	{
465
+		$content = preg_replace('/\btrue\b/', '!0', $content);
466
+		$content = preg_replace('/\bfalse\b/', '!1', $content);
467
+
468
+		// for(;;) is exactly the same as while(true)
469
+		$content = preg_replace('/\bwhile\(!0\){/', 'for(;;){', $content);
470
+
471
+		// now make sure we didn't turn any do ... while(true) into do ... for(;;)
472
+		preg_match_all('/\bdo\b/', $content, $dos, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
473
+
474
+		// go backward to make sure positional offsets aren't altered when $content changes
475
+		$dos = array_reverse($dos);
476
+		foreach ($dos as $do) {
477
+			$offsetDo = $do[0][1];
478
+
479
+			// find all `while` (now `for`) following `do`: one of those must be
480
+			// associated with the `do` and be turned back into `while`
481
+			preg_match_all('/\bfor\(;;\)/', $content, $whiles, PREG_OFFSET_CAPTURE | PREG_SET_ORDER, $offsetDo);
482
+			foreach ($whiles as $while) {
483
+				$offsetWhile = $while[0][1];
484
+
485
+				$open = substr_count($content, '{', $offsetDo, $offsetWhile - $offsetDo);
486
+				$close = substr_count($content, '}', $offsetDo, $offsetWhile - $offsetDo);
487
+				if ($open === $close) {
488
+					// only restore `while` if amount of `{` and `}` are the same;
489
+					// otherwise, that `for` isn't associated with this `do`
490
+					$content = substr_replace($content, 'while(!0)', $offsetWhile, strlen('for(;;)'));
491
+					break;
492
+				}
493
+			}
494
+		}
495
+
496
+		return $content;
497
+	}
498 498
 }
Please login to merge, or discard this patch.
Spacing   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -106,13 +106,13 @@  discard block
 block discarded – undo
106 106
     {
107 107
         call_user_func_array(array('parent', '__construct'), func_get_args());
108 108
 
109
-        $dataDir = __DIR__.'/../data/js/';
109
+        $dataDir = __DIR__ . '/../data/js/';
110 110
         $options = FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES;
111
-        $this->keywordsReserved = file($dataDir.'keywords_reserved.txt', $options);
112
-        $this->keywordsBefore = file($dataDir.'keywords_before.txt', $options);
113
-        $this->keywordsAfter = file($dataDir.'keywords_after.txt', $options);
114
-        $this->operatorsBefore = file($dataDir.'operators_before.txt', $options);
115
-        $this->operatorsAfter = file($dataDir.'operators_after.txt', $options);
111
+        $this->keywordsReserved = file($dataDir . 'keywords_reserved.txt', $options);
112
+        $this->keywordsBefore = file($dataDir . 'keywords_before.txt', $options);
113
+        $this->keywordsAfter = file($dataDir . 'keywords_after.txt', $options);
114
+        $this->operatorsBefore = file($dataDir . 'operators_before.txt', $options);
115
+        $this->operatorsAfter = file($dataDir . 'operators_after.txt', $options);
116 116
     }
117 117
 
118 118
     /**
@@ -137,7 +137,7 @@  discard block
 block discarded – undo
137 137
              * singe-line comment on the last line (in which case it would also
138 138
              * be seen as part of that comment)
139 139
              */
140
-            $content .= $js."\n;";
140
+            $content .= $js . "\n;";
141 141
         }
142 142
 
143 143
         /*
@@ -202,9 +202,9 @@  discard block
 block discarded – undo
202 202
     {
203 203
         // PHP only supports $this inside anonymous functions since 5.4
204 204
         $minifier = $this;
205
-        $callback = function ($match) use ($minifier) {
205
+        $callback = function($match) use ($minifier) {
206 206
             $count = count($minifier->extracted);
207
-            $placeholder = '/'.$count.'/';
207
+            $placeholder = '/' . $count . '/';
208 208
             $minifier->extracted[$placeholder] = $match[1];
209 209
 
210 210
             return $placeholder;
@@ -219,11 +219,11 @@  discard block
 block discarded – undo
219 219
         // it's going to be division
220 220
         // checking for that is complex, so we'll do inverse:
221 221
         // * at the beginning of the file, it's not division, but regex
222
-        $this->registerPattern('/^\s*\K'.$pattern.'/', $callback);
222
+        $this->registerPattern('/^\s*\K' . $pattern . '/', $callback);
223 223
         // * following another operator, it's not division, but regex
224 224
         $operators = $this->getOperatorsForRegex($this->operatorsBefore, '/');
225 225
         $operators += $this->getKeywordsForRegex($this->keywordsReserved, '/');
226
-        $this->registerPattern('/(?:'.implode('|', $operators).')\s*\K'.$pattern.'/', $callback);
226
+        $this->registerPattern('/(?:' . implode('|', $operators) . ')\s*\K' . $pattern . '/', $callback);
227 227
     }
228 228
 
229 229
     /**
@@ -265,8 +265,8 @@  discard block
 block discarded – undo
265 265
         unset($before['+'], $before['-'], $after['+'], $after['-']);
266 266
         $content = preg_replace(
267 267
             array(
268
-                '/('.implode('|', $before).')\s+/',
269
-                '/\s+('.implode('|', $after).')/',
268
+                '/(' . implode('|', $before) . ')\s+/',
269
+                '/\s+(' . implode('|', $after) . ')/',
270 270
             ), '\\1', $content
271 271
         );
272 272
 
@@ -284,13 +284,13 @@  discard block
 block discarded – undo
284 284
          * strip the newlines. However, we can safely strip any non-line feed
285 285
          * whitespace that follows them.
286 286
          */
287
-        $content = preg_replace('/([\}\)\]])[^\S\n]+(?!'.implode('|', $operators).')/', '\\1', $content);
287
+        $content = preg_replace('/([\}\)\]])[^\S\n]+(?!' . implode('|', $operators) . ')/', '\\1', $content);
288 288
 
289 289
         // collapse whitespace around reserved words into single space
290 290
         $before = $this->getKeywordsForRegex($this->keywordsBefore, '/');
291 291
         $after = $this->getKeywordsForRegex($this->keywordsAfter, '/');
292
-        $content = preg_replace('/(^|[;\}\s])\K('.implode('|', $before).')\s+/', '\\2 ', $content);
293
-        $content = preg_replace('/\s+('.implode('|', $after).')(?=([;\{\s]|$))/', ' \\1', $content);
292
+        $content = preg_replace('/(^|[;\}\s])\K(' . implode('|', $before) . ')\s+/', '\\2 ', $content);
293
+        $content = preg_replace('/\s+(' . implode('|', $after) . ')(?=([;\{\s]|$))/', ' \\1', $content);
294 294
 
295 295
         /*
296 296
          * Get rid of double semicolons, except where they can be used like:
@@ -364,7 +364,7 @@  discard block
 block discarded – undo
364 364
 
365 365
         // don't confuse = with other assignment shortcuts (e.g. +=)
366 366
         $chars = preg_quote('+-*\=<>%&|');
367
-        $operators['='] = '(?<!['.$chars.'])\=';
367
+        $operators['='] = '(?<![' . $chars . '])\=';
368 368
 
369 369
         return $operators;
370 370
     }
@@ -385,8 +385,8 @@  discard block
 block discarded – undo
385 385
         $escaped = array_map('preg_quote', $keywords, $delimiter);
386 386
 
387 387
         // add word boundaries
388
-        array_walk($keywords, function ($value) {
389
-            return '\b'.$value.'\b';
388
+        array_walk($keywords, function($value) {
389
+            return '\b' . $value . '\b';
390 390
         });
391 391
 
392 392
         $keywords = array_combine($keywords, $escaped);
@@ -406,7 +406,7 @@  discard block
 block discarded – undo
406 406
         // PHP only supports $this inside anonymous functions since 5.4
407 407
         $minifier = $this;
408 408
         $keywords = $this->keywordsReserved;
409
-        $callback = function ($match) use ($minifier, $keywords) {
409
+        $callback = function($match) use ($minifier, $keywords) {
410 410
             $property = trim($minifier->extracted[$match[1]], '\'"');
411 411
 
412 412
             /*
@@ -423,11 +423,11 @@  discard block
 block discarded – undo
423 423
              * array['key-here'] can't be replaced by array.key-here since '-'
424 424
              * is not a valid character there.
425 425
              */
426
-            if (!preg_match('/^'.$minifier::REGEX_VARIABLE.'$/u', $property)) {
426
+            if (!preg_match('/^' . $minifier::REGEX_VARIABLE . '$/u', $property)) {
427 427
                 return $match[0];
428 428
             }
429 429
 
430
-            return '.'.$property;
430
+            return '.' . $property;
431 431
         };
432 432
 
433 433
         /*
@@ -448,9 +448,9 @@  discard block
 block discarded – undo
448 448
          * separate look-behind assertions, one for each keyword.
449 449
          */
450 450
         $keywords = $this->getKeywordsForRegex($keywords);
451
-        $keywords = '(?<!'.implode(')(?<!', $keywords).')';
451
+        $keywords = '(?<!' . implode(')(?<!', $keywords) . ')';
452 452
 
453
-        return preg_replace_callback('/(?<='.$previousChar.'|\])'.$keywords.'\[(([\'"])[0-9]+\\2)\]/u', $callback, $content);
453
+        return preg_replace_callback('/(?<=' . $previousChar . '|\])' . $keywords . '\[(([\'"])[0-9]+\\2)\]/u', $callback, $content);
454 454
     }
455 455
 
456 456
     /**
Please login to merge, or discard this patch.
Sources/minify/src/Minify.php 2 patches
Indentation   +383 added lines, -383 removed lines patch added patch discarded remove patch
@@ -16,326 +16,326 @@  discard block
 block discarded – undo
16 16
  */
17 17
 abstract class Minify
18 18
 {
19
-    /**
20
-     * The data to be minified.
21
-     *
22
-     * @var string[]
23
-     */
24
-    protected $data = array();
25
-
26
-    /**
27
-     * Array of patterns to match.
28
-     *
29
-     * @var string[]
30
-     */
31
-    protected $patterns = array();
32
-
33
-    /**
34
-     * This array will hold content of strings and regular expressions that have
35
-     * been extracted from the JS source code, so we can reliably match "code",
36
-     * without having to worry about potential "code-like" characters inside.
37
-     *
38
-     * @var string[]
39
-     */
40
-    public $extracted = array();
41
-
42
-    /**
43
-     * Init the minify class - optionally, code may be passed along already.
44
-     */
45
-    public function __construct(/* $data = null, ... */)
46
-    {
47
-        // it's possible to add the source through the constructor as well ;)
48
-        if (func_num_args()) {
49
-            call_user_func_array(array($this, 'add'), func_get_args());
50
-        }
51
-    }
52
-
53
-    /**
54
-     * Add a file or straight-up code to be minified.
55
-     *
56
-     * @param string $data
57
-     */
58
-    public function add($data /* $data = null, ... */)
59
-    {
60
-        // bogus "usage" of parameter $data: scrutinizer warns this variable is
61
-        // not used (we're using func_get_args instead to support overloading),
62
-        // but it still needs to be defined because it makes no sense to have
63
-        // this function without argument :)
64
-        $args = array($data) + func_get_args();
65
-
66
-        // this method can be overloaded
67
-        foreach ($args as $data) {
68
-            // redefine var
69
-            $data = (string) $data;
70
-
71
-            // load data
72
-            $value = $this->load($data);
73
-            $key = ($data != $value) ? $data : count($this->data);
74
-
75
-            // store data
76
-            $this->data[$key] = $value;
77
-        }
78
-    }
79
-
80
-    /**
81
-     * Minify the data & (optionally) saves it to a file.
82
-     *
83
-     * @param string[optional] $path Path to write the data to.
84
-     *
85
-     * @return string The minified data.
86
-     */
87
-    public function minify($path = null)
88
-    {
89
-        $content = $this->execute($path);
90
-
91
-        // save to path
92
-        if ($path !== null) {
93
-            $this->save($content, $path);
94
-        }
95
-
96
-        return $content;
97
-    }
98
-
99
-    /**
100
-     * Minify & gzip the data & (optionally) saves it to a file.
101
-     *
102
-     * @param string[optional] $path  Path to write the data to.
103
-     * @param int[optional]    $level Compression level, from 0 to 9.
104
-     *
105
-     * @return string The minified & gzipped data.
106
-     */
107
-    public function gzip($path = null, $level = 9)
108
-    {
109
-        $content = $this->execute($path);
110
-        $content = gzencode($content, $level, FORCE_GZIP);
111
-
112
-        // save to path
113
-        if ($path !== null) {
114
-            $this->save($content, $path);
115
-        }
116
-
117
-        return $content;
118
-    }
119
-
120
-    /**
121
-     * Minify the data & write it to a CacheItemInterface object.
122
-     *
123
-     * @param CacheItemInterface $item Cache item to write the data to.
124
-     *
125
-     * @return CacheItemInterface Cache item with the minifier data.
126
-     */
127
-    public function cache(CacheItemInterface $item)
128
-    {
129
-        $content = $this->execute();
130
-        $item->set($content);
131
-
132
-        return $item;
133
-    }
134
-
135
-    /**
136
-     * Minify the data.
137
-     *
138
-     * @param string[optional] $path Path to write the data to.
139
-     *
140
-     * @return string The minified data.
141
-     */
142
-    abstract public function execute($path = null);
143
-
144
-    /**
145
-     * Load data.
146
-     *
147
-     * @param string $data Either a path to a file or the content itself.
148
-     *
149
-     * @return string
150
-     */
151
-    protected function load($data)
152
-    {
153
-        // check if the data is a file
154
-        if ($this->canImportFile($data)) {
155
-            $data = file_get_contents($data);
156
-
157
-            // strip BOM, if any
158
-            if (substr($data, 0, 3) == "\xef\xbb\xbf") {
159
-                $data = substr($data, 3);
160
-            }
161
-        }
162
-
163
-        return $data;
164
-    }
165
-
166
-    /**
167
-     * Save to file.
168
-     *
169
-     * @param string $content The minified data.
170
-     * @param string $path    The path to save the minified data to.
171
-     *
172
-     * @throws IOException
173
-     */
174
-    protected function save($content, $path)
175
-    {
176
-        $handler = $this->openFileForWriting($path);
177
-
178
-        $this->writeToFile($handler, $content);
179
-
180
-        @fclose($handler);
181
-    }
182
-
183
-    /**
184
-     * Register a pattern to execute against the source content.
185
-     *
186
-     * @param string          $pattern     PCRE pattern.
187
-     * @param string|callable $replacement Replacement value for matched pattern.
188
-     */
189
-    protected function registerPattern($pattern, $replacement = '')
190
-    {
191
-        // study the pattern, we'll execute it more than once
192
-        $pattern .= 'S';
193
-
194
-        $this->patterns[] = array($pattern, $replacement);
195
-    }
196
-
197
-    /**
198
-     * We can't "just" run some regular expressions against JavaScript: it's a
199
-     * complex language. E.g. having an occurrence of // xyz would be a comment,
200
-     * unless it's used within a string. Of you could have something that looks
201
-     * like a 'string', but inside a comment.
202
-     * The only way to accurately replace these pieces is to traverse the JS one
203
-     * character at a time and try to find whatever starts first.
204
-     *
205
-     * @param string $content The content to replace patterns in.
206
-     *
207
-     * @return string The (manipulated) content.
208
-     */
209
-    protected function replace($content)
210
-    {
211
-        $processed = '';
212
-        $positions = array_fill(0, count($this->patterns), -1);
213
-        $matches = array();
214
-
215
-        while ($content) {
216
-            // find first match for all patterns
217
-            foreach ($this->patterns as $i => $pattern) {
218
-                list($pattern, $replacement) = $pattern;
219
-
220
-                // no need to re-run matches that are still in the part of the
221
-                // content that hasn't been processed
222
-                if ($positions[$i] >= 0) {
223
-                    continue;
224
-                }
225
-
226
-                $match = null;
227
-                if (preg_match($pattern, $content, $match)) {
228
-                    $matches[$i] = $match;
229
-
230
-                    // we'll store the match position as well; that way, we
231
-                    // don't have to redo all preg_matches after changing only
232
-                    // the first (we'll still know where those others are)
233
-                    $positions[$i] = strpos($content, $match[0]);
234
-                } else {
235
-                    // if the pattern couldn't be matched, there's no point in
236
-                    // executing it again in later runs on this same content;
237
-                    // ignore this one until we reach end of content
238
-                    unset($matches[$i]);
239
-                    $positions[$i] = strlen($content);
240
-                }
241
-            }
242
-
243
-            // no more matches to find: everything's been processed, break out
244
-            if (!$matches) {
245
-                $processed .= $content;
246
-                break;
247
-            }
248
-
249
-            // see which of the patterns actually found the first thing (we'll
250
-            // only want to execute that one, since we're unsure if what the
251
-            // other found was not inside what the first found)
252
-            $discardLength = min($positions);
253
-            $firstPattern = array_search($discardLength, $positions);
254
-            $match = $matches[$firstPattern][0];
255
-
256
-            // execute the pattern that matches earliest in the content string
257
-            list($pattern, $replacement) = $this->patterns[$firstPattern];
258
-            $replacement = $this->replacePattern($pattern, $replacement, $content);
259
-
260
-            // figure out which part of the string was unmatched; that's the
261
-            // part we'll execute the patterns on again next
262
-            $content = substr($content, $discardLength);
263
-            $unmatched = (string) substr($content, strpos($content, $match) + strlen($match));
264
-
265
-            // move the replaced part to $processed and prepare $content to
266
-            // again match batch of patterns against
267
-            $processed .= substr($replacement, 0, strlen($replacement) - strlen($unmatched));
268
-            $content = $unmatched;
269
-
270
-            // first match has been replaced & that content is to be left alone,
271
-            // the next matches will start after this replacement, so we should
272
-            // fix their offsets
273
-            foreach ($positions as $i => $position) {
274
-                $positions[$i] -= $discardLength + strlen($match);
275
-            }
276
-        }
277
-
278
-        return $processed;
279
-    }
280
-
281
-    /**
282
-     * This is where a pattern is matched against $content and the matches
283
-     * are replaced by their respective value.
284
-     * This function will be called plenty of times, where $content will always
285
-     * move up 1 character.
286
-     *
287
-     * @param string          $pattern     Pattern to match.
288
-     * @param string|callable $replacement Replacement value.
289
-     * @param string          $content     Content to match pattern against.
290
-     *
291
-     * @return string
292
-     */
293
-    protected function replacePattern($pattern, $replacement, $content)
294
-    {
295
-        if (is_callable($replacement)) {
296
-            return preg_replace_callback($pattern, $replacement, $content, 1, $count);
297
-        } else {
298
-            return preg_replace($pattern, $replacement, $content, 1, $count);
299
-        }
300
-    }
301
-
302
-    /**
303
-     * Strings are a pattern we need to match, in order to ignore potential
304
-     * code-like content inside them, but we just want all of the string
305
-     * content to remain untouched.
306
-     *
307
-     * This method will replace all string content with simple STRING#
308
-     * placeholder text, so we've rid all strings from characters that may be
309
-     * misinterpreted. Original string content will be saved in $this->extracted
310
-     * and after doing all other minifying, we can restore the original content
311
-     * via restoreStrings().
312
-     *
313
-     * @param string[optional] $chars
314
-     */
315
-    protected function extractStrings($chars = '\'"')
316
-    {
317
-        // PHP only supports $this inside anonymous functions since 5.4
318
-        $minifier = $this;
319
-        $callback = function ($match) use ($minifier) {
320
-            // check the second index here, because the first always contains a quote
321
-            if (!$match[2]) {
322
-                /*
19
+	/**
20
+	 * The data to be minified.
21
+	 *
22
+	 * @var string[]
23
+	 */
24
+	protected $data = array();
25
+
26
+	/**
27
+	 * Array of patterns to match.
28
+	 *
29
+	 * @var string[]
30
+	 */
31
+	protected $patterns = array();
32
+
33
+	/**
34
+	 * This array will hold content of strings and regular expressions that have
35
+	 * been extracted from the JS source code, so we can reliably match "code",
36
+	 * without having to worry about potential "code-like" characters inside.
37
+	 *
38
+	 * @var string[]
39
+	 */
40
+	public $extracted = array();
41
+
42
+	/**
43
+	 * Init the minify class - optionally, code may be passed along already.
44
+	 */
45
+	public function __construct(/* $data = null, ... */)
46
+	{
47
+		// it's possible to add the source through the constructor as well ;)
48
+		if (func_num_args()) {
49
+			call_user_func_array(array($this, 'add'), func_get_args());
50
+		}
51
+	}
52
+
53
+	/**
54
+	 * Add a file or straight-up code to be minified.
55
+	 *
56
+	 * @param string $data
57
+	 */
58
+	public function add($data /* $data = null, ... */)
59
+	{
60
+		// bogus "usage" of parameter $data: scrutinizer warns this variable is
61
+		// not used (we're using func_get_args instead to support overloading),
62
+		// but it still needs to be defined because it makes no sense to have
63
+		// this function without argument :)
64
+		$args = array($data) + func_get_args();
65
+
66
+		// this method can be overloaded
67
+		foreach ($args as $data) {
68
+			// redefine var
69
+			$data = (string) $data;
70
+
71
+			// load data
72
+			$value = $this->load($data);
73
+			$key = ($data != $value) ? $data : count($this->data);
74
+
75
+			// store data
76
+			$this->data[$key] = $value;
77
+		}
78
+	}
79
+
80
+	/**
81
+	 * Minify the data & (optionally) saves it to a file.
82
+	 *
83
+	 * @param string[optional] $path Path to write the data to.
84
+	 *
85
+	 * @return string The minified data.
86
+	 */
87
+	public function minify($path = null)
88
+	{
89
+		$content = $this->execute($path);
90
+
91
+		// save to path
92
+		if ($path !== null) {
93
+			$this->save($content, $path);
94
+		}
95
+
96
+		return $content;
97
+	}
98
+
99
+	/**
100
+	 * Minify & gzip the data & (optionally) saves it to a file.
101
+	 *
102
+	 * @param string[optional] $path  Path to write the data to.
103
+	 * @param int[optional]    $level Compression level, from 0 to 9.
104
+	 *
105
+	 * @return string The minified & gzipped data.
106
+	 */
107
+	public function gzip($path = null, $level = 9)
108
+	{
109
+		$content = $this->execute($path);
110
+		$content = gzencode($content, $level, FORCE_GZIP);
111
+
112
+		// save to path
113
+		if ($path !== null) {
114
+			$this->save($content, $path);
115
+		}
116
+
117
+		return $content;
118
+	}
119
+
120
+	/**
121
+	 * Minify the data & write it to a CacheItemInterface object.
122
+	 *
123
+	 * @param CacheItemInterface $item Cache item to write the data to.
124
+	 *
125
+	 * @return CacheItemInterface Cache item with the minifier data.
126
+	 */
127
+	public function cache(CacheItemInterface $item)
128
+	{
129
+		$content = $this->execute();
130
+		$item->set($content);
131
+
132
+		return $item;
133
+	}
134
+
135
+	/**
136
+	 * Minify the data.
137
+	 *
138
+	 * @param string[optional] $path Path to write the data to.
139
+	 *
140
+	 * @return string The minified data.
141
+	 */
142
+	abstract public function execute($path = null);
143
+
144
+	/**
145
+	 * Load data.
146
+	 *
147
+	 * @param string $data Either a path to a file or the content itself.
148
+	 *
149
+	 * @return string
150
+	 */
151
+	protected function load($data)
152
+	{
153
+		// check if the data is a file
154
+		if ($this->canImportFile($data)) {
155
+			$data = file_get_contents($data);
156
+
157
+			// strip BOM, if any
158
+			if (substr($data, 0, 3) == "\xef\xbb\xbf") {
159
+				$data = substr($data, 3);
160
+			}
161
+		}
162
+
163
+		return $data;
164
+	}
165
+
166
+	/**
167
+	 * Save to file.
168
+	 *
169
+	 * @param string $content The minified data.
170
+	 * @param string $path    The path to save the minified data to.
171
+	 *
172
+	 * @throws IOException
173
+	 */
174
+	protected function save($content, $path)
175
+	{
176
+		$handler = $this->openFileForWriting($path);
177
+
178
+		$this->writeToFile($handler, $content);
179
+
180
+		@fclose($handler);
181
+	}
182
+
183
+	/**
184
+	 * Register a pattern to execute against the source content.
185
+	 *
186
+	 * @param string          $pattern     PCRE pattern.
187
+	 * @param string|callable $replacement Replacement value for matched pattern.
188
+	 */
189
+	protected function registerPattern($pattern, $replacement = '')
190
+	{
191
+		// study the pattern, we'll execute it more than once
192
+		$pattern .= 'S';
193
+
194
+		$this->patterns[] = array($pattern, $replacement);
195
+	}
196
+
197
+	/**
198
+	 * We can't "just" run some regular expressions against JavaScript: it's a
199
+	 * complex language. E.g. having an occurrence of // xyz would be a comment,
200
+	 * unless it's used within a string. Of you could have something that looks
201
+	 * like a 'string', but inside a comment.
202
+	 * The only way to accurately replace these pieces is to traverse the JS one
203
+	 * character at a time and try to find whatever starts first.
204
+	 *
205
+	 * @param string $content The content to replace patterns in.
206
+	 *
207
+	 * @return string The (manipulated) content.
208
+	 */
209
+	protected function replace($content)
210
+	{
211
+		$processed = '';
212
+		$positions = array_fill(0, count($this->patterns), -1);
213
+		$matches = array();
214
+
215
+		while ($content) {
216
+			// find first match for all patterns
217
+			foreach ($this->patterns as $i => $pattern) {
218
+				list($pattern, $replacement) = $pattern;
219
+
220
+				// no need to re-run matches that are still in the part of the
221
+				// content that hasn't been processed
222
+				if ($positions[$i] >= 0) {
223
+					continue;
224
+				}
225
+
226
+				$match = null;
227
+				if (preg_match($pattern, $content, $match)) {
228
+					$matches[$i] = $match;
229
+
230
+					// we'll store the match position as well; that way, we
231
+					// don't have to redo all preg_matches after changing only
232
+					// the first (we'll still know where those others are)
233
+					$positions[$i] = strpos($content, $match[0]);
234
+				} else {
235
+					// if the pattern couldn't be matched, there's no point in
236
+					// executing it again in later runs on this same content;
237
+					// ignore this one until we reach end of content
238
+					unset($matches[$i]);
239
+					$positions[$i] = strlen($content);
240
+				}
241
+			}
242
+
243
+			// no more matches to find: everything's been processed, break out
244
+			if (!$matches) {
245
+				$processed .= $content;
246
+				break;
247
+			}
248
+
249
+			// see which of the patterns actually found the first thing (we'll
250
+			// only want to execute that one, since we're unsure if what the
251
+			// other found was not inside what the first found)
252
+			$discardLength = min($positions);
253
+			$firstPattern = array_search($discardLength, $positions);
254
+			$match = $matches[$firstPattern][0];
255
+
256
+			// execute the pattern that matches earliest in the content string
257
+			list($pattern, $replacement) = $this->patterns[$firstPattern];
258
+			$replacement = $this->replacePattern($pattern, $replacement, $content);
259
+
260
+			// figure out which part of the string was unmatched; that's the
261
+			// part we'll execute the patterns on again next
262
+			$content = substr($content, $discardLength);
263
+			$unmatched = (string) substr($content, strpos($content, $match) + strlen($match));
264
+
265
+			// move the replaced part to $processed and prepare $content to
266
+			// again match batch of patterns against
267
+			$processed .= substr($replacement, 0, strlen($replacement) - strlen($unmatched));
268
+			$content = $unmatched;
269
+
270
+			// first match has been replaced & that content is to be left alone,
271
+			// the next matches will start after this replacement, so we should
272
+			// fix their offsets
273
+			foreach ($positions as $i => $position) {
274
+				$positions[$i] -= $discardLength + strlen($match);
275
+			}
276
+		}
277
+
278
+		return $processed;
279
+	}
280
+
281
+	/**
282
+	 * This is where a pattern is matched against $content and the matches
283
+	 * are replaced by their respective value.
284
+	 * This function will be called plenty of times, where $content will always
285
+	 * move up 1 character.
286
+	 *
287
+	 * @param string          $pattern     Pattern to match.
288
+	 * @param string|callable $replacement Replacement value.
289
+	 * @param string          $content     Content to match pattern against.
290
+	 *
291
+	 * @return string
292
+	 */
293
+	protected function replacePattern($pattern, $replacement, $content)
294
+	{
295
+		if (is_callable($replacement)) {
296
+			return preg_replace_callback($pattern, $replacement, $content, 1, $count);
297
+		} else {
298
+			return preg_replace($pattern, $replacement, $content, 1, $count);
299
+		}
300
+	}
301
+
302
+	/**
303
+	 * Strings are a pattern we need to match, in order to ignore potential
304
+	 * code-like content inside them, but we just want all of the string
305
+	 * content to remain untouched.
306
+	 *
307
+	 * This method will replace all string content with simple STRING#
308
+	 * placeholder text, so we've rid all strings from characters that may be
309
+	 * misinterpreted. Original string content will be saved in $this->extracted
310
+	 * and after doing all other minifying, we can restore the original content
311
+	 * via restoreStrings().
312
+	 *
313
+	 * @param string[optional] $chars
314
+	 */
315
+	protected function extractStrings($chars = '\'"')
316
+	{
317
+		// PHP only supports $this inside anonymous functions since 5.4
318
+		$minifier = $this;
319
+		$callback = function ($match) use ($minifier) {
320
+			// check the second index here, because the first always contains a quote
321
+			if (!$match[2]) {
322
+				/*
323 323
                  * Empty strings need no placeholder; they can't be confused for
324 324
                  * anything else anyway.
325 325
                  * But we still needed to match them, for the extraction routine
326 326
                  * to skip over this particular string.
327 327
                  */
328
-                return $match[0];
329
-            }
328
+				return $match[0];
329
+			}
330 330
 
331
-            $count = count($minifier->extracted);
332
-            $placeholder = $match[1].$count.$match[1];
333
-            $minifier->extracted[$placeholder] = $match[1].$match[2].$match[1];
331
+			$count = count($minifier->extracted);
332
+			$placeholder = $match[1].$count.$match[1];
333
+			$minifier->extracted[$placeholder] = $match[1].$match[2].$match[1];
334 334
 
335
-            return $placeholder;
336
-        };
335
+			return $placeholder;
336
+		};
337 337
 
338
-        /*
338
+		/*
339 339
          * The \\ messiness explained:
340 340
          * * Don't count ' or " as end-of-string if it's escaped (has backslash
341 341
          * in front of it)
@@ -347,75 +347,75 @@  discard block
 block discarded – undo
347 347
          * considered as escape-char (times 2) and to get it in the regex,
348 348
          * escaped (times 2)
349 349
          */
350
-        $this->registerPattern('/(['.$chars.'])(.*?(?<!\\\\)(\\\\\\\\)*+)\\1/s', $callback);
351
-    }
352
-
353
-    /**
354
-     * This method will restore all extracted data (strings, regexes) that were
355
-     * replaced with placeholder text in extract*(). The original content was
356
-     * saved in $this->extracted.
357
-     *
358
-     * @param string $content
359
-     *
360
-     * @return string
361
-     */
362
-    protected function restoreExtractedData($content)
363
-    {
364
-        if (!$this->extracted) {
365
-            // nothing was extracted, nothing to restore
366
-            return $content;
367
-        }
368
-
369
-        $content = strtr($content, $this->extracted);
370
-
371
-        $this->extracted = array();
372
-
373
-        return $content;
374
-    }
375
-
376
-    /**
377
-     * Check if the path is a regular file and can be read.
378
-     *
379
-     * @param string $path
380
-     *
381
-     * @return bool
382
-     */
383
-    protected function canImportFile($path)
384
-    {
385
-        return strlen($path) < PHP_MAXPATHLEN && is_file($path) && is_readable($path);
386
-    }
387
-
388
-    /**
389
-     * Attempts to open file specified by $path for writing.
390
-     *
391
-     * @param string $path The path to the file.
392
-     *
393
-     * @return resource Specifier for the target file.
394
-     *
395
-     * @throws IOException
396
-     */
397
-    protected function openFileForWriting($path)
398
-    {
399
-        if (($handler = @fopen($path, 'w')) === false) {
400
-            throw new IOException('The file "'.$path.'" could not be opened for writing. Check if PHP has enough permissions.');
401
-        }
402
-
403
-        return $handler;
404
-    }
405
-
406
-    /**
407
-     * Attempts to write $content to the file specified by $handler. $path is used for printing exceptions.
408
-     *
409
-     * @param resource $handler The resource to write to.
410
-     * @param string   $content The content to write.
411
-     * @param string   $path    The path to the file (for exception printing only).
412
-     *
413
-     * @throws IOException
414
-     */
415
-    protected function writeToFile($handler, $content, $path = '')
416
-    {
417
-        if (($result = @fwrite($handler, $content)) === false || ($result < strlen($content))) {
418
-            throw new IOException('The file "'.$path.'" could not be written to. Check your disk space and file permissions.');
419
-        }
420
-    }
350
+		$this->registerPattern('/(['.$chars.'])(.*?(?<!\\\\)(\\\\\\\\)*+)\\1/s', $callback);
351
+	}
352
+
353
+	/**
354
+	 * This method will restore all extracted data (strings, regexes) that were
355
+	 * replaced with placeholder text in extract*(). The original content was
356
+	 * saved in $this->extracted.
357
+	 *
358
+	 * @param string $content
359
+	 *
360
+	 * @return string
361
+	 */
362
+	protected function restoreExtractedData($content)
363
+	{
364
+		if (!$this->extracted) {
365
+			// nothing was extracted, nothing to restore
366
+			return $content;
367
+		}
368
+
369
+		$content = strtr($content, $this->extracted);
370
+
371
+		$this->extracted = array();
372
+
373
+		return $content;
374
+	}
375
+
376
+	/**
377
+	 * Check if the path is a regular file and can be read.
378
+	 *
379
+	 * @param string $path
380
+	 *
381
+	 * @return bool
382
+	 */
383
+	protected function canImportFile($path)
384
+	{
385
+		return strlen($path) < PHP_MAXPATHLEN && is_file($path) && is_readable($path);
386
+	}
387
+
388
+	/**
389
+	 * Attempts to open file specified by $path for writing.
390
+	 *
391
+	 * @param string $path The path to the file.
392
+	 *
393
+	 * @return resource Specifier for the target file.
394
+	 *
395
+	 * @throws IOException
396
+	 */
397
+	protected function openFileForWriting($path)
398
+	{
399
+		if (($handler = @fopen($path, 'w')) === false) {
400
+			throw new IOException('The file "'.$path.'" could not be opened for writing. Check if PHP has enough permissions.');
401
+		}
402
+
403
+		return $handler;
404
+	}
405
+
406
+	/**
407
+	 * Attempts to write $content to the file specified by $handler. $path is used for printing exceptions.
408
+	 *
409
+	 * @param resource $handler The resource to write to.
410
+	 * @param string   $content The content to write.
411
+	 * @param string   $path    The path to the file (for exception printing only).
412
+	 *
413
+	 * @throws IOException
414
+	 */
415
+	protected function writeToFile($handler, $content, $path = '')
416
+	{
417
+		if (($result = @fwrite($handler, $content)) === false || ($result < strlen($content))) {
418
+			throw new IOException('The file "'.$path.'" could not be written to. Check your disk space and file permissions.');
419
+		}
420
+	}
421 421
 }
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -316,7 +316,7 @@  discard block
 block discarded – undo
316 316
     {
317 317
         // PHP only supports $this inside anonymous functions since 5.4
318 318
         $minifier = $this;
319
-        $callback = function ($match) use ($minifier) {
319
+        $callback = function($match) use ($minifier) {
320 320
             // check the second index here, because the first always contains a quote
321 321
             if (!$match[2]) {
322 322
                 /*
@@ -329,8 +329,8 @@  discard block
 block discarded – undo
329 329
             }
330 330
 
331 331
             $count = count($minifier->extracted);
332
-            $placeholder = $match[1].$count.$match[1];
333
-            $minifier->extracted[$placeholder] = $match[1].$match[2].$match[1];
332
+            $placeholder = $match[1] . $count . $match[1];
333
+            $minifier->extracted[$placeholder] = $match[1] . $match[2] . $match[1];
334 334
 
335 335
             return $placeholder;
336 336
         };
@@ -347,7 +347,7 @@  discard block
 block discarded – undo
347 347
          * considered as escape-char (times 2) and to get it in the regex,
348 348
          * escaped (times 2)
349 349
          */
350
-        $this->registerPattern('/(['.$chars.'])(.*?(?<!\\\\)(\\\\\\\\)*+)\\1/s', $callback);
350
+        $this->registerPattern('/([' . $chars . '])(.*?(?<!\\\\)(\\\\\\\\)*+)\\1/s', $callback);
351 351
     }
352 352
 
353 353
     /**
@@ -397,7 +397,7 @@  discard block
 block discarded – undo
397 397
     protected function openFileForWriting($path)
398 398
     {
399 399
         if (($handler = @fopen($path, 'w')) === false) {
400
-            throw new IOException('The file "'.$path.'" could not be opened for writing. Check if PHP has enough permissions.');
400
+            throw new IOException('The file "' . $path . '" could not be opened for writing. Check if PHP has enough permissions.');
401 401
         }
402 402
 
403 403
         return $handler;
@@ -415,7 +415,7 @@  discard block
 block discarded – undo
415 415
     protected function writeToFile($handler, $content, $path = '')
416 416
     {
417 417
         if (($result = @fwrite($handler, $content)) === false || ($result < strlen($content))) {
418
-            throw new IOException('The file "'.$path.'" could not be written to. Check your disk space and file permissions.');
418
+            throw new IOException('The file "' . $path . '" could not be written to. Check your disk space and file permissions.');
419 419
         }
420 420
     }
421 421
 }
Please login to merge, or discard this patch.
Sources/Reminder.php 1 patch
Braces   +66 added lines, -46 removed lines patch added patch discarded remove patch
@@ -12,8 +12,9 @@  discard block
 block discarded – undo
12 12
  * @version 2.1 Beta 3
13 13
  */
14 14
 
15
-if (!defined('SMF'))
15
+if (!defined('SMF')) {
16 16
 	die('No direct access...');
17
+}
17 18
 
18 19
 /**
19 20
  * This is the controlling delegator
@@ -38,13 +39,15 @@  discard block
 block discarded – undo
38 39
 	);
39 40
 
40 41
 	// Any subaction?  If none, fall through to the main template, which will ask for one.
41
-	if (isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]))
42
-		call_helper($subActions[$_REQUEST['sa']]);
42
+	if (isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']])) {
43
+			call_helper($subActions[$_REQUEST['sa']]);
44
+	}
43 45
 
44 46
 	// Creating a one time token.
45
-	else
46
-		createToken('remind');
47
-}
47
+	else {
48
+			createToken('remind');
49
+	}
50
+	}
48 51
 
49 52
 /**
50 53
  * Allows the user to pick how they wish to be reminded
@@ -62,8 +65,7 @@  discard block
 block discarded – undo
62 65
 	{
63 66
 		$where = 'id_member = {int:id_member}';
64 67
 		$where_params['id_member'] = (int) $_REQUEST['uid'];
65
-	}
66
-	elseif (isset($_POST['user']) && $_POST['user'] != '')
68
+	} elseif (isset($_POST['user']) && $_POST['user'] != '')
67 69
 	{
68 70
 		$where = 'member_name = {string:member_name}';
69 71
 		$where_params['member_name'] = $_POST['user'];
@@ -71,8 +73,9 @@  discard block
 block discarded – undo
71 73
 	}
72 74
 
73 75
 	// You must enter a username/email address.
74
-	if (empty($where))
75
-		fatal_lang_error('username_no_exist', false);
76
+	if (empty($where)) {
77
+			fatal_lang_error('username_no_exist', false);
78
+	}
76 79
 
77 80
 	// Make sure we are not being slammed
78 81
 	// Don't call this if you're coming from the "Choose a reminder type" page - otherwise you'll likely get an error
@@ -101,8 +104,9 @@  discard block
 block discarded – undo
101 104
 			LIMIT 1',
102 105
 			$where_params
103 106
 		);
104
-		if ($smcFunc['db_num_rows']($request) == 0)
105
-			fatal_lang_error('no_user_with_email', false);
107
+		if ($smcFunc['db_num_rows']($request) == 0) {
108
+					fatal_lang_error('no_user_with_email', false);
109
+		}
106 110
 	}
107 111
 
108 112
 	$row = $smcFunc['db_fetch_assoc']($request);
@@ -112,16 +116,18 @@  discard block
 block discarded – undo
112 116
 	if ($row['is_activated'] != 1)
113 117
 	{
114 118
 		// Awaiting approval...
115
-		if (trim($row['validation_code']) == '')
116
-			fatal_error(sprintf($txt['registration_not_approved'], $scripturl . '?action=activate;user=' . $_POST['user']), false);
117
-		else
118
-			fatal_error(sprintf($txt['registration_not_activated'], $scripturl . '?action=activate;user=' . $_POST['user']), false);
119
+		if (trim($row['validation_code']) == '') {
120
+					fatal_error(sprintf($txt['registration_not_approved'], $scripturl . '?action=activate;user=' . $_POST['user']), false);
121
+		} else {
122
+					fatal_error(sprintf($txt['registration_not_activated'], $scripturl . '?action=activate;user=' . $_POST['user']), false);
123
+		}
119 124
 	}
120 125
 
121 126
 	// You can't get emailed if you have no email address.
122 127
 	$row['email_address'] = trim($row['email_address']);
123
-	if ($row['email_address'] == '')
124
-		fatal_error($txt['no_reminder_email'] . '<br>' . $txt['send_email'] . ' <a href="mailto:' . $webmaster_email . '">webmaster</a> ' . $txt['to_ask_password'] . '.');
128
+	if ($row['email_address'] == '') {
129
+			fatal_error($txt['no_reminder_email'] . '<br>' . $txt['send_email'] . ' <a href="mailto:' . $webmaster_email . '">webmaster</a> ' . $txt['to_ask_password'] . '.');
130
+	}
125 131
 
126 132
 	// If they have no secret question then they can only get emailed the item, or they are requesting the email, send them an email.
127 133
 	if (empty($row['secret_question']) || (isset($_POST['reminder_type']) && $_POST['reminder_type'] == 'email'))
@@ -176,8 +182,9 @@  discard block
 block discarded – undo
176 182
 	loadLanguage('Login');
177 183
 
178 184
 	// You need a code!
179
-	if (!isset($_REQUEST['code']))
180
-		fatal_lang_error('no_access', false);
185
+	if (!isset($_REQUEST['code'])) {
186
+			fatal_lang_error('no_access', false);
187
+	}
181 188
 
182 189
 	// Fill the context array.
183 190
 	$context += array(
@@ -203,16 +210,19 @@  discard block
 block discarded – undo
203 210
 	checkSession();
204 211
 	validateToken('remind-sp');
205 212
 
206
-	if (empty($_POST['u']) || !isset($_POST['passwrd1']) || !isset($_POST['passwrd2']))
207
-		fatal_lang_error('no_access', false);
213
+	if (empty($_POST['u']) || !isset($_POST['passwrd1']) || !isset($_POST['passwrd2'])) {
214
+			fatal_lang_error('no_access', false);
215
+	}
208 216
 
209 217
 	$_POST['u'] = (int) $_POST['u'];
210 218
 
211
-	if ($_POST['passwrd1'] != $_POST['passwrd2'])
212
-		fatal_lang_error('passwords_dont_match', false);
219
+	if ($_POST['passwrd1'] != $_POST['passwrd2']) {
220
+			fatal_lang_error('passwords_dont_match', false);
221
+	}
213 222
 
214
-	if ($_POST['passwrd1'] == '')
215
-		fatal_lang_error('no_password', false);
223
+	if ($_POST['passwrd1'] == '') {
224
+			fatal_lang_error('no_password', false);
225
+	}
216 226
 
217 227
 	loadLanguage('Login');
218 228
 
@@ -232,8 +242,9 @@  discard block
 block discarded – undo
232 242
 	);
233 243
 
234 244
 	// Does this user exist at all?
235
-	if ($smcFunc['db_num_rows']($request) == 0)
236
-		fatal_lang_error('invalid_userid', false);
245
+	if ($smcFunc['db_num_rows']($request) == 0) {
246
+			fatal_lang_error('invalid_userid', false);
247
+	}
237 248
 
238 249
 	list ($realCode, $username, $email, $flood_value) = $smcFunc['db_fetch_row']($request);
239 250
 	$smcFunc['db_free_result']($request);
@@ -243,8 +254,9 @@  discard block
 block discarded – undo
243 254
 	$passwordError = validatePassword($_POST['passwrd1'], $username, array($email));
244 255
 
245 256
 	// What - it's not?
246
-	if ($passwordError != null)
247
-		fatal_lang_error('profile_error_password_' . $passwordError, false);
257
+	if ($passwordError != null) {
258
+			fatal_lang_error('profile_error_password_' . $passwordError, false);
259
+	}
248 260
 
249 261
 	require_once($sourcedir . '/LogInOut.php');
250 262
 
@@ -291,8 +303,9 @@  discard block
 block discarded – undo
291 303
 	loadLanguage('Login');
292 304
 
293 305
 	// Check they entered something...
294
-	if (empty($_REQUEST['uid']))
295
-		fatal_lang_error('username_no_exist', false);
306
+	if (empty($_REQUEST['uid'])) {
307
+			fatal_lang_error('username_no_exist', false);
308
+	}
296 309
 
297 310
 	// Get the stuff....
298 311
 	$request = $smcFunc['db_query']('', '
@@ -304,15 +317,17 @@  discard block
 block discarded – undo
304 317
 			'id_member' => (int) $_REQUEST['uid'],
305 318
 		)
306 319
 	);
307
-	if ($smcFunc['db_num_rows']($request) == 0)
308
-		fatal_lang_error('username_no_exist', false);
320
+	if ($smcFunc['db_num_rows']($request) == 0) {
321
+			fatal_lang_error('username_no_exist', false);
322
+	}
309 323
 
310 324
 	$row = $smcFunc['db_fetch_assoc']($request);
311 325
 	$smcFunc['db_free_result']($request);
312 326
 
313 327
 	// If there is NO secret question - then throw an error.
314
-	if (trim($row['secret_question']) == '')
315
-		fatal_lang_error('registration_no_secret_question', false);
328
+	if (trim($row['secret_question']) == '') {
329
+			fatal_lang_error('registration_no_secret_question', false);
330
+	}
316 331
 
317 332
 	// Ask for the answer...
318 333
 	$context['remind_user'] = $row['id_member'];
@@ -335,8 +350,9 @@  discard block
 block discarded – undo
335 350
 	validateToken('remind-sai');
336 351
 
337 352
 	// Hacker?  How did you get this far without an email or username?
338
-	if (empty($_REQUEST['uid']))
339
-		fatal_lang_error('username_no_exist', false);
353
+	if (empty($_REQUEST['uid'])) {
354
+			fatal_lang_error('username_no_exist', false);
355
+	}
340 356
 
341 357
 	loadLanguage('Login');
342 358
 
@@ -350,8 +366,9 @@  discard block
 block discarded – undo
350 366
 			'id_member' => $_REQUEST['uid'],
351 367
 		)
352 368
 	);
353
-	if ($smcFunc['db_num_rows']($request) == 0)
354
-		fatal_lang_error('username_no_exist', false);
369
+	if ($smcFunc['db_num_rows']($request) == 0) {
370
+			fatal_lang_error('username_no_exist', false);
371
+	}
355 372
 
356 373
 	$row = $smcFunc['db_fetch_assoc']($request);
357 374
 	$smcFunc['db_free_result']($request);
@@ -364,20 +381,23 @@  discard block
 block discarded – undo
364 381
 	}
365 382
 
366 383
 	// You can't use a blank one!
367
-	if (strlen(trim($_POST['passwrd1'])) === 0)
368
-		fatal_lang_error('no_password', false);
384
+	if (strlen(trim($_POST['passwrd1'])) === 0) {
385
+			fatal_lang_error('no_password', false);
386
+	}
369 387
 
370 388
 	// They have to be the same too.
371
-	if ($_POST['passwrd1'] != $_POST['passwrd2'])
372
-		fatal_lang_error('passwords_dont_match', false);
389
+	if ($_POST['passwrd1'] != $_POST['passwrd2']) {
390
+			fatal_lang_error('passwords_dont_match', false);
391
+	}
373 392
 
374 393
 	// Make sure they have a strong enough password.
375 394
 	require_once($sourcedir . '/Subs-Auth.php');
376 395
 	$passwordError = validatePassword($_POST['passwrd1'], $row['member_name'], array($row['email_address']));
377 396
 
378 397
 	// Invalid?
379
-	if ($passwordError != null)
380
-		fatal_lang_error('profile_error_password_' . $passwordError, false);
398
+	if ($passwordError != null) {
399
+			fatal_lang_error('profile_error_password_' . $passwordError, false);
400
+	}
381 401
 
382 402
 	// Alright, so long as 'yer sure.
383 403
 	updateMemberData($row['id_member'], array('passwd' => hash_password($row['member_name'], $_POST['passwrd1'])));
Please login to merge, or discard this patch.
Sources/Poll.php 1 patch
Braces   +163 added lines, -119 removed lines patch added patch discarded remove patch
@@ -14,8 +14,9 @@  discard block
 block discarded – undo
14 14
  * @version 2.1 Beta 3
15 15
  */
16 16
 
17
-if (!defined('SMF'))
17
+if (!defined('SMF')) {
18 18
 	die('No direct access...');
19
+}
19 20
 
20 21
 /**
21 22
  * Allow the user to vote.
@@ -51,8 +52,9 @@  discard block
 block discarded – undo
51 52
 			'not_guest' => 0,
52 53
 		)
53 54
 	);
54
-	if ($smcFunc['db_num_rows']($request) == 0)
55
-		fatal_lang_error('poll_error', false);
55
+	if ($smcFunc['db_num_rows']($request) == 0) {
56
+			fatal_lang_error('poll_error', false);
57
+	}
56 58
 	$row = $smcFunc['db_fetch_assoc']($request);
57 59
 	$smcFunc['db_free_result']($request);
58 60
 
@@ -60,8 +62,9 @@  discard block
 block discarded – undo
60 62
 	if ($user_info['is_guest'])
61 63
 	{
62 64
 		// Guest voting disabled?
63
-		if (!$row['guest_vote'])
64
-			fatal_lang_error('guest_vote_disabled');
65
+		if (!$row['guest_vote']) {
66
+					fatal_lang_error('guest_vote_disabled');
67
+		}
65 68
 		// Guest already voted?
66 69
 		elseif (!empty($_COOKIE['guest_poll_vote']) && preg_match('~^[0-9,;]+$~', $_COOKIE['guest_poll_vote']) && strpos($_COOKIE['guest_poll_vote'], ';' . $row['id_poll'] . ',') !== false)
67 70
 		{
@@ -71,32 +74,36 @@  discard block
 block discarded – undo
71 74
 			foreach ($guestinfo as $i => $guestvoted)
72 75
 			{
73 76
 				$guestvoted = explode(',', $guestvoted);
74
-				if ($guestvoted[0] == $row['id_poll'])
75
-					break;
77
+				if ($guestvoted[0] == $row['id_poll']) {
78
+									break;
79
+				}
76 80
 			}
77 81
 			// Has the poll been reset since guest voted?
78 82
 			if ($row['reset_poll'] > $guestvoted[1])
79 83
 			{
80 84
 				// Remove the poll info from the cookie to allow guest to vote again
81 85
 				unset($guestinfo[$i]);
82
-				if (!empty($guestinfo))
83
-					$_COOKIE['guest_poll_vote'] = ';' . implode(';', $guestinfo);
84
-				else
85
-					unset($_COOKIE['guest_poll_vote']);
86
+				if (!empty($guestinfo)) {
87
+									$_COOKIE['guest_poll_vote'] = ';' . implode(';', $guestinfo);
88
+				} else {
89
+									unset($_COOKIE['guest_poll_vote']);
90
+				}
91
+			} else {
92
+							fatal_lang_error('poll_error', false);
86 93
 			}
87
-			else
88
-				fatal_lang_error('poll_error', false);
89 94
 			unset($guestinfo, $guestvoted, $i);
90 95
 		}
91 96
 	}
92 97
 
93 98
 	// Is voting locked or has it expired?
94
-	if (!empty($row['voting_locked']) || (!empty($row['expire_time']) && time() > $row['expire_time']))
95
-		fatal_lang_error('poll_error', false);
99
+	if (!empty($row['voting_locked']) || (!empty($row['expire_time']) && time() > $row['expire_time'])) {
100
+			fatal_lang_error('poll_error', false);
101
+	}
96 102
 
97 103
 	// If they have already voted and aren't allowed to change their vote - hence they are outta here!
98
-	if (!$user_info['is_guest'] && $row['selected'] != -1 && empty($row['change_vote']))
99
-		fatal_lang_error('poll_error', false);
104
+	if (!$user_info['is_guest'] && $row['selected'] != -1 && empty($row['change_vote'])) {
105
+			fatal_lang_error('poll_error', false);
106
+	}
100 107
 	// Otherwise if they can change their vote yet they haven't sent any options... remove their vote and redirect.
101 108
 	elseif (!empty($row['change_vote']) && !$user_info['is_guest'] && empty($_POST['options']))
102 109
 	{
@@ -114,8 +121,9 @@  discard block
 block discarded – undo
114 121
 				'id_poll' => $row['id_poll'],
115 122
 			)
116 123
 		);
117
-		while ($choice = $smcFunc['db_fetch_row']($request))
118
-			$pollOptions[] = $choice[0];
124
+		while ($choice = $smcFunc['db_fetch_row']($request)) {
125
+					$pollOptions[] = $choice[0];
126
+		}
119 127
 		$smcFunc['db_free_result']($request);
120 128
 
121 129
 		// Just skip it if they had voted for nothing before.
@@ -148,19 +156,22 @@  discard block
 block discarded – undo
148 156
 		}
149 157
 
150 158
 		// Redirect back to the topic so the user can vote again!
151
-		if (empty($_POST['options']))
152
-			redirectexit('topic=' . $topic . '.' . $_REQUEST['start']);
159
+		if (empty($_POST['options'])) {
160
+					redirectexit('topic=' . $topic . '.' . $_REQUEST['start']);
161
+		}
153 162
 	}
154 163
 
155 164
 	checkSession('request');
156 165
 
157 166
 	// Make sure the option(s) are valid.
158
-	if (empty($_POST['options']))
159
-		fatal_lang_error('didnt_select_vote', false);
167
+	if (empty($_POST['options'])) {
168
+			fatal_lang_error('didnt_select_vote', false);
169
+	}
160 170
 
161 171
 	// Too many options checked!
162
-	if (count($_REQUEST['options']) > $row['max_votes'])
163
-		fatal_lang_error('poll_too_many_votes', false, array($row['max_votes']));
172
+	if (count($_REQUEST['options']) > $row['max_votes']) {
173
+			fatal_lang_error('poll_too_many_votes', false, array($row['max_votes']));
174
+	}
164 175
 
165 176
 	$pollOptions = array();
166 177
 	$inserts = array();
@@ -250,24 +261,30 @@  discard block
 block discarded – undo
250 261
 	list ($memberID, $pollID, $voting_locked) = $smcFunc['db_fetch_row']($request);
251 262
 
252 263
 	// If the user _can_ modify the poll....
253
-	if (!allowedTo('poll_lock_any'))
254
-		isAllowedTo('poll_lock_' . ($user_info['id'] == $memberID ? 'own' : 'any'));
264
+	if (!allowedTo('poll_lock_any')) {
265
+			isAllowedTo('poll_lock_' . ($user_info['id'] == $memberID ? 'own' : 'any'));
266
+	}
255 267
 
256 268
 	// It's been locked by a non-moderator.
257
-	if ($voting_locked == '1')
258
-		$voting_locked = '0';
269
+	if ($voting_locked == '1') {
270
+			$voting_locked = '0';
271
+	}
259 272
 	// Locked by a moderator, and this is a moderator.
260
-	elseif ($voting_locked == '2' && allowedTo('moderate_board'))
261
-		$voting_locked = '0';
273
+	elseif ($voting_locked == '2' && allowedTo('moderate_board')) {
274
+			$voting_locked = '0';
275
+	}
262 276
 	// Sorry, a moderator locked it.
263
-	elseif ($voting_locked == '2' && !allowedTo('moderate_board'))
264
-		fatal_lang_error('locked_by_admin', 'user');
277
+	elseif ($voting_locked == '2' && !allowedTo('moderate_board')) {
278
+			fatal_lang_error('locked_by_admin', 'user');
279
+	}
265 280
 	// A moderator *is* locking it.
266
-	elseif ($voting_locked == '0' && allowedTo('moderate_board'))
267
-		$voting_locked = '2';
281
+	elseif ($voting_locked == '0' && allowedTo('moderate_board')) {
282
+			$voting_locked = '2';
283
+	}
268 284
 	// Well, it's gonna be locked one way or another otherwise...
269
-	else
270
-		$voting_locked = '1';
285
+	else {
286
+			$voting_locked = '1';
287
+	}
271 288
 
272 289
 	// Lock!  *Poof* - no one can vote.
273 290
 	$smcFunc['db_query']('', '
@@ -302,8 +319,9 @@  discard block
 block discarded – undo
302 319
 {
303 320
 	global $txt, $user_info, $context, $topic, $board, $smcFunc, $sourcedir, $scripturl;
304 321
 
305
-	if (empty($topic))
306
-		fatal_lang_error('no_access', false);
322
+	if (empty($topic)) {
323
+			fatal_lang_error('no_access', false);
324
+	}
307 325
 
308 326
 	loadLanguage('Post');
309 327
 	loadTemplate('Poll');
@@ -327,24 +345,28 @@  discard block
 block discarded – undo
327 345
 	);
328 346
 
329 347
 	// Assume the the topic exists, right?
330
-	if ($smcFunc['db_num_rows']($request) == 0)
331
-		fatal_lang_error('no_board');
348
+	if ($smcFunc['db_num_rows']($request) == 0) {
349
+			fatal_lang_error('no_board');
350
+	}
332 351
 	// Get the poll information.
333 352
 	$pollinfo = $smcFunc['db_fetch_assoc']($request);
334 353
 	$smcFunc['db_free_result']($request);
335 354
 
336 355
 	// If we are adding a new poll - make sure that there isn't already a poll there.
337
-	if (!$context['is_edit'] && !empty($pollinfo['id_poll']))
338
-		fatal_lang_error('poll_already_exists');
356
+	if (!$context['is_edit'] && !empty($pollinfo['id_poll'])) {
357
+			fatal_lang_error('poll_already_exists');
358
+	}
339 359
 	// Otherwise, if we're editing it, it does exist I assume?
340
-	elseif ($context['is_edit'] && empty($pollinfo['id_poll']))
341
-		fatal_lang_error('poll_not_found');
360
+	elseif ($context['is_edit'] && empty($pollinfo['id_poll'])) {
361
+			fatal_lang_error('poll_not_found');
362
+	}
342 363
 
343 364
 	// Can you do this?
344
-	if ($context['is_edit'] && !allowedTo('poll_edit_any'))
345
-		isAllowedTo('poll_edit_' . ($user_info['id'] == $pollinfo['id_member_started'] || ($pollinfo['poll_starter'] != 0 && $user_info['id'] == $pollinfo['poll_starter']) ? 'own' : 'any'));
346
-	elseif (!$context['is_edit'] && !allowedTo('poll_add_any'))
347
-		isAllowedTo('poll_add_' . ($user_info['id'] == $pollinfo['id_member_started'] ? 'own' : 'any'));
365
+	if ($context['is_edit'] && !allowedTo('poll_edit_any')) {
366
+			isAllowedTo('poll_edit_' . ($user_info['id'] == $pollinfo['id_member_started'] || ($pollinfo['poll_starter'] != 0 && $user_info['id'] == $pollinfo['poll_starter']) ? 'own' : 'any'));
367
+	} elseif (!$context['is_edit'] && !allowedTo('poll_add_any')) {
368
+			isAllowedTo('poll_add_' . ($user_info['id'] == $pollinfo['id_member_started'] ? 'own' : 'any'));
369
+	}
348 370
 	$context['can_moderate_poll'] = isset($_REQUEST['add']) ? true : allowedTo('poll_edit_' . ($user_info['id'] == $pollinfo['id_member_started'] || ($pollinfo['poll_starter'] != 0 && $user_info['id'] == $pollinfo['poll_starter']) ? 'own' : 'any'));
349 371
 
350 372
 	// Do we enable guest voting?
@@ -386,12 +408,14 @@  discard block
 block discarded – undo
386 408
 			while ($row = $smcFunc['db_fetch_assoc']($request))
387 409
 			{
388 410
 				// Get the highest id so we can add more without reusing.
389
-				if ($row['id_choice'] >= $last_id)
390
-					$last_id = $row['id_choice'] + 1;
411
+				if ($row['id_choice'] >= $last_id) {
412
+									$last_id = $row['id_choice'] + 1;
413
+				}
391 414
 
392 415
 				// They cleared this by either omitting it or emptying it.
393
-				if (!isset($_POST['options'][$row['id_choice']]) || $_POST['options'][$row['id_choice']] == '')
394
-					continue;
416
+				if (!isset($_POST['options'][$row['id_choice']]) || $_POST['options'][$row['id_choice']] == '') {
417
+									continue;
418
+				}
395 419
 
396 420
 				censorText($row['label']);
397 421
 
@@ -409,9 +433,10 @@  discard block
 block discarded – undo
409 433
 
410 434
 		// Work out how many options we have, so we get the 'is_last' field right...
411 435
 		$totalPostOptions = 0;
412
-		foreach ($_POST['options'] as $id => $label)
413
-			if ($label != '')
436
+		foreach ($_POST['options'] as $id => $label) {
437
+					if ($label != '')
414 438
 				$totalPostOptions++;
439
+		}
415 440
 
416 441
 		$count = 1;
417 442
 		// If an option exists, update it.  If it is new, add it - but don't reuse ids!
@@ -420,30 +445,32 @@  discard block
 block discarded – undo
420 445
 			$label = $smcFunc['htmlspecialchars']($label);
421 446
 			censorText($label);
422 447
 
423
-			if (isset($context['choices'][$id]))
424
-				$context['choices'][$id]['label'] = $label;
425
-			elseif ($label != '')
426
-				$context['choices'][] = array(
448
+			if (isset($context['choices'][$id])) {
449
+							$context['choices'][$id]['label'] = $label;
450
+			} elseif ($label != '') {
451
+							$context['choices'][] = array(
427 452
 					'id' => $last_id++,
428 453
 					'number' => $number++,
429 454
 					'label' => $label,
430 455
 					'votes' => -1,
431 456
 					'is_last' => $count++ == $totalPostOptions && $totalPostOptions > 1 ? true : false,
432 457
 				);
458
+			}
433 459
 		}
434 460
 
435 461
 		// Make sure we have two choices for sure!
436 462
 		if ($totalPostOptions < 2)
437 463
 		{
438 464
 			// Need two?
439
-			if ($totalPostOptions == 0)
440
-				$context['choices'][] = array(
465
+			if ($totalPostOptions == 0) {
466
+							$context['choices'][] = array(
441 467
 					'id' => $last_id++,
442 468
 					'number' => $number++,
443 469
 					'label' => '',
444 470
 					'votes' => -1,
445 471
 					'is_last' => false
446 472
 				);
473
+			}
447 474
 			$poll_errors[] = 'poll_few';
448 475
 		}
449 476
 
@@ -458,12 +485,14 @@  discard block
 block discarded – undo
458 485
 
459 486
 		$context['last_choice_id'] = $last_id;
460 487
 
461
-		if ($context['can_moderate_poll'])
462
-			$context['poll']['expiration'] = $_POST['poll_expire'];
488
+		if ($context['can_moderate_poll']) {
489
+					$context['poll']['expiration'] = $_POST['poll_expire'];
490
+		}
463 491
 
464 492
 		// Check the question/option count for errors.
465
-		if (trim($_POST['question']) == '' && empty($context['poll_error']))
466
-			$poll_errors[] = 'no_question';
493
+		if (trim($_POST['question']) == '' && empty($context['poll_error'])) {
494
+					$poll_errors[] = 'no_question';
495
+		}
467 496
 
468 497
 		// No check is needed, since nothing is really posted.
469 498
 		checkSubmitOnce('free');
@@ -480,8 +509,7 @@  discard block
 block discarded – undo
480 509
 				$context['poll_error']['messages'][] = $txt['error_' . $poll_error];
481 510
 			}
482 511
 		}
483
-	}
484
-	else
512
+	} else
485 513
 	{
486 514
 		// Basic theme info...
487 515
 		$context['poll'] = array(
@@ -596,18 +624,22 @@  discard block
 block discarded – undo
596 624
 	global $user_info, $smcFunc, $sourcedir;
597 625
 
598 626
 	// Sneaking off, are we?
599
-	if (empty($_POST))
600
-		redirectexit('action=editpoll;topic=' . $topic . '.0');
627
+	if (empty($_POST)) {
628
+			redirectexit('action=editpoll;topic=' . $topic . '.0');
629
+	}
601 630
 
602
-	if (checkSession('post', '', false) != '')
603
-		$poll_errors[] = 'session_timeout';
631
+	if (checkSession('post', '', false) != '') {
632
+			$poll_errors[] = 'session_timeout';
633
+	}
604 634
 
605
-	if (isset($_POST['preview']))
606
-		return EditPoll();
635
+	if (isset($_POST['preview'])) {
636
+			return EditPoll();
637
+	}
607 638
 
608 639
 	// HACKERS (!!) can't edit :P.
609
-	if (empty($topic))
610
-		fatal_lang_error('no_access', false);
640
+	if (empty($topic)) {
641
+			fatal_lang_error('no_access', false);
642
+	}
611 643
 
612 644
 	// Is this a new poll, or editing an existing?
613 645
 	$isEdit = isset($_REQUEST['add']) ? 0 : 1;
@@ -623,23 +655,27 @@  discard block
 block discarded – undo
623 655
 			'current_topic' => $topic,
624 656
 		)
625 657
 	);
626
-	if ($smcFunc['db_num_rows']($request) == 0)
627
-		fatal_lang_error('no_board');
658
+	if ($smcFunc['db_num_rows']($request) == 0) {
659
+			fatal_lang_error('no_board');
660
+	}
628 661
 	$bcinfo = $smcFunc['db_fetch_assoc']($request);
629 662
 	$smcFunc['db_free_result']($request);
630 663
 
631 664
 	// Check their adding/editing is valid.
632
-	if (!$isEdit && !empty($bcinfo['id_poll']))
633
-		fatal_lang_error('poll_already_exists');
665
+	if (!$isEdit && !empty($bcinfo['id_poll'])) {
666
+			fatal_lang_error('poll_already_exists');
667
+	}
634 668
 	// Are we editing a poll which doesn't exist?
635
-	elseif ($isEdit && empty($bcinfo['id_poll']))
636
-		fatal_lang_error('poll_not_found');
669
+	elseif ($isEdit && empty($bcinfo['id_poll'])) {
670
+			fatal_lang_error('poll_not_found');
671
+	}
637 672
 
638 673
 	// Check if they have the power to add or edit the poll.
639
-	if ($isEdit && !allowedTo('poll_edit_any'))
640
-		isAllowedTo('poll_edit_' . ($user_info['id'] == $bcinfo['id_member_started'] || ($bcinfo['poll_starter'] != 0 && $user_info['id'] == $bcinfo['poll_starter']) ? 'own' : 'any'));
641
-	elseif (!$isEdit && !allowedTo('poll_add_any'))
642
-		isAllowedTo('poll_add_' . ($user_info['id'] == $bcinfo['id_member_started'] ? 'own' : 'any'));
674
+	if ($isEdit && !allowedTo('poll_edit_any')) {
675
+			isAllowedTo('poll_edit_' . ($user_info['id'] == $bcinfo['id_member_started'] || ($bcinfo['poll_starter'] != 0 && $user_info['id'] == $bcinfo['poll_starter']) ? 'own' : 'any'));
676
+	} elseif (!$isEdit && !allowedTo('poll_add_any')) {
677
+			isAllowedTo('poll_add_' . ($user_info['id'] == $bcinfo['id_member_started'] ? 'own' : 'any'));
678
+	}
643 679
 
644 680
 	$optionCount = 0;
645 681
 	$idCount = 0;
@@ -652,14 +688,16 @@  discard block
 block discarded – undo
652 688
 			$idCount = max($idCount, $k);
653 689
 		}
654 690
 	}
655
-	if ($optionCount < 2)
656
-		$poll_errors[] = 'poll_few';
657
-	elseif ($optionCount > 256 || $idCount > 255)
658
-		$poll_errors[] = 'poll_many';
691
+	if ($optionCount < 2) {
692
+			$poll_errors[] = 'poll_few';
693
+	} elseif ($optionCount > 256 || $idCount > 255) {
694
+			$poll_errors[] = 'poll_many';
695
+	}
659 696
 
660 697
 	// Also - ensure they are not removing the question.
661
-	if (trim($_POST['question']) == '')
662
-		$poll_errors[] = 'no_question';
698
+	if (trim($_POST['question']) == '') {
699
+			$poll_errors[] = 'no_question';
700
+	}
663 701
 
664 702
 	// Got any errors to report?
665 703
 	if (!empty($poll_errors))
@@ -695,8 +733,9 @@  discard block
 block discarded – undo
695 733
 	{
696 734
 		require_once($sourcedir . '/Subs-Members.php');
697 735
 		$allowedGroups = groupsAllowedTo('poll_vote', $board);
698
-		if (!in_array(-1, $allowedGroups['allowed']))
699
-			$_POST['poll_guest_vote'] = 0;
736
+		if (!in_array(-1, $allowedGroups['allowed'])) {
737
+					$_POST['poll_guest_vote'] = 0;
738
+		}
700 739
 	}
701 740
 
702 741
 	// Ensure that the number options allowed makes sense, and the expiration date is valid.
@@ -704,17 +743,19 @@  discard block
 block discarded – undo
704 743
 	{
705 744
 		$_POST['poll_expire'] = $_POST['poll_expire'] > 9999 ? 9999 : ($_POST['poll_expire'] < 0 ? 0 : $_POST['poll_expire']);
706 745
 
707
-		if (empty($_POST['poll_expire']) && $_POST['poll_hide'] == 2)
708
-			$_POST['poll_hide'] = 1;
709
-		elseif (!$isEdit || $_POST['poll_expire'] != ceil($bcinfo['expire_time'] <= time() ? -1 : ($bcinfo['expire_time'] - time()) / (3600 * 24)))
710
-			$_POST['poll_expire'] = empty($_POST['poll_expire']) ? '0' : time() + $_POST['poll_expire'] * 3600 * 24;
711
-		else
712
-			$_POST['poll_expire'] = $bcinfo['expire_time'];
746
+		if (empty($_POST['poll_expire']) && $_POST['poll_hide'] == 2) {
747
+					$_POST['poll_hide'] = 1;
748
+		} elseif (!$isEdit || $_POST['poll_expire'] != ceil($bcinfo['expire_time'] <= time() ? -1 : ($bcinfo['expire_time'] - time()) / (3600 * 24))) {
749
+					$_POST['poll_expire'] = empty($_POST['poll_expire']) ? '0' : time() + $_POST['poll_expire'] * 3600 * 24;
750
+		} else {
751
+					$_POST['poll_expire'] = $bcinfo['expire_time'];
752
+		}
713 753
 
714
-		if (empty($_POST['poll_max_votes']) || $_POST['poll_max_votes'] <= 0)
715
-			$_POST['poll_max_votes'] = 1;
716
-		else
717
-			$_POST['poll_max_votes'] = (int) $_POST['poll_max_votes'];
754
+		if (empty($_POST['poll_max_votes']) || $_POST['poll_max_votes'] <= 0) {
755
+					$_POST['poll_max_votes'] = 1;
756
+		} else {
757
+					$_POST['poll_max_votes'] = (int) $_POST['poll_max_votes'];
758
+		}
718 759
 	}
719 760
 
720 761
 	// If we're editing, let's commit the changes.
@@ -781,8 +822,9 @@  discard block
 block discarded – undo
781 822
 		)
782 823
 	);
783 824
 	$choices = array();
784
-	while ($row = $smcFunc['db_fetch_assoc']($request))
785
-		$choices[] = $row['id_choice'];
825
+	while ($row = $smcFunc['db_fetch_assoc']($request)) {
826
+			$choices[] = $row['id_choice'];
827
+	}
786 828
 	$smcFunc['db_free_result']($request);
787 829
 
788 830
 	$delete_options = array();
@@ -795,8 +837,9 @@  discard block
 block discarded – undo
795 837
 		if (trim($option) == '')
796 838
 		{
797 839
 			// They want it deleted.  Bye.
798
-			if (in_array($k, $choices))
799
-				$delete_options[] = $k;
840
+			if (in_array($k, $choices)) {
841
+							$delete_options[] = $k;
842
+			}
800 843
 
801 844
 			// Skip the rest...
802 845
 			continue;
@@ -806,8 +849,8 @@  discard block
 block discarded – undo
806 849
 		$option = $smcFunc['htmlspecialchars']($option);
807 850
 
808 851
 		// If it's already there, update it.  If it's not... add it.
809
-		if (in_array($k, $choices))
810
-			$smcFunc['db_query']('', '
852
+		if (in_array($k, $choices)) {
853
+					$smcFunc['db_query']('', '
811 854
 				UPDATE {db_prefix}poll_choices
812 855
 				SET label = {string:option_name}
813 856
 				WHERE id_poll = {int:id_poll}
@@ -818,8 +861,8 @@  discard block
 block discarded – undo
818 861
 					'option_name' => $option,
819 862
 				)
820 863
 			);
821
-		else
822
-			$smcFunc['db_insert']('',
864
+		} else {
865
+					$smcFunc['db_insert']('',
823 866
 				'{db_prefix}poll_choices',
824 867
 				array(
825 868
 					'id_poll' => 'int', 'id_choice' => 'int', 'label' => 'string-255', 'votes' => 'int',
@@ -829,6 +872,7 @@  discard block
 block discarded – undo
829 872
 				),
830 873
 				array()
831 874
 			);
875
+		}
832 876
 	}
833 877
 
834 878
 	// I'm sorry, but... well, no one was choosing you.  Poor options, I'll put you out of your misery.
@@ -894,13 +938,11 @@  discard block
 block discarded – undo
894 938
 	{
895 939
 		// Added a poll
896 940
 		logAction('add_poll', array('topic' => $topic));
897
-	}
898
-	elseif (isset($_REQUEST['deletevotes']))
941
+	} elseif (isset($_REQUEST['deletevotes']))
899 942
 	{
900 943
 		// Reset votes
901 944
 		logAction('reset_poll', array('topic' => $topic));
902
-	}
903
-	else
945
+	} else
904 946
 	{
905 947
 		// Something else
906 948
 		logAction('editpoll', array('topic' => $topic));
@@ -923,8 +965,9 @@  discard block
 block discarded – undo
923 965
 	global $topic, $user_info, $smcFunc;
924 966
 
925 967
 	// Make sure the topic is not empty.
926
-	if (empty($topic))
927
-		fatal_lang_error('no_access', false);
968
+	if (empty($topic)) {
969
+			fatal_lang_error('no_access', false);
970
+	}
928 971
 
929 972
 	// Verify the session.
930 973
 	checkSession('get');
@@ -942,8 +985,9 @@  discard block
 block discarded – undo
942 985
 				'current_topic' => $topic,
943 986
 			)
944 987
 		);
945
-		if ($smcFunc['db_num_rows']($request) == 0)
946
-			fatal_lang_error('no_access', false);
988
+		if ($smcFunc['db_num_rows']($request) == 0) {
989
+					fatal_lang_error('no_access', false);
990
+		}
947 991
 		list ($topicStarter, $pollStarter) = $smcFunc['db_fetch_row']($request);
948 992
 		$smcFunc['db_free_result']($request);
949 993
 
Please login to merge, or discard this patch.