PK/Z #CustomFilterIterator.phpnuW+A * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Finder\Iterator; /** * CustomFilterIterator filters files by applying anonymous functions. * * The anonymous function receives a \SplFileInfo and must return false * to remove files. * * @author Fabien Potencier * * @extends \FilterIterator */ class CustomFilterIterator extends \FilterIterator { private array $filters = []; /** * @param \Iterator $iterator The Iterator to filter * @param callable[] $filters An array of PHP callbacks * * @throws \InvalidArgumentException */ public function __construct(\Iterator $iterator, array $filters) { foreach ($filters as $filter) { if (!\is_callable($filter)) { throw new \InvalidArgumentException('Invalid PHP callback.'); } } $this->filters = $filters; parent::__construct($iterator); } /** * Filters the iterator values. */ public function accept(): bool { $fileinfo = $this->current(); foreach ($this->filters as $filter) { if (false === $filter($fileinfo)) { return false; } } return true; } } PK/Z-9LazyIterator.phpnuW+A * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Finder\Iterator; /** * @author Jérémy Derussé * * @internal */ class LazyIterator implements \IteratorAggregate { private \Closure $iteratorFactory; public function __construct(callable $iteratorFactory) { $this->iteratorFactory = $iteratorFactory(...); } public function getIterator(): \Traversable { yield from ($this->iteratorFactory)(); } } PK/Zhn n "ExcludeDirectoryFilterIterator.phpnuW+A * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Finder\Iterator; use Symfony\Component\Finder\SplFileInfo; /** * ExcludeDirectoryFilterIterator filters out directories. * * @author Fabien Potencier * * @extends \FilterIterator * * @implements \RecursiveIterator */ class ExcludeDirectoryFilterIterator extends \FilterIterator implements \RecursiveIterator { /** @var \Iterator */ private \Iterator $iterator; private bool $isRecursive; private array $excludedDirs = []; private ?string $excludedPattern = null; /** * @param \Iterator $iterator The Iterator to filter * @param string[] $directories An array of directories to exclude */ public function __construct(\Iterator $iterator, array $directories) { $this->iterator = $iterator; $this->isRecursive = $iterator instanceof \RecursiveIterator; $patterns = []; foreach ($directories as $directory) { $directory = rtrim($directory, '/'); if (!$this->isRecursive || str_contains($directory, '/')) { $patterns[] = preg_quote($directory, '#'); } else { $this->excludedDirs[$directory] = true; } } if ($patterns) { $this->excludedPattern = '#(?:^|/)(?:'.implode('|', $patterns).')(?:/|$)#'; } parent::__construct($iterator); } /** * Filters the iterator values. */ public function accept(): bool { if ($this->isRecursive && isset($this->excludedDirs[$this->getFilename()]) && $this->isDir()) { return false; } if ($this->excludedPattern) { $path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath(); $path = str_replace('\\', '/', $path); return !preg_match($this->excludedPattern, $path); } return true; } public function hasChildren(): bool { return $this->isRecursive && $this->iterator->hasChildren(); } public function getChildren(): self { $children = new self($this->iterator->getChildren(), []); $children->excludedDirs = $this->excludedDirs; $children->excludedPattern = $this->excludedPattern; return $children; } } PK/Z"fooFileTypeFilterIterator.phpnuW+A * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Finder\Iterator; /** * FileTypeFilterIterator only keeps files, directories, or both. * * @author Fabien Potencier * * @extends \FilterIterator */ class FileTypeFilterIterator extends \FilterIterator { public const ONLY_FILES = 1; public const ONLY_DIRECTORIES = 2; private int $mode; /** * @param \Iterator $iterator The Iterator to filter * @param int $mode The mode (self::ONLY_FILES or self::ONLY_DIRECTORIES) */ public function __construct(\Iterator $iterator, int $mode) { $this->mode = $mode; parent::__construct($iterator); } /** * Filters the iterator values. */ public function accept(): bool { $fileinfo = $this->current(); if (self::ONLY_DIRECTORIES === (self::ONLY_DIRECTORIES & $this->mode) && $fileinfo->isFile()) { return false; } elseif (self::ONLY_FILES === (self::ONLY_FILES & $this->mode) && $fileinfo->isDir()) { return false; } return true; } } PK/ZgPPSizeRangeFilterIterator.phpnuW+A * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Finder\Iterator; use Symfony\Component\Finder\Comparator\NumberComparator; /** * SizeRangeFilterIterator filters out files that are not in the given size range. * * @author Fabien Potencier * * @extends \FilterIterator */ class SizeRangeFilterIterator extends \FilterIterator { private array $comparators = []; /** * @param \Iterator $iterator * @param NumberComparator[] $comparators */ public function __construct(\Iterator $iterator, array $comparators) { $this->comparators = $comparators; parent::__construct($iterator); } /** * Filters the iterator values. */ public function accept(): bool { $fileinfo = $this->current(); if (!$fileinfo->isFile()) { return true; } $filesize = $fileinfo->getSize(); foreach ($this->comparators as $compare) { if (!$compare->test($filesize)) { return false; } } return true; } } PK/ZQQFilenameFilterIterator.phpnuW+A * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Finder\Iterator; use Symfony\Component\Finder\Glob; /** * FilenameFilterIterator filters files by patterns (a regexp, a glob, or a string). * * @author Fabien Potencier * * @extends MultiplePcreFilterIterator */ class FilenameFilterIterator extends MultiplePcreFilterIterator { /** * Filters the iterator values. */ public function accept(): bool { return $this->isAccepted($this->current()->getFilename()); } /** * Converts glob to regexp. * * PCRE patterns are left unchanged. * Glob strings are transformed with Glob::toRegex(). * * @param string $str Pattern: glob or regexp */ protected function toRegex(string $str): string { return $this->isRegex($str) ? $str : Glob::toRegex($str); } } PK/Zdސ{PathFilterIterator.phpnuW+A * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Finder\Iterator; use Symfony\Component\Finder\SplFileInfo; /** * PathFilterIterator filters files by path patterns (e.g. some/special/dir). * * @author Fabien Potencier * @author Włodzimierz Gajda * * @extends MultiplePcreFilterIterator */ class PathFilterIterator extends MultiplePcreFilterIterator { /** * Filters the iterator values. */ public function accept(): bool { $filename = $this->current()->getRelativePathname(); if ('\\' === \DIRECTORY_SEPARATOR) { $filename = str_replace('\\', '/', $filename); } return $this->isAccepted($filename); } /** * Converts strings to regexp. * * PCRE patterns are left unchanged. * * Default conversion: * 'lorem/ipsum/dolor' ==> 'lorem\/ipsum\/dolor/' * * Use only / as directory separator (on Windows also). * * @param string $str Pattern: regexp or dirname */ protected function toRegex(string $str): string { return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/'; } } PK/ZyyDateRangeFilterIterator.phpnuW+A * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Finder\Iterator; use Symfony\Component\Finder\Comparator\DateComparator; /** * DateRangeFilterIterator filters out files that are not in the given date range (last modified dates). * * @author Fabien Potencier * * @extends \FilterIterator */ class DateRangeFilterIterator extends \FilterIterator { private array $comparators = []; /** * @param \Iterator $iterator * @param DateComparator[] $comparators */ public function __construct(\Iterator $iterator, array $comparators) { $this->comparators = $comparators; parent::__construct($iterator); } /** * Filters the iterator values. */ public function accept(): bool { $fileinfo = $this->current(); if (!file_exists($fileinfo->getPathname())) { return false; } $filedate = $fileinfo->getMTime(); foreach ($this->comparators as $compare) { if (!$compare->test($filedate)) { return false; } } return true; } } PK/Z~ FilecontentFilterIterator.phpnuW+A * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Finder\Iterator; use Symfony\Component\Finder\SplFileInfo; /** * FilecontentFilterIterator filters files by their contents using patterns (regexps or strings). * * @author Fabien Potencier * @author Włodzimierz Gajda * * @extends MultiplePcreFilterIterator */ class FilecontentFilterIterator extends MultiplePcreFilterIterator { /** * Filters the iterator values. */ public function accept(): bool { if (!$this->matchRegexps && !$this->noMatchRegexps) { return true; } $fileinfo = $this->current(); if ($fileinfo->isDir() || !$fileinfo->isReadable()) { return false; } $content = $fileinfo->getContents(); if (!$content) { return false; } return $this->isAccepted($content); } /** * Converts string to regexp if necessary. * * @param string $str Pattern: string or regexp */ protected function toRegex(string $str): string { return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/'; } } PK/ZD MultiplePcreFilterIterator.phpnuW+A * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Finder\Iterator; /** * MultiplePcreFilterIterator filters files using patterns (regexps, globs or strings). * * @author Fabien Potencier * * @template-covariant TKey * @template-covariant TValue * * @extends \FilterIterator */ abstract class MultiplePcreFilterIterator extends \FilterIterator { protected $matchRegexps = []; protected $noMatchRegexps = []; /** * @param \Iterator $iterator The Iterator to filter * @param string[] $matchPatterns An array of patterns that need to match * @param string[] $noMatchPatterns An array of patterns that need to not match */ public function __construct(\Iterator $iterator, array $matchPatterns, array $noMatchPatterns) { foreach ($matchPatterns as $pattern) { $this->matchRegexps[] = $this->toRegex($pattern); } foreach ($noMatchPatterns as $pattern) { $this->noMatchRegexps[] = $this->toRegex($pattern); } parent::__construct($iterator); } /** * Checks whether the string is accepted by the regex filters. * * If there is no regexps defined in the class, this method will accept the string. * Such case can be handled by child classes before calling the method if they want to * apply a different behavior. */ protected function isAccepted(string $string): bool { // should at least not match one rule to exclude foreach ($this->noMatchRegexps as $regex) { if (preg_match($regex, $string)) { return false; } } // should at least match one rule if ($this->matchRegexps) { foreach ($this->matchRegexps as $regex) { if (preg_match($regex, $string)) { return true; } } return false; } // If there is no match rules, the file is accepted return true; } /** * Checks whether the string is a regex. */ protected function isRegex(string $str): bool { $availableModifiers = 'imsxuADU'; if (\PHP_VERSION_ID >= 80200) { $availableModifiers .= 'n'; } if (preg_match('/^(.{3,}?)['.$availableModifiers.']*$/', $str, $m)) { $start = substr($m[1], 0, 1); $end = substr($m[1], -1); if ($start === $end) { return !preg_match('/[*?[:alnum:] \\\\]/', $start); } foreach ([['{', '}'], ['(', ')'], ['[', ']'], ['<', '>']] as $delimiters) { if ($start === $delimiters[0] && $end === $delimiters[1]) { return true; } } } return false; } /** * Converts string into regexp. */ abstract protected function toRegex(string $str): string; } PK/Z,,SortableIterator.phpnuW+A * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Finder\Iterator; /** * SortableIterator applies a sort on a given Iterator. * * @author Fabien Potencier * * @implements \IteratorAggregate */ class SortableIterator implements \IteratorAggregate { public const SORT_BY_NONE = 0; public const SORT_BY_NAME = 1; public const SORT_BY_TYPE = 2; public const SORT_BY_ACCESSED_TIME = 3; public const SORT_BY_CHANGED_TIME = 4; public const SORT_BY_MODIFIED_TIME = 5; public const SORT_BY_NAME_NATURAL = 6; public const SORT_BY_NAME_CASE_INSENSITIVE = 7; public const SORT_BY_NAME_NATURAL_CASE_INSENSITIVE = 8; public const SORT_BY_EXTENSION = 9; public const SORT_BY_SIZE = 10; /** @var \Traversable */ private \Traversable $iterator; private \Closure|int $sort; /** * @param \Traversable $iterator * @param int|callable $sort The sort type (SORT_BY_NAME, SORT_BY_TYPE, or a PHP callback) * * @throws \InvalidArgumentException */ public function __construct(\Traversable $iterator, int|callable $sort, bool $reverseOrder = false) { $this->iterator = $iterator; $order = $reverseOrder ? -1 : 1; if (self::SORT_BY_NAME === $sort) { $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); } elseif (self::SORT_BY_NAME_NATURAL === $sort) { $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * strnatcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); } elseif (self::SORT_BY_NAME_CASE_INSENSITIVE === $sort) { $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * strcasecmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); } elseif (self::SORT_BY_NAME_NATURAL_CASE_INSENSITIVE === $sort) { $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * strnatcasecmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); } elseif (self::SORT_BY_TYPE === $sort) { $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) { if ($a->isDir() && $b->isFile()) { return -$order; } elseif ($a->isFile() && $b->isDir()) { return $order; } return $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); }; } elseif (self::SORT_BY_ACCESSED_TIME === $sort) { $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * ($a->getATime() - $b->getATime()); } elseif (self::SORT_BY_CHANGED_TIME === $sort) { $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * ($a->getCTime() - $b->getCTime()); } elseif (self::SORT_BY_MODIFIED_TIME === $sort) { $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * ($a->getMTime() - $b->getMTime()); } elseif (self::SORT_BY_EXTENSION === $sort) { $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * strnatcmp($a->getExtension(), $b->getExtension()); } elseif (self::SORT_BY_SIZE === $sort) { $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * ($a->getSize() - $b->getSize()); } elseif (self::SORT_BY_NONE === $sort) { $this->sort = $order; } elseif (\is_callable($sort)) { $this->sort = $reverseOrder ? static fn (\SplFileInfo $a, \SplFileInfo $b) => -$sort($a, $b) : $sort(...); } else { throw new \InvalidArgumentException('The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.'); } } public function getIterator(): \Traversable { if (1 === $this->sort) { return $this->iterator; } $array = iterator_to_array($this->iterator, true); if (-1 === $this->sort) { $array = array_reverse($array); } else { uasort($array, $this->sort); } return new \ArrayIterator($array); } } PK/Z,bbDepthRangeFilterIterator.phpnuW+A * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Finder\Iterator; /** * DepthRangeFilterIterator limits the directory depth. * * @author Fabien Potencier * * @template-covariant TKey * @template-covariant TValue * * @extends \FilterIterator */ class DepthRangeFilterIterator extends \FilterIterator { private int $minDepth = 0; /** * @param \RecursiveIteratorIterator<\RecursiveIterator> $iterator The Iterator to filter * @param int $minDepth The min depth * @param int $maxDepth The max depth */ public function __construct(\RecursiveIteratorIterator $iterator, int $minDepth = 0, int $maxDepth = \PHP_INT_MAX) { $this->minDepth = $minDepth; $iterator->setMaxDepth(\PHP_INT_MAX === $maxDepth ? -1 : $maxDepth); parent::__construct($iterator); } /** * Filters the iterator values. */ public function accept(): bool { return $this->getInnerIterator()->getDepth() >= $this->minDepth; } } PK/ZogRecursiveDirectoryIterator.phpnuW+A * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Finder\Iterator; use Symfony\Component\Finder\Exception\AccessDeniedException; use Symfony\Component\Finder\SplFileInfo; /** * Extends the \RecursiveDirectoryIterator to support relative paths. * * @author Victor Berchet * * @extends \RecursiveDirectoryIterator */ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator { private bool $ignoreUnreadableDirs; private ?bool $rewindable = null; // these 3 properties take part of the performance optimization to avoid redoing the same work in all iterations private string $rootPath; private string $subPath; private string $directorySeparator = '/'; /** * @throws \RuntimeException */ public function __construct(string $path, int $flags, bool $ignoreUnreadableDirs = false) { if ($flags & (self::CURRENT_AS_PATHNAME | self::CURRENT_AS_SELF)) { throw new \RuntimeException('This iterator only support returning current as fileinfo.'); } parent::__construct($path, $flags); $this->ignoreUnreadableDirs = $ignoreUnreadableDirs; $this->rootPath = $path; if ('/' !== \DIRECTORY_SEPARATOR && !($flags & self::UNIX_PATHS)) { $this->directorySeparator = \DIRECTORY_SEPARATOR; } } /** * Return an instance of SplFileInfo with support for relative paths. */ public function current(): SplFileInfo { // the logic here avoids redoing the same work in all iterations if (!isset($this->subPath)) { $this->subPath = $this->getSubPath(); } $subPathname = $this->subPath; if ('' !== $subPathname) { $subPathname .= $this->directorySeparator; } $subPathname .= $this->getFilename(); if ('/' !== $basePath = $this->rootPath) { $basePath .= $this->directorySeparator; } return new SplFileInfo($basePath.$subPathname, $this->subPath, $subPathname); } public function hasChildren(bool $allowLinks = false): bool { $hasChildren = parent::hasChildren($allowLinks); if (!$hasChildren || !$this->ignoreUnreadableDirs) { return $hasChildren; } try { parent::getChildren(); return true; } catch (\UnexpectedValueException) { // If directory is unreadable and finder is set to ignore it, skip children return false; } } /** * @throws AccessDeniedException */ public function getChildren(): \RecursiveDirectoryIterator { try { $children = parent::getChildren(); if ($children instanceof self) { // parent method will call the constructor with default arguments, so unreadable dirs won't be ignored anymore $children->ignoreUnreadableDirs = $this->ignoreUnreadableDirs; // performance optimization to avoid redoing the same work in all children $children->rewindable = &$this->rewindable; $children->rootPath = $this->rootPath; } return $children; } catch (\UnexpectedValueException $e) { throw new AccessDeniedException($e->getMessage(), $e->getCode(), $e); } } /** * Do nothing for non rewindable stream. */ public function rewind(): void { if (false === $this->isRewindable()) { return; } parent::rewind(); } /** * Checks if the stream is rewindable. */ public function isRewindable(): bool { if (null !== $this->rewindable) { return $this->rewindable; } if (false !== $stream = @opendir($this->getPath())) { $infos = stream_get_meta_data($stream); closedir($stream); if ($infos['seekable']) { return $this->rewindable = true; } } return $this->rewindable = false; } } PK/ZܪY{{VcsIgnoredFilterIterator.phpnuW+A * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Finder\Iterator; use Symfony\Component\Finder\Gitignore; /** * @extends \FilterIterator */ final class VcsIgnoredFilterIterator extends \FilterIterator { /** * @var string */ private $baseDir; /** * @var array */ private $gitignoreFilesCache = []; /** * @var array */ private $ignoredPathsCache = []; /** * @param \Iterator $iterator */ public function __construct(\Iterator $iterator, string $baseDir) { $this->baseDir = $this->normalizePath($baseDir); foreach ($this->parentDirectoriesUpwards($this->baseDir) as $parentDirectory) { if (@is_dir("{$parentDirectory}/.git")) { $this->baseDir = $parentDirectory; break; } } parent::__construct($iterator); } public function accept(): bool { $file = $this->current(); $fileRealPath = $this->normalizePath($file->getRealPath()); return !$this->isIgnored($fileRealPath); } private function isIgnored(string $fileRealPath): bool { if (is_dir($fileRealPath) && !str_ends_with($fileRealPath, '/')) { $fileRealPath .= '/'; } if (isset($this->ignoredPathsCache[$fileRealPath])) { return $this->ignoredPathsCache[$fileRealPath]; } $ignored = false; foreach ($this->parentDirectoriesDownwards($fileRealPath) as $parentDirectory) { if ($this->isIgnored($parentDirectory)) { // rules in ignored directories are ignored, no need to check further. break; } $fileRelativePath = substr($fileRealPath, \strlen($parentDirectory) + 1); if (null === $regexps = $this->readGitignoreFile("{$parentDirectory}/.gitignore")) { continue; } [$exclusionRegex, $inclusionRegex] = $regexps; if (preg_match($exclusionRegex, $fileRelativePath)) { $ignored = true; continue; } if (preg_match($inclusionRegex, $fileRelativePath)) { $ignored = false; } } return $this->ignoredPathsCache[$fileRealPath] = $ignored; } /** * @return list */ private function parentDirectoriesUpwards(string $from): array { $parentDirectories = []; $parentDirectory = $from; while (true) { $newParentDirectory = \dirname($parentDirectory); // dirname('/') = '/' if ($newParentDirectory === $parentDirectory) { break; } $parentDirectories[] = $parentDirectory = $newParentDirectory; } return $parentDirectories; } private function parentDirectoriesUpTo(string $from, string $upTo): array { return array_filter( $this->parentDirectoriesUpwards($from), static fn (string $directory): bool => str_starts_with($directory, $upTo) ); } /** * @return list */ private function parentDirectoriesDownwards(string $fileRealPath): array { return array_reverse( $this->parentDirectoriesUpTo($fileRealPath, $this->baseDir) ); } /** * @return array{0: string, 1: string}|null */ private function readGitignoreFile(string $path): ?array { if (\array_key_exists($path, $this->gitignoreFilesCache)) { return $this->gitignoreFilesCache[$path]; } if (!file_exists($path)) { return $this->gitignoreFilesCache[$path] = null; } if (!is_file($path) || !is_readable($path)) { throw new \RuntimeException("The \"ignoreVCSIgnored\" option cannot be used by the Finder as the \"{$path}\" file is not readable."); } $gitignoreFileContent = file_get_contents($path); return $this->gitignoreFilesCache[$path] = [ Gitignore::toRegex($gitignoreFileContent), Gitignore::toRegexMatchingNegatedPatterns($gitignoreFileContent), ]; } private function normalizePath(string $path): string { if ('\\' === \DIRECTORY_SEPARATOR) { return str_replace('\\', '/', $path); } return $path; } } PK/Z #CustomFilterIterator.phpnuW+APK/Z-9?LazyIterator.phpnuW+APK/Zhn n "- ExcludeDirectoryFilterIterator.phpnuW+APK/Z"fooFileTypeFilterIterator.phpnuW+APK/ZgPPSizeRangeFilterIterator.phpnuW+APK/ZQQAFilenameFilterIterator.phpnuW+APK/Zdސ{#PathFilterIterator.phpnuW+APK/Zyy)DateRangeFilterIterator.phpnuW+APK/Z~ u/FilecontentFilterIterator.phpnuW+APK/ZD L5MultiplePcreFilterIterator.phpnuW+APK/Z,,2BSortableIterator.phpnuW+APK/Z,bbTDepthRangeFilterIterator.phpnuW+APK/ZogPZRecursiveDirectoryIterator.phpnuW+APK/ZܪY{{kVcsIgnoredFilterIterator.phpnuW+APKK~