diff options
Diffstat (limited to 'vendor/symfony/string')
21 files changed, 6416 insertions, 0 deletions
diff --git a/vendor/symfony/string/AbstractString.php b/vendor/symfony/string/AbstractString.php new file mode 100644 index 0000000..253d2dc --- /dev/null +++ b/vendor/symfony/string/AbstractString.php | |||
@@ -0,0 +1,702 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\String; | ||
13 | |||
14 | use Symfony\Component\String\Exception\ExceptionInterface; | ||
15 | use Symfony\Component\String\Exception\InvalidArgumentException; | ||
16 | use Symfony\Component\String\Exception\RuntimeException; | ||
17 | |||
18 | /** | ||
19 | * Represents a string of abstract characters. | ||
20 | * | ||
21 | * Unicode defines 3 types of "characters" (bytes, code points and grapheme clusters). | ||
22 | * This class is the abstract type to use as a type-hint when the logic you want to | ||
23 | * implement doesn't care about the exact variant it deals with. | ||
24 | * | ||
25 | * @author Nicolas Grekas <p@tchwork.com> | ||
26 | * @author Hugo Hamon <hugohamon@neuf.fr> | ||
27 | * | ||
28 | * @throws ExceptionInterface | ||
29 | */ | ||
30 | abstract class AbstractString implements \Stringable, \JsonSerializable | ||
31 | { | ||
32 | public const PREG_PATTERN_ORDER = \PREG_PATTERN_ORDER; | ||
33 | public const PREG_SET_ORDER = \PREG_SET_ORDER; | ||
34 | public const PREG_OFFSET_CAPTURE = \PREG_OFFSET_CAPTURE; | ||
35 | public const PREG_UNMATCHED_AS_NULL = \PREG_UNMATCHED_AS_NULL; | ||
36 | |||
37 | public const PREG_SPLIT = 0; | ||
38 | public const PREG_SPLIT_NO_EMPTY = \PREG_SPLIT_NO_EMPTY; | ||
39 | public const PREG_SPLIT_DELIM_CAPTURE = \PREG_SPLIT_DELIM_CAPTURE; | ||
40 | public const PREG_SPLIT_OFFSET_CAPTURE = \PREG_SPLIT_OFFSET_CAPTURE; | ||
41 | |||
42 | protected string $string = ''; | ||
43 | protected ?bool $ignoreCase = false; | ||
44 | |||
45 | abstract public function __construct(string $string = ''); | ||
46 | |||
47 | /** | ||
48 | * Unwraps instances of AbstractString back to strings. | ||
49 | * | ||
50 | * @return string[]|array | ||
51 | */ | ||
52 | public static function unwrap(array $values): array | ||
53 | { | ||
54 | foreach ($values as $k => $v) { | ||
55 | if ($v instanceof self) { | ||
56 | $values[$k] = $v->__toString(); | ||
57 | } elseif (\is_array($v) && $values[$k] !== $v = static::unwrap($v)) { | ||
58 | $values[$k] = $v; | ||
59 | } | ||
60 | } | ||
61 | |||
62 | return $values; | ||
63 | } | ||
64 | |||
65 | /** | ||
66 | * Wraps (and normalizes) strings in instances of AbstractString. | ||
67 | * | ||
68 | * @return static[]|array | ||
69 | */ | ||
70 | public static function wrap(array $values): array | ||
71 | { | ||
72 | $i = 0; | ||
73 | $keys = null; | ||
74 | |||
75 | foreach ($values as $k => $v) { | ||
76 | if (\is_string($k) && '' !== $k && $k !== $j = (string) new static($k)) { | ||
77 | $keys ??= array_keys($values); | ||
78 | $keys[$i] = $j; | ||
79 | } | ||
80 | |||
81 | if (\is_string($v)) { | ||
82 | $values[$k] = new static($v); | ||
83 | } elseif (\is_array($v) && $values[$k] !== $v = static::wrap($v)) { | ||
84 | $values[$k] = $v; | ||
85 | } | ||
86 | |||
87 | ++$i; | ||
88 | } | ||
89 | |||
90 | return null !== $keys ? array_combine($keys, $values) : $values; | ||
91 | } | ||
92 | |||
93 | /** | ||
94 | * @param string|string[] $needle | ||
95 | */ | ||
96 | public function after(string|iterable $needle, bool $includeNeedle = false, int $offset = 0): static | ||
97 | { | ||
98 | $str = clone $this; | ||
99 | $i = \PHP_INT_MAX; | ||
100 | |||
101 | if (\is_string($needle)) { | ||
102 | $needle = [$needle]; | ||
103 | } | ||
104 | |||
105 | foreach ($needle as $n) { | ||
106 | $n = (string) $n; | ||
107 | $j = $this->indexOf($n, $offset); | ||
108 | |||
109 | if (null !== $j && $j < $i) { | ||
110 | $i = $j; | ||
111 | $str->string = $n; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | if (\PHP_INT_MAX === $i) { | ||
116 | return $str; | ||
117 | } | ||
118 | |||
119 | if (!$includeNeedle) { | ||
120 | $i += $str->length(); | ||
121 | } | ||
122 | |||
123 | return $this->slice($i); | ||
124 | } | ||
125 | |||
126 | /** | ||
127 | * @param string|string[] $needle | ||
128 | */ | ||
129 | public function afterLast(string|iterable $needle, bool $includeNeedle = false, int $offset = 0): static | ||
130 | { | ||
131 | $str = clone $this; | ||
132 | $i = null; | ||
133 | |||
134 | if (\is_string($needle)) { | ||
135 | $needle = [$needle]; | ||
136 | } | ||
137 | |||
138 | foreach ($needle as $n) { | ||
139 | $n = (string) $n; | ||
140 | $j = $this->indexOfLast($n, $offset); | ||
141 | |||
142 | if (null !== $j && $j >= $i) { | ||
143 | $i = $offset = $j; | ||
144 | $str->string = $n; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | if (null === $i) { | ||
149 | return $str; | ||
150 | } | ||
151 | |||
152 | if (!$includeNeedle) { | ||
153 | $i += $str->length(); | ||
154 | } | ||
155 | |||
156 | return $this->slice($i); | ||
157 | } | ||
158 | |||
159 | abstract public function append(string ...$suffix): static; | ||
160 | |||
161 | /** | ||
162 | * @param string|string[] $needle | ||
163 | */ | ||
164 | public function before(string|iterable $needle, bool $includeNeedle = false, int $offset = 0): static | ||
165 | { | ||
166 | $str = clone $this; | ||
167 | $i = \PHP_INT_MAX; | ||
168 | |||
169 | if (\is_string($needle)) { | ||
170 | $needle = [$needle]; | ||
171 | } | ||
172 | |||
173 | foreach ($needle as $n) { | ||
174 | $n = (string) $n; | ||
175 | $j = $this->indexOf($n, $offset); | ||
176 | |||
177 | if (null !== $j && $j < $i) { | ||
178 | $i = $j; | ||
179 | $str->string = $n; | ||
180 | } | ||
181 | } | ||
182 | |||
183 | if (\PHP_INT_MAX === $i) { | ||
184 | return $str; | ||
185 | } | ||
186 | |||
187 | if ($includeNeedle) { | ||
188 | $i += $str->length(); | ||
189 | } | ||
190 | |||
191 | return $this->slice(0, $i); | ||
192 | } | ||
193 | |||
194 | /** | ||
195 | * @param string|string[] $needle | ||
196 | */ | ||
197 | public function beforeLast(string|iterable $needle, bool $includeNeedle = false, int $offset = 0): static | ||
198 | { | ||
199 | $str = clone $this; | ||
200 | $i = null; | ||
201 | |||
202 | if (\is_string($needle)) { | ||
203 | $needle = [$needle]; | ||
204 | } | ||
205 | |||
206 | foreach ($needle as $n) { | ||
207 | $n = (string) $n; | ||
208 | $j = $this->indexOfLast($n, $offset); | ||
209 | |||
210 | if (null !== $j && $j >= $i) { | ||
211 | $i = $offset = $j; | ||
212 | $str->string = $n; | ||
213 | } | ||
214 | } | ||
215 | |||
216 | if (null === $i) { | ||
217 | return $str; | ||
218 | } | ||
219 | |||
220 | if ($includeNeedle) { | ||
221 | $i += $str->length(); | ||
222 | } | ||
223 | |||
224 | return $this->slice(0, $i); | ||
225 | } | ||
226 | |||
227 | /** | ||
228 | * @return int[] | ||
229 | */ | ||
230 | public function bytesAt(int $offset): array | ||
231 | { | ||
232 | $str = $this->slice($offset, 1); | ||
233 | |||
234 | return '' === $str->string ? [] : array_values(unpack('C*', $str->string)); | ||
235 | } | ||
236 | |||
237 | abstract public function camel(): static; | ||
238 | |||
239 | /** | ||
240 | * @return static[] | ||
241 | */ | ||
242 | abstract public function chunk(int $length = 1): array; | ||
243 | |||
244 | public function collapseWhitespace(): static | ||
245 | { | ||
246 | $str = clone $this; | ||
247 | $str->string = trim(preg_replace("/(?:[ \n\r\t\x0C]{2,}+|[\n\r\t\x0C])/", ' ', $str->string), " \n\r\t\x0C"); | ||
248 | |||
249 | return $str; | ||
250 | } | ||
251 | |||
252 | /** | ||
253 | * @param string|string[] $needle | ||
254 | */ | ||
255 | public function containsAny(string|iterable $needle): bool | ||
256 | { | ||
257 | return null !== $this->indexOf($needle); | ||
258 | } | ||
259 | |||
260 | /** | ||
261 | * @param string|string[] $suffix | ||
262 | */ | ||
263 | public function endsWith(string|iterable $suffix): bool | ||
264 | { | ||
265 | if (\is_string($suffix)) { | ||
266 | throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class)); | ||
267 | } | ||
268 | |||
269 | foreach ($suffix as $s) { | ||
270 | if ($this->endsWith((string) $s)) { | ||
271 | return true; | ||
272 | } | ||
273 | } | ||
274 | |||
275 | return false; | ||
276 | } | ||
277 | |||
278 | public function ensureEnd(string $suffix): static | ||
279 | { | ||
280 | if (!$this->endsWith($suffix)) { | ||
281 | return $this->append($suffix); | ||
282 | } | ||
283 | |||
284 | $suffix = preg_quote($suffix); | ||
285 | $regex = '{('.$suffix.')(?:'.$suffix.')++$}D'; | ||
286 | |||
287 | return $this->replaceMatches($regex.($this->ignoreCase ? 'i' : ''), '$1'); | ||
288 | } | ||
289 | |||
290 | public function ensureStart(string $prefix): static | ||
291 | { | ||
292 | $prefix = new static($prefix); | ||
293 | |||
294 | if (!$this->startsWith($prefix)) { | ||
295 | return $this->prepend($prefix); | ||
296 | } | ||
297 | |||
298 | $str = clone $this; | ||
299 | $i = $prefixLen = $prefix->length(); | ||
300 | |||
301 | while ($this->indexOf($prefix, $i) === $i) { | ||
302 | $str = $str->slice($prefixLen); | ||
303 | $i += $prefixLen; | ||
304 | } | ||
305 | |||
306 | return $str; | ||
307 | } | ||
308 | |||
309 | /** | ||
310 | * @param string|string[] $string | ||
311 | */ | ||
312 | public function equalsTo(string|iterable $string): bool | ||
313 | { | ||
314 | if (\is_string($string)) { | ||
315 | throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class)); | ||
316 | } | ||
317 | |||
318 | foreach ($string as $s) { | ||
319 | if ($this->equalsTo((string) $s)) { | ||
320 | return true; | ||
321 | } | ||
322 | } | ||
323 | |||
324 | return false; | ||
325 | } | ||
326 | |||
327 | abstract public function folded(): static; | ||
328 | |||
329 | public function ignoreCase(): static | ||
330 | { | ||
331 | $str = clone $this; | ||
332 | $str->ignoreCase = true; | ||
333 | |||
334 | return $str; | ||
335 | } | ||
336 | |||
337 | /** | ||
338 | * @param string|string[] $needle | ||
339 | */ | ||
340 | public function indexOf(string|iterable $needle, int $offset = 0): ?int | ||
341 | { | ||
342 | if (\is_string($needle)) { | ||
343 | throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class)); | ||
344 | } | ||
345 | |||
346 | $i = \PHP_INT_MAX; | ||
347 | |||
348 | foreach ($needle as $n) { | ||
349 | $j = $this->indexOf((string) $n, $offset); | ||
350 | |||
351 | if (null !== $j && $j < $i) { | ||
352 | $i = $j; | ||
353 | } | ||
354 | } | ||
355 | |||
356 | return \PHP_INT_MAX === $i ? null : $i; | ||
357 | } | ||
358 | |||
359 | /** | ||
360 | * @param string|string[] $needle | ||
361 | */ | ||
362 | public function indexOfLast(string|iterable $needle, int $offset = 0): ?int | ||
363 | { | ||
364 | if (\is_string($needle)) { | ||
365 | throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class)); | ||
366 | } | ||
367 | |||
368 | $i = null; | ||
369 | |||
370 | foreach ($needle as $n) { | ||
371 | $j = $this->indexOfLast((string) $n, $offset); | ||
372 | |||
373 | if (null !== $j && $j >= $i) { | ||
374 | $i = $offset = $j; | ||
375 | } | ||
376 | } | ||
377 | |||
378 | return $i; | ||
379 | } | ||
380 | |||
381 | public function isEmpty(): bool | ||
382 | { | ||
383 | return '' === $this->string; | ||
384 | } | ||
385 | |||
386 | abstract public function join(array $strings, ?string $lastGlue = null): static; | ||
387 | |||
388 | public function jsonSerialize(): string | ||
389 | { | ||
390 | return $this->string; | ||
391 | } | ||
392 | |||
393 | abstract public function length(): int; | ||
394 | |||
395 | abstract public function lower(): static; | ||
396 | |||
397 | /** | ||
398 | * Matches the string using a regular expression. | ||
399 | * | ||
400 | * Pass PREG_PATTERN_ORDER or PREG_SET_ORDER as $flags to get all occurrences matching the regular expression. | ||
401 | * | ||
402 | * @return array All matches in a multi-dimensional array ordered according to flags | ||
403 | */ | ||
404 | abstract public function match(string $regexp, int $flags = 0, int $offset = 0): array; | ||
405 | |||
406 | abstract public function padBoth(int $length, string $padStr = ' '): static; | ||
407 | |||
408 | abstract public function padEnd(int $length, string $padStr = ' '): static; | ||
409 | |||
410 | abstract public function padStart(int $length, string $padStr = ' '): static; | ||
411 | |||
412 | abstract public function prepend(string ...$prefix): static; | ||
413 | |||
414 | public function repeat(int $multiplier): static | ||
415 | { | ||
416 | if (0 > $multiplier) { | ||
417 | throw new InvalidArgumentException(sprintf('Multiplier must be positive, %d given.', $multiplier)); | ||
418 | } | ||
419 | |||
420 | $str = clone $this; | ||
421 | $str->string = str_repeat($str->string, $multiplier); | ||
422 | |||
423 | return $str; | ||
424 | } | ||
425 | |||
426 | abstract public function replace(string $from, string $to): static; | ||
427 | |||
428 | abstract public function replaceMatches(string $fromRegexp, string|callable $to): static; | ||
429 | |||
430 | abstract public function reverse(): static; | ||
431 | |||
432 | abstract public function slice(int $start = 0, ?int $length = null): static; | ||
433 | |||
434 | abstract public function snake(): static; | ||
435 | |||
436 | abstract public function splice(string $replacement, int $start = 0, ?int $length = null): static; | ||
437 | |||
438 | /** | ||
439 | * @return static[] | ||
440 | */ | ||
441 | public function split(string $delimiter, ?int $limit = null, ?int $flags = null): array | ||
442 | { | ||
443 | if (null === $flags) { | ||
444 | throw new \TypeError('Split behavior when $flags is null must be implemented by child classes.'); | ||
445 | } | ||
446 | |||
447 | if ($this->ignoreCase) { | ||
448 | $delimiter .= 'i'; | ||
449 | } | ||
450 | |||
451 | set_error_handler(static fn ($t, $m) => throw new InvalidArgumentException($m)); | ||
452 | |||
453 | try { | ||
454 | if (false === $chunks = preg_split($delimiter, $this->string, $limit, $flags)) { | ||
455 | throw new RuntimeException('Splitting failed with error: '.preg_last_error_msg()); | ||
456 | } | ||
457 | } finally { | ||
458 | restore_error_handler(); | ||
459 | } | ||
460 | |||
461 | $str = clone $this; | ||
462 | |||
463 | if (self::PREG_SPLIT_OFFSET_CAPTURE & $flags) { | ||
464 | foreach ($chunks as &$chunk) { | ||
465 | $str->string = $chunk[0]; | ||
466 | $chunk[0] = clone $str; | ||
467 | } | ||
468 | } else { | ||
469 | foreach ($chunks as &$chunk) { | ||
470 | $str->string = $chunk; | ||
471 | $chunk = clone $str; | ||
472 | } | ||
473 | } | ||
474 | |||
475 | return $chunks; | ||
476 | } | ||
477 | |||
478 | /** | ||
479 | * @param string|string[] $prefix | ||
480 | */ | ||
481 | public function startsWith(string|iterable $prefix): bool | ||
482 | { | ||
483 | if (\is_string($prefix)) { | ||
484 | throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class)); | ||
485 | } | ||
486 | |||
487 | foreach ($prefix as $prefix) { | ||
488 | if ($this->startsWith((string) $prefix)) { | ||
489 | return true; | ||
490 | } | ||
491 | } | ||
492 | |||
493 | return false; | ||
494 | } | ||
495 | |||
496 | abstract public function title(bool $allWords = false): static; | ||
497 | |||
498 | public function toByteString(?string $toEncoding = null): ByteString | ||
499 | { | ||
500 | $b = new ByteString(); | ||
501 | |||
502 | $toEncoding = \in_array($toEncoding, ['utf8', 'utf-8', 'UTF8'], true) ? 'UTF-8' : $toEncoding; | ||
503 | |||
504 | if (null === $toEncoding || $toEncoding === $fromEncoding = $this instanceof AbstractUnicodeString || preg_match('//u', $b->string) ? 'UTF-8' : 'Windows-1252') { | ||
505 | $b->string = $this->string; | ||
506 | |||
507 | return $b; | ||
508 | } | ||
509 | |||
510 | try { | ||
511 | $b->string = mb_convert_encoding($this->string, $toEncoding, 'UTF-8'); | ||
512 | } catch (\ValueError $e) { | ||
513 | if (!\function_exists('iconv')) { | ||
514 | throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); | ||
515 | } | ||
516 | |||
517 | $b->string = iconv('UTF-8', $toEncoding, $this->string); | ||
518 | } | ||
519 | |||
520 | return $b; | ||
521 | } | ||
522 | |||
523 | public function toCodePointString(): CodePointString | ||
524 | { | ||
525 | return new CodePointString($this->string); | ||
526 | } | ||
527 | |||
528 | public function toString(): string | ||
529 | { | ||
530 | return $this->string; | ||
531 | } | ||
532 | |||
533 | public function toUnicodeString(): UnicodeString | ||
534 | { | ||
535 | return new UnicodeString($this->string); | ||
536 | } | ||
537 | |||
538 | abstract public function trim(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): static; | ||
539 | |||
540 | abstract public function trimEnd(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): static; | ||
541 | |||
542 | /** | ||
543 | * @param string|string[] $prefix | ||
544 | */ | ||
545 | public function trimPrefix($prefix): static | ||
546 | { | ||
547 | if (\is_array($prefix) || $prefix instanceof \Traversable) { // don't use is_iterable(), it's slow | ||
548 | foreach ($prefix as $s) { | ||
549 | $t = $this->trimPrefix($s); | ||
550 | |||
551 | if ($t->string !== $this->string) { | ||
552 | return $t; | ||
553 | } | ||
554 | } | ||
555 | |||
556 | return clone $this; | ||
557 | } | ||
558 | |||
559 | $str = clone $this; | ||
560 | |||
561 | if ($prefix instanceof self) { | ||
562 | $prefix = $prefix->string; | ||
563 | } else { | ||
564 | $prefix = (string) $prefix; | ||
565 | } | ||
566 | |||
567 | if ('' !== $prefix && \strlen($this->string) >= \strlen($prefix) && 0 === substr_compare($this->string, $prefix, 0, \strlen($prefix), $this->ignoreCase)) { | ||
568 | $str->string = substr($this->string, \strlen($prefix)); | ||
569 | } | ||
570 | |||
571 | return $str; | ||
572 | } | ||
573 | |||
574 | abstract public function trimStart(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): static; | ||
575 | |||
576 | /** | ||
577 | * @param string|string[] $suffix | ||
578 | */ | ||
579 | public function trimSuffix($suffix): static | ||
580 | { | ||
581 | if (\is_array($suffix) || $suffix instanceof \Traversable) { // don't use is_iterable(), it's slow | ||
582 | foreach ($suffix as $s) { | ||
583 | $t = $this->trimSuffix($s); | ||
584 | |||
585 | if ($t->string !== $this->string) { | ||
586 | return $t; | ||
587 | } | ||
588 | } | ||
589 | |||
590 | return clone $this; | ||
591 | } | ||
592 | |||
593 | $str = clone $this; | ||
594 | |||
595 | if ($suffix instanceof self) { | ||
596 | $suffix = $suffix->string; | ||
597 | } else { | ||
598 | $suffix = (string) $suffix; | ||
599 | } | ||
600 | |||
601 | if ('' !== $suffix && \strlen($this->string) >= \strlen($suffix) && 0 === substr_compare($this->string, $suffix, -\strlen($suffix), null, $this->ignoreCase)) { | ||
602 | $str->string = substr($this->string, 0, -\strlen($suffix)); | ||
603 | } | ||
604 | |||
605 | return $str; | ||
606 | } | ||
607 | |||
608 | public function truncate(int $length, string $ellipsis = '', bool $cut = true): static | ||
609 | { | ||
610 | $stringLength = $this->length(); | ||
611 | |||
612 | if ($stringLength <= $length) { | ||
613 | return clone $this; | ||
614 | } | ||
615 | |||
616 | $ellipsisLength = '' !== $ellipsis ? (new static($ellipsis))->length() : 0; | ||
617 | |||
618 | if ($length < $ellipsisLength) { | ||
619 | $ellipsisLength = 0; | ||
620 | } | ||
621 | |||
622 | if (!$cut) { | ||
623 | if (null === $length = $this->indexOf([' ', "\r", "\n", "\t"], ($length ?: 1) - 1)) { | ||
624 | return clone $this; | ||
625 | } | ||
626 | |||
627 | $length += $ellipsisLength; | ||
628 | } | ||
629 | |||
630 | $str = $this->slice(0, $length - $ellipsisLength); | ||
631 | |||
632 | return $ellipsisLength ? $str->trimEnd()->append($ellipsis) : $str; | ||
633 | } | ||
634 | |||
635 | abstract public function upper(): static; | ||
636 | |||
637 | /** | ||
638 | * Returns the printable length on a terminal. | ||
639 | */ | ||
640 | abstract public function width(bool $ignoreAnsiDecoration = true): int; | ||
641 | |||
642 | public function wordwrap(int $width = 75, string $break = "\n", bool $cut = false): static | ||
643 | { | ||
644 | $lines = '' !== $break ? $this->split($break) : [clone $this]; | ||
645 | $chars = []; | ||
646 | $mask = ''; | ||
647 | |||
648 | if (1 === \count($lines) && '' === $lines[0]->string) { | ||
649 | return $lines[0]; | ||
650 | } | ||
651 | |||
652 | foreach ($lines as $i => $line) { | ||
653 | if ($i) { | ||
654 | $chars[] = $break; | ||
655 | $mask .= '#'; | ||
656 | } | ||
657 | |||
658 | foreach ($line->chunk() as $char) { | ||
659 | $chars[] = $char->string; | ||
660 | $mask .= ' ' === $char->string ? ' ' : '?'; | ||
661 | } | ||
662 | } | ||
663 | |||
664 | $string = ''; | ||
665 | $j = 0; | ||
666 | $b = $i = -1; | ||
667 | $mask = wordwrap($mask, $width, '#', $cut); | ||
668 | |||
669 | while (false !== $b = strpos($mask, '#', $b + 1)) { | ||
670 | for (++$i; $i < $b; ++$i) { | ||
671 | $string .= $chars[$j]; | ||
672 | unset($chars[$j++]); | ||
673 | } | ||
674 | |||
675 | if ($break === $chars[$j] || ' ' === $chars[$j]) { | ||
676 | unset($chars[$j++]); | ||
677 | } | ||
678 | |||
679 | $string .= $break; | ||
680 | } | ||
681 | |||
682 | $str = clone $this; | ||
683 | $str->string = $string.implode('', $chars); | ||
684 | |||
685 | return $str; | ||
686 | } | ||
687 | |||
688 | public function __sleep(): array | ||
689 | { | ||
690 | return ['string']; | ||
691 | } | ||
692 | |||
693 | public function __clone() | ||
694 | { | ||
695 | $this->ignoreCase = false; | ||
696 | } | ||
697 | |||
698 | public function __toString(): string | ||
699 | { | ||
700 | return $this->string; | ||
701 | } | ||
702 | } | ||
diff --git a/vendor/symfony/string/AbstractUnicodeString.php b/vendor/symfony/string/AbstractUnicodeString.php new file mode 100644 index 0000000..2cb2917 --- /dev/null +++ b/vendor/symfony/string/AbstractUnicodeString.php | |||
@@ -0,0 +1,664 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\String; | ||
13 | |||
14 | use Symfony\Component\String\Exception\ExceptionInterface; | ||
15 | use Symfony\Component\String\Exception\InvalidArgumentException; | ||
16 | use Symfony\Component\String\Exception\RuntimeException; | ||
17 | |||
18 | /** | ||
19 | * Represents a string of abstract Unicode characters. | ||
20 | * | ||
21 | * Unicode defines 3 types of "characters" (bytes, code points and grapheme clusters). | ||
22 | * This class is the abstract type to use as a type-hint when the logic you want to | ||
23 | * implement is Unicode-aware but doesn't care about code points vs grapheme clusters. | ||
24 | * | ||
25 | * @author Nicolas Grekas <p@tchwork.com> | ||
26 | * | ||
27 | * @throws ExceptionInterface | ||
28 | */ | ||
29 | abstract class AbstractUnicodeString extends AbstractString | ||
30 | { | ||
31 | public const NFC = \Normalizer::NFC; | ||
32 | public const NFD = \Normalizer::NFD; | ||
33 | public const NFKC = \Normalizer::NFKC; | ||
34 | public const NFKD = \Normalizer::NFKD; | ||
35 | |||
36 | // all ASCII letters sorted by typical frequency of occurrence | ||
37 | private const ASCII = "\x20\x65\x69\x61\x73\x6E\x74\x72\x6F\x6C\x75\x64\x5D\x5B\x63\x6D\x70\x27\x0A\x67\x7C\x68\x76\x2E\x66\x62\x2C\x3A\x3D\x2D\x71\x31\x30\x43\x32\x2A\x79\x78\x29\x28\x4C\x39\x41\x53\x2F\x50\x22\x45\x6A\x4D\x49\x6B\x33\x3E\x35\x54\x3C\x44\x34\x7D\x42\x7B\x38\x46\x77\x52\x36\x37\x55\x47\x4E\x3B\x4A\x7A\x56\x23\x48\x4F\x57\x5F\x26\x21\x4B\x3F\x58\x51\x25\x59\x5C\x09\x5A\x2B\x7E\x5E\x24\x40\x60\x7F\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"; | ||
38 | |||
39 | // the subset of folded case mappings that is not in lower case mappings | ||
40 | private const FOLD_FROM = ['İ', 'µ', 'ſ', "\xCD\x85", 'ς', 'ϐ', 'ϑ', 'ϕ', 'ϖ', 'ϰ', 'ϱ', 'ϵ', 'ẛ', "\xE1\xBE\xBE", 'ß', 'ʼn', 'ǰ', 'ΐ', 'ΰ', 'և', 'ẖ', 'ẗ', 'ẘ', 'ẙ', 'ẚ', 'ẞ', 'ὐ', 'ὒ', 'ὔ', 'ὖ', 'ᾀ', 'ᾁ', 'ᾂ', 'ᾃ', 'ᾄ', 'ᾅ', 'ᾆ', 'ᾇ', 'ᾈ', 'ᾉ', 'ᾊ', 'ᾋ', 'ᾌ', 'ᾍ', 'ᾎ', 'ᾏ', 'ᾐ', 'ᾑ', 'ᾒ', 'ᾓ', 'ᾔ', 'ᾕ', 'ᾖ', 'ᾗ', 'ᾘ', 'ᾙ', 'ᾚ', 'ᾛ', 'ᾜ', 'ᾝ', 'ᾞ', 'ᾟ', 'ᾠ', 'ᾡ', 'ᾢ', 'ᾣ', 'ᾤ', 'ᾥ', 'ᾦ', 'ᾧ', 'ᾨ', 'ᾩ', 'ᾪ', 'ᾫ', 'ᾬ', 'ᾭ', 'ᾮ', 'ᾯ', 'ᾲ', 'ᾳ', 'ᾴ', 'ᾶ', 'ᾷ', 'ᾼ', 'ῂ', 'ῃ', 'ῄ', 'ῆ', 'ῇ', 'ῌ', 'ῒ', 'ῖ', 'ῗ', 'ῢ', 'ῤ', 'ῦ', 'ῧ', 'ῲ', 'ῳ', 'ῴ', 'ῶ', 'ῷ', 'ῼ', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'ſt', 'st', 'ﬓ', 'ﬔ', 'ﬕ', 'ﬖ', 'ﬗ']; | ||
41 | private const FOLD_TO = ['i̇', 'μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', 'ṡ', 'ι', 'ss', 'ʼn', 'ǰ', 'ΐ', 'ΰ', 'եւ', 'ẖ', 'ẗ', 'ẘ', 'ẙ', 'aʾ', 'ss', 'ὐ', 'ὒ', 'ὔ', 'ὖ', 'ἀι', 'ἁι', 'ἂι', 'ἃι', 'ἄι', 'ἅι', 'ἆι', 'ἇι', 'ἀι', 'ἁι', 'ἂι', 'ἃι', 'ἄι', 'ἅι', 'ἆι', 'ἇι', 'ἠι', 'ἡι', 'ἢι', 'ἣι', 'ἤι', 'ἥι', 'ἦι', 'ἧι', 'ἠι', 'ἡι', 'ἢι', 'ἣι', 'ἤι', 'ἥι', 'ἦι', 'ἧι', 'ὠι', 'ὡι', 'ὢι', 'ὣι', 'ὤι', 'ὥι', 'ὦι', 'ὧι', 'ὠι', 'ὡι', 'ὢι', 'ὣι', 'ὤι', 'ὥι', 'ὦι', 'ὧι', 'ὰι', 'αι', 'άι', 'ᾶ', 'ᾶι', 'αι', 'ὴι', 'ηι', 'ήι', 'ῆ', 'ῆι', 'ηι', 'ῒ', 'ῖ', 'ῗ', 'ῢ', 'ῤ', 'ῦ', 'ῧ', 'ὼι', 'ωι', 'ώι', 'ῶ', 'ῶι', 'ωι', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'st', 'st', 'մն', 'մե', 'մի', 'վն', 'մխ']; | ||
42 | |||
43 | // the subset of https://github.com/unicode-org/cldr/blob/master/common/transforms/Latin-ASCII.xml that is not in NFKD | ||
44 | private const TRANSLIT_FROM = ['Æ', 'Ð', 'Ø', 'Þ', 'ß', 'æ', 'ð', 'ø', 'þ', 'Đ', 'đ', 'Ħ', 'ħ', 'ı', 'ĸ', 'Ŀ', 'ŀ', 'Ł', 'ł', 'ʼn', 'Ŋ', 'ŋ', 'Œ', 'œ', 'Ŧ', 'ŧ', 'ƀ', 'Ɓ', 'Ƃ', 'ƃ', 'Ƈ', 'ƈ', 'Ɖ', 'Ɗ', 'Ƌ', 'ƌ', 'Ɛ', 'Ƒ', 'ƒ', 'Ɠ', 'ƕ', 'Ɩ', 'Ɨ', 'Ƙ', 'ƙ', 'ƚ', 'Ɲ', 'ƞ', 'Ƣ', 'ƣ', 'Ƥ', 'ƥ', 'ƫ', 'Ƭ', 'ƭ', 'Ʈ', 'Ʋ', 'Ƴ', 'ƴ', 'Ƶ', 'ƶ', 'DŽ', 'Dž', 'dž', 'Ǥ', 'ǥ', 'ȡ', 'Ȥ', 'ȥ', 'ȴ', 'ȵ', 'ȶ', 'ȷ', 'ȸ', 'ȹ', 'Ⱥ', 'Ȼ', 'ȼ', 'Ƚ', 'Ⱦ', 'ȿ', 'ɀ', 'Ƀ', 'Ʉ', 'Ɇ', 'ɇ', 'Ɉ', 'ɉ', 'Ɍ', 'ɍ', 'Ɏ', 'ɏ', 'ɓ', 'ɕ', 'ɖ', 'ɗ', 'ɛ', 'ɟ', 'ɠ', 'ɡ', 'ɢ', 'ɦ', 'ɧ', 'ɨ', 'ɪ', 'ɫ', 'ɬ', 'ɭ', 'ɱ', 'ɲ', 'ɳ', 'ɴ', 'ɶ', 'ɼ', 'ɽ', 'ɾ', 'ʀ', 'ʂ', 'ʈ', 'ʉ', 'ʋ', 'ʏ', 'ʐ', 'ʑ', 'ʙ', 'ʛ', 'ʜ', 'ʝ', 'ʟ', 'ʠ', 'ʣ', 'ʥ', 'ʦ', 'ʪ', 'ʫ', 'ᴀ', 'ᴁ', 'ᴃ', 'ᴄ', 'ᴅ', 'ᴆ', 'ᴇ', 'ᴊ', 'ᴋ', 'ᴌ', 'ᴍ', 'ᴏ', 'ᴘ', 'ᴛ', 'ᴜ', 'ᴠ', 'ᴡ', 'ᴢ', 'ᵫ', 'ᵬ', 'ᵭ', 'ᵮ', 'ᵯ', 'ᵰ', 'ᵱ', 'ᵲ', 'ᵳ', 'ᵴ', 'ᵵ', 'ᵶ', 'ᵺ', 'ᵻ', 'ᵽ', 'ᵾ', 'ᶀ', 'ᶁ', 'ᶂ', 'ᶃ', 'ᶄ', 'ᶅ', 'ᶆ', 'ᶇ', 'ᶈ', 'ᶉ', 'ᶊ', 'ᶌ', 'ᶍ', 'ᶎ', 'ᶏ', 'ᶑ', 'ᶒ', 'ᶓ', 'ᶖ', 'ᶙ', 'ẚ', 'ẜ', 'ẝ', 'ẞ', 'Ỻ', 'ỻ', 'Ỽ', 'ỽ', 'Ỿ', 'ỿ', '©', '®', '₠', '₢', '₣', '₤', '₧', '₺', '₹', 'ℌ', '℞', '㎧', '㎮', '㏆', '㏗', '㏞', '㏟', '¼', '½', '¾', '⅓', '⅔', '⅕', '⅖', '⅗', '⅘', '⅙', '⅚', '⅛', '⅜', '⅝', '⅞', '⅟', '〇', '‘', '’', '‚', '‛', '“', '”', '„', '‟', '′', '″', '〝', '〞', '«', '»', '‹', '›', '‐', '‑', '‒', '–', '—', '―', '︱', '︲', '﹘', '‖', '⁄', '⁅', '⁆', '⁎', '、', '。', '〈', '〉', '《', '》', '〔', '〕', '〘', '〙', '〚', '〛', '︑', '︒', '︹', '︺', '︽', '︾', '︿', '﹀', '﹑', '﹝', '﹞', '⦅', '⦆', '。', '、', '×', '÷', '−', '∕', '∖', '∣', '∥', '≪', '≫', '⦅', '⦆']; | ||
45 | private const TRANSLIT_TO = ['AE', 'D', 'O', 'TH', 'ss', 'ae', 'd', 'o', 'th', 'D', 'd', 'H', 'h', 'i', 'q', 'L', 'l', 'L', 'l', '\'n', 'N', 'n', 'OE', 'oe', 'T', 't', 'b', 'B', 'B', 'b', 'C', 'c', 'D', 'D', 'D', 'd', 'E', 'F', 'f', 'G', 'hv', 'I', 'I', 'K', 'k', 'l', 'N', 'n', 'OI', 'oi', 'P', 'p', 't', 'T', 't', 'T', 'V', 'Y', 'y', 'Z', 'z', 'DZ', 'Dz', 'dz', 'G', 'g', 'd', 'Z', 'z', 'l', 'n', 't', 'j', 'db', 'qp', 'A', 'C', 'c', 'L', 'T', 's', 'z', 'B', 'U', 'E', 'e', 'J', 'j', 'R', 'r', 'Y', 'y', 'b', 'c', 'd', 'd', 'e', 'j', 'g', 'g', 'G', 'h', 'h', 'i', 'I', 'l', 'l', 'l', 'm', 'n', 'n', 'N', 'OE', 'r', 'r', 'r', 'R', 's', 't', 'u', 'v', 'Y', 'z', 'z', 'B', 'G', 'H', 'j', 'L', 'q', 'dz', 'dz', 'ts', 'ls', 'lz', 'A', 'AE', 'B', 'C', 'D', 'D', 'E', 'J', 'K', 'L', 'M', 'O', 'P', 'T', 'U', 'V', 'W', 'Z', 'ue', 'b', 'd', 'f', 'm', 'n', 'p', 'r', 'r', 's', 't', 'z', 'th', 'I', 'p', 'U', 'b', 'd', 'f', 'g', 'k', 'l', 'm', 'n', 'p', 'r', 's', 'v', 'x', 'z', 'a', 'd', 'e', 'e', 'i', 'u', 'a', 's', 's', 'SS', 'LL', 'll', 'V', 'v', 'Y', 'y', '(C)', '(R)', 'CE', 'Cr', 'Fr.', 'L.', 'Pts', 'TL', 'Rs', 'x', 'Rx', 'm/s', 'rad/s', 'C/kg', 'pH', 'V/m', 'A/m', ' 1/4', ' 1/2', ' 3/4', ' 1/3', ' 2/3', ' 1/5', ' 2/5', ' 3/5', ' 4/5', ' 1/6', ' 5/6', ' 1/8', ' 3/8', ' 5/8', ' 7/8', ' 1/', '0', '\'', '\'', ',', '\'', '"', '"', ',,', '"', '\'', '"', '"', '"', '<<', '>>', '<', '>', '-', '-', '-', '-', '-', '-', '-', '-', '-', '||', '/', '[', ']', '*', ',', '.', '<', '>', '<<', '>>', '[', ']', '[', ']', '[', ']', ',', '.', '[', ']', '<<', '>>', '<', '>', ',', '[', ']', '((', '))', '.', ',', '*', '/', '-', '/', '\\', '|', '||', '<<', '>>', '((', '))']; | ||
46 | |||
47 | private static array $transliterators = []; | ||
48 | private static array $tableZero; | ||
49 | private static array $tableWide; | ||
50 | |||
51 | public static function fromCodePoints(int ...$codes): static | ||
52 | { | ||
53 | $string = ''; | ||
54 | |||
55 | foreach ($codes as $code) { | ||
56 | if (0x80 > $code %= 0x200000) { | ||
57 | $string .= \chr($code); | ||
58 | } elseif (0x800 > $code) { | ||
59 | $string .= \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F); | ||
60 | } elseif (0x10000 > $code) { | ||
61 | $string .= \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); | ||
62 | } else { | ||
63 | $string .= \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); | ||
64 | } | ||
65 | } | ||
66 | |||
67 | return new static($string); | ||
68 | } | ||
69 | |||
70 | /** | ||
71 | * Generic UTF-8 to ASCII transliteration. | ||
72 | * | ||
73 | * Install the intl extension for best results. | ||
74 | * | ||
75 | * @param string[]|\Transliterator[]|\Closure[] $rules See "*-Latin" rules from Transliterator::listIDs() | ||
76 | */ | ||
77 | public function ascii(array $rules = []): self | ||
78 | { | ||
79 | $str = clone $this; | ||
80 | $s = $str->string; | ||
81 | $str->string = ''; | ||
82 | |||
83 | array_unshift($rules, 'nfd'); | ||
84 | $rules[] = 'latin-ascii'; | ||
85 | |||
86 | if (\function_exists('transliterator_transliterate')) { | ||
87 | $rules[] = 'any-latin/bgn'; | ||
88 | } | ||
89 | |||
90 | $rules[] = 'nfkd'; | ||
91 | $rules[] = '[:nonspacing mark:] remove'; | ||
92 | |||
93 | while (\strlen($s) - 1 > $i = strspn($s, self::ASCII)) { | ||
94 | if (0 < --$i) { | ||
95 | $str->string .= substr($s, 0, $i); | ||
96 | $s = substr($s, $i); | ||
97 | } | ||
98 | |||
99 | if (!$rule = array_shift($rules)) { | ||
100 | $rules = []; // An empty rule interrupts the next ones | ||
101 | } | ||
102 | |||
103 | if ($rule instanceof \Transliterator) { | ||
104 | $s = $rule->transliterate($s); | ||
105 | } elseif ($rule instanceof \Closure) { | ||
106 | $s = $rule($s); | ||
107 | } elseif ($rule) { | ||
108 | if ('nfd' === $rule = strtolower($rule)) { | ||
109 | normalizer_is_normalized($s, self::NFD) ?: $s = normalizer_normalize($s, self::NFD); | ||
110 | } elseif ('nfkd' === $rule) { | ||
111 | normalizer_is_normalized($s, self::NFKD) ?: $s = normalizer_normalize($s, self::NFKD); | ||
112 | } elseif ('[:nonspacing mark:] remove' === $rule) { | ||
113 | $s = preg_replace('/\p{Mn}++/u', '', $s); | ||
114 | } elseif ('latin-ascii' === $rule) { | ||
115 | $s = str_replace(self::TRANSLIT_FROM, self::TRANSLIT_TO, $s); | ||
116 | } elseif ('de-ascii' === $rule) { | ||
117 | $s = preg_replace("/([AUO])\u{0308}(?=\p{Ll})/u", '$1e', $s); | ||
118 | $s = str_replace(["a\u{0308}", "o\u{0308}", "u\u{0308}", "A\u{0308}", "O\u{0308}", "U\u{0308}"], ['ae', 'oe', 'ue', 'AE', 'OE', 'UE'], $s); | ||
119 | } elseif (\function_exists('transliterator_transliterate')) { | ||
120 | if (null === $transliterator = self::$transliterators[$rule] ??= \Transliterator::create($rule)) { | ||
121 | if ('any-latin/bgn' === $rule) { | ||
122 | $rule = 'any-latin'; | ||
123 | $transliterator = self::$transliterators[$rule] ??= \Transliterator::create($rule); | ||
124 | } | ||
125 | |||
126 | if (null === $transliterator) { | ||
127 | throw new InvalidArgumentException(sprintf('Unknown transliteration rule "%s".', $rule)); | ||
128 | } | ||
129 | |||
130 | self::$transliterators['any-latin/bgn'] = $transliterator; | ||
131 | } | ||
132 | |||
133 | $s = $transliterator->transliterate($s); | ||
134 | } | ||
135 | } elseif (!\function_exists('iconv')) { | ||
136 | $s = preg_replace('/[^\x00-\x7F]/u', '?', $s); | ||
137 | } else { | ||
138 | $s = @preg_replace_callback('/[^\x00-\x7F]/u', static function ($c) { | ||
139 | $c = (string) iconv('UTF-8', 'ASCII//TRANSLIT', $c[0]); | ||
140 | |||
141 | if ('' === $c && '' === iconv('UTF-8', 'ASCII//TRANSLIT', '²')) { | ||
142 | throw new \LogicException(sprintf('"%s" requires a translit-able iconv implementation, try installing "gnu-libiconv" if you\'re using Alpine Linux.', static::class)); | ||
143 | } | ||
144 | |||
145 | return 1 < \strlen($c) ? ltrim($c, '\'`"^~') : ('' !== $c ? $c : '?'); | ||
146 | }, $s); | ||
147 | } | ||
148 | } | ||
149 | |||
150 | $str->string .= $s; | ||
151 | |||
152 | return $str; | ||
153 | } | ||
154 | |||
155 | public function camel(): static | ||
156 | { | ||
157 | $str = clone $this; | ||
158 | $str->string = str_replace(' ', '', preg_replace_callback('/\b.(?!\p{Lu})/u', static function ($m) { | ||
159 | static $i = 0; | ||
160 | |||
161 | return 1 === ++$i ? ('İ' === $m[0] ? 'i̇' : mb_strtolower($m[0], 'UTF-8')) : mb_convert_case($m[0], \MB_CASE_TITLE, 'UTF-8'); | ||
162 | }, preg_replace('/[^\pL0-9]++/u', ' ', $this->string))); | ||
163 | |||
164 | return $str; | ||
165 | } | ||
166 | |||
167 | /** | ||
168 | * @return int[] | ||
169 | */ | ||
170 | public function codePointsAt(int $offset): array | ||
171 | { | ||
172 | $str = $this->slice($offset, 1); | ||
173 | |||
174 | if ('' === $str->string) { | ||
175 | return []; | ||
176 | } | ||
177 | |||
178 | $codePoints = []; | ||
179 | |||
180 | foreach (preg_split('//u', $str->string, -1, \PREG_SPLIT_NO_EMPTY) as $c) { | ||
181 | $codePoints[] = mb_ord($c, 'UTF-8'); | ||
182 | } | ||
183 | |||
184 | return $codePoints; | ||
185 | } | ||
186 | |||
187 | public function folded(bool $compat = true): static | ||
188 | { | ||
189 | $str = clone $this; | ||
190 | |||
191 | if (!$compat || !\defined('Normalizer::NFKC_CF')) { | ||
192 | $str->string = normalizer_normalize($str->string, $compat ? \Normalizer::NFKC : \Normalizer::NFC); | ||
193 | $str->string = mb_strtolower(str_replace(self::FOLD_FROM, self::FOLD_TO, $str->string), 'UTF-8'); | ||
194 | } else { | ||
195 | $str->string = normalizer_normalize($str->string, \Normalizer::NFKC_CF); | ||
196 | } | ||
197 | |||
198 | return $str; | ||
199 | } | ||
200 | |||
201 | public function join(array $strings, ?string $lastGlue = null): static | ||
202 | { | ||
203 | $str = clone $this; | ||
204 | |||
205 | $tail = null !== $lastGlue && 1 < \count($strings) ? $lastGlue.array_pop($strings) : ''; | ||
206 | $str->string = implode($this->string, $strings).$tail; | ||
207 | |||
208 | if (!preg_match('//u', $str->string)) { | ||
209 | throw new InvalidArgumentException('Invalid UTF-8 string.'); | ||
210 | } | ||
211 | |||
212 | return $str; | ||
213 | } | ||
214 | |||
215 | public function lower(): static | ||
216 | { | ||
217 | $str = clone $this; | ||
218 | $str->string = mb_strtolower(str_replace('İ', 'i̇', $str->string), 'UTF-8'); | ||
219 | |||
220 | return $str; | ||
221 | } | ||
222 | |||
223 | /** | ||
224 | * @param string $locale In the format language_region (e.g. tr_TR) | ||
225 | */ | ||
226 | public function localeLower(string $locale): static | ||
227 | { | ||
228 | if (null !== $transliterator = $this->getLocaleTransliterator($locale, 'Lower')) { | ||
229 | $str = clone $this; | ||
230 | $str->string = $transliterator->transliterate($str->string); | ||
231 | |||
232 | return $str; | ||
233 | } | ||
234 | |||
235 | return $this->lower(); | ||
236 | } | ||
237 | |||
238 | public function match(string $regexp, int $flags = 0, int $offset = 0): array | ||
239 | { | ||
240 | $match = ((\PREG_PATTERN_ORDER | \PREG_SET_ORDER) & $flags) ? 'preg_match_all' : 'preg_match'; | ||
241 | |||
242 | if ($this->ignoreCase) { | ||
243 | $regexp .= 'i'; | ||
244 | } | ||
245 | |||
246 | set_error_handler(static fn ($t, $m) => throw new InvalidArgumentException($m)); | ||
247 | |||
248 | try { | ||
249 | if (false === $match($regexp.'u', $this->string, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset)) { | ||
250 | throw new RuntimeException('Matching failed with error: '.preg_last_error_msg()); | ||
251 | } | ||
252 | } finally { | ||
253 | restore_error_handler(); | ||
254 | } | ||
255 | |||
256 | return $matches; | ||
257 | } | ||
258 | |||
259 | public function normalize(int $form = self::NFC): static | ||
260 | { | ||
261 | if (!\in_array($form, [self::NFC, self::NFD, self::NFKC, self::NFKD])) { | ||
262 | throw new InvalidArgumentException('Unsupported normalization form.'); | ||
263 | } | ||
264 | |||
265 | $str = clone $this; | ||
266 | normalizer_is_normalized($str->string, $form) ?: $str->string = normalizer_normalize($str->string, $form); | ||
267 | |||
268 | return $str; | ||
269 | } | ||
270 | |||
271 | public function padBoth(int $length, string $padStr = ' '): static | ||
272 | { | ||
273 | if ('' === $padStr || !preg_match('//u', $padStr)) { | ||
274 | throw new InvalidArgumentException('Invalid UTF-8 string.'); | ||
275 | } | ||
276 | |||
277 | $pad = clone $this; | ||
278 | $pad->string = $padStr; | ||
279 | |||
280 | return $this->pad($length, $pad, \STR_PAD_BOTH); | ||
281 | } | ||
282 | |||
283 | public function padEnd(int $length, string $padStr = ' '): static | ||
284 | { | ||
285 | if ('' === $padStr || !preg_match('//u', $padStr)) { | ||
286 | throw new InvalidArgumentException('Invalid UTF-8 string.'); | ||
287 | } | ||
288 | |||
289 | $pad = clone $this; | ||
290 | $pad->string = $padStr; | ||
291 | |||
292 | return $this->pad($length, $pad, \STR_PAD_RIGHT); | ||
293 | } | ||
294 | |||
295 | public function padStart(int $length, string $padStr = ' '): static | ||
296 | { | ||
297 | if ('' === $padStr || !preg_match('//u', $padStr)) { | ||
298 | throw new InvalidArgumentException('Invalid UTF-8 string.'); | ||
299 | } | ||
300 | |||
301 | $pad = clone $this; | ||
302 | $pad->string = $padStr; | ||
303 | |||
304 | return $this->pad($length, $pad, \STR_PAD_LEFT); | ||
305 | } | ||
306 | |||
307 | public function replaceMatches(string $fromRegexp, string|callable $to): static | ||
308 | { | ||
309 | if ($this->ignoreCase) { | ||
310 | $fromRegexp .= 'i'; | ||
311 | } | ||
312 | |||
313 | if (\is_array($to) || $to instanceof \Closure) { | ||
314 | $replace = 'preg_replace_callback'; | ||
315 | $to = static function (array $m) use ($to): string { | ||
316 | $to = $to($m); | ||
317 | |||
318 | if ('' !== $to && (!\is_string($to) || !preg_match('//u', $to))) { | ||
319 | throw new InvalidArgumentException('Replace callback must return a valid UTF-8 string.'); | ||
320 | } | ||
321 | |||
322 | return $to; | ||
323 | }; | ||
324 | } elseif ('' !== $to && !preg_match('//u', $to)) { | ||
325 | throw new InvalidArgumentException('Invalid UTF-8 string.'); | ||
326 | } else { | ||
327 | $replace = 'preg_replace'; | ||
328 | } | ||
329 | |||
330 | set_error_handler(static fn ($t, $m) => throw new InvalidArgumentException($m)); | ||
331 | |||
332 | try { | ||
333 | if (null === $string = $replace($fromRegexp.'u', $to, $this->string)) { | ||
334 | $lastError = preg_last_error(); | ||
335 | |||
336 | foreach (get_defined_constants(true)['pcre'] as $k => $v) { | ||
337 | if ($lastError === $v && str_ends_with($k, '_ERROR')) { | ||
338 | throw new RuntimeException('Matching failed with '.$k.'.'); | ||
339 | } | ||
340 | } | ||
341 | |||
342 | throw new RuntimeException('Matching failed with unknown error code.'); | ||
343 | } | ||
344 | } finally { | ||
345 | restore_error_handler(); | ||
346 | } | ||
347 | |||
348 | $str = clone $this; | ||
349 | $str->string = $string; | ||
350 | |||
351 | return $str; | ||
352 | } | ||
353 | |||
354 | public function reverse(): static | ||
355 | { | ||
356 | $str = clone $this; | ||
357 | $str->string = implode('', array_reverse(preg_split('/(\X)/u', $str->string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY))); | ||
358 | |||
359 | return $str; | ||
360 | } | ||
361 | |||
362 | public function snake(): static | ||
363 | { | ||
364 | $str = $this->camel(); | ||
365 | $str->string = mb_strtolower(preg_replace(['/(\p{Lu}+)(\p{Lu}\p{Ll})/u', '/([\p{Ll}0-9])(\p{Lu})/u'], '\1_\2', $str->string), 'UTF-8'); | ||
366 | |||
367 | return $str; | ||
368 | } | ||
369 | |||
370 | public function title(bool $allWords = false): static | ||
371 | { | ||
372 | $str = clone $this; | ||
373 | |||
374 | $limit = $allWords ? -1 : 1; | ||
375 | |||
376 | $str->string = preg_replace_callback('/\b./u', static fn (array $m): string => mb_convert_case($m[0], \MB_CASE_TITLE, 'UTF-8'), $str->string, $limit); | ||
377 | |||
378 | return $str; | ||
379 | } | ||
380 | |||
381 | /** | ||
382 | * @param string $locale In the format language_region (e.g. tr_TR) | ||
383 | */ | ||
384 | public function localeTitle(string $locale): static | ||
385 | { | ||
386 | if (null !== $transliterator = $this->getLocaleTransliterator($locale, 'Title')) { | ||
387 | $str = clone $this; | ||
388 | $str->string = $transliterator->transliterate($str->string); | ||
389 | |||
390 | return $str; | ||
391 | } | ||
392 | |||
393 | return $this->title(); | ||
394 | } | ||
395 | |||
396 | public function trim(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): static | ||
397 | { | ||
398 | if (" \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}" !== $chars && !preg_match('//u', $chars)) { | ||
399 | throw new InvalidArgumentException('Invalid UTF-8 chars.'); | ||
400 | } | ||
401 | $chars = preg_quote($chars); | ||
402 | |||
403 | $str = clone $this; | ||
404 | $str->string = preg_replace("{^[$chars]++|[$chars]++$}uD", '', $str->string); | ||
405 | |||
406 | return $str; | ||
407 | } | ||
408 | |||
409 | public function trimEnd(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): static | ||
410 | { | ||
411 | if (" \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}" !== $chars && !preg_match('//u', $chars)) { | ||
412 | throw new InvalidArgumentException('Invalid UTF-8 chars.'); | ||
413 | } | ||
414 | $chars = preg_quote($chars); | ||
415 | |||
416 | $str = clone $this; | ||
417 | $str->string = preg_replace("{[$chars]++$}uD", '', $str->string); | ||
418 | |||
419 | return $str; | ||
420 | } | ||
421 | |||
422 | public function trimPrefix($prefix): static | ||
423 | { | ||
424 | if (!$this->ignoreCase) { | ||
425 | return parent::trimPrefix($prefix); | ||
426 | } | ||
427 | |||
428 | $str = clone $this; | ||
429 | |||
430 | if ($prefix instanceof \Traversable) { | ||
431 | $prefix = iterator_to_array($prefix, false); | ||
432 | } elseif ($prefix instanceof parent) { | ||
433 | $prefix = $prefix->string; | ||
434 | } | ||
435 | |||
436 | $prefix = implode('|', array_map('preg_quote', (array) $prefix)); | ||
437 | $str->string = preg_replace("{^(?:$prefix)}iuD", '', $this->string); | ||
438 | |||
439 | return $str; | ||
440 | } | ||
441 | |||
442 | public function trimStart(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): static | ||
443 | { | ||
444 | if (" \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}" !== $chars && !preg_match('//u', $chars)) { | ||
445 | throw new InvalidArgumentException('Invalid UTF-8 chars.'); | ||
446 | } | ||
447 | $chars = preg_quote($chars); | ||
448 | |||
449 | $str = clone $this; | ||
450 | $str->string = preg_replace("{^[$chars]++}uD", '', $str->string); | ||
451 | |||
452 | return $str; | ||
453 | } | ||
454 | |||
455 | public function trimSuffix($suffix): static | ||
456 | { | ||
457 | if (!$this->ignoreCase) { | ||
458 | return parent::trimSuffix($suffix); | ||
459 | } | ||
460 | |||
461 | $str = clone $this; | ||
462 | |||
463 | if ($suffix instanceof \Traversable) { | ||
464 | $suffix = iterator_to_array($suffix, false); | ||
465 | } elseif ($suffix instanceof parent) { | ||
466 | $suffix = $suffix->string; | ||
467 | } | ||
468 | |||
469 | $suffix = implode('|', array_map('preg_quote', (array) $suffix)); | ||
470 | $str->string = preg_replace("{(?:$suffix)$}iuD", '', $this->string); | ||
471 | |||
472 | return $str; | ||
473 | } | ||
474 | |||
475 | public function upper(): static | ||
476 | { | ||
477 | $str = clone $this; | ||
478 | $str->string = mb_strtoupper($str->string, 'UTF-8'); | ||
479 | |||
480 | return $str; | ||
481 | } | ||
482 | |||
483 | /** | ||
484 | * @param string $locale In the format language_region (e.g. tr_TR) | ||
485 | */ | ||
486 | public function localeUpper(string $locale): static | ||
487 | { | ||
488 | if (null !== $transliterator = $this->getLocaleTransliterator($locale, 'Upper')) { | ||
489 | $str = clone $this; | ||
490 | $str->string = $transliterator->transliterate($str->string); | ||
491 | |||
492 | return $str; | ||
493 | } | ||
494 | |||
495 | return $this->upper(); | ||
496 | } | ||
497 | |||
498 | public function width(bool $ignoreAnsiDecoration = true): int | ||
499 | { | ||
500 | $width = 0; | ||
501 | $s = str_replace(["\x00", "\x05", "\x07"], '', $this->string); | ||
502 | |||
503 | if (str_contains($s, "\r")) { | ||
504 | $s = str_replace(["\r\n", "\r"], "\n", $s); | ||
505 | } | ||
506 | |||
507 | if (!$ignoreAnsiDecoration) { | ||
508 | $s = preg_replace('/[\p{Cc}\x7F]++/u', '', $s); | ||
509 | } | ||
510 | |||
511 | foreach (explode("\n", $s) as $s) { | ||
512 | if ($ignoreAnsiDecoration) { | ||
513 | $s = preg_replace('/(?:\x1B(?: | ||
514 | \[ [\x30-\x3F]*+ [\x20-\x2F]*+ [\x40-\x7E] | ||
515 | | [P\]X^_] .*? \x1B\\\\ | ||
516 | | [\x41-\x7E] | ||
517 | )|[\p{Cc}\x7F]++)/xu', '', $s); | ||
518 | } | ||
519 | |||
520 | $lineWidth = $this->wcswidth($s); | ||
521 | |||
522 | if ($lineWidth > $width) { | ||
523 | $width = $lineWidth; | ||
524 | } | ||
525 | } | ||
526 | |||
527 | return $width; | ||
528 | } | ||
529 | |||
530 | private function pad(int $len, self $pad, int $type): static | ||
531 | { | ||
532 | $sLen = $this->length(); | ||
533 | |||
534 | if ($len <= $sLen) { | ||
535 | return clone $this; | ||
536 | } | ||
537 | |||
538 | $padLen = $pad->length(); | ||
539 | $freeLen = $len - $sLen; | ||
540 | $len = $freeLen % $padLen; | ||
541 | |||
542 | switch ($type) { | ||
543 | case \STR_PAD_RIGHT: | ||
544 | return $this->append(str_repeat($pad->string, intdiv($freeLen, $padLen)).($len ? $pad->slice(0, $len) : '')); | ||
545 | |||
546 | case \STR_PAD_LEFT: | ||
547 | return $this->prepend(str_repeat($pad->string, intdiv($freeLen, $padLen)).($len ? $pad->slice(0, $len) : '')); | ||
548 | |||
549 | case \STR_PAD_BOTH: | ||
550 | $freeLen /= 2; | ||
551 | |||
552 | $rightLen = ceil($freeLen); | ||
553 | $len = $rightLen % $padLen; | ||
554 | $str = $this->append(str_repeat($pad->string, intdiv($rightLen, $padLen)).($len ? $pad->slice(0, $len) : '')); | ||
555 | |||
556 | $leftLen = floor($freeLen); | ||
557 | $len = $leftLen % $padLen; | ||
558 | |||
559 | return $str->prepend(str_repeat($pad->string, intdiv($leftLen, $padLen)).($len ? $pad->slice(0, $len) : '')); | ||
560 | |||
561 | default: | ||
562 | throw new InvalidArgumentException('Invalid padding type.'); | ||
563 | } | ||
564 | } | ||
565 | |||
566 | /** | ||
567 | * Based on https://github.com/jquast/wcwidth, a Python implementation of https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c. | ||
568 | */ | ||
569 | private function wcswidth(string $string): int | ||
570 | { | ||
571 | $width = 0; | ||
572 | |||
573 | foreach (preg_split('//u', $string, -1, \PREG_SPLIT_NO_EMPTY) as $c) { | ||
574 | $codePoint = mb_ord($c, 'UTF-8'); | ||
575 | |||
576 | if (0 === $codePoint // NULL | ||
577 | || 0x034F === $codePoint // COMBINING GRAPHEME JOINER | ||
578 | || (0x200B <= $codePoint && 0x200F >= $codePoint) // ZERO WIDTH SPACE to RIGHT-TO-LEFT MARK | ||
579 | || 0x2028 === $codePoint // LINE SEPARATOR | ||
580 | || 0x2029 === $codePoint // PARAGRAPH SEPARATOR | ||
581 | || (0x202A <= $codePoint && 0x202E >= $codePoint) // LEFT-TO-RIGHT EMBEDDING to RIGHT-TO-LEFT OVERRIDE | ||
582 | || (0x2060 <= $codePoint && 0x2063 >= $codePoint) // WORD JOINER to INVISIBLE SEPARATOR | ||
583 | ) { | ||
584 | continue; | ||
585 | } | ||
586 | |||
587 | // Non printable characters | ||
588 | if (32 > $codePoint // C0 control characters | ||
589 | || (0x07F <= $codePoint && 0x0A0 > $codePoint) // C1 control characters and DEL | ||
590 | ) { | ||
591 | return -1; | ||
592 | } | ||
593 | |||
594 | self::$tableZero ??= require __DIR__.'/Resources/data/wcswidth_table_zero.php'; | ||
595 | |||
596 | if ($codePoint >= self::$tableZero[0][0] && $codePoint <= self::$tableZero[$ubound = \count(self::$tableZero) - 1][1]) { | ||
597 | $lbound = 0; | ||
598 | while ($ubound >= $lbound) { | ||
599 | $mid = floor(($lbound + $ubound) / 2); | ||
600 | |||
601 | if ($codePoint > self::$tableZero[$mid][1]) { | ||
602 | $lbound = $mid + 1; | ||
603 | } elseif ($codePoint < self::$tableZero[$mid][0]) { | ||
604 | $ubound = $mid - 1; | ||
605 | } else { | ||
606 | continue 2; | ||
607 | } | ||
608 | } | ||
609 | } | ||
610 | |||
611 | self::$tableWide ??= require __DIR__.'/Resources/data/wcswidth_table_wide.php'; | ||
612 | |||
613 | if ($codePoint >= self::$tableWide[0][0] && $codePoint <= self::$tableWide[$ubound = \count(self::$tableWide) - 1][1]) { | ||
614 | $lbound = 0; | ||
615 | while ($ubound >= $lbound) { | ||
616 | $mid = floor(($lbound + $ubound) / 2); | ||
617 | |||
618 | if ($codePoint > self::$tableWide[$mid][1]) { | ||
619 | $lbound = $mid + 1; | ||
620 | } elseif ($codePoint < self::$tableWide[$mid][0]) { | ||
621 | $ubound = $mid - 1; | ||
622 | } else { | ||
623 | $width += 2; | ||
624 | |||
625 | continue 2; | ||
626 | } | ||
627 | } | ||
628 | } | ||
629 | |||
630 | ++$width; | ||
631 | } | ||
632 | |||
633 | return $width; | ||
634 | } | ||
635 | |||
636 | private function getLocaleTransliterator(string $locale, string $id): ?\Transliterator | ||
637 | { | ||
638 | $rule = $locale.'-'.$id; | ||
639 | if (\array_key_exists($rule, self::$transliterators)) { | ||
640 | return self::$transliterators[$rule]; | ||
641 | } | ||
642 | |||
643 | if (null !== $transliterator = self::$transliterators[$rule] = \Transliterator::create($rule)) { | ||
644 | return $transliterator; | ||
645 | } | ||
646 | |||
647 | // Try to find a parent locale (nl_BE -> nl) | ||
648 | if (false === $i = strpos($locale, '_')) { | ||
649 | return null; | ||
650 | } | ||
651 | |||
652 | $parentRule = substr_replace($locale, '-'.$id, $i); | ||
653 | |||
654 | // Parent locale was already cached, return and store as current locale | ||
655 | if (\array_key_exists($parentRule, self::$transliterators)) { | ||
656 | return self::$transliterators[$rule] = self::$transliterators[$parentRule]; | ||
657 | } | ||
658 | |||
659 | // Create transliterator based on parent locale and cache the result on both initial and parent locale values | ||
660 | $transliterator = \Transliterator::create($parentRule); | ||
661 | |||
662 | return self::$transliterators[$rule] = self::$transliterators[$parentRule] = $transliterator; | ||
663 | } | ||
664 | } | ||
diff --git a/vendor/symfony/string/ByteString.php b/vendor/symfony/string/ByteString.php new file mode 100644 index 0000000..e6b56ae --- /dev/null +++ b/vendor/symfony/string/ByteString.php | |||
@@ -0,0 +1,490 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\String; | ||
13 | |||
14 | use Random\Randomizer; | ||
15 | use Symfony\Component\String\Exception\ExceptionInterface; | ||
16 | use Symfony\Component\String\Exception\InvalidArgumentException; | ||
17 | use Symfony\Component\String\Exception\RuntimeException; | ||
18 | |||
19 | /** | ||
20 | * Represents a binary-safe string of bytes. | ||
21 | * | ||
22 | * @author Nicolas Grekas <p@tchwork.com> | ||
23 | * @author Hugo Hamon <hugohamon@neuf.fr> | ||
24 | * | ||
25 | * @throws ExceptionInterface | ||
26 | */ | ||
27 | class ByteString extends AbstractString | ||
28 | { | ||
29 | private const ALPHABET_ALPHANUMERIC = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; | ||
30 | |||
31 | public function __construct(string $string = '') | ||
32 | { | ||
33 | $this->string = $string; | ||
34 | } | ||
35 | |||
36 | /* | ||
37 | * The following method was derived from code of the Hack Standard Library (v4.40 - 2020-05-03) | ||
38 | * | ||
39 | * https://github.com/hhvm/hsl/blob/80a42c02f036f72a42f0415e80d6b847f4bf62d5/src/random/private.php#L16 | ||
40 | * | ||
41 | * Code subject to the MIT license (https://github.com/hhvm/hsl/blob/master/LICENSE). | ||
42 | * | ||
43 | * Copyright (c) 2004-2020, Facebook, Inc. (https://www.facebook.com/) | ||
44 | */ | ||
45 | |||
46 | public static function fromRandom(int $length = 16, ?string $alphabet = null): self | ||
47 | { | ||
48 | if ($length <= 0) { | ||
49 | throw new InvalidArgumentException(sprintf('A strictly positive length is expected, "%d" given.', $length)); | ||
50 | } | ||
51 | |||
52 | $alphabet ??= self::ALPHABET_ALPHANUMERIC; | ||
53 | $alphabetSize = \strlen($alphabet); | ||
54 | $bits = (int) ceil(log($alphabetSize, 2.0)); | ||
55 | if ($bits <= 0 || $bits > 56) { | ||
56 | throw new InvalidArgumentException('The length of the alphabet must in the [2^1, 2^56] range.'); | ||
57 | } | ||
58 | |||
59 | if (\PHP_VERSION_ID >= 80300) { | ||
60 | return new static((new Randomizer())->getBytesFromString($alphabet, $length)); | ||
61 | } | ||
62 | |||
63 | $ret = ''; | ||
64 | while ($length > 0) { | ||
65 | $urandomLength = (int) ceil(2 * $length * $bits / 8.0); | ||
66 | $data = random_bytes($urandomLength); | ||
67 | $unpackedData = 0; | ||
68 | $unpackedBits = 0; | ||
69 | for ($i = 0; $i < $urandomLength && $length > 0; ++$i) { | ||
70 | // Unpack 8 bits | ||
71 | $unpackedData = ($unpackedData << 8) | \ord($data[$i]); | ||
72 | $unpackedBits += 8; | ||
73 | |||
74 | // While we have enough bits to select a character from the alphabet, keep | ||
75 | // consuming the random data | ||
76 | for (; $unpackedBits >= $bits && $length > 0; $unpackedBits -= $bits) { | ||
77 | $index = ($unpackedData & ((1 << $bits) - 1)); | ||
78 | $unpackedData >>= $bits; | ||
79 | // Unfortunately, the alphabet size is not necessarily a power of two. | ||
80 | // Worst case, it is 2^k + 1, which means we need (k+1) bits and we | ||
81 | // have around a 50% chance of missing as k gets larger | ||
82 | if ($index < $alphabetSize) { | ||
83 | $ret .= $alphabet[$index]; | ||
84 | --$length; | ||
85 | } | ||
86 | } | ||
87 | } | ||
88 | } | ||
89 | |||
90 | return new static($ret); | ||
91 | } | ||
92 | |||
93 | public function bytesAt(int $offset): array | ||
94 | { | ||
95 | $str = $this->string[$offset] ?? ''; | ||
96 | |||
97 | return '' === $str ? [] : [\ord($str)]; | ||
98 | } | ||
99 | |||
100 | public function append(string ...$suffix): static | ||
101 | { | ||
102 | $str = clone $this; | ||
103 | $str->string .= 1 >= \count($suffix) ? ($suffix[0] ?? '') : implode('', $suffix); | ||
104 | |||
105 | return $str; | ||
106 | } | ||
107 | |||
108 | public function camel(): static | ||
109 | { | ||
110 | $str = clone $this; | ||
111 | |||
112 | $parts = explode(' ', trim(ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $this->string)))); | ||
113 | $parts[0] = 1 !== \strlen($parts[0]) && ctype_upper($parts[0]) ? $parts[0] : lcfirst($parts[0]); | ||
114 | $str->string = implode('', $parts); | ||
115 | |||
116 | return $str; | ||
117 | } | ||
118 | |||
119 | public function chunk(int $length = 1): array | ||
120 | { | ||
121 | if (1 > $length) { | ||
122 | throw new InvalidArgumentException('The chunk length must be greater than zero.'); | ||
123 | } | ||
124 | |||
125 | if ('' === $this->string) { | ||
126 | return []; | ||
127 | } | ||
128 | |||
129 | $str = clone $this; | ||
130 | $chunks = []; | ||
131 | |||
132 | foreach (str_split($this->string, $length) as $chunk) { | ||
133 | $str->string = $chunk; | ||
134 | $chunks[] = clone $str; | ||
135 | } | ||
136 | |||
137 | return $chunks; | ||
138 | } | ||
139 | |||
140 | public function endsWith(string|iterable|AbstractString $suffix): bool | ||
141 | { | ||
142 | if ($suffix instanceof AbstractString) { | ||
143 | $suffix = $suffix->string; | ||
144 | } elseif (!\is_string($suffix)) { | ||
145 | return parent::endsWith($suffix); | ||
146 | } | ||
147 | |||
148 | return '' !== $suffix && \strlen($this->string) >= \strlen($suffix) && 0 === substr_compare($this->string, $suffix, -\strlen($suffix), null, $this->ignoreCase); | ||
149 | } | ||
150 | |||
151 | public function equalsTo(string|iterable|AbstractString $string): bool | ||
152 | { | ||
153 | if ($string instanceof AbstractString) { | ||
154 | $string = $string->string; | ||
155 | } elseif (!\is_string($string)) { | ||
156 | return parent::equalsTo($string); | ||
157 | } | ||
158 | |||
159 | if ('' !== $string && $this->ignoreCase) { | ||
160 | return 0 === strcasecmp($string, $this->string); | ||
161 | } | ||
162 | |||
163 | return $string === $this->string; | ||
164 | } | ||
165 | |||
166 | public function folded(): static | ||
167 | { | ||
168 | $str = clone $this; | ||
169 | $str->string = strtolower($str->string); | ||
170 | |||
171 | return $str; | ||
172 | } | ||
173 | |||
174 | public function indexOf(string|iterable|AbstractString $needle, int $offset = 0): ?int | ||
175 | { | ||
176 | if ($needle instanceof AbstractString) { | ||
177 | $needle = $needle->string; | ||
178 | } elseif (!\is_string($needle)) { | ||
179 | return parent::indexOf($needle, $offset); | ||
180 | } | ||
181 | |||
182 | if ('' === $needle) { | ||
183 | return null; | ||
184 | } | ||
185 | |||
186 | $i = $this->ignoreCase ? stripos($this->string, $needle, $offset) : strpos($this->string, $needle, $offset); | ||
187 | |||
188 | return false === $i ? null : $i; | ||
189 | } | ||
190 | |||
191 | public function indexOfLast(string|iterable|AbstractString $needle, int $offset = 0): ?int | ||
192 | { | ||
193 | if ($needle instanceof AbstractString) { | ||
194 | $needle = $needle->string; | ||
195 | } elseif (!\is_string($needle)) { | ||
196 | return parent::indexOfLast($needle, $offset); | ||
197 | } | ||
198 | |||
199 | if ('' === $needle) { | ||
200 | return null; | ||
201 | } | ||
202 | |||
203 | $i = $this->ignoreCase ? strripos($this->string, $needle, $offset) : strrpos($this->string, $needle, $offset); | ||
204 | |||
205 | return false === $i ? null : $i; | ||
206 | } | ||
207 | |||
208 | public function isUtf8(): bool | ||
209 | { | ||
210 | return '' === $this->string || preg_match('//u', $this->string); | ||
211 | } | ||
212 | |||
213 | public function join(array $strings, ?string $lastGlue = null): static | ||
214 | { | ||
215 | $str = clone $this; | ||
216 | |||
217 | $tail = null !== $lastGlue && 1 < \count($strings) ? $lastGlue.array_pop($strings) : ''; | ||
218 | $str->string = implode($this->string, $strings).$tail; | ||
219 | |||
220 | return $str; | ||
221 | } | ||
222 | |||
223 | public function length(): int | ||
224 | { | ||
225 | return \strlen($this->string); | ||
226 | } | ||
227 | |||
228 | public function lower(): static | ||
229 | { | ||
230 | $str = clone $this; | ||
231 | $str->string = strtolower($str->string); | ||
232 | |||
233 | return $str; | ||
234 | } | ||
235 | |||
236 | public function match(string $regexp, int $flags = 0, int $offset = 0): array | ||
237 | { | ||
238 | $match = ((\PREG_PATTERN_ORDER | \PREG_SET_ORDER) & $flags) ? 'preg_match_all' : 'preg_match'; | ||
239 | |||
240 | if ($this->ignoreCase) { | ||
241 | $regexp .= 'i'; | ||
242 | } | ||
243 | |||
244 | set_error_handler(static fn ($t, $m) => throw new InvalidArgumentException($m)); | ||
245 | |||
246 | try { | ||
247 | if (false === $match($regexp, $this->string, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset)) { | ||
248 | throw new RuntimeException('Matching failed with error: '.preg_last_error_msg()); | ||
249 | } | ||
250 | } finally { | ||
251 | restore_error_handler(); | ||
252 | } | ||
253 | |||
254 | return $matches; | ||
255 | } | ||
256 | |||
257 | public function padBoth(int $length, string $padStr = ' '): static | ||
258 | { | ||
259 | $str = clone $this; | ||
260 | $str->string = str_pad($this->string, $length, $padStr, \STR_PAD_BOTH); | ||
261 | |||
262 | return $str; | ||
263 | } | ||
264 | |||
265 | public function padEnd(int $length, string $padStr = ' '): static | ||
266 | { | ||
267 | $str = clone $this; | ||
268 | $str->string = str_pad($this->string, $length, $padStr, \STR_PAD_RIGHT); | ||
269 | |||
270 | return $str; | ||
271 | } | ||
272 | |||
273 | public function padStart(int $length, string $padStr = ' '): static | ||
274 | { | ||
275 | $str = clone $this; | ||
276 | $str->string = str_pad($this->string, $length, $padStr, \STR_PAD_LEFT); | ||
277 | |||
278 | return $str; | ||
279 | } | ||
280 | |||
281 | public function prepend(string ...$prefix): static | ||
282 | { | ||
283 | $str = clone $this; | ||
284 | $str->string = (1 >= \count($prefix) ? ($prefix[0] ?? '') : implode('', $prefix)).$str->string; | ||
285 | |||
286 | return $str; | ||
287 | } | ||
288 | |||
289 | public function replace(string $from, string $to): static | ||
290 | { | ||
291 | $str = clone $this; | ||
292 | |||
293 | if ('' !== $from) { | ||
294 | $str->string = $this->ignoreCase ? str_ireplace($from, $to, $this->string) : str_replace($from, $to, $this->string); | ||
295 | } | ||
296 | |||
297 | return $str; | ||
298 | } | ||
299 | |||
300 | public function replaceMatches(string $fromRegexp, string|callable $to): static | ||
301 | { | ||
302 | if ($this->ignoreCase) { | ||
303 | $fromRegexp .= 'i'; | ||
304 | } | ||
305 | |||
306 | $replace = \is_array($to) || $to instanceof \Closure ? 'preg_replace_callback' : 'preg_replace'; | ||
307 | |||
308 | set_error_handler(static fn ($t, $m) => throw new InvalidArgumentException($m)); | ||
309 | |||
310 | try { | ||
311 | if (null === $string = $replace($fromRegexp, $to, $this->string)) { | ||
312 | $lastError = preg_last_error(); | ||
313 | |||
314 | foreach (get_defined_constants(true)['pcre'] as $k => $v) { | ||
315 | if ($lastError === $v && str_ends_with($k, '_ERROR')) { | ||
316 | throw new RuntimeException('Matching failed with '.$k.'.'); | ||
317 | } | ||
318 | } | ||
319 | |||
320 | throw new RuntimeException('Matching failed with unknown error code.'); | ||
321 | } | ||
322 | } finally { | ||
323 | restore_error_handler(); | ||
324 | } | ||
325 | |||
326 | $str = clone $this; | ||
327 | $str->string = $string; | ||
328 | |||
329 | return $str; | ||
330 | } | ||
331 | |||
332 | public function reverse(): static | ||
333 | { | ||
334 | $str = clone $this; | ||
335 | $str->string = strrev($str->string); | ||
336 | |||
337 | return $str; | ||
338 | } | ||
339 | |||
340 | public function slice(int $start = 0, ?int $length = null): static | ||
341 | { | ||
342 | $str = clone $this; | ||
343 | $str->string = (string) substr($this->string, $start, $length ?? \PHP_INT_MAX); | ||
344 | |||
345 | return $str; | ||
346 | } | ||
347 | |||
348 | public function snake(): static | ||
349 | { | ||
350 | $str = $this->camel(); | ||
351 | $str->string = strtolower(preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'], '\1_\2', $str->string)); | ||
352 | |||
353 | return $str; | ||
354 | } | ||
355 | |||
356 | public function splice(string $replacement, int $start = 0, ?int $length = null): static | ||
357 | { | ||
358 | $str = clone $this; | ||
359 | $str->string = substr_replace($this->string, $replacement, $start, $length ?? \PHP_INT_MAX); | ||
360 | |||
361 | return $str; | ||
362 | } | ||
363 | |||
364 | public function split(string $delimiter, ?int $limit = null, ?int $flags = null): array | ||
365 | { | ||
366 | if (1 > $limit ??= \PHP_INT_MAX) { | ||
367 | throw new InvalidArgumentException('Split limit must be a positive integer.'); | ||
368 | } | ||
369 | |||
370 | if ('' === $delimiter) { | ||
371 | throw new InvalidArgumentException('Split delimiter is empty.'); | ||
372 | } | ||
373 | |||
374 | if (null !== $flags) { | ||
375 | return parent::split($delimiter, $limit, $flags); | ||
376 | } | ||
377 | |||
378 | $str = clone $this; | ||
379 | $chunks = $this->ignoreCase | ||
380 | ? preg_split('{'.preg_quote($delimiter).'}iD', $this->string, $limit) | ||
381 | : explode($delimiter, $this->string, $limit); | ||
382 | |||
383 | foreach ($chunks as &$chunk) { | ||
384 | $str->string = $chunk; | ||
385 | $chunk = clone $str; | ||
386 | } | ||
387 | |||
388 | return $chunks; | ||
389 | } | ||
390 | |||
391 | public function startsWith(string|iterable|AbstractString $prefix): bool | ||
392 | { | ||
393 | if ($prefix instanceof AbstractString) { | ||
394 | $prefix = $prefix->string; | ||
395 | } elseif (!\is_string($prefix)) { | ||
396 | return parent::startsWith($prefix); | ||
397 | } | ||
398 | |||
399 | return '' !== $prefix && 0 === ($this->ignoreCase ? strncasecmp($this->string, $prefix, \strlen($prefix)) : strncmp($this->string, $prefix, \strlen($prefix))); | ||
400 | } | ||
401 | |||
402 | public function title(bool $allWords = false): static | ||
403 | { | ||
404 | $str = clone $this; | ||
405 | $str->string = $allWords ? ucwords($str->string) : ucfirst($str->string); | ||
406 | |||
407 | return $str; | ||
408 | } | ||
409 | |||
410 | public function toUnicodeString(?string $fromEncoding = null): UnicodeString | ||
411 | { | ||
412 | return new UnicodeString($this->toCodePointString($fromEncoding)->string); | ||
413 | } | ||
414 | |||
415 | public function toCodePointString(?string $fromEncoding = null): CodePointString | ||
416 | { | ||
417 | $u = new CodePointString(); | ||
418 | |||
419 | if (\in_array($fromEncoding, [null, 'utf8', 'utf-8', 'UTF8', 'UTF-8'], true) && preg_match('//u', $this->string)) { | ||
420 | $u->string = $this->string; | ||
421 | |||
422 | return $u; | ||
423 | } | ||
424 | |||
425 | set_error_handler(static fn ($t, $m) => throw new InvalidArgumentException($m)); | ||
426 | |||
427 | try { | ||
428 | try { | ||
429 | $validEncoding = false !== mb_detect_encoding($this->string, $fromEncoding ?? 'Windows-1252', true); | ||
430 | } catch (InvalidArgumentException $e) { | ||
431 | if (!\function_exists('iconv')) { | ||
432 | throw $e; | ||
433 | } | ||
434 | |||
435 | $u->string = iconv($fromEncoding ?? 'Windows-1252', 'UTF-8', $this->string); | ||
436 | |||
437 | return $u; | ||
438 | } | ||
439 | } finally { | ||
440 | restore_error_handler(); | ||
441 | } | ||
442 | |||
443 | if (!$validEncoding) { | ||
444 | throw new InvalidArgumentException(sprintf('Invalid "%s" string.', $fromEncoding ?? 'Windows-1252')); | ||
445 | } | ||
446 | |||
447 | $u->string = mb_convert_encoding($this->string, 'UTF-8', $fromEncoding ?? 'Windows-1252'); | ||
448 | |||
449 | return $u; | ||
450 | } | ||
451 | |||
452 | public function trim(string $chars = " \t\n\r\0\x0B\x0C"): static | ||
453 | { | ||
454 | $str = clone $this; | ||
455 | $str->string = trim($str->string, $chars); | ||
456 | |||
457 | return $str; | ||
458 | } | ||
459 | |||
460 | public function trimEnd(string $chars = " \t\n\r\0\x0B\x0C"): static | ||
461 | { | ||
462 | $str = clone $this; | ||
463 | $str->string = rtrim($str->string, $chars); | ||
464 | |||
465 | return $str; | ||
466 | } | ||
467 | |||
468 | public function trimStart(string $chars = " \t\n\r\0\x0B\x0C"): static | ||
469 | { | ||
470 | $str = clone $this; | ||
471 | $str->string = ltrim($str->string, $chars); | ||
472 | |||
473 | return $str; | ||
474 | } | ||
475 | |||
476 | public function upper(): static | ||
477 | { | ||
478 | $str = clone $this; | ||
479 | $str->string = strtoupper($str->string); | ||
480 | |||
481 | return $str; | ||
482 | } | ||
483 | |||
484 | public function width(bool $ignoreAnsiDecoration = true): int | ||
485 | { | ||
486 | $string = preg_match('//u', $this->string) ? $this->string : preg_replace('/[\x80-\xFF]/', '?', $this->string); | ||
487 | |||
488 | return (new CodePointString($string))->width($ignoreAnsiDecoration); | ||
489 | } | ||
490 | } | ||
diff --git a/vendor/symfony/string/CHANGELOG.md b/vendor/symfony/string/CHANGELOG.md new file mode 100644 index 0000000..621cedf --- /dev/null +++ b/vendor/symfony/string/CHANGELOG.md | |||
@@ -0,0 +1,45 @@ | |||
1 | CHANGELOG | ||
2 | ========= | ||
3 | |||
4 | 7.1 | ||
5 | --- | ||
6 | |||
7 | * Add `localeLower()`, `localeUpper()`, `localeTitle()` methods to `AbstractUnicodeString` | ||
8 | |||
9 | 6.2 | ||
10 | --- | ||
11 | |||
12 | * Add support for emoji in `AsciiSlugger` | ||
13 | |||
14 | 5.4 | ||
15 | --- | ||
16 | |||
17 | * Add `trimSuffix()` and `trimPrefix()` methods | ||
18 | |||
19 | 5.3 | ||
20 | --- | ||
21 | |||
22 | * Made `AsciiSlugger` fallback to parent locale's symbolsMap | ||
23 | |||
24 | 5.2.0 | ||
25 | ----- | ||
26 | |||
27 | * added a `FrenchInflector` class | ||
28 | |||
29 | 5.1.0 | ||
30 | ----- | ||
31 | |||
32 | * added the `AbstractString::reverse()` method | ||
33 | * made `AbstractString::width()` follow POSIX.1-2001 | ||
34 | * added `LazyString` which provides memoizing stringable objects | ||
35 | * The component is not marked as `@experimental` anymore | ||
36 | * added the `s()` helper method to get either an `UnicodeString` or `ByteString` instance, | ||
37 | depending of the input string UTF-8 compliancy | ||
38 | * added `$cut` parameter to `Symfony\Component\String\AbstractString::truncate()` | ||
39 | * added `AbstractString::containsAny()` | ||
40 | * allow passing a string of custom characters to `ByteString::fromRandom()` | ||
41 | |||
42 | 5.0.0 | ||
43 | ----- | ||
44 | |||
45 | * added the component as experimental | ||
diff --git a/vendor/symfony/string/CodePointString.php b/vendor/symfony/string/CodePointString.php new file mode 100644 index 0000000..337bfc1 --- /dev/null +++ b/vendor/symfony/string/CodePointString.php | |||
@@ -0,0 +1,260 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\String; | ||
13 | |||
14 | use Symfony\Component\String\Exception\ExceptionInterface; | ||
15 | use Symfony\Component\String\Exception\InvalidArgumentException; | ||
16 | |||
17 | /** | ||
18 | * Represents a string of Unicode code points encoded as UTF-8. | ||
19 | * | ||
20 | * @author Nicolas Grekas <p@tchwork.com> | ||
21 | * @author Hugo Hamon <hugohamon@neuf.fr> | ||
22 | * | ||
23 | * @throws ExceptionInterface | ||
24 | */ | ||
25 | class CodePointString extends AbstractUnicodeString | ||
26 | { | ||
27 | public function __construct(string $string = '') | ||
28 | { | ||
29 | if ('' !== $string && !preg_match('//u', $string)) { | ||
30 | throw new InvalidArgumentException('Invalid UTF-8 string.'); | ||
31 | } | ||
32 | |||
33 | $this->string = $string; | ||
34 | } | ||
35 | |||
36 | public function append(string ...$suffix): static | ||
37 | { | ||
38 | $str = clone $this; | ||
39 | $str->string .= 1 >= \count($suffix) ? ($suffix[0] ?? '') : implode('', $suffix); | ||
40 | |||
41 | if (!preg_match('//u', $str->string)) { | ||
42 | throw new InvalidArgumentException('Invalid UTF-8 string.'); | ||
43 | } | ||
44 | |||
45 | return $str; | ||
46 | } | ||
47 | |||
48 | public function chunk(int $length = 1): array | ||
49 | { | ||
50 | if (1 > $length) { | ||
51 | throw new InvalidArgumentException('The chunk length must be greater than zero.'); | ||
52 | } | ||
53 | |||
54 | if ('' === $this->string) { | ||
55 | return []; | ||
56 | } | ||
57 | |||
58 | $rx = '/('; | ||
59 | while (65535 < $length) { | ||
60 | $rx .= '.{65535}'; | ||
61 | $length -= 65535; | ||
62 | } | ||
63 | $rx .= '.{'.$length.'})/us'; | ||
64 | |||
65 | $str = clone $this; | ||
66 | $chunks = []; | ||
67 | |||
68 | foreach (preg_split($rx, $this->string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY) as $chunk) { | ||
69 | $str->string = $chunk; | ||
70 | $chunks[] = clone $str; | ||
71 | } | ||
72 | |||
73 | return $chunks; | ||
74 | } | ||
75 | |||
76 | public function codePointsAt(int $offset): array | ||
77 | { | ||
78 | $str = $offset ? $this->slice($offset, 1) : $this; | ||
79 | |||
80 | return '' === $str->string ? [] : [mb_ord($str->string, 'UTF-8')]; | ||
81 | } | ||
82 | |||
83 | public function endsWith(string|iterable|AbstractString $suffix): bool | ||
84 | { | ||
85 | if ($suffix instanceof AbstractString) { | ||
86 | $suffix = $suffix->string; | ||
87 | } elseif (!\is_string($suffix)) { | ||
88 | return parent::endsWith($suffix); | ||
89 | } | ||
90 | |||
91 | if ('' === $suffix || !preg_match('//u', $suffix)) { | ||
92 | return false; | ||
93 | } | ||
94 | |||
95 | if ($this->ignoreCase) { | ||
96 | return preg_match('{'.preg_quote($suffix).'$}iuD', $this->string); | ||
97 | } | ||
98 | |||
99 | return \strlen($this->string) >= \strlen($suffix) && 0 === substr_compare($this->string, $suffix, -\strlen($suffix)); | ||
100 | } | ||
101 | |||
102 | public function equalsTo(string|iterable|AbstractString $string): bool | ||
103 | { | ||
104 | if ($string instanceof AbstractString) { | ||
105 | $string = $string->string; | ||
106 | } elseif (!\is_string($string)) { | ||
107 | return parent::equalsTo($string); | ||
108 | } | ||
109 | |||
110 | if ('' !== $string && $this->ignoreCase) { | ||
111 | return \strlen($string) === \strlen($this->string) && 0 === mb_stripos($this->string, $string, 0, 'UTF-8'); | ||
112 | } | ||
113 | |||
114 | return $string === $this->string; | ||
115 | } | ||
116 | |||
117 | public function indexOf(string|iterable|AbstractString $needle, int $offset = 0): ?int | ||
118 | { | ||
119 | if ($needle instanceof AbstractString) { | ||
120 | $needle = $needle->string; | ||
121 | } elseif (!\is_string($needle)) { | ||
122 | return parent::indexOf($needle, $offset); | ||
123 | } | ||
124 | |||
125 | if ('' === $needle) { | ||
126 | return null; | ||
127 | } | ||
128 | |||
129 | $i = $this->ignoreCase ? mb_stripos($this->string, $needle, $offset, 'UTF-8') : mb_strpos($this->string, $needle, $offset, 'UTF-8'); | ||
130 | |||
131 | return false === $i ? null : $i; | ||
132 | } | ||
133 | |||
134 | public function indexOfLast(string|iterable|AbstractString $needle, int $offset = 0): ?int | ||
135 | { | ||
136 | if ($needle instanceof AbstractString) { | ||
137 | $needle = $needle->string; | ||
138 | } elseif (!\is_string($needle)) { | ||
139 | return parent::indexOfLast($needle, $offset); | ||
140 | } | ||
141 | |||
142 | if ('' === $needle) { | ||
143 | return null; | ||
144 | } | ||
145 | |||
146 | $i = $this->ignoreCase ? mb_strripos($this->string, $needle, $offset, 'UTF-8') : mb_strrpos($this->string, $needle, $offset, 'UTF-8'); | ||
147 | |||
148 | return false === $i ? null : $i; | ||
149 | } | ||
150 | |||
151 | public function length(): int | ||
152 | { | ||
153 | return mb_strlen($this->string, 'UTF-8'); | ||
154 | } | ||
155 | |||
156 | public function prepend(string ...$prefix): static | ||
157 | { | ||
158 | $str = clone $this; | ||
159 | $str->string = (1 >= \count($prefix) ? ($prefix[0] ?? '') : implode('', $prefix)).$this->string; | ||
160 | |||
161 | if (!preg_match('//u', $str->string)) { | ||
162 | throw new InvalidArgumentException('Invalid UTF-8 string.'); | ||
163 | } | ||
164 | |||
165 | return $str; | ||
166 | } | ||
167 | |||
168 | public function replace(string $from, string $to): static | ||
169 | { | ||
170 | $str = clone $this; | ||
171 | |||
172 | if ('' === $from || !preg_match('//u', $from)) { | ||
173 | return $str; | ||
174 | } | ||
175 | |||
176 | if ('' !== $to && !preg_match('//u', $to)) { | ||
177 | throw new InvalidArgumentException('Invalid UTF-8 string.'); | ||
178 | } | ||
179 | |||
180 | if ($this->ignoreCase) { | ||
181 | $str->string = implode($to, preg_split('{'.preg_quote($from).'}iuD', $this->string)); | ||
182 | } else { | ||
183 | $str->string = str_replace($from, $to, $this->string); | ||
184 | } | ||
185 | |||
186 | return $str; | ||
187 | } | ||
188 | |||
189 | public function slice(int $start = 0, ?int $length = null): static | ||
190 | { | ||
191 | $str = clone $this; | ||
192 | $str->string = mb_substr($this->string, $start, $length, 'UTF-8'); | ||
193 | |||
194 | return $str; | ||
195 | } | ||
196 | |||
197 | public function splice(string $replacement, int $start = 0, ?int $length = null): static | ||
198 | { | ||
199 | if (!preg_match('//u', $replacement)) { | ||
200 | throw new InvalidArgumentException('Invalid UTF-8 string.'); | ||
201 | } | ||
202 | |||
203 | $str = clone $this; | ||
204 | $start = $start ? \strlen(mb_substr($this->string, 0, $start, 'UTF-8')) : 0; | ||
205 | $length = $length ? \strlen(mb_substr($this->string, $start, $length, 'UTF-8')) : $length; | ||
206 | $str->string = substr_replace($this->string, $replacement, $start, $length ?? \PHP_INT_MAX); | ||
207 | |||
208 | return $str; | ||
209 | } | ||
210 | |||
211 | public function split(string $delimiter, ?int $limit = null, ?int $flags = null): array | ||
212 | { | ||
213 | if (1 > $limit ??= \PHP_INT_MAX) { | ||
214 | throw new InvalidArgumentException('Split limit must be a positive integer.'); | ||
215 | } | ||
216 | |||
217 | if ('' === $delimiter) { | ||
218 | throw new InvalidArgumentException('Split delimiter is empty.'); | ||
219 | } | ||
220 | |||
221 | if (null !== $flags) { | ||
222 | return parent::split($delimiter.'u', $limit, $flags); | ||
223 | } | ||
224 | |||
225 | if (!preg_match('//u', $delimiter)) { | ||
226 | throw new InvalidArgumentException('Split delimiter is not a valid UTF-8 string.'); | ||
227 | } | ||
228 | |||
229 | $str = clone $this; | ||
230 | $chunks = $this->ignoreCase | ||
231 | ? preg_split('{'.preg_quote($delimiter).'}iuD', $this->string, $limit) | ||
232 | : explode($delimiter, $this->string, $limit); | ||
233 | |||
234 | foreach ($chunks as &$chunk) { | ||
235 | $str->string = $chunk; | ||
236 | $chunk = clone $str; | ||
237 | } | ||
238 | |||
239 | return $chunks; | ||
240 | } | ||
241 | |||
242 | public function startsWith(string|iterable|AbstractString $prefix): bool | ||
243 | { | ||
244 | if ($prefix instanceof AbstractString) { | ||
245 | $prefix = $prefix->string; | ||
246 | } elseif (!\is_string($prefix)) { | ||
247 | return parent::startsWith($prefix); | ||
248 | } | ||
249 | |||
250 | if ('' === $prefix || !preg_match('//u', $prefix)) { | ||
251 | return false; | ||
252 | } | ||
253 | |||
254 | if ($this->ignoreCase) { | ||
255 | return 0 === mb_stripos($this->string, $prefix, 0, 'UTF-8'); | ||
256 | } | ||
257 | |||
258 | return 0 === strncmp($this->string, $prefix, \strlen($prefix)); | ||
259 | } | ||
260 | } | ||
diff --git a/vendor/symfony/string/Exception/ExceptionInterface.php b/vendor/symfony/string/Exception/ExceptionInterface.php new file mode 100644 index 0000000..3619786 --- /dev/null +++ b/vendor/symfony/string/Exception/ExceptionInterface.php | |||
@@ -0,0 +1,16 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\String\Exception; | ||
13 | |||
14 | interface ExceptionInterface extends \Throwable | ||
15 | { | ||
16 | } | ||
diff --git a/vendor/symfony/string/Exception/InvalidArgumentException.php b/vendor/symfony/string/Exception/InvalidArgumentException.php new file mode 100644 index 0000000..6aa586b --- /dev/null +++ b/vendor/symfony/string/Exception/InvalidArgumentException.php | |||
@@ -0,0 +1,16 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\String\Exception; | ||
13 | |||
14 | class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface | ||
15 | { | ||
16 | } | ||
diff --git a/vendor/symfony/string/Exception/RuntimeException.php b/vendor/symfony/string/Exception/RuntimeException.php new file mode 100644 index 0000000..77cb091 --- /dev/null +++ b/vendor/symfony/string/Exception/RuntimeException.php | |||
@@ -0,0 +1,16 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\String\Exception; | ||
13 | |||
14 | class RuntimeException extends \RuntimeException implements ExceptionInterface | ||
15 | { | ||
16 | } | ||
diff --git a/vendor/symfony/string/Inflector/EnglishInflector.php b/vendor/symfony/string/Inflector/EnglishInflector.php new file mode 100644 index 0000000..77ebc13 --- /dev/null +++ b/vendor/symfony/string/Inflector/EnglishInflector.php | |||
@@ -0,0 +1,577 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\String\Inflector; | ||
13 | |||
14 | final class EnglishInflector implements InflectorInterface | ||
15 | { | ||
16 | /** | ||
17 | * Map English plural to singular suffixes. | ||
18 | * | ||
19 | * @see http://english-zone.com/spelling/plurals.html | ||
20 | */ | ||
21 | private const PLURAL_MAP = [ | ||
22 | // First entry: plural suffix, reversed | ||
23 | // Second entry: length of plural suffix | ||
24 | // Third entry: Whether the suffix may succeed a vowel | ||
25 | // Fourth entry: Whether the suffix may succeed a consonant | ||
26 | // Fifth entry: singular suffix, normal | ||
27 | |||
28 | // bacteria (bacterium) | ||
29 | ['airetcab', 8, true, true, 'bacterium'], | ||
30 | |||
31 | // corpora (corpus) | ||
32 | ['aroproc', 7, true, true, 'corpus'], | ||
33 | |||
34 | // criteria (criterion) | ||
35 | ['airetirc', 8, true, true, 'criterion'], | ||
36 | |||
37 | // curricula (curriculum) | ||
38 | ['alucirruc', 9, true, true, 'curriculum'], | ||
39 | |||
40 | // genera (genus) | ||
41 | ['areneg', 6, true, true, 'genus'], | ||
42 | |||
43 | // media (medium) | ||
44 | ['aidem', 5, true, true, 'medium'], | ||
45 | |||
46 | // memoranda (memorandum) | ||
47 | ['adnaromem', 9, true, true, 'memorandum'], | ||
48 | |||
49 | // phenomena (phenomenon) | ||
50 | ['anemonehp', 9, true, true, 'phenomenon'], | ||
51 | |||
52 | // strata (stratum) | ||
53 | ['atarts', 6, true, true, 'stratum'], | ||
54 | |||
55 | // nebulae (nebula) | ||
56 | ['ea', 2, true, true, 'a'], | ||
57 | |||
58 | // services (service) | ||
59 | ['secivres', 8, true, true, 'service'], | ||
60 | |||
61 | // mice (mouse), lice (louse) | ||
62 | ['eci', 3, false, true, 'ouse'], | ||
63 | |||
64 | // geese (goose) | ||
65 | ['esee', 4, false, true, 'oose'], | ||
66 | |||
67 | // fungi (fungus), alumni (alumnus), syllabi (syllabus), radii (radius) | ||
68 | ['i', 1, true, true, 'us'], | ||
69 | |||
70 | // men (man), women (woman) | ||
71 | ['nem', 3, true, true, 'man'], | ||
72 | |||
73 | // children (child) | ||
74 | ['nerdlihc', 8, true, true, 'child'], | ||
75 | |||
76 | // oxen (ox) | ||
77 | ['nexo', 4, false, false, 'ox'], | ||
78 | |||
79 | // indices (index), appendices (appendix), prices (price) | ||
80 | ['seci', 4, false, true, ['ex', 'ix', 'ice']], | ||
81 | |||
82 | // codes (code) | ||
83 | ['sedoc', 5, false, true, 'code'], | ||
84 | |||
85 | // selfies (selfie) | ||
86 | ['seifles', 7, true, true, 'selfie'], | ||
87 | |||
88 | // zombies (zombie) | ||
89 | ['seibmoz', 7, true, true, 'zombie'], | ||
90 | |||
91 | // movies (movie) | ||
92 | ['seivom', 6, true, true, 'movie'], | ||
93 | |||
94 | // names (name) | ||
95 | ['seman', 5, true, false, 'name'], | ||
96 | |||
97 | // conspectuses (conspectus), prospectuses (prospectus) | ||
98 | ['sesutcep', 8, true, true, 'pectus'], | ||
99 | |||
100 | // feet (foot) | ||
101 | ['teef', 4, true, true, 'foot'], | ||
102 | |||
103 | // geese (goose) | ||
104 | ['eseeg', 5, true, true, 'goose'], | ||
105 | |||
106 | // teeth (tooth) | ||
107 | ['hteet', 5, true, true, 'tooth'], | ||
108 | |||
109 | // news (news) | ||
110 | ['swen', 4, true, true, 'news'], | ||
111 | |||
112 | // series (series) | ||
113 | ['seires', 6, true, true, 'series'], | ||
114 | |||
115 | // babies (baby) | ||
116 | ['sei', 3, false, true, 'y'], | ||
117 | |||
118 | // accesses (access), addresses (address), kisses (kiss) | ||
119 | ['sess', 4, true, false, 'ss'], | ||
120 | |||
121 | // statuses (status) | ||
122 | ['sesutats', 8, true, true, 'status'], | ||
123 | |||
124 | // analyses (analysis), ellipses (ellipsis), fungi (fungus), | ||
125 | // neuroses (neurosis), theses (thesis), emphases (emphasis), | ||
126 | // oases (oasis), crises (crisis), houses (house), bases (base), | ||
127 | // atlases (atlas) | ||
128 | ['ses', 3, true, true, ['s', 'se', 'sis']], | ||
129 | |||
130 | // objectives (objective), alternative (alternatives) | ||
131 | ['sevit', 5, true, true, 'tive'], | ||
132 | |||
133 | // drives (drive) | ||
134 | ['sevird', 6, false, true, 'drive'], | ||
135 | |||
136 | // lives (life), wives (wife) | ||
137 | ['sevi', 4, false, true, 'ife'], | ||
138 | |||
139 | // moves (move) | ||
140 | ['sevom', 5, true, true, 'move'], | ||
141 | |||
142 | // hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf), caves (cave), staves (staff) | ||
143 | ['sev', 3, true, true, ['f', 've', 'ff']], | ||
144 | |||
145 | // axes (axis), axes (ax), axes (axe) | ||
146 | ['sexa', 4, false, false, ['ax', 'axe', 'axis']], | ||
147 | |||
148 | // indexes (index), matrixes (matrix) | ||
149 | ['sex', 3, true, false, 'x'], | ||
150 | |||
151 | // quizzes (quiz) | ||
152 | ['sezz', 4, true, false, 'z'], | ||
153 | |||
154 | // bureaus (bureau) | ||
155 | ['suae', 4, false, true, 'eau'], | ||
156 | |||
157 | // fees (fee), trees (tree), employees (employee) | ||
158 | ['see', 3, true, true, 'ee'], | ||
159 | |||
160 | // edges (edge) | ||
161 | ['segd', 4, true, true, 'dge'], | ||
162 | |||
163 | // roses (rose), garages (garage), cassettes (cassette), | ||
164 | // waltzes (waltz), heroes (hero), bushes (bush), arches (arch), | ||
165 | // shoes (shoe) | ||
166 | ['se', 2, true, true, ['', 'e']], | ||
167 | |||
168 | // status (status) | ||
169 | ['sutats', 6, true, true, 'status'], | ||
170 | |||
171 | // tags (tag) | ||
172 | ['s', 1, true, true, ''], | ||
173 | |||
174 | // chateaux (chateau) | ||
175 | ['xuae', 4, false, true, 'eau'], | ||
176 | |||
177 | // people (person) | ||
178 | ['elpoep', 6, true, true, 'person'], | ||
179 | ]; | ||
180 | |||
181 | /** | ||
182 | * Map English singular to plural suffixes. | ||
183 | * | ||
184 | * @see http://english-zone.com/spelling/plurals.html | ||
185 | */ | ||
186 | private const SINGULAR_MAP = [ | ||
187 | // First entry: singular suffix, reversed | ||
188 | // Second entry: length of singular suffix | ||
189 | // Third entry: Whether the suffix may succeed a vowel | ||
190 | // Fourth entry: Whether the suffix may succeed a consonant | ||
191 | // Fifth entry: plural suffix, normal | ||
192 | |||
193 | // axes (axis) | ||
194 | ['sixa', 4, false, false, 'axes'], | ||
195 | |||
196 | // criterion (criteria) | ||
197 | ['airetirc', 8, false, false, 'criterion'], | ||
198 | |||
199 | // nebulae (nebula) | ||
200 | ['aluben', 6, false, false, 'nebulae'], | ||
201 | |||
202 | // children (child) | ||
203 | ['dlihc', 5, true, true, 'children'], | ||
204 | |||
205 | // prices (price) | ||
206 | ['eci', 3, false, true, 'ices'], | ||
207 | |||
208 | // services (service) | ||
209 | ['ecivres', 7, true, true, 'services'], | ||
210 | |||
211 | // lives (life), wives (wife) | ||
212 | ['efi', 3, false, true, 'ives'], | ||
213 | |||
214 | // selfies (selfie) | ||
215 | ['eifles', 6, true, true, 'selfies'], | ||
216 | |||
217 | // movies (movie) | ||
218 | ['eivom', 5, true, true, 'movies'], | ||
219 | |||
220 | // lice (louse) | ||
221 | ['esuol', 5, false, true, 'lice'], | ||
222 | |||
223 | // mice (mouse) | ||
224 | ['esuom', 5, false, true, 'mice'], | ||
225 | |||
226 | // geese (goose) | ||
227 | ['esoo', 4, false, true, 'eese'], | ||
228 | |||
229 | // houses (house), bases (base) | ||
230 | ['es', 2, true, true, 'ses'], | ||
231 | |||
232 | // geese (goose) | ||
233 | ['esoog', 5, true, true, 'geese'], | ||
234 | |||
235 | // caves (cave) | ||
236 | ['ev', 2, true, true, 'ves'], | ||
237 | |||
238 | // drives (drive) | ||
239 | ['evird', 5, false, true, 'drives'], | ||
240 | |||
241 | // objectives (objective), alternative (alternatives) | ||
242 | ['evit', 4, true, true, 'tives'], | ||
243 | |||
244 | // moves (move) | ||
245 | ['evom', 4, true, true, 'moves'], | ||
246 | |||
247 | // staves (staff) | ||
248 | ['ffats', 5, true, true, 'staves'], | ||
249 | |||
250 | // hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf) | ||
251 | ['ff', 2, true, true, 'ffs'], | ||
252 | |||
253 | // hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf) | ||
254 | ['f', 1, true, true, ['fs', 'ves']], | ||
255 | |||
256 | // arches (arch) | ||
257 | ['hc', 2, true, true, 'ches'], | ||
258 | |||
259 | // bushes (bush) | ||
260 | ['hs', 2, true, true, 'shes'], | ||
261 | |||
262 | // teeth (tooth) | ||
263 | ['htoot', 5, true, true, 'teeth'], | ||
264 | |||
265 | // albums (album) | ||
266 | ['mubla', 5, true, true, 'albums'], | ||
267 | |||
268 | // bacteria (bacterium), curricula (curriculum), media (medium), memoranda (memorandum), phenomena (phenomenon), strata (stratum) | ||
269 | ['mu', 2, true, true, 'a'], | ||
270 | |||
271 | // men (man), women (woman) | ||
272 | ['nam', 3, true, true, 'men'], | ||
273 | |||
274 | // people (person) | ||
275 | ['nosrep', 6, true, true, ['persons', 'people']], | ||
276 | |||
277 | // criteria (criterion) | ||
278 | ['noiretirc', 9, true, true, 'criteria'], | ||
279 | |||
280 | // phenomena (phenomenon) | ||
281 | ['nonemonehp', 10, true, true, 'phenomena'], | ||
282 | |||
283 | // echoes (echo) | ||
284 | ['ohce', 4, true, true, 'echoes'], | ||
285 | |||
286 | // heroes (hero) | ||
287 | ['oreh', 4, true, true, 'heroes'], | ||
288 | |||
289 | // atlases (atlas) | ||
290 | ['salta', 5, true, true, 'atlases'], | ||
291 | |||
292 | // aliases (alias) | ||
293 | ['saila', 5, true, true, 'aliases'], | ||
294 | |||
295 | // irises (iris) | ||
296 | ['siri', 4, true, true, 'irises'], | ||
297 | |||
298 | // analyses (analysis), ellipses (ellipsis), neuroses (neurosis) | ||
299 | // theses (thesis), emphases (emphasis), oases (oasis), | ||
300 | // crises (crisis) | ||
301 | ['sis', 3, true, true, 'ses'], | ||
302 | |||
303 | // accesses (access), addresses (address), kisses (kiss) | ||
304 | ['ss', 2, true, false, 'sses'], | ||
305 | |||
306 | // syllabi (syllabus) | ||
307 | ['suballys', 8, true, true, 'syllabi'], | ||
308 | |||
309 | // buses (bus) | ||
310 | ['sub', 3, true, true, 'buses'], | ||
311 | |||
312 | // circuses (circus) | ||
313 | ['suc', 3, true, true, 'cuses'], | ||
314 | |||
315 | // hippocampi (hippocampus) | ||
316 | ['supmacoppih', 11, false, false, 'hippocampi'], | ||
317 | |||
318 | // campuses (campus) | ||
319 | ['sup', 3, true, true, 'puses'], | ||
320 | |||
321 | // status (status) | ||
322 | ['sutats', 6, true, true, ['status', 'statuses']], | ||
323 | |||
324 | // conspectuses (conspectus), prospectuses (prospectus) | ||
325 | ['sutcep', 6, true, true, 'pectuses'], | ||
326 | |||
327 | // fungi (fungus), alumni (alumnus), syllabi (syllabus), radii (radius) | ||
328 | ['su', 2, true, true, 'i'], | ||
329 | |||
330 | // news (news) | ||
331 | ['swen', 4, true, true, 'news'], | ||
332 | |||
333 | // feet (foot) | ||
334 | ['toof', 4, true, true, 'feet'], | ||
335 | |||
336 | // chateaux (chateau), bureaus (bureau) | ||
337 | ['uae', 3, false, true, ['eaus', 'eaux']], | ||
338 | |||
339 | // oxen (ox) | ||
340 | ['xo', 2, false, false, 'oxen'], | ||
341 | |||
342 | // hoaxes (hoax) | ||
343 | ['xaoh', 4, true, false, 'hoaxes'], | ||
344 | |||
345 | // indices (index) | ||
346 | ['xedni', 5, false, true, ['indicies', 'indexes']], | ||
347 | |||
348 | // boxes (box) | ||
349 | ['xo', 2, false, true, 'oxes'], | ||
350 | |||
351 | // indexes (index), matrixes (matrix) | ||
352 | ['x', 1, true, false, ['cies', 'xes']], | ||
353 | |||
354 | // appendices (appendix) | ||
355 | ['xi', 2, false, true, 'ices'], | ||
356 | |||
357 | // babies (baby) | ||
358 | ['y', 1, false, true, 'ies'], | ||
359 | |||
360 | // quizzes (quiz) | ||
361 | ['ziuq', 4, true, false, 'quizzes'], | ||
362 | |||
363 | // waltzes (waltz) | ||
364 | ['z', 1, true, true, 'zes'], | ||
365 | ]; | ||
366 | |||
367 | /** | ||
368 | * A list of words which should not be inflected, reversed. | ||
369 | */ | ||
370 | private const UNINFLECTED = [ | ||
371 | '', | ||
372 | |||
373 | // data | ||
374 | 'atad', | ||
375 | |||
376 | // deer | ||
377 | 'reed', | ||
378 | |||
379 | // equipment | ||
380 | 'tnempiuqe', | ||
381 | |||
382 | // feedback | ||
383 | 'kcabdeef', | ||
384 | |||
385 | // fish | ||
386 | 'hsif', | ||
387 | |||
388 | // health | ||
389 | 'htlaeh', | ||
390 | |||
391 | // history | ||
392 | 'yrotsih', | ||
393 | |||
394 | // info | ||
395 | 'ofni', | ||
396 | |||
397 | // information | ||
398 | 'noitamrofni', | ||
399 | |||
400 | // money | ||
401 | 'yenom', | ||
402 | |||
403 | // moose | ||
404 | 'esoom', | ||
405 | |||
406 | // series | ||
407 | 'seires', | ||
408 | |||
409 | // sheep | ||
410 | 'peehs', | ||
411 | |||
412 | // species | ||
413 | 'seiceps', | ||
414 | |||
415 | // traffic | ||
416 | 'ciffart', | ||
417 | |||
418 | // aircraft | ||
419 | 'tfarcria', | ||
420 | |||
421 | // hardware | ||
422 | 'erawdrah', | ||
423 | ]; | ||
424 | |||
425 | public function singularize(string $plural): array | ||
426 | { | ||
427 | $pluralRev = strrev($plural); | ||
428 | $lowerPluralRev = strtolower($pluralRev); | ||
429 | $pluralLength = \strlen($lowerPluralRev); | ||
430 | |||
431 | // Check if the word is one which is not inflected, return early if so | ||
432 | if (\in_array($lowerPluralRev, self::UNINFLECTED, true)) { | ||
433 | return [$plural]; | ||
434 | } | ||
435 | |||
436 | // The outer loop iterates over the entries of the plural table | ||
437 | // The inner loop $j iterates over the characters of the plural suffix | ||
438 | // in the plural table to compare them with the characters of the actual | ||
439 | // given plural suffix | ||
440 | foreach (self::PLURAL_MAP as $map) { | ||
441 | $suffix = $map[0]; | ||
442 | $suffixLength = $map[1]; | ||
443 | $j = 0; | ||
444 | |||
445 | // Compare characters in the plural table and of the suffix of the | ||
446 | // given plural one by one | ||
447 | while ($suffix[$j] === $lowerPluralRev[$j]) { | ||
448 | // Let $j point to the next character | ||
449 | ++$j; | ||
450 | |||
451 | // Successfully compared the last character | ||
452 | // Add an entry with the singular suffix to the singular array | ||
453 | if ($j === $suffixLength) { | ||
454 | // Is there any character preceding the suffix in the plural string? | ||
455 | if ($j < $pluralLength) { | ||
456 | $nextIsVowel = str_contains('aeiou', $lowerPluralRev[$j]); | ||
457 | |||
458 | if (!$map[2] && $nextIsVowel) { | ||
459 | // suffix may not succeed a vowel but next char is one | ||
460 | break; | ||
461 | } | ||
462 | |||
463 | if (!$map[3] && !$nextIsVowel) { | ||
464 | // suffix may not succeed a consonant but next char is one | ||
465 | break; | ||
466 | } | ||
467 | } | ||
468 | |||
469 | $newBase = substr($plural, 0, $pluralLength - $suffixLength); | ||
470 | $newSuffix = $map[4]; | ||
471 | |||
472 | // Check whether the first character in the plural suffix | ||
473 | // is uppercased. If yes, uppercase the first character in | ||
474 | // the singular suffix too | ||
475 | $firstUpper = ctype_upper($pluralRev[$j - 1]); | ||
476 | |||
477 | if (\is_array($newSuffix)) { | ||
478 | $singulars = []; | ||
479 | |||
480 | foreach ($newSuffix as $newSuffixEntry) { | ||
481 | $singulars[] = $newBase.($firstUpper ? ucfirst($newSuffixEntry) : $newSuffixEntry); | ||
482 | } | ||
483 | |||
484 | return $singulars; | ||
485 | } | ||
486 | |||
487 | return [$newBase.($firstUpper ? ucfirst($newSuffix) : $newSuffix)]; | ||
488 | } | ||
489 | |||
490 | // Suffix is longer than word | ||
491 | if ($j === $pluralLength) { | ||
492 | break; | ||
493 | } | ||
494 | } | ||
495 | } | ||
496 | |||
497 | // Assume that plural and singular is identical | ||
498 | return [$plural]; | ||
499 | } | ||
500 | |||
501 | public function pluralize(string $singular): array | ||
502 | { | ||
503 | $singularRev = strrev($singular); | ||
504 | $lowerSingularRev = strtolower($singularRev); | ||
505 | $singularLength = \strlen($lowerSingularRev); | ||
506 | |||
507 | // Check if the word is one which is not inflected, return early if so | ||
508 | if (\in_array($lowerSingularRev, self::UNINFLECTED, true)) { | ||
509 | return [$singular]; | ||
510 | } | ||
511 | |||
512 | // The outer loop iterates over the entries of the singular table | ||
513 | // The inner loop $j iterates over the characters of the singular suffix | ||
514 | // in the singular table to compare them with the characters of the actual | ||
515 | // given singular suffix | ||
516 | foreach (self::SINGULAR_MAP as $map) { | ||
517 | $suffix = $map[0]; | ||
518 | $suffixLength = $map[1]; | ||
519 | $j = 0; | ||
520 | |||
521 | // Compare characters in the singular table and of the suffix of the | ||
522 | // given plural one by one | ||
523 | |||
524 | while ($suffix[$j] === $lowerSingularRev[$j]) { | ||
525 | // Let $j point to the next character | ||
526 | ++$j; | ||
527 | |||
528 | // Successfully compared the last character | ||
529 | // Add an entry with the plural suffix to the plural array | ||
530 | if ($j === $suffixLength) { | ||
531 | // Is there any character preceding the suffix in the plural string? | ||
532 | if ($j < $singularLength) { | ||
533 | $nextIsVowel = str_contains('aeiou', $lowerSingularRev[$j]); | ||
534 | |||
535 | if (!$map[2] && $nextIsVowel) { | ||
536 | // suffix may not succeed a vowel but next char is one | ||
537 | break; | ||
538 | } | ||
539 | |||
540 | if (!$map[3] && !$nextIsVowel) { | ||
541 | // suffix may not succeed a consonant but next char is one | ||
542 | break; | ||
543 | } | ||
544 | } | ||
545 | |||
546 | $newBase = substr($singular, 0, $singularLength - $suffixLength); | ||
547 | $newSuffix = $map[4]; | ||
548 | |||
549 | // Check whether the first character in the singular suffix | ||
550 | // is uppercased. If yes, uppercase the first character in | ||
551 | // the singular suffix too | ||
552 | $firstUpper = ctype_upper($singularRev[$j - 1]); | ||
553 | |||
554 | if (\is_array($newSuffix)) { | ||
555 | $plurals = []; | ||
556 | |||
557 | foreach ($newSuffix as $newSuffixEntry) { | ||
558 | $plurals[] = $newBase.($firstUpper ? ucfirst($newSuffixEntry) : $newSuffixEntry); | ||
559 | } | ||
560 | |||
561 | return $plurals; | ||
562 | } | ||
563 | |||
564 | return [$newBase.($firstUpper ? ucfirst($newSuffix) : $newSuffix)]; | ||
565 | } | ||
566 | |||
567 | // Suffix is longer than word | ||
568 | if ($j === $singularLength) { | ||
569 | break; | ||
570 | } | ||
571 | } | ||
572 | } | ||
573 | |||
574 | // Assume that plural is singular with a trailing `s` | ||
575 | return [$singular.'s']; | ||
576 | } | ||
577 | } | ||
diff --git a/vendor/symfony/string/Inflector/FrenchInflector.php b/vendor/symfony/string/Inflector/FrenchInflector.php new file mode 100644 index 0000000..955abbf --- /dev/null +++ b/vendor/symfony/string/Inflector/FrenchInflector.php | |||
@@ -0,0 +1,151 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\String\Inflector; | ||
13 | |||
14 | /** | ||
15 | * French inflector. | ||
16 | * | ||
17 | * This class does only inflect nouns; not adjectives nor composed words like "soixante-dix". | ||
18 | */ | ||
19 | final class FrenchInflector implements InflectorInterface | ||
20 | { | ||
21 | /** | ||
22 | * A list of all rules for pluralise. | ||
23 | * | ||
24 | * @see https://la-conjugaison.nouvelobs.com/regles/grammaire/le-pluriel-des-noms-121.php | ||
25 | */ | ||
26 | private const PLURALIZE_REGEXP = [ | ||
27 | // First entry: regexp | ||
28 | // Second entry: replacement | ||
29 | |||
30 | // Words finishing with "s", "x" or "z" are invariables | ||
31 | // Les mots finissant par "s", "x" ou "z" sont invariables | ||
32 | ['/(s|x|z)$/i', '\1'], | ||
33 | |||
34 | // Words finishing with "eau" are pluralized with a "x" | ||
35 | // Les mots finissant par "eau" prennent tous un "x" au pluriel | ||
36 | ['/(eau)$/i', '\1x'], | ||
37 | |||
38 | // Words finishing with "au" are pluralized with a "x" excepted "landau" | ||
39 | // Les mots finissant par "au" prennent un "x" au pluriel sauf "landau" | ||
40 | ['/^(landau)$/i', '\1s'], | ||
41 | ['/(au)$/i', '\1x'], | ||
42 | |||
43 | // Words finishing with "eu" are pluralized with a "x" excepted "pneu", "bleu", "émeu" | ||
44 | // Les mots finissant en "eu" prennent un "x" au pluriel sauf "pneu", "bleu", "émeu" | ||
45 | ['/^(pneu|bleu|émeu)$/i', '\1s'], | ||
46 | ['/(eu)$/i', '\1x'], | ||
47 | |||
48 | // Words finishing with "al" are pluralized with a "aux" excepted | ||
49 | // Les mots finissant en "al" se terminent en "aux" sauf | ||
50 | ['/^(bal|carnaval|caracal|chacal|choral|corral|étal|festival|récital|val)$/i', '\1s'], | ||
51 | ['/al$/i', '\1aux'], | ||
52 | |||
53 | // Aspirail, bail, corail, émail, fermail, soupirail, travail, vantail et vitrail font leur pluriel en -aux | ||
54 | ['/^(aspir|b|cor|ém|ferm|soupir|trav|vant|vitr)ail$/i', '\1aux'], | ||
55 | |||
56 | // Bijou, caillou, chou, genou, hibou, joujou et pou qui prennent un x au pluriel | ||
57 | ['/^(bij|caill|ch|gen|hib|jouj|p)ou$/i', '\1oux'], | ||
58 | |||
59 | // Invariable words | ||
60 | ['/^(cinquante|soixante|mille)$/i', '\1'], | ||
61 | |||
62 | // French titles | ||
63 | ['/^(mon|ma)(sieur|dame|demoiselle|seigneur)$/', 'mes\2s'], | ||
64 | ['/^(Mon|Ma)(sieur|dame|demoiselle|seigneur)$/', 'Mes\2s'], | ||
65 | ]; | ||
66 | |||
67 | /** | ||
68 | * A list of all rules for singularize. | ||
69 | */ | ||
70 | private const SINGULARIZE_REGEXP = [ | ||
71 | // First entry: regexp | ||
72 | // Second entry: replacement | ||
73 | |||
74 | // Aspirail, bail, corail, émail, fermail, soupirail, travail, vantail et vitrail font leur pluriel en -aux | ||
75 | ['/((aspir|b|cor|ém|ferm|soupir|trav|vant|vitr))aux$/i', '\1ail'], | ||
76 | |||
77 | // Words finishing with "eau" are pluralized with a "x" | ||
78 | // Les mots finissant par "eau" prennent tous un "x" au pluriel | ||
79 | ['/(eau)x$/i', '\1'], | ||
80 | |||
81 | // Words finishing with "al" are pluralized with a "aux" expected | ||
82 | // Les mots finissant en "al" se terminent en "aux" sauf | ||
83 | ['/(amir|anim|arsen|boc|can|capit|capor|chev|crist|génér|hopit|hôpit|idé|journ|littor|loc|m|mét|minér|princip|radic|termin)aux$/i', '\1al'], | ||
84 | |||
85 | // Words finishing with "au" are pluralized with a "x" excepted "landau" | ||
86 | // Les mots finissant par "au" prennent un "x" au pluriel sauf "landau" | ||
87 | ['/(au)x$/i', '\1'], | ||
88 | |||
89 | // Words finishing with "eu" are pluralized with a "x" excepted "pneu", "bleu", "émeu" | ||
90 | // Les mots finissant en "eu" prennent un "x" au pluriel sauf "pneu", "bleu", "émeu" | ||
91 | ['/(eu)x$/i', '\1'], | ||
92 | |||
93 | // Words finishing with "ou" are pluralized with a "s" excepted bijou, caillou, chou, genou, hibou, joujou, pou | ||
94 | // Les mots finissant par "ou" prennent un "s" sauf bijou, caillou, chou, genou, hibou, joujou, pou | ||
95 | ['/(bij|caill|ch|gen|hib|jouj|p)oux$/i', '\1ou'], | ||
96 | |||
97 | // French titles | ||
98 | ['/^mes(dame|demoiselle)s$/', 'ma\1'], | ||
99 | ['/^Mes(dame|demoiselle)s$/', 'Ma\1'], | ||
100 | ['/^mes(sieur|seigneur)s$/', 'mon\1'], | ||
101 | ['/^Mes(sieur|seigneur)s$/', 'Mon\1'], | ||
102 | |||
103 | // Default rule | ||
104 | ['/s$/i', ''], | ||
105 | ]; | ||
106 | |||
107 | /** | ||
108 | * A list of words which should not be inflected. | ||
109 | * This list is only used by singularize. | ||
110 | */ | ||
111 | private const UNINFLECTED = '/^(abcès|accès|abus|albatros|anchois|anglais|autobus|bois|brebis|carquois|cas|chas|colis|concours|corps|cours|cyprès|décès|devis|discours|dos|embarras|engrais|entrelacs|excès|fils|fois|gâchis|gars|glas|héros|intrus|jars|jus|kermès|lacis|legs|lilas|marais|mars|matelas|mépris|mets|mois|mors|obus|os|palais|paradis|parcours|pardessus|pays|plusieurs|poids|pois|pouls|printemps|processus|progrès|puits|pus|rabais|radis|recors|recours|refus|relais|remords|remous|rictus|rhinocéros|repas|rubis|sans|sas|secours|sens|souris|succès|talus|tapis|tas|taudis|temps|tiers|univers|velours|verglas|vernis|virus)$/i'; | ||
112 | |||
113 | public function singularize(string $plural): array | ||
114 | { | ||
115 | if ($this->isInflectedWord($plural)) { | ||
116 | return [$plural]; | ||
117 | } | ||
118 | |||
119 | foreach (self::SINGULARIZE_REGEXP as $rule) { | ||
120 | [$regexp, $replace] = $rule; | ||
121 | |||
122 | if (1 === preg_match($regexp, $plural)) { | ||
123 | return [preg_replace($regexp, $replace, $plural)]; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | return [$plural]; | ||
128 | } | ||
129 | |||
130 | public function pluralize(string $singular): array | ||
131 | { | ||
132 | if ($this->isInflectedWord($singular)) { | ||
133 | return [$singular]; | ||
134 | } | ||
135 | |||
136 | foreach (self::PLURALIZE_REGEXP as $rule) { | ||
137 | [$regexp, $replace] = $rule; | ||
138 | |||
139 | if (1 === preg_match($regexp, $singular)) { | ||
140 | return [preg_replace($regexp, $replace, $singular)]; | ||
141 | } | ||
142 | } | ||
143 | |||
144 | return [$singular.'s']; | ||
145 | } | ||
146 | |||
147 | private function isInflectedWord(string $word): bool | ||
148 | { | ||
149 | return 1 === preg_match(self::UNINFLECTED, $word); | ||
150 | } | ||
151 | } | ||
diff --git a/vendor/symfony/string/Inflector/InflectorInterface.php b/vendor/symfony/string/Inflector/InflectorInterface.php new file mode 100644 index 0000000..67f2834 --- /dev/null +++ b/vendor/symfony/string/Inflector/InflectorInterface.php | |||
@@ -0,0 +1,33 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\String\Inflector; | ||
13 | |||
14 | interface InflectorInterface | ||
15 | { | ||
16 | /** | ||
17 | * Returns the singular forms of a string. | ||
18 | * | ||
19 | * If the method can't determine the form with certainty, several possible singulars are returned. | ||
20 | * | ||
21 | * @return string[] | ||
22 | */ | ||
23 | public function singularize(string $plural): array; | ||
24 | |||
25 | /** | ||
26 | * Returns the plural forms of a string. | ||
27 | * | ||
28 | * If the method can't determine the form with certainty, several possible plurals are returned. | ||
29 | * | ||
30 | * @return string[] | ||
31 | */ | ||
32 | public function pluralize(string $singular): array; | ||
33 | } | ||
diff --git a/vendor/symfony/string/LICENSE b/vendor/symfony/string/LICENSE new file mode 100644 index 0000000..f37c76b --- /dev/null +++ b/vendor/symfony/string/LICENSE | |||
@@ -0,0 +1,19 @@ | |||
1 | Copyright (c) 2019-present Fabien Potencier | ||
2 | |||
3 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
4 | of this software and associated documentation files (the "Software"), to deal | ||
5 | in the Software without restriction, including without limitation the rights | ||
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
7 | copies of the Software, and to permit persons to whom the Software is furnished | ||
8 | to do so, subject to the following conditions: | ||
9 | |||
10 | The above copyright notice and this permission notice shall be included in all | ||
11 | copies or substantial portions of the Software. | ||
12 | |||
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
19 | THE SOFTWARE. | ||
diff --git a/vendor/symfony/string/LazyString.php b/vendor/symfony/string/LazyString.php new file mode 100644 index 0000000..8f2bbbf --- /dev/null +++ b/vendor/symfony/string/LazyString.php | |||
@@ -0,0 +1,145 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\String; | ||
13 | |||
14 | /** | ||
15 | * A string whose value is computed lazily by a callback. | ||
16 | * | ||
17 | * @author Nicolas Grekas <p@tchwork.com> | ||
18 | */ | ||
19 | class LazyString implements \Stringable, \JsonSerializable | ||
20 | { | ||
21 | private \Closure|string $value; | ||
22 | |||
23 | /** | ||
24 | * @param callable|array $callback A callable or a [Closure, method] lazy-callable | ||
25 | */ | ||
26 | public static function fromCallable(callable|array $callback, mixed ...$arguments): static | ||
27 | { | ||
28 | if (\is_array($callback) && !\is_callable($callback) && !(($callback[0] ?? null) instanceof \Closure || 2 < \count($callback))) { | ||
29 | throw new \TypeError(sprintf('Argument 1 passed to "%s()" must be a callable or a [Closure, method] lazy-callable, "%s" given.', __METHOD__, '['.implode(', ', array_map('get_debug_type', $callback)).']')); | ||
30 | } | ||
31 | |||
32 | $lazyString = new static(); | ||
33 | $lazyString->value = static function () use (&$callback, &$arguments): string { | ||
34 | static $value; | ||
35 | |||
36 | if (null !== $arguments) { | ||
37 | if (!\is_callable($callback)) { | ||
38 | $callback[0] = $callback[0](); | ||
39 | $callback[1] ??= '__invoke'; | ||
40 | } | ||
41 | $value = $callback(...$arguments); | ||
42 | $callback = !\is_scalar($value) && !$value instanceof \Stringable ? self::getPrettyName($callback) : 'callable'; | ||
43 | $arguments = null; | ||
44 | } | ||
45 | |||
46 | return $value ?? ''; | ||
47 | }; | ||
48 | |||
49 | return $lazyString; | ||
50 | } | ||
51 | |||
52 | public static function fromStringable(string|int|float|bool|\Stringable $value): static | ||
53 | { | ||
54 | if (\is_object($value)) { | ||
55 | return static::fromCallable($value->__toString(...)); | ||
56 | } | ||
57 | |||
58 | $lazyString = new static(); | ||
59 | $lazyString->value = (string) $value; | ||
60 | |||
61 | return $lazyString; | ||
62 | } | ||
63 | |||
64 | /** | ||
65 | * Tells whether the provided value can be cast to string. | ||
66 | */ | ||
67 | final public static function isStringable(mixed $value): bool | ||
68 | { | ||
69 | return \is_string($value) || $value instanceof \Stringable || \is_scalar($value); | ||
70 | } | ||
71 | |||
72 | /** | ||
73 | * Casts scalars and stringable objects to strings. | ||
74 | * | ||
75 | * @throws \TypeError When the provided value is not stringable | ||
76 | */ | ||
77 | final public static function resolve(\Stringable|string|int|float|bool $value): string | ||
78 | { | ||
79 | return $value; | ||
80 | } | ||
81 | |||
82 | public function __toString(): string | ||
83 | { | ||
84 | if (\is_string($this->value)) { | ||
85 | return $this->value; | ||
86 | } | ||
87 | |||
88 | try { | ||
89 | return $this->value = ($this->value)(); | ||
90 | } catch (\Throwable $e) { | ||
91 | if (\TypeError::class === $e::class && __FILE__ === $e->getFile()) { | ||
92 | $type = explode(', ', $e->getMessage()); | ||
93 | $type = substr(array_pop($type), 0, -\strlen(' returned')); | ||
94 | $r = new \ReflectionFunction($this->value); | ||
95 | $callback = $r->getStaticVariables()['callback']; | ||
96 | |||
97 | $e = new \TypeError(sprintf('Return value of %s() passed to %s::fromCallable() must be of the type string, %s returned.', $callback, static::class, $type)); | ||
98 | } | ||
99 | |||
100 | throw $e; | ||
101 | } | ||
102 | } | ||
103 | |||
104 | public function __sleep(): array | ||
105 | { | ||
106 | $this->__toString(); | ||
107 | |||
108 | return ['value']; | ||
109 | } | ||
110 | |||
111 | public function jsonSerialize(): string | ||
112 | { | ||
113 | return $this->__toString(); | ||
114 | } | ||
115 | |||
116 | private function __construct() | ||
117 | { | ||
118 | } | ||
119 | |||
120 | private static function getPrettyName(callable $callback): string | ||
121 | { | ||
122 | if (\is_string($callback)) { | ||
123 | return $callback; | ||
124 | } | ||
125 | |||
126 | if (\is_array($callback)) { | ||
127 | $class = \is_object($callback[0]) ? get_debug_type($callback[0]) : $callback[0]; | ||
128 | $method = $callback[1]; | ||
129 | } elseif ($callback instanceof \Closure) { | ||
130 | $r = new \ReflectionFunction($callback); | ||
131 | |||
132 | if ($r->isAnonymous() || !$class = $r->getClosureCalledClass()) { | ||
133 | return $r->name; | ||
134 | } | ||
135 | |||
136 | $class = $class->name; | ||
137 | $method = $r->name; | ||
138 | } else { | ||
139 | $class = get_debug_type($callback); | ||
140 | $method = '__invoke'; | ||
141 | } | ||
142 | |||
143 | return $class.'::'.$method; | ||
144 | } | ||
145 | } | ||
diff --git a/vendor/symfony/string/README.md b/vendor/symfony/string/README.md new file mode 100644 index 0000000..9c7e1e1 --- /dev/null +++ b/vendor/symfony/string/README.md | |||
@@ -0,0 +1,14 @@ | |||
1 | String Component | ||
2 | ================ | ||
3 | |||
4 | The String component provides an object-oriented API to strings and deals | ||
5 | with bytes, UTF-8 code points and grapheme clusters in a unified way. | ||
6 | |||
7 | Resources | ||
8 | --------- | ||
9 | |||
10 | * [Documentation](https://symfony.com/doc/current/components/string.html) | ||
11 | * [Contributing](https://symfony.com/doc/current/contributing/index.html) | ||
12 | * [Report issues](https://github.com/symfony/symfony/issues) and | ||
13 | [send Pull Requests](https://github.com/symfony/symfony/pulls) | ||
14 | in the [main Symfony repository](https://github.com/symfony/symfony) | ||
diff --git a/vendor/symfony/string/Resources/data/wcswidth_table_wide.php b/vendor/symfony/string/Resources/data/wcswidth_table_wide.php new file mode 100644 index 0000000..8314c8f --- /dev/null +++ b/vendor/symfony/string/Resources/data/wcswidth_table_wide.php | |||
@@ -0,0 +1,1155 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file has been auto-generated by the Symfony String Component for internal use. | ||
5 | * | ||
6 | * Unicode version: 15.1.0 | ||
7 | * Date: 2023-09-13T11:47:12+00:00 | ||
8 | */ | ||
9 | |||
10 | return [ | ||
11 | [ | ||
12 | 4352, | ||
13 | 4447, | ||
14 | ], | ||
15 | [ | ||
16 | 8986, | ||
17 | 8987, | ||
18 | ], | ||
19 | [ | ||
20 | 9001, | ||
21 | 9001, | ||
22 | ], | ||
23 | [ | ||
24 | 9002, | ||
25 | 9002, | ||
26 | ], | ||
27 | [ | ||
28 | 9193, | ||
29 | 9196, | ||
30 | ], | ||
31 | [ | ||
32 | 9200, | ||
33 | 9200, | ||
34 | ], | ||
35 | [ | ||
36 | 9203, | ||
37 | 9203, | ||
38 | ], | ||
39 | [ | ||
40 | 9725, | ||
41 | 9726, | ||
42 | ], | ||
43 | [ | ||
44 | 9748, | ||
45 | 9749, | ||
46 | ], | ||
47 | [ | ||
48 | 9800, | ||
49 | 9811, | ||
50 | ], | ||
51 | [ | ||
52 | 9855, | ||
53 | 9855, | ||
54 | ], | ||
55 | [ | ||
56 | 9875, | ||
57 | 9875, | ||
58 | ], | ||
59 | [ | ||
60 | 9889, | ||
61 | 9889, | ||
62 | ], | ||
63 | [ | ||
64 | 9898, | ||
65 | 9899, | ||
66 | ], | ||
67 | [ | ||
68 | 9917, | ||
69 | 9918, | ||
70 | ], | ||
71 | [ | ||
72 | 9924, | ||
73 | 9925, | ||
74 | ], | ||
75 | [ | ||
76 | 9934, | ||
77 | 9934, | ||
78 | ], | ||
79 | [ | ||
80 | 9940, | ||
81 | 9940, | ||
82 | ], | ||
83 | [ | ||
84 | 9962, | ||
85 | 9962, | ||
86 | ], | ||
87 | [ | ||
88 | 9970, | ||
89 | 9971, | ||
90 | ], | ||
91 | [ | ||
92 | 9973, | ||
93 | 9973, | ||
94 | ], | ||
95 | [ | ||
96 | 9978, | ||
97 | 9978, | ||
98 | ], | ||
99 | [ | ||
100 | 9981, | ||
101 | 9981, | ||
102 | ], | ||
103 | [ | ||
104 | 9989, | ||
105 | 9989, | ||
106 | ], | ||
107 | [ | ||
108 | 9994, | ||
109 | 9995, | ||
110 | ], | ||
111 | [ | ||
112 | 10024, | ||
113 | 10024, | ||
114 | ], | ||
115 | [ | ||
116 | 10060, | ||
117 | 10060, | ||
118 | ], | ||
119 | [ | ||
120 | 10062, | ||
121 | 10062, | ||
122 | ], | ||
123 | [ | ||
124 | 10067, | ||
125 | 10069, | ||
126 | ], | ||
127 | [ | ||
128 | 10071, | ||
129 | 10071, | ||
130 | ], | ||
131 | [ | ||
132 | 10133, | ||
133 | 10135, | ||
134 | ], | ||
135 | [ | ||
136 | 10160, | ||
137 | 10160, | ||
138 | ], | ||
139 | [ | ||
140 | 10175, | ||
141 | 10175, | ||
142 | ], | ||
143 | [ | ||
144 | 11035, | ||
145 | 11036, | ||
146 | ], | ||
147 | [ | ||
148 | 11088, | ||
149 | 11088, | ||
150 | ], | ||
151 | [ | ||
152 | 11093, | ||
153 | 11093, | ||
154 | ], | ||
155 | [ | ||
156 | 11904, | ||
157 | 11929, | ||
158 | ], | ||
159 | [ | ||
160 | 11931, | ||
161 | 12019, | ||
162 | ], | ||
163 | [ | ||
164 | 12032, | ||
165 | 12245, | ||
166 | ], | ||
167 | [ | ||
168 | 12272, | ||
169 | 12287, | ||
170 | ], | ||
171 | [ | ||
172 | 12288, | ||
173 | 12288, | ||
174 | ], | ||
175 | [ | ||
176 | 12289, | ||
177 | 12291, | ||
178 | ], | ||
179 | [ | ||
180 | 12292, | ||
181 | 12292, | ||
182 | ], | ||
183 | [ | ||
184 | 12293, | ||
185 | 12293, | ||
186 | ], | ||
187 | [ | ||
188 | 12294, | ||
189 | 12294, | ||
190 | ], | ||
191 | [ | ||
192 | 12295, | ||
193 | 12295, | ||
194 | ], | ||
195 | [ | ||
196 | 12296, | ||
197 | 12296, | ||
198 | ], | ||
199 | [ | ||
200 | 12297, | ||
201 | 12297, | ||
202 | ], | ||
203 | [ | ||
204 | 12298, | ||
205 | 12298, | ||
206 | ], | ||
207 | [ | ||
208 | 12299, | ||
209 | 12299, | ||
210 | ], | ||
211 | [ | ||
212 | 12300, | ||
213 | 12300, | ||
214 | ], | ||
215 | [ | ||
216 | 12301, | ||
217 | 12301, | ||
218 | ], | ||
219 | [ | ||
220 | 12302, | ||
221 | 12302, | ||
222 | ], | ||
223 | [ | ||
224 | 12303, | ||
225 | 12303, | ||
226 | ], | ||
227 | [ | ||
228 | 12304, | ||
229 | 12304, | ||
230 | ], | ||
231 | [ | ||
232 | 12305, | ||
233 | 12305, | ||
234 | ], | ||
235 | [ | ||
236 | 12306, | ||
237 | 12307, | ||
238 | ], | ||
239 | [ | ||
240 | 12308, | ||
241 | 12308, | ||
242 | ], | ||
243 | [ | ||
244 | 12309, | ||
245 | 12309, | ||
246 | ], | ||
247 | [ | ||
248 | 12310, | ||
249 | 12310, | ||
250 | ], | ||
251 | [ | ||
252 | 12311, | ||
253 | 12311, | ||
254 | ], | ||
255 | [ | ||
256 | 12312, | ||
257 | 12312, | ||
258 | ], | ||
259 | [ | ||
260 | 12313, | ||
261 | 12313, | ||
262 | ], | ||
263 | [ | ||
264 | 12314, | ||
265 | 12314, | ||
266 | ], | ||
267 | [ | ||
268 | 12315, | ||
269 | 12315, | ||
270 | ], | ||
271 | [ | ||
272 | 12316, | ||
273 | 12316, | ||
274 | ], | ||
275 | [ | ||
276 | 12317, | ||
277 | 12317, | ||
278 | ], | ||
279 | [ | ||
280 | 12318, | ||
281 | 12319, | ||
282 | ], | ||
283 | [ | ||
284 | 12320, | ||
285 | 12320, | ||
286 | ], | ||
287 | [ | ||
288 | 12321, | ||
289 | 12329, | ||
290 | ], | ||
291 | [ | ||
292 | 12330, | ||
293 | 12333, | ||
294 | ], | ||
295 | [ | ||
296 | 12334, | ||
297 | 12335, | ||
298 | ], | ||
299 | [ | ||
300 | 12336, | ||
301 | 12336, | ||
302 | ], | ||
303 | [ | ||
304 | 12337, | ||
305 | 12341, | ||
306 | ], | ||
307 | [ | ||
308 | 12342, | ||
309 | 12343, | ||
310 | ], | ||
311 | [ | ||
312 | 12344, | ||
313 | 12346, | ||
314 | ], | ||
315 | [ | ||
316 | 12347, | ||
317 | 12347, | ||
318 | ], | ||
319 | [ | ||
320 | 12348, | ||
321 | 12348, | ||
322 | ], | ||
323 | [ | ||
324 | 12349, | ||
325 | 12349, | ||
326 | ], | ||
327 | [ | ||
328 | 12350, | ||
329 | 12350, | ||
330 | ], | ||
331 | [ | ||
332 | 12353, | ||
333 | 12438, | ||
334 | ], | ||
335 | [ | ||
336 | 12441, | ||
337 | 12442, | ||
338 | ], | ||
339 | [ | ||
340 | 12443, | ||
341 | 12444, | ||
342 | ], | ||
343 | [ | ||
344 | 12445, | ||
345 | 12446, | ||
346 | ], | ||
347 | [ | ||
348 | 12447, | ||
349 | 12447, | ||
350 | ], | ||
351 | [ | ||
352 | 12448, | ||
353 | 12448, | ||
354 | ], | ||
355 | [ | ||
356 | 12449, | ||
357 | 12538, | ||
358 | ], | ||
359 | [ | ||
360 | 12539, | ||
361 | 12539, | ||
362 | ], | ||
363 | [ | ||
364 | 12540, | ||
365 | 12542, | ||
366 | ], | ||
367 | [ | ||
368 | 12543, | ||
369 | 12543, | ||
370 | ], | ||
371 | [ | ||
372 | 12549, | ||
373 | 12591, | ||
374 | ], | ||
375 | [ | ||
376 | 12593, | ||
377 | 12686, | ||
378 | ], | ||
379 | [ | ||
380 | 12688, | ||
381 | 12689, | ||
382 | ], | ||
383 | [ | ||
384 | 12690, | ||
385 | 12693, | ||
386 | ], | ||
387 | [ | ||
388 | 12694, | ||
389 | 12703, | ||
390 | ], | ||
391 | [ | ||
392 | 12704, | ||
393 | 12735, | ||
394 | ], | ||
395 | [ | ||
396 | 12736, | ||
397 | 12771, | ||
398 | ], | ||
399 | [ | ||
400 | 12783, | ||
401 | 12783, | ||
402 | ], | ||
403 | [ | ||
404 | 12784, | ||
405 | 12799, | ||
406 | ], | ||
407 | [ | ||
408 | 12800, | ||
409 | 12830, | ||
410 | ], | ||
411 | [ | ||
412 | 12832, | ||
413 | 12841, | ||
414 | ], | ||
415 | [ | ||
416 | 12842, | ||
417 | 12871, | ||
418 | ], | ||
419 | [ | ||
420 | 12880, | ||
421 | 12880, | ||
422 | ], | ||
423 | [ | ||
424 | 12881, | ||
425 | 12895, | ||
426 | ], | ||
427 | [ | ||
428 | 12896, | ||
429 | 12927, | ||
430 | ], | ||
431 | [ | ||
432 | 12928, | ||
433 | 12937, | ||
434 | ], | ||
435 | [ | ||
436 | 12938, | ||
437 | 12976, | ||
438 | ], | ||
439 | [ | ||
440 | 12977, | ||
441 | 12991, | ||
442 | ], | ||
443 | [ | ||
444 | 12992, | ||
445 | 13055, | ||
446 | ], | ||
447 | [ | ||
448 | 13056, | ||
449 | 13311, | ||
450 | ], | ||
451 | [ | ||
452 | 13312, | ||
453 | 19903, | ||
454 | ], | ||
455 | [ | ||
456 | 19968, | ||
457 | 40959, | ||
458 | ], | ||
459 | [ | ||
460 | 40960, | ||
461 | 40980, | ||
462 | ], | ||
463 | [ | ||
464 | 40981, | ||
465 | 40981, | ||
466 | ], | ||
467 | [ | ||
468 | 40982, | ||
469 | 42124, | ||
470 | ], | ||
471 | [ | ||
472 | 42128, | ||
473 | 42182, | ||
474 | ], | ||
475 | [ | ||
476 | 43360, | ||
477 | 43388, | ||
478 | ], | ||
479 | [ | ||
480 | 44032, | ||
481 | 55203, | ||
482 | ], | ||
483 | [ | ||
484 | 63744, | ||
485 | 64109, | ||
486 | ], | ||
487 | [ | ||
488 | 64110, | ||
489 | 64111, | ||
490 | ], | ||
491 | [ | ||
492 | 64112, | ||
493 | 64217, | ||
494 | ], | ||
495 | [ | ||
496 | 64218, | ||
497 | 64255, | ||
498 | ], | ||
499 | [ | ||
500 | 65040, | ||
501 | 65046, | ||
502 | ], | ||
503 | [ | ||
504 | 65047, | ||
505 | 65047, | ||
506 | ], | ||
507 | [ | ||
508 | 65048, | ||
509 | 65048, | ||
510 | ], | ||
511 | [ | ||
512 | 65049, | ||
513 | 65049, | ||
514 | ], | ||
515 | [ | ||
516 | 65072, | ||
517 | 65072, | ||
518 | ], | ||
519 | [ | ||
520 | 65073, | ||
521 | 65074, | ||
522 | ], | ||
523 | [ | ||
524 | 65075, | ||
525 | 65076, | ||
526 | ], | ||
527 | [ | ||
528 | 65077, | ||
529 | 65077, | ||
530 | ], | ||
531 | [ | ||
532 | 65078, | ||
533 | 65078, | ||
534 | ], | ||
535 | [ | ||
536 | 65079, | ||
537 | 65079, | ||
538 | ], | ||
539 | [ | ||
540 | 65080, | ||
541 | 65080, | ||
542 | ], | ||
543 | [ | ||
544 | 65081, | ||
545 | 65081, | ||
546 | ], | ||
547 | [ | ||
548 | 65082, | ||
549 | 65082, | ||
550 | ], | ||
551 | [ | ||
552 | 65083, | ||
553 | 65083, | ||
554 | ], | ||
555 | [ | ||
556 | 65084, | ||
557 | 65084, | ||
558 | ], | ||
559 | [ | ||
560 | 65085, | ||
561 | 65085, | ||
562 | ], | ||
563 | [ | ||
564 | 65086, | ||
565 | 65086, | ||
566 | ], | ||
567 | [ | ||
568 | 65087, | ||
569 | 65087, | ||
570 | ], | ||
571 | [ | ||
572 | 65088, | ||
573 | 65088, | ||
574 | ], | ||
575 | [ | ||
576 | 65089, | ||
577 | 65089, | ||
578 | ], | ||
579 | [ | ||
580 | 65090, | ||
581 | 65090, | ||
582 | ], | ||
583 | [ | ||
584 | 65091, | ||
585 | 65091, | ||
586 | ], | ||
587 | [ | ||
588 | 65092, | ||
589 | 65092, | ||
590 | ], | ||
591 | [ | ||
592 | 65093, | ||
593 | 65094, | ||
594 | ], | ||
595 | [ | ||
596 | 65095, | ||
597 | 65095, | ||
598 | ], | ||
599 | [ | ||
600 | 65096, | ||
601 | 65096, | ||
602 | ], | ||
603 | [ | ||
604 | 65097, | ||
605 | 65100, | ||
606 | ], | ||
607 | [ | ||
608 | 65101, | ||
609 | 65103, | ||
610 | ], | ||
611 | [ | ||
612 | 65104, | ||
613 | 65106, | ||
614 | ], | ||
615 | [ | ||
616 | 65108, | ||
617 | 65111, | ||
618 | ], | ||
619 | [ | ||
620 | 65112, | ||
621 | 65112, | ||
622 | ], | ||
623 | [ | ||
624 | 65113, | ||
625 | 65113, | ||
626 | ], | ||
627 | [ | ||
628 | 65114, | ||
629 | 65114, | ||
630 | ], | ||
631 | [ | ||
632 | 65115, | ||
633 | 65115, | ||
634 | ], | ||
635 | [ | ||
636 | 65116, | ||
637 | 65116, | ||
638 | ], | ||
639 | [ | ||
640 | 65117, | ||
641 | 65117, | ||
642 | ], | ||
643 | [ | ||
644 | 65118, | ||
645 | 65118, | ||
646 | ], | ||
647 | [ | ||
648 | 65119, | ||
649 | 65121, | ||
650 | ], | ||
651 | [ | ||
652 | 65122, | ||
653 | 65122, | ||
654 | ], | ||
655 | [ | ||
656 | 65123, | ||
657 | 65123, | ||
658 | ], | ||
659 | [ | ||
660 | 65124, | ||
661 | 65126, | ||
662 | ], | ||
663 | [ | ||
664 | 65128, | ||
665 | 65128, | ||
666 | ], | ||
667 | [ | ||
668 | 65129, | ||
669 | 65129, | ||
670 | ], | ||
671 | [ | ||
672 | 65130, | ||
673 | 65131, | ||
674 | ], | ||
675 | [ | ||
676 | 65281, | ||
677 | 65283, | ||
678 | ], | ||
679 | [ | ||
680 | 65284, | ||
681 | 65284, | ||
682 | ], | ||
683 | [ | ||
684 | 65285, | ||
685 | 65287, | ||
686 | ], | ||
687 | [ | ||
688 | 65288, | ||
689 | 65288, | ||
690 | ], | ||
691 | [ | ||
692 | 65289, | ||
693 | 65289, | ||
694 | ], | ||
695 | [ | ||
696 | 65290, | ||
697 | 65290, | ||
698 | ], | ||
699 | [ | ||
700 | 65291, | ||
701 | 65291, | ||
702 | ], | ||
703 | [ | ||
704 | 65292, | ||
705 | 65292, | ||
706 | ], | ||
707 | [ | ||
708 | 65293, | ||
709 | 65293, | ||
710 | ], | ||
711 | [ | ||
712 | 65294, | ||
713 | 65295, | ||
714 | ], | ||
715 | [ | ||
716 | 65296, | ||
717 | 65305, | ||
718 | ], | ||
719 | [ | ||
720 | 65306, | ||
721 | 65307, | ||
722 | ], | ||
723 | [ | ||
724 | 65308, | ||
725 | 65310, | ||
726 | ], | ||
727 | [ | ||
728 | 65311, | ||
729 | 65312, | ||
730 | ], | ||
731 | [ | ||
732 | 65313, | ||
733 | 65338, | ||
734 | ], | ||
735 | [ | ||
736 | 65339, | ||
737 | 65339, | ||
738 | ], | ||
739 | [ | ||
740 | 65340, | ||
741 | 65340, | ||
742 | ], | ||
743 | [ | ||
744 | 65341, | ||
745 | 65341, | ||
746 | ], | ||
747 | [ | ||
748 | 65342, | ||
749 | 65342, | ||
750 | ], | ||
751 | [ | ||
752 | 65343, | ||
753 | 65343, | ||
754 | ], | ||
755 | [ | ||
756 | 65344, | ||
757 | 65344, | ||
758 | ], | ||
759 | [ | ||
760 | 65345, | ||
761 | 65370, | ||
762 | ], | ||
763 | [ | ||
764 | 65371, | ||
765 | 65371, | ||
766 | ], | ||
767 | [ | ||
768 | 65372, | ||
769 | 65372, | ||
770 | ], | ||
771 | [ | ||
772 | 65373, | ||
773 | 65373, | ||
774 | ], | ||
775 | [ | ||
776 | 65374, | ||
777 | 65374, | ||
778 | ], | ||
779 | [ | ||
780 | 65375, | ||
781 | 65375, | ||
782 | ], | ||
783 | [ | ||
784 | 65376, | ||
785 | 65376, | ||
786 | ], | ||
787 | [ | ||
788 | 65504, | ||
789 | 65505, | ||
790 | ], | ||
791 | [ | ||
792 | 65506, | ||
793 | 65506, | ||
794 | ], | ||
795 | [ | ||
796 | 65507, | ||
797 | 65507, | ||
798 | ], | ||
799 | [ | ||
800 | 65508, | ||
801 | 65508, | ||
802 | ], | ||
803 | [ | ||
804 | 65509, | ||
805 | 65510, | ||
806 | ], | ||
807 | [ | ||
808 | 94176, | ||
809 | 94177, | ||
810 | ], | ||
811 | [ | ||
812 | 94178, | ||
813 | 94178, | ||
814 | ], | ||
815 | [ | ||
816 | 94179, | ||
817 | 94179, | ||
818 | ], | ||
819 | [ | ||
820 | 94180, | ||
821 | 94180, | ||
822 | ], | ||
823 | [ | ||
824 | 94192, | ||
825 | 94193, | ||
826 | ], | ||
827 | [ | ||
828 | 94208, | ||
829 | 100343, | ||
830 | ], | ||
831 | [ | ||
832 | 100352, | ||
833 | 101119, | ||
834 | ], | ||
835 | [ | ||
836 | 101120, | ||
837 | 101589, | ||
838 | ], | ||
839 | [ | ||
840 | 101632, | ||
841 | 101640, | ||
842 | ], | ||
843 | [ | ||
844 | 110576, | ||
845 | 110579, | ||
846 | ], | ||
847 | [ | ||
848 | 110581, | ||
849 | 110587, | ||
850 | ], | ||
851 | [ | ||
852 | 110589, | ||
853 | 110590, | ||
854 | ], | ||
855 | [ | ||
856 | 110592, | ||
857 | 110847, | ||
858 | ], | ||
859 | [ | ||
860 | 110848, | ||
861 | 110882, | ||
862 | ], | ||
863 | [ | ||
864 | 110898, | ||
865 | 110898, | ||
866 | ], | ||
867 | [ | ||
868 | 110928, | ||
869 | 110930, | ||
870 | ], | ||
871 | [ | ||
872 | 110933, | ||
873 | 110933, | ||
874 | ], | ||
875 | [ | ||
876 | 110948, | ||
877 | 110951, | ||
878 | ], | ||
879 | [ | ||
880 | 110960, | ||
881 | 111355, | ||
882 | ], | ||
883 | [ | ||
884 | 126980, | ||
885 | 126980, | ||
886 | ], | ||
887 | [ | ||
888 | 127183, | ||
889 | 127183, | ||
890 | ], | ||
891 | [ | ||
892 | 127374, | ||
893 | 127374, | ||
894 | ], | ||
895 | [ | ||
896 | 127377, | ||
897 | 127386, | ||
898 | ], | ||
899 | [ | ||
900 | 127488, | ||
901 | 127490, | ||
902 | ], | ||
903 | [ | ||
904 | 127504, | ||
905 | 127547, | ||
906 | ], | ||
907 | [ | ||
908 | 127552, | ||
909 | 127560, | ||
910 | ], | ||
911 | [ | ||
912 | 127568, | ||
913 | 127569, | ||
914 | ], | ||
915 | [ | ||
916 | 127584, | ||
917 | 127589, | ||
918 | ], | ||
919 | [ | ||
920 | 127744, | ||
921 | 127776, | ||
922 | ], | ||
923 | [ | ||
924 | 127789, | ||
925 | 127797, | ||
926 | ], | ||
927 | [ | ||
928 | 127799, | ||
929 | 127868, | ||
930 | ], | ||
931 | [ | ||
932 | 127870, | ||
933 | 127891, | ||
934 | ], | ||
935 | [ | ||
936 | 127904, | ||
937 | 127946, | ||
938 | ], | ||
939 | [ | ||
940 | 127951, | ||
941 | 127955, | ||
942 | ], | ||
943 | [ | ||
944 | 127968, | ||
945 | 127984, | ||
946 | ], | ||
947 | [ | ||
948 | 127988, | ||
949 | 127988, | ||
950 | ], | ||
951 | [ | ||
952 | 127992, | ||
953 | 127994, | ||
954 | ], | ||
955 | [ | ||
956 | 127995, | ||
957 | 127999, | ||
958 | ], | ||
959 | [ | ||
960 | 128000, | ||
961 | 128062, | ||
962 | ], | ||
963 | [ | ||
964 | 128064, | ||
965 | 128064, | ||
966 | ], | ||
967 | [ | ||
968 | 128066, | ||
969 | 128252, | ||
970 | ], | ||
971 | [ | ||
972 | 128255, | ||
973 | 128317, | ||
974 | ], | ||
975 | [ | ||
976 | 128331, | ||
977 | 128334, | ||
978 | ], | ||
979 | [ | ||
980 | 128336, | ||
981 | 128359, | ||
982 | ], | ||
983 | [ | ||
984 | 128378, | ||
985 | 128378, | ||
986 | ], | ||
987 | [ | ||
988 | 128405, | ||
989 | 128406, | ||
990 | ], | ||
991 | [ | ||
992 | 128420, | ||
993 | 128420, | ||
994 | ], | ||
995 | [ | ||
996 | 128507, | ||
997 | 128511, | ||
998 | ], | ||
999 | [ | ||
1000 | 128512, | ||
1001 | 128591, | ||
1002 | ], | ||
1003 | [ | ||
1004 | 128640, | ||
1005 | 128709, | ||
1006 | ], | ||
1007 | [ | ||
1008 | 128716, | ||
1009 | 128716, | ||
1010 | ], | ||
1011 | [ | ||
1012 | 128720, | ||
1013 | 128722, | ||
1014 | ], | ||
1015 | [ | ||
1016 | 128725, | ||
1017 | 128727, | ||
1018 | ], | ||
1019 | [ | ||
1020 | 128732, | ||
1021 | 128735, | ||
1022 | ], | ||
1023 | [ | ||
1024 | 128747, | ||
1025 | 128748, | ||
1026 | ], | ||
1027 | [ | ||
1028 | 128756, | ||
1029 | 128764, | ||
1030 | ], | ||
1031 | [ | ||
1032 | 128992, | ||
1033 | 129003, | ||
1034 | ], | ||
1035 | [ | ||
1036 | 129008, | ||
1037 | 129008, | ||
1038 | ], | ||
1039 | [ | ||
1040 | 129292, | ||
1041 | 129338, | ||
1042 | ], | ||
1043 | [ | ||
1044 | 129340, | ||
1045 | 129349, | ||
1046 | ], | ||
1047 | [ | ||
1048 | 129351, | ||
1049 | 129535, | ||
1050 | ], | ||
1051 | [ | ||
1052 | 129648, | ||
1053 | 129660, | ||
1054 | ], | ||
1055 | [ | ||
1056 | 129664, | ||
1057 | 129672, | ||
1058 | ], | ||
1059 | [ | ||
1060 | 129680, | ||
1061 | 129725, | ||
1062 | ], | ||
1063 | [ | ||
1064 | 129727, | ||
1065 | 129733, | ||
1066 | ], | ||
1067 | [ | ||
1068 | 129742, | ||
1069 | 129755, | ||
1070 | ], | ||
1071 | [ | ||
1072 | 129760, | ||
1073 | 129768, | ||
1074 | ], | ||
1075 | [ | ||
1076 | 129776, | ||
1077 | 129784, | ||
1078 | ], | ||
1079 | [ | ||
1080 | 131072, | ||
1081 | 173791, | ||
1082 | ], | ||
1083 | [ | ||
1084 | 173792, | ||
1085 | 173823, | ||
1086 | ], | ||
1087 | [ | ||
1088 | 173824, | ||
1089 | 177977, | ||
1090 | ], | ||
1091 | [ | ||
1092 | 177978, | ||
1093 | 177983, | ||
1094 | ], | ||
1095 | [ | ||
1096 | 177984, | ||
1097 | 178205, | ||
1098 | ], | ||
1099 | [ | ||
1100 | 178206, | ||
1101 | 178207, | ||
1102 | ], | ||
1103 | [ | ||
1104 | 178208, | ||
1105 | 183969, | ||
1106 | ], | ||
1107 | [ | ||
1108 | 183970, | ||
1109 | 183983, | ||
1110 | ], | ||
1111 | [ | ||
1112 | 183984, | ||
1113 | 191456, | ||
1114 | ], | ||
1115 | [ | ||
1116 | 191457, | ||
1117 | 191471, | ||
1118 | ], | ||
1119 | [ | ||
1120 | 191472, | ||
1121 | 192093, | ||
1122 | ], | ||
1123 | [ | ||
1124 | 192094, | ||
1125 | 194559, | ||
1126 | ], | ||
1127 | [ | ||
1128 | 194560, | ||
1129 | 195101, | ||
1130 | ], | ||
1131 | [ | ||
1132 | 195102, | ||
1133 | 195103, | ||
1134 | ], | ||
1135 | [ | ||
1136 | 195104, | ||
1137 | 196605, | ||
1138 | ], | ||
1139 | [ | ||
1140 | 196608, | ||
1141 | 201546, | ||
1142 | ], | ||
1143 | [ | ||
1144 | 201547, | ||
1145 | 201551, | ||
1146 | ], | ||
1147 | [ | ||
1148 | 201552, | ||
1149 | 205743, | ||
1150 | ], | ||
1151 | [ | ||
1152 | 205744, | ||
1153 | 262141, | ||
1154 | ], | ||
1155 | ]; | ||
diff --git a/vendor/symfony/string/Resources/data/wcswidth_table_zero.php b/vendor/symfony/string/Resources/data/wcswidth_table_zero.php new file mode 100644 index 0000000..e5b26a2 --- /dev/null +++ b/vendor/symfony/string/Resources/data/wcswidth_table_zero.php | |||
@@ -0,0 +1,1415 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file has been auto-generated by the Symfony String Component for internal use. | ||
5 | * | ||
6 | * Unicode version: 15.1.0 | ||
7 | * Date: 2023-09-13T11:47:13+00:00 | ||
8 | */ | ||
9 | |||
10 | return [ | ||
11 | [ | ||
12 | 768, | ||
13 | 879, | ||
14 | ], | ||
15 | [ | ||
16 | 1155, | ||
17 | 1159, | ||
18 | ], | ||
19 | [ | ||
20 | 1160, | ||
21 | 1161, | ||
22 | ], | ||
23 | [ | ||
24 | 1425, | ||
25 | 1469, | ||
26 | ], | ||
27 | [ | ||
28 | 1471, | ||
29 | 1471, | ||
30 | ], | ||
31 | [ | ||
32 | 1473, | ||
33 | 1474, | ||
34 | ], | ||
35 | [ | ||
36 | 1476, | ||
37 | 1477, | ||
38 | ], | ||
39 | [ | ||
40 | 1479, | ||
41 | 1479, | ||
42 | ], | ||
43 | [ | ||
44 | 1552, | ||
45 | 1562, | ||
46 | ], | ||
47 | [ | ||
48 | 1611, | ||
49 | 1631, | ||
50 | ], | ||
51 | [ | ||
52 | 1648, | ||
53 | 1648, | ||
54 | ], | ||
55 | [ | ||
56 | 1750, | ||
57 | 1756, | ||
58 | ], | ||
59 | [ | ||
60 | 1759, | ||
61 | 1764, | ||
62 | ], | ||
63 | [ | ||
64 | 1767, | ||
65 | 1768, | ||
66 | ], | ||
67 | [ | ||
68 | 1770, | ||
69 | 1773, | ||
70 | ], | ||
71 | [ | ||
72 | 1809, | ||
73 | 1809, | ||
74 | ], | ||
75 | [ | ||
76 | 1840, | ||
77 | 1866, | ||
78 | ], | ||
79 | [ | ||
80 | 1958, | ||
81 | 1968, | ||
82 | ], | ||
83 | [ | ||
84 | 2027, | ||
85 | 2035, | ||
86 | ], | ||
87 | [ | ||
88 | 2045, | ||
89 | 2045, | ||
90 | ], | ||
91 | [ | ||
92 | 2070, | ||
93 | 2073, | ||
94 | ], | ||
95 | [ | ||
96 | 2075, | ||
97 | 2083, | ||
98 | ], | ||
99 | [ | ||
100 | 2085, | ||
101 | 2087, | ||
102 | ], | ||
103 | [ | ||
104 | 2089, | ||
105 | 2093, | ||
106 | ], | ||
107 | [ | ||
108 | 2137, | ||
109 | 2139, | ||
110 | ], | ||
111 | [ | ||
112 | 2200, | ||
113 | 2207, | ||
114 | ], | ||
115 | [ | ||
116 | 2250, | ||
117 | 2273, | ||
118 | ], | ||
119 | [ | ||
120 | 2275, | ||
121 | 2306, | ||
122 | ], | ||
123 | [ | ||
124 | 2362, | ||
125 | 2362, | ||
126 | ], | ||
127 | [ | ||
128 | 2364, | ||
129 | 2364, | ||
130 | ], | ||
131 | [ | ||
132 | 2369, | ||
133 | 2376, | ||
134 | ], | ||
135 | [ | ||
136 | 2381, | ||
137 | 2381, | ||
138 | ], | ||
139 | [ | ||
140 | 2385, | ||
141 | 2391, | ||
142 | ], | ||
143 | [ | ||
144 | 2402, | ||
145 | 2403, | ||
146 | ], | ||
147 | [ | ||
148 | 2433, | ||
149 | 2433, | ||
150 | ], | ||
151 | [ | ||
152 | 2492, | ||
153 | 2492, | ||
154 | ], | ||
155 | [ | ||
156 | 2497, | ||
157 | 2500, | ||
158 | ], | ||
159 | [ | ||
160 | 2509, | ||
161 | 2509, | ||
162 | ], | ||
163 | [ | ||
164 | 2530, | ||
165 | 2531, | ||
166 | ], | ||
167 | [ | ||
168 | 2558, | ||
169 | 2558, | ||
170 | ], | ||
171 | [ | ||
172 | 2561, | ||
173 | 2562, | ||
174 | ], | ||
175 | [ | ||
176 | 2620, | ||
177 | 2620, | ||
178 | ], | ||
179 | [ | ||
180 | 2625, | ||
181 | 2626, | ||
182 | ], | ||
183 | [ | ||
184 | 2631, | ||
185 | 2632, | ||
186 | ], | ||
187 | [ | ||
188 | 2635, | ||
189 | 2637, | ||
190 | ], | ||
191 | [ | ||
192 | 2641, | ||
193 | 2641, | ||
194 | ], | ||
195 | [ | ||
196 | 2672, | ||
197 | 2673, | ||
198 | ], | ||
199 | [ | ||
200 | 2677, | ||
201 | 2677, | ||
202 | ], | ||
203 | [ | ||
204 | 2689, | ||
205 | 2690, | ||
206 | ], | ||
207 | [ | ||
208 | 2748, | ||
209 | 2748, | ||
210 | ], | ||
211 | [ | ||
212 | 2753, | ||
213 | 2757, | ||
214 | ], | ||
215 | [ | ||
216 | 2759, | ||
217 | 2760, | ||
218 | ], | ||
219 | [ | ||
220 | 2765, | ||
221 | 2765, | ||
222 | ], | ||
223 | [ | ||
224 | 2786, | ||
225 | 2787, | ||
226 | ], | ||
227 | [ | ||
228 | 2810, | ||
229 | 2815, | ||
230 | ], | ||
231 | [ | ||
232 | 2817, | ||
233 | 2817, | ||
234 | ], | ||
235 | [ | ||
236 | 2876, | ||
237 | 2876, | ||
238 | ], | ||
239 | [ | ||
240 | 2879, | ||
241 | 2879, | ||
242 | ], | ||
243 | [ | ||
244 | 2881, | ||
245 | 2884, | ||
246 | ], | ||
247 | [ | ||
248 | 2893, | ||
249 | 2893, | ||
250 | ], | ||
251 | [ | ||
252 | 2901, | ||
253 | 2902, | ||
254 | ], | ||
255 | [ | ||
256 | 2914, | ||
257 | 2915, | ||
258 | ], | ||
259 | [ | ||
260 | 2946, | ||
261 | 2946, | ||
262 | ], | ||
263 | [ | ||
264 | 3008, | ||
265 | 3008, | ||
266 | ], | ||
267 | [ | ||
268 | 3021, | ||
269 | 3021, | ||
270 | ], | ||
271 | [ | ||
272 | 3072, | ||
273 | 3072, | ||
274 | ], | ||
275 | [ | ||
276 | 3076, | ||
277 | 3076, | ||
278 | ], | ||
279 | [ | ||
280 | 3132, | ||
281 | 3132, | ||
282 | ], | ||
283 | [ | ||
284 | 3134, | ||
285 | 3136, | ||
286 | ], | ||
287 | [ | ||
288 | 3142, | ||
289 | 3144, | ||
290 | ], | ||
291 | [ | ||
292 | 3146, | ||
293 | 3149, | ||
294 | ], | ||
295 | [ | ||
296 | 3157, | ||
297 | 3158, | ||
298 | ], | ||
299 | [ | ||
300 | 3170, | ||
301 | 3171, | ||
302 | ], | ||
303 | [ | ||
304 | 3201, | ||
305 | 3201, | ||
306 | ], | ||
307 | [ | ||
308 | 3260, | ||
309 | 3260, | ||
310 | ], | ||
311 | [ | ||
312 | 3263, | ||
313 | 3263, | ||
314 | ], | ||
315 | [ | ||
316 | 3270, | ||
317 | 3270, | ||
318 | ], | ||
319 | [ | ||
320 | 3276, | ||
321 | 3277, | ||
322 | ], | ||
323 | [ | ||
324 | 3298, | ||
325 | 3299, | ||
326 | ], | ||
327 | [ | ||
328 | 3328, | ||
329 | 3329, | ||
330 | ], | ||
331 | [ | ||
332 | 3387, | ||
333 | 3388, | ||
334 | ], | ||
335 | [ | ||
336 | 3393, | ||
337 | 3396, | ||
338 | ], | ||
339 | [ | ||
340 | 3405, | ||
341 | 3405, | ||
342 | ], | ||
343 | [ | ||
344 | 3426, | ||
345 | 3427, | ||
346 | ], | ||
347 | [ | ||
348 | 3457, | ||
349 | 3457, | ||
350 | ], | ||
351 | [ | ||
352 | 3530, | ||
353 | 3530, | ||
354 | ], | ||
355 | [ | ||
356 | 3538, | ||
357 | 3540, | ||
358 | ], | ||
359 | [ | ||
360 | 3542, | ||
361 | 3542, | ||
362 | ], | ||
363 | [ | ||
364 | 3633, | ||
365 | 3633, | ||
366 | ], | ||
367 | [ | ||
368 | 3636, | ||
369 | 3642, | ||
370 | ], | ||
371 | [ | ||
372 | 3655, | ||
373 | 3662, | ||
374 | ], | ||
375 | [ | ||
376 | 3761, | ||
377 | 3761, | ||
378 | ], | ||
379 | [ | ||
380 | 3764, | ||
381 | 3772, | ||
382 | ], | ||
383 | [ | ||
384 | 3784, | ||
385 | 3790, | ||
386 | ], | ||
387 | [ | ||
388 | 3864, | ||
389 | 3865, | ||
390 | ], | ||
391 | [ | ||
392 | 3893, | ||
393 | 3893, | ||
394 | ], | ||
395 | [ | ||
396 | 3895, | ||
397 | 3895, | ||
398 | ], | ||
399 | [ | ||
400 | 3897, | ||
401 | 3897, | ||
402 | ], | ||
403 | [ | ||
404 | 3953, | ||
405 | 3966, | ||
406 | ], | ||
407 | [ | ||
408 | 3968, | ||
409 | 3972, | ||
410 | ], | ||
411 | [ | ||
412 | 3974, | ||
413 | 3975, | ||
414 | ], | ||
415 | [ | ||
416 | 3981, | ||
417 | 3991, | ||
418 | ], | ||
419 | [ | ||
420 | 3993, | ||
421 | 4028, | ||
422 | ], | ||
423 | [ | ||
424 | 4038, | ||
425 | 4038, | ||
426 | ], | ||
427 | [ | ||
428 | 4141, | ||
429 | 4144, | ||
430 | ], | ||
431 | [ | ||
432 | 4146, | ||
433 | 4151, | ||
434 | ], | ||
435 | [ | ||
436 | 4153, | ||
437 | 4154, | ||
438 | ], | ||
439 | [ | ||
440 | 4157, | ||
441 | 4158, | ||
442 | ], | ||
443 | [ | ||
444 | 4184, | ||
445 | 4185, | ||
446 | ], | ||
447 | [ | ||
448 | 4190, | ||
449 | 4192, | ||
450 | ], | ||
451 | [ | ||
452 | 4209, | ||
453 | 4212, | ||
454 | ], | ||
455 | [ | ||
456 | 4226, | ||
457 | 4226, | ||
458 | ], | ||
459 | [ | ||
460 | 4229, | ||
461 | 4230, | ||
462 | ], | ||
463 | [ | ||
464 | 4237, | ||
465 | 4237, | ||
466 | ], | ||
467 | [ | ||
468 | 4253, | ||
469 | 4253, | ||
470 | ], | ||
471 | [ | ||
472 | 4957, | ||
473 | 4959, | ||
474 | ], | ||
475 | [ | ||
476 | 5906, | ||
477 | 5908, | ||
478 | ], | ||
479 | [ | ||
480 | 5938, | ||
481 | 5939, | ||
482 | ], | ||
483 | [ | ||
484 | 5970, | ||
485 | 5971, | ||
486 | ], | ||
487 | [ | ||
488 | 6002, | ||
489 | 6003, | ||
490 | ], | ||
491 | [ | ||
492 | 6068, | ||
493 | 6069, | ||
494 | ], | ||
495 | [ | ||
496 | 6071, | ||
497 | 6077, | ||
498 | ], | ||
499 | [ | ||
500 | 6086, | ||
501 | 6086, | ||
502 | ], | ||
503 | [ | ||
504 | 6089, | ||
505 | 6099, | ||
506 | ], | ||
507 | [ | ||
508 | 6109, | ||
509 | 6109, | ||
510 | ], | ||
511 | [ | ||
512 | 6155, | ||
513 | 6157, | ||
514 | ], | ||
515 | [ | ||
516 | 6159, | ||
517 | 6159, | ||
518 | ], | ||
519 | [ | ||
520 | 6277, | ||
521 | 6278, | ||
522 | ], | ||
523 | [ | ||
524 | 6313, | ||
525 | 6313, | ||
526 | ], | ||
527 | [ | ||
528 | 6432, | ||
529 | 6434, | ||
530 | ], | ||
531 | [ | ||
532 | 6439, | ||
533 | 6440, | ||
534 | ], | ||
535 | [ | ||
536 | 6450, | ||
537 | 6450, | ||
538 | ], | ||
539 | [ | ||
540 | 6457, | ||
541 | 6459, | ||
542 | ], | ||
543 | [ | ||
544 | 6679, | ||
545 | 6680, | ||
546 | ], | ||
547 | [ | ||
548 | 6683, | ||
549 | 6683, | ||
550 | ], | ||
551 | [ | ||
552 | 6742, | ||
553 | 6742, | ||
554 | ], | ||
555 | [ | ||
556 | 6744, | ||
557 | 6750, | ||
558 | ], | ||
559 | [ | ||
560 | 6752, | ||
561 | 6752, | ||
562 | ], | ||
563 | [ | ||
564 | 6754, | ||
565 | 6754, | ||
566 | ], | ||
567 | [ | ||
568 | 6757, | ||
569 | 6764, | ||
570 | ], | ||
571 | [ | ||
572 | 6771, | ||
573 | 6780, | ||
574 | ], | ||
575 | [ | ||
576 | 6783, | ||
577 | 6783, | ||
578 | ], | ||
579 | [ | ||
580 | 6832, | ||
581 | 6845, | ||
582 | ], | ||
583 | [ | ||
584 | 6846, | ||
585 | 6846, | ||
586 | ], | ||
587 | [ | ||
588 | 6847, | ||
589 | 6862, | ||
590 | ], | ||
591 | [ | ||
592 | 6912, | ||
593 | 6915, | ||
594 | ], | ||
595 | [ | ||
596 | 6964, | ||
597 | 6964, | ||
598 | ], | ||
599 | [ | ||
600 | 6966, | ||
601 | 6970, | ||
602 | ], | ||
603 | [ | ||
604 | 6972, | ||
605 | 6972, | ||
606 | ], | ||
607 | [ | ||
608 | 6978, | ||
609 | 6978, | ||
610 | ], | ||
611 | [ | ||
612 | 7019, | ||
613 | 7027, | ||
614 | ], | ||
615 | [ | ||
616 | 7040, | ||
617 | 7041, | ||
618 | ], | ||
619 | [ | ||
620 | 7074, | ||
621 | 7077, | ||
622 | ], | ||
623 | [ | ||
624 | 7080, | ||
625 | 7081, | ||
626 | ], | ||
627 | [ | ||
628 | 7083, | ||
629 | 7085, | ||
630 | ], | ||
631 | [ | ||
632 | 7142, | ||
633 | 7142, | ||
634 | ], | ||
635 | [ | ||
636 | 7144, | ||
637 | 7145, | ||
638 | ], | ||
639 | [ | ||
640 | 7149, | ||
641 | 7149, | ||
642 | ], | ||
643 | [ | ||
644 | 7151, | ||
645 | 7153, | ||
646 | ], | ||
647 | [ | ||
648 | 7212, | ||
649 | 7219, | ||
650 | ], | ||
651 | [ | ||
652 | 7222, | ||
653 | 7223, | ||
654 | ], | ||
655 | [ | ||
656 | 7376, | ||
657 | 7378, | ||
658 | ], | ||
659 | [ | ||
660 | 7380, | ||
661 | 7392, | ||
662 | ], | ||
663 | [ | ||
664 | 7394, | ||
665 | 7400, | ||
666 | ], | ||
667 | [ | ||
668 | 7405, | ||
669 | 7405, | ||
670 | ], | ||
671 | [ | ||
672 | 7412, | ||
673 | 7412, | ||
674 | ], | ||
675 | [ | ||
676 | 7416, | ||
677 | 7417, | ||
678 | ], | ||
679 | [ | ||
680 | 7616, | ||
681 | 7679, | ||
682 | ], | ||
683 | [ | ||
684 | 8400, | ||
685 | 8412, | ||
686 | ], | ||
687 | [ | ||
688 | 8413, | ||
689 | 8416, | ||
690 | ], | ||
691 | [ | ||
692 | 8417, | ||
693 | 8417, | ||
694 | ], | ||
695 | [ | ||
696 | 8418, | ||
697 | 8420, | ||
698 | ], | ||
699 | [ | ||
700 | 8421, | ||
701 | 8432, | ||
702 | ], | ||
703 | [ | ||
704 | 11503, | ||
705 | 11505, | ||
706 | ], | ||
707 | [ | ||
708 | 11647, | ||
709 | 11647, | ||
710 | ], | ||
711 | [ | ||
712 | 11744, | ||
713 | 11775, | ||
714 | ], | ||
715 | [ | ||
716 | 12330, | ||
717 | 12333, | ||
718 | ], | ||
719 | [ | ||
720 | 12441, | ||
721 | 12442, | ||
722 | ], | ||
723 | [ | ||
724 | 42607, | ||
725 | 42607, | ||
726 | ], | ||
727 | [ | ||
728 | 42608, | ||
729 | 42610, | ||
730 | ], | ||
731 | [ | ||
732 | 42612, | ||
733 | 42621, | ||
734 | ], | ||
735 | [ | ||
736 | 42654, | ||
737 | 42655, | ||
738 | ], | ||
739 | [ | ||
740 | 42736, | ||
741 | 42737, | ||
742 | ], | ||
743 | [ | ||
744 | 43010, | ||
745 | 43010, | ||
746 | ], | ||
747 | [ | ||
748 | 43014, | ||
749 | 43014, | ||
750 | ], | ||
751 | [ | ||
752 | 43019, | ||
753 | 43019, | ||
754 | ], | ||
755 | [ | ||
756 | 43045, | ||
757 | 43046, | ||
758 | ], | ||
759 | [ | ||
760 | 43052, | ||
761 | 43052, | ||
762 | ], | ||
763 | [ | ||
764 | 43204, | ||
765 | 43205, | ||
766 | ], | ||
767 | [ | ||
768 | 43232, | ||
769 | 43249, | ||
770 | ], | ||
771 | [ | ||
772 | 43263, | ||
773 | 43263, | ||
774 | ], | ||
775 | [ | ||
776 | 43302, | ||
777 | 43309, | ||
778 | ], | ||
779 | [ | ||
780 | 43335, | ||
781 | 43345, | ||
782 | ], | ||
783 | [ | ||
784 | 43392, | ||
785 | 43394, | ||
786 | ], | ||
787 | [ | ||
788 | 43443, | ||
789 | 43443, | ||
790 | ], | ||
791 | [ | ||
792 | 43446, | ||
793 | 43449, | ||
794 | ], | ||
795 | [ | ||
796 | 43452, | ||
797 | 43453, | ||
798 | ], | ||
799 | [ | ||
800 | 43493, | ||
801 | 43493, | ||
802 | ], | ||
803 | [ | ||
804 | 43561, | ||
805 | 43566, | ||
806 | ], | ||
807 | [ | ||
808 | 43569, | ||
809 | 43570, | ||
810 | ], | ||
811 | [ | ||
812 | 43573, | ||
813 | 43574, | ||
814 | ], | ||
815 | [ | ||
816 | 43587, | ||
817 | 43587, | ||
818 | ], | ||
819 | [ | ||
820 | 43596, | ||
821 | 43596, | ||
822 | ], | ||
823 | [ | ||
824 | 43644, | ||
825 | 43644, | ||
826 | ], | ||
827 | [ | ||
828 | 43696, | ||
829 | 43696, | ||
830 | ], | ||
831 | [ | ||
832 | 43698, | ||
833 | 43700, | ||
834 | ], | ||
835 | [ | ||
836 | 43703, | ||
837 | 43704, | ||
838 | ], | ||
839 | [ | ||
840 | 43710, | ||
841 | 43711, | ||
842 | ], | ||
843 | [ | ||
844 | 43713, | ||
845 | 43713, | ||
846 | ], | ||
847 | [ | ||
848 | 43756, | ||
849 | 43757, | ||
850 | ], | ||
851 | [ | ||
852 | 43766, | ||
853 | 43766, | ||
854 | ], | ||
855 | [ | ||
856 | 44005, | ||
857 | 44005, | ||
858 | ], | ||
859 | [ | ||
860 | 44008, | ||
861 | 44008, | ||
862 | ], | ||
863 | [ | ||
864 | 44013, | ||
865 | 44013, | ||
866 | ], | ||
867 | [ | ||
868 | 64286, | ||
869 | 64286, | ||
870 | ], | ||
871 | [ | ||
872 | 65024, | ||
873 | 65039, | ||
874 | ], | ||
875 | [ | ||
876 | 65056, | ||
877 | 65071, | ||
878 | ], | ||
879 | [ | ||
880 | 66045, | ||
881 | 66045, | ||
882 | ], | ||
883 | [ | ||
884 | 66272, | ||
885 | 66272, | ||
886 | ], | ||
887 | [ | ||
888 | 66422, | ||
889 | 66426, | ||
890 | ], | ||
891 | [ | ||
892 | 68097, | ||
893 | 68099, | ||
894 | ], | ||
895 | [ | ||
896 | 68101, | ||
897 | 68102, | ||
898 | ], | ||
899 | [ | ||
900 | 68108, | ||
901 | 68111, | ||
902 | ], | ||
903 | [ | ||
904 | 68152, | ||
905 | 68154, | ||
906 | ], | ||
907 | [ | ||
908 | 68159, | ||
909 | 68159, | ||
910 | ], | ||
911 | [ | ||
912 | 68325, | ||
913 | 68326, | ||
914 | ], | ||
915 | [ | ||
916 | 68900, | ||
917 | 68903, | ||
918 | ], | ||
919 | [ | ||
920 | 69291, | ||
921 | 69292, | ||
922 | ], | ||
923 | [ | ||
924 | 69373, | ||
925 | 69375, | ||
926 | ], | ||
927 | [ | ||
928 | 69446, | ||
929 | 69456, | ||
930 | ], | ||
931 | [ | ||
932 | 69506, | ||
933 | 69509, | ||
934 | ], | ||
935 | [ | ||
936 | 69633, | ||
937 | 69633, | ||
938 | ], | ||
939 | [ | ||
940 | 69688, | ||
941 | 69702, | ||
942 | ], | ||
943 | [ | ||
944 | 69744, | ||
945 | 69744, | ||
946 | ], | ||
947 | [ | ||
948 | 69747, | ||
949 | 69748, | ||
950 | ], | ||
951 | [ | ||
952 | 69759, | ||
953 | 69761, | ||
954 | ], | ||
955 | [ | ||
956 | 69811, | ||
957 | 69814, | ||
958 | ], | ||
959 | [ | ||
960 | 69817, | ||
961 | 69818, | ||
962 | ], | ||
963 | [ | ||
964 | 69826, | ||
965 | 69826, | ||
966 | ], | ||
967 | [ | ||
968 | 69888, | ||
969 | 69890, | ||
970 | ], | ||
971 | [ | ||
972 | 69927, | ||
973 | 69931, | ||
974 | ], | ||
975 | [ | ||
976 | 69933, | ||
977 | 69940, | ||
978 | ], | ||
979 | [ | ||
980 | 70003, | ||
981 | 70003, | ||
982 | ], | ||
983 | [ | ||
984 | 70016, | ||
985 | 70017, | ||
986 | ], | ||
987 | [ | ||
988 | 70070, | ||
989 | 70078, | ||
990 | ], | ||
991 | [ | ||
992 | 70089, | ||
993 | 70092, | ||
994 | ], | ||
995 | [ | ||
996 | 70095, | ||
997 | 70095, | ||
998 | ], | ||
999 | [ | ||
1000 | 70191, | ||
1001 | 70193, | ||
1002 | ], | ||
1003 | [ | ||
1004 | 70196, | ||
1005 | 70196, | ||
1006 | ], | ||
1007 | [ | ||
1008 | 70198, | ||
1009 | 70199, | ||
1010 | ], | ||
1011 | [ | ||
1012 | 70206, | ||
1013 | 70206, | ||
1014 | ], | ||
1015 | [ | ||
1016 | 70209, | ||
1017 | 70209, | ||
1018 | ], | ||
1019 | [ | ||
1020 | 70367, | ||
1021 | 70367, | ||
1022 | ], | ||
1023 | [ | ||
1024 | 70371, | ||
1025 | 70378, | ||
1026 | ], | ||
1027 | [ | ||
1028 | 70400, | ||
1029 | 70401, | ||
1030 | ], | ||
1031 | [ | ||
1032 | 70459, | ||
1033 | 70460, | ||
1034 | ], | ||
1035 | [ | ||
1036 | 70464, | ||
1037 | 70464, | ||
1038 | ], | ||
1039 | [ | ||
1040 | 70502, | ||
1041 | 70508, | ||
1042 | ], | ||
1043 | [ | ||
1044 | 70512, | ||
1045 | 70516, | ||
1046 | ], | ||
1047 | [ | ||
1048 | 70712, | ||
1049 | 70719, | ||
1050 | ], | ||
1051 | [ | ||
1052 | 70722, | ||
1053 | 70724, | ||
1054 | ], | ||
1055 | [ | ||
1056 | 70726, | ||
1057 | 70726, | ||
1058 | ], | ||
1059 | [ | ||
1060 | 70750, | ||
1061 | 70750, | ||
1062 | ], | ||
1063 | [ | ||
1064 | 70835, | ||
1065 | 70840, | ||
1066 | ], | ||
1067 | [ | ||
1068 | 70842, | ||
1069 | 70842, | ||
1070 | ], | ||
1071 | [ | ||
1072 | 70847, | ||
1073 | 70848, | ||
1074 | ], | ||
1075 | [ | ||
1076 | 70850, | ||
1077 | 70851, | ||
1078 | ], | ||
1079 | [ | ||
1080 | 71090, | ||
1081 | 71093, | ||
1082 | ], | ||
1083 | [ | ||
1084 | 71100, | ||
1085 | 71101, | ||
1086 | ], | ||
1087 | [ | ||
1088 | 71103, | ||
1089 | 71104, | ||
1090 | ], | ||
1091 | [ | ||
1092 | 71132, | ||
1093 | 71133, | ||
1094 | ], | ||
1095 | [ | ||
1096 | 71219, | ||
1097 | 71226, | ||
1098 | ], | ||
1099 | [ | ||
1100 | 71229, | ||
1101 | 71229, | ||
1102 | ], | ||
1103 | [ | ||
1104 | 71231, | ||
1105 | 71232, | ||
1106 | ], | ||
1107 | [ | ||
1108 | 71339, | ||
1109 | 71339, | ||
1110 | ], | ||
1111 | [ | ||
1112 | 71341, | ||
1113 | 71341, | ||
1114 | ], | ||
1115 | [ | ||
1116 | 71344, | ||
1117 | 71349, | ||
1118 | ], | ||
1119 | [ | ||
1120 | 71351, | ||
1121 | 71351, | ||
1122 | ], | ||
1123 | [ | ||
1124 | 71453, | ||
1125 | 71455, | ||
1126 | ], | ||
1127 | [ | ||
1128 | 71458, | ||
1129 | 71461, | ||
1130 | ], | ||
1131 | [ | ||
1132 | 71463, | ||
1133 | 71467, | ||
1134 | ], | ||
1135 | [ | ||
1136 | 71727, | ||
1137 | 71735, | ||
1138 | ], | ||
1139 | [ | ||
1140 | 71737, | ||
1141 | 71738, | ||
1142 | ], | ||
1143 | [ | ||
1144 | 71995, | ||
1145 | 71996, | ||
1146 | ], | ||
1147 | [ | ||
1148 | 71998, | ||
1149 | 71998, | ||
1150 | ], | ||
1151 | [ | ||
1152 | 72003, | ||
1153 | 72003, | ||
1154 | ], | ||
1155 | [ | ||
1156 | 72148, | ||
1157 | 72151, | ||
1158 | ], | ||
1159 | [ | ||
1160 | 72154, | ||
1161 | 72155, | ||
1162 | ], | ||
1163 | [ | ||
1164 | 72160, | ||
1165 | 72160, | ||
1166 | ], | ||
1167 | [ | ||
1168 | 72193, | ||
1169 | 72202, | ||
1170 | ], | ||
1171 | [ | ||
1172 | 72243, | ||
1173 | 72248, | ||
1174 | ], | ||
1175 | [ | ||
1176 | 72251, | ||
1177 | 72254, | ||
1178 | ], | ||
1179 | [ | ||
1180 | 72263, | ||
1181 | 72263, | ||
1182 | ], | ||
1183 | [ | ||
1184 | 72273, | ||
1185 | 72278, | ||
1186 | ], | ||
1187 | [ | ||
1188 | 72281, | ||
1189 | 72283, | ||
1190 | ], | ||
1191 | [ | ||
1192 | 72330, | ||
1193 | 72342, | ||
1194 | ], | ||
1195 | [ | ||
1196 | 72344, | ||
1197 | 72345, | ||
1198 | ], | ||
1199 | [ | ||
1200 | 72752, | ||
1201 | 72758, | ||
1202 | ], | ||
1203 | [ | ||
1204 | 72760, | ||
1205 | 72765, | ||
1206 | ], | ||
1207 | [ | ||
1208 | 72767, | ||
1209 | 72767, | ||
1210 | ], | ||
1211 | [ | ||
1212 | 72850, | ||
1213 | 72871, | ||
1214 | ], | ||
1215 | [ | ||
1216 | 72874, | ||
1217 | 72880, | ||
1218 | ], | ||
1219 | [ | ||
1220 | 72882, | ||
1221 | 72883, | ||
1222 | ], | ||
1223 | [ | ||
1224 | 72885, | ||
1225 | 72886, | ||
1226 | ], | ||
1227 | [ | ||
1228 | 73009, | ||
1229 | 73014, | ||
1230 | ], | ||
1231 | [ | ||
1232 | 73018, | ||
1233 | 73018, | ||
1234 | ], | ||
1235 | [ | ||
1236 | 73020, | ||
1237 | 73021, | ||
1238 | ], | ||
1239 | [ | ||
1240 | 73023, | ||
1241 | 73029, | ||
1242 | ], | ||
1243 | [ | ||
1244 | 73031, | ||
1245 | 73031, | ||
1246 | ], | ||
1247 | [ | ||
1248 | 73104, | ||
1249 | 73105, | ||
1250 | ], | ||
1251 | [ | ||
1252 | 73109, | ||
1253 | 73109, | ||
1254 | ], | ||
1255 | [ | ||
1256 | 73111, | ||
1257 | 73111, | ||
1258 | ], | ||
1259 | [ | ||
1260 | 73459, | ||
1261 | 73460, | ||
1262 | ], | ||
1263 | [ | ||
1264 | 73472, | ||
1265 | 73473, | ||
1266 | ], | ||
1267 | [ | ||
1268 | 73526, | ||
1269 | 73530, | ||
1270 | ], | ||
1271 | [ | ||
1272 | 73536, | ||
1273 | 73536, | ||
1274 | ], | ||
1275 | [ | ||
1276 | 73538, | ||
1277 | 73538, | ||
1278 | ], | ||
1279 | [ | ||
1280 | 78912, | ||
1281 | 78912, | ||
1282 | ], | ||
1283 | [ | ||
1284 | 78919, | ||
1285 | 78933, | ||
1286 | ], | ||
1287 | [ | ||
1288 | 92912, | ||
1289 | 92916, | ||
1290 | ], | ||
1291 | [ | ||
1292 | 92976, | ||
1293 | 92982, | ||
1294 | ], | ||
1295 | [ | ||
1296 | 94031, | ||
1297 | 94031, | ||
1298 | ], | ||
1299 | [ | ||
1300 | 94095, | ||
1301 | 94098, | ||
1302 | ], | ||
1303 | [ | ||
1304 | 94180, | ||
1305 | 94180, | ||
1306 | ], | ||
1307 | [ | ||
1308 | 113821, | ||
1309 | 113822, | ||
1310 | ], | ||
1311 | [ | ||
1312 | 118528, | ||
1313 | 118573, | ||
1314 | ], | ||
1315 | [ | ||
1316 | 118576, | ||
1317 | 118598, | ||
1318 | ], | ||
1319 | [ | ||
1320 | 119143, | ||
1321 | 119145, | ||
1322 | ], | ||
1323 | [ | ||
1324 | 119163, | ||
1325 | 119170, | ||
1326 | ], | ||
1327 | [ | ||
1328 | 119173, | ||
1329 | 119179, | ||
1330 | ], | ||
1331 | [ | ||
1332 | 119210, | ||
1333 | 119213, | ||
1334 | ], | ||
1335 | [ | ||
1336 | 119362, | ||
1337 | 119364, | ||
1338 | ], | ||
1339 | [ | ||
1340 | 121344, | ||
1341 | 121398, | ||
1342 | ], | ||
1343 | [ | ||
1344 | 121403, | ||
1345 | 121452, | ||
1346 | ], | ||
1347 | [ | ||
1348 | 121461, | ||
1349 | 121461, | ||
1350 | ], | ||
1351 | [ | ||
1352 | 121476, | ||
1353 | 121476, | ||
1354 | ], | ||
1355 | [ | ||
1356 | 121499, | ||
1357 | 121503, | ||
1358 | ], | ||
1359 | [ | ||
1360 | 121505, | ||
1361 | 121519, | ||
1362 | ], | ||
1363 | [ | ||
1364 | 122880, | ||
1365 | 122886, | ||
1366 | ], | ||
1367 | [ | ||
1368 | 122888, | ||
1369 | 122904, | ||
1370 | ], | ||
1371 | [ | ||
1372 | 122907, | ||
1373 | 122913, | ||
1374 | ], | ||
1375 | [ | ||
1376 | 122915, | ||
1377 | 122916, | ||
1378 | ], | ||
1379 | [ | ||
1380 | 122918, | ||
1381 | 122922, | ||
1382 | ], | ||
1383 | [ | ||
1384 | 123023, | ||
1385 | 123023, | ||
1386 | ], | ||
1387 | [ | ||
1388 | 123184, | ||
1389 | 123190, | ||
1390 | ], | ||
1391 | [ | ||
1392 | 123566, | ||
1393 | 123566, | ||
1394 | ], | ||
1395 | [ | ||
1396 | 123628, | ||
1397 | 123631, | ||
1398 | ], | ||
1399 | [ | ||
1400 | 124140, | ||
1401 | 124143, | ||
1402 | ], | ||
1403 | [ | ||
1404 | 125136, | ||
1405 | 125142, | ||
1406 | ], | ||
1407 | [ | ||
1408 | 125252, | ||
1409 | 125258, | ||
1410 | ], | ||
1411 | [ | ||
1412 | 917760, | ||
1413 | 917999, | ||
1414 | ], | ||
1415 | ]; | ||
diff --git a/vendor/symfony/string/Resources/functions.php b/vendor/symfony/string/Resources/functions.php new file mode 100644 index 0000000..7a97040 --- /dev/null +++ b/vendor/symfony/string/Resources/functions.php | |||
@@ -0,0 +1,38 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\String; | ||
13 | |||
14 | if (!\function_exists(u::class)) { | ||
15 | function u(?string $string = ''): UnicodeString | ||
16 | { | ||
17 | return new UnicodeString($string ?? ''); | ||
18 | } | ||
19 | } | ||
20 | |||
21 | if (!\function_exists(b::class)) { | ||
22 | function b(?string $string = ''): ByteString | ||
23 | { | ||
24 | return new ByteString($string ?? ''); | ||
25 | } | ||
26 | } | ||
27 | |||
28 | if (!\function_exists(s::class)) { | ||
29 | /** | ||
30 | * @return UnicodeString|ByteString | ||
31 | */ | ||
32 | function s(?string $string = ''): AbstractString | ||
33 | { | ||
34 | $string ??= ''; | ||
35 | |||
36 | return preg_match('//u', $string) ? new UnicodeString($string) : new ByteString($string); | ||
37 | } | ||
38 | } | ||
diff --git a/vendor/symfony/string/Slugger/AsciiSlugger.php b/vendor/symfony/string/Slugger/AsciiSlugger.php new file mode 100644 index 0000000..d254532 --- /dev/null +++ b/vendor/symfony/string/Slugger/AsciiSlugger.php | |||
@@ -0,0 +1,207 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\String\Slugger; | ||
13 | |||
14 | use Symfony\Component\Emoji\EmojiTransliterator; | ||
15 | use Symfony\Component\String\AbstractUnicodeString; | ||
16 | use Symfony\Component\String\UnicodeString; | ||
17 | use Symfony\Contracts\Translation\LocaleAwareInterface; | ||
18 | |||
19 | if (!interface_exists(LocaleAwareInterface::class)) { | ||
20 | throw new \LogicException('You cannot use the "Symfony\Component\String\Slugger\AsciiSlugger" as the "symfony/translation-contracts" package is not installed. Try running "composer require symfony/translation-contracts".'); | ||
21 | } | ||
22 | |||
23 | /** | ||
24 | * @author Titouan Galopin <galopintitouan@gmail.com> | ||
25 | */ | ||
26 | class AsciiSlugger implements SluggerInterface, LocaleAwareInterface | ||
27 | { | ||
28 | private const LOCALE_TO_TRANSLITERATOR_ID = [ | ||
29 | 'am' => 'Amharic-Latin', | ||
30 | 'ar' => 'Arabic-Latin', | ||
31 | 'az' => 'Azerbaijani-Latin', | ||
32 | 'be' => 'Belarusian-Latin', | ||
33 | 'bg' => 'Bulgarian-Latin', | ||
34 | 'bn' => 'Bengali-Latin', | ||
35 | 'de' => 'de-ASCII', | ||
36 | 'el' => 'Greek-Latin', | ||
37 | 'fa' => 'Persian-Latin', | ||
38 | 'he' => 'Hebrew-Latin', | ||
39 | 'hy' => 'Armenian-Latin', | ||
40 | 'ka' => 'Georgian-Latin', | ||
41 | 'kk' => 'Kazakh-Latin', | ||
42 | 'ky' => 'Kirghiz-Latin', | ||
43 | 'ko' => 'Korean-Latin', | ||
44 | 'mk' => 'Macedonian-Latin', | ||
45 | 'mn' => 'Mongolian-Latin', | ||
46 | 'or' => 'Oriya-Latin', | ||
47 | 'ps' => 'Pashto-Latin', | ||
48 | 'ru' => 'Russian-Latin', | ||
49 | 'sr' => 'Serbian-Latin', | ||
50 | 'sr_Cyrl' => 'Serbian-Latin', | ||
51 | 'th' => 'Thai-Latin', | ||
52 | 'tk' => 'Turkmen-Latin', | ||
53 | 'uk' => 'Ukrainian-Latin', | ||
54 | 'uz' => 'Uzbek-Latin', | ||
55 | 'zh' => 'Han-Latin', | ||
56 | ]; | ||
57 | |||
58 | private \Closure|array $symbolsMap = [ | ||
59 | 'en' => ['@' => 'at', '&' => 'and'], | ||
60 | ]; | ||
61 | private bool|string $emoji = false; | ||
62 | |||
63 | /** | ||
64 | * Cache of transliterators per locale. | ||
65 | * | ||
66 | * @var \Transliterator[] | ||
67 | */ | ||
68 | private array $transliterators = []; | ||
69 | |||
70 | public function __construct( | ||
71 | private ?string $defaultLocale = null, | ||
72 | array|\Closure|null $symbolsMap = null, | ||
73 | ) { | ||
74 | $this->symbolsMap = $symbolsMap ?? $this->symbolsMap; | ||
75 | } | ||
76 | |||
77 | public function setLocale(string $locale): void | ||
78 | { | ||
79 | $this->defaultLocale = $locale; | ||
80 | } | ||
81 | |||
82 | public function getLocale(): string | ||
83 | { | ||
84 | return $this->defaultLocale; | ||
85 | } | ||
86 | |||
87 | /** | ||
88 | * @param bool|string $emoji true will use the same locale, | ||
89 | * false will disable emoji, | ||
90 | * and a string to use a specific locale | ||
91 | */ | ||
92 | public function withEmoji(bool|string $emoji = true): static | ||
93 | { | ||
94 | if (false !== $emoji && !class_exists(EmojiTransliterator::class)) { | ||
95 | throw new \LogicException(sprintf('You cannot use the "%s()" method as the "symfony/emoji" package is not installed. Try running "composer require symfony/emoji".', __METHOD__)); | ||
96 | } | ||
97 | |||
98 | $new = clone $this; | ||
99 | $new->emoji = $emoji; | ||
100 | |||
101 | return $new; | ||
102 | } | ||
103 | |||
104 | public function slug(string $string, string $separator = '-', ?string $locale = null): AbstractUnicodeString | ||
105 | { | ||
106 | $locale ??= $this->defaultLocale; | ||
107 | |||
108 | $transliterator = []; | ||
109 | if ($locale && ('de' === $locale || str_starts_with($locale, 'de_'))) { | ||
110 | // Use the shortcut for German in UnicodeString::ascii() if possible (faster and no requirement on intl) | ||
111 | $transliterator = ['de-ASCII']; | ||
112 | } elseif (\function_exists('transliterator_transliterate') && $locale) { | ||
113 | $transliterator = (array) $this->createTransliterator($locale); | ||
114 | } | ||
115 | |||
116 | if ($emojiTransliterator = $this->createEmojiTransliterator($locale)) { | ||
117 | $transliterator[] = $emojiTransliterator; | ||
118 | } | ||
119 | |||
120 | if ($this->symbolsMap instanceof \Closure) { | ||
121 | // If the symbols map is passed as a closure, there is no need to fallback to the parent locale | ||
122 | // as the closure can just provide substitutions for all locales of interest. | ||
123 | $symbolsMap = $this->symbolsMap; | ||
124 | array_unshift($transliterator, static fn ($s) => $symbolsMap($s, $locale)); | ||
125 | } | ||
126 | |||
127 | $unicodeString = (new UnicodeString($string))->ascii($transliterator); | ||
128 | |||
129 | if (\is_array($this->symbolsMap)) { | ||
130 | $map = null; | ||
131 | if (isset($this->symbolsMap[$locale])) { | ||
132 | $map = $this->symbolsMap[$locale]; | ||
133 | } else { | ||
134 | $parent = self::getParentLocale($locale); | ||
135 | if ($parent && isset($this->symbolsMap[$parent])) { | ||
136 | $map = $this->symbolsMap[$parent]; | ||
137 | } | ||
138 | } | ||
139 | if ($map) { | ||
140 | foreach ($map as $char => $replace) { | ||
141 | $unicodeString = $unicodeString->replace($char, ' '.$replace.' '); | ||
142 | } | ||
143 | } | ||
144 | } | ||
145 | |||
146 | return $unicodeString | ||
147 | ->replaceMatches('/[^A-Za-z0-9]++/', $separator) | ||
148 | ->trim($separator) | ||
149 | ; | ||
150 | } | ||
151 | |||
152 | private function createTransliterator(string $locale): ?\Transliterator | ||
153 | { | ||
154 | if (\array_key_exists($locale, $this->transliterators)) { | ||
155 | return $this->transliterators[$locale]; | ||
156 | } | ||
157 | |||
158 | // Exact locale supported, cache and return | ||
159 | if ($id = self::LOCALE_TO_TRANSLITERATOR_ID[$locale] ?? null) { | ||
160 | return $this->transliterators[$locale] = \Transliterator::create($id.'/BGN') ?? \Transliterator::create($id); | ||
161 | } | ||
162 | |||
163 | // Locale not supported and no parent, fallback to any-latin | ||
164 | if (!$parent = self::getParentLocale($locale)) { | ||
165 | return $this->transliterators[$locale] = null; | ||
166 | } | ||
167 | |||
168 | // Try to use the parent locale (ie. try "de" for "de_AT") and cache both locales | ||
169 | if ($id = self::LOCALE_TO_TRANSLITERATOR_ID[$parent] ?? null) { | ||
170 | $transliterator = \Transliterator::create($id.'/BGN') ?? \Transliterator::create($id); | ||
171 | } | ||
172 | |||
173 | return $this->transliterators[$locale] = $this->transliterators[$parent] = $transliterator ?? null; | ||
174 | } | ||
175 | |||
176 | private function createEmojiTransliterator(?string $locale): ?EmojiTransliterator | ||
177 | { | ||
178 | if (\is_string($this->emoji)) { | ||
179 | $locale = $this->emoji; | ||
180 | } elseif (!$this->emoji) { | ||
181 | return null; | ||
182 | } | ||
183 | |||
184 | while (null !== $locale) { | ||
185 | try { | ||
186 | return EmojiTransliterator::create("emoji-$locale"); | ||
187 | } catch (\IntlException) { | ||
188 | $locale = self::getParentLocale($locale); | ||
189 | } | ||
190 | } | ||
191 | |||
192 | return null; | ||
193 | } | ||
194 | |||
195 | private static function getParentLocale(?string $locale): ?string | ||
196 | { | ||
197 | if (!$locale) { | ||
198 | return null; | ||
199 | } | ||
200 | if (false === $str = strrchr($locale, '_')) { | ||
201 | // no parent locale | ||
202 | return null; | ||
203 | } | ||
204 | |||
205 | return substr($locale, 0, -\strlen($str)); | ||
206 | } | ||
207 | } | ||
diff --git a/vendor/symfony/string/Slugger/SluggerInterface.php b/vendor/symfony/string/Slugger/SluggerInterface.php new file mode 100644 index 0000000..dd0d581 --- /dev/null +++ b/vendor/symfony/string/Slugger/SluggerInterface.php | |||
@@ -0,0 +1,27 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\String\Slugger; | ||
13 | |||
14 | use Symfony\Component\String\AbstractUnicodeString; | ||
15 | |||
16 | /** | ||
17 | * Creates a URL-friendly slug from a given string. | ||
18 | * | ||
19 | * @author Titouan Galopin <galopintitouan@gmail.com> | ||
20 | */ | ||
21 | interface SluggerInterface | ||
22 | { | ||
23 | /** | ||
24 | * Creates a slug for the given string and locale, using appropriate transliteration when needed. | ||
25 | */ | ||
26 | public function slug(string $string, string $separator = '-', ?string $locale = null): AbstractUnicodeString; | ||
27 | } | ||
diff --git a/vendor/symfony/string/UnicodeString.php b/vendor/symfony/string/UnicodeString.php new file mode 100644 index 0000000..4b16caf --- /dev/null +++ b/vendor/symfony/string/UnicodeString.php | |||
@@ -0,0 +1,382 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\String; | ||
13 | |||
14 | use Symfony\Component\String\Exception\ExceptionInterface; | ||
15 | use Symfony\Component\String\Exception\InvalidArgumentException; | ||
16 | |||
17 | /** | ||
18 | * Represents a string of Unicode grapheme clusters encoded as UTF-8. | ||
19 | * | ||
20 | * A letter followed by combining characters (accents typically) form what Unicode defines | ||
21 | * as a grapheme cluster: a character as humans mean it in written texts. This class knows | ||
22 | * about the concept and won't split a letter apart from its combining accents. It also | ||
23 | * ensures all string comparisons happen on their canonically-composed representation, | ||
24 | * ignoring e.g. the order in which accents are listed when a letter has many of them. | ||
25 | * | ||
26 | * @see https://unicode.org/reports/tr15/ | ||
27 | * | ||
28 | * @author Nicolas Grekas <p@tchwork.com> | ||
29 | * @author Hugo Hamon <hugohamon@neuf.fr> | ||
30 | * | ||
31 | * @throws ExceptionInterface | ||
32 | */ | ||
33 | class UnicodeString extends AbstractUnicodeString | ||
34 | { | ||
35 | public function __construct(string $string = '') | ||
36 | { | ||
37 | if ('' === $string || normalizer_is_normalized($this->string = $string)) { | ||
38 | return; | ||
39 | } | ||
40 | |||
41 | if (false === $string = normalizer_normalize($string)) { | ||
42 | throw new InvalidArgumentException('Invalid UTF-8 string.'); | ||
43 | } | ||
44 | |||
45 | $this->string = $string; | ||
46 | } | ||
47 | |||
48 | public function append(string ...$suffix): static | ||
49 | { | ||
50 | $str = clone $this; | ||
51 | $str->string = $this->string.(1 >= \count($suffix) ? ($suffix[0] ?? '') : implode('', $suffix)); | ||
52 | |||
53 | if (normalizer_is_normalized($str->string)) { | ||
54 | return $str; | ||
55 | } | ||
56 | |||
57 | if (false === $string = normalizer_normalize($str->string)) { | ||
58 | throw new InvalidArgumentException('Invalid UTF-8 string.'); | ||
59 | } | ||
60 | |||
61 | $str->string = $string; | ||
62 | |||
63 | return $str; | ||
64 | } | ||
65 | |||
66 | public function chunk(int $length = 1): array | ||
67 | { | ||
68 | if (1 > $length) { | ||
69 | throw new InvalidArgumentException('The chunk length must be greater than zero.'); | ||
70 | } | ||
71 | |||
72 | if ('' === $this->string) { | ||
73 | return []; | ||
74 | } | ||
75 | |||
76 | $rx = '/('; | ||
77 | while (65535 < $length) { | ||
78 | $rx .= '\X{65535}'; | ||
79 | $length -= 65535; | ||
80 | } | ||
81 | $rx .= '\X{'.$length.'})/u'; | ||
82 | |||
83 | $str = clone $this; | ||
84 | $chunks = []; | ||
85 | |||
86 | foreach (preg_split($rx, $this->string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY) as $chunk) { | ||
87 | $str->string = $chunk; | ||
88 | $chunks[] = clone $str; | ||
89 | } | ||
90 | |||
91 | return $chunks; | ||
92 | } | ||
93 | |||
94 | public function endsWith(string|iterable|AbstractString $suffix): bool | ||
95 | { | ||
96 | if ($suffix instanceof AbstractString) { | ||
97 | $suffix = $suffix->string; | ||
98 | } elseif (!\is_string($suffix)) { | ||
99 | return parent::endsWith($suffix); | ||
100 | } | ||
101 | |||
102 | $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC; | ||
103 | normalizer_is_normalized($suffix, $form) ?: $suffix = normalizer_normalize($suffix, $form); | ||
104 | |||
105 | if ('' === $suffix || false === $suffix) { | ||
106 | return false; | ||
107 | } | ||
108 | |||
109 | if ($this->ignoreCase) { | ||
110 | return 0 === mb_stripos(grapheme_extract($this->string, \strlen($suffix), \GRAPHEME_EXTR_MAXBYTES, \strlen($this->string) - \strlen($suffix)), $suffix, 0, 'UTF-8'); | ||
111 | } | ||
112 | |||
113 | return $suffix === grapheme_extract($this->string, \strlen($suffix), \GRAPHEME_EXTR_MAXBYTES, \strlen($this->string) - \strlen($suffix)); | ||
114 | } | ||
115 | |||
116 | public function equalsTo(string|iterable|AbstractString $string): bool | ||
117 | { | ||
118 | if ($string instanceof AbstractString) { | ||
119 | $string = $string->string; | ||
120 | } elseif (!\is_string($string)) { | ||
121 | return parent::equalsTo($string); | ||
122 | } | ||
123 | |||
124 | $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC; | ||
125 | normalizer_is_normalized($string, $form) ?: $string = normalizer_normalize($string, $form); | ||
126 | |||
127 | if ('' !== $string && false !== $string && $this->ignoreCase) { | ||
128 | return \strlen($string) === \strlen($this->string) && 0 === mb_stripos($this->string, $string, 0, 'UTF-8'); | ||
129 | } | ||
130 | |||
131 | return $string === $this->string; | ||
132 | } | ||
133 | |||
134 | public function indexOf(string|iterable|AbstractString $needle, int $offset = 0): ?int | ||
135 | { | ||
136 | if ($needle instanceof AbstractString) { | ||
137 | $needle = $needle->string; | ||
138 | } elseif (!\is_string($needle)) { | ||
139 | return parent::indexOf($needle, $offset); | ||
140 | } | ||
141 | |||
142 | $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC; | ||
143 | normalizer_is_normalized($needle, $form) ?: $needle = normalizer_normalize($needle, $form); | ||
144 | |||
145 | if ('' === $needle || false === $needle) { | ||
146 | return null; | ||
147 | } | ||
148 | |||
149 | try { | ||
150 | $i = $this->ignoreCase ? grapheme_stripos($this->string, $needle, $offset) : grapheme_strpos($this->string, $needle, $offset); | ||
151 | } catch (\ValueError) { | ||
152 | return null; | ||
153 | } | ||
154 | |||
155 | return false === $i ? null : $i; | ||
156 | } | ||
157 | |||
158 | public function indexOfLast(string|iterable|AbstractString $needle, int $offset = 0): ?int | ||
159 | { | ||
160 | if ($needle instanceof AbstractString) { | ||
161 | $needle = $needle->string; | ||
162 | } elseif (!\is_string($needle)) { | ||
163 | return parent::indexOfLast($needle, $offset); | ||
164 | } | ||
165 | |||
166 | $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC; | ||
167 | normalizer_is_normalized($needle, $form) ?: $needle = normalizer_normalize($needle, $form); | ||
168 | |||
169 | if ('' === $needle || false === $needle) { | ||
170 | return null; | ||
171 | } | ||
172 | |||
173 | $string = $this->string; | ||
174 | |||
175 | if (0 > $offset) { | ||
176 | // workaround https://bugs.php.net/74264 | ||
177 | if (0 > $offset += grapheme_strlen($needle)) { | ||
178 | $string = grapheme_substr($string, 0, $offset); | ||
179 | } | ||
180 | $offset = 0; | ||
181 | } | ||
182 | |||
183 | $i = $this->ignoreCase ? grapheme_strripos($string, $needle, $offset) : grapheme_strrpos($string, $needle, $offset); | ||
184 | |||
185 | return false === $i ? null : $i; | ||
186 | } | ||
187 | |||
188 | public function join(array $strings, ?string $lastGlue = null): static | ||
189 | { | ||
190 | $str = parent::join($strings, $lastGlue); | ||
191 | normalizer_is_normalized($str->string) ?: $str->string = normalizer_normalize($str->string); | ||
192 | |||
193 | return $str; | ||
194 | } | ||
195 | |||
196 | public function length(): int | ||
197 | { | ||
198 | return grapheme_strlen($this->string); | ||
199 | } | ||
200 | |||
201 | public function normalize(int $form = self::NFC): static | ||
202 | { | ||
203 | $str = clone $this; | ||
204 | |||
205 | if (\in_array($form, [self::NFC, self::NFKC], true)) { | ||
206 | normalizer_is_normalized($str->string, $form) ?: $str->string = normalizer_normalize($str->string, $form); | ||
207 | } elseif (!\in_array($form, [self::NFD, self::NFKD], true)) { | ||
208 | throw new InvalidArgumentException('Unsupported normalization form.'); | ||
209 | } elseif (!normalizer_is_normalized($str->string, $form)) { | ||
210 | $str->string = normalizer_normalize($str->string, $form); | ||
211 | $str->ignoreCase = null; | ||
212 | } | ||
213 | |||
214 | return $str; | ||
215 | } | ||
216 | |||
217 | public function prepend(string ...$prefix): static | ||
218 | { | ||
219 | $str = clone $this; | ||
220 | $str->string = (1 >= \count($prefix) ? ($prefix[0] ?? '') : implode('', $prefix)).$this->string; | ||
221 | |||
222 | if (normalizer_is_normalized($str->string)) { | ||
223 | return $str; | ||
224 | } | ||
225 | |||
226 | if (false === $string = normalizer_normalize($str->string)) { | ||
227 | throw new InvalidArgumentException('Invalid UTF-8 string.'); | ||
228 | } | ||
229 | |||
230 | $str->string = $string; | ||
231 | |||
232 | return $str; | ||
233 | } | ||
234 | |||
235 | public function replace(string $from, string $to): static | ||
236 | { | ||
237 | $str = clone $this; | ||
238 | normalizer_is_normalized($from) ?: $from = normalizer_normalize($from); | ||
239 | |||
240 | if ('' !== $from && false !== $from) { | ||
241 | $tail = $str->string; | ||
242 | $result = ''; | ||
243 | $indexOf = $this->ignoreCase ? 'grapheme_stripos' : 'grapheme_strpos'; | ||
244 | |||
245 | while ('' !== $tail && false !== $i = $indexOf($tail, $from)) { | ||
246 | $slice = grapheme_substr($tail, 0, $i); | ||
247 | $result .= $slice.$to; | ||
248 | $tail = substr($tail, \strlen($slice) + \strlen($from)); | ||
249 | } | ||
250 | |||
251 | $str->string = $result.$tail; | ||
252 | |||
253 | if (normalizer_is_normalized($str->string)) { | ||
254 | return $str; | ||
255 | } | ||
256 | |||
257 | if (false === $string = normalizer_normalize($str->string)) { | ||
258 | throw new InvalidArgumentException('Invalid UTF-8 string.'); | ||
259 | } | ||
260 | |||
261 | $str->string = $string; | ||
262 | } | ||
263 | |||
264 | return $str; | ||
265 | } | ||
266 | |||
267 | public function replaceMatches(string $fromRegexp, string|callable $to): static | ||
268 | { | ||
269 | $str = parent::replaceMatches($fromRegexp, $to); | ||
270 | normalizer_is_normalized($str->string) ?: $str->string = normalizer_normalize($str->string); | ||
271 | |||
272 | return $str; | ||
273 | } | ||
274 | |||
275 | public function slice(int $start = 0, ?int $length = null): static | ||
276 | { | ||
277 | $str = clone $this; | ||
278 | |||
279 | $str->string = (string) grapheme_substr($this->string, $start, $length ?? 2147483647); | ||
280 | |||
281 | return $str; | ||
282 | } | ||
283 | |||
284 | public function splice(string $replacement, int $start = 0, ?int $length = null): static | ||
285 | { | ||
286 | $str = clone $this; | ||
287 | |||
288 | $start = $start ? \strlen(grapheme_substr($this->string, 0, $start)) : 0; | ||
289 | $length = $length ? \strlen(grapheme_substr($this->string, $start, $length ?? 2147483647)) : $length; | ||
290 | $str->string = substr_replace($this->string, $replacement, $start, $length ?? 2147483647); | ||
291 | |||
292 | if (normalizer_is_normalized($str->string)) { | ||
293 | return $str; | ||
294 | } | ||
295 | |||
296 | if (false === $string = normalizer_normalize($str->string)) { | ||
297 | throw new InvalidArgumentException('Invalid UTF-8 string.'); | ||
298 | } | ||
299 | |||
300 | $str->string = $string; | ||
301 | |||
302 | return $str; | ||
303 | } | ||
304 | |||
305 | public function split(string $delimiter, ?int $limit = null, ?int $flags = null): array | ||
306 | { | ||
307 | if (1 > $limit ??= 2147483647) { | ||
308 | throw new InvalidArgumentException('Split limit must be a positive integer.'); | ||
309 | } | ||
310 | |||
311 | if ('' === $delimiter) { | ||
312 | throw new InvalidArgumentException('Split delimiter is empty.'); | ||
313 | } | ||
314 | |||
315 | if (null !== $flags) { | ||
316 | return parent::split($delimiter.'u', $limit, $flags); | ||
317 | } | ||
318 | |||
319 | normalizer_is_normalized($delimiter) ?: $delimiter = normalizer_normalize($delimiter); | ||
320 | |||
321 | if (false === $delimiter) { | ||
322 | throw new InvalidArgumentException('Split delimiter is not a valid UTF-8 string.'); | ||
323 | } | ||
324 | |||
325 | $str = clone $this; | ||
326 | $tail = $this->string; | ||
327 | $chunks = []; | ||
328 | $indexOf = $this->ignoreCase ? 'grapheme_stripos' : 'grapheme_strpos'; | ||
329 | |||
330 | while (1 < $limit && false !== $i = $indexOf($tail, $delimiter)) { | ||
331 | $str->string = grapheme_substr($tail, 0, $i); | ||
332 | $chunks[] = clone $str; | ||
333 | $tail = substr($tail, \strlen($str->string) + \strlen($delimiter)); | ||
334 | --$limit; | ||
335 | } | ||
336 | |||
337 | $str->string = $tail; | ||
338 | $chunks[] = clone $str; | ||
339 | |||
340 | return $chunks; | ||
341 | } | ||
342 | |||
343 | public function startsWith(string|iterable|AbstractString $prefix): bool | ||
344 | { | ||
345 | if ($prefix instanceof AbstractString) { | ||
346 | $prefix = $prefix->string; | ||
347 | } elseif (!\is_string($prefix)) { | ||
348 | return parent::startsWith($prefix); | ||
349 | } | ||
350 | |||
351 | $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC; | ||
352 | normalizer_is_normalized($prefix, $form) ?: $prefix = normalizer_normalize($prefix, $form); | ||
353 | |||
354 | if ('' === $prefix || false === $prefix) { | ||
355 | return false; | ||
356 | } | ||
357 | |||
358 | if ($this->ignoreCase) { | ||
359 | return 0 === mb_stripos(grapheme_extract($this->string, \strlen($prefix), \GRAPHEME_EXTR_MAXBYTES), $prefix, 0, 'UTF-8'); | ||
360 | } | ||
361 | |||
362 | return $prefix === grapheme_extract($this->string, \strlen($prefix), \GRAPHEME_EXTR_MAXBYTES); | ||
363 | } | ||
364 | |||
365 | public function __wakeup(): void | ||
366 | { | ||
367 | if (!\is_string($this->string)) { | ||
368 | throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); | ||
369 | } | ||
370 | |||
371 | normalizer_is_normalized($this->string) ?: $this->string = normalizer_normalize($this->string); | ||
372 | } | ||
373 | |||
374 | public function __clone() | ||
375 | { | ||
376 | if (null === $this->ignoreCase) { | ||
377 | normalizer_is_normalized($this->string) ?: $this->string = normalizer_normalize($this->string); | ||
378 | } | ||
379 | |||
380 | $this->ignoreCase = false; | ||
381 | } | ||
382 | } | ||
diff --git a/vendor/symfony/string/composer.json b/vendor/symfony/string/composer.json new file mode 100644 index 0000000..10d0ee6 --- /dev/null +++ b/vendor/symfony/string/composer.json | |||
@@ -0,0 +1,44 @@ | |||
1 | { | ||
2 | "name": "symfony/string", | ||
3 | "type": "library", | ||
4 | "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", | ||
5 | "keywords": ["string", "utf8", "utf-8", "grapheme", "i18n", "unicode"], | ||
6 | "homepage": "https://symfony.com", | ||
7 | "license": "MIT", | ||
8 | "authors": [ | ||
9 | { | ||
10 | "name": "Nicolas Grekas", | ||
11 | "email": "p@tchwork.com" | ||
12 | }, | ||
13 | { | ||
14 | "name": "Symfony Community", | ||
15 | "homepage": "https://symfony.com/contributors" | ||
16 | } | ||
17 | ], | ||
18 | "require": { | ||
19 | "php": ">=8.2", | ||
20 | "symfony/polyfill-ctype": "~1.8", | ||
21 | "symfony/polyfill-intl-grapheme": "~1.0", | ||
22 | "symfony/polyfill-intl-normalizer": "~1.0", | ||
23 | "symfony/polyfill-mbstring": "~1.0" | ||
24 | }, | ||
25 | "require-dev": { | ||
26 | "symfony/error-handler": "^6.4|^7.0", | ||
27 | "symfony/emoji": "^7.1", | ||
28 | "symfony/http-client": "^6.4|^7.0", | ||
29 | "symfony/intl": "^6.4|^7.0", | ||
30 | "symfony/translation-contracts": "^2.5|^3.0", | ||
31 | "symfony/var-exporter": "^6.4|^7.0" | ||
32 | }, | ||
33 | "conflict": { | ||
34 | "symfony/translation-contracts": "<2.5" | ||
35 | }, | ||
36 | "autoload": { | ||
37 | "psr-4": { "Symfony\\Component\\String\\": "" }, | ||
38 | "files": [ "Resources/functions.php" ], | ||
39 | "exclude-from-classmap": [ | ||
40 | "/Tests/" | ||
41 | ] | ||
42 | }, | ||
43 | "minimum-stability": "dev" | ||
44 | } | ||