diff --git a/Server/vendor/.gitignore b/Server/vendor/.gitignore
new file mode 100755
index 000000000..e69de29bb
diff --git a/Server/vendor/adbario/php-dot-notation/LICENSE.md b/Server/vendor/adbario/php-dot-notation/LICENSE.md
new file mode 100755
index 000000000..fe013238b
--- /dev/null
+++ b/Server/vendor/adbario/php-dot-notation/LICENSE.md
@@ -0,0 +1,21 @@
+# The MIT License (MIT)
+
+Copyright (c) 2016-2019 Riku Särkinen
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Server/vendor/adbario/php-dot-notation/composer.json b/Server/vendor/adbario/php-dot-notation/composer.json
new file mode 100755
index 000000000..cea712612
--- /dev/null
+++ b/Server/vendor/adbario/php-dot-notation/composer.json
@@ -0,0 +1,29 @@
+{
+ "name": "adbario/php-dot-notation",
+ "description": "PHP dot notation access to arrays",
+ "keywords": ["dotnotation", "arrayaccess"],
+ "homepage": "https://github.com/adbario/php-dot-notation",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Riku Särkinen",
+ "email": "riku@adbar.io"
+ }
+ ],
+ "require": {
+ "php": "^5.5 || ^7.0 || ^8.0",
+ "ext-json": "*"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8|^5.7|^6.6|^7.5|^8.5|^9.5",
+ "squizlabs/php_codesniffer": "^3.6"
+ },
+ "autoload": {
+ "files": [
+ "src/helpers.php"
+ ],
+ "psr-4": {
+ "Adbar\\": "src"
+ }
+ }
+}
diff --git a/Server/vendor/adbario/php-dot-notation/src/Dot.php b/Server/vendor/adbario/php-dot-notation/src/Dot.php
new file mode 100755
index 000000000..34cb4f657
--- /dev/null
+++ b/Server/vendor/adbario/php-dot-notation/src/Dot.php
@@ -0,0 +1,607 @@
+
+ * @link https://github.com/adbario/php-dot-notation
+ * @license https://github.com/adbario/php-dot-notation/blob/2.x/LICENSE.md (MIT License)
+ */
+namespace Adbar;
+
+use Countable;
+use ArrayAccess;
+use ArrayIterator;
+use JsonSerializable;
+use IteratorAggregate;
+
+/**
+ * Dot
+ *
+ * This class provides a dot notation access and helper functions for
+ * working with arrays of data. Inspired by Laravel Collection.
+ */
+class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
+{
+ /**
+ * The stored items
+ *
+ * @var array
+ */
+ protected $items = [];
+
+ /**
+ * Create a new Dot instance
+ *
+ * @param mixed $items
+ */
+ public function __construct($items = [])
+ {
+ $this->items = $this->getArrayItems($items);
+ }
+
+ /**
+ * Set a given key / value pair or pairs
+ * if the key doesn't exist already
+ *
+ * @param array|int|string $keys
+ * @param mixed $value
+ */
+ public function add($keys, $value = null)
+ {
+ if (is_array($keys)) {
+ foreach ($keys as $key => $value) {
+ $this->add($key, $value);
+ }
+ } elseif (is_null($this->get($keys))) {
+ $this->set($keys, $value);
+ }
+ }
+
+ /**
+ * Return all the stored items
+ *
+ * @return array
+ */
+ public function all()
+ {
+ return $this->items;
+ }
+
+ /**
+ * Delete the contents of a given key or keys
+ *
+ * @param array|int|string|null $keys
+ */
+ public function clear($keys = null)
+ {
+ if (is_null($keys)) {
+ $this->items = [];
+
+ return;
+ }
+
+ $keys = (array) $keys;
+
+ foreach ($keys as $key) {
+ $this->set($key, []);
+ }
+ }
+
+ /**
+ * Delete the given key or keys
+ *
+ * @param array|int|string $keys
+ */
+ public function delete($keys)
+ {
+ $keys = (array) $keys;
+
+ foreach ($keys as $key) {
+ if ($this->exists($this->items, $key)) {
+ unset($this->items[$key]);
+
+ continue;
+ }
+
+ $items = &$this->items;
+ $segments = explode('.', $key);
+ $lastSegment = array_pop($segments);
+
+ foreach ($segments as $segment) {
+ if (!isset($items[$segment]) || !is_array($items[$segment])) {
+ continue 2;
+ }
+
+ $items = &$items[$segment];
+ }
+
+ unset($items[$lastSegment]);
+ }
+ }
+
+ /**
+ * Checks if the given key exists in the provided array.
+ *
+ * @param array $array Array to validate
+ * @param int|string $key The key to look for
+ *
+ * @return bool
+ */
+ protected function exists($array, $key)
+ {
+ return array_key_exists($key, $array);
+ }
+
+ /**
+ * Flatten an array with the given character as a key delimiter
+ *
+ * @param string $delimiter
+ * @param array|null $items
+ * @param string $prepend
+ * @return array
+ */
+ public function flatten($delimiter = '.', $items = null, $prepend = '')
+ {
+ $flatten = [];
+
+ if (is_null($items)) {
+ $items = $this->items;
+ }
+
+ foreach ($items as $key => $value) {
+ if (is_array($value) && !empty($value)) {
+ $flatten = array_merge(
+ $flatten,
+ $this->flatten($delimiter, $value, $prepend.$key.$delimiter)
+ );
+ } else {
+ $flatten[$prepend.$key] = $value;
+ }
+ }
+
+ return $flatten;
+ }
+
+ /**
+ * Return the value of a given key
+ *
+ * @param int|string|null $key
+ * @param mixed $default
+ * @return mixed
+ */
+ public function get($key = null, $default = null)
+ {
+ if (is_null($key)) {
+ return $this->items;
+ }
+
+ if ($this->exists($this->items, $key)) {
+ return $this->items[$key];
+ }
+
+ if (strpos($key, '.') === false) {
+ return $default;
+ }
+
+ $items = $this->items;
+
+ foreach (explode('.', $key) as $segment) {
+ if (!is_array($items) || !$this->exists($items, $segment)) {
+ return $default;
+ }
+
+ $items = &$items[$segment];
+ }
+
+ return $items;
+ }
+
+ /**
+ * Return the given items as an array
+ *
+ * @param mixed $items
+ * @return array
+ */
+ protected function getArrayItems($items)
+ {
+ if (is_array($items)) {
+ return $items;
+ } elseif ($items instanceof self) {
+ return $items->all();
+ }
+
+ return (array) $items;
+ }
+
+ /**
+ * Check if a given key or keys exists
+ *
+ * @param array|int|string $keys
+ * @return bool
+ */
+ public function has($keys)
+ {
+ $keys = (array) $keys;
+
+ if (!$this->items || $keys === []) {
+ return false;
+ }
+
+ foreach ($keys as $key) {
+ $items = $this->items;
+
+ if ($this->exists($items, $key)) {
+ continue;
+ }
+
+ foreach (explode('.', $key) as $segment) {
+ if (!is_array($items) || !$this->exists($items, $segment)) {
+ return false;
+ }
+
+ $items = $items[$segment];
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Check if a given key or keys are empty
+ *
+ * @param array|int|string|null $keys
+ * @return bool
+ */
+ public function isEmpty($keys = null)
+ {
+ if (is_null($keys)) {
+ return empty($this->items);
+ }
+
+ $keys = (array) $keys;
+
+ foreach ($keys as $key) {
+ if (!empty($this->get($key))) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Merge a given array or a Dot object with the given key
+ * or with the whole Dot object
+ *
+ * @param array|string|self $key
+ * @param array|self $value
+ */
+ public function merge($key, $value = [])
+ {
+ if (is_array($key)) {
+ $this->items = array_merge($this->items, $key);
+ } elseif (is_string($key)) {
+ $items = (array) $this->get($key);
+ $value = array_merge($items, $this->getArrayItems($value));
+
+ $this->set($key, $value);
+ } elseif ($key instanceof self) {
+ $this->items = array_merge($this->items, $key->all());
+ }
+ }
+
+ /**
+ * Recursively merge a given array or a Dot object with the given key
+ * or with the whole Dot object.
+ *
+ * Duplicate keys are converted to arrays.
+ *
+ * @param array|string|self $key
+ * @param array|self $value
+ */
+ public function mergeRecursive($key, $value = [])
+ {
+ if (is_array($key)) {
+ $this->items = array_merge_recursive($this->items, $key);
+ } elseif (is_string($key)) {
+ $items = (array) $this->get($key);
+ $value = array_merge_recursive($items, $this->getArrayItems($value));
+
+ $this->set($key, $value);
+ } elseif ($key instanceof self) {
+ $this->items = array_merge_recursive($this->items, $key->all());
+ }
+ }
+
+ /**
+ * Recursively merge a given array or a Dot object with the given key
+ * or with the whole Dot object.
+ *
+ * Instead of converting duplicate keys to arrays, the value from
+ * given array will replace the value in Dot object.
+ *
+ * @param array|string|self $key
+ * @param array|self $value
+ */
+ public function mergeRecursiveDistinct($key, $value = [])
+ {
+ if (is_array($key)) {
+ $this->items = $this->arrayMergeRecursiveDistinct($this->items, $key);
+ } elseif (is_string($key)) {
+ $items = (array) $this->get($key);
+ $value = $this->arrayMergeRecursiveDistinct($items, $this->getArrayItems($value));
+
+ $this->set($key, $value);
+ } elseif ($key instanceof self) {
+ $this->items = $this->arrayMergeRecursiveDistinct($this->items, $key->all());
+ }
+ }
+
+ /**
+ * Merges two arrays recursively. In contrast to array_merge_recursive,
+ * duplicate keys are not converted to arrays but rather overwrite the
+ * value in the first array with the duplicate value in the second array.
+ *
+ * @param array $array1 Initial array to merge
+ * @param array $array2 Array to recursively merge
+ * @return array
+ */
+ protected function arrayMergeRecursiveDistinct(array $array1, array $array2)
+ {
+ $merged = &$array1;
+
+ foreach ($array2 as $key => $value) {
+ if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
+ $merged[$key] = $this->arrayMergeRecursiveDistinct($merged[$key], $value);
+ } else {
+ $merged[$key] = $value;
+ }
+ }
+
+ return $merged;
+ }
+
+ /**
+ * Return the value of a given key and
+ * delete the key
+ *
+ * @param int|string|null $key
+ * @param mixed $default
+ * @return mixed
+ */
+ public function pull($key = null, $default = null)
+ {
+ if (is_null($key)) {
+ $value = $this->all();
+ $this->clear();
+
+ return $value;
+ }
+
+ $value = $this->get($key, $default);
+ $this->delete($key);
+
+ return $value;
+ }
+
+ /**
+ * Push a given value to the end of the array
+ * in a given key
+ *
+ * @param mixed $key
+ * @param mixed $value
+ */
+ public function push($key, $value = null)
+ {
+ if (is_null($value)) {
+ $this->items[] = $key;
+
+ return;
+ }
+
+ $items = $this->get($key);
+
+ if (is_array($items) || is_null($items)) {
+ $items[] = $value;
+ $this->set($key, $items);
+ }
+ }
+
+ /**
+ * Replace all values or values within the given key
+ * with an array or Dot object
+ *
+ * @param array|string|self $key
+ * @param array|self $value
+ */
+ public function replace($key, $value = [])
+ {
+ if (is_array($key)) {
+ $this->items = array_replace($this->items, $key);
+ } elseif (is_string($key)) {
+ $items = (array) $this->get($key);
+ $value = array_replace($items, $this->getArrayItems($value));
+
+ $this->set($key, $value);
+ } elseif ($key instanceof self) {
+ $this->items = array_replace($this->items, $key->all());
+ }
+ }
+
+ /**
+ * Set a given key / value pair or pairs
+ *
+ * @param array|int|string $keys
+ * @param mixed $value
+ */
+ public function set($keys, $value = null)
+ {
+ if (is_array($keys)) {
+ foreach ($keys as $key => $value) {
+ $this->set($key, $value);
+ }
+
+ return;
+ }
+
+ $items = &$this->items;
+
+ foreach (explode('.', $keys) as $key) {
+ if (!isset($items[$key]) || !is_array($items[$key])) {
+ $items[$key] = [];
+ }
+
+ $items = &$items[$key];
+ }
+
+ $items = $value;
+ }
+
+ /**
+ * Replace all items with a given array
+ *
+ * @param mixed $items
+ */
+ public function setArray($items)
+ {
+ $this->items = $this->getArrayItems($items);
+ }
+
+ /**
+ * Replace all items with a given array as a reference
+ *
+ * @param array $items
+ */
+ public function setReference(array &$items)
+ {
+ $this->items = &$items;
+ }
+
+ /**
+ * Return the value of a given key or all the values as JSON
+ *
+ * @param mixed $key
+ * @param int $options
+ * @return string
+ */
+ public function toJson($key = null, $options = 0)
+ {
+ if (is_string($key)) {
+ return json_encode($this->get($key), $options);
+ }
+
+ $options = $key === null ? 0 : $key;
+
+ return json_encode($this->items, $options);
+ }
+
+ /*
+ * --------------------------------------------------------------
+ * ArrayAccess interface
+ * --------------------------------------------------------------
+ */
+
+ /**
+ * Check if a given key exists
+ *
+ * @param int|string $key
+ * @return bool
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetExists($key)
+ {
+ return $this->has($key);
+ }
+
+ /**
+ * Return the value of a given key
+ *
+ * @param int|string $key
+ * @return mixed
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetGet($key)
+ {
+ return $this->get($key);
+ }
+
+ /**
+ * Set a given value to the given key
+ *
+ * @param int|string|null $key
+ * @param mixed $value
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetSet($key, $value)
+ {
+ if (is_null($key)) {
+ $this->items[] = $value;
+
+ return;
+ }
+
+ $this->set($key, $value);
+ }
+
+ /**
+ * Delete the given key
+ *
+ * @param int|string $key
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetUnset($key)
+ {
+ $this->delete($key);
+ }
+
+ /*
+ * --------------------------------------------------------------
+ * Countable interface
+ * --------------------------------------------------------------
+ */
+
+ /**
+ * Return the number of items in a given key
+ *
+ * @param int|string|null $key
+ * @return int
+ */
+ #[\ReturnTypeWillChange]
+ public function count($key = null)
+ {
+ return count($this->get($key));
+ }
+
+ /*
+ * --------------------------------------------------------------
+ * IteratorAggregate interface
+ * --------------------------------------------------------------
+ */
+
+ /**
+ * Get an iterator for the stored items
+ *
+ * @return \ArrayIterator
+ */
+ #[\ReturnTypeWillChange]
+ public function getIterator()
+ {
+ return new ArrayIterator($this->items);
+ }
+
+ /*
+ * --------------------------------------------------------------
+ * JsonSerializable interface
+ * --------------------------------------------------------------
+ */
+
+ /**
+ * Return items for JSON serialization
+ *
+ * @return array
+ */
+ public function jsonSerialize()
+ {
+ return $this->items;
+ }
+}
diff --git a/Server/vendor/adbario/php-dot-notation/src/helpers.php b/Server/vendor/adbario/php-dot-notation/src/helpers.php
new file mode 100755
index 000000000..ffdc82687
--- /dev/null
+++ b/Server/vendor/adbario/php-dot-notation/src/helpers.php
@@ -0,0 +1,23 @@
+
+ * @link https://github.com/adbario/php-dot-notation
+ * @license https://github.com/adbario/php-dot-notation/blob/2.x/LICENSE.md (MIT License)
+ */
+
+use Adbar\Dot;
+
+if (! function_exists('dot')) {
+ /**
+ * Create a new Dot object with the given items
+ *
+ * @param mixed $items
+ * @return \Adbar\Dot
+ */
+ function dot($items)
+ {
+ return new Dot($items);
+ }
+}
diff --git a/Server/vendor/alibabacloud/credentials/CHANGELOG.md b/Server/vendor/alibabacloud/credentials/CHANGELOG.md
new file mode 100755
index 000000000..6180270e6
--- /dev/null
+++ b/Server/vendor/alibabacloud/credentials/CHANGELOG.md
@@ -0,0 +1,14 @@
+# CHANGELOG
+
+## 1.1.3 - 2020-12-24
+
+- Require guzzle ^6.3|^7.0
+
+## 1.0.2 - 2020-02-14
+- Update Tea.
+
+## 1.0.1 - 2019-12-30
+- Supported get `Role Name` automatically.
+
+## 1.0.0 - 2019-09-01
+- Initial release of the Alibaba Cloud Credentials for PHP Version 1.0.0 on Packagist See
";
+ break;
+ }
+ }
+ } else {
+ echo "open " . $filename . " failed.
";
+ }
+ fclose($fp);
+ }
+
+ /**
+ * Get MD5 of the file.
+ *
+ * @param $filename
+ * @param $from_pos
+ * @param $to_pos
+ * @return string
+ */
+ public static function getMd5SumForFile($filename, $from_pos, $to_pos)
+ {
+ $content_md5 = "";
+ if (($to_pos - $from_pos) > self::OSS_MAX_PART_SIZE) {
+ return $content_md5;
+ }
+ $filesize = sprintf('%u',filesize($filename));
+ if ($from_pos >= $filesize || $to_pos >= $filesize || $from_pos < 0 || $to_pos < 0) {
+ return $content_md5;
+ }
+
+ $total_length = $to_pos - $from_pos + 1;
+ $buffer = 8192;
+ $left_length = $total_length;
+ if (!file_exists($filename)) {
+ return $content_md5;
+ }
+
+ if (false === $fh = fopen($filename, 'rb')) {
+ return $content_md5;
+ }
+
+ fseek($fh, $from_pos);
+ $data = '';
+ while (!feof($fh)) {
+ if ($left_length >= $buffer) {
+ $read_length = $buffer;
+ } else {
+ $read_length = $left_length;
+ }
+ if ($read_length <= 0) {
+ break;
+ } else {
+ $data .= fread($fh, $read_length);
+ $left_length = $left_length - $read_length;
+ }
+ }
+ fclose($fh);
+ $content_md5 = base64_encode(md5($data, true));
+ return $content_md5;
+ }
+
+ /**
+ * Check if the OS is Windows. The default encoding in Windows is GBK.
+ *
+ * @return bool
+ */
+ public static function isWin()
+ {
+ return strtoupper(substr(PHP_OS, 0, 3)) == "WIN";
+ }
+
+ /**
+ * Encodes the file path from GBK to UTF-8.
+ * The default encoding in Windows is GBK.
+ * And if the file path is in Chinese, the file would not be found without the transcoding to UTF-8.
+ *
+ * @param $file_path
+ * @return string
+ */
+ public static function encodePath($file_path)
+ {
+ if (self::chkChinese($file_path) && self::isWin()) {
+ $file_path = iconv('utf-8', 'gbk', $file_path);
+ }
+ return $file_path;
+ }
+
+ /**
+ * Check if the endpoint is in the IPv4 format, such as xxx.xxx.xxx.xxx:port or xxx.xxx.xxx.xxx.
+ *
+ * @param string $endpoint The endpoint to check.
+ * @return boolean
+ */
+ public static function isIPFormat($endpoint)
+ {
+ $ip_array = explode(":", $endpoint);
+ $hostname = $ip_array[0];
+ $ret = filter_var($hostname, FILTER_VALIDATE_IP);
+ if (!$ret) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Get the host:port from endpoint.
+ *
+ * @param string $endpoint the endpoint.
+ * @return string
+ * @throws OssException
+ */
+ public static function getHostPortFromEndpoint($endpoint)
+ {
+ $str = $endpoint;
+ $pos = strpos($str, "://");
+ if ($pos !== false) {
+ $str = substr($str, $pos+3);
+ }
+
+ $pos = strpos($str, '#');
+ if ($pos !== false) {
+ $str = substr($str, 0, $pos);
+ }
+
+ $pos = strpos($str, '?');
+ if ($pos !== false) {
+ $str = substr($str, 0, $pos);
+ }
+
+ $pos = strpos($str, '/');
+ if ($pos !== false) {
+ $str = substr($str, 0, $pos);
+ }
+
+ $pos = strpos($str, '@');
+ if ($pos !== false) {
+ $str = substr($str, $pos+1);
+ }
+
+ if (!preg_match('/^[\w.-]+(:[0-9]+)?$/', $str)) {
+ throw new OssException("endpoint is invalid:" . $endpoint);
+ }
+
+ return $str;
+ }
+
+ /**
+ * Generate the xml message of DeleteMultiObjects.
+ *
+ * @param string[] $objects
+ * @param bool $quiet
+ * @return string
+ */
+ public static function createDeleteObjectsXmlBody($objects, $quiet)
+ {
+ $xml = new \SimpleXMLElement('
+ *
+ *
+ * @param string|array|function $callback (Required) The callback function is called by $curl_handle - resource - Required - The cURL handle resource that represents the in-progress transfer.$file_handle - resource - Required - The file handle resource that represents the file on the local file system.$length - integer - Required - The length in kilobytes of the data chunk that was transferred.
+ *
+ * @return $this A reference to the current instance.
+ */
+ public function register_streaming_read_callback($callback)
+ {
+ $this->registered_streaming_read_callback = $callback;
+
+ return $this;
+ }
+
+ /**
+ * Register a callback function to execute whenever a data stream is written to using
+ * array('ClassName', 'MethodName').
+ *
+ *
+ * @param string|array|function $callback (Required) The callback function is called by $curl_handle - resource - Required - The cURL handle resource that represents the in-progress transfer.$length - integer - Required - The length in kilobytes of the data chunk that was transferred.
+ *
+ * @return $this A reference to the current instance.
+ */
+ public function register_streaming_write_callback($callback)
+ {
+ $this->registered_streaming_write_callback = $callback;
+
+ return $this;
+ }
+
+
+ /*%******************************************************************************************%*/
+ // PREPARE, SEND, AND PROCESS REQUEST
+
+ /**
+ * A callback function that is invoked by cURL for streaming up.
+ *
+ * @param resource $curl_handle (Required) The cURL handle for the request.
+ * @param resource $file_handle (Required) The open file handle resource.
+ * @param integer $length (Required) The maximum number of bytes to read.
+ * @return binary Binary data from a stream.
+ */
+ public function streaming_read_callback($curl_handle, $file_handle, $length)
+ {
+ // Once we've sent as much as we're supposed to send...
+ if ($this->read_stream_read >= $this->read_stream_size) {
+ // Send EOF
+ return '';
+ }
+
+ // If we're at the beginning of an upload and need to seek...
+ if ($this->read_stream_read == 0 && isset($this->seek_position) && $this->seek_position !== ftell($this->read_stream)) {
+ if (fseek($this->read_stream, $this->seek_position) !== 0) {
+ throw new RequestCore_Exception('The stream does not support seeking and is either not at the requested position or the position is unknown.');
+ }
+ }
+
+ $read = fread($this->read_stream, min($this->read_stream_size - $this->read_stream_read, $length)); // Remaining upload data or cURL's requested chunk size
+ $this->read_stream_read += strlen($read);
+
+ $out = $read === false ? '' : $read;
+
+ // Execute callback function
+ if ($this->registered_streaming_read_callback) {
+ call_user_func($this->registered_streaming_read_callback, $curl_handle, $file_handle, $out);
+ }
+
+ return $out;
+ }
+
+ /**
+ * A callback function that is invoked by cURL for streaming down.
+ *
+ * @param resource $curl_handle (Required) The cURL handle for the request.
+ * @param binary $data (Required) The data to write.
+ * @return integer The number of bytes written.
+ */
+ public function streaming_write_callback($curl_handle, $data)
+ {
+ $code = curl_getinfo($curl_handle, CURLINFO_HTTP_CODE);
+
+ if (intval($code) / 100 != 2)
+ {
+ $this->response_error_body .= $data;
+ return strlen($data);
+ }
+
+ $length = strlen($data);
+ $written_total = 0;
+ $written_last = 0;
+
+ while ($written_total < $length) {
+ $written_last = fwrite($this->write_stream, substr($data, $written_total));
+
+ if ($written_last === false) {
+ return $written_total;
+ }
+
+ $written_total += $written_last;
+ }
+
+ // Execute callback function
+ if ($this->registered_streaming_write_callback) {
+ call_user_func($this->registered_streaming_write_callback, $curl_handle, $written_total);
+ }
+
+ return $written_total;
+ }
+
+ /**
+ * Prepare and adds the details of the cURL request. This can be passed along to a array('ClassName', 'MethodName').');
+ if ($start === false) {
+ return '';
+ }
+ $start += 6;
+ $end = strpos($body, '', $start);
+ if ($end === false) {
+ return '';
+ }
+ return substr($body, $start, $end - $start);
+ }
+
+ return '';
+ }
+
+ /**
+ * Judging from the return http status code, [200-299] that is OK
+ *
+ * @return bool
+ */
+ protected function isResponseOk()
+ {
+ $status = $this->rawResponse->status;
+ if ((int)(intval($status) / 100) == 2) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Return the original return data
+ *
+ * @return ResponseCore
+ */
+ public function getRawResponse()
+ {
+ return $this->rawResponse;
+ }
+
+ /**
+ * Indicate whether the request is successful
+ */
+ protected $isOk = false;
+ /**
+ * Data parsed by subclasses
+ */
+ protected $parsedData = null;
+ /**
+ * Store the original Response returned by the auth function
+ *
+ * @var ResponseCore
+ */
+ protected $rawResponse;
+}
\ No newline at end of file
diff --git a/Server/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/SymlinkResult.php b/Server/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/SymlinkResult.php
new file mode 100644
index 000000000..9c6d861a6
--- /dev/null
+++ b/Server/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/SymlinkResult.php
@@ -0,0 +1,24 @@
+rawResponse->header[OssClient::OSS_SYMLINK_TARGET] = rawurldecode($this->rawResponse->header[OssClient::OSS_SYMLINK_TARGET]);
+ return $this->rawResponse->header;
+ }
+}
+
diff --git a/Server/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/UploadPartResult.php b/Server/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/UploadPartResult.php
new file mode 100644
index 000000000..c6b66d454
--- /dev/null
+++ b/Server/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/UploadPartResult.php
@@ -0,0 +1,28 @@
+rawResponse->header;
+ if (isset($header["etag"])) {
+ return $header["etag"];
+ }
+ throw new OssException("cannot get ETag");
+
+ }
+}
\ No newline at end of file
diff --git a/Server/vendor/aliyuncs/oss-sdk-php/src/OSS/Signer/SignerInterface.php b/Server/vendor/aliyuncs/oss-sdk-php/src/OSS/Signer/SignerInterface.php
new file mode 100644
index 000000000..c592a4f8e
--- /dev/null
+++ b/Server/vendor/aliyuncs/oss-sdk-php/src/OSS/Signer/SignerInterface.php
@@ -0,0 +1,12 @@
+request_headers['Date'])) {
+ $request->add_header('Date', gmdate('D, d M Y H:i:s \G\M\T'));
+ }
+ // Credentials information
+ if (!empty($credentials->getSecurityToken())) {
+ $request->add_header("x-oss-security-token", $credentials->getSecurityToken());
+ }
+ $headers = $request->request_headers;
+ $method = strtoupper($request->method);
+ $date = $headers['Date'];
+ $resourcePath = $this->getResourcePath($options);
+ $queryString = parse_url($request->request_url, PHP_URL_QUERY);
+ $query = array();
+ if ($queryString !== null) {
+ parse_str($queryString, $query);
+ }
+ $stringToSign = $this->calcStringToSign($method, $date, $headers, $resourcePath, $query);
+// printf("sign str:%s" . PHP_EOL, $stringToSign);
+ $options['string_to_sign'] = $stringToSign;
+ $signature = base64_encode(hash_hmac('sha1', $stringToSign, $credentials->getAccessKeySecret(), true));
+ $request->add_header('Authorization', 'OSS ' . $credentials->getAccessKeyId() . ':' . $signature);
+ }
+
+ public function presign(RequestCore $request, Credentials $credentials, array &$options)
+ {
+ $headers = $request->request_headers;
+ // Date
+ $expiration = $options['expiration'];
+ if (!isset($request->request_headers['Date'])) {
+ $request->add_header('Date', gmdate('D, d M Y H:i:s \G\M\T'));
+ }
+ $parsed_url = parse_url($request->request_url);
+ $queryString = isset($parsed_url['query']) ? $parsed_url['query'] : '';
+ $query = array();
+ if ($queryString !== null) {
+ parse_str($queryString, $query);
+ }
+ // Credentials information
+ if (!empty($credentials->getSecurityToken())) {
+ $query["security-token"] = $credentials->getSecurityToken();
+ }
+ $method = strtoupper($request->method);
+ $date = $expiration . "";
+ $resourcePath = $this->getResourcePath($options);
+ $stringToSign = $this->calcStringToSign($method, $date, $headers, $resourcePath, $query);
+ $options['string_to_sign'] = $stringToSign;
+ $signature = base64_encode(hash_hmac('sha1', $stringToSign, $credentials->getAccessKeySecret(), true));
+ $query['OSSAccessKeyId'] = $credentials->getAccessKeyId();
+ $query['Expires'] = $date;
+ $query['Signature'] = $signature;
+ $queryString = OssUtil::toQueryString($query);
+ $parsed_url['query'] = $queryString;
+ $request->request_url = OssUtil::unparseUrl($parsed_url);
+ }
+
+ private function getResourcePath(array $options)
+ {
+ $resourcePath = '/';
+ if (strlen($options['bucket']) > 0) {
+ $resourcePath .= $options['bucket'] . '/';
+ }
+ if (strlen($options['key']) > 0) {
+ $resourcePath .= $options['key'];
+ }
+ return $resourcePath;
+ }
+
+ private function calcStringToSign($method, $date, array $headers, $resourcePath, array $query)
+ {
+ /*
+ SignToString =
+ VERB + "\n"
+ + Content-MD5 + "\n"
+ + Content-Type + "\n"
+ + Date + "\n"
+ + CanonicalizedOSSHeaders
+ + CanonicalizedResource
+ Signature = base64(hmac-sha1(AccessKeySecret, SignToString))
+ */
+ $contentMd5 = '';
+ $contentType = '';
+ // CanonicalizedOSSHeaders
+ $signheaders = array();
+ foreach ($headers as $key => $value) {
+ $lowk = strtolower($key);
+ if (strncmp($lowk, "x-oss-", 6) == 0) {
+ $signheaders[$lowk] = $value;
+ } else if ($lowk === 'content-md5') {
+ $contentMd5 = $value;
+ } else if ($lowk === 'content-type') {
+ $contentType = $value;
+ }
+ }
+ ksort($signheaders);
+ $canonicalizedOSSHeaders = '';
+ foreach ($signheaders as $key => $value) {
+ $canonicalizedOSSHeaders .= $key . ':' . $value . "\n";
+ }
+ // CanonicalizedResource
+ $signquery = array();
+ foreach ($query as $key => $value) {
+ if (in_array($key, $this->signKeyList)) {
+ $signquery[$key] = $value;
+ }
+ }
+ ksort($signquery);
+ $sortedQueryList = array();
+ foreach ($signquery as $key => $value) {
+ if (strlen($value) > 0) {
+ $sortedQueryList[] = $key . '=' . $value;
+ } else {
+ $sortedQueryList[] = $key;
+ }
+ }
+ $queryStringSorted = implode('&', $sortedQueryList);
+ $canonicalizedResource = $resourcePath;
+ if (!empty($queryStringSorted)) {
+ $canonicalizedResource .= '?' . $queryStringSorted;
+ }
+ return $method . "\n" . $contentMd5 . "\n" . $contentType . "\n" . $date . "\n" . $canonicalizedOSSHeaders . $canonicalizedResource;
+ }
+
+ private $signKeyList = array(
+ "acl", "uploads", "location", "cors",
+ "logging", "website", "referer", "lifecycle",
+ "delete", "append", "tagging", "objectMeta",
+ "uploadId", "partNumber", "security-token", "x-oss-security-token",
+ "position", "img", "style", "styleName",
+ "replication", "replicationProgress",
+ "replicationLocation", "cname", "bucketInfo",
+ "comp", "qos", "live", "status", "vod",
+ "startTime", "endTime", "symlink",
+ "x-oss-process", "response-content-type", "x-oss-traffic-limit",
+ "response-content-language", "response-expires",
+ "response-cache-control", "response-content-disposition",
+ "response-content-encoding", "udf", "udfName", "udfImage",
+ "udfId", "udfImageDesc", "udfApplication",
+ "udfApplicationLog", "restore", "callback", "callback-var", "qosInfo",
+ "policy", "stat", "encryption", "versions", "versioning", "versionId", "requestPayment",
+ "x-oss-request-payer", "sequential",
+ "inventory", "inventoryId", "continuation-token", "asyncFetch",
+ "worm", "wormId", "wormExtend", "withHashContext",
+ "x-oss-enable-md5", "x-oss-enable-sha1", "x-oss-enable-sha256",
+ "x-oss-hash-ctx", "x-oss-md5-ctx", "transferAcceleration",
+ "regionList", "cloudboxes", "x-oss-ac-source-ip", "x-oss-ac-subnet-mask", "x-oss-ac-vpc-id", "x-oss-ac-forward-allow",
+ "metaQuery", "resourceGroup", "rtc", "x-oss-async-process", "responseHeader"
+ );
+}
\ No newline at end of file
diff --git a/Server/vendor/aliyuncs/oss-sdk-php/src/OSS/Signer/SignerV4.php b/Server/vendor/aliyuncs/oss-sdk-php/src/OSS/Signer/SignerV4.php
new file mode 100644
index 000000000..039b04aab
--- /dev/null
+++ b/Server/vendor/aliyuncs/oss-sdk-php/src/OSS/Signer/SignerV4.php
@@ -0,0 +1,244 @@
+request_headers['Date'])) {
+ $request->add_header('Date', gmdate('D, d M Y H:i:s \G\M\T'));
+ }
+ $timestamp = strtotime($request->request_headers['Date']);
+ if ($timestamp === false) {
+ $timestamp = time();
+ }
+ $datetime = gmdate('Ymd\THis\Z', $timestamp);
+ $date = substr($datetime, 0, 8);
+ $request->add_header("x-oss-date", $datetime);
+ if (!isset($request->request_headers['x-oss-content-sha256'])) {
+ $request->add_header("x-oss-content-sha256", 'UNSIGNED-PAYLOAD');
+ }
+ // Credentials information
+ if (!empty($credentials->getSecurityToken())) {
+ $request->add_header("x-oss-security-token", $credentials->getSecurityToken());
+ }
+ $headers = $request->request_headers;
+ $method = strtoupper($request->method);
+ $region = $options['region'];
+ $product = $options['product'];
+ $scope = $this->buildScope($date, $region, $product);
+ $resourcePath = $this->getResourcePath($options);
+ $additionalHeaders = $this->getCommonAdditionalHeaders($request, $options);
+ $queryString = parse_url($request->request_url, PHP_URL_QUERY);
+ $query = array();
+ if ($queryString !== null) {
+ parse_str($queryString, $query);
+ }
+ $canonicalRequest = $this->calcCanonicalRequest($method, $resourcePath, $query, $headers, $additionalHeaders);
+ $stringToSign = $this->calcStringToSign($datetime, $scope, $canonicalRequest);
+// printf('canonical request:%s' . PHP_EOL, $canonicalRequest);
+// printf('sign str:%s' . PHP_EOL, $stringToSign);
+ $options['string_to_sign'] = $stringToSign;
+ $signature = $this->calcSignature($credentials->getAccessKeySecret(), $date, $region, $product, $stringToSign);
+ $authorization = 'OSS4-HMAC-SHA256 Credential=' . $credentials->getAccessKeyId() . '/' . $scope;
+ $additionalHeadersString = implode(';', $additionalHeaders);
+ if ($additionalHeadersString !== '') {
+ $authorization .= ',AdditionalHeaders=' . $additionalHeadersString;
+ }
+ $authorization .= ',Signature=' . $signature;
+ $request->add_header('Authorization', $authorization);
+ }
+
+ public function presign(RequestCore $request, Credentials $credentials, array &$options)
+ {
+ if (!isset($request->request_headers['Date'])) {
+ $request->add_header('Date', gmdate('D, d M Y H:i:s \G\M\T'));
+ }
+ $timestamp = strtotime($request->request_headers['Date']);
+ if ($timestamp === false) {
+ $timestamp = time();
+ }
+ $datetime = gmdate('Ymd\THis\Z', $timestamp);
+ $expiration = $options['expiration'];
+ $date = substr($datetime, 0, 8);
+ $expires = $expiration - $timestamp;
+ $headers = $request->request_headers;
+ $method = strtoupper($request->method);
+ $region = $options['region'];
+ $product = $options['product'];
+ $scope = $this->buildScope($date, $region, $product);
+ $resourcePath = $this->getResourcePath($options);
+ $additionalHeaders = $this->getCommonAdditionalHeaders($request, $options);
+ $queryString = parse_url($request->request_url, PHP_URL_QUERY);
+ $query = array();
+ if ($queryString !== null) {
+ parse_str($queryString, $query);
+ }
+ if (!empty($credentials->getSecurityToken())) {
+ $query["x-oss-security-token"] = $credentials->getSecurityToken();
+ }
+ $query["x-oss-signature-version"] = 'OSS4-HMAC-SHA256';
+ $query["x-oss-date"] = $datetime;
+ $query["x-oss-expires"] = $expires;
+ $query["x-oss-credential"] = $credentials->getAccessKeyId() . '/' . $scope;
+ if (count($additionalHeaders) > 0) {
+ $query["x-oss-additional-headers"] = implode(";", $additionalHeaders);
+ }
+ $canonicalRequest = $this->calcCanonicalRequest($method, $resourcePath, $query, $headers, $additionalHeaders);
+ $stringToSign = $this->calcStringToSign($datetime, $scope, $canonicalRequest);
+// printf('canonical request:%s' . PHP_EOL, $canonicalRequest);
+// printf('sign str:%s' . PHP_EOL, $stringToSign);
+ $options['string_to_sign'] = $stringToSign;
+ $signature = $this->calcSignature($credentials->getAccessKeySecret(), $date, $region, $product, $stringToSign);
+ $query["x-oss-signature"] = $signature;
+ $queryStr = OssUtil::toQueryString($query);
+ $explodeUrl = explode('?', $request->request_url);
+ $index = count($explodeUrl);
+ if ($index === 1) {
+ $request->request_url .= '?' . $queryStr;
+ } else {
+ $baseUrl = $explodeUrl[0];
+ $request->request_url = $baseUrl . '?' . $queryStr;
+ }
+ }
+
+ private function getResourcePath(array $options)
+ {
+ $resourcePath = '/';
+ if (strlen($options['bucket']) > 0) {
+ $resourcePath .= $options['bucket'] . '/';
+ }
+ if (strlen($options['key']) > 0) {
+ $resourcePath .= $options['key'];
+ }
+ return $resourcePath;
+ }
+
+ private function getCommonAdditionalHeaders(RequestCore $request, array $options)
+ {
+ if (isset($options[OssClient::OSS_ADDITIONAL_HEADERS])) {
+ $addHeaders = array();
+ foreach ($options[OssClient::OSS_ADDITIONAL_HEADERS] as $key) {
+ $lowk = strtolower($key);
+ if ($this->isDefaultSignedHeader($lowk)) {
+ continue;
+ }
+ $addHeaders[$lowk] = '';
+ }
+ $headers = array();
+ foreach ($request->request_headers as $key => $value) {
+ $lowk = strtolower($key);
+ if (isset($addHeaders[$lowk])) {
+ $headers[$lowk] = '';
+ }
+ }
+ ksort($headers);
+ return array_keys($headers);
+ }
+ return array();
+ }
+
+ private function isDefaultSignedHeader($low)
+ {
+ if (strncmp($low, "x-oss-", 6) == 0 ||
+ $low === "content-type" ||
+ $low === "content-md5") {
+ return true;
+ }
+ return false;
+ }
+
+ private function calcStringToSign($datetime, $scope, $canonicalRequest)
+ {
+ /*
+ StringToSign
+ "OSS4-HMAC-SHA256" + "\n" +
+ TimeStamp + "\n" +
+ Scope + "\n" +
+ Hex(SHA256Hash(Canonical Request))
+ */
+ $hashedRequest = hash('sha256', $canonicalRequest);
+ return "OSS4-HMAC-SHA256" . "\n" . $datetime . "\n" . $scope . "\n" . $hashedRequest;
+ }
+
+ private function calcCanonicalRequest($method, $resourcePath, array $query, array $headers, array $additionalHeaders)
+ {
+ /*
+ Canonical Request
+ HTTP Verb + "\n" +
+ Canonical URI + "\n" +
+ Canonical Query String + "\n" +
+ Canonical Headers + "\n" +
+ Additional Headers + "\n" +
+ Hashed PayLoad
+ */
+
+ //Canonical Uri
+ $canonicalUri = str_replace(array('%2F'), array('/'), rawurlencode($resourcePath));
+ //Canonical Query
+ $querySigned = array();
+ foreach ($query as $key => $value) {
+ $querySigned[rawurlencode($key)] = rawurlencode($value);
+ }
+ ksort($querySigned);
+ $sortedQueryList = array();
+ foreach ($querySigned as $key => $value) {
+ if (strlen($value) > 0) {
+ $sortedQueryList[] = $key . '=' . $value;
+ } else {
+ $sortedQueryList[] = $key;
+ }
+ }
+ $canonicalQuery = implode('&', $sortedQueryList);
+ //Canonical Headers
+ $headersSigned = array();
+ foreach ($headers as $key => $value) {
+ $lowk = strtolower($key);
+ if (SignerV4::isDefaultSignedHeader($lowk) ||
+ in_array($lowk, $additionalHeaders)) {
+ $headersSigned[$lowk] = trim($value);
+ }
+ }
+ ksort($headersSigned);
+ $canonicalizedHeaders = '';
+ foreach ($headersSigned as $key => $value) {
+ $canonicalizedHeaders .= $key . ':' . $value . "\n";
+ }
+ //Additional Headers
+ $canonicalAdditionalHeaders = implode(';', $additionalHeaders);
+ $hashPayload = "UNSIGNED-PAYLOAD";
+ if (isset($headersSigned['x-oss-content-sha256'])) {
+ $hashPayload = $headersSigned['x-oss-content-sha256'];
+ }
+
+ $stringToSign = $method . "\n"
+ . $canonicalUri . "\n"
+ . $canonicalQuery . "\n"
+ . $canonicalizedHeaders . "\n"
+ . $canonicalAdditionalHeaders . "\n"
+ . $hashPayload;
+ return $stringToSign;
+ }
+
+ private function buildScope($date, $region, $product)
+ {
+ return $date . "/" . $region . "/" . $product . "/aliyun_v4_request";
+ }
+
+ private function calcSignature($secret, $date, $region, $product, $stringToSign)
+ {
+ $h1Key = hash_hmac("sha256", $date, "aliyun_v4" . $secret, true);
+ $h2Key = hash_hmac("sha256", $region, $h1Key, true);
+ $h3Key = hash_hmac("sha256", $product, $h2Key, true);
+ $h4Key = hash_hmac("sha256", "aliyun_v4_request", $h3Key, true);
+ return bin2hex(hash_hmac("sha256", $stringToSign, $h4Key, true));
+ }
+}
diff --git a/Server/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/AclResultTest.php b/Server/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/AclResultTest.php
new file mode 100644
index 000000000..82168d05d
--- /dev/null
+++ b/Server/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/AclResultTest.php
@@ -0,0 +1,59 @@
+
+NoSuchBucket
+ ' . $textCode . '
';
+
+ return $result;
+ }
+}
diff --git a/Server/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Text/Plain.php b/Server/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Text/Plain.php
new file mode 100755
index 000000000..a7e4cfb74
--- /dev/null
+++ b/Server/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Text/Plain.php
@@ -0,0 +1,150 @@
+fullBlock = $fullBlock;
+ }
+
+ /**
+ * Get char used as full block (occupied space, "black").
+ *
+ * @return string
+ */
+ public function getFullBlock()
+ {
+ return $this->fullBlock;
+ }
+
+ /**
+ * Set char used as empty block (empty space, "white").
+ *
+ * @param string $emptyBlock
+ */
+ public function setEmptyBlock($emptyBlock)
+ {
+ $this->emptyBlock = $emptyBlock;
+ }
+
+ /**
+ * Get char used as empty block (empty space, "white").
+ *
+ * @return string
+ */
+ public function getEmptyBlock()
+ {
+ return $this->emptyBlock;
+ }
+
+ /**
+ * Sets the margin around the QR code.
+ *
+ * @param integer $margin
+ * @return AbstractRenderer
+ * @throws Exception\InvalidArgumentException
+ */
+ public function setMargin($margin)
+ {
+ if ($margin < 0) {
+ throw new Exception\InvalidArgumentException('Margin must be equal to greater than 0');
+ }
+
+ $this->margin = (int) $margin;
+
+ return $this;
+ }
+
+ /**
+ * Gets the margin around the QR code.
+ *
+ * @return integer
+ */
+ public function getMargin()
+ {
+ return $this->margin;
+ }
+
+ /**
+ * render(): defined by RendererInterface.
+ *
+ * @see RendererInterface::render()
+ * @param QrCode $qrCode
+ * @return string
+ */
+ public function render(QrCode $qrCode)
+ {
+ $result = '';
+ $matrix = $qrCode->getMatrix();
+ $width = $matrix->getWidth();
+
+ // Top margin
+ for ($x = 0; $x < $this->margin; $x++) {
+ $result .= str_repeat($this->emptyBlock, $width + 2 * $this->margin)."\n";
+ }
+
+ // Body
+ $array = $matrix->getArray();
+
+ foreach ($array as $row) {
+ $result .= str_repeat($this->emptyBlock, $this->margin); // left margin
+ foreach ($row as $byte) {
+ $result .= $byte ? $this->fullBlock : $this->emptyBlock;
+ }
+ $result .= str_repeat($this->emptyBlock, $this->margin); // right margin
+ $result .= "\n";
+ }
+
+ // Bottom margin
+ for ($x = 0; $x < $this->margin; $x++) {
+ $result .= str_repeat($this->emptyBlock, $width + 2 * $this->margin)."\n";
+ }
+
+ return $result;
+ }
+}
diff --git a/Server/vendor/bacon/bacon-qr-code/src/BaconQrCode/Writer.php b/Server/vendor/bacon/bacon-qr-code/src/BaconQrCode/Writer.php
new file mode 100755
index 000000000..0f8031384
--- /dev/null
+++ b/Server/vendor/bacon/bacon-qr-code/src/BaconQrCode/Writer.php
@@ -0,0 +1,105 @@
+renderer = $renderer;
+ }
+
+ /**
+ * Sets the renderer used to create a byte stream.
+ *
+ * @param RendererInterface $renderer
+ * @return Writer
+ */
+ public function setRenderer(RendererInterface $renderer)
+ {
+ $this->renderer = $renderer;
+ return $this;
+ }
+
+ /**
+ * Gets the renderer used to create a byte stream.
+ *
+ * @return RendererInterface
+ */
+ public function getRenderer()
+ {
+ return $this->renderer;
+ }
+
+ /**
+ * Writes QR code and returns it as string.
+ *
+ * Content is a string which *should* be encoded in UTF-8, in case there are
+ * non ASCII-characters present.
+ *
+ * @param string $content
+ * @param string $encoding
+ * @param integer $ecLevel
+ * @return string
+ * @throws Exception\InvalidArgumentException
+ */
+ public function writeString(
+ $content,
+ $encoding = Encoder::DEFAULT_BYTE_MODE_ECODING,
+ $ecLevel = ErrorCorrectionLevel::L
+ ) {
+ if (strlen($content) === 0) {
+ throw new Exception\InvalidArgumentException('Found empty contents');
+ }
+
+ $qrCode = Encoder::encode($content, new ErrorCorrectionLevel($ecLevel), $encoding);
+
+ return $this->getRenderer()->render($qrCode);
+ }
+
+ /**
+ * Writes QR code to a file.
+ *
+ * @see Writer::writeString()
+ * @param string $content
+ * @param string $filename
+ * @param string $encoding
+ * @param integer $ecLevel
+ * @return void
+ */
+ public function writeFile(
+ $content,
+ $filename,
+ $encoding = Encoder::DEFAULT_BYTE_MODE_ECODING,
+ $ecLevel = ErrorCorrectionLevel::L
+ ) {
+ file_put_contents($filename, $this->writeString($content, $encoding, $ecLevel));
+ }
+}
diff --git a/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/BitArrayTest.php b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/BitArrayTest.php
new file mode 100755
index 000000000..81bcbce6d
--- /dev/null
+++ b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/BitArrayTest.php
@@ -0,0 +1,201 @@
+assertFalse($array->get($i));
+ $array->set($i);
+ $this->assertTrue($array->get($i));
+ }
+ }
+
+ public function testGetNextSet1()
+ {
+ $array = new BitArray(32);
+
+ for ($i = 0; $i < $array->getSize(); $i++) {
+ $this->assertEquals($i, 32, '', $array->getNextSet($i));
+ }
+
+ $array = new BitArray(33);
+
+ for ($i = 0; $i < $array->getSize(); $i++) {
+ $this->assertEquals($i, 33, '', $array->getNextSet($i));
+ }
+ }
+
+ public function testGetNextSet2()
+ {
+ $array = new BitArray(33);
+
+ for ($i = 0; $i < $array->getSize(); $i++) {
+ $this->assertEquals($i, $i <= 31 ? 31 : 33, '', $array->getNextSet($i));
+ }
+
+ $array = new BitArray(33);
+
+ for ($i = 0; $i < $array->getSize(); $i++) {
+ $this->assertEquals($i, 32, '', $array->getNextSet($i));
+ }
+ }
+
+ public function testGetNextSet3()
+ {
+ $array = new BitArray(63);
+ $array->set(31);
+ $array->set(32);
+
+ for ($i = 0; $i < $array->getSize(); $i++) {
+ if ($i <= 31) {
+ $expected = 31;
+ } elseif ($i <= 32) {
+ $expected = 32;
+ } else {
+ $expected = 63;
+ }
+
+ $this->assertEquals($i, $expected, '', $array->getNextSet($i));
+ }
+ }
+
+ public function testGetNextSet4()
+ {
+ $array = new BitArray(63);
+ $array->set(33);
+ $array->set(40);
+
+ for ($i = 0; $i < $array->getSize(); $i++) {
+ if ($i <= 33) {
+ $expected = 33;
+ } elseif ($i <= 40) {
+ $expected = 40;
+ } else {
+ $expected = 63;
+ }
+
+ $this->assertEquals($i, $expected, '', $array->getNextSet($i));
+ }
+ }
+
+ public function testGetNextSet5()
+ {
+ if (defined('MT_RAND_PHP')) {
+ mt_srand(0xdeadbeef, MT_RAND_PHP);
+ } else {
+ mt_srand(0xdeadbeef);
+ }
+
+ for ($i = 0; $i < 10; $i++) {
+ $array = new BitArray(mt_rand(1, 100));
+ $numSet = mt_rand(0, 19);
+
+ for ($j = 0; $j < $numSet; $j++) {
+ $array->set(mt_rand(0, $array->getSize() - 1));
+ }
+
+ $numQueries = mt_rand(0, 19);
+
+ for ($j = 0; $j < $numQueries; $j++) {
+ $query = mt_rand(0, $array->getSize() - 1);
+ $expected = $query;
+
+ while ($expected < $array->getSize() && !$array->get($expected)) {
+ $expected++;
+ }
+
+ $actual = $array->getNextSet($query);
+
+ if ($actual !== $expected) {
+ $array->getNextSet($query);
+ }
+
+ $this->assertEquals($expected, $actual);
+ }
+ }
+ }
+
+ public function testSetBulk()
+ {
+ $array = new BitArray(64);
+ $array->setBulk(32, 0xFFFF0000);
+
+ for ($i = 0; $i < 48; $i++) {
+ $this->assertFalse($array->get($i));
+ }
+
+ for ($i = 48; $i < 64; $i++) {
+ $this->assertTrue($array->get($i));
+ }
+ }
+
+ public function testClear()
+ {
+ $array = new BitArray(32);
+
+ for ($i = 0; $i < 32; $i++) {
+ $array->set($i);
+ }
+
+ $array->clear();
+
+ for ($i = 0; $i < 32; $i++) {
+ $this->assertFalse($array->get($i));
+ }
+ }
+
+ public function testGetArray()
+ {
+ $array = new BitArray(64);
+ $array->set(0);
+ $array->set(63);
+
+ $ints = $array->getBitArray();
+
+ $this->assertEquals(1, $ints[0]);
+ $this->assertEquals(0x80000000, $ints[1]);
+ }
+
+ public function testIsRange()
+ {
+ $array = new BitArray(64);
+ $this->assertTrue($array->isRange(0, 64, false));
+ $this->assertFalse($array->isRange(0, 64, true));
+
+ $array->set(32);
+ $this->assertTrue($array->isRange(32, 33, true));
+
+ $array->set(31);
+ $this->assertTrue($array->isRange(31, 33, true));
+
+ $array->set(34);
+ $this->assertFalse($array->isRange(31, 35, true));
+
+ for ($i = 0; $i < 31; $i++) {
+ $array->set($i);
+ }
+
+ $this->assertTrue($array->isRange(0, 33, true));
+
+ for ($i = 33; $i < 64; $i++) {
+ $array->set($i);
+ }
+
+ $this->assertTrue($array->isRange(0, 64, true));
+ $this->assertFalse($array->isRange(0, 64, false));
+ }
+}
\ No newline at end of file
diff --git a/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/BitMatrixTest.php b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/BitMatrixTest.php
new file mode 100755
index 000000000..89a58812f
--- /dev/null
+++ b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/BitMatrixTest.php
@@ -0,0 +1,119 @@
+assertEquals(33, $matrix->getHeight());
+
+ for ($y = 0; $y < 33; $y++) {
+ for ($x = 0; $x < 33; $x++) {
+ if ($y * $x % 3 === 0) {
+ $matrix->set($x, $y);
+ }
+ }
+ }
+
+ for ($y = 0; $y < 33; $y++) {
+ for ($x = 0; $x < 33; $x++) {
+ $this->assertEquals($x * $y % 3 === 0, $matrix->get($x, $y));
+ }
+ }
+ }
+
+ public function testSetRegion()
+ {
+ $matrix = new BitMatrix(5);
+ $matrix->setRegion(1, 1, 3, 3);
+
+ for ($y = 0; $y < 5; $y++) {
+ for ($x = 0; $x < 5; $x++) {
+ $this->assertEquals($y >= 1 && $y <= 3 && $x >= 1 && $x <= 3, $matrix->get($x, $y));
+ }
+ }
+ }
+
+ public function testRectangularMatrix()
+ {
+ $matrix = new BitMatrix(75, 20);
+ $this->assertEquals(75, $matrix->getWidth());
+ $this->assertEquals(20, $matrix->getHeight());
+
+ $matrix->set(10, 0);
+ $matrix->set(11, 1);
+ $matrix->set(50, 2);
+ $matrix->set(51, 3);
+ $matrix->flip(74, 4);
+ $matrix->flip(0, 5);
+
+ $this->assertTrue($matrix->get(10, 0));
+ $this->assertTrue($matrix->get(11, 1));
+ $this->assertTrue($matrix->get(50, 2));
+ $this->assertTrue($matrix->get(51, 3));
+ $this->assertTrue($matrix->get(74, 4));
+ $this->assertTrue($matrix->get(0, 5));
+
+ $matrix->flip(50, 2);
+ $matrix->flip(51, 3);
+
+ $this->assertFalse($matrix->get(50, 2));
+ $this->assertFalse($matrix->get(51, 3));
+ }
+
+ public function testRectangularSetRegion()
+ {
+ $matrix = new BitMatrix(320, 240);
+ $this->assertEquals(320, $matrix->getWidth());
+ $this->assertEquals(240, $matrix->getHeight());
+
+ $matrix->setRegion(105, 22, 80, 12);
+
+ for ($y = 0; $y < 240; $y++) {
+ for ($x = 0; $x < 320; $x++) {
+ $this->assertEquals($y >= 22 && $y < 34 && $x >= 105 && $x < 185, $matrix->get($x, $y));
+ }
+ }
+ }
+
+ public function testGetRow()
+ {
+ $matrix = new BitMatrix(102, 5);
+
+ for ($x = 0; $x < 102; $x++) {
+ if ($x & 3 === 0) {
+ $matrix->set($x, 2);
+ }
+ }
+
+ $array1 = $matrix->getRow(2, null);
+ $this->assertEquals(102, $array1->getSize());
+
+ $array2 = new BitArray(60);
+ $array2 = $matrix->getRow(2, $array2);
+ $this->assertEquals(102, $array2->getSize());
+
+ $array3 = new BitArray(200);
+ $array3 = $matrix->getRow(2, $array3);
+ $this->assertEquals(200, $array3->getSize());
+
+ for ($x = 0; $x < 102; $x++) {
+ $on = ($x & 3 === 0);
+
+ $this->assertEquals($on, $array1->get($x));
+ $this->assertEquals($on, $array2->get($x));
+ $this->assertEquals($on, $array3->get($x));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/BitUtilsTest.php b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/BitUtilsTest.php
new file mode 100755
index 000000000..b80ff7df5
--- /dev/null
+++ b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/BitUtilsTest.php
@@ -0,0 +1,30 @@
+assertEquals(1, BitUtils::unsignedRightShift(1, 0));
+ $this->assertEquals(1, BitUtils::unsignedRightShift(10, 3));
+ $this->assertEquals(536870910, BitUtils::unsignedRightShift(-10, 3));
+ }
+
+ public function testNumberOfTrailingZeros()
+ {
+ $this->assertEquals(32, BitUtils::numberOfTrailingZeros(0));
+ $this->assertEquals(1, BitUtils::numberOfTrailingZeros(10));
+ $this->assertEquals(0, BitUtils::numberOfTrailingZeros(15));
+ $this->assertEquals(2, BitUtils::numberOfTrailingZeros(20));
+ }
+}
\ No newline at end of file
diff --git a/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/ErrorCorrectionLevelTest.php b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/ErrorCorrectionLevelTest.php
new file mode 100755
index 000000000..736e995db
--- /dev/null
+++ b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/ErrorCorrectionLevelTest.php
@@ -0,0 +1,40 @@
+assertEquals(0x0, ErrorCorrectionLevel::M);
+ $this->assertEquals(0x1, ErrorCorrectionLevel::L);
+ $this->assertEquals(0x2, ErrorCorrectionLevel::H);
+ $this->assertEquals(0x3, ErrorCorrectionLevel::Q);
+ }
+
+ public function testInvalidErrorCorrectionLevelThrowsException()
+ {
+ $this->setExpectedException(
+ 'BaconQrCode\Exception\UnexpectedValueException',
+ 'Value not a const in enum BaconQrCode\Common\ErrorCorrectionLevel'
+ );
+ new ErrorCorrectionLevel(4);
+ }
+}
\ No newline at end of file
diff --git a/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/FormatInformationTest.php b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/FormatInformationTest.php
new file mode 100755
index 000000000..5f6ee58c0
--- /dev/null
+++ b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/FormatInformationTest.php
@@ -0,0 +1,104 @@
+unmaskedTestFormatInfo = $this->maskedTestFormatInfo ^ 0x5412;
+ }
+
+
+ public function testBitsDiffering()
+ {
+ $this->assertEquals(0, FormatInformation::numBitsDiffering(1, 1));
+ $this->assertEquals(1, FormatInformation::numBitsDiffering(0, 2));
+ $this->assertEquals(2, FormatInformation::numBitsDiffering(1, 2));
+ $this->assertEquals(32, FormatInformation::numBitsDiffering(-1, 0));
+ }
+
+ public function testDecode()
+ {
+ $expected = FormatInformation::decodeFormatInformation(
+ $this->maskedTestFormatInfo,
+ $this->maskedTestFormatInfo
+ );
+
+ $this->assertNotNull($expected);
+ $this->assertEquals(7, $expected->getDataMask());
+ $this->assertEquals(ErrorCorrectionLevel::Q, $expected->getErrorCorrectionLevel()->get());
+
+ $this->assertEquals(
+ $expected,
+ FormatInformation::decodeFormatInformation(
+ $this->unmaskedTestFormatInfo,
+ $this->maskedTestFormatInfo
+ )
+ );
+ }
+
+ public function testDecodeWithBitDifference()
+ {
+ $expected = FormatInformation::decodeFormatInformation(
+ $this->maskedTestFormatInfo,
+ $this->maskedTestFormatInfo
+ );
+
+ $this->assertEquals(
+ $expected,
+ FormatInformation::decodeFormatInformation(
+ $this->maskedTestFormatInfo ^ 0x1,
+ $this->maskedTestFormatInfo ^ 0x1
+ )
+ );
+ $this->assertEquals(
+ $expected,
+ FormatInformation::decodeFormatInformation(
+ $this->maskedTestFormatInfo ^ 0x3,
+ $this->maskedTestFormatInfo ^ 0x3
+ )
+ );
+ $this->assertEquals(
+ $expected,
+ FormatInformation::decodeFormatInformation(
+ $this->maskedTestFormatInfo ^ 0x7,
+ $this->maskedTestFormatInfo ^ 0x7
+ )
+ );
+ $this->assertNull(
+ FormatInformation::decodeFormatInformation(
+ $this->maskedTestFormatInfo ^ 0xf,
+ $this->maskedTestFormatInfo ^ 0xf
+ )
+ );
+ }
+
+ public function testDecodeWithMisRead()
+ {
+ $expected = FormatInformation::decodeFormatInformation(
+ $this->maskedTestFormatInfo,
+ $this->maskedTestFormatInfo
+ );
+
+ $this->assertEquals(
+ $expected,
+ FormatInformation::decodeFormatInformation(
+ $this->maskedTestFormatInfo ^ 0x3,
+ $this->maskedTestFormatInfo ^ 0xf
+ )
+ );
+ }
+}
\ No newline at end of file
diff --git a/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/ModeTest.php b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/ModeTest.php
new file mode 100755
index 000000000..4daab7c31
--- /dev/null
+++ b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/ModeTest.php
@@ -0,0 +1,42 @@
+assertEquals(0x0, Mode::TERMINATOR);
+ $this->assertEquals(0x1, Mode::NUMERIC);
+ $this->assertEquals(0x2, Mode::ALPHANUMERIC);
+ $this->assertEquals(0x4, Mode::BYTE);
+ $this->assertEquals(0x8, Mode::KANJI);
+ }
+
+ public function testInvalidModeThrowsException()
+ {
+ $this->setExpectedException(
+ 'BaconQrCode\Exception\UnexpectedValueException',
+ 'Value not a const in enum BaconQrCode\Common\Mode'
+ );
+ new Mode(10);
+ }
+}
\ No newline at end of file
diff --git a/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/ReedSolomonCodecTest.php b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/ReedSolomonCodecTest.php
new file mode 100755
index 000000000..604641a05
--- /dev/null
+++ b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/ReedSolomonCodecTest.php
@@ -0,0 +1,111 @@
+encode($block, $parity);
+
+ // Copy parity into test blocks
+ for ($i = 0; $i < $numRoots; $i++) {
+ $block[$i + $dataSize] = $parity[$i];
+ $tBlock[$i + $dataSize] = $parity[$i];
+ }
+
+ // Seed with errors
+ for ($i = 0; $i < $errors; $i++) {
+ $errorValue = mt_rand(1, $blockSize);
+
+ do {
+ $errorLocation = mt_rand(0, $blockSize);
+ } while ($errorLocations[$errorLocation] !== 0);
+
+ $errorLocations[$errorLocation] = 1;
+
+ if (mt_rand(0, 1)) {
+ $erasures[] = $errorLocation;
+ }
+
+ $tBlock[$errorLocation] ^= $errorValue;
+ }
+
+ $erasures = SplFixedArray::fromArray($erasures, false);
+
+ // Decode the errored block
+ $foundErrors = $codec->decode($tBlock, $erasures);
+
+ if ($errors > 0 && $foundErrors === null) {
+ $this->assertEquals($block, $tBlock, 'Decoder failed to correct errors');
+ }
+
+ $this->assertEquals($errors, $foundErrors, 'Found errors do not equal expected errors');
+
+ for ($i = 0; $i < $foundErrors; $i++) {
+ if ($errorLocations[$erasures[$i]] === 0) {
+ $this->fail(sprintf('Decoder indicates error in location %d without error', $erasures[$i]));
+ }
+ }
+
+ $this->assertEquals($block, $tBlock, 'Decoder did not correct errors');
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/VersionTest.php b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/VersionTest.php
new file mode 100755
index 000000000..8b3fc01f9
--- /dev/null
+++ b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Common/VersionTest.php
@@ -0,0 +1,88 @@
+assertNotNull($version);
+ $this->assertEquals($versionNumber, $version->getVersionNumber());
+ $this->assertNotNull($version->getAlignmentPatternCenters());
+
+ if ($versionNumber > 1) {
+ $this->assertTrue(count($version->getAlignmentPatternCenters()) > 0);
+ }
+
+ $this->assertEquals($dimension, $version->getDimensionForVersion());
+ $this->assertNotNull($version->getEcBlocksForLevel(new ErrorCorrectionLevel(ErrorCorrectionLevel::H)));
+ $this->assertNotNull($version->getEcBlocksForLevel(new ErrorCorrectionLevel(ErrorCorrectionLevel::L)));
+ $this->assertNotNull($version->getEcBlocksForLevel(new ErrorCorrectionLevel(ErrorCorrectionLevel::M)));
+ $this->assertNotNull($version->getEcBlocksForLevel(new ErrorCorrectionLevel(ErrorCorrectionLevel::Q)));
+ $this->assertNotNull($version->buildFunctionPattern());
+ }
+
+ /**
+ * @dataProvider versionProvider
+ * @param integer $versionNumber
+ * @param integer $dimension
+ */
+ public function testGetProvisionalVersionForDimension($versionNumber, $dimension)
+ {
+ $this->assertEquals(
+ $versionNumber,
+ Version::getProvisionalVersionForDimension($dimension)->getVersionNumber()
+ );
+ }
+
+ /**
+ * @dataProvider decodeInformationProvider
+ * @param integer $expectedVersion
+ * @param integer $mask
+ */
+ public function testDecodeVersionInformation($expectedVersion, $mask)
+ {
+ $version = Version::decodeVersionInformation($mask);
+ $this->assertNotNull($version);
+ $this->assertEquals($expectedVersion, $version->getVersionNumber());
+ }
+}
\ No newline at end of file
diff --git a/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Encoder/EncoderTest.php b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Encoder/EncoderTest.php
new file mode 100755
index 000000000..31cdaa4e7
--- /dev/null
+++ b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Encoder/EncoderTest.php
@@ -0,0 +1,468 @@
+getMethods(ReflectionMethod::IS_STATIC) as $method) {
+ $method->setAccessible(true);
+ $this->methods[$method->getName()] = $method;
+ }
+ }
+
+ public function testGetAlphanumericCode()
+ {
+ // The first ten code points are numbers.
+ for ($i = 0; $i < 10; $i++) {
+ $this->assertEquals($i, $this->methods['getAlphanumericCode']->invoke(null, ord('0') + $i));
+ }
+
+ // The next 26 code points are capital alphabet letters.
+ for ($i = 10; $i < 36; $i++) {
+ // The first ten code points are numbers
+ $this->assertEquals($i, $this->methods['getAlphanumericCode']->invoke(null, ord('A') + $i - 10));
+ }
+
+ // Others are symbol letters.
+ $this->assertEquals(36, $this->methods['getAlphanumericCode']->invoke(null, ' '));
+ $this->assertEquals(37, $this->methods['getAlphanumericCode']->invoke(null, '$'));
+ $this->assertEquals(38, $this->methods['getAlphanumericCode']->invoke(null, '%'));
+ $this->assertEquals(39, $this->methods['getAlphanumericCode']->invoke(null, '*'));
+ $this->assertEquals(40, $this->methods['getAlphanumericCode']->invoke(null, '+'));
+ $this->assertEquals(41, $this->methods['getAlphanumericCode']->invoke(null, '-'));
+ $this->assertEquals(42, $this->methods['getAlphanumericCode']->invoke(null, '.'));
+ $this->assertEquals(43, $this->methods['getAlphanumericCode']->invoke(null, '/'));
+ $this->assertEquals(44, $this->methods['getAlphanumericCode']->invoke(null, ':'));
+
+ // Should return -1 for other letters.
+ $this->assertEquals(-1, $this->methods['getAlphanumericCode']->invoke(null, 'a'));
+ $this->assertEquals(-1, $this->methods['getAlphanumericCode']->invoke(null, '#'));
+ $this->assertEquals(-1, $this->methods['getAlphanumericCode']->invoke(null, "\0"));
+ }
+
+ public function testChooseMode()
+ {
+ // Numeric mode
+ $this->assertSame(Mode::NUMERIC, $this->methods['chooseMode']->invoke(null, '0')->get());
+ $this->assertSame(Mode::NUMERIC, $this->methods['chooseMode']->invoke(null, '0123456789')->get());
+
+ // Alphanumeric mode
+ $this->assertSame(Mode::ALPHANUMERIC, $this->methods['chooseMode']->invoke(null, 'A')->get());
+ $this->assertSame(Mode::ALPHANUMERIC, $this->methods['chooseMode']->invoke(null, '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:')->get());
+
+ // 8-bit byte mode
+ $this->assertSame(Mode::BYTE, $this->methods['chooseMode']->invoke(null, 'a')->get());
+ $this->assertSame(Mode::BYTE, $this->methods['chooseMode']->invoke(null, '#')->get());
+ $this->assertSame(Mode::BYTE, $this->methods['chooseMode']->invoke(null, '')->get());
+
+ // AIUE in Hiragana in SHIFT-JIS
+ $this->assertSame(Mode::BYTE, $this->methods['chooseMode']->invoke(null, "\x8\xa\x8\xa\x8\xa\x8\xa6")->get());
+
+ // Nihon in Kanji in SHIFT-JIS
+ $this->assertSame(Mode::BYTE, $this->methods['chooseMode']->invoke(null, "\x9\xf\x9\x7b")->get());
+
+ // Sou-Utso-Byou in Kanji in SHIFT-JIS
+ $this->assertSame(Mode::BYTE, $this->methods['chooseMode']->invoke(null, "\xe\x4\x9\x5\x9\x61")->get());
+ }
+
+ public function testEncode()
+ {
+ $qrCode = Encoder::encode('ABCDEF', new ErrorCorrectionLevel(ErrorCorrectionLevel::H));
+ $expected = "<<\n"
+ . " mode: ALPHANUMERIC\n"
+ . " ecLevel: H\n"
+ . " version: 1\n"
+ . " maskPattern: 0\n"
+ . " matrix:\n"
+ . " 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 1 1 1 1\n"
+ . " 1 0 0 0 0 0 1 0 0 1 1 1 0 0 1 0 0 0 0 0 1\n"
+ . " 1 0 1 1 1 0 1 0 0 1 0 1 1 0 1 0 1 1 1 0 1\n"
+ . " 1 0 1 1 1 0 1 0 1 1 1 0 1 0 1 0 1 1 1 0 1\n"
+ . " 1 0 1 1 1 0 1 0 0 1 1 1 0 0 1 0 1 1 1 0 1\n"
+ . " 1 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 1\n"
+ . " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n"
+ . " 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0\n"
+ . " 0 0 1 0 1 1 1 0 1 1 0 0 1 1 0 0 0 1 0 0 1\n"
+ . " 1 0 1 1 1 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0\n"
+ . " 0 0 1 1 0 0 1 0 1 0 0 0 1 0 1 0 1 0 1 1 0\n"
+ . " 1 1 0 1 0 1 0 1 1 1 0 1 0 1 0 0 0 0 0 1 0\n"
+ . " 0 0 1 1 0 1 1 1 1 0 0 0 1 0 1 0 1 1 1 1 0\n"
+ . " 0 0 0 0 0 0 0 0 1 0 0 1 1 1 0 1 0 1 0 0 0\n"
+ . " 1 1 1 1 1 1 1 0 0 0 1 0 1 0 1 1 0 0 0 0 1\n"
+ . " 1 0 0 0 0 0 1 0 1 1 1 1 0 1 0 1 1 1 1 0 1\n"
+ . " 1 0 1 1 1 0 1 0 1 0 1 1 0 1 0 1 0 0 0 0 1\n"
+ . " 1 0 1 1 1 0 1 0 0 1 1 0 1 1 1 1 0 1 0 1 0\n"
+ . " 1 0 1 1 1 0 1 0 1 0 0 0 1 0 1 0 1 1 1 0 1\n"
+ . " 1 0 0 0 0 0 1 0 0 1 1 0 1 1 0 1 0 0 0 1 1\n"
+ . " 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 1\n"
+ . ">>\n";
+
+ $this->assertEquals($expected, $qrCode->__toString());
+ }
+
+ public function testSimpleUtf8Eci()
+ {
+ $qrCode = Encoder::encode('hello', new ErrorCorrectionLevel(ErrorCorrectionLevel::H), 'utf-8');
+ $expected = "<<\n"
+ . " mode: BYTE\n"
+ . " ecLevel: H\n"
+ . " version: 1\n"
+ . " maskPattern: 3\n"
+ . " matrix:\n"
+ . " 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1\n"
+ . " 1 0 0 0 0 0 1 0 0 0 1 0 1 0 1 0 0 0 0 0 1\n"
+ . " 1 0 1 1 1 0 1 0 0 1 0 1 0 0 1 0 1 1 1 0 1\n"
+ . " 1 0 1 1 1 0 1 0 0 1 1 0 1 0 1 0 1 1 1 0 1\n"
+ . " 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 0 1\n"
+ . " 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1\n"
+ . " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n"
+ . " 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0\n"
+ . " 0 0 1 1 0 0 1 1 1 1 0 0 0 1 1 0 1 0 0 0 0\n"
+ . " 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 1 0 1 1 1 0\n"
+ . " 0 1 0 1 0 1 1 1 0 1 0 1 0 0 0 0 0 1 1 1 1\n"
+ . " 1 1 0 0 1 0 0 1 1 0 0 1 1 1 1 0 1 0 1 1 0\n"
+ . " 0 0 0 0 1 0 1 1 1 1 0 0 0 0 0 1 0 0 1 0 0\n"
+ . " 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 1 1 0 0 0 1\n"
+ . " 1 1 1 1 1 1 1 0 1 1 1 0 1 0 1 1 0 0 1 0 0\n"
+ . " 1 0 0 0 0 0 1 0 0 0 1 0 0 1 1 1 1 1 1 0 1\n"
+ . " 1 0 1 1 1 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0\n"
+ . " 1 0 1 1 1 0 1 0 1 1 1 0 1 0 0 0 1 1 0 0 0\n"
+ . " 1 0 1 1 1 0 1 0 1 1 0 0 0 1 0 0 1 0 0 0 0\n"
+ . " 1 0 0 0 0 0 1 0 0 0 0 1 1 0 1 0 1 0 1 1 0\n"
+ . " 1 1 1 1 1 1 1 0 0 1 0 1 1 1 0 1 1 0 0 0 0\n"
+ . ">>\n";
+
+ $this->assertEquals($expected, $qrCode->__toString());
+ }
+
+ public function testAppendModeInfo()
+ {
+ $bits = new BitArray();
+ $this->methods['appendModeInfo']->invoke(null, new Mode(Mode::NUMERIC), $bits);
+ $this->assertEquals(' ...X', $bits->__toString());
+ }
+
+ public function testAppendLengthInfo()
+ {
+ // 1 letter (1/1), 10 bits.
+ $bits = new BitArray();
+ $this->methods['appendLengthInfo']->invoke(
+ null,
+ 1,
+ Version::getVersionForNumber(1),
+ new Mode(Mode::NUMERIC),
+ $bits
+ );
+ $this->assertEquals(' ........ .X', $bits->__toString());
+
+ // 2 letters (2/1), 11 bits.
+ $bits = new BitArray();
+ $this->methods['appendLengthInfo']->invoke(
+ null,
+ 2,
+ Version::getVersionForNumber(10),
+ new Mode(Mode::ALPHANUMERIC),
+ $bits
+ );
+ $this->assertEquals(' ........ .X.', $bits->__toString());
+
+ // 255 letters (255/1), 16 bits.
+ $bits = new BitArray();
+ $this->methods['appendLengthInfo']->invoke(
+ null,
+ 255,
+ Version::getVersionForNumber(27),
+ new Mode(Mode::BYTE),
+ $bits
+ );
+ $this->assertEquals(' ........ XXXXXXXX', $bits->__toString());
+
+ // 512 letters (1024/2), 12 bits.
+ $bits = new BitArray();
+ $this->methods['appendLengthInfo']->invoke(
+ null,
+ 512,
+ Version::getVersionForNumber(40),
+ new Mode(Mode::KANJI),
+ $bits
+ );
+ $this->assertEquals(' ..X..... ....', $bits->__toString());
+ }
+
+ public function testAppendBytes()
+ {
+ // Should use appendNumericBytes.
+ // 1 = 01 = 0001 in 4 bits.
+ $bits = new BitArray();
+ $this->methods['appendBytes']->invoke(
+ null,
+ '1',
+ new Mode(Mode::NUMERIC),
+ $bits,
+ Encoder::DEFAULT_BYTE_MODE_ECODING
+ );
+ $this->assertEquals(' ...X', $bits->__toString());
+
+ // Should use appendAlphaNumericBytes.
+ // A = 10 = 0xa = 001010 in 6 bits.
+ $bits = new BitArray();
+ $this->methods['appendBytes']->invoke(
+ null,
+ 'A',
+ new Mode(Mode::ALPHANUMERIC),
+ $bits,
+ Encoder::DEFAULT_BYTE_MODE_ECODING
+ );
+ $this->assertEquals(' ..X.X.', $bits->__toString());
+
+ // Should use append8BitBytes.
+ // 0x61, 0x62, 0x63
+ $bits = new BitArray();
+ $this->methods['appendBytes']->invoke(
+ null,
+ 'abc',
+ new Mode(Mode::BYTE),
+ $bits,
+ Encoder::DEFAULT_BYTE_MODE_ECODING
+ );
+ $this->assertEquals(' .XX....X .XX...X. .XX...XX', $bits->__toString());
+
+ // Should use appendKanjiBytes.
+ // 0x93, 0x5f
+ $bits = new BitArray();
+ $this->methods['appendBytes']->invoke(
+ null,
+ "\x93\x5f",
+ new Mode(Mode::KANJI),
+ $bits,
+ Encoder::DEFAULT_BYTE_MODE_ECODING
+ );
+ $this->assertEquals(' .XX.XX.. XXXXX', $bits->__toString());
+
+ // Lower letters such as 'a' cannot be encoded in alphanumeric mode.
+ $this->setExpectedException(
+ 'BaconQrCode\Exception\WriterException',
+ 'Invalid alphanumeric code'
+ );
+ $this->methods['appendBytes']->invoke(
+ null,
+ "a",
+ new Mode(Mode::ALPHANUMERIC),
+ $bits,
+ Encoder::DEFAULT_BYTE_MODE_ECODING
+ );
+ }
+
+ public function testTerminateBits()
+ {
+ $bits = new BitArray();
+ $this->methods['terminateBits']->invoke(null, 0, $bits);
+ $this->assertEquals('', $bits->__toString());
+
+ $bits = new BitArray();
+ $this->methods['terminateBits']->invoke(null, 1, $bits);
+ $this->assertEquals(' ........', $bits->__toString());
+
+ $bits = new BitArray();
+ $bits->appendBits(0, 3);
+ $this->methods['terminateBits']->invoke(null, 1, $bits);
+ $this->assertEquals(' ........', $bits->__toString());
+
+ $bits = new BitArray();
+ $bits->appendBits(0, 5);
+ $this->methods['terminateBits']->invoke(null, 1, $bits);
+ $this->assertEquals(' ........', $bits->__toString());
+
+ $bits = new BitArray();
+ $bits->appendBits(0, 8);
+ $this->methods['terminateBits']->invoke(null, 1, $bits);
+ $this->assertEquals(' ........', $bits->__toString());
+
+ $bits = new BitArray();
+ $this->methods['terminateBits']->invoke(null, 2, $bits);
+ $this->assertEquals(' ........ XXX.XX..', $bits->__toString());
+
+ $bits = new BitArray();
+ $bits->appendBits(0, 1);
+ $this->methods['terminateBits']->invoke(null, 3, $bits);
+ $this->assertEquals(' ........ XXX.XX.. ...X...X', $bits->__toString());
+ }
+
+ public function testGetNumDataBytesAndNumEcBytesForBlockId()
+ {
+ // Version 1-H.
+ list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId']->invoke(null, 26, 9, 1, 0);
+ $this->assertEquals(9, $numDataBytes);
+ $this->assertEquals(17, $numEcBytes);
+
+ // Version 3-H. 2 blocks.
+ list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId']->invoke(null, 70, 26, 2, 0);
+ $this->assertEquals(13, $numDataBytes);
+ $this->assertEquals(22, $numEcBytes);
+ list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId']->invoke(null, 70, 26, 2, 1);
+ $this->assertEquals(13, $numDataBytes);
+ $this->assertEquals(22, $numEcBytes);
+
+ // Version 7-H. (4 + 1) blocks.
+ list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId']->invoke(null, 196, 66, 5, 0);
+ $this->assertEquals(13, $numDataBytes);
+ $this->assertEquals(26, $numEcBytes);
+ list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId']->invoke(null, 196, 66, 5, 4);
+ $this->assertEquals(14, $numDataBytes);
+ $this->assertEquals(26, $numEcBytes);
+
+ // Version 40-H. (20 + 61) blocks.
+ list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId']->invoke(null, 3706, 1276, 81, 0);
+ $this->assertEquals(15, $numDataBytes);
+ $this->assertEquals(30, $numEcBytes);
+ list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId']->invoke(null, 3706, 1276, 81, 20);
+ $this->assertEquals(16, $numDataBytes);
+ $this->assertEquals(30, $numEcBytes);
+ list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId']->invoke(null, 3706, 1276, 81, 80);
+ $this->assertEquals(16, $numDataBytes);
+ $this->assertEquals(30, $numEcBytes);
+ }
+
+ public function testInterleaveWithEcBytes()
+ {
+ $dataBytes = SplFixedArray::fromArray(array(32, 65, 205, 69, 41, 220, 46, 128, 236), false);
+ $in = new BitArray();
+
+ foreach ($dataBytes as $dataByte) {
+ $in->appendBits($dataByte, 8);
+ }
+
+ $outBits = $this->methods['interleaveWithEcBytes']->invoke(null, $in, 26, 9, 1);
+ $expected = SplFixedArray::fromArray(array(
+ // Data bytes.
+ 32, 65, 205, 69, 41, 220, 46, 128, 236,
+ // Error correction bytes.
+ 42, 159, 74, 221, 244, 169, 239, 150, 138, 70, 237, 85, 224, 96, 74, 219, 61,
+ ), false);
+
+ $out = $outBits->toBytes(0, count($expected));
+
+ $this->assertEquals($expected, $out);
+ }
+
+ public function testAppendNumericBytes()
+ {
+ // 1 = 01 = 0001 in 4 bits.
+ $bits = new BitArray();
+ $this->methods['appendNumericBytes']->invoke(null, '1', $bits);
+ $this->assertEquals(' ...X', $bits->__toString());
+
+ // 12 = 0xc = 0001100 in 7 bits.
+ $bits = new BitArray();
+ $this->methods['appendNumericBytes']->invoke(null, '12', $bits);
+ $this->assertEquals(' ...XX..', $bits->__toString());
+
+ // 123 = 0x7b = 0001111011 in 10 bits.
+ $bits = new BitArray();
+ $this->methods['appendNumericBytes']->invoke(null, '123', $bits);
+ $this->assertEquals(' ...XXXX. XX', $bits->__toString());
+
+ // 1234 = "123" + "4" = 0001111011 + 0100 in 14 bits.
+ $bits = new BitArray();
+ $this->methods['appendNumericBytes']->invoke(null, '1234', $bits);
+ $this->assertEquals(' ...XXXX. XX.X..', $bits->__toString());
+
+ // Empty
+ $bits = new BitArray();
+ $this->methods['appendNumericBytes']->invoke(null, '', $bits);
+ $this->assertEquals('', $bits->__toString());
+ }
+
+ public function testAppendAlphanumericBytes()
+ {
+ $bits = new BitArray();
+ $this->methods['appendAlphanumericBytes']->invoke(null, 'A', $bits);
+ $this->assertEquals(' ..X.X.', $bits->__toString());
+
+ $bits = new BitArray();
+ $this->methods['appendAlphanumericBytes']->invoke(null, 'AB', $bits);
+ $this->assertEquals(' ..XXX..X X.X', $bits->__toString());
+
+ $bits = new BitArray();
+ $this->methods['appendAlphanumericBytes']->invoke(null, 'ABC', $bits);
+ $this->assertEquals(' ..XXX..X X.X..XX. .', $bits->__toString());
+
+ // Empty
+ $bits = new BitArray();
+ $this->methods['appendAlphanumericBytes']->invoke(null, '', $bits);
+ $this->assertEquals('', $bits->__toString());
+
+ // Invalid data
+ $this->setExpectedException('BaconQrCode\Exception\WriterException', 'Invalid alphanumeric code');
+ $bits = new BitArray();
+ $this->methods['appendAlphanumericBytes']->invoke(null, 'abc', $bits);
+ }
+
+ public function testAppend8BitBytes()
+ {
+ // 0x61, 0x62, 0x63
+ $bits = new BitArray();
+ $this->methods['append8BitBytes']->invoke(null, 'abc', $bits, Encoder::DEFAULT_BYTE_MODE_ECODING);
+ $this->assertEquals(' .XX....X .XX...X. .XX...XX', $bits->__toString());
+
+ // Empty
+ $bits = new BitArray();
+ $this->methods['append8BitBytes']->invoke(null, '', $bits, Encoder::DEFAULT_BYTE_MODE_ECODING);
+ $this->assertEquals('', $bits->__toString());
+ }
+
+ public function testAppendKanjiBytes()
+ {
+ // Numbers are from page 21 of JISX0510:2004
+ $bits = new BitArray();
+ $this->methods['appendKanjiBytes']->invoke(null, "\x93\x5f", $bits);
+ $this->assertEquals(' .XX.XX.. XXXXX', $bits->__toString());
+
+ $this->methods['appendKanjiBytes']->invoke(null, "\xe4\xaa", $bits);
+ $this->assertEquals(' .XX.XX.. XXXXXXX. X.X.X.X. X.', $bits->__toString());
+ }
+
+ public function testGenerateEcBytes()
+ {
+ // Numbers are from http://www.swetake.com/qr/qr3.html and
+ // http://www.swetake.com/qr/qr9.html
+ $dataBytes = SplFixedArray::fromArray(array(32, 65, 205, 69, 41, 220, 46, 128, 236), false);
+ $ecBytes = $this->methods['generateEcBytes']->invoke(null, $dataBytes, 17);
+ $expected = SplFixedArray::fromArray(array(42, 159, 74, 221, 244, 169, 239, 150, 138, 70, 237, 85, 224, 96, 74, 219, 61), false);
+ $this->assertEquals($expected, $ecBytes);
+
+ $dataBytes = SplFixedArray::fromArray(array(67, 70, 22, 38, 54, 70, 86, 102, 118, 134, 150, 166, 182, 198, 214), false);
+ $ecBytes = $this->methods['generateEcBytes']->invoke(null, $dataBytes, 18);
+ $expected = SplFixedArray::fromArray(array(175, 80, 155, 64, 178, 45, 214, 233, 65, 209, 12, 155, 117, 31, 140, 214, 27, 187), false);
+ $this->assertEquals($expected, $ecBytes);
+
+ // High-order zero coefficient case.
+ $dataBytes = SplFixedArray::fromArray(array(32, 49, 205, 69, 42, 20, 0, 236, 17), false);
+ $ecBytes = $this->methods['generateEcBytes']->invoke(null, $dataBytes, 17);
+ $expected = SplFixedArray::fromArray(array(0, 3, 130, 179, 194, 0, 55, 211, 110, 79, 98, 72, 170, 96, 211, 137, 213), false);
+ $this->assertEquals($expected, $ecBytes);
+ }
+}
\ No newline at end of file
diff --git a/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Encoder/MaskUtilTest.php b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Encoder/MaskUtilTest.php
new file mode 100755
index 000000000..a5c386562
--- /dev/null
+++ b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Encoder/MaskUtilTest.php
@@ -0,0 +1,281 @@
+fail('Data mask bit did not match');
+ }
+ }
+ }
+ }
+
+ public function testApplyMaskPenaltyRule1()
+ {
+ $matrix = new ByteMatrix(4, 1);
+ $matrix->set(0, 0, 0);
+ $matrix->set(1, 0, 0);
+ $matrix->set(2, 0, 0);
+ $matrix->set(3, 0, 0);
+
+ $this->assertEquals(0, MaskUtil::applyMaskPenaltyRule1($matrix));
+
+ // Horizontal
+ $matrix = new ByteMatrix(6, 1);
+ $matrix->set(0, 0, 0);
+ $matrix->set(1, 0, 0);
+ $matrix->set(2, 0, 0);
+ $matrix->set(3, 0, 0);
+ $matrix->set(4, 0, 0);
+ $matrix->set(5, 0, 1);
+ $this->assertEquals(3, MaskUtil::applyMaskPenaltyRule1($matrix));
+ $matrix->set(5, 0, 0);
+ $this->assertEquals(4, MaskUtil::applyMaskPenaltyRule1($matrix));
+
+ // Vertical
+ $matrix = new ByteMatrix(1, 6);
+ $matrix->set(0, 0, 0);
+ $matrix->set(0, 1, 0);
+ $matrix->set(0, 2, 0);
+ $matrix->set(0, 3, 0);
+ $matrix->set(0, 4, 0);
+ $matrix->set(0, 5, 1);
+ $this->assertEquals(3, MaskUtil::applyMaskPenaltyRule1($matrix));
+ $matrix->set(0, 5, 0);
+ $this->assertEquals(4, MaskUtil::applyMaskPenaltyRule1($matrix));
+ }
+
+ public function testApplyMaskPenaltyRule2()
+ {
+ $matrix = new ByteMatrix(1, 1);
+ $matrix->set(0, 0, 0);
+ $this->assertEquals(0, MaskUtil::applyMaskPenaltyRule2($matrix));
+
+ $matrix = new ByteMatrix(2, 2);
+ $matrix->set(0, 0, 0);
+ $matrix->set(1, 0, 0);
+ $matrix->set(0, 1, 0);
+ $matrix->set(1, 1, 1);
+ $this->assertEquals(0, MaskUtil::applyMaskPenaltyRule2($matrix));
+
+ $matrix = new ByteMatrix(2, 2);
+ $matrix->set(0, 0, 0);
+ $matrix->set(1, 0, 0);
+ $matrix->set(0, 1, 0);
+ $matrix->set(1, 1, 0);
+ $this->assertEquals(3, MaskUtil::applyMaskPenaltyRule2($matrix));
+
+ $matrix = new ByteMatrix(3, 3);
+ $matrix->set(0, 0, 0);
+ $matrix->set(1, 0, 0);
+ $matrix->set(2, 0, 0);
+ $matrix->set(0, 1, 0);
+ $matrix->set(1, 1, 0);
+ $matrix->set(2, 1, 0);
+ $matrix->set(0, 2, 0);
+ $matrix->set(1, 2, 0);
+ $matrix->set(2, 2, 0);
+ $this->assertEquals(3 * 4, MaskUtil::applyMaskPenaltyRule2($matrix));
+ }
+
+ public function testApplyMaskPenalty3()
+ {
+ // Horizontal 00001011101
+ $matrix = new ByteMatrix(11, 1);
+ $matrix->set(0, 0, 0);
+ $matrix->set(1, 0, 0);
+ $matrix->set(2, 0, 0);
+ $matrix->set(3, 0, 0);
+ $matrix->set(4, 0, 1);
+ $matrix->set(5, 0, 0);
+ $matrix->set(6, 0, 1);
+ $matrix->set(7, 0, 1);
+ $matrix->set(8, 0, 1);
+ $matrix->set(9, 0, 0);
+ $matrix->set(10, 0, 1);
+ $this->assertEquals(40, MaskUtil::applyMaskPenaltyRule3($matrix));
+
+ // Horizontal 10111010000
+ $matrix = new ByteMatrix(11, 1);
+ $matrix->set(0, 0, 1);
+ $matrix->set(1, 0, 0);
+ $matrix->set(2, 0, 1);
+ $matrix->set(3, 0, 1);
+ $matrix->set(4, 0, 1);
+ $matrix->set(5, 0, 0);
+ $matrix->set(6, 0, 1);
+ $matrix->set(7, 0, 0);
+ $matrix->set(8, 0, 0);
+ $matrix->set(9, 0, 0);
+ $matrix->set(10, 0, 0);
+ $this->assertEquals(40, MaskUtil::applyMaskPenaltyRule3($matrix));
+
+ // Vertical 00001011101
+ $matrix = new ByteMatrix(1, 11);
+ $matrix->set(0, 0, 0);
+ $matrix->set(0, 1, 0);
+ $matrix->set(0, 2, 0);
+ $matrix->set(0, 3, 0);
+ $matrix->set(0, 4, 1);
+ $matrix->set(0, 5, 0);
+ $matrix->set(0, 6, 1);
+ $matrix->set(0, 7, 1);
+ $matrix->set(0, 8, 1);
+ $matrix->set(0, 9, 0);
+ $matrix->set(0, 10, 1);
+ $this->assertEquals(40, MaskUtil::applyMaskPenaltyRule3($matrix));
+
+ // Vertical 10111010000
+ $matrix = new ByteMatrix(1, 11);
+ $matrix->set(0, 0, 1);
+ $matrix->set(0, 1, 0);
+ $matrix->set(0, 2, 1);
+ $matrix->set(0, 3, 1);
+ $matrix->set(0, 4, 1);
+ $matrix->set(0, 5, 0);
+ $matrix->set(0, 6, 1);
+ $matrix->set(0, 7, 0);
+ $matrix->set(0, 8, 0);
+ $matrix->set(0, 9, 0);
+ $matrix->set(0, 10, 0);
+ $this->assertEquals(40, MaskUtil::applyMaskPenaltyRule3($matrix));
+ }
+
+ public function testApplyMaskPenaltyRule4()
+ {
+ // Dark cell ratio = 0%
+ $matrix = new ByteMatrix(1, 1);
+ $matrix->set(0, 0, 0);
+ $this->assertEquals(100, MaskUtil::applyMaskPenaltyRule4($matrix));
+
+ // Dark cell ratio = 5%
+ $matrix = new ByteMatrix(2, 1);
+ $matrix->set(0, 0, 0);
+ $matrix->set(0, 0, 1);
+ $this->assertEquals(0, MaskUtil::applyMaskPenaltyRule4($matrix));
+
+ // Dark cell ratio = 66.67%
+ $matrix = new ByteMatrix(6, 1);
+ $matrix->set(0, 0, 0);
+ $matrix->set(1, 0, 1);
+ $matrix->set(2, 0, 1);
+ $matrix->set(3, 0, 1);
+ $matrix->set(4, 0, 1);
+ $matrix->set(5, 0, 0);
+ $this->assertEquals(30, MaskUtil::applyMaskPenaltyRule4($matrix));
+ }
+}
\ No newline at end of file
diff --git a/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Encoder/MatrixUtilTest.php b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Encoder/MatrixUtilTest.php
new file mode 100755
index 000000000..bf3544f0c
--- /dev/null
+++ b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Encoder/MatrixUtilTest.php
@@ -0,0 +1,336 @@
+getMethods(ReflectionMethod::IS_STATIC) as $method) {
+ $method->setAccessible(true);
+ $this->methods[$method->getName()] = $method;
+ }
+ }
+
+ public function testToString()
+ {
+ $matrix= new ByteMatrix(3, 3);
+ $matrix->set(0, 0, 0);
+ $matrix->set(1, 0, 1);
+ $matrix->set(2, 0, 0);
+ $matrix->set(0, 1, 1);
+ $matrix->set(1, 1, 0);
+ $matrix->set(2, 1, 1);
+ $matrix->set(0, 2, -1);
+ $matrix->set(1, 2, -1);
+ $matrix->set(2, 2, -1);
+
+ $expected = " 0 1 0\n 1 0 1\n \n";
+ $this->assertEquals($expected, $matrix->__toString());
+ }
+
+ public function testClearMatrix()
+ {
+ $matrix = new ByteMatrix(2, 2);
+ MatrixUtil::clearMatrix($matrix);
+
+ $this->assertEquals(-1, $matrix->get(0, 0));
+ $this->assertEquals(-1, $matrix->get(1, 0));
+ $this->assertEquals(-1, $matrix->get(0, 1));
+ $this->assertEquals(-1, $matrix->get(1, 1));
+ }
+
+ public function testEmbedBasicPatterns1()
+ {
+ $matrix = new ByteMatrix(21, 21);
+ MatrixUtil::clearMatrix($matrix);
+ $this->methods['embedBasicPatterns']->invoke(
+ null,
+ Version::getVersionForNumber(1),
+ $matrix
+ );
+ $expected = " 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1\n"
+ . " 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1\n"
+ . " 1 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1\n"
+ . " 1 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1\n"
+ . " 1 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1\n"
+ . " 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1\n"
+ . " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n"
+ . " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ . " 1 \n"
+ . " 0 \n"
+ . " 1 \n"
+ . " 0 \n"
+ . " 1 \n"
+ . " 0 0 0 0 0 0 0 0 1 \n"
+ . " 1 1 1 1 1 1 1 0 \n"
+ . " 1 0 0 0 0 0 1 0 \n"
+ . " 1 0 1 1 1 0 1 0 \n"
+ . " 1 0 1 1 1 0 1 0 \n"
+ . " 1 0 1 1 1 0 1 0 \n"
+ . " 1 0 0 0 0 0 1 0 \n"
+ . " 1 1 1 1 1 1 1 0 \n";
+
+ $this->assertEquals($expected, $matrix->__toString());
+ }
+
+ public function testEmbedBasicPatterns2()
+ {
+ $matrix = new ByteMatrix(25, 25);
+ MatrixUtil::clearMatrix($matrix);
+ $this->methods['embedBasicPatterns']->invoke(
+ null,
+ Version::getVersionForNumber(2),
+ $matrix
+ );
+ $expected = " 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1\n"
+ . " 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1\n"
+ . " 1 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1\n"
+ . " 1 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1\n"
+ . " 1 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1\n"
+ . " 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1\n"
+ . " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n"
+ . " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ . " 1 \n"
+ . " 0 \n"
+ . " 1 \n"
+ . " 0 \n"
+ . " 1 \n"
+ . " 0 \n"
+ . " 1 \n"
+ . " 0 \n"
+ . " 1 1 1 1 1 1 \n"
+ . " 0 0 0 0 0 0 0 0 1 1 0 0 0 1 \n"
+ . " 1 1 1 1 1 1 1 0 1 0 1 0 1 \n"
+ . " 1 0 0 0 0 0 1 0 1 0 0 0 1 \n"
+ . " 1 0 1 1 1 0 1 0 1 1 1 1 1 \n"
+ . " 1 0 1 1 1 0 1 0 \n"
+ . " 1 0 1 1 1 0 1 0 \n"
+ . " 1 0 0 0 0 0 1 0 \n"
+ . " 1 1 1 1 1 1 1 0 \n";
+
+ $this->assertEquals($expected, $matrix->__toString());
+ }
+
+ public function testEmbedTypeInfo()
+ {
+ $matrix = new ByteMatrix(21, 21);
+ MatrixUtil::clearMatrix($matrix);
+ $this->methods['embedTypeInfo']->invoke(
+ null,
+ new ErrorCorrectionLevel(ErrorCorrectionLevel::M),
+ 5,
+ $matrix
+ );
+ $expected = " 0 \n"
+ . " 1 \n"
+ . " 1 \n"
+ . " 1 \n"
+ . " 0 \n"
+ . " 0 \n"
+ . " \n"
+ . " 1 \n"
+ . " 1 0 0 0 0 0 0 1 1 1 0 0 1 1 1 0\n"
+ . " \n"
+ . " \n"
+ . " \n"
+ . " \n"
+ . " \n"
+ . " 0 \n"
+ . " 0 \n"
+ . " 0 \n"
+ . " 0 \n"
+ . " 0 \n"
+ . " 0 \n"
+ . " 1 \n";
+
+ $this->assertEquals($expected, $matrix->__toString());
+ }
+
+ public function testEmbedVersionInfo()
+ {
+ $matrix = new ByteMatrix(21, 21);
+ MatrixUtil::clearMatrix($matrix);
+ $this->methods['maybeEmbedVersionInfo']->invoke(
+ null,
+ Version::getVersionForNumber(7),
+ $matrix
+ );
+ $expected = " 0 0 1 \n"
+ . " 0 1 0 \n"
+ . " 0 1 0 \n"
+ . " 0 1 1 \n"
+ . " 1 1 1 \n"
+ . " 0 0 0 \n"
+ . " \n"
+ . " \n"
+ . " \n"
+ . " \n"
+ . " 0 0 0 0 1 0 \n"
+ . " 0 1 1 1 1 0 \n"
+ . " 1 0 0 1 1 0 \n"
+ . " \n"
+ . " \n"
+ . " \n"
+ . " \n"
+ . " \n"
+ . " \n"
+ . " \n"
+ . " \n";
+
+ $this->assertEquals($expected, $matrix->__toString());
+ }
+
+ public function testEmbedDataBits()
+ {
+ $matrix = new ByteMatrix(21, 21);
+ MatrixUtil::clearMatrix($matrix);
+ $this->methods['embedBasicPatterns']->invoke(
+ null,
+ Version::getVersionForNumber(1),
+ $matrix
+ );
+
+ $bits = new BitArray();
+ $this->methods['embedDataBits']->invoke(
+ null,
+ $bits,
+ -1,
+ $matrix
+ );
+
+ $expected = " 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1\n"
+ . " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1\n"
+ . " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 1 0 1 1 1 0 1\n"
+ . " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 1 0 1 1 1 0 1\n"
+ . " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 1 0 1 1 1 0 1\n"
+ . " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1\n"
+ . " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n"
+ . " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ . " 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ . " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ . " 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ . " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ . " 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ . " 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ . " 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ . " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ . " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ . " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ . " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ . " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ . " 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n";
+
+ $this->assertEquals($expected, $matrix->__toString());
+ }
+
+ public function testBuildMatrix()
+ {
+ $bytes = array(
+ 32, 65, 205, 69, 41, 220, 46, 128, 236, 42, 159, 74, 221, 244, 169,
+ 239, 150, 138, 70, 237, 85, 224, 96, 74, 219 , 61
+ );
+ $bits = new BitArray();
+
+ foreach ($bytes as $byte) {
+ $bits->appendBits($byte, 8);
+ }
+
+ $matrix = new ByteMatrix(21, 21);
+ MatrixUtil::buildMatrix(
+ $bits,
+ new ErrorCorrectionLevel(ErrorCorrectionLevel::H),
+ Version::getVersionForNumber(1),
+ 3,
+ $matrix
+ );
+
+ $expected = " 1 1 1 1 1 1 1 0 0 1 1 0 0 0 1 1 1 1 1 1 1\n"
+ . " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1\n"
+ . " 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 1 1 1 0 1\n"
+ . " 1 0 1 1 1 0 1 0 0 1 1 0 0 0 1 0 1 1 1 0 1\n"
+ . " 1 0 1 1 1 0 1 0 1 1 0 0 1 0 1 0 1 1 1 0 1\n"
+ . " 1 0 0 0 0 0 1 0 0 0 1 1 1 0 1 0 0 0 0 0 1\n"
+ . " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n"
+ . " 0 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0\n"
+ . " 0 0 1 1 0 0 1 1 1 0 0 1 1 1 1 0 1 0 0 0 0\n"
+ . " 1 0 1 0 1 0 0 0 0 0 1 1 1 0 0 1 0 1 1 1 0\n"
+ . " 1 1 1 1 0 1 1 0 1 0 1 1 1 0 0 1 1 1 0 1 0\n"
+ . " 1 0 1 0 1 1 0 1 1 1 0 0 1 1 1 0 0 1 0 1 0\n"
+ . " 0 0 1 0 0 1 1 1 0 0 0 0 0 0 1 0 1 1 1 1 1\n"
+ . " 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 1 0 1 1\n"
+ . " 1 1 1 1 1 1 1 0 1 1 1 1 0 0 0 0 1 0 1 1 0\n"
+ . " 1 0 0 0 0 0 1 0 0 0 0 1 0 1 1 1 0 0 0 0 0\n"
+ . " 1 0 1 1 1 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 1\n"
+ . " 1 0 1 1 1 0 1 0 1 1 0 1 0 0 0 0 0 1 1 1 0\n"
+ . " 1 0 1 1 1 0 1 0 1 1 1 1 0 0 0 0 1 1 1 0 0\n"
+ . " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0\n"
+ . " 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 0 1 0 0 1 0\n";
+
+ $this->assertEquals($expected, $matrix->__toString());
+ }
+
+ public function testFindMsbSet()
+ {
+ $this->assertEquals(0, $this->methods['findMsbSet']->invoke(null, 0));
+ $this->assertEquals(1, $this->methods['findMsbSet']->invoke(null, 1));
+ $this->assertEquals(8, $this->methods['findMsbSet']->invoke(null, 0x80));
+ $this->assertEquals(32, $this->methods['findMsbSet']->invoke(null, 0x80000000));
+ }
+
+ public function testCalculateBchCode()
+ {
+ // Encoding of type information.
+ // From Appendix C in JISX0510:2004 (p 65)
+ $this->assertEquals(0xdc, $this->methods['calculateBchCode']->invoke(null, 5, 0x537));
+ // From http://www.swetake.com/qr/qr6.html
+ $this->assertEquals(0x1c2, $this->methods['calculateBchCode']->invoke(null, 0x13, 0x537));
+ // From http://www.swetake.com/qr/qr11.html
+ $this->assertEquals(0x214, $this->methods['calculateBchCode']->invoke(null, 0x1b, 0x537));
+
+ // Encoding of version information.
+ // From Appendix D in JISX0510:2004 (p 68)
+ $this->assertEquals(0xc94, $this->methods['calculateBchCode']->invoke(null, 7, 0x1f25));
+ $this->assertEquals(0x5bc, $this->methods['calculateBchCode']->invoke(null, 8, 0x1f25));
+ $this->assertEquals(0xa99, $this->methods['calculateBchCode']->invoke(null, 9, 0x1f25));
+ $this->assertEquals(0x4d3, $this->methods['calculateBchCode']->invoke(null, 10, 0x1f25));
+ $this->assertEquals(0x9a6, $this->methods['calculateBchCode']->invoke(null, 20, 0x1f25));
+ $this->assertEquals(0xd75, $this->methods['calculateBchCode']->invoke(null, 30, 0x1f25));
+ $this->assertEquals(0xc69, $this->methods['calculateBchCode']->invoke(null, 40, 0x1f25));
+ }
+
+ public function testMakeVersionInfoBits()
+ {
+ // From Appendix D in JISX0510:2004 (p 68)
+ $bits = new BitArray();
+ $this->methods['makeVersionInfoBits']->invoke(null, Version::getVersionForNumber(7), $bits);
+ $this->assertEquals(' ...XXXXX ..X..X.X ..', $bits->__toString());
+ }
+
+ public function testMakeTypeInfoBits()
+ {
+ // From Appendix D in JISX0510:2004 (p 68)
+ $bits = new BitArray();
+ $this->methods['makeTypeInfoBits']->invoke(null, new ErrorCorrectionLevel(ErrorCorrectionLevel::M), 5, $bits);
+ $this->assertEquals(' X......X X..XXX.', $bits->__toString());
+ }
+}
\ No newline at end of file
diff --git a/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Renderer/Text/HtmlTest.php b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Renderer/Text/HtmlTest.php
new file mode 100755
index 000000000..0c69dd2e8
--- /dev/null
+++ b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Renderer/Text/HtmlTest.php
@@ -0,0 +1,99 @@
+renderer = new Html();
+ $this->writer = new Writer($this->renderer);
+ }
+
+ public function testBasicRender()
+ {
+ $content = 'foobar';
+ $expected =
+ '' .
+ " \n" .
+ " ███████ █████ ███████ \n" .
+ " █ █ █ █ █ █ \n" .
+ " █ ███ █ ██ █ ███ █ \n" .
+ " █ ███ █ ███ █ ███ █ \n" .
+ " █ ███ █ █ █ █ ███ █ \n" .
+ " █ █ ██ █ █ \n" .
+ " ███████ █ █ █ ███████ \n" .
+ " █████ \n" .
+ " ██ ██ █ ██ █ █ █ \n" .
+ " ██ ██ █ █ ██ \n" .
+ " ████████ █ ██ █ ██ \n" .
+ " ██ █ █ \n" .
+ " ██ ███ █ █ █ █ \n" .
+ " █ ███ █ █ \n" .
+ " ███████ ██ ██████ \n" .
+ " █ █ ████ ██ \n" .
+ " █ ███ █ ██ ██ ██ █ ██ \n" .
+ " █ ███ █ ██ ██ █ ██ \n" .
+ " █ ███ █ █ █ ██ ██ \n" .
+ " █ █ ███ ███ ████ \n" .
+ " ███████ ████ ██ \n" .
+ " \n" .
+ '
'
+ ;
+
+ $qrCode = Encoder::encode(
+ $content,
+ new ErrorCorrectionLevel(ErrorCorrectionLevel::L),
+ Encoder::DEFAULT_BYTE_MODE_ECODING
+ );
+ $this->assertEquals($expected, $this->renderer->render($qrCode));
+ }
+
+ public function testSetStyle()
+ {
+ $content = 'foobar';
+ $qrCode = Encoder::encode(
+ $content,
+ new ErrorCorrectionLevel(ErrorCorrectionLevel::L),
+ Encoder::DEFAULT_BYTE_MODE_ECODING
+ );
+ $this->renderer->setStyle('bar');
+ $this->assertEquals('bar', $this->renderer->getStyle());
+ $this->assertStringMatchesFormat('%astyle="bar"%a', $this->renderer->render($qrCode));
+ }
+
+ public function testSetClass()
+ {
+ $content = 'foobar';
+ $qrCode = Encoder::encode(
+ $content,
+ new ErrorCorrectionLevel(ErrorCorrectionLevel::L),
+ Encoder::DEFAULT_BYTE_MODE_ECODING
+ );
+ $this->renderer->setClass('bar');
+ $this->assertEquals('bar', $this->renderer->getClass());
+ $this->assertStringMatchesFormat('%aclass="bar"%a', $this->renderer->render($qrCode));
+ }
+}
diff --git a/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Renderer/Text/TextTest.php b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Renderer/Text/TextTest.php
new file mode 100755
index 000000000..d94e8e5d0
--- /dev/null
+++ b/Server/vendor/bacon/bacon-qr-code/tests/BaconQrCode/Renderer/Text/TextTest.php
@@ -0,0 +1,149 @@
+renderer = new Plain();
+ $this->writer = new Writer($this->renderer);
+ }
+
+ public function testBasicRender()
+ {
+ $content = 'foobar';
+ $expected =
+ " \n" .
+ " ███████ █████ ███████ \n" .
+ " █ █ █ █ █ █ \n" .
+ " █ ███ █ ██ █ ███ █ \n" .
+ " █ ███ █ ███ █ ███ █ \n" .
+ " █ ███ █ █ █ █ ███ █ \n" .
+ " █ █ ██ █ █ \n" .
+ " ███████ █ █ █ ███████ \n" .
+ " █████ \n" .
+ " ██ ██ █ ██ █ █ █ \n" .
+ " ██ ██ █ █ ██ \n" .
+ " ████████ █ ██ █ ██ \n" .
+ " ██ █ █ \n" .
+ " ██ ███ █ █ █ █ \n" .
+ " █ ███ █ █ \n" .
+ " ███████ ██ ██████ \n" .
+ " █ █ ████ ██ \n" .
+ " █ ███ █ ██ ██ ██ █ ██ \n" .
+ " █ ███ █ ██ ██ █ ██ \n" .
+ " █ ███ █ █ █ ██ ██ \n" .
+ " █ █ ███ ███ ████ \n" .
+ " ███████ ████ ██ \n" .
+ " \n"
+ ;
+
+ $qrCode = Encoder::encode(
+ $content,
+ new ErrorCorrectionLevel(ErrorCorrectionLevel::L),
+ Encoder::DEFAULT_BYTE_MODE_ECODING
+ );
+ $this->assertEquals($expected, $this->renderer->render($qrCode));
+ }
+
+ public function testBasicRenderNoMargins()
+ {
+ $content = 'foobar';
+ $expected =
+ "███████ █████ ███████\n" .
+ "█ █ █ █ █ █\n" .
+ "█ ███ █ ██ █ ███ █\n" .
+ "█ ███ █ ███ █ ███ █\n" .
+ "█ ███ █ █ █ █ ███ █\n" .
+ "█ █ ██ █ █\n" .
+ "███████ █ █ █ ███████\n" .
+ " █████ \n" .
+ "██ ██ █ ██ █ █ █\n" .
+ " ██ ██ █ █ ██ \n" .
+ " ████████ █ ██ █ ██\n" .
+ " ██ █ █\n" .
+ " ██ ███ █ █ █ █\n" .
+ " █ ███ █ █ \n" .
+ "███████ ██ ██████ \n" .
+ "█ █ ████ ██ \n" .
+ "█ ███ █ ██ ██ ██ █ ██\n" .
+ "█ ███ █ ██ ██ █ ██ \n" .
+ "█ ███ █ █ █ ██ ██\n" .
+ "█ █ ███ ███ ████\n" .
+ "███████ ████ ██ \n"
+ ;
+
+ $qrCode = Encoder::encode(
+ $content,
+ new ErrorCorrectionLevel(ErrorCorrectionLevel::L),
+ Encoder::DEFAULT_BYTE_MODE_ECODING
+ );
+ $this->renderer->setMargin(0);
+ $this->assertEquals(0, $this->renderer->getMargin());
+ $this->assertEquals($expected, $this->renderer->render($qrCode));
+ }
+
+ public function testBasicRenderCustomChar()
+ {
+ $content = 'foobar';
+ $expected =
+ "-----------------------\n" .
+ "-#######-#####-#######-\n" .
+ "-#-----#--#-#--#-----#-\n" .
+ "-#-###-#--##---#-###-#-\n" .
+ "-#-###-#--###--#-###-#-\n" .
+ "-#-###-#---#-#-#-###-#-\n" .
+ "-#-----#----##-#-----#-\n" .
+ "-#######-#-#-#-#######-\n" .
+ "---------#####---------\n" .
+ "-##-##-#--##-#-#-----#-\n" .
+ "----##----##-#-#-##----\n" .
+ "--########-#--##-#--##-\n" .
+ "-----------##------#-#-\n" .
+ "--##--###--#---#--#--#-\n" .
+ "---------#-###----#-#--\n" .
+ "-#######--##-######----\n" .
+ "-#-----#---####---##---\n" .
+ "-#-###-#-##-##-##-#-##-\n" .
+ "-#-###-#-##-##--#-##---\n" .
+ "-#-###-#---#---#-##-##-\n" .
+ "-#-----#-###--###-####-\n" .
+ "-#######-####---##-----\n" .
+ "-----------------------\n"
+ ;
+
+ $qrCode = Encoder::encode(
+ $content,
+ new ErrorCorrectionLevel(ErrorCorrectionLevel::L),
+ Encoder::DEFAULT_BYTE_MODE_ECODING
+ );
+ $this->renderer->setFullBlock('#');
+ $this->renderer->setEmptyBlock('-');
+ $this->assertEquals('#', $this->renderer->getFullBlock());
+ $this->assertEquals('-', $this->renderer->getEmptyBlock());
+ $this->assertEquals($expected, $this->renderer->render($qrCode));
+ }
+}
diff --git a/Server/vendor/bacon/bacon-qr-code/tests/bootstrap.php b/Server/vendor/bacon/bacon-qr-code/tests/bootstrap.php
new file mode 100755
index 000000000..05a494152
--- /dev/null
+++ b/Server/vendor/bacon/bacon-qr-code/tests/bootstrap.php
@@ -0,0 +1,10 @@
+
+
+
+
+```
+
+## Versioning
+
+Version numbers follow the MAJOR.MINOR.PATCH scheme. Backwards compatibility
+breaking changes will be kept to a minimum but be aware that these can occur.
+Lock your dependencies for production and test your code when upgrading.
+
+## License
+
+This bundle is under the MIT license. For the full copyright and license
+information please view the LICENSE file that was distributed with this source code.
diff --git a/Server/vendor/endroid/qr-code/assets/noto_sans.otf b/Server/vendor/endroid/qr-code/assets/noto_sans.otf
new file mode 100755
index 000000000..296fbebd8
Binary files /dev/null and b/Server/vendor/endroid/qr-code/assets/noto_sans.otf differ
diff --git a/Server/vendor/endroid/qr-code/assets/open_sans.ttf b/Server/vendor/endroid/qr-code/assets/open_sans.ttf
new file mode 100755
index 000000000..db433349b
Binary files /dev/null and b/Server/vendor/endroid/qr-code/assets/open_sans.ttf differ
diff --git a/Server/vendor/endroid/qr-code/assets/symfony.png b/Server/vendor/endroid/qr-code/assets/symfony.png
new file mode 100755
index 000000000..55fe19836
Binary files /dev/null and b/Server/vendor/endroid/qr-code/assets/symfony.png differ
diff --git a/Server/vendor/endroid/qr-code/composer.json b/Server/vendor/endroid/qr-code/composer.json
new file mode 100755
index 000000000..dcaf7f3f8
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/composer.json
@@ -0,0 +1,53 @@
+{
+ "name": "endroid/qrcode",
+ "description": "Endroid QR Code",
+ "keywords": ["endroid", "qrcode", "qr", "code", "bundle", "symfony", "flex"],
+ "homepage": "https://github.com/endroid/QrCode",
+ "type": "symfony-bundle",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Jeroen van den Enden",
+ "email": "info@endroid.nl",
+ "homepage": "http://endroid.nl/"
+ }
+ ],
+ "require": {
+ "php": ">=5.6",
+ "ext-gd": "*",
+ "symfony/options-resolver": "^2.7",
+ "bacon/bacon-qr-code": "^1.0.3",
+ "khanamiryan/qrcode-detector-decoder": "1",
+ "symfony/property-access": "^2.7",
+ "myclabs/php-enum": "^1.5"
+ },
+ "require-dev": {
+ "symfony/asset": "^2.7",
+ "symfony/browser-kit": "^2.7",
+ "symfony/finder": "^2.7",
+ "symfony/framework-bundle": "^2.7",
+ "symfony/http-kernel": "^2.7",
+ "symfony/templating": "^2.7",
+ "symfony/twig-bundle": "^2.7",
+ "symfony/yaml": "^2.7",
+ "phpunit/phpunit": "^5.7"
+ },
+ "autoload": {
+ "psr-4": {
+ "Endroid\\QrCode\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Endroid\\QrCode\\Tests\\": "tests/"
+ }
+ },
+ "config": {
+ "bin-dir": "bin"
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.x-dev"
+ }
+ }
+}
diff --git a/Server/vendor/endroid/qr-code/phpunit.xml.dist b/Server/vendor/endroid/qr-code/phpunit.xml.dist
new file mode 100755
index 000000000..0b5f706bc
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/phpunit.xml.dist
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/Server/vendor/endroid/qr-code/src/ErrorCorrectionLevel.php b/Server/vendor/endroid/qr-code/src/ErrorCorrectionLevel.php
new file mode 100755
index 000000000..4a963f342
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/ErrorCorrectionLevel.php
@@ -0,0 +1,20 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode;
+
+use MyCLabs\Enum\Enum;
+
+class ErrorCorrectionLevel extends Enum
+{
+ const LOW = 'low';
+ const MEDIUM = 'medium';
+ const QUARTILE = 'quartile';
+ const HIGH = 'high';
+}
diff --git a/Server/vendor/endroid/qr-code/src/Exception/InvalidPathException.php b/Server/vendor/endroid/qr-code/src/Exception/InvalidPathException.php
new file mode 100755
index 000000000..6492b548f
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/Exception/InvalidPathException.php
@@ -0,0 +1,14 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode\Exception;
+
+class InvalidPathException extends QrCodeException
+{
+}
diff --git a/Server/vendor/endroid/qr-code/src/Exception/InvalidWriterException.php b/Server/vendor/endroid/qr-code/src/Exception/InvalidWriterException.php
new file mode 100755
index 000000000..4663403f6
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/Exception/InvalidWriterException.php
@@ -0,0 +1,14 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode\Exception;
+
+class InvalidWriterException extends QrCodeException
+{
+}
diff --git a/Server/vendor/endroid/qr-code/src/Exception/MissingFunctionException.php b/Server/vendor/endroid/qr-code/src/Exception/MissingFunctionException.php
new file mode 100755
index 000000000..9afe99717
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/Exception/MissingFunctionException.php
@@ -0,0 +1,14 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode\Exception;
+
+class MissingFunctionException extends QrCodeException
+{
+}
diff --git a/Server/vendor/endroid/qr-code/src/Exception/QrCodeException.php b/Server/vendor/endroid/qr-code/src/Exception/QrCodeException.php
new file mode 100755
index 000000000..f076a9552
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/Exception/QrCodeException.php
@@ -0,0 +1,16 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode\Exception;
+
+use Exception;
+
+abstract class QrCodeException extends Exception
+{
+}
diff --git a/Server/vendor/endroid/qr-code/src/Exception/UnsupportedExtensionException.php b/Server/vendor/endroid/qr-code/src/Exception/UnsupportedExtensionException.php
new file mode 100755
index 000000000..4b1c6f229
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/Exception/UnsupportedExtensionException.php
@@ -0,0 +1,14 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode\Exception;
+
+class UnsupportedExtensionException extends QrCodeException
+{
+}
diff --git a/Server/vendor/endroid/qr-code/src/Exception/ValidationException.php b/Server/vendor/endroid/qr-code/src/Exception/ValidationException.php
new file mode 100755
index 000000000..85d8380f2
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/Exception/ValidationException.php
@@ -0,0 +1,14 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode\Exception;
+
+class ValidationException extends QrCodeException
+{
+}
diff --git a/Server/vendor/endroid/qr-code/src/Factory/QrCodeFactory.php b/Server/vendor/endroid/qr-code/src/Factory/QrCodeFactory.php
new file mode 100755
index 000000000..383e486e2
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/Factory/QrCodeFactory.php
@@ -0,0 +1,120 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode\Factory;
+
+use Endroid\QrCode\QrCode;
+use Endroid\QrCode\WriterRegistryInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+use Symfony\Component\PropertyAccess\PropertyAccess;
+
+class QrCodeFactory
+{
+ /**
+ * @var array
+ */
+ protected $definedOptions = [
+ 'writer',
+ 'size',
+ 'margin',
+ 'foreground_color',
+ 'background_color',
+ 'encoding',
+ 'error_correction_level',
+ 'logo_path',
+ 'logo_width',
+ 'label',
+ 'label_font_size',
+ 'label_font_path',
+ 'label_alignment',
+ 'label_margin',
+ 'validate_result',
+ ];
+
+ /**
+ * @var array
+ */
+ protected $defaultOptions;
+
+ /**
+ * @var WriterRegistryInterface
+ */
+ protected $writerRegistry;
+
+ /**
+ * @var OptionsResolver
+ */
+ protected $optionsResolver;
+
+ /**
+ * @param array $defaultOptions
+ * @param WriterRegistryInterface $writerRegistry
+ */
+ public function __construct(array $defaultOptions = [], WriterRegistryInterface $writerRegistry = null)
+ {
+ $this->defaultOptions = $defaultOptions;
+ $this->writerRegistry = $writerRegistry;
+ }
+
+ /**
+ * @param string $text
+ * @param array $options
+ *
+ * @return QrCode
+ */
+ public function create($text = '', array $options = [])
+ {
+ $options = $this->getOptionsResolver()->resolve($options);
+ $accessor = PropertyAccess::createPropertyAccessor();
+
+ $qrCode = new QrCode($text);
+
+ if ($this->writerRegistry instanceof WriterRegistryInterface) {
+ $qrCode->setWriterRegistry($this->writerRegistry);
+ }
+
+ foreach ($this->definedOptions as $option) {
+ if (isset($options[$option])) {
+ if ('writer' === $option) {
+ $options['writer_by_name'] = $options[$option];
+ $option = 'writer_by_name';
+ }
+ $accessor->setValue($qrCode, $option, $options[$option]);
+ }
+ }
+
+ return $qrCode;
+ }
+
+ /**
+ * @return OptionsResolver
+ */
+ protected function getOptionsResolver()
+ {
+ if (!$this->optionsResolver instanceof OptionsResolver) {
+ $this->optionsResolver = $this->createOptionsResolver();
+ }
+
+ return $this->optionsResolver;
+ }
+
+ /**
+ * @return OptionsResolver
+ */
+ protected function createOptionsResolver()
+ {
+ $optionsResolver = new OptionsResolver();
+ $optionsResolver
+ ->setDefaults($this->defaultOptions)
+ ->setDefined($this->definedOptions)
+ ;
+
+ return $optionsResolver;
+ }
+}
diff --git a/Server/vendor/endroid/qr-code/src/LabelAlignment.php b/Server/vendor/endroid/qr-code/src/LabelAlignment.php
new file mode 100755
index 000000000..ac30cc953
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/LabelAlignment.php
@@ -0,0 +1,19 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode;
+
+use MyCLabs\Enum\Enum;
+
+class LabelAlignment extends Enum
+{
+ const LEFT = 'left';
+ const CENTER = 'center';
+ const RIGHT = 'right';
+}
diff --git a/Server/vendor/endroid/qr-code/src/QrCode.php b/Server/vendor/endroid/qr-code/src/QrCode.php
new file mode 100755
index 000000000..900e3fe70
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/QrCode.php
@@ -0,0 +1,591 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode;
+
+use Endroid\QrCode\Exception\InvalidPathException;
+use Endroid\QrCode\Exception\InvalidWriterException;
+use Endroid\QrCode\Exception\UnsupportedExtensionException;
+use Endroid\QrCode\Writer\WriterInterface;
+
+class QrCode implements QrCodeInterface
+{
+ const LABEL_FONT_PATH_DEFAULT = __DIR__.'/../assets/noto_sans.otf';
+
+ /**
+ * @var string
+ */
+ protected $text;
+
+ /**
+ * @var int
+ */
+ protected $size = 300;
+
+ /**
+ * @var int
+ */
+ protected $margin = 10;
+
+ /**
+ * @var array
+ */
+ protected $foregroundColor = [
+ 'r' => 0,
+ 'g' => 0,
+ 'b' => 0,
+ ];
+
+ /**
+ * @var array
+ */
+ protected $backgroundColor = [
+ 'r' => 255,
+ 'g' => 255,
+ 'b' => 255,
+ ];
+
+ /**
+ * @var string
+ */
+ protected $encoding = 'UTF-8';
+
+ /**
+ * @var ErrorCorrectionLevel
+ */
+ protected $errorCorrectionLevel;
+
+ /**
+ * @var string
+ */
+ protected $logoPath;
+
+ /**
+ * @var int
+ */
+ protected $logoWidth;
+
+ /**
+ * @var string
+ */
+ protected $label;
+
+ /**
+ * @var int
+ */
+ protected $labelFontSize = 16;
+
+ /**
+ * @var string
+ */
+ protected $labelFontPath = self::LABEL_FONT_PATH_DEFAULT;
+
+ /**
+ * @var LabelAlignment
+ */
+ protected $labelAlignment;
+
+ /**
+ * @var array
+ */
+ protected $labelMargin = [
+ 't' => 0,
+ 'r' => 10,
+ 'b' => 10,
+ 'l' => 10,
+ ];
+
+ /**
+ * @var WriterRegistryInterface
+ */
+ protected $writerRegistry;
+
+ /**
+ * @var WriterInterface
+ */
+ protected $writer;
+
+ /**
+ * @var bool
+ */
+ protected $validateResult = false;
+
+ /**
+ * @param string $text
+ */
+ public function __construct($text = '')
+ {
+ $this->text = $text;
+
+ $this->errorCorrectionLevel = new ErrorCorrectionLevel(ErrorCorrectionLevel::LOW);
+ $this->labelAlignment = new LabelAlignment(LabelAlignment::CENTER);
+
+ $this->writerRegistry = new StaticWriterRegistry();
+ }
+
+ /**
+ * @param string $text
+ *
+ * @return $this
+ */
+ public function setText($text)
+ {
+ $this->text = $text;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getText()
+ {
+ return $this->text;
+ }
+
+ /**
+ * @param int $size
+ *
+ * @return $this
+ */
+ public function setSize($size)
+ {
+ $this->size = $size;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSize()
+ {
+ return $this->size;
+ }
+
+ /**
+ * @param int $margin
+ *
+ * @return $this
+ */
+ public function setMargin($margin)
+ {
+ $this->margin = $margin;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMargin()
+ {
+ return $this->margin;
+ }
+
+ /**
+ * @param array $foregroundColor
+ *
+ * @return $this
+ */
+ public function setForegroundColor($foregroundColor)
+ {
+ $this->foregroundColor = $foregroundColor;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getForegroundColor()
+ {
+ return $this->foregroundColor;
+ }
+
+ /**
+ * @param array $backgroundColor
+ *
+ * @return $this
+ */
+ public function setBackgroundColor($backgroundColor)
+ {
+ $this->backgroundColor = $backgroundColor;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getBackgroundColor()
+ {
+ return $this->backgroundColor;
+ }
+
+ /**
+ * @param string $encoding
+ *
+ * @return $this
+ */
+ public function setEncoding($encoding)
+ {
+ $this->encoding = $encoding;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getEncoding()
+ {
+ return $this->encoding;
+ }
+
+ /**
+ * @param string $errorCorrectionLevel
+ *
+ * @return $this
+ */
+ public function setErrorCorrectionLevel($errorCorrectionLevel)
+ {
+ $this->errorCorrectionLevel = new ErrorCorrectionLevel($errorCorrectionLevel);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getErrorCorrectionLevel()
+ {
+ return $this->errorCorrectionLevel->getValue();
+ }
+
+ /**
+ * @param string $logoPath
+ *
+ * @return $this
+ *
+ * @throws InvalidPathException
+ */
+ public function setLogoPath($logoPath)
+ {
+ $logoPath = realpath($logoPath);
+
+ if (!is_file($logoPath)) {
+ throw new InvalidPathException('Invalid logo path: '.$logoPath);
+ }
+
+ $this->logoPath = $logoPath;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getLogoPath()
+ {
+ return $this->logoPath;
+ }
+
+ /**
+ * @param int $logoWidth
+ *
+ * @return $this
+ */
+ public function setLogoWidth($logoWidth)
+ {
+ $this->logoWidth = $logoWidth;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getLogoWidth()
+ {
+ return $this->logoWidth;
+ }
+
+ /**
+ * @param string $label
+ * @param int $labelFontSize
+ * @param string $labelFontPath
+ * @param string $labelAlignment
+ * @param array $labelMargin
+ *
+ * @return $this
+ */
+ public function setLabel($label, $labelFontSize = null, $labelFontPath = null, $labelAlignment = null, $labelMargin = null)
+ {
+ $this->label = $label;
+
+ if (null !== $labelFontSize) {
+ $this->setLabelFontSize($labelFontSize);
+ }
+
+ if (null !== $labelFontPath) {
+ $this->setLabelFontPath($labelFontPath);
+ }
+
+ if (null !== $labelAlignment) {
+ $this->setLabelAlignment($labelAlignment);
+ }
+
+ if (null !== $labelMargin) {
+ $this->setLabelMargin($labelMargin);
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getLabel()
+ {
+ return $this->label;
+ }
+
+ /**
+ * @param int $labelFontSize
+ *
+ * @return $this
+ */
+ public function setLabelFontSize($labelFontSize)
+ {
+ $this->labelFontSize = $labelFontSize;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getLabelFontSize()
+ {
+ return $this->labelFontSize;
+ }
+
+ /**
+ * @param string $labelFontPath
+ *
+ * @return $this
+ *
+ * @throws InvalidPathException
+ */
+ public function setLabelFontPath($labelFontPath)
+ {
+ $labelFontPath = realpath($labelFontPath);
+
+ if (!is_file($labelFontPath)) {
+ throw new InvalidPathException('Invalid label font path: '.$labelFontPath);
+ }
+
+ $this->labelFontPath = $labelFontPath;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getLabelFontPath()
+ {
+ return $this->labelFontPath;
+ }
+
+ /**
+ * @param string $labelAlignment
+ *
+ * @return $this
+ */
+ public function setLabelAlignment($labelAlignment)
+ {
+ $this->labelAlignment = new LabelAlignment($labelAlignment);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getLabelAlignment()
+ {
+ return $this->labelAlignment->getValue();
+ }
+
+ /**
+ * @param int[] $labelMargin
+ *
+ * @return $this
+ */
+ public function setLabelMargin(array $labelMargin)
+ {
+ $this->labelMargin = array_merge($this->labelMargin, $labelMargin);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getLabelMargin()
+ {
+ return $this->labelMargin;
+ }
+
+ /**
+ * @param WriterRegistryInterface $writerRegistry
+ *
+ * @return $this
+ */
+ public function setWriterRegistry(WriterRegistryInterface $writerRegistry)
+ {
+ $this->writerRegistry = $writerRegistry;
+
+ return $this;
+ }
+
+ /**
+ * @param WriterInterface $writer
+ *
+ * @return $this
+ */
+ public function setWriter(WriterInterface $writer)
+ {
+ $this->writer = $writer;
+
+ return $this;
+ }
+
+ /**
+ * @param WriterInterface $name
+ *
+ * @return WriterInterface
+ */
+ public function getWriter($name = null)
+ {
+ if (!is_null($name)) {
+ return $this->writerRegistry->getWriter($name);
+ }
+
+ if ($this->writer instanceof WriterInterface) {
+ return $this->writer;
+ }
+
+ return $this->writerRegistry->getDefaultWriter();
+ }
+
+ /**
+ * @param string $name
+ *
+ * @return $this
+ *
+ * @throws InvalidWriterException
+ */
+ public function setWriterByName($name)
+ {
+ $this->writer = $this->writerRegistry->getWriter($name);
+
+ return $this;
+ }
+
+ /**
+ * @param string $path
+ *
+ * @return $this
+ */
+ public function setWriterByPath($path)
+ {
+ $extension = pathinfo($path, PATHINFO_EXTENSION);
+
+ $this->setWriterByExtension($extension);
+
+ return $this;
+ }
+
+ /**
+ * @param string $extension
+ *
+ * @return $this
+ *
+ * @throws UnsupportedExtensionException
+ */
+ public function setWriterByExtension($extension)
+ {
+ foreach ($this->writerRegistry->getWriters() as $writer) {
+ if ($writer->supportsExtension($extension)) {
+ $this->writer = $writer;
+
+ return $this;
+ }
+ }
+
+ throw new UnsupportedExtensionException('Missing writer for extension "'.$extension.'"');
+ }
+
+ /**
+ * @param bool $validateResult
+ *
+ * @return $this
+ */
+ public function setValidateResult($validateResult)
+ {
+ $this->validateResult = $validateResult;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getValidateResult()
+ {
+ return $this->validateResult;
+ }
+
+ /**
+ * @return string
+ */
+ public function writeString()
+ {
+ return $this->getWriter()->writeString($this);
+ }
+
+ /**
+ * @return string
+ */
+ public function writeDataUri()
+ {
+ return $this->getWriter()->writeDataUri($this);
+ }
+
+ /**
+ * @param string $path
+ */
+ public function writeFile($path)
+ {
+ return $this->getWriter()->writeFile($this, $path);
+ }
+
+ /**
+ * @return string
+ *
+ * @throws InvalidWriterException
+ */
+ public function getContentType()
+ {
+ return $this->getWriter()->getContentType();
+ }
+}
diff --git a/Server/vendor/endroid/qr-code/src/QrCodeInterface.php b/Server/vendor/endroid/qr-code/src/QrCodeInterface.php
new file mode 100755
index 000000000..0fdcb9669
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/QrCodeInterface.php
@@ -0,0 +1,95 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode;
+
+interface QrCodeInterface
+{
+ /**
+ * @return string
+ */
+ public function getText();
+
+ /**
+ * @return int
+ */
+ public function getSize();
+
+ /**
+ * @return int
+ */
+ public function getMargin();
+
+ /**
+ * @return int[]
+ */
+ public function getForegroundColor();
+
+ /**
+ * @return int[]
+ */
+ public function getBackgroundColor();
+
+ /**
+ * @return string
+ */
+ public function getEncoding();
+
+ /**
+ * @return string
+ */
+ public function getErrorCorrectionLevel();
+
+ /**
+ * @return string
+ */
+ public function getLogoPath();
+
+ /**
+ * @return int
+ */
+ public function getLogoWidth();
+
+ /**
+ * @return string
+ */
+ public function getLabel();
+
+ /**
+ * @return string
+ */
+ public function getLabelFontPath();
+
+ /**
+ * @return int
+ */
+ public function getLabelFontSize();
+
+ /**
+ * @return string
+ */
+ public function getLabelAlignment();
+
+ /**
+ * @return int[]
+ */
+ public function getLabelMargin();
+
+ /**
+ * @return bool
+ */
+ public function getValidateResult();
+
+ /**
+ * @param WriterRegistryInterface $writerRegistry
+ *
+ * @return mixed
+ */
+ public function setWriterRegistry(WriterRegistryInterface $writerRegistry);
+}
diff --git a/Server/vendor/endroid/qr-code/src/StaticWriterRegistry.php b/Server/vendor/endroid/qr-code/src/StaticWriterRegistry.php
new file mode 100755
index 000000000..9ab9a86b6
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/StaticWriterRegistry.php
@@ -0,0 +1,42 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode;
+
+use Endroid\QrCode\Writer\BinaryWriter;
+use Endroid\QrCode\Writer\DebugWriter;
+use Endroid\QrCode\Writer\EpsWriter;
+use Endroid\QrCode\Writer\PngWriter;
+use Endroid\QrCode\Writer\SvgWriter;
+
+class StaticWriterRegistry extends WriterRegistry
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function __construct()
+ {
+ parent::__construct();
+
+ $this->loadWriters();
+ }
+
+ protected function loadWriters()
+ {
+ if (count($this->writers) > 0) {
+ return;
+ }
+
+ $this->addWriter(new BinaryWriter());
+ $this->addWriter(new DebugWriter());
+ $this->addWriter(new EpsWriter());
+ $this->addWriter(new PngWriter(), true);
+ $this->addWriter(new SvgWriter());
+ }
+}
diff --git a/Server/vendor/endroid/qr-code/src/Twig/Extension/QrCodeExtension.php b/Server/vendor/endroid/qr-code/src/Twig/Extension/QrCodeExtension.php
new file mode 100755
index 000000000..cca3c2eeb
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/Twig/Extension/QrCodeExtension.php
@@ -0,0 +1,117 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode\Twig\Extension;
+
+use Endroid\QrCode\Exception\UnsupportedExtensionException;
+use Endroid\QrCode\Factory\QrCodeFactory;
+use Endroid\QrCode\WriterRegistryInterface;
+use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+use Symfony\Component\Routing\RouterInterface;
+use Twig_Extension;
+use Twig_SimpleFunction;
+
+class QrCodeExtension extends Twig_Extension
+{
+ /**
+ * @var QrCodeFactory
+ */
+ protected $qrCodeFactory;
+
+ /**
+ * @var RouterInterface
+ */
+ protected $router;
+
+ /**
+ * @param QrCodeFactory $qrCodeFactory
+ * @param RouterInterface $router
+ * @param WriterRegistryInterface $writerRegistry
+ */
+ public function __construct(QrCodeFactory $qrCodeFactory, RouterInterface $router)
+ {
+ $this->qrCodeFactory = $qrCodeFactory;
+ $this->router = $router;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFunctions()
+ {
+ return [
+ new Twig_SimpleFunction('qrcode_path', [$this, 'qrCodePathFunction']),
+ new Twig_SimpleFunction('qrcode_url', [$this, 'qrCodeUrlFunction']),
+ new Twig_SimpleFunction('qrcode_data_uri', [$this, 'qrCodeDataUriFunction']),
+ ];
+ }
+
+ /**
+ * @param string $text
+ * @param array $options
+ *
+ * @return string
+ */
+ public function qrcodeUrlFunction($text, array $options = [])
+ {
+ return $this->getQrCodeReference($text, $options, UrlGeneratorInterface::ABSOLUTE_URL);
+ }
+
+ /**
+ * @param string $text
+ * @param array $options
+ *
+ * @return string
+ */
+ public function qrCodePathFunction($text, array $options = [])
+ {
+ return $this->getQrCodeReference($text, $options, UrlGeneratorInterface::ABSOLUTE_PATH);
+ }
+
+ /**
+ * @param string $text
+ * @param array $options
+ * @param int $referenceType
+ *
+ * @return string
+ */
+ public function getQrCodeReference($text, array $options = [], $referenceType)
+ {
+ $qrCode = $this->qrCodeFactory->create($text, $options);
+ $supportedExtensions = $qrCode->getWriter()->getSupportedExtensions();
+
+ $options['text'] = $text;
+ $options['extension'] = current($supportedExtensions);
+
+ return $this->router->generate('endroid_qrcode_generate', $options, $referenceType);
+ }
+
+ /**
+ * @param string $text
+ * @param array $options
+ *
+ * @return string
+ *
+ * @throws UnsupportedExtensionException
+ */
+ public function qrcodeDataUriFunction($text, array $options = [])
+ {
+ $qrCode = $this->qrCodeFactory->create($text, $options);
+
+ return $qrCode->writeDataUri();
+ }
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ return 'qrcode';
+ }
+}
diff --git a/Server/vendor/endroid/qr-code/src/Writer/AbstractBaconWriter.php b/Server/vendor/endroid/qr-code/src/Writer/AbstractBaconWriter.php
new file mode 100755
index 000000000..a52e3a054
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/Writer/AbstractBaconWriter.php
@@ -0,0 +1,40 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode\Writer;
+
+use BaconQrCode\Renderer\Color\Rgb;
+
+abstract class AbstractBaconWriter extends AbstractWriter
+{
+ /**
+ * @param array $color
+ *
+ * @return Rgb
+ */
+ protected function convertColor(array $color)
+ {
+ $color = new Rgb($color['r'], $color['g'], $color['b']);
+
+ return $color;
+ }
+
+ /**
+ * @param string $errorCorrectionLevel
+ *
+ * @return string
+ */
+ protected function convertErrorCorrectionLevel($errorCorrectionLevel)
+ {
+ $name = strtoupper(substr($errorCorrectionLevel, 0, 1));
+ $errorCorrectionLevel = constant('BaconQrCode\Common\ErrorCorrectionLevel::'.$name);
+
+ return $errorCorrectionLevel;
+ }
+}
diff --git a/Server/vendor/endroid/qr-code/src/Writer/AbstractWriter.php b/Server/vendor/endroid/qr-code/src/Writer/AbstractWriter.php
new file mode 100755
index 000000000..27c564caf
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/Writer/AbstractWriter.php
@@ -0,0 +1,63 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode\Writer;
+
+use Endroid\QrCode\QrCodeInterface;
+use ReflectionClass;
+
+abstract class AbstractWriter implements WriterInterface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function writeDataUri(QrCodeInterface $qrCode)
+ {
+ $dataUri = 'data:'.$this->getContentType().';base64,'.base64_encode($this->writeString($qrCode));
+
+ return $dataUri;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function writeFile(QrCodeInterface $qrCode, $path)
+ {
+ $string = $this->writeString($qrCode);
+ file_put_contents($path, $string);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function supportsExtension($extension)
+ {
+ return in_array($extension, static::getSupportedExtensions());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getSupportedExtensions()
+ {
+ return [];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ $reflectionClass = new ReflectionClass($this);
+ $className = $reflectionClass->getShortName();
+ $name = strtolower(preg_replace('/(?
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode\Writer;
+
+use Endroid\QrCode\QrCodeInterface;
+
+class BinaryWriter extends AbstractWriter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function writeString(QrCodeInterface $qrCode)
+ {
+ $string = '
+ 0001010101
+ 0001010101
+ 1000101010
+ 0001010101
+ 0101010101
+ 0001010101
+ 0001010101
+ 0001010101
+ 0001010101
+ 1000101010
+ ';
+
+ return $string;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getContentType()
+ {
+ return 'text/plain';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getSupportedExtensions()
+ {
+ return ['bin', 'txt'];
+ }
+}
diff --git a/Server/vendor/endroid/qr-code/src/Writer/DebugWriter.php b/Server/vendor/endroid/qr-code/src/Writer/DebugWriter.php
new file mode 100755
index 000000000..f779ccf9c
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/Writer/DebugWriter.php
@@ -0,0 +1,58 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode\Writer;
+
+use Endroid\QrCode\QrCodeInterface;
+use ReflectionClass;
+use Exception;
+
+class DebugWriter extends AbstractWriter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function writeString(QrCodeInterface $qrCode)
+ {
+ $data = [];
+
+ $reflectionClass = new ReflectionClass($qrCode);
+ foreach ($reflectionClass->getMethods() as $method) {
+ $methodName = $method->getShortName();
+ if (0 === strpos($methodName, 'get') && 0 == $method->getNumberOfParameters()) {
+ $value = $qrCode->{$methodName}();
+ if (is_array($value) && !is_object(current($value))) {
+ $value = '['.implode(', ', $value).']';
+ } elseif (is_bool($value)) {
+ $value = $value ? 'true' : 'false';
+ } elseif (is_string($value)) {
+ $value = '"'.$value.'"';
+ } elseif (is_null($value)) {
+ $value = 'null';
+ }
+ try {
+ $data[] = $methodName.': '.$value;
+ } catch (Exception $exception) {
+ }
+ }
+ }
+
+ $string = implode(" \n", $data);
+
+ return $string;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getContentType()
+ {
+ return 'text/plain';
+ }
+}
diff --git a/Server/vendor/endroid/qr-code/src/Writer/EpsWriter.php b/Server/vendor/endroid/qr-code/src/Writer/EpsWriter.php
new file mode 100755
index 000000000..2b8b44be4
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/Writer/EpsWriter.php
@@ -0,0 +1,98 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode\Writer;
+
+use BaconQrCode\Renderer\Image\Eps;
+use BaconQrCode\Writer;
+use Endroid\QrCode\QrCodeInterface;
+
+class EpsWriter extends AbstractBaconWriter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function writeString(QrCodeInterface $qrCode)
+ {
+ $renderer = new Eps();
+ $renderer->setWidth($qrCode->getSize());
+ $renderer->setHeight($qrCode->getSize());
+ $renderer->setMargin(0);
+ $renderer->setForegroundColor($this->convertColor($qrCode->getForegroundColor()));
+ $renderer->setBackgroundColor($this->convertColor($qrCode->getBackgroundColor()));
+
+ $writer = new Writer($renderer);
+ $string = $writer->writeString($qrCode->getText(), $qrCode->getEncoding(), $this->convertErrorCorrectionLevel($qrCode->getErrorCorrectionLevel()));
+
+ $string = $this->addMargin($string, $qrCode);
+
+ return $string;
+ }
+
+ /**
+ * @param string $string
+ * @param QrCodeInterface $qrCode
+ *
+ * @return string
+ */
+ protected function addMargin($string, QrCodeInterface $qrCode)
+ {
+ $targetSize = $qrCode->getSize() + $qrCode->getMargin() * 2;
+
+ $lines = explode("\n", $string);
+
+ $sourceBlockSize = 0;
+ $additionalWhitespace = $qrCode->getSize();
+ foreach ($lines as $line) {
+ if (preg_match('#[0-9]+ [0-9]+ [0-9]+ [0-9]+ F#i', $line) && false === strpos($line, $qrCode->getSize().' '.$qrCode->getSize().' F')) {
+ $parts = explode(' ', $line);
+ $sourceBlockSize = $parts[2];
+ $additionalWhitespace = min($additionalWhitespace, $parts[0]);
+ }
+ }
+
+ $blockCount = ($qrCode->getSize() - 2 * $additionalWhitespace) / $sourceBlockSize;
+ $targetBlockSize = $qrCode->getSize() / $blockCount;
+
+ foreach ($lines as &$line) {
+ if (false !== strpos($line, 'BoundingBox')) {
+ $line = '%%BoundingBox: 0 0 '.$targetSize.' '.$targetSize;
+ } elseif (false !== strpos($line, $qrCode->getSize().' '.$qrCode->getSize().' F')) {
+ $line = '0 0 '.$targetSize.' '.$targetSize.' F';
+ } elseif (preg_match('#[0-9]+ [0-9]+ [0-9]+ [0-9]+ F#i', $line)) {
+ $parts = explode(' ', $line);
+ $parts[0] = $qrCode->getMargin() + $targetBlockSize * ($parts[0] - $additionalWhitespace) / $sourceBlockSize;
+ $parts[1] = $qrCode->getMargin() + $targetBlockSize * ($parts[1] - $sourceBlockSize - $additionalWhitespace) / $sourceBlockSize;
+ $parts[2] = $targetBlockSize;
+ $parts[3] = $targetBlockSize;
+ $line = implode(' ', $parts);
+ }
+ }
+
+ $string = implode("\n", $lines);
+
+ return $string;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getContentType()
+ {
+ return 'image/eps';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getSupportedExtensions()
+ {
+ return ['eps'];
+ }
+}
diff --git a/Server/vendor/endroid/qr-code/src/Writer/PngWriter.php b/Server/vendor/endroid/qr-code/src/Writer/PngWriter.php
new file mode 100755
index 000000000..d35656d9f
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/Writer/PngWriter.php
@@ -0,0 +1,228 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode\Writer;
+
+use BaconQrCode\Renderer\Image\Png;
+use BaconQrCode\Writer;
+use Endroid\QrCode\Exception\MissingFunctionException;
+use Endroid\QrCode\Exception\ValidationException;
+use Endroid\QrCode\LabelAlignment;
+use Endroid\QrCode\QrCodeInterface;
+use QrReader;
+
+class PngWriter extends AbstractBaconWriter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function writeString(QrCodeInterface $qrCode)
+ {
+ $renderer = new Png();
+ $renderer->setWidth($qrCode->getSize());
+ $renderer->setHeight($qrCode->getSize());
+ $renderer->setMargin(0);
+ $renderer->setForegroundColor($this->convertColor($qrCode->getForegroundColor()));
+ $renderer->setBackgroundColor($this->convertColor($qrCode->getBackgroundColor()));
+
+ $writer = new Writer($renderer);
+ $string = $writer->writeString($qrCode->getText(), $qrCode->getEncoding(), $this->convertErrorCorrectionLevel($qrCode->getErrorCorrectionLevel()));
+
+ $image = imagecreatefromstring($string);
+ $image = $this->addMargin($image, $qrCode->getMargin(), $qrCode->getSize(), $qrCode->getForegroundColor(), $qrCode->getBackgroundColor());
+
+ if ($qrCode->getLogoPath()) {
+ $image = $this->addLogo($image, $qrCode->getLogoPath(), $qrCode->getLogoWidth());
+ }
+
+ if ($qrCode->getLabel()) {
+ $image = $this->addLabel($image, $qrCode->getLabel(), $qrCode->getLabelFontPath(), $qrCode->getLabelFontSize(), $qrCode->getLabelAlignment(), $qrCode->getLabelMargin(), $qrCode->getForegroundColor(), $qrCode->getBackgroundColor());
+ }
+
+ $string = $this->imageToString($image);
+
+ if ($qrCode->getValidateResult()) {
+ $reader = new QrReader($string, QrReader::SOURCE_TYPE_BLOB);
+ if ($reader->text() !== $qrCode->getText()) {
+ throw new ValidationException(
+ 'Built-in validation reader read "'.$reader->text().'" instead of "'.$qrCode->getText().'".
+ Adjust your parameters to increase readability or disable built-in validation.');
+ }
+ }
+
+ return $string;
+ }
+
+ /**
+ * @param resource $sourceImage
+ * @param int $margin
+ * @param int $size
+ * @param int[] $foregroundColor
+ * @param int[] $backgroundColor
+ *
+ * @return resource
+ */
+ protected function addMargin($sourceImage, $margin, $size, array $foregroundColor, array $backgroundColor)
+ {
+ $additionalWhitespace = $this->calculateAdditionalWhiteSpace($sourceImage, $foregroundColor);
+
+ if (0 == $additionalWhitespace && 0 == $margin) {
+ return $sourceImage;
+ }
+
+ $targetImage = imagecreatetruecolor($size + $margin * 2, $size + $margin * 2);
+ $backgroundColor = imagecolorallocate($targetImage, $backgroundColor['r'], $backgroundColor['g'], $backgroundColor['b']);
+ imagefill($targetImage, 0, 0, $backgroundColor);
+ imagecopyresampled($targetImage, $sourceImage, $margin, $margin, $additionalWhitespace, $additionalWhitespace, $size, $size, $size - 2 * $additionalWhitespace, $size - 2 * $additionalWhitespace);
+
+ return $targetImage;
+ }
+
+ /**
+ * @param resource $image
+ * @param int[] $foregroundColor
+ *
+ * @return int
+ */
+ protected function calculateAdditionalWhiteSpace($image, array $foregroundColor)
+ {
+ $width = imagesx($image);
+ $height = imagesy($image);
+
+ $foregroundColor = imagecolorallocate($image, $foregroundColor['r'], $foregroundColor['g'], $foregroundColor['b']);
+
+ $whitespace = $width;
+ for ($y = 0; $y < $height; ++$y) {
+ for ($x = 0; $x < $width; ++$x) {
+ $color = imagecolorat($image, $x, $y);
+ if ($color == $foregroundColor || $x == $whitespace) {
+ $whitespace = min($whitespace, $x);
+ break;
+ }
+ }
+ }
+
+ return $whitespace;
+ }
+
+ /**
+ * @param resource $sourceImage
+ * @param string $logoPath
+ * @param int $logoWidth
+ *
+ * @return resource
+ */
+ protected function addLogo($sourceImage, $logoPath, $logoWidth = null)
+ {
+ $logoImage = imagecreatefromstring(file_get_contents($logoPath));
+ $logoSourceWidth = imagesx($logoImage);
+ $logoSourceHeight = imagesy($logoImage);
+ $logoTargetWidth = $logoWidth;
+
+ if (null === $logoTargetWidth) {
+ $logoTargetWidth = $logoSourceWidth;
+ $logoTargetHeight = $logoSourceHeight;
+ } else {
+ $scale = $logoTargetWidth / $logoSourceWidth;
+ $logoTargetHeight = intval($scale * imagesy($logoImage));
+ }
+
+ $logoX = imagesx($sourceImage) / 2 - $logoTargetWidth / 2;
+ $logoY = imagesy($sourceImage) / 2 - $logoTargetHeight / 2;
+ imagecopyresampled($sourceImage, $logoImage, $logoX, $logoY, 0, 0, $logoTargetWidth, $logoTargetHeight, $logoSourceWidth, $logoSourceHeight);
+
+ return $sourceImage;
+ }
+
+ /**
+ * @param resource $sourceImage
+ * @param string $label
+ * @param string $labelFontPath
+ * @param int $labelFontSize
+ * @param string $labelAlignment
+ * @param int[] $labelMargin
+ * @param int[] $foregroundColor
+ * @param int[] $backgroundColor
+ *
+ * @return resource
+ *
+ * @throws MissingFunctionException
+ */
+ protected function addLabel($sourceImage, $label, $labelFontPath, $labelFontSize, $labelAlignment, $labelMargin, array $foregroundColor, array $backgroundColor)
+ {
+ if (!function_exists('imagettfbbox')) {
+ throw new MissingFunctionException('Missing function "imagettfbbox". Did you install the FreeType library?');
+ }
+
+ $labelBox = imagettfbbox($labelFontSize, 0, $labelFontPath, $label);
+ $labelBoxWidth = intval($labelBox[2] - $labelBox[0]);
+ $labelBoxHeight = intval($labelBox[0] - $labelBox[7]);
+
+ $sourceWidth = imagesx($sourceImage);
+ $sourceHeight = imagesy($sourceImage);
+ $targetWidth = $sourceWidth;
+ $targetHeight = $sourceHeight + $labelBoxHeight + $labelMargin['t'] + $labelMargin['b'];
+
+ // Create empty target image
+ $targetImage = imagecreatetruecolor($targetWidth, $targetHeight);
+ $foregroundColor = imagecolorallocate($targetImage, $foregroundColor['r'], $foregroundColor['g'], $foregroundColor['b']);
+ $backgroundColor = imagecolorallocate($targetImage, $backgroundColor['r'], $backgroundColor['g'], $backgroundColor['b']);
+ imagefill($targetImage, 0, 0, $backgroundColor);
+
+ // Copy source image to target image
+ imagecopyresampled($targetImage, $sourceImage, 0, 0, 0, 0, $sourceWidth, $sourceHeight, $sourceWidth, $sourceHeight);
+
+ switch ($labelAlignment) {
+ case LabelAlignment::LEFT:
+ $labelX = $labelMargin['l'];
+ break;
+ case LabelAlignment::RIGHT:
+ $labelX = $targetWidth - $labelBoxWidth - $labelMargin['r'];
+ break;
+ default:
+ $labelX = intval($targetWidth / 2 - $labelBoxWidth / 2);
+ break;
+ }
+
+ $labelY = $targetHeight - $labelMargin['b'];
+ imagettftext($targetImage, $labelFontSize, 0, $labelX, $labelY, $foregroundColor, $labelFontPath, $label);
+
+ return $targetImage;
+ }
+
+ /**
+ * @param resource $image
+ *
+ * @return string
+ */
+ protected function imageToString($image)
+ {
+ ob_start();
+ imagepng($image);
+ $string = ob_get_clean();
+
+ return $string;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getContentType()
+ {
+ return 'image/png';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getSupportedExtensions()
+ {
+ return ['png'];
+ }
+}
diff --git a/Server/vendor/endroid/qr-code/src/Writer/SvgWriter.php b/Server/vendor/endroid/qr-code/src/Writer/SvgWriter.php
new file mode 100755
index 000000000..204d34f67
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/Writer/SvgWriter.php
@@ -0,0 +1,92 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode\Writer;
+
+use BaconQrCode\Renderer\Image\Svg;
+use BaconQrCode\Writer;
+use Endroid\QrCode\QrCodeInterface;
+use SimpleXMLElement;
+
+class SvgWriter extends AbstractBaconWriter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function writeString(QrCodeInterface $qrCode)
+ {
+ $renderer = new Svg();
+ $renderer->setWidth($qrCode->getSize());
+ $renderer->setHeight($qrCode->getSize());
+ $renderer->setMargin(0);
+ $renderer->setForegroundColor($this->convertColor($qrCode->getForegroundColor()));
+ $renderer->setBackgroundColor($this->convertColor($qrCode->getBackgroundColor()));
+
+ $writer = new Writer($renderer);
+ $string = $writer->writeString($qrCode->getText(), $qrCode->getEncoding(), $this->convertErrorCorrectionLevel($qrCode->getErrorCorrectionLevel()));
+
+ $string = $this->addMargin($string, $qrCode->getMargin(), $qrCode->getSize());
+
+ return $string;
+ }
+
+ /**
+ * @param string $string
+ * @param int $margin
+ * @param int $size
+ *
+ * @return string
+ */
+ protected function addMargin($string, $margin, $size)
+ {
+ $targetSize = $size + $margin * 2;
+
+ $xml = new SimpleXMLElement($string);
+ $xml['width'] = $targetSize;
+ $xml['height'] = $targetSize;
+ $xml['viewBox'] = '0 0 '.$targetSize.' '.$targetSize;
+ $xml->rect['width'] = $targetSize;
+ $xml->rect['height'] = $targetSize;
+
+ $additionalWhitespace = $targetSize;
+ foreach ($xml->use as $block) {
+ $additionalWhitespace = min($additionalWhitespace, (int) $block['x']);
+ }
+
+ $sourceBlockSize = (int) $xml->defs->rect['width'];
+ $blockCount = ($size - 2 * $additionalWhitespace) / $sourceBlockSize;
+ $targetBlockSize = $size / $blockCount;
+
+ $xml->defs->rect['width'] = $targetBlockSize;
+ $xml->defs->rect['height'] = $targetBlockSize;
+
+ foreach ($xml->use as $block) {
+ $block['x'] = $margin + $targetBlockSize * ($block['x'] - $additionalWhitespace) / $sourceBlockSize;
+ $block['y'] = $margin + $targetBlockSize * ($block['y'] - $additionalWhitespace) / $sourceBlockSize;
+ }
+
+ return $xml->asXML();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getContentType()
+ {
+ return 'image/svg+xml';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getSupportedExtensions()
+ {
+ return ['svg'];
+ }
+}
diff --git a/Server/vendor/endroid/qr-code/src/Writer/WriterInterface.php b/Server/vendor/endroid/qr-code/src/Writer/WriterInterface.php
new file mode 100755
index 000000000..53954126b
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/Writer/WriterInterface.php
@@ -0,0 +1,57 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode\Writer;
+
+use Endroid\QrCode\QrCodeInterface;
+
+interface WriterInterface
+{
+ /**
+ * @param QrCodeInterface $qrCode
+ *
+ * @return string
+ */
+ public function writeString(QrCodeInterface $qrCode);
+
+ /**
+ * @param QrCodeInterface $qrCode
+ *
+ * @return string
+ */
+ public function writeDataUri(QrCodeInterface $qrCode);
+
+ /**
+ * @param QrCodeInterface $qrCode
+ * @param string $path
+ */
+ public function writeFile(QrCodeInterface $qrCode, $path);
+
+ /**
+ * @return string
+ */
+ public static function getContentType();
+
+ /**
+ * @param string $extension
+ *
+ * @return bool
+ */
+ public static function supportsExtension($extension);
+
+ /**
+ * @return string[]
+ */
+ public static function getSupportedExtensions();
+
+ /**
+ * @return string
+ */
+ public function getName();
+}
diff --git a/Server/vendor/endroid/qr-code/src/WriterRegistry.php b/Server/vendor/endroid/qr-code/src/WriterRegistry.php
new file mode 100755
index 000000000..c346fe5e9
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/WriterRegistry.php
@@ -0,0 +1,89 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode;
+
+use Endroid\QrCode\Exception\InvalidWriterException;
+use Endroid\QrCode\Writer\WriterInterface;
+
+class WriterRegistry implements WriterRegistryInterface
+{
+ /**
+ * @var WriterInterface[]
+ */
+ protected $writers;
+
+ /**
+ * @var WriterInterface
+ */
+ protected $defaultWriter;
+
+ public function __construct()
+ {
+ $this->writers = [];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addWriter(WriterInterface $writer, $setAsDefault = false)
+ {
+ $this->writers[$writer->getName()] = $writer;
+
+ if ($setAsDefault || 1 === count($this->writers)) {
+ $this->defaultWriter = $writer;
+ }
+ }
+
+ /**
+ * @param $name
+ *
+ * @return WriterInterface
+ */
+ public function getWriter($name)
+ {
+ $this->assertValidWriter($name);
+
+ return $this->writers[$name];
+ }
+
+ /**
+ * @return WriterInterface
+ *
+ * @throws InvalidWriterException
+ */
+ public function getDefaultWriter()
+ {
+ if ($this->defaultWriter instanceof WriterInterface) {
+ return $this->defaultWriter;
+ }
+
+ throw new InvalidWriterException('Please set the default writer via the second argument of addWriter');
+ }
+
+ /**
+ * @return WriterInterface[]
+ */
+ public function getWriters()
+ {
+ return $this->writers;
+ }
+
+ /**
+ * @param string $writer
+ *
+ * @throws InvalidWriterException
+ */
+ protected function assertValidWriter($writer)
+ {
+ if (!isset($this->writers[$writer])) {
+ throw new InvalidWriterException('Invalid writer "'.$writer.'"');
+ }
+ }
+}
diff --git a/Server/vendor/endroid/qr-code/src/WriterRegistryInterface.php b/Server/vendor/endroid/qr-code/src/WriterRegistryInterface.php
new file mode 100755
index 000000000..d172ecade
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/src/WriterRegistryInterface.php
@@ -0,0 +1,34 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode;
+
+use Endroid\QrCode\Writer\WriterInterface;
+
+interface WriterRegistryInterface
+{
+ /**
+ * @param WriterInterface $writer
+ *
+ * @return $this
+ */
+ public function addWriter(WriterInterface $writer);
+
+ /**
+ * @param $name
+ *
+ * @return WriterInterface
+ */
+ public function getWriter($name);
+
+ /**
+ * @return WriterInterface[]
+ */
+ public function getWriters();
+}
diff --git a/Server/vendor/endroid/qr-code/tests/Bundle/Controller/QrCodeControllerTest.php b/Server/vendor/endroid/qr-code/tests/Bundle/Controller/QrCodeControllerTest.php
new file mode 100755
index 000000000..4a591d870
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/tests/Bundle/Controller/QrCodeControllerTest.php
@@ -0,0 +1,45 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode\Tests\Bundle\Controller;
+
+use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
+use Symfony\Component\HttpFoundation\Response;
+
+class QrCodeControllerTest extends WebTestCase
+{
+ public function testGenerateAction()
+ {
+ $client = static::createClient();
+ $client->request('GET', $client->getContainer()->get('router')->generate('endroid_qrcode_generate', [
+ 'text' => 'Life is too short to be generating QR codes',
+ 'extension' => 'png',
+ 'size' => 200,
+ 'margin' => 10,
+ 'label' => 'Scan the code',
+ 'label_font_size' => 16,
+ ]));
+
+ $response = $client->getResponse();
+ $image = imagecreatefromstring($response->getContent());
+
+ $this->assertTrue(220 == imagesx($image));
+ $this->assertEquals(Response::HTTP_OK, $response->getStatusCode());
+ }
+
+ public function testTwigFunctionsAction()
+ {
+ $client = static::createClient();
+ $client->request('GET', $client->getContainer()->get('router')->generate('endroid_qrcode_twig_functions'));
+
+ $response = $client->getResponse();
+
+ $this->assertEquals(Response::HTTP_OK, $response->getStatusCode());
+ }
+}
diff --git a/Server/vendor/endroid/qr-code/tests/Bundle/EndroidQrCodeBundleTest.php b/Server/vendor/endroid/qr-code/tests/Bundle/EndroidQrCodeBundleTest.php
new file mode 100755
index 000000000..f0a154407
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/tests/Bundle/EndroidQrCodeBundleTest.php
@@ -0,0 +1,20 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode\Tests\Bundle;
+
+use PHPUnit\Framework\TestCase;
+
+class EndroidQrCodeBundleTest extends TestCase
+{
+ public function testNoTestsYet()
+ {
+ $this->assertTrue(true);
+ }
+}
diff --git a/Server/vendor/endroid/qr-code/tests/Bundle/app/.gitignore b/Server/vendor/endroid/qr-code/tests/Bundle/app/.gitignore
new file mode 100755
index 000000000..6dd26c5b0
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/tests/Bundle/app/.gitignore
@@ -0,0 +1,2 @@
+/cache
+/logs
diff --git a/Server/vendor/endroid/qr-code/tests/Bundle/app/AppKernel.php b/Server/vendor/endroid/qr-code/tests/Bundle/app/AppKernel.php
new file mode 100755
index 000000000..d30b3de32
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/tests/Bundle/app/AppKernel.php
@@ -0,0 +1,36 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+use Symfony\Component\Config\Loader\LoaderInterface;
+use Symfony\Component\HttpKernel\Kernel;
+
+class AppKernel extends Kernel
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function registerBundles()
+ {
+ $bundles = [
+ new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
+ new Symfony\Bundle\TwigBundle\TwigBundle(),
+ new Endroid\QrCode\Bundle\QrCodeBundle\EndroidQrCodeBundle(),
+ ];
+
+ return $bundles;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function registerContainerConfiguration(LoaderInterface $loader)
+ {
+ $loader->load(__DIR__.'/config/config.yml');
+ }
+}
diff --git a/Server/vendor/endroid/qr-code/tests/Bundle/app/bootstrap.php b/Server/vendor/endroid/qr-code/tests/Bundle/app/bootstrap.php
new file mode 100755
index 000000000..15c731c8e
--- /dev/null
+++ b/Server/vendor/endroid/qr-code/tests/Bundle/app/bootstrap.php
@@ -0,0 +1,3 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Endroid\QrCode\Tests;
+
+use Endroid\QrCode\Factory\QrCodeFactory;
+use Endroid\QrCode\QrCode;
+use PHPUnit\Framework\TestCase;
+
+class QrCodeTest extends TestCase
+{
+ public function testReadable()
+ {
+ $messages = [
+ 'Tiny',
+ 'This one has spaces',
+ 'd2llMS9uU01BVmlvalM2YU9BUFBPTTdQMmJabHpqdndt',
+ 'http://this.is.an/url?with=query&string=attached',
+ '11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111',
+ '{"i":"serialized.data","v":1,"t":1,"d":"4AEPc9XuIQ0OjsZoSRWp9DRWlN6UyDvuMlyOYy8XjOw="}',
+ 'Spëci&al ch@ract3rs',
+ '有限公司',
+ ];
+
+ foreach ($messages as $message) {
+ $qrCode = new QrCode($message);
+ $qrCode->setSize(300);
+ $qrCode->setValidateResult(true);
+ $pngData = $qrCode->writeString();
+ $this->assertTrue(is_string($pngData));
+ }
+ }
+
+ public function testFactory()
+ {
+ $qrCodeFactory = new QrCodeFactory();
+ $qrCode = $qrCodeFactory->create('QR Code', [
+ 'writer' => 'png',
+ 'size' => 300,
+ 'margin' => 10,
+ ]);
+
+ $pngData = $qrCode->writeString();
+ $this->assertTrue(is_string($pngData));
+ }
+
+ public function testWriteQrCode()
+ {
+ $qrCode = new QrCode('QrCode');
+
+ $qrCode->setWriterByName('binary');
+ $binData = $qrCode->writeString();
+ $this->assertTrue(is_string($binData));
+
+ $qrCode->setWriterByName('debug');
+ $debugData = $qrCode->writeString();
+ $this->assertTrue(is_string($debugData));
+
+ $qrCode->setWriterByName('eps');
+ $epsData = $qrCode->writeString();
+ $this->assertTrue(is_string($epsData));
+
+ $qrCode->setWriterByName('png');
+ $pngData = $qrCode->writeString();
+ $this->assertTrue(is_string($pngData));
+ $pngDataUriData = $qrCode->writeDataUri();
+ $this->assertTrue(0 === strpos($pngDataUriData, 'data:image/png;base64'));
+
+ $qrCode->setWriterByName('svg');
+ $svgData = $qrCode->writeString();
+ $this->assertTrue(is_string($svgData));
+ $svgDataUriData = $qrCode->writeDataUri();
+ $this->assertTrue(0 === strpos($svgDataUriData, 'data:image/svg+xml;base64'));
+ }
+
+ public function testSetSize()
+ {
+ $size = 400;
+ $margin = 10;
+
+ $qrCode = new QrCode('QrCode');
+ $qrCode->setSize($size);
+ $qrCode->setMargin($margin);
+
+ $pngData = $qrCode->writeString();
+ $image = imagecreatefromstring($pngData);
+
+ $this->assertTrue(imagesx($image) === $size + 2 * $margin);
+ $this->assertTrue(imagesy($image) === $size + 2 * $margin);
+ }
+
+ public function testSetLabel()
+ {
+ $qrCode = new QrCode('QrCode');
+ $qrCode
+ ->setSize(300)
+ ->setLabel('Scan the code', 15)
+ ;
+
+ $pngData = $qrCode->writeString();
+ $this->assertTrue(is_string($pngData));
+ }
+
+ public function testSetLogo()
+ {
+ $qrCode = new QrCode('QrCode');
+ $qrCode
+ ->setSize(400)
+ ->setLogoPath(__DIR__.'/../assets/symfony.png')
+ ->setLogoWidth(150)
+ ->setValidateResult(true);
+
+ $pngData = $qrCode->writeString();
+ $this->assertTrue(is_string($pngData));
+ }
+}
diff --git a/Server/vendor/guzzlehttp/guzzle/.php_cs b/Server/vendor/guzzlehttp/guzzle/.php_cs
new file mode 100755
index 000000000..2dd5036c1
--- /dev/null
+++ b/Server/vendor/guzzlehttp/guzzle/.php_cs
@@ -0,0 +1,23 @@
+setRiskyAllowed(true)
+ ->setRules([
+ '@PSR2' => true,
+ 'array_syntax' => ['syntax' => 'short'],
+ 'declare_strict_types' => false,
+ 'concat_space' => ['spacing'=>'one'],
+ 'php_unit_test_case_static_method_calls' => ['call_type' => 'self'],
+ 'ordered_imports' => true,
+ // 'phpdoc_align' => ['align'=>'vertical'],
+ // 'native_function_invocation' => true,
+ ])
+ ->setFinder(
+ PhpCsFixer\Finder::create()
+ ->in(__DIR__.'/src')
+ ->in(__DIR__.'/tests')
+ ->name('*.php')
+ )
+;
+
+return $config;
diff --git a/Server/vendor/guzzlehttp/guzzle/CHANGELOG.md b/Server/vendor/guzzlehttp/guzzle/CHANGELOG.md
new file mode 100755
index 000000000..b053017a9
--- /dev/null
+++ b/Server/vendor/guzzlehttp/guzzle/CHANGELOG.md
@@ -0,0 +1,1352 @@
+# Change Log
+
+## 6.5.8 - 2022-06-20
+
+* Fix change in port should be considered a change in origin
+* Fix `CURLOPT_HTTPAUTH` option not cleared on change of origin
+
+## 6.5.7 - 2022-06-09
+
+* Fix failure to strip Authorization header on HTTP downgrade
+* Fix failure to strip the Cookie header on change in host or HTTP downgrade
+
+## 6.5.6 - 2022-05-25
+
+* Fix cross-domain cookie leakage
+
+## 6.5.5 - 2020-06-16
+
+* Unpin version constraint for `symfony/polyfill-intl-idn` [#2678](https://github.com/guzzle/guzzle/pull/2678)
+
+## 6.5.4 - 2020-05-25
+
+* Fix various intl icu issues [#2626](https://github.com/guzzle/guzzle/pull/2626)
+
+## 6.5.3 - 2020-04-18
+
+* Use Symfony intl-idn polyfill [#2550](https://github.com/guzzle/guzzle/pull/2550)
+* Remove use of internal functions [#2548](https://github.com/guzzle/guzzle/pull/2548)
+
+## 6.5.2 - 2019-12-23
+
+* idn_to_ascii() fix for old PHP versions [#2489](https://github.com/guzzle/guzzle/pull/2489)
+
+## 6.5.1 - 2019-12-21
+
+* Better defaults for PHP installations with old ICU lib [#2454](https://github.com/guzzle/guzzle/pull/2454)
+* IDN support for redirects [#2424](https://github.com/guzzle/guzzle/pull/2424)
+
+## 6.5.0 - 2019-12-07
+
+* Improvement: Added support for reset internal queue in MockHandler. [#2143](https://github.com/guzzle/guzzle/pull/2143)
+* Improvement: Added support to pass arbitrary options to `curl_multi_init`. [#2287](https://github.com/guzzle/guzzle/pull/2287)
+* Fix: Gracefully handle passing `null` to the `header` option. [#2132](https://github.com/guzzle/guzzle/pull/2132)
+* Fix: `RetryMiddleware` did not do exponential delay between retries due unit mismatch. [#2132](https://github.com/guzzle/guzzle/pull/2132)
+ Previously, `RetryMiddleware` would sleep for 1 millisecond, then 2 milliseconds, then 4 milliseconds.
+ **After this change, `RetryMiddleware` will sleep for 1 second, then 2 seconds, then 4 seconds.**
+ `Middleware::retry()` accepts a second callback parameter to override the default timeouts if needed.
+* Fix: Prevent undefined offset when using array for ssl_key options. [#2348](https://github.com/guzzle/guzzle/pull/2348)
+* Deprecated `ClientInterface::VERSION`
+
+## 6.4.1 - 2019-10-23
+
+* No `guzzle.phar` was created in 6.4.0 due expired API token. This release will fix that
+* Added `parent::__construct()` to `FileCookieJar` and `SessionCookieJar`
+
+## 6.4.0 - 2019-10-23
+
+* Improvement: Improved error messages when using curl < 7.21.2 [#2108](https://github.com/guzzle/guzzle/pull/2108)
+* Fix: Test if response is readable before returning a summary in `RequestException::getResponseBodySummary()` [#2081](https://github.com/guzzle/guzzle/pull/2081)
+* Fix: Add support for GUZZLE_CURL_SELECT_TIMEOUT environment variable [#2161](https://github.com/guzzle/guzzle/pull/2161)
+* Improvement: Added `GuzzleHttp\Exception\InvalidArgumentException` [#2163](https://github.com/guzzle/guzzle/pull/2163)
+* Improvement: Added `GuzzleHttp\_current_time()` to use `hrtime()` if that function exists. [#2242](https://github.com/guzzle/guzzle/pull/2242)
+* Improvement: Added curl's `appconnect_time` in `TransferStats` [#2284](https://github.com/guzzle/guzzle/pull/2284)
+* Improvement: Make GuzzleException extend Throwable wherever it's available [#2273](https://github.com/guzzle/guzzle/pull/2273)
+* Fix: Prevent concurrent writes to file when saving `CookieJar` [#2335](https://github.com/guzzle/guzzle/pull/2335)
+* Improvement: Update `MockHandler` so we can test transfer time [#2362](https://github.com/guzzle/guzzle/pull/2362)
+
+## 6.3.3 - 2018-04-22
+
+* Fix: Default headers when decode_content is specified
+
+
+## 6.3.2 - 2018-03-26
+
+* Fix: Release process
+
+
+## 6.3.1 - 2018-03-26
+
+* Bug fix: Parsing 0 epoch expiry times in cookies [#2014](https://github.com/guzzle/guzzle/pull/2014)
+* Improvement: Better ConnectException detection [#2012](https://github.com/guzzle/guzzle/pull/2012)
+* Bug fix: Malformed domain that contains a "/" [#1999](https://github.com/guzzle/guzzle/pull/1999)
+* Bug fix: Undefined offset when a cookie has no first key-value pair [#1998](https://github.com/guzzle/guzzle/pull/1998)
+* Improvement: Support PHPUnit 6 [#1953](https://github.com/guzzle/guzzle/pull/1953)
+* Bug fix: Support empty headers [#1915](https://github.com/guzzle/guzzle/pull/1915)
+* Bug fix: Ignore case during header modifications [#1916](https://github.com/guzzle/guzzle/pull/1916)
+
++ Minor code cleanups, documentation fixes and clarifications.
+
+
+## 6.3.0 - 2017-06-22
+
+* Feature: force IP resolution (ipv4 or ipv6) [#1608](https://github.com/guzzle/guzzle/pull/1608), [#1659](https://github.com/guzzle/guzzle/pull/1659)
+* Improvement: Don't include summary in exception message when body is empty [#1621](https://github.com/guzzle/guzzle/pull/1621)
+* Improvement: Handle `on_headers` option in MockHandler [#1580](https://github.com/guzzle/guzzle/pull/1580)
+* Improvement: Added SUSE Linux CA path [#1609](https://github.com/guzzle/guzzle/issues/1609)
+* Improvement: Use class reference for getting the name of the class instead of using hardcoded strings [#1641](https://github.com/guzzle/guzzle/pull/1641)
+* Feature: Added `read_timeout` option [#1611](https://github.com/guzzle/guzzle/pull/1611)
+* Bug fix: PHP 7.x fixes [#1685](https://github.com/guzzle/guzzle/pull/1685), [#1686](https://github.com/guzzle/guzzle/pull/1686), [#1811](https://github.com/guzzle/guzzle/pull/1811)
+* Deprecation: BadResponseException instantiation without a response [#1642](https://github.com/guzzle/guzzle/pull/1642)
+* Feature: Added NTLM auth [#1569](https://github.com/guzzle/guzzle/pull/1569)
+* Feature: Track redirect HTTP status codes [#1711](https://github.com/guzzle/guzzle/pull/1711)
+* Improvement: Check handler type during construction [#1745](https://github.com/guzzle/guzzle/pull/1745)
+* Improvement: Always include the Content-Length if there's a body [#1721](https://github.com/guzzle/guzzle/pull/1721)
+* Feature: Added convenience method to access a cookie by name [#1318](https://github.com/guzzle/guzzle/pull/1318)
+* Bug fix: Fill `CURLOPT_CAPATH` and `CURLOPT_CAINFO` properly [#1684](https://github.com/guzzle/guzzle/pull/1684)
+* Improvement: Use `\GuzzleHttp\Promise\rejection_for` function instead of object init [#1827](https://github.com/guzzle/guzzle/pull/1827)
+
+
++ Minor code cleanups, documentation fixes and clarifications.
+
+## 6.2.3 - 2017-02-28
+
+* Fix deprecations with guzzle/psr7 version 1.4
+
+## 6.2.2 - 2016-10-08
+
+* Allow to pass nullable Response to delay callable
+* Only add scheme when host is present
+* Fix drain case where content-length is the literal string zero
+* Obfuscate in-URL credentials in exceptions
+
+## 6.2.1 - 2016-07-18
+
+* Address HTTP_PROXY security vulnerability, CVE-2016-5385:
+ https://httpoxy.org/
+* Fixing timeout bug with StreamHandler:
+ https://github.com/guzzle/guzzle/pull/1488
+* Only read up to `Content-Length` in PHP StreamHandler to avoid timeouts when
+ a server does not honor `Connection: close`.
+* Ignore URI fragment when sending requests.
+
+## 6.2.0 - 2016-03-21
+
+* Feature: added `GuzzleHttp\json_encode` and `GuzzleHttp\json_decode`.
+ https://github.com/guzzle/guzzle/pull/1389
+* Bug fix: Fix sleep calculation when waiting for delayed requests.
+ https://github.com/guzzle/guzzle/pull/1324
+* Feature: More flexible history containers.
+ https://github.com/guzzle/guzzle/pull/1373
+* Bug fix: defer sink stream opening in StreamHandler.
+ https://github.com/guzzle/guzzle/pull/1377
+* Bug fix: do not attempt to escape cookie values.
+ https://github.com/guzzle/guzzle/pull/1406
+* Feature: report original content encoding and length on decoded responses.
+ https://github.com/guzzle/guzzle/pull/1409
+* Bug fix: rewind seekable request bodies before dispatching to cURL.
+ https://github.com/guzzle/guzzle/pull/1422
+* Bug fix: provide an empty string to `http_build_query` for HHVM workaround.
+ https://github.com/guzzle/guzzle/pull/1367
+
+## 6.1.1 - 2015-11-22
+
+* Bug fix: Proxy::wrapSync() now correctly proxies to the appropriate handler
+ https://github.com/guzzle/guzzle/commit/911bcbc8b434adce64e223a6d1d14e9a8f63e4e4
+* Feature: HandlerStack is now more generic.
+ https://github.com/guzzle/guzzle/commit/f2102941331cda544745eedd97fc8fd46e1ee33e
+* Bug fix: setting verify to false in the StreamHandler now disables peer
+ verification. https://github.com/guzzle/guzzle/issues/1256
+* Feature: Middleware now uses an exception factory, including more error
+ context. https://github.com/guzzle/guzzle/pull/1282
+* Feature: better support for disabled functions.
+ https://github.com/guzzle/guzzle/pull/1287
+* Bug fix: fixed regression where MockHandler was not using `sink`.
+ https://github.com/guzzle/guzzle/pull/1292
+
+## 6.1.0 - 2015-09-08
+
+* Feature: Added the `on_stats` request option to provide access to transfer
+ statistics for requests. https://github.com/guzzle/guzzle/pull/1202
+* Feature: Added the ability to persist session cookies in CookieJars.
+ https://github.com/guzzle/guzzle/pull/1195
+* Feature: Some compatibility updates for Google APP Engine
+ https://github.com/guzzle/guzzle/pull/1216
+* Feature: Added support for NO_PROXY to prevent the use of a proxy based on
+ a simple set of rules. https://github.com/guzzle/guzzle/pull/1197
+* Feature: Cookies can now contain square brackets.
+ https://github.com/guzzle/guzzle/pull/1237
+* Bug fix: Now correctly parsing `=` inside of quotes in Cookies.
+ https://github.com/guzzle/guzzle/pull/1232
+* Bug fix: Cusotm cURL options now correctly override curl options of the
+ same name. https://github.com/guzzle/guzzle/pull/1221
+* Bug fix: Content-Type header is now added when using an explicitly provided
+ multipart body. https://github.com/guzzle/guzzle/pull/1218
+* Bug fix: Now ignoring Set-Cookie headers that have no name.
+* Bug fix: Reason phrase is no longer cast to an int in some cases in the
+ cURL handler. https://github.com/guzzle/guzzle/pull/1187
+* Bug fix: Remove the Authorization header when redirecting if the Host
+ header changes. https://github.com/guzzle/guzzle/pull/1207
+* Bug fix: Cookie path matching fixes
+ https://github.com/guzzle/guzzle/issues/1129
+* Bug fix: Fixing the cURL `body_as_string` setting
+ https://github.com/guzzle/guzzle/pull/1201
+* Bug fix: quotes are no longer stripped when parsing cookies.
+ https://github.com/guzzle/guzzle/issues/1172
+* Bug fix: `form_params` and `query` now always uses the `&` separator.
+ https://github.com/guzzle/guzzle/pull/1163
+* Bug fix: Adding a Content-Length to PHP stream wrapper requests if not set.
+ https://github.com/guzzle/guzzle/pull/1189
+
+## 6.0.2 - 2015-07-04
+
+* Fixed a memory leak in the curl handlers in which references to callbacks
+ were not being removed by `curl_reset`.
+* Cookies are now extracted properly before redirects.
+* Cookies now allow more character ranges.
+* Decoded Content-Encoding responses are now modified to correctly reflect
+ their state if the encoding was automatically removed by a handler. This
+ means that the `Content-Encoding` header may be removed an the
+ `Content-Length` modified to reflect the message size after removing the
+ encoding.
+* Added a more explicit error message when trying to use `form_params` and
+ `multipart` in the same request.
+* Several fixes for HHVM support.
+* Functions are now conditionally required using an additional level of
+ indirection to help with global Composer installations.
+
+## 6.0.1 - 2015-05-27
+
+* Fixed a bug with serializing the `query` request option where the `&`
+ separator was missing.
+* Added a better error message for when `body` is provided as an array. Please
+ use `form_params` or `multipart` instead.
+* Various doc fixes.
+
+## 6.0.0 - 2015-05-26
+
+* See the UPGRADING.md document for more information.
+* Added `multipart` and `form_params` request options.
+* Added `synchronous` request option.
+* Added the `on_headers` request option.
+* Fixed `expect` handling.
+* No longer adding default middlewares in the client ctor. These need to be
+ present on the provided handler in order to work.
+* Requests are no longer initiated when sending async requests with the
+ CurlMultiHandler. This prevents unexpected recursion from requests completing
+ while ticking the cURL loop.
+* Removed the semantics of setting `default` to `true`. This is no longer
+ required now that the cURL loop is not ticked for async requests.
+* Added request and response logging middleware.
+* No longer allowing self signed certificates when using the StreamHandler.
+* Ensuring that `sink` is valid if saving to a file.
+* Request exceptions now include a "handler context" which provides handler
+ specific contextual information.
+* Added `GuzzleHttp\RequestOptions` to allow request options to be applied
+ using constants.
+* `$maxHandles` has been removed from CurlMultiHandler.
+* `MultipartPostBody` is now part of the `guzzlehttp/psr7` package.
+
+## 5.3.0 - 2015-05-19
+
+* Mock now supports `save_to`
+* Marked `AbstractRequestEvent::getTransaction()` as public.
+* Fixed a bug in which multiple headers using different casing would overwrite
+ previous headers in the associative array.
+* Added `Utils::getDefaultHandler()`
+* Marked `GuzzleHttp\Client::getDefaultUserAgent` as deprecated.
+* URL scheme is now always lowercased.
+
+## 6.0.0-beta.1
+
+* Requires PHP >= 5.5
+* Updated to use PSR-7
+ * Requires immutable messages, which basically means an event based system
+ owned by a request instance is no longer possible.
+ * Utilizing the [Guzzle PSR-7 package](https://github.com/guzzle/psr7).
+ * Removed the dependency on `guzzlehttp/streams`. These stream abstractions
+ are available in the `guzzlehttp/psr7` package under the `GuzzleHttp\Psr7`
+ namespace.
+* Added middleware and handler system
+ * Replaced the Guzzle event and subscriber system with a middleware system.
+ * No longer depends on RingPHP, but rather places the HTTP handlers directly
+ in Guzzle, operating on PSR-7 messages.
+ * Retry logic is now encapsulated in `GuzzleHttp\Middleware::retry`, which
+ means the `guzzlehttp/retry-subscriber` is now obsolete.
+ * Mocking responses is now handled using `GuzzleHttp\Handler\MockHandler`.
+* Asynchronous responses
+ * No longer supports the `future` request option to send an async request.
+ Instead, use one of the `*Async` methods of a client (e.g., `requestAsync`,
+ `getAsync`, etc.).
+ * Utilizing `GuzzleHttp\Promise` instead of React's promise library to avoid
+ recursion required by chaining and forwarding react promises. See
+ https://github.com/guzzle/promises
+ * Added `requestAsync` and `sendAsync` to send request asynchronously.
+ * Added magic methods for `getAsync()`, `postAsync()`, etc. to send requests
+ asynchronously.
+* Request options
+ * POST and form updates
+ * Added the `form_fields` and `form_files` request options.
+ * Removed the `GuzzleHttp\Post` namespace.
+ * The `body` request option no longer accepts an array for POST requests.
+ * The `exceptions` request option has been deprecated in favor of the
+ `http_errors` request options.
+ * The `save_to` request option has been deprecated in favor of `sink` request
+ option.
+* Clients no longer accept an array of URI template string and variables for
+ URI variables. You will need to expand URI templates before passing them
+ into a client constructor or request method.
+* Client methods `get()`, `post()`, `put()`, `patch()`, `options()`, etc. are
+ now magic methods that will send synchronous requests.
+* Replaced `Utils.php` with plain functions in `functions.php`.
+* Removed `GuzzleHttp\Collection`.
+* Removed `GuzzleHttp\BatchResults`. Batched pool results are now returned as
+ an array.
+* Removed `GuzzleHttp\Query`. Query string handling is now handled using an
+ associative array passed into the `query` request option. The query string
+ is serialized using PHP's `http_build_query`. If you need more control, you
+ can pass the query string in as a string.
+* `GuzzleHttp\QueryParser` has been replaced with the
+ `GuzzleHttp\Psr7\parse_query`.
+
+## 5.2.0 - 2015-01-27
+
+* Added `AppliesHeadersInterface` to make applying headers to a request based
+ on the body more generic and not specific to `PostBodyInterface`.
+* Reduced the number of stack frames needed to send requests.
+* Nested futures are now resolved in the client rather than the RequestFsm
+* Finishing state transitions is now handled in the RequestFsm rather than the
+ RingBridge.
+* Added a guard in the Pool class to not use recursion for request retries.
+
+## 5.1.0 - 2014-12-19
+
+* Pool class no longer uses recursion when a request is intercepted.
+* The size of a Pool can now be dynamically adjusted using a callback.
+ See https://github.com/guzzle/guzzle/pull/943.
+* Setting a request option to `null` when creating a request with a client will
+ ensure that the option is not set. This allows you to overwrite default
+ request options on a per-request basis.
+ See https://github.com/guzzle/guzzle/pull/937.
+* Added the ability to limit which protocols are allowed for redirects by
+ specifying a `protocols` array in the `allow_redirects` request option.
+* Nested futures due to retries are now resolved when waiting for synchronous
+ responses. See https://github.com/guzzle/guzzle/pull/947.
+* `"0"` is now an allowed URI path. See
+ https://github.com/guzzle/guzzle/pull/935.
+* `Query` no longer typehints on the `$query` argument in the constructor,
+ allowing for strings and arrays.
+* Exceptions thrown in the `end` event are now correctly wrapped with Guzzle
+ specific exceptions if necessary.
+
+## 5.0.3 - 2014-11-03
+
+This change updates query strings so that they are treated as un-encoded values
+by default where the value represents an un-encoded value to send over the
+wire. A Query object then encodes the value before sending over the wire. This
+means that even value query string values (e.g., ":") are url encoded. This
+makes the Query class match PHP's http_build_query function. However, if you
+want to send requests over the wire using valid query string characters that do
+not need to be encoded, then you can provide a string to Url::setQuery() and
+pass true as the second argument to specify that the query string is a raw
+string that should not be parsed or encoded (unless a call to getQuery() is
+subsequently made, forcing the query-string to be converted into a Query
+object).
+
+## 5.0.2 - 2014-10-30
+
+* Added a trailing `\r\n` to multipart/form-data payloads. See
+ https://github.com/guzzle/guzzle/pull/871
+* Added a `GuzzleHttp\Pool::send()` convenience method to match the docs.
+* Status codes are now returned as integers. See
+ https://github.com/guzzle/guzzle/issues/881
+* No longer overwriting an existing `application/x-www-form-urlencoded` header
+ when sending POST requests, allowing for customized headers. See
+ https://github.com/guzzle/guzzle/issues/877
+* Improved path URL serialization.
+
+ * No longer double percent-encoding characters in the path or query string if
+ they are already encoded.
+ * Now properly encoding the supplied path to a URL object, instead of only
+ encoding ' ' and '?'.
+ * Note: This has been changed in 5.0.3 to now encode query string values by
+ default unless the `rawString` argument is provided when setting the query
+ string on a URL: Now allowing many more characters to be present in the
+ query string without being percent encoded. See http://tools.ietf.org/html/rfc3986#appendix-A
+
+## 5.0.1 - 2014-10-16
+
+Bugfix release.
+
+* Fixed an issue where connection errors still returned response object in
+ error and end events event though the response is unusable. This has been
+ corrected so that a response is not returned in the `getResponse` method of
+ these events if the response did not complete. https://github.com/guzzle/guzzle/issues/867
+* Fixed an issue where transfer statistics were not being populated in the
+ RingBridge. https://github.com/guzzle/guzzle/issues/866
+
+## 5.0.0 - 2014-10-12
+
+Adding support for non-blocking responses and some minor API cleanup.
+
+### New Features
+
+* Added support for non-blocking responses based on `guzzlehttp/guzzle-ring`.
+* Added a public API for creating a default HTTP adapter.
+* Updated the redirect plugin to be non-blocking so that redirects are sent
+ concurrently. Other plugins like this can now be updated to be non-blocking.
+* Added a "progress" event so that you can get upload and download progress
+ events.
+* Added `GuzzleHttp\Pool` which implements FutureInterface and transfers
+ requests concurrently using a capped pool size as efficiently as possible.
+* Added `hasListeners()` to EmitterInterface.
+* Removed `GuzzleHttp\ClientInterface::sendAll` and marked
+ `GuzzleHttp\Client::sendAll` as deprecated (it's still there, just not the
+ recommended way).
+
+### Breaking changes
+
+The breaking changes in this release are relatively minor. The biggest thing to
+look out for is that request and response objects no longer implement fluent
+interfaces.
+
+* Removed the fluent interfaces (i.e., `return $this`) from requests,
+ responses, `GuzzleHttp\Collection`, `GuzzleHttp\Url`,
+ `GuzzleHttp\Query`, `GuzzleHttp\Post\PostBody`, and
+ `GuzzleHttp\Cookie\SetCookie`. This blog post provides a good outline of
+ why I did this: http://ocramius.github.io/blog/fluent-interfaces-are-evil/.
+ This also makes the Guzzle message interfaces compatible with the current
+ PSR-7 message proposal.
+* Removed "functions.php", so that Guzzle is truly PSR-4 compliant. Except
+ for the HTTP request functions from function.php, these functions are now
+ implemented in `GuzzleHttp\Utils` using camelCase. `GuzzleHttp\json_decode`
+ moved to `GuzzleHttp\Utils::jsonDecode`. `GuzzleHttp\get_path` moved to
+ `GuzzleHttp\Utils::getPath`. `GuzzleHttp\set_path` moved to
+ `GuzzleHttp\Utils::setPath`. `GuzzleHttp\batch` should now be
+ `GuzzleHttp\Pool::batch`, which returns an `objectStorage`. Using functions.php
+ caused problems for many users: they aren't PSR-4 compliant, require an
+ explicit include, and needed an if-guard to ensure that the functions are not
+ declared multiple times.
+* Rewrote adapter layer.
+ * Removing all classes from `GuzzleHttp\Adapter`, these are now
+ implemented as callables that are stored in `GuzzleHttp\Ring\Client`.
+ * Removed the concept of "parallel adapters". Sending requests serially or
+ concurrently is now handled using a single adapter.
+ * Moved `GuzzleHttp\Adapter\Transaction` to `GuzzleHttp\Transaction`. The
+ Transaction object now exposes the request, response, and client as public
+ properties. The getters and setters have been removed.
+* Removed the "headers" event. This event was only useful for changing the
+ body a response once the headers of the response were known. You can implement
+ a similar behavior in a number of ways. One example might be to use a
+ FnStream that has access to the transaction being sent. For example, when the
+ first byte is written, you could check if the response headers match your
+ expectations, and if so, change the actual stream body that is being
+ written to.
+* Removed the `asArray` parameter from
+ `GuzzleHttp\Message\MessageInterface::getHeader`. If you want to get a header
+ value as an array, then use the newly added `getHeaderAsArray()` method of
+ `MessageInterface`. This change makes the Guzzle interfaces compatible with
+ the PSR-7 interfaces.
+* `GuzzleHttp\Message\MessageFactory` no longer allows subclasses to add
+ custom request options using double-dispatch (this was an implementation
+ detail). Instead, you should now provide an associative array to the
+ constructor which is a mapping of the request option name mapping to a
+ function that applies the option value to a request.
+* Removed the concept of "throwImmediately" from exceptions and error events.
+ This control mechanism was used to stop a transfer of concurrent requests
+ from completing. This can now be handled by throwing the exception or by
+ cancelling a pool of requests or each outstanding future request individually.
+* Updated to "GuzzleHttp\Streams" 3.0.
+ * `GuzzleHttp\Stream\StreamInterface::getContents()` no longer accepts a
+ `maxLen` parameter. This update makes the Guzzle streams project
+ compatible with the current PSR-7 proposal.
+ * `GuzzleHttp\Stream\Stream::__construct`,
+ `GuzzleHttp\Stream\Stream::factory`, and
+ `GuzzleHttp\Stream\Utils::create` no longer accept a size in the second
+ argument. They now accept an associative array of options, including the
+ "size" key and "metadata" key which can be used to provide custom metadata.
+
+## 4.2.2 - 2014-09-08
+
+* Fixed a memory leak in the CurlAdapter when reusing cURL handles.
+* No longer using `request_fulluri` in stream adapter proxies.
+* Relative redirects are now based on the last response, not the first response.
+
+## 4.2.1 - 2014-08-19
+
+* Ensuring that the StreamAdapter does not always add a Content-Type header
+* Adding automated github releases with a phar and zip
+
+## 4.2.0 - 2014-08-17
+
+* Now merging in default options using a case-insensitive comparison.
+ Closes https://github.com/guzzle/guzzle/issues/767
+* Added the ability to automatically decode `Content-Encoding` response bodies
+ using the `decode_content` request option. This is set to `true` by default
+ to decode the response body if it comes over the wire with a
+ `Content-Encoding`. Set this value to `false` to disable decoding the
+ response content, and pass a string to provide a request `Accept-Encoding`
+ header and turn on automatic response decoding. This feature now allows you
+ to pass an `Accept-Encoding` header in the headers of a request but still
+ disable automatic response decoding.
+ Closes https://github.com/guzzle/guzzle/issues/764
+* Added the ability to throw an exception immediately when transferring
+ requests in parallel. Closes https://github.com/guzzle/guzzle/issues/760
+* Updating guzzlehttp/streams dependency to ~2.1
+* No longer utilizing the now deprecated namespaced methods from the stream
+ package.
+
+## 4.1.8 - 2014-08-14
+
+* Fixed an issue in the CurlFactory that caused setting the `stream=false`
+ request option to throw an exception.
+ See: https://github.com/guzzle/guzzle/issues/769
+* TransactionIterator now calls rewind on the inner iterator.
+ See: https://github.com/guzzle/guzzle/pull/765
+* You can now set the `Content-Type` header to `multipart/form-data`
+ when creating POST requests to force multipart bodies.
+ See https://github.com/guzzle/guzzle/issues/768
+
+## 4.1.7 - 2014-08-07
+
+* Fixed an error in the HistoryPlugin that caused the same request and response
+ to be logged multiple times when an HTTP protocol error occurs.
+* Ensuring that cURL does not add a default Content-Type when no Content-Type
+ has been supplied by the user. This prevents the adapter layer from modifying
+ the request that is sent over the wire after any listeners may have already
+ put the request in a desired state (e.g., signed the request).
+* Throwing an exception when you attempt to send requests that have the
+ "stream" set to true in parallel using the MultiAdapter.
+* Only calling curl_multi_select when there are active cURL handles. This was
+ previously changed and caused performance problems on some systems due to PHP
+ always selecting until the maximum select timeout.
+* Fixed a bug where multipart/form-data POST fields were not correctly
+ aggregated (e.g., values with "&").
+
+## 4.1.6 - 2014-08-03
+
+* Added helper methods to make it easier to represent messages as strings,
+ including getting the start line and getting headers as a string.
+
+## 4.1.5 - 2014-08-02
+
+* Automatically retrying cURL "Connection died, retrying a fresh connect"
+ errors when possible.
+* cURL implementation cleanup
+* Allowing multiple event subscriber listeners to be registered per event by
+ passing an array of arrays of listener configuration.
+
+## 4.1.4 - 2014-07-22
+
+* Fixed a bug that caused multi-part POST requests with more than one field to
+ serialize incorrectly.
+* Paths can now be set to "0"
+* `ResponseInterface::xml` now accepts a `libxml_options` option and added a
+ missing default argument that was required when parsing XML response bodies.
+* A `save_to` stream is now created lazily, which means that files are not
+ created on disk unless a request succeeds.
+
+## 4.1.3 - 2014-07-15
+
+* Various fixes to multipart/form-data POST uploads
+* Wrapping function.php in an if-statement to ensure Guzzle can be used
+ globally and in a Composer install
+* Fixed an issue with generating and merging in events to an event array
+* POST headers are only applied before sending a request to allow you to change
+ the query aggregator used before uploading
+* Added much more robust query string parsing
+* Fixed various parsing and normalization issues with URLs
+* Fixing an issue where multi-valued headers were not being utilized correctly
+ in the StreamAdapter
+
+## 4.1.2 - 2014-06-18
+
+* Added support for sending payloads with GET requests
+
+## 4.1.1 - 2014-06-08
+
+* Fixed an issue related to using custom message factory options in subclasses
+* Fixed an issue with nested form fields in a multi-part POST
+* Fixed an issue with using the `json` request option for POST requests
+* Added `ToArrayInterface` to `GuzzleHttp\Cookie\CookieJar`
+
+## 4.1.0 - 2014-05-27
+
+* Added a `json` request option to easily serialize JSON payloads.
+* Added a `GuzzleHttp\json_decode()` wrapper to safely parse JSON.
+* Added `setPort()` and `getPort()` to `GuzzleHttp\Message\RequestInterface`.
+* Added the ability to provide an emitter to a client in the client constructor.
+* Added the ability to persist a cookie session using $_SESSION.
+* Added a trait that can be used to add event listeners to an iterator.
+* Removed request method constants from RequestInterface.
+* Fixed warning when invalid request start-lines are received.
+* Updated MessageFactory to work with custom request option methods.
+* Updated cacert bundle to latest build.
+
+4.0.2 (2014-04-16)
+------------------
+
+* Proxy requests using the StreamAdapter now properly use request_fulluri (#632)
+* Added the ability to set scalars as POST fields (#628)
+
+## 4.0.1 - 2014-04-04
+
+* The HTTP status code of a response is now set as the exception code of
+ RequestException objects.
+* 303 redirects will now correctly switch from POST to GET requests.
+* The default parallel adapter of a client now correctly uses the MultiAdapter.
+* HasDataTrait now initializes the internal data array as an empty array so
+ that the toArray() method always returns an array.
+
+## 4.0.0 - 2014-03-29
+
+* For more information on the 4.0 transition, see:
+ http://mtdowling.com/blog/2014/03/15/guzzle-4-rc/
+* For information on changes and upgrading, see:
+ https://github.com/guzzle/guzzle/blob/master/UPGRADING.md#3x-to-40
+* Added `GuzzleHttp\batch()` as a convenience function for sending requests in
+ parallel without needing to write asynchronous code.
+* Restructured how events are added to `GuzzleHttp\ClientInterface::sendAll()`.
+ You can now pass a callable or an array of associative arrays where each
+ associative array contains the "fn", "priority", and "once" keys.
+
+## 4.0.0.rc-2 - 2014-03-25
+
+* Removed `getConfig()` and `setConfig()` from clients to avoid confusion
+ around whether things like base_url, message_factory, etc. should be able to
+ be retrieved or modified.
+* Added `getDefaultOption()` and `setDefaultOption()` to ClientInterface
+* functions.php functions were renamed using snake_case to match PHP idioms
+* Added support for `HTTP_PROXY`, `HTTPS_PROXY`, and
+ `GUZZLE_CURL_SELECT_TIMEOUT` environment variables
+* Added the ability to specify custom `sendAll()` event priorities
+* Added the ability to specify custom stream context options to the stream
+ adapter.
+* Added a functions.php function for `get_path()` and `set_path()`
+* CurlAdapter and MultiAdapter now use a callable to generate curl resources
+* MockAdapter now properly reads a body and emits a `headers` event
+* Updated Url class to check if a scheme and host are set before adding ":"
+ and "//". This allows empty Url (e.g., "") to be serialized as "".
+* Parsing invalid XML no longer emits warnings
+* Curl classes now properly throw AdapterExceptions
+* Various performance optimizations
+* Streams are created with the faster `Stream\create()` function
+* Marked deprecation_proxy() as internal
+* Test server is now a collection of static methods on a class
+
+## 4.0.0-rc.1 - 2014-03-15
+
+* See https://github.com/guzzle/guzzle/blob/master/UPGRADING.md#3x-to-40
+
+## 3.8.1 - 2014-01-28
+
+* Bug: Always using GET requests when redirecting from a 303 response
+* Bug: CURLOPT_SSL_VERIFYHOST is now correctly set to false when setting `$certificateAuthority` to false in
+ `Guzzle\Http\ClientInterface::setSslVerification()`
+* Bug: RedirectPlugin now uses strict RFC 3986 compliance when combining a base URL with a relative URL
+* Bug: The body of a request can now be set to `"0"`
+* Sending PHP stream requests no longer forces `HTTP/1.0`
+* Adding more information to ExceptionCollection exceptions so that users have more context, including a stack trace of
+ each sub-exception
+* Updated the `$ref` attribute in service descriptions to merge over any existing parameters of a schema (rather than
+ clobbering everything).
+* Merging URLs will now use the query string object from the relative URL (thus allowing custom query aggregators)
+* Query strings are now parsed in a way that they do no convert empty keys with no value to have a dangling `=`.
+ For example `foo&bar=baz` is now correctly parsed and recognized as `foo&bar=baz` rather than `foo=&bar=baz`.
+* Now properly escaping the regular expression delimiter when matching Cookie domains.
+* Network access is now disabled when loading XML documents
+
+## 3.8.0 - 2013-12-05
+
+* Added the ability to define a POST name for a file
+* JSON response parsing now properly walks additionalProperties
+* cURL error code 18 is now retried automatically in the BackoffPlugin
+* Fixed a cURL error when URLs contain fragments
+* Fixed an issue in the BackoffPlugin retry event where it was trying to access all exceptions as if they were
+ CurlExceptions
+* CURLOPT_PROGRESS function fix for PHP 5.5 (69fcc1e)
+* Added the ability for Guzzle to work with older versions of cURL that do not support `CURLOPT_TIMEOUT_MS`
+* Fixed a bug that was encountered when parsing empty header parameters
+* UriTemplate now has a `setRegex()` method to match the docs
+* The `debug` request parameter now checks if it is truthy rather than if it exists
+* Setting the `debug` request parameter to true shows verbose cURL output instead of using the LogPlugin
+* Added the ability to combine URLs using strict RFC 3986 compliance
+* Command objects can now return the validation errors encountered by the command
+* Various fixes to cache revalidation (#437 and 29797e5)
+* Various fixes to the AsyncPlugin
+* Cleaned up build scripts
+
+## 3.7.4 - 2013-10-02
+
+* Bug fix: 0 is now an allowed value in a description parameter that has a default value (#430)
+* Bug fix: SchemaFormatter now returns an integer when formatting to a Unix timestamp
+ (see https://github.com/aws/aws-sdk-php/issues/147)
+* Bug fix: Cleaned up and fixed URL dot segment removal to properly resolve internal dots
+* Minimum PHP version is now properly specified as 5.3.3 (up from 5.3.2) (#420)
+* Updated the bundled cacert.pem (#419)
+* OauthPlugin now supports adding authentication to headers or query string (#425)
+
+## 3.7.3 - 2013-09-08
+
+* Added the ability to get the exception associated with a request/command when using `MultiTransferException` and
+ `CommandTransferException`.
+* Setting `additionalParameters` of a response to false is now honored when parsing responses with a service description
+* Schemas are only injected into response models when explicitly configured.
+* No longer guessing Content-Type based on the path of a request. Content-Type is now only guessed based on the path of
+ an EntityBody.
+* Bug fix: ChunkedIterator can now properly chunk a \Traversable as well as an \Iterator.
+* Bug fix: FilterIterator now relies on `\Iterator` instead of `\Traversable`.
+* Bug fix: Gracefully handling malformed responses in RequestMediator::writeResponseBody()
+* Bug fix: Replaced call to canCache with canCacheRequest in the CallbackCanCacheStrategy of the CachePlugin
+* Bug fix: Visiting XML attributes first before visiting XML children when serializing requests
+* Bug fix: Properly parsing headers that contain commas contained in quotes
+* Bug fix: mimetype guessing based on a filename is now case-insensitive
+
+## 3.7.2 - 2013-08-02
+
+* Bug fix: Properly URL encoding paths when using the PHP-only version of the UriTemplate expander
+ See https://github.com/guzzle/guzzle/issues/371
+* Bug fix: Cookie domains are now matched correctly according to RFC 6265
+ See https://github.com/guzzle/guzzle/issues/377
+* Bug fix: GET parameters are now used when calculating an OAuth signature
+* Bug fix: Fixed an issue with cache revalidation where the If-None-Match header was being double quoted
+* `Guzzle\Common\AbstractHasDispatcher::dispatch()` now returns the event that was dispatched
+* `Guzzle\Http\QueryString::factory()` now guesses the most appropriate query aggregator to used based on the input.
+ See https://github.com/guzzle/guzzle/issues/379
+* Added a way to add custom domain objects to service description parsing using the `operation.parse_class` event. See
+ https://github.com/guzzle/guzzle/pull/380
+* cURL multi cleanup and optimizations
+
+## 3.7.1 - 2013-07-05
+
+* Bug fix: Setting default options on a client now works
+* Bug fix: Setting options on HEAD requests now works. See #352
+* Bug fix: Moving stream factory before send event to before building the stream. See #353
+* Bug fix: Cookies no longer match on IP addresses per RFC 6265
+* Bug fix: Correctly parsing header parameters that are in `<>` and quotes
+* Added `cert` and `ssl_key` as request options
+* `Host` header can now diverge from the host part of a URL if the header is set manually
+* `Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor` was rewritten to change from using SimpleXML to XMLWriter
+* OAuth parameters are only added via the plugin if they aren't already set
+* Exceptions are now thrown when a URL cannot be parsed
+* Returning `false` if `Guzzle\Http\EntityBody::getContentMd5()` fails
+* Not setting a `Content-MD5` on a command if calculating the Content-MD5 fails via the CommandContentMd5Plugin
+
+## 3.7.0 - 2013-06-10
+
+* See UPGRADING.md for more information on how to upgrade.
+* Requests now support the ability to specify an array of $options when creating a request to more easily modify a
+ request. You can pass a 'request.options' configuration setting to a client to apply default request options to
+ every request created by a client (e.g. default query string variables, headers, curl options, etc.).
+* Added a static facade class that allows you to use Guzzle with static methods and mount the class to `\Guzzle`.
+ See `Guzzle\Http\StaticClient::mount`.
+* Added `command.request_options` to `Guzzle\Service\Command\AbstractCommand` to pass request options to requests
+ created by a command (e.g. custom headers, query string variables, timeout settings, etc.).
+* Stream size in `Guzzle\Stream\PhpStreamRequestFactory` will now be set if Content-Length is returned in the
+ headers of a response
+* Added `Guzzle\Common\Collection::setPath($path, $value)` to set a value into an array using a nested key
+ (e.g. `$collection->setPath('foo/baz/bar', 'test'); echo $collection['foo']['bar']['bar'];`)
+* ServiceBuilders now support storing and retrieving arbitrary data
+* CachePlugin can now purge all resources for a given URI
+* CachePlugin can automatically purge matching cached items when a non-idempotent request is sent to a resource
+* CachePlugin now uses the Vary header to determine if a resource is a cache hit
+* `Guzzle\Http\Message\Response` now implements `\Serializable`
+* Added `Guzzle\Cache\CacheAdapterFactory::fromCache()` to more easily create cache adapters
+* `Guzzle\Service\ClientInterface::execute()` now accepts an array, single command, or Traversable
+* Fixed a bug in `Guzzle\Http\Message\Header\Link::addLink()`
+* Better handling of calculating the size of a stream in `Guzzle\Stream\Stream` using fstat() and caching the size
+* `Guzzle\Common\Exception\ExceptionCollection` now creates a more readable exception message
+* Fixing BC break: Added back the MonologLogAdapter implementation rather than extending from PsrLog so that older
+ Symfony users can still use the old version of Monolog.
+* Fixing BC break: Added the implementation back in for `Guzzle\Http\Message\AbstractMessage::getTokenizedHeader()`.
+ Now triggering an E_USER_DEPRECATED warning when used. Use `$message->getHeader()->parseParams()`.
+* Several performance improvements to `Guzzle\Common\Collection`
+* Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`:
+ createRequest, head, delete, put, patch, post, options, prepareRequest
+* Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()`
+* Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface`
+* Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to
+ `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a
+ resource, string, or EntityBody into the $options parameter to specify the download location of the response.
+* Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a
+ default `array()`
+* Added `Guzzle\Stream\StreamInterface::isRepeatable`
+* Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use
+ $client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or
+ $client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))`.
+* Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use $client->getConfig()->getPath('request.options/headers')`.
+* Removed `Guzzle\Http\ClientInterface::expandTemplate()`
+* Removed `Guzzle\Http\ClientInterface::setRequestFactory()`
+* Removed `Guzzle\Http\ClientInterface::getCurlMulti()`
+* Removed `Guzzle\Http\Message\RequestInterface::canCache`
+* Removed `Guzzle\Http\Message\RequestInterface::setIsRedirect`
+* Removed `Guzzle\Http\Message\RequestInterface::isRedirect`
+* Made `Guzzle\Http\Client::expandTemplate` and `getUriTemplate` protected methods.
+* You can now enable E_USER_DEPRECATED warnings to see if you are using a deprecated method by setting
+ `Guzzle\Common\Version::$emitWarnings` to true.
+* Marked `Guzzle\Http\Message\Request::isResponseBodyRepeatable()` as deprecated. Use
+ `$request->getResponseBody()->isRepeatable()` instead.
+* Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use
+ `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
+* Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use
+ `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
+* Marked `Guzzle\Http\Message\Request::setIsRedirect()` as deprecated. Use the HistoryPlugin instead.
+* Marked `Guzzle\Http\Message\Request::isRedirect()` as deprecated. Use the HistoryPlugin instead.
+* Marked `Guzzle\Cache\CacheAdapterFactory::factory()` as deprecated
+* Marked 'command.headers', 'command.response_body' and 'command.on_complete' as deprecated for AbstractCommand.
+ These will work through Guzzle 4.0
+* Marked 'request.params' for `Guzzle\Http\Client` as deprecated. Use [request.options][params].
+* Marked `Guzzle\Service\Client::enableMagicMethods()` as deprecated. Magic methods can no longer be disabled on a Guzzle\Service\Client.
+* Marked `Guzzle\Service\Client::getDefaultHeaders()` as deprecated. Use $client->getConfig()->getPath('request.options/headers')`.
+* Marked `Guzzle\Service\Client::setDefaultHeaders()` as deprecated. Use $client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`.
+* Marked `Guzzle\Parser\Url\UrlParser` as deprecated. Just use PHP's `parse_url()` and percent encode your UTF-8.
+* Marked `Guzzle\Common\Collection::inject()` as deprecated.
+* Marked `Guzzle\Plugin\CurlAuth\CurlAuthPlugin` as deprecated. Use `$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest');`
+* CacheKeyProviderInterface and DefaultCacheKeyProvider are no longer used. All of this logic is handled in a
+ CacheStorageInterface. These two objects and interface will be removed in a future version.
+* Always setting X-cache headers on cached responses
+* Default cache TTLs are now handled by the CacheStorageInterface of a CachePlugin
+* `CacheStorageInterface::cache($key, Response $response, $ttl = null)` has changed to `cache(RequestInterface
+ $request, Response $response);`
+* `CacheStorageInterface::fetch($key)` has changed to `fetch(RequestInterface $request);`
+* `CacheStorageInterface::delete($key)` has changed to `delete(RequestInterface $request);`
+* Added `CacheStorageInterface::purge($url)`
+* `DefaultRevalidation::__construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin
+ $plugin)` has changed to `DefaultRevalidation::__construct(CacheStorageInterface $cache,
+ CanCacheStrategyInterface $canCache = null)`
+* Added `RevalidationInterface::shouldRevalidate(RequestInterface $request, Response $response)`
+
+## 3.6.0 - 2013-05-29
+
+* ServiceDescription now implements ToArrayInterface
+* Added command.hidden_params to blacklist certain headers from being treated as additionalParameters
+* Guzzle can now correctly parse incomplete URLs
+* Mixed casing of headers are now forced to be a single consistent casing across all values for that header.
+* Messages internally use a HeaderCollection object to delegate handling case-insensitive header resolution
+* Removed the whole changedHeader() function system of messages because all header changes now go through addHeader().
+* Specific header implementations can be created for complex headers. When a message creates a header, it uses a
+ HeaderFactory which can map specific headers to specific header classes. There is now a Link header and
+ CacheControl header implementation.
+* Removed from interface: Guzzle\Http\ClientInterface::setUriTemplate
+* Removed from interface: Guzzle\Http\ClientInterface::setCurlMulti()
+* Removed Guzzle\Http\Message\Request::receivedRequestHeader() and implemented this functionality in
+ Guzzle\Http\Curl\RequestMediator
+* Removed the optional $asString parameter from MessageInterface::getHeader(). Just cast the header to a string.
+* Removed the optional $tryChunkedTransfer option from Guzzle\Http\Message\EntityEnclosingRequestInterface
+* Removed the $asObjects argument from Guzzle\Http\Message\MessageInterface::getHeaders()
+* Removed Guzzle\Parser\ParserRegister::get(). Use getParser()
+* Removed Guzzle\Parser\ParserRegister::set(). Use registerParser().
+* All response header helper functions return a string rather than mixing Header objects and strings inconsistently
+* Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc. are managed by Guzzle
+ directly via interfaces
+* Removed the injecting of a request object onto a response object. The methods to get and set a request still exist
+ but are a no-op until removed.
+* Most classes that used to require a `Guzzle\Service\Command\CommandInterface` typehint now request a
+ `Guzzle\Service\Command\ArrayCommandInterface`.
+* Added `Guzzle\Http\Message\RequestInterface::startResponse()` to the RequestInterface to handle injecting a response
+ on a request while the request is still being transferred
+* The ability to case-insensitively search for header values
+* Guzzle\Http\Message\Header::hasExactHeader
+* Guzzle\Http\Message\Header::raw. Use getAll()
+* Deprecated cache control specific methods on Guzzle\Http\Message\AbstractMessage. Use the CacheControl header object
+ instead.
+* `Guzzle\Service\Command\CommandInterface` now extends from ToArrayInterface and ArrayAccess
+* Added the ability to cast Model objects to a string to view debug information.
+
+## 3.5.0 - 2013-05-13
+
+* Bug: Fixed a regression so that request responses are parsed only once per oncomplete event rather than multiple times
+* Bug: Better cleanup of one-time events across the board (when an event is meant to fire once, it will now remove
+ itself from the EventDispatcher)
+* Bug: `Guzzle\Log\MessageFormatter` now properly writes "total_time" and "connect_time" values
+* Bug: Cloning an EntityEnclosingRequest now clones the EntityBody too
+* Bug: Fixed an undefined index error when parsing nested JSON responses with a sentAs parameter that reference a
+ non-existent key
+* Bug: All __call() method arguments are now required (helps with mocking frameworks)
+* Deprecating Response::getRequest() and now using a shallow clone of a request object to remove a circular reference
+ to help with refcount based garbage collection of resources created by sending a request
+* Deprecating ZF1 cache and log adapters. These will be removed in the next major version.
+* Deprecating `Response::getPreviousResponse()` (method signature still exists, but it's deprecated). Use the
+ HistoryPlugin for a history.
+* Added a `responseBody` alias for the `response_body` location
+* Refactored internals to no longer rely on Response::getRequest()
+* HistoryPlugin can now be cast to a string
+* HistoryPlugin now logs transactions rather than requests and responses to more accurately keep track of the requests
+ and responses that are sent over the wire
+* Added `getEffectiveUrl()` and `getRedirectCount()` to Response objects
+
+## 3.4.3 - 2013-04-30
+
+* Bug fix: Fixing bug introduced in 3.4.2 where redirect responses are duplicated on the final redirected response
+* Added a check to re-extract the temp cacert bundle from the phar before sending each request
+
+## 3.4.2 - 2013-04-29
+
+* Bug fix: Stream objects now work correctly with "a" and "a+" modes
+* Bug fix: Removing `Transfer-Encoding: chunked` header when a Content-Length is present
+* Bug fix: AsyncPlugin no longer forces HEAD requests
+* Bug fix: DateTime timezones are now properly handled when using the service description schema formatter
+* Bug fix: CachePlugin now properly handles stale-if-error directives when a request to the origin server fails
+* Setting a response on a request will write to the custom request body from the response body if one is specified
+* LogPlugin now writes to php://output when STDERR is undefined
+* Added the ability to set multiple POST files for the same key in a single call
+* application/x-www-form-urlencoded POSTs now use the utf-8 charset by default
+* Added the ability to queue CurlExceptions to the MockPlugin
+* Cleaned up how manual responses are queued on requests (removed "queued_response" and now using request.before_send)
+* Configuration loading now allows remote files
+
+## 3.4.1 - 2013-04-16
+
+* Large refactoring to how CurlMulti handles work. There is now a proxy that sits in front of a pool of CurlMulti
+ handles. This greatly simplifies the implementation, fixes a couple bugs, and provides a small performance boost.
+* Exceptions are now properly grouped when sending requests in parallel
+* Redirects are now properly aggregated when a multi transaction fails
+* Redirects now set the response on the original object even in the event of a failure
+* Bug fix: Model names are now properly set even when using $refs
+* Added support for PHP 5.5's CurlFile to prevent warnings with the deprecated @ syntax
+* Added support for oauth_callback in OAuth signatures
+* Added support for oauth_verifier in OAuth signatures
+* Added support to attempt to retrieve a command first literally, then ucfirst, the with inflection
+
+## 3.4.0 - 2013-04-11
+
+* Bug fix: URLs are now resolved correctly based on http://tools.ietf.org/html/rfc3986#section-5.2. #289
+* Bug fix: Absolute URLs with a path in a service description will now properly override the base URL. #289
+* Bug fix: Parsing a query string with a single PHP array value will now result in an array. #263
+* Bug fix: Better normalization of the User-Agent header to prevent duplicate headers. #264.
+* Bug fix: Added `number` type to service descriptions.
+* Bug fix: empty parameters are removed from an OAuth signature
+* Bug fix: Revalidating a cache entry prefers the Last-Modified over the Date header
+* Bug fix: Fixed "array to string" error when validating a union of types in a service description
+* Bug fix: Removed code that attempted to determine the size of a stream when data is written to the stream
+* Bug fix: Not including an `oauth_token` if the value is null in the OauthPlugin.
+* Bug fix: Now correctly aggregating successful requests and failed requests in CurlMulti when a redirect occurs.
+* The new default CURLOPT_TIMEOUT setting has been increased to 150 seconds so that Guzzle works on poor connections.
+* Added a feature to EntityEnclosingRequest::setBody() that will automatically set the Content-Type of the request if
+ the Content-Type can be determined based on the entity body or the path of the request.
+* Added the ability to overwrite configuration settings in a client when grabbing a throwaway client from a builder.
+* Added support for a PSR-3 LogAdapter.
+* Added a `command.after_prepare` event
+* Added `oauth_callback` parameter to the OauthPlugin
+* Added the ability to create a custom stream class when using a stream factory
+* Added a CachingEntityBody decorator
+* Added support for `additionalParameters` in service descriptions to define how custom parameters are serialized.
+* The bundled SSL certificate is now provided in the phar file and extracted when running Guzzle from a phar.
+* You can now send any EntityEnclosingRequest with POST fields or POST files and cURL will handle creating bodies
+* POST requests using a custom entity body are now treated exactly like PUT requests but with a custom cURL method. This
+ means that the redirect behavior of POST requests with custom bodies will not be the same as POST requests that use
+ POST fields or files (the latter is only used when emulating a form POST in the browser).
+* Lots of cleanup to CurlHandle::factory and RequestFactory::createRequest
+
+## 3.3.1 - 2013-03-10
+
+* Added the ability to create PHP streaming responses from HTTP requests
+* Bug fix: Running any filters when parsing response headers with service descriptions
+* Bug fix: OauthPlugin fixes to allow for multi-dimensional array signing, and sorting parameters before signing
+* Bug fix: Removed the adding of default empty arrays and false Booleans to responses in order to be consistent across
+ response location visitors.
+* Bug fix: Removed the possibility of creating configuration files with circular dependencies
+* RequestFactory::create() now uses the key of a POST file when setting the POST file name
+* Added xmlAllowEmpty to serialize an XML body even if no XML specific parameters are set
+
+## 3.3.0 - 2013-03-03
+
+* A large number of performance optimizations have been made
+* Bug fix: Added 'wb' as a valid write mode for streams
+* Bug fix: `Guzzle\Http\Message\Response::json()` now allows scalar values to be returned
+* Bug fix: Fixed bug in `Guzzle\Http\Message\Response` where wrapping quotes were stripped from `getEtag()`
+* BC: Removed `Guzzle\Http\Utils` class
+* BC: Setting a service description on a client will no longer modify the client's command factories.
+* BC: Emitting IO events from a RequestMediator is now a parameter that must be set in a request's curl options using
+ the 'emit_io' key. This was previously set under a request's parameters using 'curl.emit_io'
+* BC: `Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getSteamType()` are no longer converted to
+ lowercase
+* Operation parameter objects are now lazy loaded internally
+* Added ErrorResponsePlugin that can throw errors for responses defined in service description operations' errorResponses
+* Added support for instantiating responseType=class responseClass classes. Classes must implement
+ `Guzzle\Service\Command\ResponseClassInterface`
+* Added support for additionalProperties for top-level parameters in responseType=model responseClasses. These
+ additional properties also support locations and can be used to parse JSON responses where the outermost part of the
+ JSON is an array
+* Added support for nested renaming of JSON models (rename sentAs to name)
+* CachePlugin
+ * Added support for stale-if-error so that the CachePlugin can now serve stale content from the cache on error
+ * Debug headers can now added to cached response in the CachePlugin
+
+## 3.2.0 - 2013-02-14
+
+* CurlMulti is no longer reused globally. A new multi object is created per-client. This helps to isolate clients.
+* URLs with no path no longer contain a "/" by default
+* Guzzle\Http\QueryString does no longer manages the leading "?". This is now handled in Guzzle\Http\Url.
+* BadResponseException no longer includes the full request and response message
+* Adding setData() to Guzzle\Service\Description\ServiceDescriptionInterface
+* Adding getResponseBody() to Guzzle\Http\Message\RequestInterface
+* Various updates to classes to use ServiceDescriptionInterface type hints rather than ServiceDescription
+* Header values can now be normalized into distinct values when multiple headers are combined with a comma separated list
+* xmlEncoding can now be customized for the XML declaration of a XML service description operation
+* Guzzle\Http\QueryString now uses Guzzle\Http\QueryAggregator\QueryAggregatorInterface objects to add custom value
+ aggregation and no longer uses callbacks
+* The URL encoding implementation of Guzzle\Http\QueryString can now be customized
+* Bug fix: Filters were not always invoked for array service description parameters
+* Bug fix: Redirects now use a target response body rather than a temporary response body
+* Bug fix: The default exponential backoff BackoffPlugin was not giving when the request threshold was exceeded
+* Bug fix: Guzzle now takes the first found value when grabbing Cache-Control directives
+
+## 3.1.2 - 2013-01-27
+
+* Refactored how operation responses are parsed. Visitors now include a before() method responsible for parsing the
+ response body. For example, the XmlVisitor now parses the XML response into an array in the before() method.
+* Fixed an issue where cURL would not automatically decompress responses when the Accept-Encoding header was sent
+* CURLOPT_SSL_VERIFYHOST is never set to 1 because it is deprecated (see 5e0ff2ef20f839e19d1eeb298f90ba3598784444)
+* Fixed a bug where redirect responses were not chained correctly using getPreviousResponse()
+* Setting default headers on a client after setting the user-agent will not erase the user-agent setting
+
+## 3.1.1 - 2013-01-20
+
+* Adding wildcard support to Guzzle\Common\Collection::getPath()
+* Adding alias support to ServiceBuilder configs
+* Adding Guzzle\Service\Resource\CompositeResourceIteratorFactory and cleaning up factory interface
+
+## 3.1.0 - 2013-01-12
+
+* BC: CurlException now extends from RequestException rather than BadResponseException
+* BC: Renamed Guzzle\Plugin\Cache\CanCacheStrategyInterface::canCache() to canCacheRequest() and added CanCacheResponse()
+* Added getData to ServiceDescriptionInterface
+* Added context array to RequestInterface::setState()
+* Bug: Removing hard dependency on the BackoffPlugin from Guzzle\Http
+* Bug: Adding required content-type when JSON request visitor adds JSON to a command
+* Bug: Fixing the serialization of a service description with custom data
+* Made it easier to deal with exceptions thrown when transferring commands or requests in parallel by providing
+ an array of successful and failed responses
+* Moved getPath from Guzzle\Service\Resource\Model to Guzzle\Common\Collection
+* Added Guzzle\Http\IoEmittingEntityBody
+* Moved command filtration from validators to location visitors
+* Added `extends` attributes to service description parameters
+* Added getModels to ServiceDescriptionInterface
+
+## 3.0.7 - 2012-12-19
+
+* Fixing phar detection when forcing a cacert to system if null or true
+* Allowing filename to be passed to `Guzzle\Http\Message\Request::setResponseBody()`
+* Cleaning up `Guzzle\Common\Collection::inject` method
+* Adding a response_body location to service descriptions
+
+## 3.0.6 - 2012-12-09
+
+* CurlMulti performance improvements
+* Adding setErrorResponses() to Operation
+* composer.json tweaks
+
+## 3.0.5 - 2012-11-18
+
+* Bug: Fixing an infinite recursion bug caused from revalidating with the CachePlugin
+* Bug: Response body can now be a string containing "0"
+* Bug: Using Guzzle inside of a phar uses system by default but now allows for a custom cacert
+* Bug: QueryString::fromString now properly parses query string parameters that contain equal signs
+* Added support for XML attributes in service description responses
+* DefaultRequestSerializer now supports array URI parameter values for URI template expansion
+* Added better mimetype guessing to requests and post files
+
+## 3.0.4 - 2012-11-11
+
+* Bug: Fixed a bug when adding multiple cookies to a request to use the correct glue value
+* Bug: Cookies can now be added that have a name, domain, or value set to "0"
+* Bug: Using the system cacert bundle when using the Phar
+* Added json and xml methods to Response to make it easier to parse JSON and XML response data into data structures
+* Enhanced cookie jar de-duplication
+* Added the ability to enable strict cookie jars that throw exceptions when invalid cookies are added
+* Added setStream to StreamInterface to actually make it possible to implement custom rewind behavior for entity bodies
+* Added the ability to create any sort of hash for a stream rather than just an MD5 hash
+
+## 3.0.3 - 2012-11-04
+
+* Implementing redirects in PHP rather than cURL
+* Added PECL URI template extension and using as default parser if available
+* Bug: Fixed Content-Length parsing of Response factory
+* Adding rewind() method to entity bodies and streams. Allows for custom rewinding of non-repeatable streams.
+* Adding ToArrayInterface throughout library
+* Fixing OauthPlugin to create unique nonce values per request
+
+## 3.0.2 - 2012-10-25
+
+* Magic methods are enabled by default on clients
+* Magic methods return the result of a command
+* Service clients no longer require a base_url option in the factory
+* Bug: Fixed an issue with URI templates where null template variables were being expanded
+
+## 3.0.1 - 2012-10-22
+
+* Models can now be used like regular collection objects by calling filter, map, etc.
+* Models no longer require a Parameter structure or initial data in the constructor
+* Added a custom AppendIterator to get around a PHP bug with the `\AppendIterator`
+
+## 3.0.0 - 2012-10-15
+
+* Rewrote service description format to be based on Swagger
+ * Now based on JSON schema
+ * Added nested input structures and nested response models
+ * Support for JSON and XML input and output models
+ * Renamed `commands` to `operations`
+ * Removed dot class notation
+ * Removed custom types
+* Broke the project into smaller top-level namespaces to be more component friendly
+* Removed support for XML configs and descriptions. Use arrays or JSON files.
+* Removed the Validation component and Inspector
+* Moved all cookie code to Guzzle\Plugin\Cookie
+* Magic methods on a Guzzle\Service\Client now return the command un-executed.
+* Calling getResult() or getResponse() on a command will lazily execute the command if needed.
+* Now shipping with cURL's CA certs and using it by default
+* Added previousResponse() method to response objects
+* No longer sending Accept and Accept-Encoding headers on every request
+* Only sending an Expect header by default when a payload is greater than 1MB
+* Added/moved client options:
+ * curl.blacklist to curl.option.blacklist
+ * Added ssl.certificate_authority
+* Added a Guzzle\Iterator component
+* Moved plugins from Guzzle\Http\Plugin to Guzzle\Plugin
+* Added a more robust backoff retry strategy (replaced the ExponentialBackoffPlugin)
+* Added a more robust caching plugin
+* Added setBody to response objects
+* Updating LogPlugin to use a more flexible MessageFormatter
+* Added a completely revamped build process
+* Cleaning up Collection class and removing default values from the get method
+* Fixed ZF2 cache adapters
+
+## 2.8.8 - 2012-10-15
+
+* Bug: Fixed a cookie issue that caused dot prefixed domains to not match where popular browsers did
+
+## 2.8.7 - 2012-09-30
+
+* Bug: Fixed config file aliases for JSON includes
+* Bug: Fixed cookie bug on a request object by using CookieParser to parse cookies on requests
+* Bug: Removing the path to a file when sending a Content-Disposition header on a POST upload
+* Bug: Hardening request and response parsing to account for missing parts
+* Bug: Fixed PEAR packaging
+* Bug: Fixed Request::getInfo
+* Bug: Fixed cases where CURLM_CALL_MULTI_PERFORM return codes were causing curl transactions to fail
+* Adding the ability for the namespace Iterator factory to look in multiple directories
+* Added more getters/setters/removers from service descriptions
+* Added the ability to remove POST fields from OAuth signatures
+* OAuth plugin now supports 2-legged OAuth
+
+## 2.8.6 - 2012-09-05
+
+* Added the ability to modify and build service descriptions
+* Added the use of visitors to apply parameters to locations in service descriptions using the dynamic command
+* Added a `json` parameter location
+* Now allowing dot notation for classes in the CacheAdapterFactory
+* Using the union of two arrays rather than an array_merge when extending service builder services and service params
+* Ensuring that a service is a string before doing strpos() checks on it when substituting services for references
+ in service builder config files.
+* Services defined in two different config files that include one another will by default replace the previously
+ defined service, but you can now create services that extend themselves and merge their settings over the previous
+* The JsonLoader now supports aliasing filenames with different filenames. This allows you to alias something like
+ '_default' with a default JSON configuration file.
+
+## 2.8.5 - 2012-08-29
+
+* Bug: Suppressed empty arrays from URI templates
+* Bug: Added the missing $options argument from ServiceDescription::factory to enable caching
+* Added support for HTTP responses that do not contain a reason phrase in the start-line
+* AbstractCommand commands are now invokable
+* Added a way to get the data used when signing an Oauth request before a request is sent
+
+## 2.8.4 - 2012-08-15
+
+* Bug: Custom delay time calculations are no longer ignored in the ExponentialBackoffPlugin
+* Added the ability to transfer entity bodies as a string rather than streamed. This gets around curl error 65. Set `body_as_string` in a request's curl options to enable.
+* Added a StreamInterface, EntityBodyInterface, and added ftell() to Guzzle\Common\Stream
+* Added an AbstractEntityBodyDecorator and a ReadLimitEntityBody decorator to transfer only a subset of a decorated stream
+* Stream and EntityBody objects will now return the file position to the previous position after a read required operation (e.g. getContentMd5())
+* Added additional response status codes
+* Removed SSL information from the default User-Agent header
+* DELETE requests can now send an entity body
+* Added an EventDispatcher to the ExponentialBackoffPlugin and added an ExponentialBackoffLogger to log backoff retries
+* Added the ability of the MockPlugin to consume mocked request bodies
+* LogPlugin now exposes request and response objects in the extras array
+
+## 2.8.3 - 2012-07-30
+
+* Bug: Fixed a case where empty POST requests were sent as GET requests
+* Bug: Fixed a bug in ExponentialBackoffPlugin that caused fatal errors when retrying an EntityEnclosingRequest that does not have a body
+* Bug: Setting the response body of a request to null after completing a request, not when setting the state of a request to new
+* Added multiple inheritance to service description commands
+* Added an ApiCommandInterface and added `getParamNames()` and `hasParam()`
+* Removed the default 2mb size cutoff from the Md5ValidatorPlugin so that it now defaults to validating everything
+* Changed CurlMulti::perform to pass a smaller timeout to CurlMulti::executeHandles
+
+## 2.8.2 - 2012-07-24
+
+* Bug: Query string values set to 0 are no longer dropped from the query string
+* Bug: A Collection object is no longer created each time a call is made to `Guzzle\Service\Command\AbstractCommand::getRequestHeaders()`
+* Bug: `+` is now treated as an encoded space when parsing query strings
+* QueryString and Collection performance improvements
+* Allowing dot notation for class paths in filters attribute of a service descriptions
+
+## 2.8.1 - 2012-07-16
+
+* Loosening Event Dispatcher dependency
+* POST redirects can now be customized using CURLOPT_POSTREDIR
+
+## 2.8.0 - 2012-07-15
+
+* BC: Guzzle\Http\Query
+ * Query strings with empty variables will always show an equal sign unless the variable is set to QueryString::BLANK (e.g. ?acl= vs ?acl)
+ * Changed isEncodingValues() and isEncodingFields() to isUrlEncoding()
+ * Changed setEncodeValues(bool) and setEncodeFields(bool) to useUrlEncoding(bool)
+ * Changed the aggregation functions of QueryString to be static methods
+ * Can now use fromString() with querystrings that have a leading ?
+* cURL configuration values can be specified in service descriptions using `curl.` prefixed parameters
+* Content-Length is set to 0 before emitting the request.before_send event when sending an empty request body
+* Cookies are no longer URL decoded by default
+* Bug: URI template variables set to null are no longer expanded
+
+## 2.7.2 - 2012-07-02
+
+* BC: Moving things to get ready for subtree splits. Moving Inflection into Common. Moving Guzzle\Http\Parser to Guzzle\Parser.
+* BC: Removing Guzzle\Common\Batch\Batch::count() and replacing it with isEmpty()
+* CachePlugin now allows for a custom request parameter function to check if a request can be cached
+* Bug fix: CachePlugin now only caches GET and HEAD requests by default
+* Bug fix: Using header glue when transferring headers over the wire
+* Allowing deeply nested arrays for composite variables in URI templates
+* Batch divisors can now return iterators or arrays
+
+## 2.7.1 - 2012-06-26
+
+* Minor patch to update version number in UA string
+* Updating build process
+
+## 2.7.0 - 2012-06-25
+
+* BC: Inflection classes moved to Guzzle\Inflection. No longer static methods. Can now inject custom inflectors into classes.
+* BC: Removed magic setX methods from commands
+* BC: Magic methods mapped to service description commands are now inflected in the command factory rather than the client __call() method
+* Verbose cURL options are no longer enabled by default. Set curl.debug to true on a client to enable.
+* Bug: Now allowing colons in a response start-line (e.g. HTTP/1.1 503 Service Unavailable: Back-end server is at capacity)
+* Guzzle\Service\Resource\ResourceIteratorApplyBatched now internally uses the Guzzle\Common\Batch namespace
+* Added Guzzle\Service\Plugin namespace and a PluginCollectionPlugin
+* Added the ability to set POST fields and files in a service description
+* Guzzle\Http\EntityBody::factory() now accepts objects with a __toString() method
+* Adding a command.before_prepare event to clients
+* Added BatchClosureTransfer and BatchClosureDivisor
+* BatchTransferException now includes references to the batch divisor and transfer strategies
+* Fixed some tests so that they pass more reliably
+* Added Guzzle\Common\Log\ArrayLogAdapter
+
+## 2.6.6 - 2012-06-10
+
+* BC: Removing Guzzle\Http\Plugin\BatchQueuePlugin
+* BC: Removing Guzzle\Service\Command\CommandSet
+* Adding generic batching system (replaces the batch queue plugin and command set)
+* Updating ZF cache and log adapters and now using ZF's composer repository
+* Bug: Setting the name of each ApiParam when creating through an ApiCommand
+* Adding result_type, result_doc, deprecated, and doc_url to service descriptions
+* Bug: Changed the default cookie header casing back to 'Cookie'
+
+## 2.6.5 - 2012-06-03
+
+* BC: Renaming Guzzle\Http\Message\RequestInterface::getResourceUri() to getResource()
+* BC: Removing unused AUTH_BASIC and AUTH_DIGEST constants from
+* BC: Guzzle\Http\Cookie is now used to manage Set-Cookie data, not Cookie data
+* BC: Renaming methods in the CookieJarInterface
+* Moving almost all cookie logic out of the CookiePlugin and into the Cookie or CookieJar implementations
+* Making the default glue for HTTP headers ';' instead of ','
+* Adding a removeValue to Guzzle\Http\Message\Header
+* Adding getCookies() to request interface.
+* Making it easier to add event subscribers to HasDispatcherInterface classes. Can now directly call addSubscriber()
+
+## 2.6.4 - 2012-05-30
+
+* BC: Cleaning up how POST files are stored in EntityEnclosingRequest objects. Adding PostFile class.
+* BC: Moving ApiCommand specific functionality from the Inspector and on to the ApiCommand
+* Bug: Fixing magic method command calls on clients
+* Bug: Email constraint only validates strings
+* Bug: Aggregate POST fields when POST files are present in curl handle
+* Bug: Fixing default User-Agent header
+* Bug: Only appending or prepending parameters in commands if they are specified
+* Bug: Not requiring response reason phrases or status codes to match a predefined list of codes
+* Allowing the use of dot notation for class namespaces when using instance_of constraint
+* Added any_match validation constraint
+* Added an AsyncPlugin
+* Passing request object to the calculateWait method of the ExponentialBackoffPlugin
+* Allowing the result of a command object to be changed
+* Parsing location and type sub values when instantiating a service description rather than over and over at runtime
+
+## 2.6.3 - 2012-05-23
+
+* [BC] Guzzle\Common\FromConfigInterface no longer requires any config options.
+* [BC] Refactoring how POST files are stored on an EntityEnclosingRequest. They are now separate from POST fields.
+* You can now use an array of data when creating PUT request bodies in the request factory.
+* Removing the requirement that HTTPS requests needed a Cache-Control: public directive to be cacheable.
+* [Http] Adding support for Content-Type in multipart POST uploads per upload
+* [Http] Added support for uploading multiple files using the same name (foo[0], foo[1])
+* Adding more POST data operations for easier manipulation of POST data.
+* You can now set empty POST fields.
+* The body of a request is only shown on EntityEnclosingRequest objects that do not use POST files.
+* Split the Guzzle\Service\Inspector::validateConfig method into two methods. One to initialize when a command is created, and one to validate.
+* CS updates
+
+## 2.6.2 - 2012-05-19
+
+* [Http] Better handling of nested scope requests in CurlMulti. Requests are now always prepares in the send() method rather than the addRequest() method.
+
+## 2.6.1 - 2012-05-19
+
+* [BC] Removing 'path' support in service descriptions. Use 'uri'.
+* [BC] Guzzle\Service\Inspector::parseDocBlock is now protected. Adding getApiParamsForClass() with cache.
+* [BC] Removing Guzzle\Common\NullObject. Use https://github.com/mtdowling/NullObject if you need it.
+* [BC] Removing Guzzle\Common\XmlElement.
+* All commands, both dynamic and concrete, have ApiCommand objects.
+* Adding a fix for CurlMulti so that if all of the connections encounter some sort of curl error, then the loop exits.
+* Adding checks to EntityEnclosingRequest so that empty POST files and fields are ignored.
+* Making the method signature of Guzzle\Service\Builder\ServiceBuilder::factory more flexible.
+
+## 2.6.0 - 2012-05-15
+
+* [BC] Moving Guzzle\Service\Builder to Guzzle\Service\Builder\ServiceBuilder
+* [BC] Executing a Command returns the result of the command rather than the command
+* [BC] Moving all HTTP parsing logic to Guzzle\Http\Parsers. Allows for faster C implementations if needed.
+* [BC] Changing the Guzzle\Http\Message\Response::setProtocol() method to accept a protocol and version in separate args.
+* [BC] Moving ResourceIterator* to Guzzle\Service\Resource
+* [BC] Completely refactored ResourceIterators to iterate over a cloned command object
+* [BC] Moved Guzzle\Http\UriTemplate to Guzzle\Http\Parser\UriTemplate\UriTemplate
+* [BC] Guzzle\Guzzle is now deprecated
+* Moving Guzzle\Common\Guzzle::inject to Guzzle\Common\Collection::inject
+* Adding Guzzle\Version class to give version information about Guzzle
+* Adding Guzzle\Http\Utils class to provide getDefaultUserAgent() and getHttpDate()
+* Adding Guzzle\Curl\CurlVersion to manage caching curl_version() data
+* ServiceDescription and ServiceBuilder are now cacheable using similar configs
+* Changing the format of XML and JSON service builder configs. Backwards compatible.
+* Cleaned up Cookie parsing
+* Trimming the default Guzzle User-Agent header
+* Adding a setOnComplete() method to Commands that is called when a command completes
+* Keeping track of requests that were mocked in the MockPlugin
+* Fixed a caching bug in the CacheAdapterFactory
+* Inspector objects can be injected into a Command object
+* Refactoring a lot of code and tests to be case insensitive when dealing with headers
+* Adding Guzzle\Http\Message\HeaderComparison for easy comparison of HTTP headers using a DSL
+* Adding the ability to set global option overrides to service builder configs
+* Adding the ability to include other service builder config files from within XML and JSON files
+* Moving the parseQuery method out of Url and on to QueryString::fromString() as a static factory method.
+
+## 2.5.0 - 2012-05-08
+
+* Major performance improvements
+* [BC] Simplifying Guzzle\Common\Collection. Please check to see if you are using features that are now deprecated.
+* [BC] Using a custom validation system that allows a flyweight implementation for much faster validation. No longer using Symfony2 Validation component.
+* [BC] No longer supporting "{{ }}" for injecting into command or UriTemplates. Use "{}"
+* Added the ability to passed parameters to all requests created by a client
+* Added callback functionality to the ExponentialBackoffPlugin
+* Using microtime in ExponentialBackoffPlugin to allow more granular backoff strategies.
+* Rewinding request stream bodies when retrying requests
+* Exception is thrown when JSON response body cannot be decoded
+* Added configurable magic method calls to clients and commands. This is off by default.
+* Fixed a defect that added a hash to every parsed URL part
+* Fixed duplicate none generation for OauthPlugin.
+* Emitting an event each time a client is generated by a ServiceBuilder
+* Using an ApiParams object instead of a Collection for parameters of an ApiCommand
+* cache.* request parameters should be renamed to params.cache.*
+* Added the ability to set arbitrary curl options on requests (disable_wire, progress, etc.). See CurlHandle.
+* Added the ability to disable type validation of service descriptions
+* ServiceDescriptions and ServiceBuilders are now Serializable
diff --git a/Server/vendor/guzzlehttp/guzzle/Dockerfile b/Server/vendor/guzzlehttp/guzzle/Dockerfile
new file mode 100755
index 000000000..f6a095230
--- /dev/null
+++ b/Server/vendor/guzzlehttp/guzzle/Dockerfile
@@ -0,0 +1,18 @@
+FROM composer:latest as setup
+
+RUN mkdir /guzzle
+
+WORKDIR /guzzle
+
+RUN set -xe \
+ && composer init --name=guzzlehttp/test --description="Simple project for testing Guzzle scripts" --author="Márk Sági-Kazár
This is first and only QR code reader that works without extensions.
+Ported from [ZXing library](https://github.com/zxing/zxing)
+
+
+## Installation
+The recommended method of installing this library is via [Composer](https://getcomposer.org/).
+
+Run the following command from your project root:
+
+```bash
+$ composer require khanamiryan/qrcode-detector-decoder
+```
+
+
+## Usage
+```php
+require __DIR__ . "/vendor/autoload.php";
+$qrcode = new QrReader('path/to_image');
+$text = $qrcode->text(); //return decoded text from QR Code
+```
+
+## Requirements
+* PHP >= 5.6
+* GD Library
+
+
+## Contributing
+
+You can help the project by adding features, cleaning the code, adding composer and other.
+
+
+1. Fork it
+2. Create your feature branch: `git checkout -b my-new-feature`
+3. Commit your changes: `git commit -am 'Add some feature'`
+4. Push to the branch: `git push origin my-new-feature`
+5. Submit a pull request
diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/composer.json b/Server/vendor/khanamiryan/qrcode-detector-decoder/composer.json
new file mode 100755
index 000000000..53267b89e
--- /dev/null
+++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/composer.json
@@ -0,0 +1,24 @@
+{
+ "name": "khanamiryan/qrcode-detector-decoder",
+ "type": "library",
+ "description": "QR code decoder / reader",
+ "keywords": ["qr", "zxing", "barcode"],
+ "homepage": "https://github.com/khanamiryan/php-qrcode-detector-decoder",
+ "license": "MIT",
+ "authors": [{
+ "name": "Ashot Khanamiryan",
+ "email": "a.khanamiryan@gmail.com",
+ "homepage": "https://github.com/khanamiryan",
+ "role": "Developer"
+ }],
+ "require": {
+ "php": "^5.6|^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7"
+ },
+ "autoload": {
+ "classmap": ["lib/"],
+ "files": ["lib/common/customFunctions.php"]
+ }
+}
diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/Binarizer.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/Binarizer.php
new file mode 100755
index 000000000..462113be3
--- /dev/null
+++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/Binarizer.php
@@ -0,0 +1,89 @@
+source = $source;
+ }
+
+ public final function getLuminanceSource() {
+ return $this->source;
+ }
+
+ /**
+ * Converts one row of luminance data to 1 bit data. May actually do the conversion, or return
+ * cached data. Callers should assume this method is expensive and call it as seldom as possible.
+ * This method is intended for decoding 1D barcodes and may choose to apply sharpening.
+ * For callers which only examine one row of pixels at a time, the same BitArray should be reused
+ * and passed in with each call for performance. However it is legal to keep more than one row
+ * at a time if needed.
+ *
+ * @param y The row to fetch, which must be in [0, bitmap height)
+ * @param row An optional preallocated array. If null or too small, it will be ignored.
+ * If used, the Binarizer will call BitArray.clear(). Always use the returned object.
+ * @return The array of bits for this row (true means black).
+ * @throws NotFoundException if row can't be binarized
+ */
+ public abstract function getBlackRow($y, $row);
+
+ /**
+ * Converts a 2D array of luminance data to 1 bit data. As above, assume this method is expensive
+ * and do not call it repeatedly. This method is intended for decoding 2D barcodes and may or
+ * may not apply sharpening. Therefore, a row from this matrix may not be identical to one
+ * fetched using getBlackRow(), so don't mix and match between them.
+ *
+ * @return The 2D array of bits for the image (true means black).
+ * @throws NotFoundException if image can't be binarized to make a matrix
+ */
+ public abstract function getBlackMatrix();
+
+ /**
+ * Creates a new object with the same type as this Binarizer implementation, but with pristine
+ * state. This is needed because Binarizer implementations may be stateful, e.g. keeping a cache
+ * of 1 bit data. See Effective Java for why we can't use Java's clone() method.
+ *
+ * @param source The LuminanceSource this Binarizer will operate on.
+ * @return A new concrete Binarizer implementation object.
+ */
+ public abstract function createBinarizer($source);
+
+ public final function getWidth() {
+ return $this->source->getWidth();
+ }
+
+ public final function getHeight() {
+ return $this->source->getHeight();
+ }
+
+}
diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/BinaryBitmap.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/BinaryBitmap.php
new file mode 100755
index 000000000..5b19b4312
--- /dev/null
+++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/BinaryBitmap.php
@@ -0,0 +1,152 @@
+binarizer = $binarizer;
+ }
+
+ /**
+ * @return The width of the bitmap.
+ */
+ public function getWidth() {
+ return $this->binarizer->getWidth();
+ }
+
+ /**
+ * @return The height of the bitmap.
+ */
+ public function getHeight() {
+ return $this->binarizer->getHeight();
+ }
+
+ /**
+ * Converts one row of luminance data to 1 bit data. May actually do the conversion, or return
+ * cached data. Callers should assume this method is expensive and call it as seldom as possible.
+ * This method is intended for decoding 1D barcodes and may choose to apply sharpening.
+ *
+ * @param y The row to fetch, which must be in [0, bitmap height)
+ * @param row An optional preallocated array. If null or too small, it will be ignored.
+ * If used, the Binarizer will call BitArray.clear(). Always use the returned object.
+ * @return The array of bits for this row (true means black).
+ * @throws NotFoundException if row can't be binarized
+ */
+ public function getBlackRow($y, $row) {
+ return $this->binarizer->getBlackRow($y, $row);
+ }
+
+ /**
+ * Converts a 2D array of luminance data to 1 bit. As above, assume this method is expensive
+ * and do not call it repeatedly. This method is intended for decoding 2D barcodes and may or
+ * may not apply sharpening. Therefore, a row from this matrix may not be identical to one
+ * fetched using getBlackRow(), so don't mix and match between them.
+ *
+ * @return The 2D array of bits for the image (true means black).
+ * @throws NotFoundException if image can't be binarized to make a matrix
+ */
+ public function getBlackMatrix(){
+// The matrix is created on demand the first time it is requested, then cached. There are two
+// reasons for this:
+// 1. This work will never be done if the caller only installs 1D Reader objects, or if a
+// 1D Reader finds a barcode before the 2D Readers run.
+// 2. This work will only be done once even if the caller installs multiple 2D Readers.
+ if ($this->matrix == null) {
+ $this->matrix = $this->binarizer->getBlackMatrix();
+ }
+ return $this->matrix;
+ }
+
+ /**
+ * @return Whether this bitmap can be cropped.
+ */
+ public function isCropSupported() {
+ return $this->binarizer->getLuminanceSource()->isCropSupported();
+ }
+
+ /**
+ * Returns a new object with cropped image data. Implementations may keep a reference to the
+ * original data rather than a copy. Only callable if isCropSupported() is true.
+ *
+ * @param left The left coordinate, which must be in [0,getWidth())
+ * @param top The top coordinate, which must be in [0,getHeight())
+ * @param width The width of the rectangle to crop.
+ * @param height The height of the rectangle to crop.
+ * @return A cropped version of this object.
+ */
+ public function crop($left, $top, $width, $height) {
+ $newSource = $this->binarizer->getLuminanceSource()->crop($left, $top, $width, $height);
+ return new BinaryBitmap($this->binarizer->createBinarizer($newSource));
+ }
+
+ /**
+ * @return Whether this bitmap supports counter-clockwise rotation.
+ */
+ public function isRotateSupported() {
+ return $this->binarizer->getLuminanceSource()->isRotateSupported();
+ }
+
+ /**
+ * Returns a new object with rotated image data by 90 degrees counterclockwise.
+ * Only callable if {@link #isRotateSupported()} is true.
+ *
+ * @return A rotated version of this object.
+ */
+ public function rotateCounterClockwise() {
+ $newSource = $this->binarizer->getLuminanceSource()->rotateCounterClockwise();
+ return new BinaryBitmap($this->binarizer->createBinarizer($newSource));
+ }
+
+ /**
+ * Returns a new object with rotated image data by 45 degrees counterclockwise.
+ * Only callable if {@link #isRotateSupported()} is true.
+ *
+ * @return A rotated version of this object.
+ */
+ public function rotateCounterClockwise45() {
+ $newSource = $this->binarizer->getLuminanceSource()->rotateCounterClockwise45();
+ return new BinaryBitmap($this->binarizer->createBinarizer($newSource));
+ }
+
+//@Override
+ public function toString() {
+ try {
+ return $this->getBlackMatrix()->toString();
+ } catch (NotFoundException $e) {
+ return "";
+ }
+ }
+
+}
diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/ChecksumException.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/ChecksumException.php
new file mode 100755
index 000000000..72446e1a8
--- /dev/null
+++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/ChecksumException.php
@@ -0,0 +1,44 @@
+GDLuminanceSource($gdImage,$dataWidth,$dataHeight);
+ return;
+ }
+ parent::__construct($width, $height);
+ if ($left + $width > $dataWidth || $top + $height > $dataHeight) {
+ throw new \InvalidArgumentException("Crop rectangle does not fit within image data.");
+ }
+ $this->luminances = $gdImage;
+ $this->dataWidth = $dataWidth;
+ $this->dataHeight = $dataHeight;
+ $this->left = $left;
+ $this->top = $top;
+ }
+
+ public function GDLuminanceSource($gdImage, $width, $height)
+ {
+ parent::__construct($width, $height);
+
+ $this->dataWidth = $width;
+ $this->dataHeight = $height;
+ $this->left = 0;
+ $this->top = 0;
+ $this->$gdImage = $gdImage;
+
+
+// In order to measure pure decoding speed, we convert the entire image to a greyscale array
+// up front, which is the same as the Y channel of the YUVLuminanceSource in the real app.
+ $this->luminances = array();
+ //$this->luminances = $this->grayScaleToBitmap($this->grayscale());
+
+ $array = array();
+ $rgb = array();
+
+for($j=0;$j<$height;$j++){
+ for($i=0;$i<$width;$i++){
+ $argb = imagecolorat($this->$gdImage, $i, $j);
+ $pixel = imagecolorsforindex($this->$gdImage, $argb);
+ $r = $pixel['red'];
+ $g = $pixel['green'];
+ $b = $pixel['blue'];
+ if ($r == $g && $g == $b) {
+// Image is already greyscale, so pick any channel.
+
+ $this->luminances[] = $r;//(($r + 128) % 256) - 128;
+ } else {
+// Calculate luminance cheaply, favoring green.
+ $this->luminances[] = ($r+2*$g+$b)/4;//(((($r + 2 * $g + $b) / 4) + 128) % 256) - 128;
+ }
+ }
+}
+
+
+
+ /*
+
+ for ($y = 0; $y < $height; $y++) {
+ $offset = $y * $width;
+ for ($x = 0; $x < $width; $x++) {
+ $pixel = $pixels[$offset + $x];
+ $r = ($pixel >> 16) & 0xff;
+ $g = ($pixel >> 8) & 0xff;
+ $b = $pixel & 0xff;
+ if ($r == $g && $g == $b) {
+// Image is already greyscale, so pick any channel.
+
+ $this->luminances[intval($offset + $x)] = (($r+128) % 256) - 128;
+ } else {
+// Calculate luminance cheaply, favoring green.
+ $this->luminances[intval($offset + $x)] = (((($r + 2 * $g + $b) / 4)+128)%256) - 128;
+ }
+
+
+
+ }
+ */
+ //}
+ // $this->luminances = $this->grayScaleToBitmap($this->luminances);
+
+ }
+
+//@Override
+ public function getRow($y, $row=null) {
+ if ($y < 0 || $y >= $this->getHeight()) {
+ throw new \InvalidArgumentException("Requested row is outside the image: " + y);
+ }
+ $width = $this->getWidth();
+ if ($row == null || count($row) < $width) {
+ $row = array();
+ }
+ $offset = ($y + $this->top) * $this->dataWidth + $this->left;
+ $row = arraycopy($this->luminances,$offset, $row, 0, $width);
+ return $row;
+ }
+
+//@Override
+ public function getMatrix() {
+ $width = $this->getWidth();
+ $height = $this->getHeight();
+
+// If the caller asks for the entire underlying image, save the copy and give them the
+// original data. The docs specifically warn that result.length must be ignored.
+ if ($width == $this->dataWidth && $height == $this->dataHeight) {
+ return $this->luminances;
+ }
+
+ $area = $width * $height;
+ $matrix = array();
+ $inputOffset = $this->top * $this->dataWidth + $this->left;
+
+// If the width matches the full width of the underlying data, perform a single copy.
+ if ($width == $this->dataWidth) {
+ $matrix = arraycopy($this->luminances, $inputOffset, $matrix, 0, $area);
+ return $matrix;
+ }
+
+// Otherwise copy one cropped row at a time.
+ $rgb = $this->luminances;
+ for ($y = 0; $y < $height; $y++) {
+ $outputOffset = $y * $width;
+ $matrix = arraycopy($rgb, $inputOffset, $matrix, $outputOffset, $width);
+ $inputOffset += $this->dataWidth;
+ }
+ return $matrix;
+ }
+
+//@Override
+ public function isCropSupported() {
+ return true;
+ }
+
+//@Override
+ public function crop($left, $top, $width, $height) {
+ return new GDLuminanceSource($this->luminances,
+ $this->dataWidth,
+ $this->dataHeight,
+ $this->left + $left,
+ $this->top + $top,
+ $width,
+ $height);
+ }
+
+}
diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/IMagickLuminanceSource.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/IMagickLuminanceSource.php
new file mode 100755
index 000000000..3f0a26ea6
--- /dev/null
+++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/IMagickLuminanceSource.php
@@ -0,0 +1,149 @@
+_IMagickLuminanceSource($image,$dataWidth,$dataHeight);
+ return;
+ }
+ parent::__construct($width, $height);
+ if ($left + $width > $dataWidth || $top + $height > $dataHeight) {
+ throw new \InvalidArgumentException("Crop rectangle does not fit within image data.");
+ }
+ $this->luminances = $image;
+ $this->dataWidth = $dataWidth;
+ $this->dataHeight = $dataHeight;
+ $this->left = $left;
+ $this->top = $top;
+ }
+
+ public function _IMagickLuminanceSource($image, $width, $height)
+ {
+ parent::__construct($width, $height);
+
+ $this->dataWidth = $width;
+ $this->dataHeight = $height;
+ $this->left = 0;
+ $this->top = 0;
+ $this->image = $image;
+
+
+// In order to measure pure decoding speed, we convert the entire image to a greyscale array
+// up front, which is the same as the Y channel of the YUVLuminanceSource in the real app.
+ $this->luminances = array();
+
+ $image->setImageColorspace (\Imagick::COLORSPACE_GRAY);
+ // $image->newPseudoImage(0, 0, "magick:rose");
+ $pixels = $image->exportImagePixels(1, 1, $width, $height, "RGB", \Imagick::COLORSPACE_RGB);
+
+ $array = array();
+ $rgb = array();
+
+
+ for($i=0;$i
Gets the requested bit, where true means black.
+ * + * @param $x; The horizontal component (i.e. which column) + * @param $y; The vertical component (i.e. which row) + * @return value of given bit in matrix + */ + public function get($x, $y) { + + $offset = intval($y * $this->rowSize + ($x / 32)); + if(!isset($this->bits[$offset])){ + $this->bits[$offset] = 0; + } + + // return (($this->bits[$offset] >> ($x & 0x1f)) & 1) != 0; + return (uRShift($this->bits[$offset],($x & 0x1f)) & 1) != 0;//было >>> вместо >>, не знаю как эмулировать беззнаковый сдвиг + } + + /** + *Sets the given bit to true.
+ * + * @param $x; The horizontal component (i.e. which column) + * @param $y; The vertical component (i.e. which row) + */ + public function set($x, $y) { + $offset = intval($y * $this->rowSize + ($x / 32)); + if(!isset($this->bits[$offset])){ + $this->bits[$offset] = 0; + } + //$this->bits[$offset] = $this->bits[$offset]; + + // if($this->bits[$offset]>200748364){ + //$this->bits= array(0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-1090519040,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,1056964608,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-1358954496,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,117440512,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,50331648,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,33554432,-1,-1,536870911,-4096,65279,0,0,0,0,0,0,0,0,-1,-1,65535,-4096,65535,0,0,0,0,0,0,0,0,-193,536870911,0,-4096,65279,0,0,0,0,0,0,0,0,-254,32767,0,-4096,61951,0,0,0,0,0,0,0,0,20913920,0,0,-4096,50175,0,0,0,0,0,0,0,0,0,0,0,-4096,60159,0,0,0,0,0,0,0,0,0,0,0,-4096,64255,0,0,0,0,0,0,0,0,0,0,0,-8192,56319,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,251658240,0,0,0,-4096,-1,255,0,256,0,0,0,0,117440512,0,0,0,-4096,-1,255,0,512,0,0,0,0,117440512,0,0,0,-4096,-1,255,0,1024,0,0,0,0,117440512,0,0,0,-4096,-1,223,0,256,0,0,0,0,117440512,0,0,33030144,-4096,-1,191,0,256,0,0,0,0,117440512,0,0,33554428,-4096,-1,255,0,768,0,0,0,0,117440512,0,402849792,67108862,-8192,-1,255,0,768,0,0,0,0,117440512,0,470278396,63045630,-8192,-1,255,0,256,0,0,0,0,251658240,-8388608,470278399,58720286,-8192,-1,2686975,0,3842,0,0,0,0,251658240,-131072,1007149567,58720286,-8192,-1,2031615,0,3879,0,0,0,0,251658240,536739840,1007092192,58720286,-8192,-1,851967,0,3840,0,0,0,0,251658240,917504,1007092192,58720284,-8192,-1,2031615,0,3968,0,0,0,0,251658240,917504,1007092160,59244060,-8192,-1,65535,0,7936,0,0,0,0,251658240,917504,1009779136,59244060,-8192,-1,9371647,0,1792,0,0,0,0,251658240,917504,946921920,59244060,-8192,-1,8585215,0,1792,0,0,0,0,117440512,-15859712,477159875,59244060,-8192,-1,65535,0,12032,0,0,0,0,251658240,-15859712,52490691,59244060,-8192,-1,-1,0,65408,0,0,0,0,251658240,-15859712,58778051,59244060,-8192,-1,-1,0,65473,0,0,0,0,251658240,-15859712,125886915,59244060,-8192,-1,-1,0,65472,0,0,0,0,251658240,-15859712,58778051,59244060,-8192,-1,-1,0,65408,0,0,0,0,251658240,-15859712,8380867,59244060,-8192,-1,-1,0,65473,0,0,0,0,251658240,-15859712,8380867,59244060,-8192,-1,-1,0,131011,0,0,0,0,251658240,-15859712,8380867,58720284,-8192,-1,-1,0,130947,0,0,0,0,251658240,-15859712,2089411,58720284,-8192,-1,-1,0,130947,0,0,0,0,251658240,-32636928,449,58720284,-8192,-1,-1,33554431,131015,0,0,0,0,251658240,786432,448,62914588,-8192,-1,-1,16777215,131015,0,0,0,0,251658240,786432,448,67108860,-8192,-1,-1,553648127,131015,0,0,0,0,251658240,786432,946864576,67108860,-8192,-1,-1,32505855,131015,0,0,0,0,251658240,786432,946921976,8388604,-8192,-1,-1,8191999,131015,0,0,0,0,251658240,-262144,946921983,248,-8192,-1,-1,8126463,196551,0,0,0,0,251658240,-262144,7397887,0,-8192,-1,-1,16777215,262087,0,0,0,0,251658240,-262144,8257543,0,-8192,-1,-1,-2121269249,262095,0,0,0,0,520093696,0,8257536,0,-8192,-1,-1,-201326593,262095,0,0,0,0,520290304,0,8257536,117963776,-8192,-1,-1,-201326593,262095,0,0,0,0,520093696,0,-2140143616,118488579,-8192,-1,-1,-201326593,131023,0,0,0,0,520093696,0,-2131697280,118488579,-8192,-1,-1,-503316481,131023,0,0,0,0,520093696,2145386496,-2131631232,118484995,-16384,-1,-1,-469762049,262095,0,0,0,0,520093696,2147221504,552649600,118481344,-16384,-1,-1,-469762049,131023,0,0,0,0,520290304,2147221504,2029002240,118481344,-16384,-1,-1,-469762049,262031,0,0,0,0,520290304,-266600448,2029001791,125952960,-16384,-1,-1,-469762049,262031,0,0,0,0,1057423360,-266600448,2027953215,133177312,-16384,-1,-1,-134217729,262111,0,0,0,0,1058471936,-266600448,-119531393,133177343,-16384,-1,-1,-134217729,262111,0,0,0,0,1058471936,-2145648640,-253754369,66068479,-16384,-1,-1,-134217729,262111,0,0,0,0,1058471936,236716032,-253754369,15729663,-16384,-1,-1,-134217729,262095,0,0,0,0,1057947648,236716032,-253754369,6348807,-16384,-1,-1,-134217729,262095,0,0,0,0,524222464,236716032,-253690305,6348803,-16384,-1,-1,-134217729,262111,0,0,0,0,521076736,2115764224,-253625344,14737411,-16384,-1,-1,-134217729,262095,0,0,0,0,522125312,2115764224,-253625344,14743555,-16384,-1,-1,-134217729,262111,0,0,16772608,0,1073676288,-31719424,-2014283776,14810115,-16384,-1,-1,-1,262143,0,0,16776704,0,1065287680,-1642594304,-1879178880,14810115,-16384,-1,-1,-1,524287,0,0,16776192,0,2139029504,264241152,-2013396089,14809091,-16384,-1,-1,-1,262095,0,0,16776192,0,2139029504,264241152,-2080636025,14803335,-16384,-1,-1,-1,262087,0,0,16776192,0,2147418112,264241152,-2132803581,14803847,-16384,-1,-1,-402653185,524259,0,0,8386048,0,2147418112,0,-2132688896,123783,-16384,-1,-1,1207959551,262112,0,0,16775168,0,2147418112,0,14794752,1046535,-16384,-1,-1,268435455,262128,0,0,16775168,0,2147418112,0,14712832,1047615,-16384,-1,-1,536870911,524284,0,0,16776705,0,2147418112,0,14680832,1047615,-16384,-1,-1,-1,524287,0,0,16776704,0,2147418112,-1048576,14681087,1046591,-32768,-1,-1,-1,524287,0,0,16776704,0,2147418112,-524288,-2132802561,2080831,-32768,-1,-1,-1,524287,0,0,16776705,0,2147418112,-524288,-31718401,2080831,-32768,-1,-1,-1,1048575,0,0,16776193,0,2147418112,3670016,-31718528,2080831,-32768,-1,-1,-1,524287,0,0,16776195,0,2147418112,3670016,-31718528,134086719,-32768,-1,-1,-1,524287,0,0,16776195,0,2147418112,3670016,253494144,268173368,-32768,-1,-1,-1,524287,0,0,16775171,0,2147418112,3670016,268174208,268173368,-32768,-1,-1,-1,1048575,0,0,16771072,0,2147418112,-63438848,268174223,31457328,-32768,-1,-1,-1,1048575,0,0,10418176,0,-65536,-63438848,133957519,14807040,-32768,-1,-1,-1,2097151,0,0,15923200,0,2147418112,-63438848,1968015,14809095,-32768,-1,-1,-1,1048575,0,0,12808192,0,2147418112,-63438848,2082703,12711943,-32768,-1,-1,-1,2097151,0,0,6420480,0,2147418112,-63438848,2082703,14343,-32768,-1,-1,-1,2097151,0,0,15202304,0,-65536,-63438848,2082703,1849351,-32768,-1,-1,-1,2097151,0,0,15464448,0,-65536,-63438848,264472335,1849351,-32768,-1,-1,-1,4194303,0,0,16371712,0,-65536,-63438848,264472335,14343,-32768,-1,-1,-1,8388607,0,0,0,0,-65536,-63438848,532907791,235010048,-32768,-1,-1,-1,16777215,0,0,0,0,-65536,-63438848,-1603833,235010160,-32768,-1,-1,-1,16777215,0,0,0,0,-65536,3670016,-30976,67238000,-32768,-1,-1,-1,16777215,0,0,0,0,-65536,3670016,-30976,48,-32768,-1,-1,-1,16777215,0,0,0,0,-65536,3670016,-29391104,768,-32768,-1,-1,-1,16777215,0,0,0,0,-65536,3670016,-29391104,768,-32768,-1,-1,-1,16777215,0,0,0,0,-65536,-524287,-65042433,768,-32768,-1,-1,-1,16777215,0,0,0,0,-65536,-524287,2082441215,0,-65536,-1,-1,-1,16777215,0,0,0,0,-13697024,-524287,511,0,-65536,-1,-1,-1,16777215,0,0,0,0,-12648448,1,0,0,-65536,-1,-1,-1,14680063,0,0,0,0,-12648448,1,0,0,-65536,-1,-1,-1,16777215,0,0,0,0,-65536,1,0,0,-65536,-1,-1,-1,14680063,0,0,0,0,-8454144,1,0,0,-65536,-1,-1,-1,12582911,0,0,0,0,-12648448,1,0,0,-65536,-1,-1,-1,2097151,0,0,0,0,-12648448,1,0,0,-65536,-1,-1,-1,1048575,0,0,0,0,-14745600,1,0,0,-65536,-1,-1,-1,3145727,0,0,0,0,1056964608,1,0,0,-65536,-1,-1,-1,1048575,0,0,0,0,1056964608,1,0,0,-65536,-1,-1,-1,1048575,0,0,0,0,1056964608,1,0,0,-65536,-1,-1,-1,524287,0,0,0,0,2130706432,1,0,0,-65536,-1,-1,-1,1048575,0,0,0,0,1056964608,1,0,0,-65536,-1,-1,-1,524287,0,0,0,0,2130706432,1,0,0,-65536,-1,-1,-1,524287,0,0,0,0,2130706432,1,0,0,-65536,-1,-1,-1,1048575,0,0,0,0,2130706432,1,0,0,-65536,-1,-1,-1,1048575,0,0,0,0,50331648,1,0,0,-65536,-1,-1,-1,1048575,0,0,0,0,117440512,1,0,-268435456,-1,-1,-1,-1,524287,0,0,0,0,251658240,1,0,-320,-1,-1,-1,-1,262143,0,0,0,0,520093696,1,-2048,-1,-1,-1,-1,-1,262143,0,0,0,0,1056964608,-16777213,-1,-1,-1,-1,-1,-1,131071,0,0,0,0,-16777216,-121,-1,-1,-1,-1,-1,-1,131071,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,131071,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,131071,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,131071,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,65535,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,65535,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,131071,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,262143,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,524287,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,524287,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,589823,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,8179,0,0,0,0,50331648,-1,-1,-1,-1,-1,-1,-1,4080,0,0,0,0,117440512,-1,-1,-1,-1,-1,-1,-1,1016,0,0,0,0,251658240,-1,-1,-1,-1,-1,-1,1073741823,1020,0,0,0,0,50331648,-1,-1,-1,-1,-1,-1,536870911,254,0,0,0,0,50331648,-1,-1,-1,-1,-1,-1,536870911,255,0,0,0,0,50331648,-1,-1,-1,-1,-1,-1,-1879048193,127,0,0,0,0,50331648,-1,-1,-1,-1,-1,-1,-469762049,63,0,0,0,0,1191182336,-1,-1,-1,-1,1023999,0,-520093712,15,0,0,0,0,-218103808,-1,-1,-1,-1,0,-8454144,-260046849,7,0,0,0,0,0,-193,-1,-1,-1057947649,-2147483648,-1,-58720257,1,0,0,0,0,0,-251,-1,-1,-1057423361,-2074,-1,-1,0,0,0,0,0,0,-59648,-1,-1,-1,-1,-1,1073741823,0,0,0,0,0,0,-65536,-1,-1,-1,-1,-1,268435455,0,0,0,0,0,0,-65536,-1,-1,-1,-1,-1,67108863,0,0,0,0,0,0,-65536,-1,-1,-1,-1,-1,8388607,0,0,0,0,0,0,0,-403603456,-1,-1,-1,-1,262143,0,0,0,8388656,0,0,0,-1891434496,-1,-1,-1,-1,16383,0,0,0,8388608,0,0,0,-1612513280,-1,-1,-1,-1,63,0,0,0,0,0,0,0,-24320,-1,-1,-1,8388607,0,0,0,0,0,0,0,0,-256,-1,-1,1073741823,1,0,0,0,0,0,0,0,1610612736,-15,-1,-1,16383,0,0,0,0,0,0,0,0,-16646144,-1,-1,251658239,0,0,0,0,0,0,0,0,0,-51200,-1,-1,40959,0,0,0,0,0,0,268419584,103809024,-12713984,-1,-2147483137,4194303,0,0,0,0,0,0,0,402620416,-2144010240,-13631487,-32513,3,20480,0,0,0,0,0,0,0,419299328,0,-262144,-1,0,0,0,0,0,0,0,0,0,0,0,-5832704,268049407,0,0,0,0,0,0,0,0,0,0,0,0,33030144,0,0,0,0,0,0,0,0,0,0,0,0,3670016,0,0,0,0,0,0,0,0,0,0,0,0,1572864,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,458752,0,0,0,0,0,0,0,0,0,0,0,0,229376,0,0,0,0,0,0,0,0,0,0,0,0,32768,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8192,0,0,0,0,0,0,0,0,0,0,0,0,8192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31744,0,0,0,0,0,0,0,0,0,0,0,0,31744,0,0,0,0,0,0,0,0,0,0,0,0,64512,0,0,0,0,0,0,0,0,0,0,0,0,15872,0,0,0,0,0,0,0,0,0,0,0,0,3584,0,0,0,0,0,0,0,0,0,0,0,0,7680,0,0,0,0,0,0,0,0,0,0,0,0,512,0,0,0,0,0,0,0,0,0,0,0,0,3968,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3840,0,0,0,0,0,0,0,0,0,0,0,0,1855,0,0,0,0,0,0,0,0,0,0,0,0,63,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,134217728,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,124,0,0,0,0,0,0,0,0,0,0,0,-260046848,63,0,0,0,0,0,0,0,0,0,0,0,-17301504,127,0,0,0,0,0,0,0,0,0,0,0,-524288,127,0,0,0,0,0,0,0,0,0,0,0,-262144,127,0,0,0,0,0,0,0,0,0,0,0,-262144,63,0,0,0,0,0,0,0,0,0,0,0,-262144,63,0,0,0,0,0,0,0,0,0,0,0,-262144,63,0,0,0,0,0,0,0,0,0,0,0,-262144,31,0,0,0,0,0,0,0,0,0,0,0,-262144,63,0,0,0,0,3,0,0,0,0,0,0,-262144,63,0,0,0,0,7,0,0,0,0,0,0,-262144,63,0,0,0,0,63,0,0,0,0,0,0,-262144,63,0,0,0,0,511,0,0,0,0,0,0,-524288,31,0,0,0,0,8191,0,0,0,0,0,0,-1048576,63,0,0,0,0,131071,0,0,0,0,0,0,-524288,63,0,0,0,0,262143,0,0,0,0,0,0,-524288,63,0,0,0,0,131071,0,0,0,0,0,0,-1048576,63,0,0,0,0,262143,0,0,0,0,0,0,-1048576,63,0,0,0,0,262143,0,0,0,0,0,0,-1048576,63,0,0,0,0,262143,0,0,0,0,0,0,-1048576,63,0,0,0,0,262143,0,0,0,0,0,0,-2097152,127,0,0,0,0,262143,0,0,0,0,0,0,-2097152,127,0,0,0,0,262143,0,0,0,0,0,0,-1048576,127,0,0,0,0,262143,0,0,0,0,0,0,-1048576,127,0,0,0,0,262143,0,0,0,0,0,0,-2097152,255,0,0,0,0,262143,0,0,0,0,0,0,-2097152,255,0,0,0,0,262142,0,0,0,0,0,0,-2097152,255,0,0,0,0,262142,0,0,0,0,0,0,-2097152,255,0,0,0,0,262142,0,0,0,0,0,0,-2097152,255,0,0,0,0,262140,0,0,0,0,0,0,-2097152,255,0,0,0,0,131068,0,0,0,0,0,0,-4194304,255,0,0,0,0,131068,0,0,0,0,0,0,-4194304,255,0,0,0,0,65528,0,0,0,0,0,0,-8388608,255,0,0,0,0,65528,0,0,0,0,0,0,-8388608,255,0,0,0,0,65528,0,0,0,0,0,0,-8388608,255,0,0,0,0,32760,0,0,0,0,0,0,-8388608,255,0,0,0,0,32760,0,0,0,0,0,0,-16777216,255,0,0,-2147483648,255,16368,0,0,0,0,0,0,-16777216,255,0,0,-536870912,1023,16368,0,0,0,0,0,0,-33554432,255,0,0,-16777216,4095,16352,0,0,0,0,0,0,-33554432,255,0,0,-8388608,262143,16352,0,0,0,0,0,0,-33554432,255,0,0,-1048576,2097151,16352,0,0,0,0,0,0,-67108864,255,0,0,-524288,8388607,16352,0,0,0,0,0,0,-67108864,255,0,0,-262144,16777215,16320,0,0,0,0,0,0,-67108864,255,0,0,-131072,16777215,100679648,0,0,0,0,0,0,-67108864,255,0,0,-16384,16776959,125861824,0,0,0,0,0,0,-134217728,255,0,0,-4096,16773121,62930880,0,0,0,0,0,0,-134217728,127,0,0,2147482624,16252928,32704,0,0,0,0,0,0,-134217728,127,0,0,268435200,14680064,16320,0,0,0,0,0,0,-134217728,127,0,0,134217600,0,32704,0,0,0,0,0,0,-33554432,127,0,1056964608,67108736,0,32704,0,0,0,0,0,0,-33554432,127,0,2130706432,33554368,0,65408,0,0,0,0,0,0,-33554432,127,0,-16777216,8388576,0,32640,0,0,0,0,0,0,-134217728,127,0,-16777216,2097136,0,32640,0,0,0,0,0,0,-134217728,63,0,-16776960,1048573,0,32640,0,0,0,0,0,0,-536870912,63,0,-16776448,1048575,0,32640,0,0,0,0,0,0,-536870912,63,0,-33553664,6291455,66752,32640,0,0,0,0,0,0,-536870912,63,0,2013266688,2097148,229376,32640,0,0,0,0,0,0,-536870912,63,0,256,4194300,229376,32640,0,0,0,0,0,0,-536870912,63,0,0,524280,196608,32512,0,0,8,0,0,0,-1073741824,63,0,0,-200,15,65280,0,0,24,0,0,0,-1073741824,63,0,0,-1867768,127,32512,0,0,56,0,0,0,-1073741824,63,0,0,-1056768,4095,32512,0,0,124,0,0,0,-1073741824,63,0,0,-1050624,8191,32512,0,0,508,0,0,0,-2147483648,31,0,0,-7866368,8191,32512,0,0,1020,0,0,0,-2147483648,31,0,0,-33030656,8095,32512,0,0,2046,0,0,0,-2147483648,63,0,0,-66586624,771,32512,0,0,4094,0,0,0,0,63,0,0,-134184960,1,32256,0,0,8190,0,0,0,0,63,0,0,1610612736,0,32256,0,0,16382,0,0,0,-2147483648,63,0,0,0,0,15872,0,0,32767,0,0,0,-2147483648,31,0,0,0,0,15872,0,-2147483648,65535,0,0,0,-2147483648,31,0,0,0,0,7680,0,0,65535,0,0,0,-2147483648,31,0,0,134217728,0,7680,0,-2147483648,65535,0,0,0,-2147483648,31,0,0,0,0,7680,0,-2147483648,65535,0,0,0,-2147483648,31,0,0,0,0,7680,0,-1073741824,65535,0,0,0,-2147483648,31,0,0,0,0,3072,0,-1073741824,65535,0,0,0,-2147483648,31,0,0,0,0,3072,0,-1073741824,65535,0,0,0,-2147483648,31,0,0,0,0,0,0,-2147483648,65535,0,0,0,-2147483648,31,0,0,0,0,0,0,-1073741824,65535,0,0,0,0,31,0,0,0,0,0,0,-1073741824,65535,0,0,0,0,31,0,0,0,0,0,0,-2147483648,65535,0,0,0,0,30,0,0,0,0,0,0,-1073741824,65535,0,0,0,0,30,0,0,0,0,0,0,-2147483648,65535,0,0,0,0,30,0,0,0,0,0,0,0,65535,0,0,0,0,28,0,0,0,0,0,0,0,65535,0,0,0,0,28,0,0,0,0,0,0,0,65535,0,0,0,0,28,0,0,0,0,0,0,0,65535,0,0,0,0,24,0,0,0,0,0,0,-2147483648,65535,0,0,0,0,0,0,0,0,0,0,0,-536870912,65535);//[$offset] |= intval32bits(1 << ($x & 0x1f)); + $bob = $this->bits[$offset]; + $bob |= 1 << ($x & 0x1f); + $this->bits[$offset] |= overflow32($bob); + //$this->bits[$offset] = intval32bits($this->bits[$offset]); + + //} +//16777216 + } + + public function _unset($x, $y) {//было unset, php не позволяет использовать unset + $offset = intval($y * $this->rowSize + ($x / 32)); + $this->bits[$offset] &= ~(1 << ($x & 0x1f)); + } + + + /**1 << (249 & 0x1f) + *Flips the given bit.
+ * + * @param $x; The horizontal component (i.e. which column) + * @param $y; The vertical component (i.e. which row) + */ + public function flip($x, $y) { + $offset = $y * $this->rowSize + intval($x / 32); + + $this->bits[$offset] = overflow32($this->bits[$offset]^(1 << ($x & 0x1f))); + } + + /** + * Exclusive-or (XOR): Flip the bit in this {@code BitMatrix} if the corresponding + * mask bit is set. + * + * @param $mask; XOR mask + */ + public function _xor($mask) {//было xor, php не позволяет использовать xor + if ($this->width != $mask->getWidth() || $this->height != $mask->getHeight() + || $this->rowSize != $mask->getRowSize()) { + throw new \InvalidArgumentException("input matrix dimensions do not match"); + } + $rowArray = new BitArray($this->width / 32 + 1); + for ($y = 0; $y < $this->height; $y++) { + $offset = $y * $this->rowSize; + $row = $mask->getRow($y, $rowArray)->getBitArray(); + for ($x = 0; $x < $this->rowSize; $x++) { + $this->bits[$offset + $x] ^= $row[$x]; + } + } + } + + /** + * Clears all bits (sets to false). + */ + public function clear() { + $max = count($this->bits); + for ($i = 0; $i < $max; $i++) { + $this->bits[$i] = 0; + } + } + + /** + *Sets a square region of the bit matrix to true.
+ * + * @param $left; The horizontal position to begin at (inclusive) + * @param $top; The vertical position to begin at (inclusive) + * @param $width; The width of the region + * @param $height; The height of the region + */ + public function setRegion($left, $top, $width, $height) { + if ($top < 0 || $left < 0) { + throw new \InvalidArgumentException("Left and top must be nonnegative"); + } + if ($height < 1 || $width < 1) { + throw new \InvalidArgumentException("Height and width must be at least 1"); + } + $right = $left + $width; + $bottom = $top + $height; + if ($bottom > $this->height || $right > $this->width) { //> this.height || right > this.width + throw new \InvalidArgumentException("The region must fit inside the matrix"); + } + for ($y = $top; $y < $bottom; $y++) { + $offset = $y * $this->rowSize; + for ($x = $left; $x < $right; $x++) { + $this->bits[$offset + intval($x / 32)] = overflow32($this->bits[$offset + intval($x / 32)]|= 1 << ($x & 0x1f)); + } + } + } + + /** + * A fast method to retrieve one row of data from the matrix as a BitArray. + * + * @param $y; The row to retrieve + * @param $row; An optional caller-allocated BitArray, will be allocated if null or too small + * @return The resulting BitArray - this reference should always be used even when passing + * your own row + */ + public function getRow($y, $row) { + if ($row == null || $row->getSize() < $this->width) { + $row = new BitArray($this->width); + } else { + $row->clear(); + } + $offset = $y * $this->rowSize; + for ($x = 0; $x < $this->rowSize; $x++) { + $row->setBulk($x * 32, $this->bits[$offset + $x]); + } + return $row; + } + + /** + * @param $y; row to set + * @param $row; {@link BitArray} to copy from + */ + public function setRow($y, $row) { + $this->bits = arraycopy($row->getBitArray(), 0, $this->bits, $y * $this->rowSize, $this->rowSize); + } + + /** + * Modifies this {@code BitMatrix} to represent the same but rotated 180 degrees + */ + public function rotate180() { + $width = $this->getWidth(); + $height = $this-getHeight(); + $topRow = new BitArray($width); + $bottomRow = new BitArray($width); + for ($i = 0; $i < ($height+1) / 2; $i++) { + $topRow = $this->getRow($i, $topRow); + $bottomRow = $this->getRow($height - 1 - $i, $bottomRow); + $topRow->reverse(); + $bottomRow->reverse(); + $this->setRow($i, $bottomRow); + $this->setRow($height - 1 - $i, $topRow); + } + } + + /** + * This is useful in detecting the enclosing rectangle of a 'pure' barcode. + * + * @return {@code left,top,width,height} enclosing rectangle of all 1 bits, or null if it is all white + */ + public function getEnclosingRectangle() { + $left = $this->width; + $top = $this->height; + $right = -1; + $bottom = -1; + + for ($y = 0; $y < $this->height; $y++) { + for ($x32 = 0; $x32 < $this->rowSize; $x32++) { + $theBits = $this->bits[$y * $this->rowSize + $x32]; + if ($theBits != 0) { + if ($y < $top) { + $top = $y; + } + if ($y > $bottom) { + $bottom = $y; + } + if ($x32 * 32 < $left) { + $bit = 0; + while (($theBits << (31 - $bit)) == 0) { + $bit++; + } + if (($x32 * 32 + $bit) < $left) { + $left = $x32 * 32 + $bit; + } + } + if ($x32 * 32 + 31 > $right) { + $bit = 31; + while ((sdvig3($theBits, $bit)) == 0) {//>>> + $bit--; + } + if (($x32 * 32 + $bit) > $right) { + $right = $x32 * 32 + $bit; + } + } + } + } + } + + $width = $right - $left; + $height = $bottom - $top; + + if ($width < 0 || $height < 0) { + return null; + } + + return array($left, $top, $width, $height); + } + + /** + * This is useful in detecting a corner of a 'pure' barcode. + * + * @return {@code x,y} coordinate of top-left-most 1 bit, or null if it is all white + */ + public function getTopLeftOnBit() { + $bitsOffset = 0; + while ($bitsOffset < count($this->bits) && $this->bits[$bitsOffset] == 0) { + $bitsOffset++; + } + if ($bitsOffset == count($this->bits)) { + return null; + } + $y = $bitsOffset / $this->rowSize; + $x = ($bitsOffset % $this->rowSize) * 32; + + $theBits = $this->bits[$bitsOffset]; + $bit = 0; + while (($theBits << (31-$bit)) == 0) { + $bit++; + } + $x += $bit; + return array($x, $y); + } + + public function getBottomRightOnBit() { + $bitsOffset = count($this->bits) - 1; + while ($bitsOffset >= 0 && $this->bits[$bitsOffset] == 0) { + $bitsOffset--; + } + if ($bitsOffset < 0) { + return null; + } + + $y = $bitsOffset / $this->rowSize; + $x = ($bitsOffset % $this->rowSize) * 32; + + $theBits = $this->bits[$bitsOffset]; + $bit = 31; + while ((sdvig3($theBits, $bit)) == 0) {//>>> + $bit--; + } + $x += $bit; + + return array($x, $y); + } + + /** + * @return The width of the matrix + */ + public function getWidth() { + return $this->width; + } + + /** + * @return The height of the matrix + */ + public function getHeight() { + return $this->height; + } + + /** + * @return The row size of the matrix + */ + public function getRowSize() { + return $this->rowSize; + } + + //@Override + public function equals($o) { + if (!($o instanceof BitMatrix)) { + return false; + } + $other = $o; + return $this->width == $other->width && $this->height == $other->height && $this->rowSize == $other->rowSize && + $this->bits===$other->bits; + } + + //@Override + public function hashCode() { + $hash = $this->width; + $hash = 31 * $hash + $this->width; + $hash = 31 * $hash + $this->height; + $hash = 31 * $hash + $this->rowSize; + $hash = 31 * $hash + hashCode($this->bits); + return $hash; + } + + //@Override + public function toString($setString='', $unsetString='',$lineSeparator='') { + if(!$setString||!$unsetString){ + return (string)"X "." "; + } + if($lineSeparator&&$lineSeparator!=="\n"){ + return $this->toString_($setString, $unsetString, $lineSeparator); + } + return (string)($setString. $unsetString. "\n"); + } + + /** + * @deprecated call {@link #toString(String,String)} only, which uses \n line separator always + */ + // @Deprecated + public function toString_($setString, $unsetString, $lineSeparator) { + //$result = new StringBuilder(height * (width + 1)); + $result = ''; + for ($y = 0; $y < $this->height; $y++) { + for ($x = 0; $x < $this->width; $x++) { + $result .= ($this->get($x, $y) ? $setString : $unsetString); + } + $result .= ($lineSeparator); + } + return (string)$result; + } + +// @Override + public function _clone() {//clone() + return new BitMatrix($this->width, $this->height, $this->rowSize, $this->bits); + } + +} \ No newline at end of file diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/BitSource.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/BitSource.php new file mode 100755 index 000000000..058550699 --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/BitSource.php @@ -0,0 +1,112 @@ +This provides an easy abstraction to read bits at a time from a sequence of bytes, where the + * number of bits read is not often a multiple of 8. + * + *This class is thread-safe but not reentrant -- unless the caller modifies the bytes array + * it passed in, in which case all bets are off.
+ * + * @author Sean Owen + */ +final class BitSource { + + private $bytes; + private $byteOffset = 0; + private $bitOffset = 0; + + /** + * @param bytes bytes from which this will read bits. Bits will be read from the first byte first. + * Bits are read within a byte from most-significant to least-significant bit. + */ + public function __construct($bytes) { + $this->bytes = $bytes; + } + + /** + * @return index of next bit in current byte which would be read by the next call to {@link #readBits(int)}. + */ + public function getBitOffset() { + return $this->bitOffset; + } + + /** + * @return index of next byte in input byte array which would be read by the next call to {@link #readBits(int)}. + */ + public function getByteOffset() { + return $this->byteOffset; + } + + /** + * @param numBits number of bits to read + * @return int representing the bits read. The bits will appear as the least-significant + * bits of the int + * @throws IllegalArgumentException if numBits isn't in [1,32] or more than is available + */ + public function readBits($numBits) { + if ($numBits < 1 || $numBits > 32 || $numBits > $this->available()) { + throw new \InvalidArgumentException(strval($numBits)); + } + + $result = 0; + + // First, read remainder from current byte + if ($this->bitOffset > 0) { + $bitsLeft = 8 - $this->bitOffset; + $toRead = $numBits < $bitsLeft ? $numBits : $bitsLeft; + $bitsToNotRead = $bitsLeft - $toRead; + $mask = (0xFF >> (8 - $toRead)) << $bitsToNotRead; + $result = ($this->bytes[$this->byteOffset] & $mask) >> $bitsToNotRead; + $numBits -= $toRead; + $this->bitOffset += $toRead; + if ($this->bitOffset == 8) { + $this->bitOffset = 0; + $this->byteOffset++; + } + } + + // Next read whole bytes + if ($numBits > 0) { + while ($numBits >= 8) { + $result = ($result << 8) | ($this->bytes[$this->byteOffset] & 0xFF); + $this->byteOffset++; + $numBits -= 8; + } + + // Finally read a partial byte + if ($numBits > 0) { + $bitsToNotRead = 8 - $numBits; + $mask = (0xFF >> $bitsToNotRead) << $bitsToNotRead; + $result = ($result << $numBits) | (($this->bytes[$this->byteOffset] & $mask) >> $bitsToNotRead); + $this->bitOffset += $numBits; + } + } + + return $result; + } + + /** + * @return number of bits that can be read successfully + */ + public function available() { + return 8 * (count($this->bytes) - $this->byteOffset) - $this->bitOffset; + } + +} diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/CharacterSetEci.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/CharacterSetEci.php new file mode 100755 index 000000000..b44074701 --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/CharacterSetEci.php @@ -0,0 +1,154 @@ + self::ISO8859_1, + 'ISO-8859-2' => self::ISO8859_2, + 'ISO-8859-3' => self::ISO8859_3, + 'ISO-8859-4' => self::ISO8859_4, + 'ISO-8859-5' => self::ISO8859_5, + 'ISO-8859-6' => self::ISO8859_6, + 'ISO-8859-7' => self::ISO8859_7, + 'ISO-8859-8' => self::ISO8859_8, + 'ISO-8859-9' => self::ISO8859_9, + 'ISO-8859-10' => self::ISO8859_10, + 'ISO-8859-11' => self::ISO8859_11, + 'ISO-8859-12' => self::ISO8859_12, + 'ISO-8859-13' => self::ISO8859_13, + 'ISO-8859-14' => self::ISO8859_14, + 'ISO-8859-15' => self::ISO8859_15, + 'ISO-8859-16' => self::ISO8859_16, + 'SHIFT-JIS' => self::SJIS, + 'WINDOWS-1250' => self::CP1250, + 'WINDOWS-1251' => self::CP1251, + 'WINDOWS-1252' => self::CP1252, + 'WINDOWS-1256' => self::CP1256, + 'UTF-16BE' => self::UNICODE_BIG_UNMARKED, + 'UTF-8' => self::UTF8, + 'ASCII' => self::ASCII, + 'GBK' => self::GB18030, + 'EUC-KR' => self::EUC_KR, + ); + /** + * Additional possible values for character sets. + * + * @var array + */ + protected static $additionalValues = array( + self::CP437 => 2, + self::ASCII => 170, + ); + /** + * Gets character set ECI by value. + * + * @param string $name + * @return CharacterSetEci|null + */ + public static function getCharacterSetECIByValue($value) + { + if ($value < 0 || $value >= 900) { + throw new Exception\InvalidArgumentException('Value must be between 0 and 900'); + } + if (false !== ($key = array_search($value, self::$additionalValues))) { + $value = $key; + } + array_search($value, self::$nameToEci); + try + { + self::setName($value); + return new self($value); + } catch (Exception\UnexpectedValueException $e) { + return null; + } + } + + private static function setName($value) + { + foreach (self::$nameToEci as $name => $key) { + if($key == $value) + { + self::$name = $name; + return true; + } + } + if(self::$name == null) + { + foreach (self::$additionalValues as $name => $key) { + if($key == $value) + { + self::$name = $name; + return true; + } + } + } + } + /** + * Gets character set ECI name. + * + * @return character set ECI name|null + */ + public static function name() + { + return self::$name; + } + /** + * Gets character set ECI by name. + * + * @param string $name + * @return CharacterSetEci|null + */ + public static function getCharacterSetECIByName($name) + { + $name = strtoupper($name); + if (isset(self::$nameToEci[$name])) { + return new self(self::$nameToEci[$name]); + } + return null; + } +} \ No newline at end of file diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/DecoderResult.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/DecoderResult.php new file mode 100755 index 000000000..5568f901a --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/DecoderResult.php @@ -0,0 +1,109 @@ +Encapsulates the result of decoding a matrix of bits. This typically + * applies to 2D barcode formats. For now it contains the raw bytes obtained, + * as well as a String interpretation of those bytes, if applicable. + * + * @author Sean Owen + */ +final class DecoderResult { + + private $rawBytes; + private $text; + private $byteSegments; + private $ecLevel; + private $errorsCorrected; + private $erasures; + private $other; + private $structuredAppendParity; + private $structuredAppendSequenceNumber; + + + + public function __construct($rawBytes, + $text, + $byteSegments, + $ecLevel, + $saSequence = -1, + $saParity = -1) { + $this->rawBytes = $rawBytes; + $this->text = $text; + $this->byteSegments = $byteSegments; + $this->ecLevel = $ecLevel; + $this->structuredAppendParity = $saParity; + $this->structuredAppendSequenceNumber = $saSequence; + } + + public function getRawBytes() { + return $this->rawBytes; + } + + public function getText() { + return $this->text; + } + + public function getByteSegments() { + return $this->byteSegments; + } + + public function getECLevel() { + return $this->ecLevel; + } + + public function getErrorsCorrected() { + return $this->errorsCorrected; + } + + public function setErrorsCorrected($errorsCorrected) { + $this->errorsCorrected = $errorsCorrected; + } + + public function getErasures() { + return $this->erasures; + } + + public function setErasures($erasures) { + $this->erasures = $erasures; + } + + public function getOther() { + return $this->other; + } + + public function setOther($other) { + $this->other = $other; + } + + public function hasStructuredAppend() { + return $this->structuredAppendParity >= 0 && $this->structuredAppendSequenceNumber >= 0; + } + + public function getStructuredAppendParity() { + return $this->structuredAppendParity; + } + + public function getStructuredAppendSequenceNumber() { + return $this->structuredAppendSequenceNumber; + } + +} \ No newline at end of file diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/DefaultGridSampler.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/DefaultGridSampler.php new file mode 100755 index 000000000..1e790a8f6 --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/DefaultGridSampler.php @@ -0,0 +1,89 @@ +sampleGrid_($image, $dimensionX, $dimensionY, $transform); + } + +//@Override + public function sampleGrid_($image, + $dimensionX, + $dimensionY, + $transform) { + if ($dimensionX <= 0 || $dimensionY <= 0) { + throw NotFoundException::getNotFoundInstance(); + } + $bits = new BitMatrix($dimensionX, $dimensionY); + $points = fill_array(0,2 * $dimensionX,0.0); + for ($y = 0; $y < $dimensionY; $y++) { + $max = count($points); + $iValue = (float) $y + 0.5; + for ($x = 0; $x < $max; $x += 2) { + $points[$x] = (float) ($x / 2) + 0.5; + $points[$x + 1] = $iValue; + } + $transform->transformPoints($points); +// Quick check to see if points transformed to something inside the image; +// sufficient to check the endpoints + $this->checkAndNudgePoints($image, $points); + try { + for ($x = 0; $x < $max; $x += 2) { + if ($image->get((int) $points[$x], (int) $points[$x + 1])) { +// Black(-ish) pixel + $bits->set($x / 2, $y); + } + } + } catch (\Exception $aioobe) {//ArrayIndexOutOfBoundsException +// This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting +// transform gets "twisted" such that it maps a straight line of points to a set of points +// whose endpoints are in bounds, but others are not. There is probably some mathematical +// way to detect this about the transformation that I don't know yet. +// This results in an ugly runtime exception despite our clever checks above -- can't have +// that. We could check each point's coordinates but that feels duplicative. We settle for +// catching and wrapping ArrayIndexOutOfBoundsException. + throw NotFoundException::getNotFoundInstance(); + } + } + return $bits; + } + +} diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/DetectorResult.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/DetectorResult.php new file mode 100755 index 000000000..97f056788 --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/DetectorResult.php @@ -0,0 +1,47 @@ +Encapsulates the result of detecting a barcode in an image. This includes the raw + * matrix of black/white pixels corresponding to the barcode, and possibly points of interest + * in the image, like the location of finder patterns or corners of the barcode in the image. + * + * @author Sean Owen + */ +class DetectorResult { + + private $bits; + private $points; + + public function __construct($bits, $points) { + $this->bits = $bits; + $this->points = $points; + } + + public final function getBits() { + return $this->bits; + } + + public final function getPoints() { + return $this->points; + } + +} \ No newline at end of file diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/GlobalHistogramBinarizer.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/GlobalHistogramBinarizer.php new file mode 100755 index 000000000..2df580f43 --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/GlobalHistogramBinarizer.php @@ -0,0 +1,206 @@ +luminances = self::$EMPTY; + $this->buckets = fill_array(0, self::$LUMINANCE_BUCKETS,0); + $this->source = $source; + } + +// Applies simple sharpening to the row data to improve performance of the 1D Readers. +//@Override + public function getBlackRow($y, $row=null) { + $this->source = $this->getLuminanceSource(); + $width = $this->source->getWidth(); + if ($row == null || $row->getSize() < $width) { + $row = new BitArray($width); + } else { + $row->clear(); + } + + $this->initArrays($width); + $localLuminances = $this->source->getRow($y, $this->luminances); + $localBuckets = $this->buckets; + for ($x = 0; $x < $width; $x++) { + $pixel = $localLuminances[$x] & 0xff; + $localBuckets[$pixel >> self::$LUMINANCE_SHIFT]++; + } + $blackPoint = $this->estimateBlackPoint($localBuckets); + + $left = $localLuminances[0] & 0xff; + $center = $localLuminances[1] & 0xff; + for ($x = 1; $x < $width - 1; $x++) { + $right = $localLuminances[$x + 1] & 0xff; +// A simple -1 4 -1 box filter with a weight of 2. + $luminance = (($center * 4) - $left - $right) / 2; + if ($luminance < $blackPoint) { + $row->set($x); + } + $left = $center; + $center = $right; + } + return $row; + } + +// Does not sharpen the data, as this call is intended to only be used by 2D Readers. +//@Override + public function getBlackMatrix(){ + $source = $this->getLuminanceSource(); + $width = $source->getWidth(); + $height = $source->getHeight(); + $matrix = new BitMatrix($width, $height); + +// Quickly calculates the histogram by sampling four rows from the image. This proved to be +// more robust on the blackbox tests than sampling a diagonal as we used to do. + $this->initArrays($width); + $localBuckets = $this->buckets; + for ($y = 1; $y < 5; $y++) { + $row = intval($height * $y / 5); + $localLuminances = $source->getRow($row, $this->luminances); + $right = intval(($width * 4) / 5); + for ($x = intval($width / 5); $x < $right; $x++) { + $pixel = intval32bits($localLuminances[intval($x)] & 0xff); + $localBuckets[intval32bits($pixel >> self::$LUMINANCE_SHIFT)]++; + } + } + $blackPoint = $this->estimateBlackPoint($localBuckets); + +// We delay reading the entire image luminance until the black point estimation succeeds. +// Although we end up reading four rows twice, it is consistent with our motto of +// "fail quickly" which is necessary for continuous scanning. + $localLuminances = $source->getMatrix(); + for ($y = 0; $y < $height; $y++) { + $offset = $y * $width; + for ($x = 0; $x< $width; $x++) { + $pixel = intval($localLuminances[$offset + $x] & 0xff); + if ($pixel < $blackPoint) { + $matrix->set($x, $y); + } + } + } + + return $matrix; + } + +//@Override + public function createBinarizer($source) { + return new GlobalHistogramBinarizer($source); + } + + private function initArrays($luminanceSize) { + if (count($this->luminances) < $luminanceSize) { + $this->luminances = array(); + } + for ($x = 0; $x < self::$LUMINANCE_BUCKETS; $x++) { + $this->buckets[$x] = 0; + } + } + + private static function estimateBlackPoint($buckets){ +// Find the tallest peak in the histogram. + $numBuckets = count($buckets); + $maxBucketCount = 0; + $firstPeak = 0; + $firstPeakSize = 0; + for ($x = 0; $x < $numBuckets; $x++) { + if ($buckets[$x] > $firstPeakSize) { + $firstPeak = $x; + $firstPeakSize = $buckets[$x]; + } + if ($buckets[$x] > $maxBucketCount) { + $maxBucketCount = $buckets[$x]; + } + } + +// Find the second-tallest peak which is somewhat far from the tallest peak. + $secondPeak = 0; + $secondPeakScore = 0; + for ($x = 0; $x < $numBuckets; $x++) { + $distanceToBiggest = $x - $firstPeak; +// Encourage more distant second peaks by multiplying by square of distance. + $score = $buckets[$x] * $distanceToBiggest * $distanceToBiggest; + if ($score > $secondPeakScore) { + $secondPeak = $x; + $secondPeakScore = $score; + } + } + +// Make sure firstPeak corresponds to the black peak. + if ($firstPeak > $secondPeak) { + $temp = $firstPeak; + $firstPeak = $secondPeak; + $secondPeak = $temp; + } + +// If there is too little contrast in the image to pick a meaningful black point, throw rather +// than waste time trying to decode the image, and risk false positives. + if ($secondPeak - $firstPeak <= $numBuckets / 16) { + throw NotFoundException::getNotFoundInstance(); + } + +// Find a valley between them that is low and closer to the white peak. + $bestValley = $secondPeak - 1; + $bestValleyScore = -1; + for ($x = $secondPeak - 1; $x > $firstPeak; $x--) { + $fromFirst = $x - $firstPeak; + $score = $fromFirst * $fromFirst * ($secondPeak - $x) * ($maxBucketCount - $buckets[$x]); + if ($score > $bestValleyScore) { + $bestValley = $x; + $bestValleyScore = $score; + } + } + + return intval32bits($bestValley << self::$LUMINANCE_SHIFT); + } + +} diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/GridSampler.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/GridSampler.php new file mode 100755 index 000000000..30c3aee27 --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/GridSampler.php @@ -0,0 +1,177 @@ +Checks a set of points that have been transformed to sample points on an image against + * the image's dimensions to see if the point are even within the image. + * + *This method will actually "nudge" the endpoints back onto the image if they are found to be + * barely (less than 1 pixel) off the image. This accounts for imperfect detection of finder + * patterns in an image where the QR Code runs all the way to the image border.
+ * + *For efficiency, the method will check points from either end of the line until one is found + * to be within the image. Because the set of points are assumed to be linear, this is valid.
+ * + * @param image image into which the points should map + * @param points actual points in x1,y1,...,xn,yn form + * @throws NotFoundException if an endpoint is lies outside the image boundaries + */ + protected static function checkAndNudgePoints($image, + $points) { + $width = $image->getWidth(); + $height = $image->getHeight(); +// Check and nudge points from start until we see some that are OK: + $nudged = true; + for ($offset = 0; $offset < count($points) && $nudged; $offset += 2) { + $x = (int) $points[$offset]; + $y = (int) $points[$offset + 1]; + if ($x < -1 || $x > $width || $y < -1 || $y > $height) { + throw NotFoundException::getNotFoundInstance(); + } + $nudged = false; + if ($x == -1) { + $points[$offset] = 0.0; + $nudged = true; + } else if ($x == $width) { + $points[$offset] = $width - 1; + $nudged = true; + } + if ($y == -1) { + $points[$offset + 1] = 0.0; + $nudged = true; + } else if ($y == $height) { + $points[$offset + 1] = $height - 1; + $nudged = true; + } + } +// Check and nudge points from end: + $nudged = true; + for ($offset = count($points) - 2; $offset >= 0 && $nudged; $offset -= 2) { + $x = (int) $points[$offset]; + $y = (int) $points[$offset + 1]; + if ($x < -1 || $x > $width || $y < -1 || $y > $height) { + throw NotFoundException::getNotFoundInstance(); + } + $nudged = false; + if ($x == -1) { + $points[$offset] = 0.0; + $nudged = true; + } else if ($x == $width) { + $points[$offset] = $width - 1; + $nudged = true; + } + if ($y == -1) { + $points[$offset + 1] = 0.0; + $nudged = true; + } else if ($y == $height) { + $points[$offset + 1] = $height - 1; + $nudged = true; + } + } + } + +} diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/HybridBinarizer.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/HybridBinarizer.php new file mode 100755 index 000000000..670562c3e --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/HybridBinarizer.php @@ -0,0 +1,259 @@ +matrix != null) { + return $this->matrix; + } + $source = $this->getLuminanceSource(); + $width = $source->getWidth(); + $height = $source->getHeight(); + if ($width >= self::$MINIMUM_DIMENSION && $height >= self::$MINIMUM_DIMENSION) { + $luminances = $source->getMatrix(); + $subWidth = $width >> self::$BLOCK_SIZE_POWER; + if (($width & self::$BLOCK_SIZE_MASK) != 0) { + $subWidth++; + } + $subHeight = $height >> self::$BLOCK_SIZE_POWER; + if (($height & self::$BLOCK_SIZE_MASK) != 0) { + $subHeight++; + } + $blackPoints = $this->calculateBlackPoints($luminances, $subWidth, $subHeight, $width, $height); + + $newMatrix = new BitMatrix($width, $height); + $this->calculateThresholdForBlock($luminances, $subWidth, $subHeight, $width, $height, $blackPoints, $newMatrix); + $this->matrix = $newMatrix; + } else { +// If the image is too small, fall back to the global histogram approach. + $this->matrix = parent::getBlackMatrix(); + } + return $this->matrix; + } + +//@Override + public function createBinarizer($source) { + return new HybridBinarizer($source); + } + + /** + * For each block in the image, calculate the average black point using a 5x5 grid + * of the blocks around it. Also handles the corner cases (fractional blocks are computed based + * on the last pixels in the row/column which are also used in the previous block). + */ + private static function calculateThresholdForBlock($luminances, + $subWidth, + $subHeight, + $width, + $height, + $blackPoints, + $matrix) { + for ($y = 0; $y < $subHeight; $y++) { + $yoffset = intval32bits($y << self::$BLOCK_SIZE_POWER); + $maxYOffset = $height - self::$BLOCK_SIZE; + if ($yoffset > $maxYOffset) { + $yoffset = $maxYOffset; + } + for ($x = 0; $x < $subWidth; $x++) { + $xoffset = intval32bits($x << self::$BLOCK_SIZE_POWER); + $maxXOffset = $width - self::$BLOCK_SIZE; + if ($xoffset > $maxXOffset) { + $xoffset = $maxXOffset; + } + $left = self::cap($x, 2, $subWidth - 3); + $top = self::cap($y, 2, $subHeight - 3); + $sum = 0; + for ($z = -2; $z <= 2; $z++) { + $blackRow = $blackPoints[$top + $z]; + $sum += $blackRow[$left - 2] + $blackRow[$left - 1] + $blackRow[$left] + $blackRow[$left + 1] + $blackRow[$left + 2]; + } + $average = intval($sum / 25); + + self::thresholdBlock($luminances, $xoffset, $yoffset, $average, $width, $matrix); + } + } + } + + private static function cap($value, $min, $max) { + if($value<$min){ + return $min; + }elseif($value>$max){ + return $max; + }else{ + return $value; + } + + + + } + + /** + * Applies a single threshold to a block of pixels. + */ + private static function thresholdBlock($luminances, + $xoffset, + $yoffset, + $threshold, + $stride, + $matrix) { + + for ($y = 0, $offset = $yoffset * $stride + $xoffset; $y < self::$BLOCK_SIZE; $y++, $offset += $stride) { + for ($x = 0; $x < self::$BLOCK_SIZE; $x++) { +// Comparison needs to be <= so that black == 0 pixels are black even if the threshold is 0. + if (($luminances[$offset + $x] & 0xFF) <= $threshold) { + $matrix->set($xoffset + $x, $yoffset + $y); + } + } + } + } + + /** + * Calculates a single black point for each block of pixels and saves it away. + * See the following thread for a discussion of this algorithm: + * http://groups.google.com/group/zxing/browse_thread/thread/d06efa2c35a7ddc0 + */ + private static function calculateBlackPoints($luminances, + $subWidth, + $subHeight, + $width, + $height) { + $blackPoints = fill_array(0,$subHeight,0); + foreach($blackPoints as $key=>$point){ + $blackPoints[$key] = fill_array(0,$subWidth,0); + } + for ($y = 0; $y < $subHeight; $y++) { + $yoffset = intval32bits($y << self::$BLOCK_SIZE_POWER); + $maxYOffset = $height - self::$BLOCK_SIZE; + if ($yoffset > $maxYOffset) { + $yoffset = $maxYOffset; + } + for ($x = 0; $x < $subWidth; $x++) { + $xoffset = intval32bits($x << self::$BLOCK_SIZE_POWER); + $maxXOffset = $width - self::$BLOCK_SIZE; + if ($xoffset > $maxXOffset) { + $xoffset = $maxXOffset; + } + $sum = 0; + $min = 0xFF; + $max = 0; + for ($yy = 0, $offset = $yoffset * $width + $xoffset; $yy < self::$BLOCK_SIZE; $yy++, $offset += $width) { + for ($xx = 0; $xx < self::$BLOCK_SIZE; $xx++) { + $pixel = intval32bits(intval($luminances[intval($offset +$xx)]) & 0xFF); + $sum += $pixel; +// still looking for good contrast + if ($pixel < $min) { + $min = $pixel; + } + if ($pixel > $max) { + $max = $pixel; + } + } +// short-circuit min/max tests once dynamic range is met + if ($max - $min > self::$MIN_DYNAMIC_RANGE) { +// finish the rest of the rows quickly + for ($yy++, $offset += $width; $yy < self::$BLOCK_SIZE; $yy++, $offset += $width) { + for ($xx = 0; $xx < self::$BLOCK_SIZE; $xx++) { + $sum += intval32bits($luminances[$offset +$xx] & 0xFF); + } + } + } + } + +// The default estimate is the average of the values in the block. + $average = intval32bits($sum >> (self::$BLOCK_SIZE_POWER * 2)); + if ($max - $min <= self::$MIN_DYNAMIC_RANGE) { +// If variation within the block is low, assume this is a block with only light or only +// dark pixels. In that case we do not want to use the average, as it would divide this +// low contrast area into black and white pixels, essentially creating data out of noise. +// +// The default assumption is that the block is light/background. Since no estimate for +// the level of dark pixels exists locally, use half the min for the block. + $average = intval($min / 2); + + if ($y > 0 && $x > 0) { +// Correct the "white background" assumption for blocks that have neighbors by comparing +// the pixels in this block to the previously calculated black points. This is based on +// the fact that dark barcode symbology is always surrounded by some amount of light +// background for which reasonable black point estimates were made. The bp estimated at +// the boundaries is used for the interior. + +// The (min < bp) is arbitrary but works better than other heuristics that were tried. + $averageNeighborBlackPoint = + intval(($blackPoints[$y - 1][$x] + (2 * $blackPoints[$y][$x - 1]) + $blackPoints[$y - 1][$x - 1]) / 4); + if ($min < $averageNeighborBlackPoint) { + $average = $averageNeighborBlackPoint; + } + } + } + $blackPoints[$y][$x] = intval($average); + } + } + return $blackPoints; + } + +} diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/PerspectiveTransform.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/PerspectiveTransform.php new file mode 100755 index 000000000..7c046a8b8 --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/PerspectiveTransform.php @@ -0,0 +1,161 @@ +This class implements a perspective transform in two dimensions. Given four source and four + * destination points, it will compute the transformation implied between them. The code is based + * directly upon section 3.4.2 of George Wolberg's "Digital Image Warping"; see pages 54-56. + * + * @author Sean Owen + */ +final class PerspectiveTransform { + + private $a11; + private $a12; + private $a13; + private $a21; + private $a22; + private $a23; + private $a31; + private $a32; + private $a33; + + private function __construct($a11, $a21, $a31, + $a12, $a22, $a32, + $a13, $a23, $a33) { + $this->a11 = $a11; + $this->a12 = $a12; + $this->a13 = $a13; + $this->a21 = $a21; + $this->a22 = $a22; + $this->a23 = $a23; + $this->a31 = $a31; + $this->a32 = $a32; + $this->a33 = $a33; + } + + public static function quadrilateralToQuadrilateral($x0, $y0, + $x1, $y1, + $x2, $y2, + $x3, $y3, + $x0p, $y0p, + $x1p, $y1p, + $x2p, $y2p, + $x3p, $y3p) { + + $qToS = self::quadrilateralToSquare($x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3); + $sToQ = self::squareToQuadrilateral($x0p, $y0p, $x1p, $y1p, $x2p, $y2p, $x3p, $y3p); + return $sToQ->times($qToS); + } + + public function transformPoints(&$points,&$yValues=0) { + if($yValues) { + $this->transformPoints_($points,$yValues); + return; + } + $max =count($points); + $a11 = $this->a11; + $a12 = $this->a12; + $a13 = $this->a13; + $a21 = $this->a21; + $a22 = $this->a22; + $a23 = $this->a23; + $a31 = $this->a31; + $a32 = $this->a32; + $a33 = $this->a33; + for ($i = 0; $i < $max; $i += 2) { + $x = $points[$i]; + $y = $points[$i + 1]; + $denominator = $a13 * $x + $a23 * $y + $a33; + $points[$i] = ($a11 * $x + $a21 * $y + $a31) / $denominator; + $points[$i + 1] = ($a12 * $x + $a22 * $y +$a32) / $denominator; + } + } + + public function transformPoints_(&$xValues, &$yValues) { + $n = count($xValues); + for ($i = 0; $i < $n; $i ++) { + $x = $xValues[$i]; + $y = $yValues[$i]; + $denominator = $this->a13 * $x + $this->a23 * $y + $this->a33; + $xValues[$i] = ($this->a11 * $x + $this->a21 * $y + $this->a31) / $denominator; + $yValues[$i] = ($this->a12 * $x + $this->a22 *$y + $this->a32) / $denominator; + } + } + + public static function squareToQuadrilateral($x0, $y0, + $x1, $y1, + $x2, $y2, + $x3, $y3) { + $dx3 = $x0 - $x1 + $x2 - $x3; + $dy3 = $y0 - $y1 + $y2 - $y3; + if ($dx3 == 0.0 && $dy3 == 0.0) { +// Affine + return new PerspectiveTransform($x1 - $x0, $x2 - $x1, $x0, + $y1 - $y0, $y2 - $y1, $y0, + 0.0, 0.0, 1.0); + } else { + $dx1 = $x1 - $x2; + $dx2 = $x3 - $x2; + $dy1 = $y1 - $y2; + $dy2 = $y3 - $y2; + $denominator = $dx1 * $dy2 - $dx2 * $dy1; + $a13 = ($dx3 * $dy2 - $dx2 * $dy3) / $denominator; + $a23 = ($dx1 * $dy3 - $dx3 * $dy1) / $denominator; + return new PerspectiveTransform($x1 - $x0 + $a13 * $x1, $x3 - $x0 + $a23 * $x3, $x0, + $y1 - $y0 + $a13 * $y1, $y3 - $y0 + $a23 * $y3, $y0, + $a13, $a23, 1.0); + } + } + + public static function quadrilateralToSquare($x0, $y0, + $x1, $y1, + $x2, $y2, + $x3, $y3) { +// Here, the adjoint serves as the inverse: + return self::squareToQuadrilateral($x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3)->buildAdjoint(); + } + + function buildAdjoint() { +// Adjoint is the transpose of the cofactor matrix: + return new PerspectiveTransform($this->a22 * $this->a33 - $this->a23 * $this->a32, + $this->a23 * $this->a31 - $this->a21 * $this->a33, + $this->a21 * $this->a32 - $this->a22 * $this->a31, + $this->a13 * $this->a32 - $this->a12 * $this->a33, + $this->a11 * $this->a33 - $this->a13 * $this->a31, + $this->a12 * $this->a31 - $this->a11 * $this->a32, + $this->a12 * $this->a23 - $this->a13 * $this->a22, + $this->a13 * $this->a21 - $this->a11 * $this->a23, + $this->a11 * $this->a22 - $this->a12 * $this->a21); + } + + function times($other) { + return new PerspectiveTransform($this->a11 * $other->a11 + $this->a21 * $other->a12 + $this->a31 * $other->a13, + $this->a11 * $other->a21 + $this->a21 * $other->a22 + $this->a31 * $other->a23, + $this->a11 * $other->a31 + $this->a21 * $other->a32 + $this->a31 * $other->a33, + $this->a12 * $other->a11 + $this->a22 * $other->a12 + $this->a32 * $other->a13, + $this->a12 * $other->a21 + $this->a22 * $other->a22 + $this->a32 * $other->a23, + $this->a12 * $other->a31 + $this->a22 * $other->a32 + $this->a32 * $other->a33, + $this->a13 * $other->a11 + $this->a23 * $other->a12 + $this->a33 * $other->a13, + $this->a13 * $other->a21 + $this->a23 * $other->a22 + $this->a33 * $other->a23, + $this->a13 * $other->a31 + $this->a23 * $other->a32 + $this->a33 * $other->a33); + + } + +} diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/customFunctions.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/customFunctions.php new file mode 100755 index 000000000..6ae71cc0a --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/customFunctions.php @@ -0,0 +1,93 @@ +>= 1; + $num++; + } + return $num; +} +function intval32bits($value) +{ + $value = ($value & 0xFFFFFFFF); + + if ($value & 0x80000000) + $value = -((~$value & 0xFFFFFFFF) + 1); + + return $value; +} + +function uRShift($a, $b) +{ + + if($b == 0) return $a; + return ($a >> $b) & ~(1<<(8*PHP_INT_SIZE-1)>>($b-1)); +} +/* +function sdvig3($num,$count=1){//>>> 32 bit + $s = decbin($num); + + $sarray = str_split($s,1); + $sarray = array_slice($sarray,-32);//32bit + + for($i=0;$i<=1;$i++) { + array_pop($sarray); + array_unshift($sarray, '0'); + } + return bindec(implode($sarray)); +} +*/ + +function sdvig3($a,$b) { + + if ($a >= 0) { + return bindec(decbin($a>>$b)); //simply right shift for positive number + } + + $bin = decbin($a>>$b); + + $bin = substr($bin, $b); // zero fill on the left side + + $o = bindec($bin); + return $o; +} + +function floatToIntBits($float_val) +{ + $int = unpack('i', pack('f', $float_val)); + return $int[1]; +} + +function fill_array($index,$count,$value){ + if($count<=0){ + return array(0); + }else { + return array_fill($index, $count, $value); + } +} \ No newline at end of file diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/detector/MathUtils.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/detector/MathUtils.php new file mode 100755 index 000000000..1d3de23d7 --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/detector/MathUtils.php @@ -0,0 +1,46 @@ +A somewhat generic detector that looks for a barcode-like rectangular region within an image. + * It looks within a mostly white region of an image for a region of black and white, but mostly + * black. It returns the four corners of the region, as best it can determine. + * + * @author Sean Owen + * @port Ashot Khanamiryan + */ +class MonochromeRectangleDetector { + private static $MAX_MODULES = 32; + private $image; + function __construct($image){ + $this->image = $image; + + } + + /** + *Detects a rectangular region of black and white -- mostly black -- with a region of mostly + * white, in an image.
+ * + * @return {@link ResultPoint}[] describing the corners of the rectangular region. The first and + * last points are opposed on the diagonal, as are the second and third. The first point will be + * the topmost point and the last, the bottommost. The second point will be leftmost and the + * third, the rightmost + * @throws NotFoundException if no Data Matrix Code can be found + */ + public function detect(){ + + $height = $this->image->getHeight(); + $width = $this->image->getWidth(); + $halfHeight = $height / 2; + $halfWidth = $width / 2; + + $deltaY = max(1, $height / (self::$MAX_MODULES * 8)); + $deltaX = max(1, $width / (self::$MAX_MODULES * 8)); + + + $top = 0; + $bottom = $height; + $left = 0; + $right = $width; + $pointA = $this->findCornerFromCenter($halfWidth, 0, $left, $right, + $halfHeight, -$deltaY, $top, $bottom, $halfWidth / 2); + $top = (int) $pointA->getY() - 1; + $pointB = $this->findCornerFromCenter($halfWidth, -$deltaX, $left,$right, + $halfHeight, 0, $top, $bottom, $halfHeight / 2); + $left = (int) $pointB->getX() - 1; + $pointC = $this->findCornerFromCenter($halfWidth, $deltaX, $left, $right, + $halfHeight, 0, $top, $bottom, $halfHeight / 2); + $right = (int) $pointC->getX() + 1; + $pointD = $this->findCornerFromCenter($halfWidth, 0, $left, $right, + $halfHeight, $deltaY, $top, $bottom, $halfWidth / 2); + $bottom = (int) $pointD->getY() + 1; + + // Go try to find po$A again with better information -- might have been off at first. + $pointA = $this->findCornerFromCenter($halfWidth, 0, $left, $right, + $halfHeight, -$deltaY, $top, $bottom, $halfWidth / 4); + + return new ResultPoint( $pointA, $pointB, $pointC, $pointD ); + + } + + + + /** + * Attempts to locate a corner of the barcode by scanning up, down, left or right from a center + * point which should be within the barcode. + * + * @param centerX center's x component (horizontal) + * @param deltaX same as deltaY but change in x per step instead + * @param left minimum value of x + * @param right maximum value of x + * @param centerY center's y component (vertical) + * @param deltaY change in y per step. If scanning up this is negative; down, positive; + * left or right, 0 + * @param top minimum value of y to search through (meaningless when di == 0) + * @param bottom maximum value of y + * @param maxWhiteRun maximum run of white pixels that can still be considered to be within + * the barcode + * @return a {@link com.google.zxing.ResultPoint} encapsulating the corner that was found + * @throws NotFoundException if such a point cannot be found + */ + private function findCornerFromCenter($centerX, + $deltaX, + $left, + $right, + $centerY, + $deltaY, + $top, + $bottom, + $maxWhiteRun){ + $lastRange = null; + for ($y = $centerY, $x = $centerX; + $y < $bottom && $y >= $top && $x < $right && $x >= $left; + $y += $deltaY, $x += $deltaX) { + $range = 0; + if ($deltaX == 0) { + // horizontal slices, up and down + $range = $this->blackWhiteRange($y, $maxWhiteRun, $left, $right, true); + } else { + // vertical slices, left and right + $range = $this->blackWhiteRange($x, $maxWhiteRun, $top, $bottom, false); + } + if ($range == null) { + if ($lastRange == null) { + throw NotFoundException::getNotFoundInstance(); + } + // lastRange was found + if ($deltaX == 0) { + $lastY = $y - $deltaY; + if ($lastRange[0] < $centerX) { + if ($lastRange[1] > $centerX) { + // straddle, choose one or the other based on direction + return new ResultPoint($deltaY > 0 ? $lastRange[0] : $lastRange[1], $lastY); + } + return new ResultPoint($lastRange[0], $lastY); + } else { + return new ResultPoint($lastRange[1], $lastY); + } + } else { + $lastX = $x - $deltaX; + if ($lastRange[0] < $centerY) { + if ($lastRange[1] > $centerY) { + return new ResultPoint($lastX, $deltaX < 0 ? $lastRange[0] : $lastRange[1]); + } + return new ResultPoint($lastX, $lastRange[0]); + } else { + return new ResultPoint($lastX, $lastRange[1]); + } + } + } + $lastRange = $range; + } + throw NotFoundException::getNotFoundInstance(); + } + + + + /** + * Computes the start and end of a region of pixels, either horizontally or vertically, that could + * be part of a Data Matrix barcode. + * + * @param fixedDimension if scanning horizontally, this is the row (the fixed vertical location) + * where we are scanning. If scanning vertically it's the column, the fixed horizontal location + * @param maxWhiteRun largest run of white pixels that can still be considered part of the + * barcode region + * @param minDim minimum pixel location, horizontally or vertically, to consider + * @param maxDim maximum pixel location, horizontally or vertically, to consider + * @param horizontal if true, we're scanning left-right, instead of up-down + * @return int[] with start and end of found range, or null if no such range is found + * (e.g. only white was found) + */ + + private function blackWhiteRange($fixedDimension, $maxWhiteRun, $minDim, $maxDim, $horizontal){ + $center = ($minDim + $maxDim) / 2; + + // Scan left/up first + $start = $center; + while ($start >= $minDim) { + if ($horizontal ? $this->image->get($start, $fixedDimension) : $this->image->get($fixedDimension, $start)) { + $start--; + } else { + $whiteRunStart = $start; + do { + $start--; + } while ($start >= $minDim && !($horizontal ? $this->image->get($start, $fixedDimension) : + $this->image->get($fixedDimension, $start))); + $whiteRunSize = $whiteRunStart - $start; + if ($start < $minDim || $whiteRunSize > $maxWhiteRun) { + $start = $whiteRunStart; + break; + } + } + } + $start++; + + // Then try right/down + $end = $center; + while ($end < $maxDim) { + if ($horizontal ? $this->image->get($end, $fixedDimension) : $this->image->get($fixedDimension, $end)) { + $end++; + } else { + $whiteRunStart = $end; + do { + $end++; + } while ($end < $maxDim && !($horizontal ? $this->image->get($end, $fixedDimension) : + $this->image->get($fixedDimension, $end))); + $whiteRunSize = $end - $whiteRunStart; + if ($end >= $maxDim || $whiteRunSize > $maxWhiteRun) { + $end = $whiteRunStart; + break; + } + } + } + $end--; + + return $end > $start ? array($start, $end) : null; + } +} \ No newline at end of file diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/GenericGF.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/GenericGF.php new file mode 100755 index 000000000..ea9d7b9de --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/GenericGF.php @@ -0,0 +1,181 @@ +This class contains utility methods for performing mathematical operations over + * the Galois Fields. Operations use a given primitive polynomial in calculations. + * + *Throughout this package, elements of the GF are represented as an {@code int} + * for convenience and speed (but at the cost of memory). + *
+ * + * @author Sean Owen + * @author David Olivier + */ +final class GenericGF { + + public static $AZTEC_DATA_12; + public static $AZTEC_DATA_10; + public static $AZTEC_DATA_6; + public static $AZTEC_PARAM; + public static $QR_CODE_FIELD_256; + public static $DATA_MATRIX_FIELD_256; + public static $AZTEC_DATA_8; + public static $MAXICODE_FIELD_64; + + private $expTable; + private $logTable; + private $zero; + private $one; + private $size; + private $primitive; + private $generatorBase; + + + public static function Init(){ + self::$AZTEC_DATA_12 = new GenericGF(0x1069, 4096, 1); // x^12 + x^6 + x^5 + x^3 + 1 + self::$AZTEC_DATA_10 = new GenericGF(0x409, 1024, 1); // x^10 + x^3 + 1 + self::$AZTEC_DATA_6 = new GenericGF(0x43, 64, 1); // x^6 + x + 1 + self::$AZTEC_PARAM = new GenericGF(0x13, 16, 1); // x^4 + x + 1 + self::$QR_CODE_FIELD_256 = new GenericGF(0x011D, 256, 0); // x^8 + x^4 + x^3 + x^2 + 1 + self::$DATA_MATRIX_FIELD_256 = new GenericGF(0x012D, 256, 1); // x^8 + x^5 + x^3 + x^2 + 1 + self::$AZTEC_DATA_8 = self::$DATA_MATRIX_FIELD_256; + self::$MAXICODE_FIELD_64 = self::$AZTEC_DATA_6; + } + + + /** + * Create a representation of GF(size) using the given primitive polynomial. + * + * @param primitive irreducible polynomial whose coefficients are represented by + * the bits of an int, where the least-significant bit represents the constant + * coefficient + * @param size the size of the field + * @param b the factor b in the generator polynomial can be 0- or 1-based + * (g(x) = (x+a^b)(x+a^(b+1))...(x+a^(b+2t-1))). + * In most cases it should be 1, but for QR code it is 0. + */ + public function __construct($primitive, $size, $b) { + $this->primitive = $primitive; + $this->size = $size; + $this->generatorBase = $b; + + $this->expTable = array(); + $this->logTable =array(); + $x = 1; + for ($i = 0; $i < $size; $i++) { + $this->expTable[$i] = $x; + $x *= 2; // we're assuming the generator alpha is 2 + if ($x >= $size) { + $x ^= $primitive; + $x &= $size-1; + } + } + for ($i = 0; $i < $size-1; $i++) { + $this->logTable[$this->expTable[$i]] = $i; + } + // logTable[0] == 0 but this should never be used + $this->zero = new GenericGFPoly($this, array(0)); + $this->one = new GenericGFPoly($this, array(1)); + } + + function getZero() { + return $this->zero; + } + + function getOne() { + return $this->one; + } + + /** + * @return the monomial representing coefficient * x^degree + */ + function buildMonomial($degree, $coefficient) { + if ($degree < 0) { + throw new \InvalidArgumentException(); + } + if ($coefficient == 0) { + return $this->zero; + } + $coefficients = fill_array(0,$degree+1,0);//new int[degree + 1]; + $coefficients[0] = $coefficient; + return new GenericGFPoly($this, $coefficients); + } + + /** + * Implements both addition and subtraction -- they are the same in GF(size). + * + * @return sum/difference of a and b + */ + static function addOrSubtract($a, $b) { + return $a ^ $b; + } + + /** + * @return 2 to the power of a in GF(size) + */ + function exp($a) { + return $this->expTable[$a]; + } + + /** + * @return base 2 log of a in GF(size) + */ + function log($a) { + if ($a == 0) { + throw new \InvalidArgumentException(); + } + return $this->logTable[$a]; + } + + /** + * @return multiplicative inverse of a + */ + function inverse($a) { + if ($a == 0) { + throw new Exception(); + } + return $this->expTable[$this->size - $this->logTable[$a] - 1]; + } + + /** + * @return product of a and b in GF(size) + */ + function multiply($a, $b) { + if ($a == 0 || $b == 0) { + return 0; + } + return $this->expTable[($this->logTable[$a] + $this->logTable[$b]) % ($this->size - 1)]; + } + + public function getSize() { + return $this->size; + } + + public function getGeneratorBase() { + return $this->generatorBase; + } + + // @Override + public function toString() { + return "GF(0x" . dechex(intval($this->primitive)) . ',' . $this->size . ')'; + } + +} +GenericGF::Init(); \ No newline at end of file diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/GenericGFPoly.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/GenericGFPoly.php new file mode 100755 index 000000000..9e9aa3339 --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/GenericGFPoly.php @@ -0,0 +1,268 @@ +Represents a polynomial whose coefficients are elements of a GF. + * Instances of this class are immutable. + * + *Much credit is due to William Rucklidge since portions of this code are an indirect + * port of his C++ Reed-Solomon implementation.
+ * + * @author Sean Owen + */ +final class GenericGFPoly { + + private $field; + private $coefficients; + + /** + * @param field the {@link GenericGF} instance representing the field to use + * to perform computations + * @param coefficients array coefficients as ints representing elements of GF(size), arranged + * from most significant (highest-power term) coefficient to least significant + * @throws IllegalArgumentException if argument is null or empty, + * or if leading coefficient is 0 and this is not a + * constant polynomial (that is, it is not the monomial "0") + */ + function __construct($field, $coefficients) { + if (count($coefficients) == 0) { + throw new \InvalidArgumentException(); + } + $this->field = $field; + $coefficientsLength = count($coefficients); + if ($coefficientsLength > 1 && $coefficients[0] == 0) { + // Leading term must be non-zero for anything except the constant polynomial "0" + $firstNonZero = 1; + while ($firstNonZero < $coefficientsLength && $coefficients[$firstNonZero] == 0) { + $firstNonZero++; + } + if ($firstNonZero == $coefficientsLength) { + $this->coefficients = array(0); + } else { + $this->coefficients = fill_array(0,$coefficientsLength - $firstNonZero,0); + $this->coefficients = arraycopy($coefficients, + $firstNonZero, + $this->coefficients, + 0, + count($this->coefficients)); + } + } else { + $this->coefficients = $coefficients; + } + } + + function getCoefficients() { + return $this->coefficients; + } + + /** + * @return degree of this polynomial + */ + function getDegree() { + return count($this->coefficients) - 1; + } + + /** + * @return true iff this polynomial is the monomial "0" + */ + function isZero() { + return $this->coefficients[0] == 0; + } + + /** + * @return coefficient of x^degree term in this polynomial + */ + function getCoefficient($degree) { + return $this->coefficients[count($this->coefficients) - 1 - $degree]; + } + + /** + * @return evaluation of this polynomial at a given point + */ + function evaluateAt($a) { + if ($a == 0) { + // Just return the x^0 coefficient + return $this->getCoefficient(0); + } + $size = count($this->coefficients); + if ($a == 1) { + // Just the sum of the coefficients + $result = 0; + foreach ($this->coefficients as $coefficient ) { + $result = GenericGF::addOrSubtract($result, $coefficient); + } + return $result; + } + $result = $this->coefficients[0]; + for ($i = 1; $i < $size; $i++) { + $result = GenericGF::addOrSubtract($this->field->multiply($a, $result), $this->coefficients[$i]); + } + return $result; + } + + function addOrSubtract($other) { + if ($this->field !== $other->field) { + throw new \InvalidArgumentException("GenericGFPolys do not have same GenericGF field"); + } + if ($this->isZero()) { + return $other; + } + if ($other->isZero()) { + return $this; + } + + $smallerCoefficients = $this->coefficients; + $largerCoefficients = $other->coefficients; + if (count($smallerCoefficients) > count($largerCoefficients)) { + $temp = $smallerCoefficients; + $smallerCoefficients = $largerCoefficients; + $largerCoefficients = $temp; + } + $sumDiff = fill_array(0,count($largerCoefficients),0); + $lengthDiff = count($largerCoefficients) - count($smallerCoefficients); + // Copy high-order terms only found in higher-degree polynomial's coefficients + $sumDiff = arraycopy($largerCoefficients, 0, $sumDiff, 0, $lengthDiff); + + for ($i = $lengthDiff; $i < count($largerCoefficients); $i++) { + $sumDiff[$i] = GenericGF::addOrSubtract($smallerCoefficients[$i - $lengthDiff], $largerCoefficients[$i]); + } + + return new GenericGFPoly($this->field, $sumDiff); + } + + function multiply($other) { + if(is_int($other)){ + return $this->multiply_($other); + } + if ($this->field !== $other->field) { + throw new \InvalidArgumentException("GenericGFPolys do not have same GenericGF field"); + } + if ($this->isZero() || $other->isZero()) { + return $this->field->getZero(); + } + $aCoefficients = $this->coefficients; + $aLength = count($aCoefficients); + $bCoefficients = $other->coefficients; + $bLength = count($bCoefficients); + $product = fill_array(0,$aLength + $bLength - 1,0); + for ($i = 0; $i < $aLength; $i++) { + $aCoeff = $aCoefficients[$i]; + for ($j = 0; $j < $bLength; $j++) { + $product[$i + $j] = GenericGF::addOrSubtract($product[$i + $j], + $this->field->multiply($aCoeff, $bCoefficients[$j])); + } + } + return new GenericGFPoly($this->field, $product); + } + + function multiply_($scalar) { + if ($scalar == 0) { + return $this->field->getZero(); + } + if ($scalar == 1) { + return $this; + } + $size = count($this->coefficients); + $product = fill_array(0,$size,0); + for ($i = 0; $i < $size; $i++) { + $product[$i] = $this->field->multiply($this->coefficients[$i], $scalar); + } + return new GenericGFPoly($this->field, $product); + } + + function multiplyByMonomial($degree, $coefficient) { + if ($degree < 0) { + throw new \InvalidArgumentException(); + } + if ($coefficient == 0) { + return $this->field->getZero(); + } + $size = count($this->coefficients); + $product = fill_array(0,$size + $degree,0); + for ($i = 0; $i < $size; $i++) { + $product[$i] = $this->field->multiply($this->coefficients[$i], $coefficient); + } + return new GenericGFPoly($this->field, $product); + } + + function divide($other) { + if ($this->field !==$other->field) { + throw new \InvalidArgumentException("GenericGFPolys do not have same GenericGF field"); + } + if ($other->isZero()) { + throw new \InvalidArgumentException("Divide by 0"); + } + + $quotient = $this->field->getZero(); + $remainder = $this; + + $denominatorLeadingTerm = $other->getCoefficient($other->getDegree()); + $inverseDenominatorLeadingTerm = $this->field->inverse($denominatorLeadingTerm); + + while ($remainder->getDegree() >= $other->getDegree() && !$remainder->isZero()) { + $degreeDifference = $remainder->getDegree() - $other->getDegree(); + $scale = $this->field->multiply($remainder->getCoefficient($remainder->getDegree()), $inverseDenominatorLeadingTerm); + $term = $other->multiplyByMonomial($degreeDifference, $scale); + $iterationQuotient = $this->field->buildMonomial($degreeDifference, $scale); + $quotient = $quotient->addOrSubtract($iterationQuotient); + $remainder = $remainder->addOrSubtract($term); + } + + return array($quotient, $remainder ); + } + + //@Override + public function toString() { + $result = ''; + for ($degree = $this->getDegree(); $degree >= 0; $degree--) { + $coefficient = $this->getCoefficient($degree); + if ($coefficient != 0) { + if ($coefficient < 0) { + $result.=" - "; + $coefficient = -$coefficient; + } else { + if (strlen($result) > 0) { + $result .= " + "; + } + } + if ($degree == 0 || $coefficient != 1) { + $alphaPower = $this->field->log($coefficient); + if ($alphaPower == 0) { + $result.='1'; + } else if ($alphaPower == 1) { + $result.='a'; + } else { + $result.="a^"; + $result.=($alphaPower); + } + } + if ($degree != 0) { + if ($degree == 1) { + $result.='x'; + } else { + $result.="x^"; + $result.= $degree; + } + } + } + } + return $result; + } + +} diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/ReedSolomonDecoder.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/ReedSolomonDecoder.php new file mode 100755 index 000000000..3fb1c2efb --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/ReedSolomonDecoder.php @@ -0,0 +1,192 @@ +Implements Reed-Solomon decoding, as the name implies. + * + *The algorithm will not be explained here, but the following references were helpful + * in creating this implementation:
+ * + *Much credit is due to William Rucklidge since portions of this code are an indirect + * port of his C++ Reed-Solomon implementation.
+ * + * @author Sean Owen + * @author William Rucklidge + * @author sanfordsquires + */ +final class ReedSolomonDecoder { + + private $field; + + public function __construct($field) { + $this->field = $field; + } + + /** + *Decodes given set of received codewords, which include both data and error-correction + * codewords. Really, this means it uses Reed-Solomon to detect and correct errors, in-place, + * in the input.
+ * + * @param received data and error-correction codewords + * @param twoS number of error-correction codewords available + * @throws ReedSolomonException if decoding fails for any reason + */ + public function decode(&$received, $twoS) { + $poly = new GenericGFPoly($this->field, $received); + $syndromeCoefficients = fill_array(0,$twoS,0); + $noError = true; + for ($i = 0; $i < $twoS; $i++) { + $eval = $poly->evaluateAt($this->field->exp($i + $this->field->getGeneratorBase())); + $syndromeCoefficients[count($syndromeCoefficients) - 1 - $i] = $eval; + if ($eval != 0) { + $noError = false; + } + } + if ($noError) { + return; + } + $syndrome = new GenericGFPoly($this->field, $syndromeCoefficients); + $sigmaOmega = + $this->runEuclideanAlgorithm($this->field->buildMonomial($twoS, 1), $syndrome, $twoS); + $sigma = $sigmaOmega[0]; + $omega = $sigmaOmega[1]; + $errorLocations = $this->findErrorLocations($sigma); + $errorMagnitudes = $this->findErrorMagnitudes($omega, $errorLocations); + for ($i = 0; $i < count($errorLocations); $i++) { + $position = count($received) - 1 - $this->field->log($errorLocations[$i]); + if ($position < 0) { + throw new ReedSolomonException("Bad error location"); + } + $received[$position] = GenericGF::addOrSubtract($received[$position], $errorMagnitudes[$i]); + } + + } + + private function runEuclideanAlgorithm($a, $b, $R) + { + // Assume a's degree is >= b's + if ($a->getDegree() < $b->getDegree()) { + $temp = $a; + $a = $b; + $b = $temp; + } + + $rLast = $a; + $r = $b; + $tLast = $this->field->getZero(); + $t = $this->field->getOne(); + + // Run Euclidean algorithm until r's degree is less than R/2 + while ($r->getDegree() >= $R / 2) { + $rLastLast = $rLast; + $tLastLast = $tLast; + $rLast = $r; + $tLast = $t; + + // Divide rLastLast by rLast, with quotient in q and remainder in r + if ($rLast->isZero()) { + // Oops, Euclidean algorithm already terminated? + throw new ReedSolomonException("r_{i-1} was zero"); + } + $r = $rLastLast; + $q = $this->field->getZero(); + $denominatorLeadingTerm = $rLast->getCoefficient($rLast->getDegree()); + $dltInverse = $this->field->inverse($denominatorLeadingTerm); + while ($r->getDegree() >= $rLast->getDegree() && !$r->isZero()) { + $degreeDiff = $r->getDegree() - $rLast->getDegree(); + $scale = $this->field->multiply($r->getCoefficient($r->getDegree()), $dltInverse); + $q = $q->addOrSubtract($this->field->buildMonomial($degreeDiff, $scale)); + $r = $r->addOrSubtract($rLast->multiplyByMonomial($degreeDiff, $scale)); + } + + $t = $q->multiply($tLast)->addOrSubtract($tLastLast); + + if ($r->getDegree() >= $rLast->getDegree()) { + throw new IllegalStateException("Division algorithm failed to reduce polynomial?"); + } + } + + $sigmaTildeAtZero = $t->getCoefficient(0); + if ($sigmaTildeAtZero == 0) { + throw new ReedSolomonException("sigmaTilde(0) was zero"); + } + + $inverse = $this->field->inverse($sigmaTildeAtZero); + $sigma = $t->multiply($inverse); + $omega = $r->multiply($inverse); + return array($sigma, $omega); + } + + private function findErrorLocations($errorLocator) { + // This is a direct application of Chien's search + $numErrors = $errorLocator->getDegree(); + if ($numErrors == 1) { // shortcut + return array($errorLocator->getCoefficient(1) ); + } + $result = fill_array(0,$numErrors,0); + $e = 0; + for ($i = 1; $i < $this->field->getSize() && $e < $numErrors; $i++) { + if ($errorLocator->evaluateAt($i) == 0) { + $result[$e] = $this->field->inverse($i); + $e++; + } + } + if ($e != $numErrors) { + throw new ReedSolomonException("Error locator degree does not match number of roots"); + } + return $result; + } + + private function findErrorMagnitudes($errorEvaluator, $errorLocations) { + // This is directly applying Forney's Formula + $s = count($errorLocations); + $result = fill_array(0,$s,0); + for ($i = 0; $i < $s; $i++) { + $xiInverse = $this->field->inverse($errorLocations[$i]); + $denominator = 1; + for ($j = 0; $j < $s; $j++) { + if ($i != $j) { + //denominator = field.multiply(denominator, + // GenericGF.addOrSubtract(1, field.multiply(errorLocations[j], xiInverse))); + // Above should work but fails on some Apple and Linux JDKs due to a Hotspot bug. + // Below is a funny-looking workaround from Steven Parkes + $term = $this->field->multiply($errorLocations[$j], $xiInverse); + $termPlus1 = ($term & 0x1) == 0 ? $term | 1 : $term & ~1; + $denominator = $this->field->multiply($denominator, $termPlus1); + } + } + $result[$i] = $this->field->multiply($errorEvaluator->evaluateAt($xiInverse), + $this->field->inverse($denominator)); + if ($this->field->getGeneratorBase() != 0) { + $result[$i] = $this->field->multiply($result[$i], $xiInverse); + } + } + return $result; + } + +} diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/ReedSolomonException.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/ReedSolomonException.php new file mode 100755 index 000000000..10ac55ed9 --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/ReedSolomonException.php @@ -0,0 +1,31 @@ +Thrown when an exception occurs during Reed-Solomon decoding, such as when + * there are too many errors to correct. +* +* @author Sean Owen +*/ +final class ReedSolomonException extends \Exception { + + +} + +?> \ No newline at end of file diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/QRCodeReader.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/QRCodeReader.php new file mode 100755 index 000000000..dafdbd4fe --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/QRCodeReader.php @@ -0,0 +1,222 @@ +decoder = new Decoder(); + + } + + protected final function getDecoder() { + return $this->decoder; + } + + /** + * Locates and decodes a QR code in an image. + * + * @return a String representing the content encoded by the QR code + * @throws NotFoundException if a QR code cannot be found + * @throws FormatException if a QR code cannot be decoded + * @throws ChecksumException if error correction fails + */ + //@Override + + + // @Override + public function decode($image, $hints=null){/* MapReads format information from one of its two locations within the QR Code.
+ * + * @return {@link FormatInformation} encapsulating the QR Code's format info + * @throws FormatException if both format information locations cannot be parsed as + * the valid encoding of format information + */ + function readFormatInformation() { + + if ($this->parsedFormatInfo != null) { + return $this->parsedFormatInfo; + } + + // Read top-left format info bits + $formatInfoBits1 = 0; + for ($i = 0; $i < 6; $i++) { + $formatInfoBits1 = $this->copyBit($i, 8, $formatInfoBits1); + } + // .. and skip a bit in the timing pattern ... + $formatInfoBits1 = $this->copyBit(7, 8, $formatInfoBits1); + $formatInfoBits1 = $this->copyBit(8, 8, $formatInfoBits1); + $formatInfoBits1 = $this->copyBit(8, 7, $formatInfoBits1); + // .. and skip a bit in the timing pattern ... + for ($j = 5; $j >= 0; $j--) { + $formatInfoBits1 = $this->copyBit(8, $j, $formatInfoBits1); + } + + // Read the top-right/bottom-left pattern too + $dimension = $this->bitMatrix->getHeight(); + $formatInfoBits2 = 0; + $jMin = $dimension - 7; + for ($j = $dimension - 1; $j >= $jMin; $j--) { + $formatInfoBits2 = $this->copyBit(8, $j, $formatInfoBits2); + } + for ($i = $dimension - 8; $i < $dimension; $i++) { + $formatInfoBits2 = $this->copyBit($i, 8, $formatInfoBits2); + } + + $parsedFormatInfo = FormatInformation::decodeFormatInformation($formatInfoBits1, $formatInfoBits2); + if ($parsedFormatInfo != null) { + return $parsedFormatInfo; + } + throw FormatException::getFormatInstance(); + } + + /** + *Reads version information from one of its two locations within the QR Code.
+ * + * @return {@link Version} encapsulating the QR Code's version + * @throws FormatException if both version information locations cannot be parsed as + * the valid encoding of version information + */ + function readVersion(){ + + if ($this->parsedVersion != null) { + return $this->parsedVersion; + } + + $dimension = $this->bitMatrix->getHeight(); + + $provisionalVersion = ($dimension - 17) / 4; + if ($provisionalVersion <= 6) { + return Version::getVersionForNumber($provisionalVersion); + } + + // Read top-right version info: 3 wide by 6 tall + $versionBits = 0; + $ijMin = $dimension - 11; + for ($j = 5; $j >= 0; $j--) { + for ($i = $dimension - 9; $i >= $ijMin; $i--) { + $versionBits = $this->copyBit($i, $j, $versionBits); + } + } + + $theParsedVersion = Version::decodeVersionInformation($versionBits); + if ($theParsedVersion != null && $theParsedVersion->getDimensionForVersion() == $dimension) { + $this->parsedVersion = $theParsedVersion; + return $theParsedVersion; + } + + // Hmm, failed. Try bottom left: 6 wide by 3 tall + $versionBits = 0; + for ($i = 5; $i >= 0; $i--) { + for ($j = $dimension - 9; $j >=$ijMin; $j--) { + $versionBits = $this->copyBit($i, $j, $versionBits); + } + } + + $theParsedVersion = Version::decodeVersionInformation($versionBits); + if ($theParsedVersion != null && $theParsedVersion->getDimensionForVersion() == $dimension) { + $this->parsedVersion = $theParsedVersion; + return $theParsedVersion; + } + throw FormatException::getFormatInstance(); + } + + private function copyBit($i, $j, $versionBits) { + $bit = $this->mirror ? $this->bitMatrix->get($j, $i) : $this->bitMatrix->get($i, $j); + return $bit ? ($versionBits << 1) | 0x1 : $versionBits << 1; + } + + /** + *Reads the bits in the {@link BitMatrix} representing the finder pattern in the + * correct order in order to reconstruct the codewords bytes contained within the + * QR Code.
+ * + * @return bytes encoded within the QR Code + * @throws FormatException if the exact number of bytes expected is not read + */ + function readCodewords(){ + + $formatInfo = $this->readFormatInformation(); + $version = $this->readVersion(); + + // Get the data mask for the format used in this QR Code. This will exclude + // some bits from reading as we wind through the bit matrix. + $dataMask = DataMask::forReference($formatInfo->getDataMask()); + $dimension = $this->bitMatrix->getHeight(); + $dataMask->unmaskBitMatrix($this->bitMatrix, $dimension); + + $functionPattern = $version->buildFunctionPattern(); + + $readingUp = true; + if($version->getTotalCodewords()) { + $result = fill_array(0, $version->getTotalCodewords(), 0); + }else{ + $result = array(); + } + $resultOffset = 0; + $currentByte = 0; + $bitsRead = 0; + // Read columns in pairs, from right to left + for ($j = $dimension - 1; $j > 0; $j -= 2) { + if ($j == 6) { + // Skip whole column with vertical alignment pattern; + // saves time and makes the other code proceed more cleanly + $j--; + } + // Read alternatingly from bottom to top then top to bottom + for ($count = 0; $count < $dimension; $count++) { + $i = $readingUp ? $dimension - 1 - $count : $count; + for ($col = 0; $col < 2; $col++) { + // Ignore bits covered by the function pattern + if (!$functionPattern->get($j - $col, $i)) { + // Read a bit + $bitsRead++; + $currentByte <<= 1; + if ($this->bitMatrix->get($j - $col, $i)) { + $currentByte |= 1; + } + // If we've made a whole byte, save it off + if ($bitsRead == 8) { + $result[$resultOffset++] = $currentByte; //(byte) + $bitsRead = 0; + $currentByte = 0; + } + } + } + } + $readingUp ^= true; // readingUp = !readingUp; // switch directions + } + if ($resultOffset != $version->getTotalCodewords()) { + throw FormatException::getFormatInstance(); + } + return $result; + } + + /** + * Revert the mask removal done while reading the code words. The bit matrix should revert to its original state. + */ + function remask() { + if ($this->parsedFormatInfo == null) { + return; // We have no format information, and have no data mask + } + $dataMask = DataMask::forReference($this->parsedFormatInfo->getDataMask()); + $dimension = $this->bitMatrix->getHeight(); + $dataMask->unmaskBitMatrix($this->bitMatrix, $dimension); + } + + /** + * Prepare the parser for a mirrored operation. + * This flag has effect only on the {@link #readFormatInformation()} and the + * {@link #readVersion()}. Before proceeding with {@link #readCodewords()} the + * {@link #mirror()} method should be called. + * + * @param mirror Whether to read version and format information mirrored. + */ + function setMirror($mirror) { + $parsedVersion = null; + $parsedFormatInfo = null; + $this->mirror = $mirror; + } + + /** Mirror the bit matrix in order to attempt a second reading. */ + function mirror() { + for ($x = 0; $x < $this->bitMatrix->getWidth(); $x++) { + for ($y = $x + 1; $y < $this->bitMatrix->getHeight(); $y++) { + if ($this->bitMatrix->get($x, $y) != $this->bitMatrix->get($y, $x)) { + $this->bitMatrix->flip($y, $x); + $this->bitMatrix->flip($x, $y); + } + } + } + } + +} diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataBlock.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataBlock.php new file mode 100755 index 000000000..803c14f9d --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataBlock.php @@ -0,0 +1,123 @@ +Encapsulates a block of data within a QR Code. QR Codes may split their data into + * multiple blocks, each of which is a unit of data and error-correction codewords. Each + * is represented by an instance of this class. + * + * @author Sean Owen + */ +final class DataBlock { + + private $numDataCodewords; + private $codewords; //byte[] + + private function __construct($numDataCodewords, $codewords) { + $this->numDataCodewords = $numDataCodewords; + $this->codewords = $codewords; + } + + /** + *When QR Codes use multiple data blocks, they are actually interleaved. + * That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This + * method will separate the data into original blocks.
+ * + * @param rawCodewords bytes as read directly from the QR Code + * @param version version of the QR Code + * @param ecLevel error-correction level of the QR Code + * @return DataBlocks containing original bytes, "de-interleaved" from representation in the + * QR Code + */ + static function getDataBlocks($rawCodewords, + $version, + $ecLevel) { + + if (count($rawCodewords) != $version->getTotalCodewords()) { + throw new \InvalidArgumentException(); + } + + // Figure out the number and size of data blocks used by this version and + // error correction level + $ecBlocks = $version->getECBlocksForLevel($ecLevel); + + // First count the total number of data blocks + $totalBlocks = 0; + $ecBlockArray = $ecBlocks->getECBlocks(); + foreach ($ecBlockArray as $ecBlock) { + $totalBlocks += $ecBlock->getCount(); + } + + // Now establish DataBlocks of the appropriate size and number of data codewords + $result = array();//new DataBlock[$totalBlocks]; + $numResultBlocks = 0; + foreach ($ecBlockArray as $ecBlock) { + for ($i = 0; $i < $ecBlock->getCount(); $i++) { + $numDataCodewords = $ecBlock->getDataCodewords(); + $numBlockCodewords = $ecBlocks->getECCodewordsPerBlock() + $numDataCodewords; + $result[$numResultBlocks++] = new DataBlock($numDataCodewords, fill_array(0,$numBlockCodewords,0)); + } + } + + // All blocks have the same amount of data, except that the last n + // (where n may be 0) have 1 more byte. Figure out where these start. + $shorterBlocksTotalCodewords = count($result[0]->codewords); + $longerBlocksStartAt = count($result) - 1; + while ($longerBlocksStartAt >= 0) { + $numCodewords = count($result[$longerBlocksStartAt]->codewords); + if ($numCodewords == $shorterBlocksTotalCodewords) { + break; + } + $longerBlocksStartAt--; + } + $longerBlocksStartAt++; + + $shorterBlocksNumDataCodewords = $shorterBlocksTotalCodewords - $ecBlocks->getECCodewordsPerBlock(); + // The last elements of result may be 1 element longer; + // first fill out as many elements as all of them have + $rawCodewordsOffset = 0; + for ($i = 0; $i < $shorterBlocksNumDataCodewords; $i++) { + for ($j = 0; $j < $numResultBlocks; $j++) { + $result[$j]->codewords[$i] = $rawCodewords[$rawCodewordsOffset++]; + } + } + // Fill out the last data block in the longer ones + for ($j = $longerBlocksStartAt; $j < $numResultBlocks; $j++) { + $result[$j]->codewords[$shorterBlocksNumDataCodewords] = $rawCodewords[$rawCodewordsOffset++]; + } + // Now add in error correction blocks + $max = count($result[0]->codewords); + for ($i = $shorterBlocksNumDataCodewords; $i < $max; $i++) { + for ($j = 0; $j < $numResultBlocks; $j++) { + $iOffset = $j < $longerBlocksStartAt ? $i : $i + 1; + $result[$j]->codewords[$iOffset] = $rawCodewords[$rawCodewordsOffset++]; + } + } + return $result; + } + + function getNumDataCodewords() { + return $this->numDataCodewords; + } + + function getCodewords() { + return $this->codewords; + } + +} diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php new file mode 100755 index 000000000..852aab77d --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php @@ -0,0 +1,175 @@ +Encapsulates data masks for the data bits in a QR code, per ISO 18004:2006 6.8. Implementations + * of this class can un-mask a raw BitMatrix. For simplicity, they will unmask the entire BitMatrix, + * including areas used for finder patterns, timing patterns, etc. These areas should be unused + * after the point they are unmasked anyway. + * + *Note that the diagram in section 6.8.1 is misleading since it indicates that i is column position + * and j is row position. In fact, as the text says, i is row position and j is column position.
+ * + * @author Sean Owen + */ +abstract class DataMask +{ + + /** + * See ISO 18004:2006 6.8.1 + */ + private static $DATA_MASKS = array(); + + static function Init() + { + self::$DATA_MASKS = array( + new DataMask000(), + new DataMask001(), + new DataMask010(), + new DataMask011(), + new DataMask100(), + new DataMask101(), + new DataMask110(), + new DataMask111(), + ); + } + + function __construct() + { + + } + + /** + *Implementations of this method reverse the data masking process applied to a QR Code and + * make its bits ready to read.
+ * + * @param bits representation of QR Code bits + * @param dimension dimension of QR Code, represented by bits, being unmasked + */ + final function unmaskBitMatrix($bits, $dimension) + { + for ($i = 0; $i < $dimension; $i++) { + for ($j = 0; $j < $dimension; $j++) { + if ($this->isMasked($i, $j)) { + $bits->flip($j, $i); + } + } + } + } + + abstract function isMasked($i, $j); + + /** + * @param reference a value between 0 and 7 indicating one of the eight possible + * data mask patterns a QR Code may use + * @return DataMask encapsulating the data mask pattern + */ + static function forReference($reference) + { + if ($reference < 0 || $reference > 7) { + throw new \InvalidArgumentException(); + } + return self::$DATA_MASKS[$reference]; + } +} +DataMask::Init(); +/** + * 000: mask bits for which (x + y) mod 2 == 0 + */ +final class DataMask000 extends DataMask { + // @Override + function isMasked($i, $j) { + return (($i + $j) & 0x01) == 0; + } +} + +/** + * 001: mask bits for which x mod 2 == 0 + */ +final class DataMask001 extends DataMask { + //@Override + function isMasked($i, $j) { + return ($i & 0x01) == 0; + } +} + +/** + * 010: mask bits for which y mod 3 == 0 + */ +final class DataMask010 extends DataMask { + //@Override + function isMasked($i, $j) { + return $j % 3 == 0; + } +} + +/** + * 011: mask bits for which (x + y) mod 3 == 0 + */ +final class DataMask011 extends DataMask { + //@Override + function isMasked($i, $j) { + return ($i + $j) % 3 == 0; + } +} + +/** + * 100: mask bits for which (x/2 + y/3) mod 2 == 0 + */ +final class DataMask100 extends DataMask { + //@Override + function isMasked($i, $j) { + return intval((intval($i / 2) + intval($j /3)) & 0x01) == 0; + } +} + +/** + * 101: mask bits for which xy mod 2 + xy mod 3 == 0 + */ +final class DataMask101 extends DataMask { + //@Override + function isMasked($i, $j) { + $temp = $i * $j; + return ($temp & 0x01) + ($temp % 3) == 0; + } +} + +/** + * 110: mask bits for which (xy mod 2 + xy mod 3) mod 2 == 0 + */ +final class DataMask110 extends DataMask { + //@Override + function isMasked($i, $j) { + $temp = $i * $j; + return ((($temp & 0x01) + ($temp % 3)) & 0x01) == 0; + } +} + +/** + * 111: mask bits for which ((x+y)mod 2 + xy mod 3) mod 2 == 0 + */ +final class DataMask111 extends DataMask { + //@Override + function isMasked($i, $j) { + return (((($i + $j) & 0x01) + (($i * $j) % 3)) & 0x01) == 0; + } +} + diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DecodedBitStreamParser.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DecodedBitStreamParser.php new file mode 100755 index 000000000..ec4e66733 --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DecodedBitStreamParser.php @@ -0,0 +1,359 @@ +QR Codes can encode text as bits in one of several modes, and can use multiple modes + * in one QR Code. This class decodes the bits back into text. + * + *See ISO 18004:2006, 6.4.3 - 6.4.7
+ * + * @author Sean Owen + */ +final class DecodedBitStreamParser { + + /** + * See ISO 18004:2006, 6.4.4 Table 5 + */ + private static $ALPHANUMERIC_CHARS = array( + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', + 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', + 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + ' ', '$', '%', '*', '+', '-', '.', '/', ':' + ); + private static $GB2312_SUBSET = 1; + + + private function DecodedBitStreamParser() { + + + } + + static function decode($bytes, + $version, + $ecLevel, + $hints) { + $bits = new BitSource($bytes); + $result = '';//new StringBuilder(50); + $byteSegments = array(); + $symbolSequence = -1; + $parityData = -1; + + try { + $currentCharacterSetECI = null; + $fc1InEffect = false; + $mode=''; + do { + // While still another segment to read... + if ($bits->available() < 4) { + // OK, assume we're done. Really, a TERMINATOR mode should have been recorded here + $mode = Mode::$TERMINATOR; + } else { + $mode = Mode::forBits($bits->readBits(4)); // mode is encoded by 4 bits + } + if ($mode != Mode::$TERMINATOR) { + if ($mode == Mode::$FNC1_FIRST_POSITION || $mode == Mode::$FNC1_SECOND_POSITION) { + // We do little with FNC1 except alter the parsed result a bit according to the spec + $fc1InEffect = true; + } else if ($mode == Mode::$STRUCTURED_APPEND) { + if ($bits->available() < 16) { + throw FormatException::getFormatInstance(); + } + // sequence number and parity is added later to the result metadata + // Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue + $symbolSequence = $bits->readBits(8); + $parityData = $bits->readBits(8); + } else if ($mode == Mode::$ECI) { + // Count doesn't apply to ECI + $value = self::parseECIValue($bits); + $currentCharacterSetECI = CharacterSetECI::getCharacterSetECIByValue($value); + if ($currentCharacterSetECI == null) { + throw FormatException::getFormatInstance(); + } + } else { + // First handle Hanzi mode which does not start with character count + if ($mode == Mode::$HANZI) { + //chinese mode contains a sub set indicator right after mode indicator + $subset = $bits->readBits(4); + $countHanzi = $bits->readBits($mode->getCharacterCountBits($version)); + if ($subset == self::$GB2312_SUBSET) { + self::decodeHanziSegment($bits, $result, $countHanzi); + } + } else { + // "Normal" QR code modes: + // How many characters will follow, encoded in this mode? + $count = $bits->readBits($mode->getCharacterCountBits($version)); + if ($mode == Mode::$NUMERIC) { + self::decodeNumericSegment($bits, $result, $count); + } else if ($mode == Mode::$ALPHANUMERIC) { + self::decodeAlphanumericSegment($bits, $result, $count, $fc1InEffect); + } else if ($mode == Mode::$BYTE) { + self::decodeByteSegment($bits, $result, $count, $currentCharacterSetECI, $byteSegments, $hints); + } else if ($mode == Mode::$KANJI) { + self::decodeKanjiSegment($bits, $result, $count); + } else { + throw FormatException::getFormatInstance(); + } + } + } + } + } while ($mode != Mode::$TERMINATOR); + } catch (IllegalArgumentException $iae) { + // from readBits() calls + throw FormatException::getFormatInstance(); + } + + return new DecoderResult($bytes, + $result, + empty($byteSegments) ? null : $byteSegments, + $ecLevel == null ? null : 'L',//ErrorCorrectionLevel::toString($ecLevel), + $symbolSequence, + $parityData); + } + + /** + * See specification GBT 18284-2000 + */ + private static function decodeHanziSegment($bits, + &$result, + $count) { + // Don't crash trying to read more bits than we have available. + if ($count * 13 > $bits->available()) { + throw FormatException::getFormatInstance(); + } + + // Each character will require 2 bytes. Read the characters as 2-byte pairs + // and decode as GB2312 afterwards + $buffer = fill_array(0,2 * $count,0); + $offset = 0; + while ($count > 0) { + // Each 13 bits encodes a 2-byte character + $twoBytes = $bits->readBits(13); + $assembledTwoBytes = (($twoBytes / 0x060) << 8) | ($twoBytes % 0x060); + if ($assembledTwoBytes < 0x003BF) { + // In the 0xA1A1 to 0xAAFE range + $assembledTwoBytes += 0x0A1A1; + } else { + // In the 0xB0A1 to 0xFAFE range + $assembledTwoBytes += 0x0A6A1; + } + $buffer[$offset] = (($assembledTwoBytes >> 8) & 0xFF);//(byte) + $buffer[$offset + 1] = ($assembledTwoBytes & 0xFF);//(byte) + $offset += 2; + $count--; + } + + try { + $result .= iconv('GB2312', 'UTF-8', implode($buffer)); + } catch (UnsupportedEncodingException $ignored) { + throw FormatException::getFormatInstance(); + } + } + + private static function decodeKanjiSegment($bits, + &$result, + $count) { + // Don't crash trying to read more bits than we have available. + if ($count * 13 > $bits->available()) { + throw FormatException::getFormatInstance(); + } + + // Each character will require 2 bytes. Read the characters as 2-byte pairs + // and decode as Shift_JIS afterwards + $buffer = array(0,2 * $count,0); + $offset = 0; + while ($count > 0) { + // Each 13 bits encodes a 2-byte character + $twoBytes = $bits->readBits(13); + $assembledTwoBytes = (($twoBytes / 0x0C0) << 8) | ($twoBytes % 0x0C0); + if ($assembledTwoBytes < 0x01F00) { + // In the 0x8140 to 0x9FFC range + $assembledTwoBytes += 0x08140; + } else { + // In the 0xE040 to 0xEBBF range + $assembledTwoBytes += 0x0C140; + } + $buffer[$offset] = ($assembledTwoBytes >> 8);//(byte) + $buffer[$offset + 1] = $assembledTwoBytes; //(byte) + $offset += 2; + $count--; + } + // Shift_JIS may not be supported in some environments: + try { + $result .= iconv('shift-jis','utf-8',implode($buffer)); + + + } catch (UnsupportedEncodingException $ignored) { + throw FormatException::getFormatInstance(); + } + } + + private static function decodeByteSegment($bits, + &$result, + $count, + $currentCharacterSetECI, + &$byteSegments, + $hints) { + // Don't crash trying to read more bits than we have available. + if (8 * $count > $bits->available()) { + throw FormatException::getFormatInstance(); + } + + $readBytes = fill_array(0,$count,0); + for ($i = 0; $i < $count; $i++) { + $readBytes[$i] = $bits->readBits(8);//(byte) + } + $text = implode(array_map('chr',$readBytes)); + $encoding = ''; + if ($currentCharacterSetECI == null) { + // The spec isn't clear on this mode; see + // section 6.4.5: t does not say which encoding to assuming + // upon decoding. I have seen ISO-8859-1 used as well as + // Shift_JIS -- without anything like an ECI designator to + // give a hint. + + $encoding = mb_detect_encoding($text, $hints); + } else { + $encoding = $currentCharacterSetECI->name(); + } + try { + // $result.= mb_convert_encoding($text ,$encoding);//(new String(readBytes, encoding)); + $result.= $text;//(new String(readBytes, encoding)); + } catch (UnsupportedEncodingException $ignored) { + throw FormatException::getFormatInstance(); + } + $byteSegments = array_merge($byteSegments, $readBytes); + } + + private static function toAlphaNumericChar($value) { + if ($value >= count(self::$ALPHANUMERIC_CHARS)) { + throw FormatException::getFormatInstance(); + } + return self::$ALPHANUMERIC_CHARS[$value]; + } + + private static function decodeAlphanumericSegment($bits, + &$result, + $count, + $fc1InEffect) { + // Read two characters at a time + $start = strlen($result); + while ($count > 1) { + if ($bits->available() < 11) { + throw FormatException::getFormatInstance(); + } + $nextTwoCharsBits = $bits->readBits(11); + $result.=(self::toAlphaNumericChar($nextTwoCharsBits / 45)); + $result.=(self::toAlphaNumericChar($nextTwoCharsBits % 45)); + $count -= 2; + } + if ($count == 1) { + // special case: one character left + if ($bits->available() < 6) { + throw FormatException::getFormatInstance(); + } + $result.=self::toAlphaNumericChar($bits->readBits(6)); + } + // See section 6.4.8.1, 6.4.8.2 + if ($fc1InEffect) { + // We need to massage the result a bit if in an FNC1 mode: + for ($i = $start; $i < strlen($result); $i++) { + if ($result{$i} == '%') { + if ($i < strlen($result) - 1 && $result{$i + 1} == '%') { + // %% is rendered as % + $result = substr_replace($result,'',$i + 1,1);//deleteCharAt(i + 1); + } else { + // In alpha mode, % should be converted to FNC1 separator 0x1D + $result.setCharAt($i, chr(0x1D)); + } + } + } + } + } + + private static function decodeNumericSegment($bits, + &$result, + $count) { + // Read three digits at a time + while ($count >= 3) { + // Each 10 bits encodes three digits + if ($bits->available() < 10) { + throw FormatException::getFormatInstance(); + } + $threeDigitsBits = $bits->readBits(10); + if ($threeDigitsBits >= 1000) { + throw FormatException::getFormatInstance(); + } + $result.=(self::toAlphaNumericChar($threeDigitsBits / 100)); + $result.=(self::toAlphaNumericChar(($threeDigitsBits / 10) % 10)); + $result.=(self::toAlphaNumericChar($threeDigitsBits % 10)); + $count -= 3; + } + if ($count == 2) { + // Two digits left over to read, encoded in 7 bits + if ($bits->available() < 7) { + throw FormatException::getFormatInstance(); + } + $twoDigitsBits = $bits->readBits(7); + if ($twoDigitsBits >= 100) { + throw FormatException::getFormatInstance(); + } + $result.=(self::toAlphaNumericChar($twoDigitsBits / 10)); + $result.=(self::toAlphaNumericChar($twoDigitsBits % 10)); + } else if ($count == 1) { + // One digit left over to read + if ($bits->available() < 4) { + throw FormatException::getFormatInstance(); + } + $digitBits = $bits->readBits(4); + if ($digitBits >= 10) { + throw FormatException::getFormatInstance(); + } + $result.=(self::toAlphaNumericChar($digitBits)); + } + } + + private static function parseECIValue($bits) { + $firstByte = $bits->readBits(8); + if (($firstByte & 0x80) == 0) { + // just one byte + return $firstByte & 0x7F; + } + if (($firstByte & 0xC0) == 0x80) { + // two bytes + $secondByte = $bits->readBits(8); + return (($firstByte & 0x3F) << 8) | $secondByte; + } + if (($firstByte & 0xE0) == 0xC0) { + // three bytes + $secondThirdBytes = $bits->readBits(16); + return (($firstByte & 0x1F) << 16) | $secondThirdBytes; + } + throw FormatException::getFormatInstance(); + } + +} diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Decoder.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Decoder.php new file mode 100755 index 000000000..1859fc7aa --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Decoder.php @@ -0,0 +1,214 @@ +The main class which implements QR Code decoding -- as opposed to locating and extracting + * the QR Code from an image. + * + * @author Sean Owen + */ +final class Decoder { + + private $rsDecoder; + + public function __construct() { + $this->rsDecoder = new ReedSolomonDecoder(GenericGF::$QR_CODE_FIELD_256); + } + + + function decode($variable, $hints=null){ + if(is_array($variable)){ + return $this->decodeImage($variable,$hints); + }elseif(is_object($variable)&&$variable instanceof BitMatrix){ + return $this->decodeBits($variable,$hints); + }elseif(is_object($variable)&&$variable instanceof BitMatrixParser){ + return $this->decodeParser($variable,$hints); + }else{ + die('decode error Decoder.php'); + } + + + } + + /** + *Convenience method that can decode a QR Code represented as a 2D array of booleans. + * "true" is taken to mean a black module.
+ * + * @param image booleans representing white/black QR Code modules + * @param hints decoding hints that should be used to influence decoding + * @return text and bytes encoded within the QR Code + * @throws FormatException if the QR Code cannot be decoded + * @throws ChecksumException if error correction fails + */ + public function decodeImage($image, $hints=null) + { + $dimension = count($image); + $bits = new BitMatrix($dimension); + for ($i = 0; $i < $dimension; $i++) { + for ($j = 0; $j < $dimension; $j++) { + if ($image[$i][$j]) { + $bits->set($j, $i); + } + } + } + return $this->decode($bits, $hints); + } + + + + /** + *Decodes a QR Code represented as a {@link BitMatrix}. A 1 or "true" is taken to mean a black module.
+ * + * @param bits booleans representing white/black QR Code modules + * @param hints decoding hints that should be used to influence decoding + * @return text and bytes encoded within the QR Code + * @throws FormatException if the QR Code cannot be decoded + * @throws ChecksumException if error correction fails + */ + public function decodeBits($bits, $hints=null) + { + +// Construct a parser and read version, error-correction level + $parser = new BitMatrixParser($bits); + $fe = null; + $ce = null; + try { + return $this->decode($parser, $hints); + } catch (FormatException $e) { + $fe = $e; + } catch (ChecksumException $e) { + $ce = $e; + } + + try { + +// Revert the bit matrix + $parser->remask(); + +// Will be attempting a mirrored reading of the version and format info. + $parser->setMirror(true); + +// Preemptively read the version. + $parser->readVersion(); + +// Preemptively read the format information. + $parser->readFormatInformation(); + + /* + * Since we're here, this means we have successfully detected some kind + * of version and format information when mirrored. This is a good sign, + * that the QR code may be mirrored, and we should try once more with a + * mirrored content. + */ +// Prepare for a mirrored reading. + $parser->mirror(); + + $result = $this->decode($parser, $hints); + +// Success! Notify the caller that the code was mirrored. + $result->setOther(new QRCodeDecoderMetaData(true)); + + return $result; + + } catch (FormatException $e ) {// catch (FormatException | ChecksumException e) { +// Throw the exception from the original reading + if ($fe != null) { + throw $fe; + } + if ($ce != null) { + throw $ce; + } + throw $e; + + } + } + + private function decodeParser($parser,$hints=null) + { + $version = $parser->readVersion(); + $ecLevel = $parser->readFormatInformation()->getErrorCorrectionLevel(); + +// Read codewords + $codewords = $parser->readCodewords(); +// Separate into data blocks + $dataBlocks = DataBlock::getDataBlocks($codewords, $version, $ecLevel); + +// Count total number of data bytes + $totalBytes = 0; + foreach ($dataBlocks as $dataBlock) { + $totalBytes += $dataBlock->getNumDataCodewords(); + } + $resultBytes = fill_array(0,$totalBytes,0); + $resultOffset = 0; + +// Error-correct and copy data blocks together into a stream of bytes + foreach ($dataBlocks as $dataBlock) { + $codewordBytes = $dataBlock->getCodewords(); + $numDataCodewords = $dataBlock->getNumDataCodewords(); + $this->correctErrors($codewordBytes, $numDataCodewords); + for ($i = 0; $i < $numDataCodewords; $i++) { + $resultBytes[$resultOffset++] = $codewordBytes[$i]; + } + } + +// Decode the contents of that stream of bytes + return DecodedBitStreamParser::decode($resultBytes, $version, $ecLevel, $hints); + } + + /** + *Given data and error-correction codewords received, possibly corrupted by errors, attempts to + * correct the errors in-place using Reed-Solomon error correction.
+ * + * @param codewordBytes data and error correction codewords + * @param numDataCodewords number of codewords that are data bytes + * @throws ChecksumException if error correction fails + */ + private function correctErrors(&$codewordBytes, $numDataCodewords){ + $numCodewords = count($codewordBytes); +// First read into an array of ints + $codewordsInts =fill_array(0,$numCodewords,0); + for ($i = 0; $i < $numCodewords; $i++) { + $codewordsInts[$i] = $codewordBytes[$i] & 0xFF; + } + $numECCodewords = count($codewordBytes)- $numDataCodewords; + try { + $this->rsDecoder->decode($codewordsInts, $numECCodewords); + } catch (ReedSolomonException $ignored) { + throw ChecksumException::getChecksumInstance(); + } +// Copy back into array of bytes -- only need to worry about the bytes that were data +// We don't care about errors in the error-correction codewords + for ($i = 0; $i < $numDataCodewords; $i++) { + $codewordBytes[$i] = $codewordsInts[$i]; + } + + } + +} diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/ErrorCorrectionLevel.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/ErrorCorrectionLevel.php new file mode 100755 index 000000000..5f61b5cef --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/ErrorCorrectionLevel.php @@ -0,0 +1,86 @@ +See ISO 18004:2006, 6.5.1. This enum encapsulates the four error correction levels + * defined by the QR code standard. + * + * @author Sean Owen + */ +class ErrorCorrectionLevel { + + + private static $FOR_BITS; + + + private $bits; + private $ordinal; + + function __construct($bits,$ordinal=0) { + $this->bits = $bits; + $this->ordinal = $ordinal; + } + + public static function Init(){ + self::$FOR_BITS = array( + + + new ErrorCorrectionLevel(0x00,1), //M + new ErrorCorrectionLevel(0x01,0), //L + new ErrorCorrectionLevel(0x02,3), //H + new ErrorCorrectionLevel(0x03,2), //Q + + ); + } + /** L = ~7% correction */ + // self::$L = new ErrorCorrectionLevel(0x01); + /** M = ~15% correction */ + //self::$M = new ErrorCorrectionLevel(0x00); + /** Q = ~25% correction */ + //self::$Q = new ErrorCorrectionLevel(0x03); + /** H = ~30% correction */ + //self::$H = new ErrorCorrectionLevel(0x02); + + + public function getBits() { + return $this->bits; + } + public function toString() { + return $this->bits; + } + public function getOrdinal() { + return $this->ordinal; + } + + /** + * @param bits int containing the two bits encoding a QR Code's error correction level + * @return ErrorCorrectionLevel representing the encoded error correction level + */ + public static function forBits($bits) { + if ($bits < 0 || $bits >= count(self::$FOR_BITS)) { + throw new \InvalidArgumentException(); + } + $level = self::$FOR_BITS[$bits]; + // $lev = self::$$bit; + return $level; + } + + +} +ErrorCorrectionLevel::Init(); diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/FormatInformation.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/FormatInformation.php new file mode 100755 index 000000000..ac802fd6c --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/FormatInformation.php @@ -0,0 +1,179 @@ +Encapsulates a QR Code's format information, including the data mask used and + * error correction level. + * + * @author Sean Owen + * @see DataMask + * @see ErrorCorrectionLevel + */ +final class FormatInformation { + + public static $FORMAT_INFO_MASK_QR; + + /** + * See ISO 18004:2006, Annex C, Table C.1 + */ + public static $FORMAT_INFO_DECODE_LOOKUP; + /** + * Offset i holds the number of 1 bits in the binary representation of i + */ + private static $BITS_SET_IN_HALF_BYTE; + + private $errorCorrectionLevel; + private $dataMask; + + public static function Init(){ + + self::$FORMAT_INFO_MASK_QR= 0x5412; + self::$BITS_SET_IN_HALF_BYTE = array(0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4); + self::$FORMAT_INFO_DECODE_LOOKUP = array( + array(0x5412, 0x00), + array (0x5125, 0x01), + array(0x5E7C, 0x02), + array(0x5B4B, 0x03), + array(0x45F9, 0x04), + array(0x40CE, 0x05), + array(0x4F97, 0x06), + array(0x4AA0, 0x07), + array(0x77C4, 0x08), + array(0x72F3, 0x09), + array(0x7DAA, 0x0A), + array(0x789D, 0x0B), + array(0x662F, 0x0C), + array(0x6318, 0x0D), + array(0x6C41, 0x0E), + array(0x6976, 0x0F), + array(0x1689, 0x10), + array(0x13BE, 0x11), + array(0x1CE7, 0x12), + array(0x19D0, 0x13), + array(0x0762, 0x14), + array(0x0255, 0x15), + array(0x0D0C, 0x16), + array(0x083B, 0x17), + array(0x355F, 0x18), + array(0x3068, 0x19), + array(0x3F31, 0x1A), + array(0x3A06, 0x1B), + array(0x24B4, 0x1C), + array(0x2183, 0x1D), + array(0x2EDA, 0x1E), + array(0x2BED, 0x1F), + ); + + } + private function __construct($formatInfo) { + // Bits 3,4 + $this->errorCorrectionLevel = ErrorCorrectionLevel::forBits(($formatInfo >> 3) & 0x03); + // Bottom 3 bits + $this->dataMask = ($formatInfo & 0x07);//(byte) + } + + static function numBitsDiffering($a, $b) { + $a ^= $b; // a now has a 1 bit exactly where its bit differs with b's + // Count bits set quickly with a series of lookups: + return self::$BITS_SET_IN_HALF_BYTE[$a & 0x0F] + + self::$BITS_SET_IN_HALF_BYTE[intval(uRShift($a, 4) & 0x0F)] + + self::$BITS_SET_IN_HALF_BYTE[(uRShift($a ,8) & 0x0F)] + + self::$BITS_SET_IN_HALF_BYTE[(uRShift($a , 12) & 0x0F)] + + self::$BITS_SET_IN_HALF_BYTE[(uRShift($a, 16) & 0x0F)] + + self::$BITS_SET_IN_HALF_BYTE[(uRShift($a , 20) & 0x0F)] + + self::$BITS_SET_IN_HALF_BYTE[(uRShift($a, 24) & 0x0F)] + + self::$BITS_SET_IN_HALF_BYTE[(uRShift($a ,28) & 0x0F)]; + } + + /** + * @param maskedFormatInfo1; format info indicator, with mask still applied + * @param maskedFormatInfo2; second copy of same info; both are checked at the same time + * to establish best match + * @return information about the format it specifies, or {@code null} + * if doesn't seem to match any known pattern + */ + static function decodeFormatInformation($maskedFormatInfo1, $maskedFormatInfo2) { + $formatInfo = self::doDecodeFormatInformation($maskedFormatInfo1, $maskedFormatInfo2); + if ($formatInfo != null) { + return $formatInfo; + } + // Should return null, but, some QR codes apparently + // do not mask this info. Try again by actually masking the pattern + // first + return self::doDecodeFormatInformation($maskedFormatInfo1 ^ self::$FORMAT_INFO_MASK_QR, + $maskedFormatInfo2 ^ self::$FORMAT_INFO_MASK_QR); + } + + private static function doDecodeFormatInformation($maskedFormatInfo1, $maskedFormatInfo2) { + // Find the int in FORMAT_INFO_DECODE_LOOKUP with fewest bits differing + $bestDifference = PHP_INT_MAX; + $bestFormatInfo = 0; + foreach (self::$FORMAT_INFO_DECODE_LOOKUP as $decodeInfo ) { + $targetInfo = $decodeInfo[0]; + if ($targetInfo == $maskedFormatInfo1 || $targetInfo == $maskedFormatInfo2) { + // Found an exact match + return new FormatInformation($decodeInfo[1]); + } + $bitsDifference = self::numBitsDiffering($maskedFormatInfo1, $targetInfo); + if ($bitsDifference < $bestDifference) { + $bestFormatInfo = $decodeInfo[1]; + $bestDifference = $bitsDifference; + } + if ($maskedFormatInfo1 != $maskedFormatInfo2) { + // also try the other option + $bitsDifference = self::numBitsDiffering($maskedFormatInfo2, $targetInfo); + if ($bitsDifference < $bestDifference) { + $bestFormatInfo = $decodeInfo[1]; + $bestDifference = $bitsDifference; + } + } + } + // Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits + // differing means we found a match + if ($bestDifference <= 3) { + return new FormatInformation($bestFormatInfo); + } + return null; + } + + function getErrorCorrectionLevel() { + return $this->errorCorrectionLevel; + } + + function getDataMask() { + return $this->dataMask; + } + + //@Override + public function hashCode() { + return ($this->errorCorrectionLevel->ordinal() << 3) | intval($this->dataMask); + } + + //@Override + public function equals($o) { + if (!($o instanceof FormatInformation)) { + return false; + } + $other =$o; + return $this->errorCorrectionLevel == $other->errorCorrectionLevel && + $this->dataMask == $other->dataMask; + } + +} +FormatInformation::Init(); diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Mode.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Mode.php new file mode 100755 index 000000000..30421ad9f --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Mode.php @@ -0,0 +1,118 @@ +See ISO 18004:2006, 6.4.1, Tables 2 and 3. This enum encapsulates the various modes in which + * data can be encoded to bits in the QR code standard. + * + * @author Sean Owen + */ +class Mode { + static $TERMINATOR; + static $NUMERIC; + static $ALPHANUMERIC; + static $STRUCTURED_APPEND; + static $BYTE; + static $ECI; + static $KANJI; + static $FNC1_FIRST_POSITION; + static $FNC1_SECOND_POSITION; + static $HANZI; + + + private $characterCountBitsForVersions; + private $bits; + + function __construct($characterCountBitsForVersions, $bits) { + $this->characterCountBitsForVersions = $characterCountBitsForVersions; + $this->bits = $bits; + } + static function Init() + { + + + self::$TERMINATOR = new Mode(array(0, 0, 0), 0x00); // Not really a mode... + self::$NUMERIC = new Mode(array(10, 12, 14), 0x01); + self::$ALPHANUMERIC = new Mode(array(9, 11, 13), 0x02); + self::$STRUCTURED_APPEND = new Mode(array(0, 0, 0), 0x03); // Not supported + self::$BYTE = new Mode(array(8, 16, 16), 0x04); + self::$ECI = new Mode(array(0, 0, 0), 0x07); // character counts don't apply + self::$KANJI = new Mode(array(8, 10, 12), 0x08); + self::$FNC1_FIRST_POSITION = new Mode(array(0, 0, 0), 0x05); + self::$FNC1_SECOND_POSITION =new Mode(array(0, 0, 0), 0x09); + /** See GBT 18284-2000; "Hanzi" is a transliteration of this mode name. */ + self::$HANZI = new Mode(array(8, 10, 12), 0x0D); + } + /** + * @param bits four bits encoding a QR Code data mode + * @return Mode encoded by these bits + * @throws IllegalArgumentException if bits do not correspond to a known mode + */ + public static function forBits($bits) { + switch ($bits) { + case 0x0: + return self::$TERMINATOR; + case 0x1: + return self::$NUMERIC; + case 0x2: + return self::$ALPHANUMERIC; + case 0x3: + return self::$STRUCTURED_APPEND; + case 0x4: + return self::$BYTE; + case 0x5: + return self::$FNC1_FIRST_POSITION; + case 0x7: + return self::$ECI; + case 0x8: + return self::$KANJI; + case 0x9: + return self::$FNC1_SECOND_POSITION; + case 0xD: + // 0xD is defined in GBT 18284-2000, may not be supported in foreign country + return self::$HANZI; + default: + throw new \InvalidArgumentException(); + } + } + + /** + * @param version version in question + * @return number of bits used, in this QR Code symbol {@link Version}, to encode the + * count of characters that will follow encoded in this Mode + */ + public function getCharacterCountBits($version) { + $number = $version->getVersionNumber(); + $offset = 0; + if ($number <= 9) { + $offset = 0; + } else if ($number <= 26) { + $offset = 1; + } else { + $offset = 2; + } + return $this->characterCountBitsForVersions[$offset]; + } + + public function getBits() { + return $this->bits; + } + +} +Mode::Init(); \ No newline at end of file diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Version.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Version.php new file mode 100755 index 000000000..a3cc03f30 --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Version.php @@ -0,0 +1,619 @@ +versionNumber = $versionNumber; + $this->alignmentPatternCenters = $alignmentPatternCenters; + $this->ecBlocks = $ecBlocks; + $total = 0; + if(is_array($ecBlocks)) { + $ecCodewords = $ecBlocks[0]->getECCodewordsPerBlock(); + $ecbArray = $ecBlocks[0]->getECBlocks(); + }else{ + $ecCodewords = $ecBlocks->getECCodewordsPerBlock(); + $ecbArray = $ecBlocks->getECBlocks(); + } + foreach ($ecbArray as $ecBlock) { + $total += $ecBlock->getCount() * ($ecBlock->getDataCodewords() + $ecCodewords); + } + $this->totalCodewords = $total; + } + public function getVersionNumber() + { + return $this->versionNumber; + } + + public function getAlignmentPatternCenters() + { + return $this->alignmentPatternCenters; + } + + public function getTotalCodewords() + { + return $this->totalCodewords; + } + + public function getDimensionForVersion() + { + return 17 + 4 * $this->versionNumber; + } + + public function getECBlocksForLevel($ecLevel) + { + return $this->ecBlocks[$ecLevel->getOrdinal()]; + } + + /** + *Deduces version information purely from QR Code dimensions.
+ * + * @param dimension dimension in modules + * @return Version for a QR Code of that dimension + * @throws FormatException if dimension is not 1 mod 4 + */ + public static function getProvisionalVersionForDimension($dimension) + { + if ($dimension % 4 != 1) { + throw FormatException::getFormatInstance(); + } + try { + return self::getVersionForNumber(($dimension - 17) / 4); + } catch (InvalidArgumentException $ignored) { + throw FormatException::getFormatInstance(); + } + } + + public static function getVersionForNumber($versionNumber) + { + if ($versionNumber < 1 || $versionNumber > 40) { + throw new \InvalidArgumentException(); + } + if(!self::$VERSIONS){ + + self::$VERSIONS = self::buildVersions(); + + } + return self::$VERSIONS[$versionNumber - 1]; + } + + static function decodeVersionInformation($versionBits) + { + $bestDifference = PHP_INT_MAX; + $bestVersion = 0; + for ($i = 0; $i < count(self::$VERSION_DECODE_INFO); $i++) { + $targetVersion = self::$VERSION_DECODE_INFO[$i]; +// Do the version info bits match exactly? done. + if ($targetVersion == $versionBits) { + return self::getVersionForNumber($i + 7); + } +// Otherwise see if this is the closest to a real version info bit string +// we have seen so far + $bitsDifference = FormatInformation::numBitsDiffering($versionBits, $targetVersion); + if ($bitsDifference < $bestDifference) { + $bestVersion = $i + 7; + $bestDifference = $bitsDifference; + } + } +// We can tolerate up to 3 bits of error since no two version info codewords will +// differ in less than 8 bits. + if ($bestDifference <= 3) { + return self::getVersionForNumber($bestVersion); + } +// If we didn't find a close enough match, fail + return null; + } + + /** + * See ISO 18004:2006 Annex E + */ + function buildFunctionPattern() + { + $dimension = self::getDimensionForVersion(); + $bitMatrix = new BitMatrix($dimension); + +// Top left finder pattern + separator + format + $bitMatrix->setRegion(0, 0, 9, 9); +// Top right finder pattern + separator + format + $bitMatrix->setRegion($dimension - 8, 0, 8, 9); +// Bottom left finder pattern + separator + format + $bitMatrix->setRegion(0, $dimension - 8, 9, 8); + +// Alignment patterns + $max = count($this->alignmentPatternCenters); + for ($x = 0; $x < $max; $x++) { + $i = $this->alignmentPatternCenters[$x] - 2; + for ($y = 0; $y < $max; $y++) { + if (($x == 0 && ($y == 0 || $y == $max - 1)) || ($x == $max - 1 && $y == 0)) { +// No alignment patterns near the three finder paterns + continue; + } + $bitMatrix->setRegion($this->alignmentPatternCenters[$y] - 2, $i, 5, 5); + } + } + +// Vertical timing pattern + $bitMatrix->setRegion(6, 9, 1, $dimension - 17); +// Horizontal timing pattern + $bitMatrix->setRegion(9, 6, $dimension - 17, 1); + + if ($this->versionNumber > 6) { +// Version info, top right + $bitMatrix->setRegion($dimension - 11, 0, 3, 6); +// Version info, bottom left + $bitMatrix->setRegion(0, $dimension - 11, 6, 3); + } + + return $bitMatrix; + } + /** + * See ISO 18004:2006 6.5.1 Table 9 + */ + private static function buildVersions() + { + + + return array( + new Version(1, array(), + array(new ECBlocks(7, array(new ECB(1, 19))), + new ECBlocks(10, array(new ECB(1, 16))), + new ECBlocks(13, array(new ECB(1, 13))), + new ECBlocks(17, array(new ECB(1, 9))))), + new Version(2, array(6, 18), + array(new ECBlocks(10, array(new ECB(1, 34))), + new ECBlocks(16, array(new ECB(1, 28))), + new ECBlocks(22, array(new ECB(1, 22))), + new ECBlocks(28, array(new ECB(1, 16))))), + new Version(3, array(6, 22), + array( new ECBlocks(15, array(new ECB(1, 55))), + new ECBlocks(26, array(new ECB(1, 44))), + new ECBlocks(18, array(new ECB(2, 17))), + new ECBlocks(22, array(new ECB(2, 13))))), + new Version(4, array(6, 26), + array(new ECBlocks(20, array(new ECB(1, 80))), + new ECBlocks(18, array(new ECB(2, 32))), + new ECBlocks(26, array(new ECB(2, 24))), + new ECBlocks(16, array(new ECB(4, 9))))), + new Version(5, array(6, 30), + array(new ECBlocks(26, array(new ECB(1, 108))), + new ECBlocks(24, array(new ECB(2, 43))), + new ECBlocks(18, array(new ECB(2, 15), + new ECB(2, 16))), + new ECBlocks(22, array(new ECB(2, 11), + new ECB(2, 12))))), + new Version(6, array(6, 34), + array(new ECBlocks(18, array(new ECB(2, 68))), + new ECBlocks(16, array(new ECB(4, 27))), + new ECBlocks(24, array(new ECB(4, 19))), + new ECBlocks(28, array(new ECB(4, 15))))), + new Version(7, array(6, 22, 38), + array(new ECBlocks(20, array(new ECB(2, 78))), + new ECBlocks(18, array(new ECB(4, 31))), + new ECBlocks(18, array(new ECB(2, 14), + new ECB(4, 15))), + new ECBlocks(26, array(new ECB(4, 13), + new ECB(1, 14))))), + new Version(8, array(6, 24, 42), + array(new ECBlocks(24, array(new ECB(2, 97))), + new ECBlocks(22, array(new ECB(2, 38), + new ECB(2, 39))), + new ECBlocks(22, array(new ECB(4, 18), + new ECB(2, 19))), + new ECBlocks(26, array(new ECB(4, 14), + new ECB(2, 15))))), + new Version(9, array(6, 26, 46), + array(new ECBlocks(30, array(new ECB(2, 116))), + new ECBlocks(22, array(new ECB(3, 36), + new ECB(2, 37))), + new ECBlocks(20, array(new ECB(4, 16), + new ECB(4, 17))), + new ECBlocks(24, array(new ECB(4, 12), + new ECB(4, 13))))), + new Version(10, array(6, 28, 50), + array(new ECBlocks(18, array(new ECB(2, 68), + new ECB(2, 69))), + new ECBlocks(26, array(new ECB(4, 43), + new ECB(1, 44))), + new ECBlocks(24, array(new ECB(6, 19), + new ECB(2, 20))), + new ECBlocks(28, array(new ECB(6, 15), + new ECB(2, 16))))), + new Version(11, array(6, 30, 54), + array(new ECBlocks(20, array(new ECB(4, 81))), + new ECBlocks(30, array(new ECB(1, 50), + new ECB(4, 51))), + new ECBlocks(28, array(new ECB(4, 22), + new ECB(4, 23))), + new ECBlocks(24, array(new ECB(3, 12), + new ECB(8, 13))))), + new Version(12, array(6, 32, 58), + array(new ECBlocks(24, array(new ECB(2, 92), + new ECB(2, 93))), + new ECBlocks(22, array(new ECB(6, 36), + new ECB(2, 37))), + new ECBlocks(26, array(new ECB(4, 20), + new ECB(6, 21))), + new ECBlocks(28, array(new ECB(7, 14), + new ECB(4, 15))))), + new Version(13, array(6, 34, 62), + array(new ECBlocks(26, array(new ECB(4, 107))), + new ECBlocks(22, array(new ECB(8, 37), + new ECB(1, 38))), + new ECBlocks(24, array(new ECB(8, 20), + new ECB(4, 21))), + new ECBlocks(22, array(new ECB(12, 11), + new ECB(4, 12))))), + new Version(14, array(6, 26, 46, 66), + array(new ECBlocks(30, array(new ECB(3, 115), + new ECB(1, 116))), + new ECBlocks(24, array(new ECB(4, 40), + new ECB(5, 41))), + new ECBlocks(20, array(new ECB(11, 16), + new ECB(5, 17))), + new ECBlocks(24, array(new ECB(11, 12), + new ECB(5, 13))))), + new Version(15, array(6, 26, 48, 70), + array(new ECBlocks(22, array(new ECB(5, 87), + new ECB(1, 88))), + new ECBlocks(24, array(new ECB(5, 41), + new ECB(5, 42))), + new ECBlocks(30, array(new ECB(5, 24), + new ECB(7, 25))), + new ECBlocks(24, array(new ECB(11, 12), + new ECB(7, 13))))), + new Version(16, array(6, 26, 50, 74), + array(new ECBlocks(24, array(new ECB(5, 98), + new ECB(1, 99))), + new ECBlocks(28, array(new ECB(7, 45), + new ECB(3, 46))), + new ECBlocks(24, array(new ECB(15, 19), + new ECB(2, 20))), + new ECBlocks(30, array(new ECB(3, 15), + new ECB(13, 16))))), + new Version(17, array(6, 30, 54, 78), + array(new ECBlocks(28, array(new ECB(1, 107), + new ECB(5, 108))), + new ECBlocks(28, array(new ECB(10, 46), + new ECB(1, 47))), + new ECBlocks(28, array(new ECB(1, 22), + new ECB(15, 23))), + new ECBlocks(28, array(new ECB(2, 14), + new ECB(17, 15))))), + new Version(18, array(6, 30, 56, 82), + array(new ECBlocks(30, array(new ECB(5, 120), + new ECB(1, 121))), + new ECBlocks(26, array(new ECB(9, 43), + new ECB(4, 44))), + new ECBlocks(28, array(new ECB(17, 22), + new ECB(1, 23))), + new ECBlocks(28, array(new ECB(2, 14), + new ECB(19, 15))))), + new Version(19, array(6, 30, 58, 86), + array(new ECBlocks(28, array(new ECB(3, 113), + new ECB(4, 114))), + new ECBlocks(26, array(new ECB(3, 44), + new ECB(11, 45))), + new ECBlocks(26, array(new ECB(17, 21), + new ECB(4, 22))), + new ECBlocks(26, array(new ECB(9, 13), + new ECB(16, 14))))), + new Version(20, array(6, 34, 62, 90), + array(new ECBlocks(28, array(new ECB(3, 107), + new ECB(5, 108))), + new ECBlocks(26, array(new ECB(3, 41), + new ECB(13, 42))), + new ECBlocks(30, array(new ECB(15, 24), + new ECB(5, 25))), + new ECBlocks(28, array(new ECB(15, 15), + new ECB(10, 16))))), + new Version(21, array(6, 28, 50, 72, 94), + array( new ECBlocks(28, array(new ECB(4, 116), + new ECB(4, 117))), + new ECBlocks(26, array(new ECB(17, 42))), + new ECBlocks(28, array(new ECB(17, 22), + new ECB(6, 23))), + new ECBlocks(30, array(new ECB(19, 16), + new ECB(6, 17))))), + new Version(22, array(6, 26, 50, 74, 98), + array(new ECBlocks(28, array(new ECB(2, 111), + new ECB(7, 112))), + new ECBlocks(28, array(new ECB(17, 46))), + new ECBlocks(30, array(new ECB(7, 24), + new ECB(16, 25))), + new ECBlocks(24, array(new ECB(34, 13))))), + new Version(23, array(6, 30, 54, 78, 102), + new ECBlocks(30, array(new ECB(4, 121), + new ECB(5, 122))), + new ECBlocks(28, array(new ECB(4, 47), + new ECB(14, 48))), + new ECBlocks(30, array(new ECB(11, 24), + new ECB(14, 25))), + new ECBlocks(30, array(new ECB(16, 15), + new ECB(14, 16)))), + new Version(24, array(6, 28, 54, 80, 106), + array(new ECBlocks(30, array(new ECB(6, 117), + new ECB(4, 118))), + new ECBlocks(28, array(new ECB(6, 45), + new ECB(14, 46))), + new ECBlocks(30, array(new ECB(11, 24), + new ECB(16, 25))), + new ECBlocks(30, array(new ECB(30, 16), + new ECB(2, 17))))), + new Version(25, array(6, 32, 58, 84, 110), + array(new ECBlocks(26, array(new ECB(8, 106), + new ECB(4, 107))), + new ECBlocks(28, array(new ECB(8, 47), + new ECB(13, 48))), + new ECBlocks(30, array(new ECB(7, 24), + new ECB(22, 25))), + new ECBlocks(30, array(new ECB(22, 15), + new ECB(13, 16))))), + new Version(26, array(6, 30, 58, 86, 114), + array(new ECBlocks(28, array(new ECB(10, 114), + new ECB(2, 115))), + new ECBlocks(28, array(new ECB(19, 46), + new ECB(4, 47))), + new ECBlocks(28, array(new ECB(28, 22), + new ECB(6, 23))), + new ECBlocks(30, array(new ECB(33, 16), + new ECB(4, 17))))), + new Version(27, array(6, 34, 62, 90, 118), + array(new ECBlocks(30, array(new ECB(8, 122), + new ECB(4, 123))), + new ECBlocks(28, array(new ECB(22, 45), + new ECB(3, 46))), + new ECBlocks(30, array(new ECB(8, 23), + new ECB(26, 24))), + new ECBlocks(30, array(new ECB(12, 15), + new ECB(28, 16))))), + new Version(28, array(6, 26, 50, 74, 98, 122), + array(new ECBlocks(30, array(new ECB(3, 117), + new ECB(10, 118))), + new ECBlocks(28, array(new ECB(3, 45), + new ECB(23, 46))), + new ECBlocks(30, array(new ECB(4, 24), + new ECB(31, 25))), + new ECBlocks(30, array(new ECB(11, 15), + new ECB(31, 16))))), + new Version(29, array(6, 30, 54, 78, 102, 126), + array(new ECBlocks(30, array(new ECB(7, 116), + new ECB(7, 117))), + new ECBlocks(28, array(new ECB(21, 45), + new ECB(7, 46))), + new ECBlocks(30, array(new ECB(1, 23), + new ECB(37, 24))), + new ECBlocks(30, array(new ECB(19, 15), + new ECB(26, 16))))), + new Version(30, array(6, 26, 52, 78, 104, 130), + array(new ECBlocks(30, array(new ECB(5, 115), + new ECB(10, 116))), + new ECBlocks(28, array(new ECB(19, 47), + new ECB(10, 48))), + new ECBlocks(30, array(new ECB(15, 24), + new ECB(25, 25))), + new ECBlocks(30, array(new ECB(23, 15), + new ECB(25, 16))))), + new Version(31, array(6, 30, 56, 82, 108, 134), + array(new ECBlocks(30, array(new ECB(13, 115), + new ECB(3, 116))), + new ECBlocks(28, array(new ECB(2, 46), + new ECB(29, 47))), + new ECBlocks(30, array(new ECB(42, 24), + new ECB(1, 25))), + new ECBlocks(30, array(new ECB(23, 15), + new ECB(28, 16))))), + new Version(32, array(6, 34, 60, 86, 112, 138), + array(new ECBlocks(30, array(new ECB(17, 115))), + new ECBlocks(28, array(new ECB(10, 46), + new ECB(23, 47))), + new ECBlocks(30, array(new ECB(10, 24), + new ECB(35, 25))), + new ECBlocks(30, array(new ECB(19, 15), + new ECB(35, 16))))), + new Version(33, array(6, 30, 58, 86, 114, 142), + array(new ECBlocks(30, array(new ECB(17, 115), + new ECB(1, 116))), + new ECBlocks(28, array(new ECB(14, 46), + new ECB(21, 47))), + new ECBlocks(30, array(new ECB(29, 24), + new ECB(19, 25))), + new ECBlocks(30, array(new ECB(11, 15), + new ECB(46, 16))))), + new Version(34, array(6, 34, 62, 90, 118, 146), + array(new ECBlocks(30, array(new ECB(13, 115), + new ECB(6, 116))), + new ECBlocks(28, array(new ECB(14, 46), + new ECB(23, 47))), + new ECBlocks(30, array(new ECB(44, 24), + new ECB(7, 25))), + new ECBlocks(30, array(new ECB(59, 16), + new ECB(1, 17))))), + new Version(35, array(6, 30, 54, 78, 102, 126, 150), + array(new ECBlocks(30, array(new ECB(12, 121), + new ECB(7, 122))), + new ECBlocks(28, array(new ECB(12, 47), + new ECB(26, 48))), + new ECBlocks(30, array(new ECB(39, 24), + new ECB(14, 25))), + new ECBlocks(30, array(new ECB(22, 15), + new ECB(41, 16))))), + new Version(36, array(6, 24, 50, 76, 102, 128, 154), + array(new ECBlocks(30, array(new ECB(6, 121), + new ECB(14, 122))), + new ECBlocks(28, array(new ECB(6, 47), + new ECB(34, 48))), + new ECBlocks(30, array(new ECB(46, 24), + new ECB(10, 25))), + new ECBlocks(30, array(new ECB(2, 15), + new ECB(64, 16))))), + new Version(37, array(6, 28, 54, 80, 106, 132, 158), + array(new ECBlocks(30, array(new ECB(17, 122), + new ECB(4, 123))), + new ECBlocks(28, array(new ECB(29, 46), + new ECB(14, 47))), + new ECBlocks(30, array(new ECB(49, 24), + new ECB(10, 25))), + new ECBlocks(30, array(new ECB(24, 15), + new ECB(46, 16))))), + new Version(38, array(6, 32, 58, 84, 110, 136, 162), + array(new ECBlocks(30, array(new ECB(4, 122), + new ECB(18, 123))), + new ECBlocks(28, array(new ECB(13, 46), + new ECB(32, 47))), + new ECBlocks(30, array(new ECB(48, 24), + new ECB(14, 25))), + new ECBlocks(30, array(new ECB(42, 15), + new ECB(32, 16))))), + new Version(39, array(6, 26, 54, 82, 110, 138, 166), + array(new ECBlocks(30, array(new ECB(20, 117), + new ECB(4, 118))), + new ECBlocks(28, array(new ECB(40, 47), + new ECB(7, 48))), + new ECBlocks(30, array(new ECB(43, 24), + new ECB(22, 25))), + new ECBlocks(30, array(new ECB(10, 15), + new ECB(67, 16))))), + new Version(40, array(6, 30, 58, 86, 114, 142, 170), + array(new ECBlocks(30, array(new ECB(19, 118), + new ECB(6, 119))), + new ECBlocks(28, array(new ECB(18, 47), + new ECB(31, 48))), + new ECBlocks(30, array(new ECB(34, 24), + new ECB(34, 25))), + new ECBlocks(30, array(new ECB(20, 15), + new ECB(61, 16))))) + ); + } +} + +/** + *Encapsulates a set of error-correction blocks in one symbol version. Most versions will + * use blocks of differing sizes within one version, so, this encapsulates the parameters for + * each set of blocks. It also holds the number of error-correction codewords per block since it + * will be the same across all blocks within one version.
+ */ +final class ECBlocks +{ + private $ecCodewordsPerBlock; + private $ecBlocks; + + function __construct($ecCodewordsPerBlock, $ecBlocks) + { + $this->ecCodewordsPerBlock = $ecCodewordsPerBlock; + $this->ecBlocks = $ecBlocks; + } + + public function getECCodewordsPerBlock() + { + return $this->ecCodewordsPerBlock; + } + + public function getNumBlocks() + { + $total = 0; + foreach ($this->ecBlocks as $ecBlock) { + $total += $ecBlock->getCount(); + } + return $total; + } + + public function getTotalECCodewords() + { + return $this->ecCodewordsPerBlock * $this->getNumBlocks(); + } + + public function getECBlocks() + { + return $this->ecBlocks; + } +} + +/** + *Encapsualtes the parameters for one error-correction block in one symbol version. + * This includes the number of data codewords, and the number of times a block with these + * parameters is used consecutively in the QR code version's format.
+ */ +final class ECB +{ + private $count; + private $dataCodewords; + + function __construct($count, $dataCodewords) + { + $this->count = $count; + $this->dataCodewords = $dataCodewords; + } + + public function getCount() + { + return $this->count; + } + + public function getDataCodewords() + { + return $this->dataCodewords; + } + + +//@Override + public function toString() + { + die('Version ECB toString()'); + // return parent::$versionNumber; + } + + +} + + diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/AlignmentPattern.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/AlignmentPattern.php new file mode 100755 index 000000000..b6d413076 --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/AlignmentPattern.php @@ -0,0 +1,60 @@ +Encapsulates an alignment pattern, which are the smaller square patterns found in + * all but the simplest QR Codes. + * + * @author Sean Owen + */ +final class AlignmentPattern extends ResultPoint { + +private $estimatedModuleSize; + +function __construct($posX, $posY, $estimatedModuleSize) { +parent::__construct($posX, $posY); +$this->estimatedModuleSize = $estimatedModuleSize; +} + + /** + *Determines if this alignment pattern "about equals" an alignment pattern at the stated + * position and size -- meaning, it is at nearly the same center with nearly the same size.
+ */ + function aboutEquals($moduleSize, $i, $j) { + if (abs($i - $this->getY()) <= $moduleSize && abs($j - $this->getX()) <= $moduleSize) { + $moduleSizeDiff = abs($moduleSize - $this->estimatedModuleSize); + return $moduleSizeDiff <= 1.0 || $moduleSizeDiff <= $this->estimatedModuleSize; + } + return false; +} + + /** + * Combines this object's current estimate of a finder pattern position and module size + * with a new estimate. It returns a new {@code FinderPattern} containing an average of the two. + */ + function combineEstimate($i, $j, $newModuleSize) { + $combinedX = ($this->getX() + $j) / 2.0; + $combinedY = ($this->getY() + $i) / 2.0; + $combinedModuleSize = ($this->estimatedModuleSize + $newModuleSize) / 2.0; + return new AlignmentPattern($combinedX, $combinedY, $combinedModuleSize); + } + +} \ No newline at end of file diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/AlignmentPatternFinder.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/AlignmentPatternFinder.php new file mode 100755 index 000000000..0484ffa6b --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/AlignmentPatternFinder.php @@ -0,0 +1,277 @@ +This class attempts to find alignment patterns in a QR Code. Alignment patterns look like finder + * patterns but are smaller and appear at regular intervals throughout the image. + * + *At the moment this only looks for the bottom-right alignment pattern.
+ * + *This is mostly a simplified copy of {@link FinderPatternFinder}. It is copied, + * pasted and stripped down here for maximum performance but does unfortunately duplicate + * some code.
+ * + *This class is thread-safe but not reentrant. Each thread must allocate its own object.
+ * + * @author Sean Owen + */ +final class AlignmentPatternFinder { + + private $image; + private $possibleCenters; + private $startX; + private $startY; + private $width; + private $height; + private $moduleSize; + private $crossCheckStateCount; + private $resultPointCallback; + + /** + *Creates a finder that will look in a portion of the whole image.
+ * + * @param image image to search + * @param startX left column from which to start searching + * @param startY top row from which to start searching + * @param width width of region to search + * @param height height of region to search + * @param moduleSize estimated module size so far + */ + function __construct($image, + $startX, + $startY, + $width, + $height, + $moduleSize, + $resultPointCallback) { + $this->image = $image; + $this->possibleCenters = array(); + $this->startX = $startX; + $this->startY = $startY; + $this->width = $width; + $this->height = $height; + $this->moduleSize = $moduleSize; + $this->crossCheckStateCount = array(); + $this->resultPointCallback = $resultPointCallback; + } + + /** + *This method attempts to find the bottom-right alignment pattern in the image. It is a bit messy since + * it's pretty performance-critical and so is written to be fast foremost.
+ * + * @return {@link AlignmentPattern} if found + * @throws NotFoundException if not found + */ + function find() { + $startX = $this->startX; + $height = $this->height; + $maxJ = $startX + $this->width; + $middleI = $this->startY + ($height / 2); + // We are looking for black/white/black modules in 1:1:1 ratio; + // this tracks the number of black/white/black modules seen so far + $stateCount = array(); + for ($iGen = 0; $iGen < $height; $iGen++) { + // Search from middle outwards + $i = $middleI + (($iGen & 0x01) == 0 ? ($iGen + 1) / 2 : -(($iGen + 1) / 2)); + $i = intval($i); + $stateCount[0] = 0; + $stateCount[1] = 0; + $stateCount[2] = 0; + $j = $startX; + // Burn off leading white pixels before anything else; if we start in the middle of + // a white run, it doesn't make sense to count its length, since we don't know if the + // white run continued to the left of the start point + while ($j < $maxJ && !$this->image->get($j, $i)) { + $j++; + } + $currentState = 0; + while ($j < $maxJ) { + if ($this->image->get($j, $i)) { + // Black pixel + if ($currentState == 1) { // Counting black pixels + $stateCount[$currentState]++; + } else { // Counting white pixels + if ($currentState == 2) { // A winner? + if ($this->foundPatternCross($stateCount)) { // Yes + $confirmed = $this->handlePossibleCenter($stateCount, $i, $j); + if ($confirmed != null) { + return $confirmed; + } + } + $stateCount[0] = $stateCount[2]; + $stateCount[1] = 1; + $stateCount[2] = 0; + $currentState = 1; + } else { + $stateCount[++$currentState]++; + } + } + } else { // White pixel + if ($currentState == 1) { // Counting black pixels + $currentState++; + } + $stateCount[$currentState]++; + } + $j++; + } + if ($this->foundPatternCross($stateCount)) { + $confirmed = $this->handlePossibleCenter($stateCount, $i, $maxJ); + if ($confirmed != null) { + return $confirmed; + } + } + + } + + // Hmm, nothing we saw was observed and confirmed twice. If we had + // any guess at all, return it. + if (count($this->possibleCenters)) { + return $this->possibleCenters[0]; + } + + throw NotFoundException::getNotFoundInstance(); + } + + /** + * Given a count of black/white/black pixels just seen and an end position, + * figures the location of the center of this black/white/black run. + */ + private static function centerFromEnd($stateCount, $end) { + return (float) ($end - $stateCount[2]) - $stateCount[1] / 2.0; + } + + /** + * @param stateCount count of black/white/black pixels just read + * @return true iff the proportions of the counts is close enough to the 1/1/1 ratios + * used by alignment patterns to be considered a match + */ + private function foundPatternCross($stateCount) { + $moduleSize = $this->moduleSize; + $maxVariance = $moduleSize / 2.0; + for ($i = 0; $i < 3; $i++) { + if (abs($moduleSize - $stateCount[$i]) >= $maxVariance) { + return false; + } + } + return true; + } + + /** + *After a horizontal scan finds a potential alignment pattern, this method + * "cross-checks" by scanning down vertically through the center of the possible + * alignment pattern to see if the same proportion is detected.
+ * + * @param startI row where an alignment pattern was detected + * @param centerJ center of the section that appears to cross an alignment pattern + * @param maxCount maximum reasonable number of modules that should be + * observed in any reading state, based on the results of the horizontal scan + * @return vertical center of alignment pattern, or {@link Float#NaN} if not found + */ + private function crossCheckVertical($startI, $centerJ, $maxCount, + $originalStateCountTotal) { + $image = $this->image; + + $maxI = $image->getHeight(); + $stateCount = $this->crossCheckStateCount; + $stateCount[0] = 0; + $stateCount[1] = 0; + $stateCount[2] = 0; + + // Start counting up from center + $i = $startI; + while ($i >= 0 && $image->get($centerJ, $i) && $stateCount[1] <= $maxCount) { + $stateCount[1]++; + $i--; + } + // If already too many modules in this state or ran off the edge: + if ($i < 0 || $stateCount[1] > $maxCount) { + return NAN; + } + while ($i >= 0 && !$image->get($centerJ, $i) && $stateCount[0] <= $maxCount) { + $stateCount[0]++; + $i--; + } + if ($stateCount[0] > $maxCount) { + return NAN; + } + + // Now also count down from center + $i = $startI + 1; + while ($i < $maxI && $image->get($centerJ, $i) && $stateCount[1] <= $maxCount) { + $stateCount[1]++; + $i++; + } + if ($i == $maxI || $stateCount[1] > $maxCount) { + return NAN; + } + while ($i < $maxI && !$image->get($centerJ, $i) && $stateCount[2] <= $maxCount) { + $stateCount[2]++; + $i++; + } + if ($stateCount[2] > $maxCount) { + return NAN; + } + + $stateCountTotal = $stateCount[0] + $stateCount[1] + $stateCount[2]; + if (5 * abs($stateCountTotal - $originalStateCountTotal) >= 2 * $originalStateCountTotal) { + return NAN; + } + + return $this->foundPatternCross($stateCount) ? $this->centerFromEnd($stateCount, $i) : NAN; + } + + /** + *This is called when a horizontal scan finds a possible alignment pattern. It will + * cross check with a vertical scan, and if successful, will see if this pattern had been + * found on a previous horizontal scan. If so, we consider it confirmed and conclude we have + * found the alignment pattern.
+ * + * @param stateCount reading state module counts from horizontal scan + * @param i row where alignment pattern may be found + * @param j end of possible alignment pattern in row + * @return {@link AlignmentPattern} if we have found the same pattern twice, or null if not + */ + private function handlePossibleCenter($stateCount, $i, $j) { + $stateCountTotal = $stateCount[0] + $stateCount[1] + $stateCount[2]; + $centerJ = $this->centerFromEnd($stateCount, $j); + $centerI = $this->crossCheckVertical($i, (int) $centerJ, 2 * $stateCount[1], $stateCountTotal); + if (!is_nan($centerI)) { + $estimatedModuleSize = (float) ($stateCount[0] + $stateCount[1] + $stateCount[2]) / 3.0; + foreach ($this->possibleCenters as $center) { + // Look for about the same center and module size: + if ($center->aboutEquals($estimatedModuleSize, $centerI, $centerJ)) { + return $center->combineEstimate($centerI, $centerJ, $estimatedModuleSize); + } + } + // Hadn't found this before; save it + $point = new AlignmentPattern($centerJ, $centerI, $estimatedModuleSize); + $this->possibleCenters[] = $point; + if ($this->resultPointCallback != null) { + $this->resultPointCallback->foundPossibleResultPoint($point); + } + } + return null; + } + +} diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/Detector.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/Detector.php new file mode 100755 index 000000000..2043a49ac --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/Detector.php @@ -0,0 +1,405 @@ +Encapsulates logic that can detect a QR Code in an image, even if the QR Code + * is rotated or skewed, or partially obscured. + * + * @author Sean Owen + */ +?> +image = $image; + } + + protected final function getImage() { + return $this->image; + } + + protected final function getResultPointCallback() { + return $this->resultPointCallback; + } + + /** + *Detects a QR Code in an image.
+ * + * @return {@link DetectorResult} encapsulating results of detecting a QR Code + * @throws NotFoundException if QR Code cannot be found + * @throws FormatException if a QR Code cannot be decoded + */ + + + /** + *Detects a QR Code in an image.
+ * + * @param hints optional hints to detector + * @return {@link DetectorResult} encapsulating results of detecting a QR Code + * @throws NotFoundException if QR Code cannot be found + * @throws FormatException if a QR Code cannot be decoded + */ + public final function detect($hints=null){/*MapComputes the dimension (number of modules on a size) of the QR Code based on the position + * of the finder patterns and estimated module size.
+ */ + private static function computeDimension($topLeft, + $topRight, + $bottomLeft, + $moduleSize) { + $tltrCentersDimension = MathUtils::round(ResultPoint::distance($topLeft, $topRight) / $moduleSize); + $tlblCentersDimension = MathUtils::round(ResultPoint::distance($topLeft, $bottomLeft) / $moduleSize); + $dimension = (($tltrCentersDimension + $tlblCentersDimension) / 2) + 7; + switch ($dimension & 0x03) { // mod 4 + case 0: + $dimension++; + break; +// 1? do nothing + case 2: + $dimension--; + break; + case 3: + throw NotFoundException::getNotFoundInstance(); + } + return $dimension; + } + + /** + *Computes an average estimated module size based on estimated derived from the positions + * of the three finder patterns.
+ * + * @param topLeft detected top-left finder pattern center + * @param topRight detected top-right finder pattern center + * @param bottomLeft detected bottom-left finder pattern center + * @return estimated module size + */ + protected final function calculateModuleSize($topLeft, + $topRight, + $bottomLeft) { +// Take the average + return ($this->calculateModuleSizeOneWay($topLeft, $topRight) + + $this->calculateModuleSizeOneWay($topLeft, $bottomLeft)) / 2.0; + } + + /** + *Estimates module size based on two finder patterns -- it uses + * {@link #sizeOfBlackWhiteBlackRunBothWays(int, int, int, int)} to figure the + * width of each, measuring along the axis between their centers.
+ */ + private function calculateModuleSizeOneWay($pattern, $otherPattern) { + $moduleSizeEst1 = $this->sizeOfBlackWhiteBlackRunBothWays($pattern->getX(), + (int) $pattern->getY(), + (int) $otherPattern->getX(), + (int) $otherPattern->getY()); + $moduleSizeEst2 = $this->sizeOfBlackWhiteBlackRunBothWays((int) $otherPattern->getX(), + (int) $otherPattern->getY(), + (int) $pattern->getX(), + (int) $pattern->getY()); + if (is_nan($moduleSizeEst1)) { + return $moduleSizeEst2 / 7.0; + } + if (is_nan($moduleSizeEst2)) { + return $moduleSizeEst1 / 7.0; + } +// Average them, and divide by 7 since we've counted the width of 3 black modules, +// and 1 white and 1 black module on either side. Ergo, divide sum by 14. + return ($moduleSizeEst1 + $moduleSizeEst2) / 14.0; + } + + /** + * See {@link #sizeOfBlackWhiteBlackRun(int, int, int, int)}; computes the total width of + * a finder pattern by looking for a black-white-black run from the center in the direction + * of another po$(another finder pattern center), and in the opposite direction too. + */ + private function sizeOfBlackWhiteBlackRunBothWays($fromX, $fromY, $toX, $toY) { + + $result = $this->sizeOfBlackWhiteBlackRun($fromX, $fromY, $toX, $toY); + +// Now count other way -- don't run off image though of course + $scale = 1.0; + $otherToX = $fromX - ($toX - $fromX); + if ($otherToX < 0) { + $scale = (float) $fromX / (float) ($fromX - $otherToX); + $otherToX = 0; + } else if ($otherToX >= $this->image->getWidth()) { + $scale = (float) ($this->image->getWidth() - 1 - $fromX) / (float) ($otherToX - $fromX); + $otherToX = $this->image->getWidth() - 1; + } + $otherToY = (int) ($fromY - ($toY - $fromY) * $scale); + + $scale = 1.0; + if ($otherToY < 0) { + $scale = (float) $fromY / (float) ($fromY - $otherToY); + $otherToY = 0; + } else if ($otherToY >= $this->image->getHeight()) { + $scale = (float) ($this->image->getHeight() - 1 - $fromY) / (float) ($otherToY - $fromY); + $otherToY = $this->image->getHeight() - 1; + } + $otherToX = (int) ($fromX + ($otherToX - $fromX) * $scale); + + $result += $this->sizeOfBlackWhiteBlackRun($fromX, $fromY, $otherToX, $otherToY); + +// Middle pixel is double-counted this way; subtract 1 + return $result - 1.0; + } + + /** + *This method traces a line from a po$in the image, in the direction towards another point. + * It begins in a black region, and keeps going until it finds white, then black, then white again. + * It reports the distance from the start to this point.
+ * + *This is used when figuring out how wide a finder pattern is, when the finder pattern + * may be skewed or rotated.
+ */ + private function sizeOfBlackWhiteBlackRun($fromX, $fromY, $toX, $toY) { +// Mild variant of Bresenham's algorithm; +// see http://en.wikipedia.org/wiki/Bresenham's_line_algorithm + $steep = abs($toY - $fromY) > abs($toX - $fromX); + if ($steep) { + $temp = $fromX; + $fromX = $fromY; + $fromY = $temp; + $temp = $toX; + $toX = $toY; + $toY = $temp; + } + + $dx = abs($toX - $fromX); + $dy = abs($toY - $fromY); + $error = -$dx / 2; + $xstep = $fromX < $toX ? 1 : -1; + $ystep = $fromY < $toY ? 1 : -1; + +// In black pixels, looking for white, first or second time. + $state = 0; +// Loop up until x == toX, but not beyond + $xLimit = $toX + $xstep; + for ($x = $fromX, $y = $fromY; $x != $xLimit; $x += $xstep) { + $realX = $steep ? $y : $x; + $realY = $steep ? $x : $y; + +// Does current pixel mean we have moved white to black or vice versa? +// Scanning black in state 0,2 and white in state 1, so if we find the wrong +// color, advance to next state or end if we are in state 2 already + if (($state == 1) == $this->image->get($realX, $realY)) { + if ($state == 2) { + return MathUtils::distance($x, $y, $fromX, $fromY); + } + $state++; + } + + $error += $dy; + if ($error > 0) { + if ($y == $toY) { + break; + } + $y += $ystep; + $error -= $dx; + } + } +// Found black-white-black; give the benefit of the doubt that the next pixel outside the image +// is "white" so this last po$at (toX+xStep,toY) is the right ending. This is really a +// small approximation; (toX+xStep,toY+yStep) might be really correct. Ignore this. + if ($state == 2) { + return MathUtils::distance($toX + $xstep, $toY, $fromX, $fromY); + } +// else we didn't find even black-white-black; no estimate is really possible + return NAN; + } + + /** + *Attempts to locate an alignment pattern in a limited region of the image, which is + * guessed to contain it. This method uses {@link AlignmentPattern}.
+ * + * @param overallEstModuleSize estimated module size so far + * @param estAlignmentX x coordinate of center of area probably containing alignment pattern + * @param estAlignmentY y coordinate of above + * @param allowanceFactor number of pixels in all directions to search from the center + * @return {@link AlignmentPattern} if found, or null otherwise + * @throws NotFoundException if an unexpected error occurs during detection + */ + protected final function findAlignmentInRegion($overallEstModuleSize, + $estAlignmentX, + $estAlignmentY, + $allowanceFactor) + { +// Look for an alignment pattern (3 modules in size) around where it +// should be + $allowance = (int) ($allowanceFactor * $overallEstModuleSize); + $alignmentAreaLeftX = max(0, $estAlignmentX - $allowance); + $alignmentAreaRightX = min($this->image->getWidth() - 1, $estAlignmentX + $allowance); + if ($alignmentAreaRightX - $alignmentAreaLeftX < $overallEstModuleSize * 3) { + throw NotFoundException::getNotFoundInstance(); + } + + $alignmentAreaTopY = max(0, $estAlignmentY - $allowance); + $alignmentAreaBottomY = min($this->image->getHeight() - 1, $estAlignmentY + $allowance); + if ($alignmentAreaBottomY - $alignmentAreaTopY < $overallEstModuleSize * 3) { + throw NotFoundException::getNotFoundInstance(); + } + + $alignmentFinder = + new AlignmentPatternFinder( + $this->image, + $alignmentAreaLeftX, + $alignmentAreaTopY, + $alignmentAreaRightX - $alignmentAreaLeftX, + $alignmentAreaBottomY - $alignmentAreaTopY, + $overallEstModuleSize, + $this->resultPointCallback); + return $alignmentFinder->find(); + } + +} diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/FinderPattern.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/FinderPattern.php new file mode 100755 index 000000000..1900a78ee --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/FinderPattern.php @@ -0,0 +1,81 @@ +Encapsulates a finder pattern, which are the three square patterns found in + * the corners of QR Codes. It also encapsulates a count of similar finder patterns, + * as a convenience to the finder's bookkeeping. + * + * @author Sean Owen + */ +final class FinderPattern extends ResultPoint { + +private $estimatedModuleSize; +private $count; + + + + function __construct($posX, $posY, $estimatedModuleSize, $count=1) { + parent::__construct($posX, $posY); + $this->estimatedModuleSize = $estimatedModuleSize; + $this->count = $count; +} + + public function getEstimatedModuleSize() { + return $this->estimatedModuleSize; + } + + function getCount() { + return $this->count; + } + + /* + void incrementCount() { + this.count++; + } + */ + + /** + *Determines if this finder pattern "about equals" a finder pattern at the stated + * position and size -- meaning, it is at nearly the same center with nearly the same size.
+ */ + function aboutEquals($moduleSize, $i, $j) { + if (abs($i - $this->getY()) <= $moduleSize && abs($j - $this->getX()) <= $moduleSize) { + $moduleSizeDiff = abs($moduleSize - $this->estimatedModuleSize); + return $moduleSizeDiff <= 1.0 || $moduleSizeDiff <= $this->estimatedModuleSize; + } + return false; +} + + /** + * Combines this object's current estimate of a finder pattern position and module size + * with a new estimate. It returns a new {@code FinderPattern} containing a weighted average + * based on count. + */ + function combineEstimate($i, $j, $newModuleSize) { + $combinedCount = $this->count + 1; + $combinedX = ($this->count * $this->getX() + $j) / $combinedCount; + $combinedY = ($this->count * $this->getY() + $i) / $combinedCount; + $combinedModuleSize = ($this->count * $this->estimatedModuleSize + $newModuleSize) / $combinedCount; + return new FinderPattern($combinedX, $combinedY, $combinedModuleSize, $combinedCount); + } + +} diff --git a/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/FinderPatternFinder.php b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/FinderPatternFinder.php new file mode 100755 index 000000000..d2fe473ae --- /dev/null +++ b/Server/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/FinderPatternFinder.php @@ -0,0 +1,705 @@ +This class attempts to find finder patterns in a QR Code. Finder patterns are the square + * markers at three corners of a QR Code. + * + *This class is thread-safe but not reentrant. Each thread must allocate its own object.
+ *
+ * @author Sean Owen
+ */
+class FinderPatternFinder
+{
+
+ private static $CENTER_QUORUM = 2;
+ protected static $MIN_SKIP = 3; // 1 pixel/module times 3 modules/center
+ protected static $MAX_MODULES = 57; // support up to version 10 for mobile clients
+
+ private $image;
+ private $average;
+ private $possibleCenters; //private final List Creates a finder that will search the image for three finder patterns. After a horizontal scan finds a potential finder pattern, this method
+ * "cross-checks" by scanning down vertically through the center of the possible
+ * finder pattern to see if the same proportion is detected. Like {@link #crossCheckVertical(int, int, int, int)}, and in fact is basically identical,
+ * except it reads horizontally instead of vertically. This is used to cross-cross
+ * check a vertical cross check and locate the real center of the alignment pattern. This is called when a horizontal scan finds a possible alignment pattern. It will
+ * cross check with a vertical scan, and if successful, will, ah, cross-cross-check
+ * with another horizontal scan. This is needed primarily to locate the real horizontal
+ * center of the pattern in cases of extreme skew.
+ * And then we cross-cross-cross check with another diagonal scan. If that succeeds the finder pattern location is added to a list that tracks
+ * the number of times each location has been nearly-matched as a finder pattern.
+ * Each additional find is more evidence that the location is in fact a finder
+ * pattern center
+ *
+ * @param $stateCount reading state module counts from horizontal scan
+ * @param i row where finder pattern may be found
+ * @param j end of possible finder pattern in row
+ * @param pureBarcode true if in "pure barcode" mode
+ * @return true if a finder pattern candidate was found this time
+ */
+ protected final function handlePossibleCenter($stateCount, $i, $j, $pureBarcode)
+ {
+ $stateCountTotal = $stateCount[0] + $stateCount[1] + $stateCount[2] + $stateCount[3] +
+ $stateCount[4];
+ $centerJ = $this->centerFromEnd($stateCount, $j);
+ $centerI = $this->crossCheckVertical($i, intval($centerJ), $stateCount[2], $stateCountTotal);
+ if (!is_nan($centerI)) {
+ // Re-cross check
+ $centerJ = $this->crossCheckHorizontal(intval($centerJ), intval($centerI), $stateCount[2], $stateCountTotal);
+ if (!is_nan($centerJ) &&
+ (!$pureBarcode || $this->crossCheckDiagonal(intval($centerI), intval($centerJ), $stateCount[2], $stateCountTotal))
+ ) {
+ $estimatedModuleSize = (float)$stateCountTotal / 7.0;
+ $found = false;
+ for ($index = 0; $index < count($this->possibleCenters); $index++) {
+ $center = $this->possibleCenters[$index];
+ // Look for about the same center and module size:
+ if ($center->aboutEquals($estimatedModuleSize, $centerI, $centerJ)) {
+ $this->possibleCenters[$index] = $center->combineEstimate($centerI, $centerJ, $estimatedModuleSize);
+ $found = true;
+ break;
+ }
+ }
+ if (!$found) {
+ $point = new FinderPattern($centerJ, $centerI, $estimatedModuleSize);
+ $this->possibleCenters[] = $point;
+ if ($this->resultPointCallback != null) {
+ $this->resultPointCallback->foundPossibleResultPoint($point);
+ }
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @return number of rows we could safely skip during scanning, based on the first
+ * two finder patterns that have been located. In some cases their position will
+ * allow us to infer that the third pattern must lie below a certain point farther
+ * down in the image.
+ */
+ private function findRowSkip()
+ {
+ $max = count($this->possibleCenters);
+ if ($max <= 1) {
+ return 0;
+ }
+ $firstConfirmedCenter = null;
+ foreach ($this->possibleCenters as $center) {
+
+
+ if ($center->getCount() >= self::$CENTER_QUORUM) {
+ if ($firstConfirmedCenter == null) {
+ $firstConfirmedCenter = $center;
+ } else {
+ // We have two confirmed centers
+ // How far down can we skip before resuming looking for the next
+ // pattern? In the worst case, only the difference between the
+ // difference in the x / y coordinates of the two centers.
+ // This is the case where you find top left last.
+ $this->hasSkipped = true;
+ return intval((abs($firstConfirmedCenter->getX() - $center->getX()) -
+ abs($firstConfirmedCenter->getY() - $center->getY())) / 2);
+ }
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * @return true iff we have found at least 3 finder patterns that have been detected
+ * at least {@link #CENTER_QUORUM} times each, and, the estimated module size of the
+ * candidates is "pretty similar"
+ */
+ private function haveMultiplyConfirmedCenters()
+ {
+ $confirmedCount = 0;
+ $totalModuleSize = 0.0;
+ $max = count($this->possibleCenters);
+ foreach ($this->possibleCenters as $pattern) {
+ if ($pattern->getCount() >= self::$CENTER_QUORUM) {
+ $confirmedCount++;
+ $totalModuleSize += $pattern->getEstimatedModuleSize();
+ }
+ }
+ if ($confirmedCount < 3) {
+ return false;
+ }
+ // OK, we have at least 3 confirmed centers, but, it's possible that one is a "false positive"
+ // and that we need to keep looking. We detect this by asking if the estimated module sizes
+ // vary too much. We arbitrarily say that when the total deviation from average exceeds
+ // 5% of the total module size estimates, it's too much.
+ $average = $totalModuleSize / (float)$max;
+ $totalDeviation = 0.0;
+ foreach ($this->possibleCenters as $pattern) {
+ $totalDeviation += abs($pattern->getEstimatedModuleSize() - $average);
+ }
+ return $totalDeviation <= 0.05 * $totalModuleSize;
+ }
+
+ /**
+ * @return the 3 best {@link FinderPattern}s from our list of candidates. The "best" are
+ * those that have been detected at least {@link #CENTER_QUORUM} times, and whose module
+ * size differs from the average among those patterns the least
+ * @throws NotFoundException if 3 such finder patterns do not exist
+ */
+ private function selectBestPatterns()
+ {
+ $startSize = count($this->possibleCenters);
+ if ($startSize < 3) {
+ // Couldn't find enough finder patterns
+ throw new NotFoundException;
+ }
+
+ // Filter outlier possibilities whose module size is too different
+ if ($startSize > 3) {
+ // But we can only afford to do so if we have at least 4 possibilities to choose from
+ $totalModuleSize = 0.0;
+ $square = 0.0;
+ foreach ($this->possibleCenters as $center) {
+ $size = $center->getEstimatedModuleSize();
+ $totalModuleSize += $size;
+ $square += $size * $size;
+ }
+ $this->average = $totalModuleSize / (float)$startSize;
+ $stdDev = (float)sqrt($square / $startSize - $this->average * $this->average);
+
+ usort($this->possibleCenters, array($this,'FurthestFromAverageComparator'));
+
+ $limit = max(0.2 * $this->average, $stdDev);
+
+ for ($i = 0; $i < count($this->possibleCenters) && count($this->possibleCenters) > 3; $i++) {
+ $pattern = $this->possibleCenters[$i];
+ if (abs($pattern->getEstimatedModuleSize() - $this->average) > $limit) {
+ unset($this->possibleCenters[$i]);//возможно что ключи меняются в java при вызове .remove(i) ???
+ $this->possibleCenters = array_values($this->possibleCenters);
+ $i--;
+ }
+ }
+ }
+
+ if (count($this->possibleCenters) > 3) {
+ // Throw away all but those first size candidate points we found.
+
+ $totalModuleSize = 0.0;
+ foreach ($this->possibleCenters as $possibleCenter) {
+ $totalModuleSize += $possibleCenter->getEstimatedModuleSize();
+ }
+
+ $this->average = $totalModuleSize / (float)count($this->possibleCenters);
+
+ usort($this->possibleCenters, array($this,'CenterComparator'));
+
+ array_slice($this->possibleCenters, 3, count($this->possibleCenters) - 3);
+
+
+ }
+
+ return array($this->possibleCenters[0], $this->possibleCenters[1], $this->possibleCenters[2]);
+
+
+ }
+ /**
+ * Orders by furthest from average Orders by {@link FinderPattern#getCount()}, descending.
+ * References: + *
+ * From the original documentation: + *
+ *+ * This routine calculates the LOG(GAMMA) function for a positive real argument X. + * Computation is based on an algorithm outlined in references 1 and 2. + * The program uses rational functions that theoretically approximate LOG(GAMMA) + * to at least 18 significant decimal digits. The approximation for X > 12 is from + * reference 3, while approximations for X < 12.0 are similar to those in reference + * 1, but are unpublished. The accuracy achieved depends on the arithmetic system, + * the compiler, the intrinsic functions, and proper selection of the + * machine-dependent constants. + *
+ *
+ * Error returns:
+ * The program returns the value XINF for X .LE. 0.0 or when overflow would occur.
+ * The computation is believed to be free of underflow and overflow.
+ *
'; +// echo htmlentities($gFileData,ENT_QUOTES,'UTF-8'); +// echo '
'; +// print_r($namespacesMeta); +// echo '
'; +// print_r($namespacesContent); +// echo '
= -1; --$k) {
+ if ($k == -1) {
+ break;
+ }
+ if (abs($e[$k]) <= $eps * (abs($this->s[$k]) + abs($this->s[$k+1]))) {
+ $e[$k] = 0.0;
+ break;
+ }
+ }
+ if ($k == $p - 2) {
+ $kase = 4;
+ } else {
+ for ($ks = $p - 1; $ks >= $k; --$ks) {
+ if ($ks == $k) {
+ break;
+ }
+ $t = ($ks != $p ? abs($e[$ks]) : 0.) + ($ks != $k + 1 ? abs($e[$ks-1]) : 0.);
+ if (abs($this->s[$ks]) <= $eps * $t) {
+ $this->s[$ks] = 0.0;
+ break;
+ }
+ }
+ if ($ks == $k) {
+ $kase = 3;
+ } elseif ($ks == $p-1) {
+ $kase = 1;
+ } else {
+ $kase = 2;
+ $k = $ks;
+ }
+ }
+ ++$k;
+
+ // Perform the task indicated by kase.
+ switch ($kase) {
+ // Deflate negligible s(p).
+ case 1:
+ $f = $e[$p-2];
+ $e[$p-2] = 0.0;
+ for ($j = $p - 2; $j >= $k; --$j) {
+ $t = hypo($this->s[$j], $f);
+ $cs = $this->s[$j] / $t;
+ $sn = $f / $t;
+ $this->s[$j] = $t;
+ if ($j != $k) {
+ $f = -$sn * $e[$j-1];
+ $e[$j-1] = $cs * $e[$j-1];
+ }
+ if ($wantv) {
+ for ($i = 0; $i < $this->n; ++$i) {
+ $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$p-1];
+ $this->V[$i][$p-1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$p-1];
+ $this->V[$i][$j] = $t;
+ }
+ }
+ }
+ break;
+ // Split at negligible s(k).
+ case 2:
+ $f = $e[$k-1];
+ $e[$k-1] = 0.0;
+ for ($j = $k; $j < $p; ++$j) {
+ $t = hypo($this->s[$j], $f);
+ $cs = $this->s[$j] / $t;
+ $sn = $f / $t;
+ $this->s[$j] = $t;
+ $f = -$sn * $e[$j];
+ $e[$j] = $cs * $e[$j];
+ if ($wantu) {
+ for ($i = 0; $i < $this->m; ++$i) {
+ $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$k-1];
+ $this->U[$i][$k-1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$k-1];
+ $this->U[$i][$j] = $t;
+ }
+ }
+ }
+ break;
+ // Perform one qr step.
+ case 3:
+ // Calculate the shift.
+ $scale = max(max(max(max(abs($this->s[$p-1]), abs($this->s[$p-2])), abs($e[$p-2])), abs($this->s[$k])), abs($e[$k]));
+ $sp = $this->s[$p-1] / $scale;
+ $spm1 = $this->s[$p-2] / $scale;
+ $epm1 = $e[$p-2] / $scale;
+ $sk = $this->s[$k] / $scale;
+ $ek = $e[$k] / $scale;
+ $b = (($spm1 + $sp) * ($spm1 - $sp) + $epm1 * $epm1) / 2.0;
+ $c = ($sp * $epm1) * ($sp * $epm1);
+ $shift = 0.0;
+ if (($b != 0.0) || ($c != 0.0)) {
+ $shift = sqrt($b * $b + $c);
+ if ($b < 0.0) {
+ $shift = -$shift;
+ }
+ $shift = $c / ($b + $shift);
+ }
+ $f = ($sk + $sp) * ($sk - $sp) + $shift;
+ $g = $sk * $ek;
+ // Chase zeros.
+ for ($j = $k; $j < $p-1; ++$j) {
+ $t = hypo($f, $g);
+ $cs = $f/$t;
+ $sn = $g/$t;
+ if ($j != $k) {
+ $e[$j-1] = $t;
+ }
+ $f = $cs * $this->s[$j] + $sn * $e[$j];
+ $e[$j] = $cs * $e[$j] - $sn * $this->s[$j];
+ $g = $sn * $this->s[$j+1];
+ $this->s[$j+1] = $cs * $this->s[$j+1];
+ if ($wantv) {
+ for ($i = 0; $i < $this->n; ++$i) {
+ $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$j+1];
+ $this->V[$i][$j+1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$j+1];
+ $this->V[$i][$j] = $t;
+ }
+ }
+ $t = hypo($f, $g);
+ $cs = $f/$t;
+ $sn = $g/$t;
+ $this->s[$j] = $t;
+ $f = $cs * $e[$j] + $sn * $this->s[$j+1];
+ $this->s[$j+1] = -$sn * $e[$j] + $cs * $this->s[$j+1];
+ $g = $sn * $e[$j+1];
+ $e[$j+1] = $cs * $e[$j+1];
+ if ($wantu && ($j < $this->m - 1)) {
+ for ($i = 0; $i < $this->m; ++$i) {
+ $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$j+1];
+ $this->U[$i][$j+1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$j+1];
+ $this->U[$i][$j] = $t;
+ }
+ }
+ }
+ $e[$p-2] = $f;
+ $iter = $iter + 1;
+ break;
+ // Convergence.
+ case 4:
+ // Make the singular values positive.
+ if ($this->s[$k] <= 0.0) {
+ $this->s[$k] = ($this->s[$k] < 0.0 ? -$this->s[$k] : 0.0);
+ if ($wantv) {
+ for ($i = 0; $i <= $pp; ++$i) {
+ $this->V[$i][$k] = -$this->V[$i][$k];
+ }
+ }
+ }
+ // Order the singular values.
+ while ($k < $pp) {
+ if ($this->s[$k] >= $this->s[$k+1]) {
+ break;
+ }
+ $t = $this->s[$k];
+ $this->s[$k] = $this->s[$k+1];
+ $this->s[$k+1] = $t;
+ if ($wantv and ($k < $this->n - 1)) {
+ for ($i = 0; $i < $this->n; ++$i) {
+ $t = $this->V[$i][$k+1];
+ $this->V[$i][$k+1] = $this->V[$i][$k];
+ $this->V[$i][$k] = $t;
+ }
+ }
+ if ($wantu and ($k < $this->m-1)) {
+ for ($i = 0; $i < $this->m; ++$i) {
+ $t = $this->U[$i][$k+1];
+ $this->U[$i][$k+1] = $this->U[$i][$k];
+ $this->U[$i][$k] = $t;
+ }
+ }
+ ++$k;
+ }
+ $iter = 0;
+ --$p;
+ break;
+ } // end switch
+ } // end while
+
+ } // end constructor
+
+
+ /**
+ * Return the left singular vectors
+ *
+ * @access public
+ * @return U
+ */
+ public function getU()
+ {
+ return new Matrix($this->U, $this->m, min($this->m + 1, $this->n));
+ }
+
+
+ /**
+ * Return the right singular vectors
+ *
+ * @access public
+ * @return V
+ */
+ public function getV()
+ {
+ return new Matrix($this->V);
+ }
+
+
+ /**
+ * Return the one-dimensional array of singular values
+ *
+ * @access public
+ * @return diagonal of S.
+ */
+ public function getSingularValues()
+ {
+ return $this->s;
+ }
+
+
+ /**
+ * Return the diagonal matrix of singular values
+ *
+ * @access public
+ * @return S
+ */
+ public function getS()
+ {
+ for ($i = 0; $i < $this->n; ++$i) {
+ for ($j = 0; $j < $this->n; ++$j) {
+ $S[$i][$j] = 0.0;
+ }
+ $S[$i][$i] = $this->s[$i];
+ }
+ return new Matrix($S);
+ }
+
+
+ /**
+ * Two norm
+ *
+ * @access public
+ * @return max(S)
+ */
+ public function norm2()
+ {
+ return $this->s[0];
+ }
+
+
+ /**
+ * Two norm condition number
+ *
+ * @access public
+ * @return max(S)/min(S)
+ */
+ public function cond()
+ {
+ return $this->s[0] / $this->s[min($this->m, $this->n) - 1];
+ }
+
+
+ /**
+ * Effective numerical matrix rank
+ *
+ * @access public
+ * @return Number of nonnegligible singular values.
+ */
+ public function rank()
+ {
+ $eps = pow(2.0, -52.0);
+ $tol = max($this->m, $this->n) * $this->s[0] * $eps;
+ $r = 0;
+ for ($i = 0; $i < count($this->s); ++$i) {
+ if ($this->s[$i] > $tol) {
+ ++$r;
+ }
+ }
+ return $r;
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/JAMA/utils/Error.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/JAMA/utils/Error.php
new file mode 100755
index 000000000..71b8c994a
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/JAMA/utils/Error.php
@@ -0,0 +1,83 @@
+ abs($b)) {
+ $r = $b / $a;
+ $r = abs($a) * sqrt(1 + $r * $r);
+ } elseif ($b != 0) {
+ $r = $a / $b;
+ $r = abs($b) * sqrt(1 + $r * $r);
+ } else {
+ $r = 0.0;
+ }
+ return $r;
+} // function hypo()
+
+
+/**
+ * Mike Bommarito's version.
+ * Compute n-dimensional hyotheneuse.
+ *
+function hypot() {
+ $s = 0;
+ foreach (func_get_args() as $d) {
+ if (is_numeric($d)) {
+ $s += pow($d, 2);
+ } else {
+ throw new PHPExcel_Calculation_Exception(JAMAError(ARGUMENT_TYPE_EXCEPTION));
+ }
+ }
+ return sqrt($s);
+}
+*/
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/OLE.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/OLE.php
new file mode 100755
index 000000000..42a3c529f
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/OLE.php
@@ -0,0 +1,526 @@
+ |
+// | Based on OLE::Storage_Lite by Kawai, Takanori |
+// +----------------------------------------------------------------------+
+//
+// $Id: OLE.php,v 1.13 2007/03/07 14:38:25 schmidt Exp $
+
+
+/**
+* Array for storing OLE instances that are accessed from
+* OLE_ChainedBlockStream::stream_open().
+* @var array
+*/
+$GLOBALS['_OLE_INSTANCES'] = array();
+
+/**
+* OLE package base class.
+*
+* @author Xavier Noguer Warning: The PHPExcel DATEVALUE() function accepts a wider range of date formats than MS Excel's DATEFORMAT() function.
+
+This block contains an italicized word;
+while this block uses an underline.
+
+
+I want to eat
+
+ 100°C is a hot temperature
+
+
+ *
+ * @internal
+ */
+class Normalizer
+{
+ public const FORM_D = \Normalizer::FORM_D;
+ public const FORM_KD = \Normalizer::FORM_KD;
+ public const FORM_C = \Normalizer::FORM_C;
+ public const FORM_KC = \Normalizer::FORM_KC;
+ public const NFD = \Normalizer::NFD;
+ public const NFKD = \Normalizer::NFKD;
+ public const NFC = \Normalizer::NFC;
+ public const NFKC = \Normalizer::NFKC;
+
+ private static $C;
+ private static $D;
+ private static $KD;
+ private static $cC;
+ private static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4];
+ private static $ASCII = "\x20\x65\x69\x61\x73\x6E\x74\x72\x6F\x6C\x75\x64\x5D\x5B\x63\x6D\x70\x27\x0A\x67\x7C\x68\x76\x2E\x66\x62\x2C\x3A\x3D\x2D\x71\x31\x30\x43\x32\x2A\x79\x78\x29\x28\x4C\x39\x41\x53\x2F\x50\x22\x45\x6A\x4D\x49\x6B\x33\x3E\x35\x54\x3C\x44\x34\x7D\x42\x7B\x38\x46\x77\x52\x36\x37\x55\x47\x4E\x3B\x4A\x7A\x56\x23\x48\x4F\x57\x5F\x26\x21\x4B\x3F\x58\x51\x25\x59\x5C\x09\x5A\x2B\x7E\x5E\x24\x40\x60\x7F\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
+
+ public static function isNormalized(string $s, int $form = self::FORM_C)
+ {
+ if (!\in_array($form, [self::NFD, self::NFKD, self::NFC, self::NFKC])) {
+ return false;
+ }
+ if (!isset($s[strspn($s, self::$ASCII)])) {
+ return true;
+ }
+ if (self::NFC == $form && preg_match('//u', $s) && !preg_match('/[^\x00-\x{2FF}]/u', $s)) {
+ return true;
+ }
+
+ return self::normalize($s, $form) === $s;
+ }
+
+ public static function normalize(string $s, int $form = self::FORM_C)
+ {
+ if (!preg_match('//u', $s)) {
+ return false;
+ }
+
+ switch ($form) {
+ case self::NFC: $C = true; $K = false; break;
+ case self::NFD: $C = false; $K = false; break;
+ case self::NFKC: $C = true; $K = true; break;
+ case self::NFKD: $C = false; $K = true; break;
+ default:
+ if (\defined('Normalizer::NONE') && \Normalizer::NONE == $form) {
+ return $s;
+ }
+
+ if (80000 > \PHP_VERSION_ID) {
+ return false;
+ }
+
+ throw new \ValueError('normalizer_normalize(): Argument #2 ($form) must be a a valid normalization form');
+ }
+
+ if ('' === $s) {
+ return '';
+ }
+
+ if ($K && null === self::$KD) {
+ self::$KD = self::getData('compatibilityDecomposition');
+ }
+
+ if (null === self::$D) {
+ self::$D = self::getData('canonicalDecomposition');
+ self::$cC = self::getData('combiningClass');
+ }
+
+ if (null !== $mbEncoding = (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) ? mb_internal_encoding() : null) {
+ mb_internal_encoding('8bit');
+ }
+
+ $r = self::decompose($s, $K);
+
+ if ($C) {
+ if (null === self::$C) {
+ self::$C = self::getData('canonicalComposition');
+ }
+
+ $r = self::recompose($r);
+ }
+ if (null !== $mbEncoding) {
+ mb_internal_encoding($mbEncoding);
+ }
+
+ return $r;
+ }
+
+ private static function recompose($s)
+ {
+ $ASCII = self::$ASCII;
+ $compMap = self::$C;
+ $combClass = self::$cC;
+ $ulenMask = self::$ulenMask;
+
+ $result = $tail = '';
+
+ $i = $s[0] < "\x80" ? 1 : $ulenMask[$s[0] & "\xF0"];
+ $len = \strlen($s);
+
+ $lastUchr = substr($s, 0, $i);
+ $lastUcls = isset($combClass[$lastUchr]) ? 256 : 0;
+
+ while ($i < $len) {
+ if ($s[$i] < "\x80") {
+ // ASCII chars
+
+ if ($tail) {
+ $lastUchr .= $tail;
+ $tail = '';
+ }
+
+ if ($j = strspn($s, $ASCII, $i + 1)) {
+ $lastUchr .= substr($s, $i, $j);
+ $i += $j;
+ }
+
+ $result .= $lastUchr;
+ $lastUchr = $s[$i];
+ $lastUcls = 0;
+ ++$i;
+ continue;
+ }
+
+ $ulen = $ulenMask[$s[$i] & "\xF0"];
+ $uchr = substr($s, $i, $ulen);
+
+ if ($lastUchr < "\xE1\x84\x80" || "\xE1\x84\x92" < $lastUchr
+ || $uchr < "\xE1\x85\xA1" || "\xE1\x85\xB5" < $uchr
+ || $lastUcls) {
+ // Table lookup and combining chars composition
+
+ $ucls = $combClass[$uchr] ?? 0;
+
+ if (isset($compMap[$lastUchr.$uchr]) && (!$lastUcls || $lastUcls < $ucls)) {
+ $lastUchr = $compMap[$lastUchr.$uchr];
+ } elseif ($lastUcls = $ucls) {
+ $tail .= $uchr;
+ } else {
+ if ($tail) {
+ $lastUchr .= $tail;
+ $tail = '';
+ }
+
+ $result .= $lastUchr;
+ $lastUchr = $uchr;
+ }
+ } else {
+ // Hangul chars
+
+ $L = \ord($lastUchr[2]) - 0x80;
+ $V = \ord($uchr[2]) - 0xA1;
+ $T = 0;
+
+ $uchr = substr($s, $i + $ulen, 3);
+
+ if ("\xE1\x86\xA7" <= $uchr && $uchr <= "\xE1\x87\x82") {
+ $T = \ord($uchr[2]) - 0xA7;
+ 0 > $T && $T += 0x40;
+ $ulen += 3;
+ }
+
+ $L = 0xAC00 + ($L * 21 + $V) * 28 + $T;
+ $lastUchr = \chr(0xE0 | $L >> 12).\chr(0x80 | $L >> 6 & 0x3F).\chr(0x80 | $L & 0x3F);
+ }
+
+ $i += $ulen;
+ }
+
+ return $result.$lastUchr.$tail;
+ }
+
+ private static function decompose($s, $c)
+ {
+ $result = '';
+
+ $ASCII = self::$ASCII;
+ $decompMap = self::$D;
+ $combClass = self::$cC;
+ $ulenMask = self::$ulenMask;
+ if ($c) {
+ $compatMap = self::$KD;
+ }
+
+ $c = [];
+ $i = 0;
+ $len = \strlen($s);
+
+ while ($i < $len) {
+ if ($s[$i] < "\x80") {
+ // ASCII chars
+
+ if ($c) {
+ ksort($c);
+ $result .= implode('', $c);
+ $c = [];
+ }
+
+ $j = 1 + strspn($s, $ASCII, $i + 1);
+ $result .= substr($s, $i, $j);
+ $i += $j;
+ continue;
+ }
+
+ $ulen = $ulenMask[$s[$i] & "\xF0"];
+ $uchr = substr($s, $i, $ulen);
+ $i += $ulen;
+
+ if ($uchr < "\xEA\xB0\x80" || "\xED\x9E\xA3" < $uchr) {
+ // Table lookup
+
+ if ($uchr !== $j = $compatMap[$uchr] ?? ($decompMap[$uchr] ?? $uchr)) {
+ $uchr = $j;
+
+ $j = \strlen($uchr);
+ $ulen = $uchr[0] < "\x80" ? 1 : $ulenMask[$uchr[0] & "\xF0"];
+
+ if ($ulen != $j) {
+ // Put trailing chars in $s
+
+ $j -= $ulen;
+ $i -= $j;
+
+ if (0 > $i) {
+ $s = str_repeat(' ', -$i).$s;
+ $len -= $i;
+ $i = 0;
+ }
+
+ while ($j--) {
+ $s[$i + $j] = $uchr[$ulen + $j];
+ }
+
+ $uchr = substr($uchr, 0, $ulen);
+ }
+ }
+ if (isset($combClass[$uchr])) {
+ // Combining chars, for sorting
+
+ if (!isset($c[$combClass[$uchr]])) {
+ $c[$combClass[$uchr]] = '';
+ }
+ $c[$combClass[$uchr]] .= $uchr;
+ continue;
+ }
+ } else {
+ // Hangul chars
+
+ $uchr = unpack('C*', $uchr);
+ $j = (($uchr[1] - 224) << 12) + (($uchr[2] - 128) << 6) + $uchr[3] - 0xAC80;
+
+ $uchr = "\xE1\x84".\chr(0x80 + (int) ($j / 588))
+ ."\xE1\x85".\chr(0xA1 + (int) (($j % 588) / 28));
+
+ if ($j %= 28) {
+ $uchr .= $j < 25
+ ? ("\xE1\x86".\chr(0xA7 + $j))
+ : ("\xE1\x87".\chr(0x67 + $j));
+ }
+ }
+ if ($c) {
+ ksort($c);
+ $result .= implode('', $c);
+ $c = [];
+ }
+
+ $result .= $uchr;
+ }
+
+ if ($c) {
+ ksort($c);
+ $result .= implode('', $c);
+ }
+
+ return $result;
+ }
+
+ private static function getData($file)
+ {
+ if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) {
+ return require $file;
+ }
+
+ return false;
+ }
+}
diff --git a/Server/vendor/symfony/polyfill-intl-normalizer/README.md b/Server/vendor/symfony/polyfill-intl-normalizer/README.md
new file mode 100755
index 000000000..b9b762e85
--- /dev/null
+++ b/Server/vendor/symfony/polyfill-intl-normalizer/README.md
@@ -0,0 +1,14 @@
+Symfony Polyfill / Intl: Normalizer
+===================================
+
+This component provides a fallback implementation for the
+[`Normalizer`](https://php.net/Normalizer) class provided
+by the [Intl](https://php.net/intl) extension.
+
+More information can be found in the
+[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md).
+
+License
+=======
+
+This library is released under the [MIT license](LICENSE).
diff --git a/Server/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php b/Server/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php
new file mode 100755
index 000000000..0fdfc890a
--- /dev/null
+++ b/Server/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php
@@ -0,0 +1,17 @@
+ 'À',
+ 'Á' => 'Á',
+ 'Â' => 'Â',
+ 'Ã' => 'Ã',
+ 'Ä' => 'Ä',
+ 'Å' => 'Å',
+ 'Ç' => 'Ç',
+ 'È' => 'È',
+ 'É' => 'É',
+ 'Ê' => 'Ê',
+ 'Ë' => 'Ë',
+ 'Ì' => 'Ì',
+ 'Í' => 'Í',
+ 'Î' => 'Î',
+ 'Ï' => 'Ï',
+ 'Ñ' => 'Ñ',
+ 'Ò' => 'Ò',
+ 'Ó' => 'Ó',
+ 'Ô' => 'Ô',
+ 'Õ' => 'Õ',
+ 'Ö' => 'Ö',
+ 'Ù' => 'Ù',
+ 'Ú' => 'Ú',
+ 'Û' => 'Û',
+ 'Ü' => 'Ü',
+ 'Ý' => 'Ý',
+ 'à' => 'à',
+ 'á' => 'á',
+ 'â' => 'â',
+ 'ã' => 'ã',
+ 'ä' => 'ä',
+ 'å' => 'å',
+ 'ç' => 'ç',
+ 'è' => 'è',
+ 'é' => 'é',
+ 'ê' => 'ê',
+ 'ë' => 'ë',
+ 'ì' => 'ì',
+ 'í' => 'í',
+ 'î' => 'î',
+ 'ï' => 'ï',
+ 'ñ' => 'ñ',
+ 'ò' => 'ò',
+ 'ó' => 'ó',
+ 'ô' => 'ô',
+ 'õ' => 'õ',
+ 'ö' => 'ö',
+ 'ù' => 'ù',
+ 'ú' => 'ú',
+ 'û' => 'û',
+ 'ü' => 'ü',
+ 'ý' => 'ý',
+ 'ÿ' => 'ÿ',
+ 'Ā' => 'Ā',
+ 'ā' => 'ā',
+ 'Ă' => 'Ă',
+ 'ă' => 'ă',
+ 'Ą' => 'Ą',
+ 'ą' => 'ą',
+ 'Ć' => 'Ć',
+ 'ć' => 'ć',
+ 'Ĉ' => 'Ĉ',
+ 'ĉ' => 'ĉ',
+ 'Ċ' => 'Ċ',
+ 'ċ' => 'ċ',
+ 'Č' => 'Č',
+ 'č' => 'č',
+ 'Ď' => 'Ď',
+ 'ď' => 'ď',
+ 'Ē' => 'Ē',
+ 'ē' => 'ē',
+ 'Ĕ' => 'Ĕ',
+ 'ĕ' => 'ĕ',
+ 'Ė' => 'Ė',
+ 'ė' => 'ė',
+ 'Ę' => 'Ę',
+ 'ę' => 'ę',
+ 'Ě' => 'Ě',
+ 'ě' => 'ě',
+ 'Ĝ' => 'Ĝ',
+ 'ĝ' => 'ĝ',
+ 'Ğ' => 'Ğ',
+ 'ğ' => 'ğ',
+ 'Ġ' => 'Ġ',
+ 'ġ' => 'ġ',
+ 'Ģ' => 'Ģ',
+ 'ģ' => 'ģ',
+ 'Ĥ' => 'Ĥ',
+ 'ĥ' => 'ĥ',
+ 'Ĩ' => 'Ĩ',
+ 'ĩ' => 'ĩ',
+ 'Ī' => 'Ī',
+ 'ī' => 'ī',
+ 'Ĭ' => 'Ĭ',
+ 'ĭ' => 'ĭ',
+ 'Į' => 'Į',
+ 'į' => 'į',
+ 'İ' => 'İ',
+ 'Ĵ' => 'Ĵ',
+ 'ĵ' => 'ĵ',
+ 'Ķ' => 'Ķ',
+ 'ķ' => 'ķ',
+ 'Ĺ' => 'Ĺ',
+ 'ĺ' => 'ĺ',
+ 'Ļ' => 'Ļ',
+ 'ļ' => 'ļ',
+ 'Ľ' => 'Ľ',
+ 'ľ' => 'ľ',
+ 'Ń' => 'Ń',
+ 'ń' => 'ń',
+ 'Ņ' => 'Ņ',
+ 'ņ' => 'ņ',
+ 'Ň' => 'Ň',
+ 'ň' => 'ň',
+ 'Ō' => 'Ō',
+ 'ō' => 'ō',
+ 'Ŏ' => 'Ŏ',
+ 'ŏ' => 'ŏ',
+ 'Ő' => 'Ő',
+ 'ő' => 'ő',
+ 'Ŕ' => 'Ŕ',
+ 'ŕ' => 'ŕ',
+ 'Ŗ' => 'Ŗ',
+ 'ŗ' => 'ŗ',
+ 'Ř' => 'Ř',
+ 'ř' => 'ř',
+ 'Ś' => 'Ś',
+ 'ś' => 'ś',
+ 'Ŝ' => 'Ŝ',
+ 'ŝ' => 'ŝ',
+ 'Ş' => 'Ş',
+ 'ş' => 'ş',
+ 'Š' => 'Š',
+ 'š' => 'š',
+ 'Ţ' => 'Ţ',
+ 'ţ' => 'ţ',
+ 'Ť' => 'Ť',
+ 'ť' => 'ť',
+ 'Ũ' => 'Ũ',
+ 'ũ' => 'ũ',
+ 'Ū' => 'Ū',
+ 'ū' => 'ū',
+ 'Ŭ' => 'Ŭ',
+ 'ŭ' => 'ŭ',
+ 'Ů' => 'Ů',
+ 'ů' => 'ů',
+ 'Ű' => 'Ű',
+ 'ű' => 'ű',
+ 'Ų' => 'Ų',
+ 'ų' => 'ų',
+ 'Ŵ' => 'Ŵ',
+ 'ŵ' => 'ŵ',
+ 'Ŷ' => 'Ŷ',
+ 'ŷ' => 'ŷ',
+ 'Ÿ' => 'Ÿ',
+ 'Ź' => 'Ź',
+ 'ź' => 'ź',
+ 'Ż' => 'Ż',
+ 'ż' => 'ż',
+ 'Ž' => 'Ž',
+ 'ž' => 'ž',
+ 'Ơ' => 'Ơ',
+ 'ơ' => 'ơ',
+ 'Ư' => 'Ư',
+ 'ư' => 'ư',
+ 'Ǎ' => 'Ǎ',
+ 'ǎ' => 'ǎ',
+ 'Ǐ' => 'Ǐ',
+ 'ǐ' => 'ǐ',
+ 'Ǒ' => 'Ǒ',
+ 'ǒ' => 'ǒ',
+ 'Ǔ' => 'Ǔ',
+ 'ǔ' => 'ǔ',
+ 'Ǖ' => 'Ǖ',
+ 'ǖ' => 'ǖ',
+ 'Ǘ' => 'Ǘ',
+ 'ǘ' => 'ǘ',
+ 'Ǚ' => 'Ǚ',
+ 'ǚ' => 'ǚ',
+ 'Ǜ' => 'Ǜ',
+ 'ǜ' => 'ǜ',
+ 'Ǟ' => 'Ǟ',
+ 'ǟ' => 'ǟ',
+ 'Ǡ' => 'Ǡ',
+ 'ǡ' => 'ǡ',
+ 'Ǣ' => 'Ǣ',
+ 'ǣ' => 'ǣ',
+ 'Ǧ' => 'Ǧ',
+ 'ǧ' => 'ǧ',
+ 'Ǩ' => 'Ǩ',
+ 'ǩ' => 'ǩ',
+ 'Ǫ' => 'Ǫ',
+ 'ǫ' => 'ǫ',
+ 'Ǭ' => 'Ǭ',
+ 'ǭ' => 'ǭ',
+ 'Ǯ' => 'Ǯ',
+ 'ǯ' => 'ǯ',
+ 'ǰ' => 'ǰ',
+ 'Ǵ' => 'Ǵ',
+ 'ǵ' => 'ǵ',
+ 'Ǹ' => 'Ǹ',
+ 'ǹ' => 'ǹ',
+ 'Ǻ' => 'Ǻ',
+ 'ǻ' => 'ǻ',
+ 'Ǽ' => 'Ǽ',
+ 'ǽ' => 'ǽ',
+ 'Ǿ' => 'Ǿ',
+ 'ǿ' => 'ǿ',
+ 'Ȁ' => 'Ȁ',
+ 'ȁ' => 'ȁ',
+ 'Ȃ' => 'Ȃ',
+ 'ȃ' => 'ȃ',
+ 'Ȅ' => 'Ȅ',
+ 'ȅ' => 'ȅ',
+ 'Ȇ' => 'Ȇ',
+ 'ȇ' => 'ȇ',
+ 'Ȉ' => 'Ȉ',
+ 'ȉ' => 'ȉ',
+ 'Ȋ' => 'Ȋ',
+ 'ȋ' => 'ȋ',
+ 'Ȍ' => 'Ȍ',
+ 'ȍ' => 'ȍ',
+ 'Ȏ' => 'Ȏ',
+ 'ȏ' => 'ȏ',
+ 'Ȑ' => 'Ȑ',
+ 'ȑ' => 'ȑ',
+ 'Ȓ' => 'Ȓ',
+ 'ȓ' => 'ȓ',
+ 'Ȕ' => 'Ȕ',
+ 'ȕ' => 'ȕ',
+ 'Ȗ' => 'Ȗ',
+ 'ȗ' => 'ȗ',
+ 'Ș' => 'Ș',
+ 'ș' => 'ș',
+ 'Ț' => 'Ț',
+ 'ț' => 'ț',
+ 'Ȟ' => 'Ȟ',
+ 'ȟ' => 'ȟ',
+ 'Ȧ' => 'Ȧ',
+ 'ȧ' => 'ȧ',
+ 'Ȩ' => 'Ȩ',
+ 'ȩ' => 'ȩ',
+ 'Ȫ' => 'Ȫ',
+ 'ȫ' => 'ȫ',
+ 'Ȭ' => 'Ȭ',
+ 'ȭ' => 'ȭ',
+ 'Ȯ' => 'Ȯ',
+ 'ȯ' => 'ȯ',
+ 'Ȱ' => 'Ȱ',
+ 'ȱ' => 'ȱ',
+ 'Ȳ' => 'Ȳ',
+ 'ȳ' => 'ȳ',
+ '΅' => '΅',
+ 'Ά' => 'Ά',
+ 'Έ' => 'Έ',
+ 'Ή' => 'Ή',
+ 'Ί' => 'Ί',
+ 'Ό' => 'Ό',
+ 'Ύ' => 'Ύ',
+ 'Ώ' => 'Ώ',
+ 'ΐ' => 'ΐ',
+ 'Ϊ' => 'Ϊ',
+ 'Ϋ' => 'Ϋ',
+ 'ά' => 'ά',
+ 'έ' => 'έ',
+ 'ή' => 'ή',
+ 'ί' => 'ί',
+ 'ΰ' => 'ΰ',
+ 'ϊ' => 'ϊ',
+ 'ϋ' => 'ϋ',
+ 'ό' => 'ό',
+ 'ύ' => 'ύ',
+ 'ώ' => 'ώ',
+ 'ϓ' => 'ϓ',
+ 'ϔ' => 'ϔ',
+ 'Ѐ' => 'Ѐ',
+ 'Ё' => 'Ё',
+ 'Ѓ' => 'Ѓ',
+ 'Ї' => 'Ї',
+ 'Ќ' => 'Ќ',
+ 'Ѝ' => 'Ѝ',
+ 'Ў' => 'Ў',
+ 'Й' => 'Й',
+ 'й' => 'й',
+ 'ѐ' => 'ѐ',
+ 'ё' => 'ё',
+ 'ѓ' => 'ѓ',
+ 'ї' => 'ї',
+ 'ќ' => 'ќ',
+ 'ѝ' => 'ѝ',
+ 'ў' => 'ў',
+ 'Ѷ' => 'Ѷ',
+ 'ѷ' => 'ѷ',
+ 'Ӂ' => 'Ӂ',
+ 'ӂ' => 'ӂ',
+ 'Ӑ' => 'Ӑ',
+ 'ӑ' => 'ӑ',
+ 'Ӓ' => 'Ӓ',
+ 'ӓ' => 'ӓ',
+ 'Ӗ' => 'Ӗ',
+ 'ӗ' => 'ӗ',
+ 'Ӛ' => 'Ӛ',
+ 'ӛ' => 'ӛ',
+ 'Ӝ' => 'Ӝ',
+ 'ӝ' => 'ӝ',
+ 'Ӟ' => 'Ӟ',
+ 'ӟ' => 'ӟ',
+ 'Ӣ' => 'Ӣ',
+ 'ӣ' => 'ӣ',
+ 'Ӥ' => 'Ӥ',
+ 'ӥ' => 'ӥ',
+ 'Ӧ' => 'Ӧ',
+ 'ӧ' => 'ӧ',
+ 'Ӫ' => 'Ӫ',
+ 'ӫ' => 'ӫ',
+ 'Ӭ' => 'Ӭ',
+ 'ӭ' => 'ӭ',
+ 'Ӯ' => 'Ӯ',
+ 'ӯ' => 'ӯ',
+ 'Ӱ' => 'Ӱ',
+ 'ӱ' => 'ӱ',
+ 'Ӳ' => 'Ӳ',
+ 'ӳ' => 'ӳ',
+ 'Ӵ' => 'Ӵ',
+ 'ӵ' => 'ӵ',
+ 'Ӹ' => 'Ӹ',
+ 'ӹ' => 'ӹ',
+ 'آ' => 'آ',
+ 'أ' => 'أ',
+ 'ؤ' => 'ؤ',
+ 'إ' => 'إ',
+ 'ئ' => 'ئ',
+ 'ۀ' => 'ۀ',
+ 'ۂ' => 'ۂ',
+ 'ۓ' => 'ۓ',
+ 'ऩ' => 'ऩ',
+ 'ऱ' => 'ऱ',
+ 'ऴ' => 'ऴ',
+ 'ো' => 'ো',
+ 'ৌ' => 'ৌ',
+ 'ୈ' => 'ୈ',
+ 'ୋ' => 'ୋ',
+ 'ୌ' => 'ୌ',
+ 'ஔ' => 'ஔ',
+ 'ொ' => 'ொ',
+ 'ோ' => 'ோ',
+ 'ௌ' => 'ௌ',
+ 'ై' => 'ై',
+ 'ೀ' => 'ೀ',
+ 'ೇ' => 'ೇ',
+ 'ೈ' => 'ೈ',
+ 'ೊ' => 'ೊ',
+ 'ೋ' => 'ೋ',
+ 'ൊ' => 'ൊ',
+ 'ോ' => 'ോ',
+ 'ൌ' => 'ൌ',
+ 'ේ' => 'ේ',
+ 'ො' => 'ො',
+ 'ෝ' => 'ෝ',
+ 'ෞ' => 'ෞ',
+ 'ဦ' => 'ဦ',
+ 'ᬆ' => 'ᬆ',
+ 'ᬈ' => 'ᬈ',
+ 'ᬊ' => 'ᬊ',
+ 'ᬌ' => 'ᬌ',
+ 'ᬎ' => 'ᬎ',
+ 'ᬒ' => 'ᬒ',
+ 'ᬻ' => 'ᬻ',
+ 'ᬽ' => 'ᬽ',
+ 'ᭀ' => 'ᭀ',
+ 'ᭁ' => 'ᭁ',
+ 'ᭃ' => 'ᭃ',
+ 'Ḁ' => 'Ḁ',
+ 'ḁ' => 'ḁ',
+ 'Ḃ' => 'Ḃ',
+ 'ḃ' => 'ḃ',
+ 'Ḅ' => 'Ḅ',
+ 'ḅ' => 'ḅ',
+ 'Ḇ' => 'Ḇ',
+ 'ḇ' => 'ḇ',
+ 'Ḉ' => 'Ḉ',
+ 'ḉ' => 'ḉ',
+ 'Ḋ' => 'Ḋ',
+ 'ḋ' => 'ḋ',
+ 'Ḍ' => 'Ḍ',
+ 'ḍ' => 'ḍ',
+ 'Ḏ' => 'Ḏ',
+ 'ḏ' => 'ḏ',
+ 'Ḑ' => 'Ḑ',
+ 'ḑ' => 'ḑ',
+ 'Ḓ' => 'Ḓ',
+ 'ḓ' => 'ḓ',
+ 'Ḕ' => 'Ḕ',
+ 'ḕ' => 'ḕ',
+ 'Ḗ' => 'Ḗ',
+ 'ḗ' => 'ḗ',
+ 'Ḙ' => 'Ḙ',
+ 'ḙ' => 'ḙ',
+ 'Ḛ' => 'Ḛ',
+ 'ḛ' => 'ḛ',
+ 'Ḝ' => 'Ḝ',
+ 'ḝ' => 'ḝ',
+ 'Ḟ' => 'Ḟ',
+ 'ḟ' => 'ḟ',
+ 'Ḡ' => 'Ḡ',
+ 'ḡ' => 'ḡ',
+ 'Ḣ' => 'Ḣ',
+ 'ḣ' => 'ḣ',
+ 'Ḥ' => 'Ḥ',
+ 'ḥ' => 'ḥ',
+ 'Ḧ' => 'Ḧ',
+ 'ḧ' => 'ḧ',
+ 'Ḩ' => 'Ḩ',
+ 'ḩ' => 'ḩ',
+ 'Ḫ' => 'Ḫ',
+ 'ḫ' => 'ḫ',
+ 'Ḭ' => 'Ḭ',
+ 'ḭ' => 'ḭ',
+ 'Ḯ' => 'Ḯ',
+ 'ḯ' => 'ḯ',
+ 'Ḱ' => 'Ḱ',
+ 'ḱ' => 'ḱ',
+ 'Ḳ' => 'Ḳ',
+ 'ḳ' => 'ḳ',
+ 'Ḵ' => 'Ḵ',
+ 'ḵ' => 'ḵ',
+ 'Ḷ' => 'Ḷ',
+ 'ḷ' => 'ḷ',
+ 'Ḹ' => 'Ḹ',
+ 'ḹ' => 'ḹ',
+ 'Ḻ' => 'Ḻ',
+ 'ḻ' => 'ḻ',
+ 'Ḽ' => 'Ḽ',
+ 'ḽ' => 'ḽ',
+ 'Ḿ' => 'Ḿ',
+ 'ḿ' => 'ḿ',
+ 'Ṁ' => 'Ṁ',
+ 'ṁ' => 'ṁ',
+ 'Ṃ' => 'Ṃ',
+ 'ṃ' => 'ṃ',
+ 'Ṅ' => 'Ṅ',
+ 'ṅ' => 'ṅ',
+ 'Ṇ' => 'Ṇ',
+ 'ṇ' => 'ṇ',
+ 'Ṉ' => 'Ṉ',
+ 'ṉ' => 'ṉ',
+ 'Ṋ' => 'Ṋ',
+ 'ṋ' => 'ṋ',
+ 'Ṍ' => 'Ṍ',
+ 'ṍ' => 'ṍ',
+ 'Ṏ' => 'Ṏ',
+ 'ṏ' => 'ṏ',
+ 'Ṑ' => 'Ṑ',
+ 'ṑ' => 'ṑ',
+ 'Ṓ' => 'Ṓ',
+ 'ṓ' => 'ṓ',
+ 'Ṕ' => 'Ṕ',
+ 'ṕ' => 'ṕ',
+ 'Ṗ' => 'Ṗ',
+ 'ṗ' => 'ṗ',
+ 'Ṙ' => 'Ṙ',
+ 'ṙ' => 'ṙ',
+ 'Ṛ' => 'Ṛ',
+ 'ṛ' => 'ṛ',
+ 'Ṝ' => 'Ṝ',
+ 'ṝ' => 'ṝ',
+ 'Ṟ' => 'Ṟ',
+ 'ṟ' => 'ṟ',
+ 'Ṡ' => 'Ṡ',
+ 'ṡ' => 'ṡ',
+ 'Ṣ' => 'Ṣ',
+ 'ṣ' => 'ṣ',
+ 'Ṥ' => 'Ṥ',
+ 'ṥ' => 'ṥ',
+ 'Ṧ' => 'Ṧ',
+ 'ṧ' => 'ṧ',
+ 'Ṩ' => 'Ṩ',
+ 'ṩ' => 'ṩ',
+ 'Ṫ' => 'Ṫ',
+ 'ṫ' => 'ṫ',
+ 'Ṭ' => 'Ṭ',
+ 'ṭ' => 'ṭ',
+ 'Ṯ' => 'Ṯ',
+ 'ṯ' => 'ṯ',
+ 'Ṱ' => 'Ṱ',
+ 'ṱ' => 'ṱ',
+ 'Ṳ' => 'Ṳ',
+ 'ṳ' => 'ṳ',
+ 'Ṵ' => 'Ṵ',
+ 'ṵ' => 'ṵ',
+ 'Ṷ' => 'Ṷ',
+ 'ṷ' => 'ṷ',
+ 'Ṹ' => 'Ṹ',
+ 'ṹ' => 'ṹ',
+ 'Ṻ' => 'Ṻ',
+ 'ṻ' => 'ṻ',
+ 'Ṽ' => 'Ṽ',
+ 'ṽ' => 'ṽ',
+ 'Ṿ' => 'Ṿ',
+ 'ṿ' => 'ṿ',
+ 'Ẁ' => 'Ẁ',
+ 'ẁ' => 'ẁ',
+ 'Ẃ' => 'Ẃ',
+ 'ẃ' => 'ẃ',
+ 'Ẅ' => 'Ẅ',
+ 'ẅ' => 'ẅ',
+ 'Ẇ' => 'Ẇ',
+ 'ẇ' => 'ẇ',
+ 'Ẉ' => 'Ẉ',
+ 'ẉ' => 'ẉ',
+ 'Ẋ' => 'Ẋ',
+ 'ẋ' => 'ẋ',
+ 'Ẍ' => 'Ẍ',
+ 'ẍ' => 'ẍ',
+ 'Ẏ' => 'Ẏ',
+ 'ẏ' => 'ẏ',
+ 'Ẑ' => 'Ẑ',
+ 'ẑ' => 'ẑ',
+ 'Ẓ' => 'Ẓ',
+ 'ẓ' => 'ẓ',
+ 'Ẕ' => 'Ẕ',
+ 'ẕ' => 'ẕ',
+ 'ẖ' => 'ẖ',
+ 'ẗ' => 'ẗ',
+ 'ẘ' => 'ẘ',
+ 'ẙ' => 'ẙ',
+ 'ẛ' => 'ẛ',
+ 'Ạ' => 'Ạ',
+ 'ạ' => 'ạ',
+ 'Ả' => 'Ả',
+ 'ả' => 'ả',
+ 'Ấ' => 'Ấ',
+ 'ấ' => 'ấ',
+ 'Ầ' => 'Ầ',
+ 'ầ' => 'ầ',
+ 'Ẩ' => 'Ẩ',
+ 'ẩ' => 'ẩ',
+ 'Ẫ' => 'Ẫ',
+ 'ẫ' => 'ẫ',
+ 'Ậ' => 'Ậ',
+ 'ậ' => 'ậ',
+ 'Ắ' => 'Ắ',
+ 'ắ' => 'ắ',
+ 'Ằ' => 'Ằ',
+ 'ằ' => 'ằ',
+ 'Ẳ' => 'Ẳ',
+ 'ẳ' => 'ẳ',
+ 'Ẵ' => 'Ẵ',
+ 'ẵ' => 'ẵ',
+ 'Ặ' => 'Ặ',
+ 'ặ' => 'ặ',
+ 'Ẹ' => 'Ẹ',
+ 'ẹ' => 'ẹ',
+ 'Ẻ' => 'Ẻ',
+ 'ẻ' => 'ẻ',
+ 'Ẽ' => 'Ẽ',
+ 'ẽ' => 'ẽ',
+ 'Ế' => 'Ế',
+ 'ế' => 'ế',
+ 'Ề' => 'Ề',
+ 'ề' => 'ề',
+ 'Ể' => 'Ể',
+ 'ể' => 'ể',
+ 'Ễ' => 'Ễ',
+ 'ễ' => 'ễ',
+ 'Ệ' => 'Ệ',
+ 'ệ' => 'ệ',
+ 'Ỉ' => 'Ỉ',
+ 'ỉ' => 'ỉ',
+ 'Ị' => 'Ị',
+ 'ị' => 'ị',
+ 'Ọ' => 'Ọ',
+ 'ọ' => 'ọ',
+ 'Ỏ' => 'Ỏ',
+ 'ỏ' => 'ỏ',
+ 'Ố' => 'Ố',
+ 'ố' => 'ố',
+ 'Ồ' => 'Ồ',
+ 'ồ' => 'ồ',
+ 'Ổ' => 'Ổ',
+ 'ổ' => 'ổ',
+ 'Ỗ' => 'Ỗ',
+ 'ỗ' => 'ỗ',
+ 'Ộ' => 'Ộ',
+ 'ộ' => 'ộ',
+ 'Ớ' => 'Ớ',
+ 'ớ' => 'ớ',
+ 'Ờ' => 'Ờ',
+ 'ờ' => 'ờ',
+ 'Ở' => 'Ở',
+ 'ở' => 'ở',
+ 'Ỡ' => 'Ỡ',
+ 'ỡ' => 'ỡ',
+ 'Ợ' => 'Ợ',
+ 'ợ' => 'ợ',
+ 'Ụ' => 'Ụ',
+ 'ụ' => 'ụ',
+ 'Ủ' => 'Ủ',
+ 'ủ' => 'ủ',
+ 'Ứ' => 'Ứ',
+ 'ứ' => 'ứ',
+ 'Ừ' => 'Ừ',
+ 'ừ' => 'ừ',
+ 'Ử' => 'Ử',
+ 'ử' => 'ử',
+ 'Ữ' => 'Ữ',
+ 'ữ' => 'ữ',
+ 'Ự' => 'Ự',
+ 'ự' => 'ự',
+ 'Ỳ' => 'Ỳ',
+ 'ỳ' => 'ỳ',
+ 'Ỵ' => 'Ỵ',
+ 'ỵ' => 'ỵ',
+ 'Ỷ' => 'Ỷ',
+ 'ỷ' => 'ỷ',
+ 'Ỹ' => 'Ỹ',
+ 'ỹ' => 'ỹ',
+ 'ἀ' => 'ἀ',
+ 'ἁ' => 'ἁ',
+ 'ἂ' => 'ἂ',
+ 'ἃ' => 'ἃ',
+ 'ἄ' => 'ἄ',
+ 'ἅ' => 'ἅ',
+ 'ἆ' => 'ἆ',
+ 'ἇ' => 'ἇ',
+ 'Ἀ' => 'Ἀ',
+ 'Ἁ' => 'Ἁ',
+ 'Ἂ' => 'Ἂ',
+ 'Ἃ' => 'Ἃ',
+ 'Ἄ' => 'Ἄ',
+ 'Ἅ' => 'Ἅ',
+ 'Ἆ' => 'Ἆ',
+ 'Ἇ' => 'Ἇ',
+ 'ἐ' => 'ἐ',
+ 'ἑ' => 'ἑ',
+ 'ἒ' => 'ἒ',
+ 'ἓ' => 'ἓ',
+ 'ἔ' => 'ἔ',
+ 'ἕ' => 'ἕ',
+ 'Ἐ' => 'Ἐ',
+ 'Ἑ' => 'Ἑ',
+ 'Ἒ' => 'Ἒ',
+ 'Ἓ' => 'Ἓ',
+ 'Ἔ' => 'Ἔ',
+ 'Ἕ' => 'Ἕ',
+ 'ἠ' => 'ἠ',
+ 'ἡ' => 'ἡ',
+ 'ἢ' => 'ἢ',
+ 'ἣ' => 'ἣ',
+ 'ἤ' => 'ἤ',
+ 'ἥ' => 'ἥ',
+ 'ἦ' => 'ἦ',
+ 'ἧ' => 'ἧ',
+ 'Ἠ' => 'Ἠ',
+ 'Ἡ' => 'Ἡ',
+ 'Ἢ' => 'Ἢ',
+ 'Ἣ' => 'Ἣ',
+ 'Ἤ' => 'Ἤ',
+ 'Ἥ' => 'Ἥ',
+ 'Ἦ' => 'Ἦ',
+ 'Ἧ' => 'Ἧ',
+ 'ἰ' => 'ἰ',
+ 'ἱ' => 'ἱ',
+ 'ἲ' => 'ἲ',
+ 'ἳ' => 'ἳ',
+ 'ἴ' => 'ἴ',
+ 'ἵ' => 'ἵ',
+ 'ἶ' => 'ἶ',
+ 'ἷ' => 'ἷ',
+ 'Ἰ' => 'Ἰ',
+ 'Ἱ' => 'Ἱ',
+ 'Ἲ' => 'Ἲ',
+ 'Ἳ' => 'Ἳ',
+ 'Ἴ' => 'Ἴ',
+ 'Ἵ' => 'Ἵ',
+ 'Ἶ' => 'Ἶ',
+ 'Ἷ' => 'Ἷ',
+ 'ὀ' => 'ὀ',
+ 'ὁ' => 'ὁ',
+ 'ὂ' => 'ὂ',
+ 'ὃ' => 'ὃ',
+ 'ὄ' => 'ὄ',
+ 'ὅ' => 'ὅ',
+ 'Ὀ' => 'Ὀ',
+ 'Ὁ' => 'Ὁ',
+ 'Ὂ' => 'Ὂ',
+ 'Ὃ' => 'Ὃ',
+ 'Ὄ' => 'Ὄ',
+ 'Ὅ' => 'Ὅ',
+ 'ὐ' => 'ὐ',
+ 'ὑ' => 'ὑ',
+ 'ὒ' => 'ὒ',
+ 'ὓ' => 'ὓ',
+ 'ὔ' => 'ὔ',
+ 'ὕ' => 'ὕ',
+ 'ὖ' => 'ὖ',
+ 'ὗ' => 'ὗ',
+ 'Ὑ' => 'Ὑ',
+ 'Ὓ' => 'Ὓ',
+ 'Ὕ' => 'Ὕ',
+ 'Ὗ' => 'Ὗ',
+ 'ὠ' => 'ὠ',
+ 'ὡ' => 'ὡ',
+ 'ὢ' => 'ὢ',
+ 'ὣ' => 'ὣ',
+ 'ὤ' => 'ὤ',
+ 'ὥ' => 'ὥ',
+ 'ὦ' => 'ὦ',
+ 'ὧ' => 'ὧ',
+ 'Ὠ' => 'Ὠ',
+ 'Ὡ' => 'Ὡ',
+ 'Ὢ' => 'Ὢ',
+ 'Ὣ' => 'Ὣ',
+ 'Ὤ' => 'Ὤ',
+ 'Ὥ' => 'Ὥ',
+ 'Ὦ' => 'Ὦ',
+ 'Ὧ' => 'Ὧ',
+ 'ὰ' => 'ὰ',
+ 'ὲ' => 'ὲ',
+ 'ὴ' => 'ὴ',
+ 'ὶ' => 'ὶ',
+ 'ὸ' => 'ὸ',
+ 'ὺ' => 'ὺ',
+ 'ὼ' => 'ὼ',
+ 'ᾀ' => 'ᾀ',
+ 'ᾁ' => 'ᾁ',
+ 'ᾂ' => 'ᾂ',
+ 'ᾃ' => 'ᾃ',
+ 'ᾄ' => 'ᾄ',
+ 'ᾅ' => 'ᾅ',
+ 'ᾆ' => 'ᾆ',
+ 'ᾇ' => 'ᾇ',
+ 'ᾈ' => 'ᾈ',
+ 'ᾉ' => 'ᾉ',
+ 'ᾊ' => 'ᾊ',
+ 'ᾋ' => 'ᾋ',
+ 'ᾌ' => 'ᾌ',
+ 'ᾍ' => 'ᾍ',
+ 'ᾎ' => 'ᾎ',
+ 'ᾏ' => 'ᾏ',
+ 'ᾐ' => 'ᾐ',
+ 'ᾑ' => 'ᾑ',
+ 'ᾒ' => 'ᾒ',
+ 'ᾓ' => 'ᾓ',
+ 'ᾔ' => 'ᾔ',
+ 'ᾕ' => 'ᾕ',
+ 'ᾖ' => 'ᾖ',
+ 'ᾗ' => 'ᾗ',
+ 'ᾘ' => 'ᾘ',
+ 'ᾙ' => 'ᾙ',
+ 'ᾚ' => 'ᾚ',
+ 'ᾛ' => 'ᾛ',
+ 'ᾜ' => 'ᾜ',
+ 'ᾝ' => 'ᾝ',
+ 'ᾞ' => 'ᾞ',
+ 'ᾟ' => 'ᾟ',
+ 'ᾠ' => 'ᾠ',
+ 'ᾡ' => 'ᾡ',
+ 'ᾢ' => 'ᾢ',
+ 'ᾣ' => 'ᾣ',
+ 'ᾤ' => 'ᾤ',
+ 'ᾥ' => 'ᾥ',
+ 'ᾦ' => 'ᾦ',
+ 'ᾧ' => 'ᾧ',
+ 'ᾨ' => 'ᾨ',
+ 'ᾩ' => 'ᾩ',
+ 'ᾪ' => 'ᾪ',
+ 'ᾫ' => 'ᾫ',
+ 'ᾬ' => 'ᾬ',
+ 'ᾭ' => 'ᾭ',
+ 'ᾮ' => 'ᾮ',
+ 'ᾯ' => 'ᾯ',
+ 'ᾰ' => 'ᾰ',
+ 'ᾱ' => 'ᾱ',
+ 'ᾲ' => 'ᾲ',
+ 'ᾳ' => 'ᾳ',
+ 'ᾴ' => 'ᾴ',
+ 'ᾶ' => 'ᾶ',
+ 'ᾷ' => 'ᾷ',
+ 'Ᾰ' => 'Ᾰ',
+ 'Ᾱ' => 'Ᾱ',
+ 'Ὰ' => 'Ὰ',
+ 'ᾼ' => 'ᾼ',
+ '῁' => '῁',
+ 'ῂ' => 'ῂ',
+ 'ῃ' => 'ῃ',
+ 'ῄ' => 'ῄ',
+ 'ῆ' => 'ῆ',
+ 'ῇ' => 'ῇ',
+ 'Ὲ' => 'Ὲ',
+ 'Ὴ' => 'Ὴ',
+ 'ῌ' => 'ῌ',
+ '῍' => '῍',
+ '῎' => '῎',
+ '῏' => '῏',
+ 'ῐ' => 'ῐ',
+ 'ῑ' => 'ῑ',
+ 'ῒ' => 'ῒ',
+ 'ῖ' => 'ῖ',
+ 'ῗ' => 'ῗ',
+ 'Ῐ' => 'Ῐ',
+ 'Ῑ' => 'Ῑ',
+ 'Ὶ' => 'Ὶ',
+ '῝' => '῝',
+ '῞' => '῞',
+ '῟' => '῟',
+ 'ῠ' => 'ῠ',
+ 'ῡ' => 'ῡ',
+ 'ῢ' => 'ῢ',
+ 'ῤ' => 'ῤ',
+ 'ῥ' => 'ῥ',
+ 'ῦ' => 'ῦ',
+ 'ῧ' => 'ῧ',
+ 'Ῠ' => 'Ῠ',
+ 'Ῡ' => 'Ῡ',
+ 'Ὺ' => 'Ὺ',
+ 'Ῥ' => 'Ῥ',
+ '῭' => '῭',
+ 'ῲ' => 'ῲ',
+ 'ῳ' => 'ῳ',
+ 'ῴ' => 'ῴ',
+ 'ῶ' => 'ῶ',
+ 'ῷ' => 'ῷ',
+ 'Ὸ' => 'Ὸ',
+ 'Ὼ' => 'Ὼ',
+ 'ῼ' => 'ῼ',
+ '↚' => '↚',
+ '↛' => '↛',
+ '↮' => '↮',
+ '⇍' => '⇍',
+ '⇎' => '⇎',
+ '⇏' => '⇏',
+ '∄' => '∄',
+ '∉' => '∉',
+ '∌' => '∌',
+ '∤' => '∤',
+ '∦' => '∦',
+ '≁' => '≁',
+ '≄' => '≄',
+ '≇' => '≇',
+ '≉' => '≉',
+ '≠' => '≠',
+ '≢' => '≢',
+ '≭' => '≭',
+ '≮' => '≮',
+ '≯' => '≯',
+ '≰' => '≰',
+ '≱' => '≱',
+ '≴' => '≴',
+ '≵' => '≵',
+ '≸' => '≸',
+ '≹' => '≹',
+ '⊀' => '⊀',
+ '⊁' => '⊁',
+ '⊄' => '⊄',
+ '⊅' => '⊅',
+ '⊈' => '⊈',
+ '⊉' => '⊉',
+ '⊬' => '⊬',
+ '⊭' => '⊭',
+ '⊮' => '⊮',
+ '⊯' => '⊯',
+ '⋠' => '⋠',
+ '⋡' => '⋡',
+ '⋢' => '⋢',
+ '⋣' => '⋣',
+ '⋪' => '⋪',
+ '⋫' => '⋫',
+ '⋬' => '⋬',
+ '⋭' => '⋭',
+ 'が' => 'が',
+ 'ぎ' => 'ぎ',
+ 'ぐ' => 'ぐ',
+ 'げ' => 'げ',
+ 'ご' => 'ご',
+ 'ざ' => 'ざ',
+ 'じ' => 'じ',
+ 'ず' => 'ず',
+ 'ぜ' => 'ぜ',
+ 'ぞ' => 'ぞ',
+ 'だ' => 'だ',
+ 'ぢ' => 'ぢ',
+ 'づ' => 'づ',
+ 'で' => 'で',
+ 'ど' => 'ど',
+ 'ば' => 'ば',
+ 'ぱ' => 'ぱ',
+ 'び' => 'び',
+ 'ぴ' => 'ぴ',
+ 'ぶ' => 'ぶ',
+ 'ぷ' => 'ぷ',
+ 'べ' => 'べ',
+ 'ぺ' => 'ぺ',
+ 'ぼ' => 'ぼ',
+ 'ぽ' => 'ぽ',
+ 'ゔ' => 'ゔ',
+ 'ゞ' => 'ゞ',
+ 'ガ' => 'ガ',
+ 'ギ' => 'ギ',
+ 'グ' => 'グ',
+ 'ゲ' => 'ゲ',
+ 'ゴ' => 'ゴ',
+ 'ザ' => 'ザ',
+ 'ジ' => 'ジ',
+ 'ズ' => 'ズ',
+ 'ゼ' => 'ゼ',
+ 'ゾ' => 'ゾ',
+ 'ダ' => 'ダ',
+ 'ヂ' => 'ヂ',
+ 'ヅ' => 'ヅ',
+ 'デ' => 'デ',
+ 'ド' => 'ド',
+ 'バ' => 'バ',
+ 'パ' => 'パ',
+ 'ビ' => 'ビ',
+ 'ピ' => 'ピ',
+ 'ブ' => 'ブ',
+ 'プ' => 'プ',
+ 'ベ' => 'ベ',
+ 'ペ' => 'ペ',
+ 'ボ' => 'ボ',
+ 'ポ' => 'ポ',
+ 'ヴ' => 'ヴ',
+ 'ヷ' => 'ヷ',
+ 'ヸ' => 'ヸ',
+ 'ヹ' => 'ヹ',
+ 'ヺ' => 'ヺ',
+ 'ヾ' => 'ヾ',
+ '𑂚' => '𑂚',
+ '𑂜' => '𑂜',
+ '𑂫' => '𑂫',
+ '𑄮' => '𑄮',
+ '𑄯' => '𑄯',
+ '𑍋' => '𑍋',
+ '𑍌' => '𑍌',
+ '𑒻' => '𑒻',
+ '𑒼' => '𑒼',
+ '𑒾' => '𑒾',
+ '𑖺' => '𑖺',
+ '𑖻' => '𑖻',
+ '𑤸' => '𑤸',
+);
diff --git a/Server/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php b/Server/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php
new file mode 100755
index 000000000..5a3e8e096
--- /dev/null
+++ b/Server/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php
@@ -0,0 +1,2065 @@
+ 'À',
+ 'Á' => 'Á',
+ 'Â' => 'Â',
+ 'Ã' => 'Ã',
+ 'Ä' => 'Ä',
+ 'Å' => 'Å',
+ 'Ç' => 'Ç',
+ 'È' => 'È',
+ 'É' => 'É',
+ 'Ê' => 'Ê',
+ 'Ë' => 'Ë',
+ 'Ì' => 'Ì',
+ 'Í' => 'Í',
+ 'Î' => 'Î',
+ 'Ï' => 'Ï',
+ 'Ñ' => 'Ñ',
+ 'Ò' => 'Ò',
+ 'Ó' => 'Ó',
+ 'Ô' => 'Ô',
+ 'Õ' => 'Õ',
+ 'Ö' => 'Ö',
+ 'Ù' => 'Ù',
+ 'Ú' => 'Ú',
+ 'Û' => 'Û',
+ 'Ü' => 'Ü',
+ 'Ý' => 'Ý',
+ 'à' => 'à',
+ 'á' => 'á',
+ 'â' => 'â',
+ 'ã' => 'ã',
+ 'ä' => 'ä',
+ 'å' => 'å',
+ 'ç' => 'ç',
+ 'è' => 'è',
+ 'é' => 'é',
+ 'ê' => 'ê',
+ 'ë' => 'ë',
+ 'ì' => 'ì',
+ 'í' => 'í',
+ 'î' => 'î',
+ 'ï' => 'ï',
+ 'ñ' => 'ñ',
+ 'ò' => 'ò',
+ 'ó' => 'ó',
+ 'ô' => 'ô',
+ 'õ' => 'õ',
+ 'ö' => 'ö',
+ 'ù' => 'ù',
+ 'ú' => 'ú',
+ 'û' => 'û',
+ 'ü' => 'ü',
+ 'ý' => 'ý',
+ 'ÿ' => 'ÿ',
+ 'Ā' => 'Ā',
+ 'ā' => 'ā',
+ 'Ă' => 'Ă',
+ 'ă' => 'ă',
+ 'Ą' => 'Ą',
+ 'ą' => 'ą',
+ 'Ć' => 'Ć',
+ 'ć' => 'ć',
+ 'Ĉ' => 'Ĉ',
+ 'ĉ' => 'ĉ',
+ 'Ċ' => 'Ċ',
+ 'ċ' => 'ċ',
+ 'Č' => 'Č',
+ 'č' => 'č',
+ 'Ď' => 'Ď',
+ 'ď' => 'ď',
+ 'Ē' => 'Ē',
+ 'ē' => 'ē',
+ 'Ĕ' => 'Ĕ',
+ 'ĕ' => 'ĕ',
+ 'Ė' => 'Ė',
+ 'ė' => 'ė',
+ 'Ę' => 'Ę',
+ 'ę' => 'ę',
+ 'Ě' => 'Ě',
+ 'ě' => 'ě',
+ 'Ĝ' => 'Ĝ',
+ 'ĝ' => 'ĝ',
+ 'Ğ' => 'Ğ',
+ 'ğ' => 'ğ',
+ 'Ġ' => 'Ġ',
+ 'ġ' => 'ġ',
+ 'Ģ' => 'Ģ',
+ 'ģ' => 'ģ',
+ 'Ĥ' => 'Ĥ',
+ 'ĥ' => 'ĥ',
+ 'Ĩ' => 'Ĩ',
+ 'ĩ' => 'ĩ',
+ 'Ī' => 'Ī',
+ 'ī' => 'ī',
+ 'Ĭ' => 'Ĭ',
+ 'ĭ' => 'ĭ',
+ 'Į' => 'Į',
+ 'į' => 'į',
+ 'İ' => 'İ',
+ 'Ĵ' => 'Ĵ',
+ 'ĵ' => 'ĵ',
+ 'Ķ' => 'Ķ',
+ 'ķ' => 'ķ',
+ 'Ĺ' => 'Ĺ',
+ 'ĺ' => 'ĺ',
+ 'Ļ' => 'Ļ',
+ 'ļ' => 'ļ',
+ 'Ľ' => 'Ľ',
+ 'ľ' => 'ľ',
+ 'Ń' => 'Ń',
+ 'ń' => 'ń',
+ 'Ņ' => 'Ņ',
+ 'ņ' => 'ņ',
+ 'Ň' => 'Ň',
+ 'ň' => 'ň',
+ 'Ō' => 'Ō',
+ 'ō' => 'ō',
+ 'Ŏ' => 'Ŏ',
+ 'ŏ' => 'ŏ',
+ 'Ő' => 'Ő',
+ 'ő' => 'ő',
+ 'Ŕ' => 'Ŕ',
+ 'ŕ' => 'ŕ',
+ 'Ŗ' => 'Ŗ',
+ 'ŗ' => 'ŗ',
+ 'Ř' => 'Ř',
+ 'ř' => 'ř',
+ 'Ś' => 'Ś',
+ 'ś' => 'ś',
+ 'Ŝ' => 'Ŝ',
+ 'ŝ' => 'ŝ',
+ 'Ş' => 'Ş',
+ 'ş' => 'ş',
+ 'Š' => 'Š',
+ 'š' => 'š',
+ 'Ţ' => 'Ţ',
+ 'ţ' => 'ţ',
+ 'Ť' => 'Ť',
+ 'ť' => 'ť',
+ 'Ũ' => 'Ũ',
+ 'ũ' => 'ũ',
+ 'Ū' => 'Ū',
+ 'ū' => 'ū',
+ 'Ŭ' => 'Ŭ',
+ 'ŭ' => 'ŭ',
+ 'Ů' => 'Ů',
+ 'ů' => 'ů',
+ 'Ű' => 'Ű',
+ 'ű' => 'ű',
+ 'Ų' => 'Ų',
+ 'ų' => 'ų',
+ 'Ŵ' => 'Ŵ',
+ 'ŵ' => 'ŵ',
+ 'Ŷ' => 'Ŷ',
+ 'ŷ' => 'ŷ',
+ 'Ÿ' => 'Ÿ',
+ 'Ź' => 'Ź',
+ 'ź' => 'ź',
+ 'Ż' => 'Ż',
+ 'ż' => 'ż',
+ 'Ž' => 'Ž',
+ 'ž' => 'ž',
+ 'Ơ' => 'Ơ',
+ 'ơ' => 'ơ',
+ 'Ư' => 'Ư',
+ 'ư' => 'ư',
+ 'Ǎ' => 'Ǎ',
+ 'ǎ' => 'ǎ',
+ 'Ǐ' => 'Ǐ',
+ 'ǐ' => 'ǐ',
+ 'Ǒ' => 'Ǒ',
+ 'ǒ' => 'ǒ',
+ 'Ǔ' => 'Ǔ',
+ 'ǔ' => 'ǔ',
+ 'Ǖ' => 'Ǖ',
+ 'ǖ' => 'ǖ',
+ 'Ǘ' => 'Ǘ',
+ 'ǘ' => 'ǘ',
+ 'Ǚ' => 'Ǚ',
+ 'ǚ' => 'ǚ',
+ 'Ǜ' => 'Ǜ',
+ 'ǜ' => 'ǜ',
+ 'Ǟ' => 'Ǟ',
+ 'ǟ' => 'ǟ',
+ 'Ǡ' => 'Ǡ',
+ 'ǡ' => 'ǡ',
+ 'Ǣ' => 'Ǣ',
+ 'ǣ' => 'ǣ',
+ 'Ǧ' => 'Ǧ',
+ 'ǧ' => 'ǧ',
+ 'Ǩ' => 'Ǩ',
+ 'ǩ' => 'ǩ',
+ 'Ǫ' => 'Ǫ',
+ 'ǫ' => 'ǫ',
+ 'Ǭ' => 'Ǭ',
+ 'ǭ' => 'ǭ',
+ 'Ǯ' => 'Ǯ',
+ 'ǯ' => 'ǯ',
+ 'ǰ' => 'ǰ',
+ 'Ǵ' => 'Ǵ',
+ 'ǵ' => 'ǵ',
+ 'Ǹ' => 'Ǹ',
+ 'ǹ' => 'ǹ',
+ 'Ǻ' => 'Ǻ',
+ 'ǻ' => 'ǻ',
+ 'Ǽ' => 'Ǽ',
+ 'ǽ' => 'ǽ',
+ 'Ǿ' => 'Ǿ',
+ 'ǿ' => 'ǿ',
+ 'Ȁ' => 'Ȁ',
+ 'ȁ' => 'ȁ',
+ 'Ȃ' => 'Ȃ',
+ 'ȃ' => 'ȃ',
+ 'Ȅ' => 'Ȅ',
+ 'ȅ' => 'ȅ',
+ 'Ȇ' => 'Ȇ',
+ 'ȇ' => 'ȇ',
+ 'Ȉ' => 'Ȉ',
+ 'ȉ' => 'ȉ',
+ 'Ȋ' => 'Ȋ',
+ 'ȋ' => 'ȋ',
+ 'Ȍ' => 'Ȍ',
+ 'ȍ' => 'ȍ',
+ 'Ȏ' => 'Ȏ',
+ 'ȏ' => 'ȏ',
+ 'Ȑ' => 'Ȑ',
+ 'ȑ' => 'ȑ',
+ 'Ȓ' => 'Ȓ',
+ 'ȓ' => 'ȓ',
+ 'Ȕ' => 'Ȕ',
+ 'ȕ' => 'ȕ',
+ 'Ȗ' => 'Ȗ',
+ 'ȗ' => 'ȗ',
+ 'Ș' => 'Ș',
+ 'ș' => 'ș',
+ 'Ț' => 'Ț',
+ 'ț' => 'ț',
+ 'Ȟ' => 'Ȟ',
+ 'ȟ' => 'ȟ',
+ 'Ȧ' => 'Ȧ',
+ 'ȧ' => 'ȧ',
+ 'Ȩ' => 'Ȩ',
+ 'ȩ' => 'ȩ',
+ 'Ȫ' => 'Ȫ',
+ 'ȫ' => 'ȫ',
+ 'Ȭ' => 'Ȭ',
+ 'ȭ' => 'ȭ',
+ 'Ȯ' => 'Ȯ',
+ 'ȯ' => 'ȯ',
+ 'Ȱ' => 'Ȱ',
+ 'ȱ' => 'ȱ',
+ 'Ȳ' => 'Ȳ',
+ 'ȳ' => 'ȳ',
+ '̀' => '̀',
+ '́' => '́',
+ '̓' => '̓',
+ '̈́' => '̈́',
+ 'ʹ' => 'ʹ',
+ ';' => ';',
+ '΅' => '΅',
+ 'Ά' => 'Ά',
+ '·' => '·',
+ 'Έ' => 'Έ',
+ 'Ή' => 'Ή',
+ 'Ί' => 'Ί',
+ 'Ό' => 'Ό',
+ 'Ύ' => 'Ύ',
+ 'Ώ' => 'Ώ',
+ 'ΐ' => 'ΐ',
+ 'Ϊ' => 'Ϊ',
+ 'Ϋ' => 'Ϋ',
+ 'ά' => 'ά',
+ 'έ' => 'έ',
+ 'ή' => 'ή',
+ 'ί' => 'ί',
+ 'ΰ' => 'ΰ',
+ 'ϊ' => 'ϊ',
+ 'ϋ' => 'ϋ',
+ 'ό' => 'ό',
+ 'ύ' => 'ύ',
+ 'ώ' => 'ώ',
+ 'ϓ' => 'ϓ',
+ 'ϔ' => 'ϔ',
+ 'Ѐ' => 'Ѐ',
+ 'Ё' => 'Ё',
+ 'Ѓ' => 'Ѓ',
+ 'Ї' => 'Ї',
+ 'Ќ' => 'Ќ',
+ 'Ѝ' => 'Ѝ',
+ 'Ў' => 'Ў',
+ 'Й' => 'Й',
+ 'й' => 'й',
+ 'ѐ' => 'ѐ',
+ 'ё' => 'ё',
+ 'ѓ' => 'ѓ',
+ 'ї' => 'ї',
+ 'ќ' => 'ќ',
+ 'ѝ' => 'ѝ',
+ 'ў' => 'ў',
+ 'Ѷ' => 'Ѷ',
+ 'ѷ' => 'ѷ',
+ 'Ӂ' => 'Ӂ',
+ 'ӂ' => 'ӂ',
+ 'Ӑ' => 'Ӑ',
+ 'ӑ' => 'ӑ',
+ 'Ӓ' => 'Ӓ',
+ 'ӓ' => 'ӓ',
+ 'Ӗ' => 'Ӗ',
+ 'ӗ' => 'ӗ',
+ 'Ӛ' => 'Ӛ',
+ 'ӛ' => 'ӛ',
+ 'Ӝ' => 'Ӝ',
+ 'ӝ' => 'ӝ',
+ 'Ӟ' => 'Ӟ',
+ 'ӟ' => 'ӟ',
+ 'Ӣ' => 'Ӣ',
+ 'ӣ' => 'ӣ',
+ 'Ӥ' => 'Ӥ',
+ 'ӥ' => 'ӥ',
+ 'Ӧ' => 'Ӧ',
+ 'ӧ' => 'ӧ',
+ 'Ӫ' => 'Ӫ',
+ 'ӫ' => 'ӫ',
+ 'Ӭ' => 'Ӭ',
+ 'ӭ' => 'ӭ',
+ 'Ӯ' => 'Ӯ',
+ 'ӯ' => 'ӯ',
+ 'Ӱ' => 'Ӱ',
+ 'ӱ' => 'ӱ',
+ 'Ӳ' => 'Ӳ',
+ 'ӳ' => 'ӳ',
+ 'Ӵ' => 'Ӵ',
+ 'ӵ' => 'ӵ',
+ 'Ӹ' => 'Ӹ',
+ 'ӹ' => 'ӹ',
+ 'آ' => 'آ',
+ 'أ' => 'أ',
+ 'ؤ' => 'ؤ',
+ 'إ' => 'إ',
+ 'ئ' => 'ئ',
+ 'ۀ' => 'ۀ',
+ 'ۂ' => 'ۂ',
+ 'ۓ' => 'ۓ',
+ 'ऩ' => 'ऩ',
+ 'ऱ' => 'ऱ',
+ 'ऴ' => 'ऴ',
+ 'क़' => 'क़',
+ 'ख़' => 'ख़',
+ 'ग़' => 'ग़',
+ 'ज़' => 'ज़',
+ 'ड़' => 'ड़',
+ 'ढ़' => 'ढ़',
+ 'फ़' => 'फ़',
+ 'य़' => 'य़',
+ 'ো' => 'ো',
+ 'ৌ' => 'ৌ',
+ 'ড়' => 'ড়',
+ 'ঢ়' => 'ঢ়',
+ 'য়' => 'য়',
+ 'ਲ਼' => 'ਲ਼',
+ 'ਸ਼' => 'ਸ਼',
+ 'ਖ਼' => 'ਖ਼',
+ 'ਗ਼' => 'ਗ਼',
+ 'ਜ਼' => 'ਜ਼',
+ 'ਫ਼' => 'ਫ਼',
+ 'ୈ' => 'ୈ',
+ 'ୋ' => 'ୋ',
+ 'ୌ' => 'ୌ',
+ 'ଡ଼' => 'ଡ଼',
+ 'ଢ଼' => 'ଢ଼',
+ 'ஔ' => 'ஔ',
+ 'ொ' => 'ொ',
+ 'ோ' => 'ோ',
+ 'ௌ' => 'ௌ',
+ 'ై' => 'ై',
+ 'ೀ' => 'ೀ',
+ 'ೇ' => 'ೇ',
+ 'ೈ' => 'ೈ',
+ 'ೊ' => 'ೊ',
+ 'ೋ' => 'ೋ',
+ 'ൊ' => 'ൊ',
+ 'ോ' => 'ോ',
+ 'ൌ' => 'ൌ',
+ 'ේ' => 'ේ',
+ 'ො' => 'ො',
+ 'ෝ' => 'ෝ',
+ 'ෞ' => 'ෞ',
+ 'གྷ' => 'གྷ',
+ 'ཌྷ' => 'ཌྷ',
+ 'དྷ' => 'དྷ',
+ 'བྷ' => 'བྷ',
+ 'ཛྷ' => 'ཛྷ',
+ 'ཀྵ' => 'ཀྵ',
+ 'ཱི' => 'ཱི',
+ 'ཱུ' => 'ཱུ',
+ 'ྲྀ' => 'ྲྀ',
+ 'ླྀ' => 'ླྀ',
+ 'ཱྀ' => 'ཱྀ',
+ 'ྒྷ' => 'ྒྷ',
+ 'ྜྷ' => 'ྜྷ',
+ 'ྡྷ' => 'ྡྷ',
+ 'ྦྷ' => 'ྦྷ',
+ 'ྫྷ' => 'ྫྷ',
+ 'ྐྵ' => 'ྐྵ',
+ 'ဦ' => 'ဦ',
+ 'ᬆ' => 'ᬆ',
+ 'ᬈ' => 'ᬈ',
+ 'ᬊ' => 'ᬊ',
+ 'ᬌ' => 'ᬌ',
+ 'ᬎ' => 'ᬎ',
+ 'ᬒ' => 'ᬒ',
+ 'ᬻ' => 'ᬻ',
+ 'ᬽ' => 'ᬽ',
+ 'ᭀ' => 'ᭀ',
+ 'ᭁ' => 'ᭁ',
+ 'ᭃ' => 'ᭃ',
+ 'Ḁ' => 'Ḁ',
+ 'ḁ' => 'ḁ',
+ 'Ḃ' => 'Ḃ',
+ 'ḃ' => 'ḃ',
+ 'Ḅ' => 'Ḅ',
+ 'ḅ' => 'ḅ',
+ 'Ḇ' => 'Ḇ',
+ 'ḇ' => 'ḇ',
+ 'Ḉ' => 'Ḉ',
+ 'ḉ' => 'ḉ',
+ 'Ḋ' => 'Ḋ',
+ 'ḋ' => 'ḋ',
+ 'Ḍ' => 'Ḍ',
+ 'ḍ' => 'ḍ',
+ 'Ḏ' => 'Ḏ',
+ 'ḏ' => 'ḏ',
+ 'Ḑ' => 'Ḑ',
+ 'ḑ' => 'ḑ',
+ 'Ḓ' => 'Ḓ',
+ 'ḓ' => 'ḓ',
+ 'Ḕ' => 'Ḕ',
+ 'ḕ' => 'ḕ',
+ 'Ḗ' => 'Ḗ',
+ 'ḗ' => 'ḗ',
+ 'Ḙ' => 'Ḙ',
+ 'ḙ' => 'ḙ',
+ 'Ḛ' => 'Ḛ',
+ 'ḛ' => 'ḛ',
+ 'Ḝ' => 'Ḝ',
+ 'ḝ' => 'ḝ',
+ 'Ḟ' => 'Ḟ',
+ 'ḟ' => 'ḟ',
+ 'Ḡ' => 'Ḡ',
+ 'ḡ' => 'ḡ',
+ 'Ḣ' => 'Ḣ',
+ 'ḣ' => 'ḣ',
+ 'Ḥ' => 'Ḥ',
+ 'ḥ' => 'ḥ',
+ 'Ḧ' => 'Ḧ',
+ 'ḧ' => 'ḧ',
+ 'Ḩ' => 'Ḩ',
+ 'ḩ' => 'ḩ',
+ 'Ḫ' => 'Ḫ',
+ 'ḫ' => 'ḫ',
+ 'Ḭ' => 'Ḭ',
+ 'ḭ' => 'ḭ',
+ 'Ḯ' => 'Ḯ',
+ 'ḯ' => 'ḯ',
+ 'Ḱ' => 'Ḱ',
+ 'ḱ' => 'ḱ',
+ 'Ḳ' => 'Ḳ',
+ 'ḳ' => 'ḳ',
+ 'Ḵ' => 'Ḵ',
+ 'ḵ' => 'ḵ',
+ 'Ḷ' => 'Ḷ',
+ 'ḷ' => 'ḷ',
+ 'Ḹ' => 'Ḹ',
+ 'ḹ' => 'ḹ',
+ 'Ḻ' => 'Ḻ',
+ 'ḻ' => 'ḻ',
+ 'Ḽ' => 'Ḽ',
+ 'ḽ' => 'ḽ',
+ 'Ḿ' => 'Ḿ',
+ 'ḿ' => 'ḿ',
+ 'Ṁ' => 'Ṁ',
+ 'ṁ' => 'ṁ',
+ 'Ṃ' => 'Ṃ',
+ 'ṃ' => 'ṃ',
+ 'Ṅ' => 'Ṅ',
+ 'ṅ' => 'ṅ',
+ 'Ṇ' => 'Ṇ',
+ 'ṇ' => 'ṇ',
+ 'Ṉ' => 'Ṉ',
+ 'ṉ' => 'ṉ',
+ 'Ṋ' => 'Ṋ',
+ 'ṋ' => 'ṋ',
+ 'Ṍ' => 'Ṍ',
+ 'ṍ' => 'ṍ',
+ 'Ṏ' => 'Ṏ',
+ 'ṏ' => 'ṏ',
+ 'Ṑ' => 'Ṑ',
+ 'ṑ' => 'ṑ',
+ 'Ṓ' => 'Ṓ',
+ 'ṓ' => 'ṓ',
+ 'Ṕ' => 'Ṕ',
+ 'ṕ' => 'ṕ',
+ 'Ṗ' => 'Ṗ',
+ 'ṗ' => 'ṗ',
+ 'Ṙ' => 'Ṙ',
+ 'ṙ' => 'ṙ',
+ 'Ṛ' => 'Ṛ',
+ 'ṛ' => 'ṛ',
+ 'Ṝ' => 'Ṝ',
+ 'ṝ' => 'ṝ',
+ 'Ṟ' => 'Ṟ',
+ 'ṟ' => 'ṟ',
+ 'Ṡ' => 'Ṡ',
+ 'ṡ' => 'ṡ',
+ 'Ṣ' => 'Ṣ',
+ 'ṣ' => 'ṣ',
+ 'Ṥ' => 'Ṥ',
+ 'ṥ' => 'ṥ',
+ 'Ṧ' => 'Ṧ',
+ 'ṧ' => 'ṧ',
+ 'Ṩ' => 'Ṩ',
+ 'ṩ' => 'ṩ',
+ 'Ṫ' => 'Ṫ',
+ 'ṫ' => 'ṫ',
+ 'Ṭ' => 'Ṭ',
+ 'ṭ' => 'ṭ',
+ 'Ṯ' => 'Ṯ',
+ 'ṯ' => 'ṯ',
+ 'Ṱ' => 'Ṱ',
+ 'ṱ' => 'ṱ',
+ 'Ṳ' => 'Ṳ',
+ 'ṳ' => 'ṳ',
+ 'Ṵ' => 'Ṵ',
+ 'ṵ' => 'ṵ',
+ 'Ṷ' => 'Ṷ',
+ 'ṷ' => 'ṷ',
+ 'Ṹ' => 'Ṹ',
+ 'ṹ' => 'ṹ',
+ 'Ṻ' => 'Ṻ',
+ 'ṻ' => 'ṻ',
+ 'Ṽ' => 'Ṽ',
+ 'ṽ' => 'ṽ',
+ 'Ṿ' => 'Ṿ',
+ 'ṿ' => 'ṿ',
+ 'Ẁ' => 'Ẁ',
+ 'ẁ' => 'ẁ',
+ 'Ẃ' => 'Ẃ',
+ 'ẃ' => 'ẃ',
+ 'Ẅ' => 'Ẅ',
+ 'ẅ' => 'ẅ',
+ 'Ẇ' => 'Ẇ',
+ 'ẇ' => 'ẇ',
+ 'Ẉ' => 'Ẉ',
+ 'ẉ' => 'ẉ',
+ 'Ẋ' => 'Ẋ',
+ 'ẋ' => 'ẋ',
+ 'Ẍ' => 'Ẍ',
+ 'ẍ' => 'ẍ',
+ 'Ẏ' => 'Ẏ',
+ 'ẏ' => 'ẏ',
+ 'Ẑ' => 'Ẑ',
+ 'ẑ' => 'ẑ',
+ 'Ẓ' => 'Ẓ',
+ 'ẓ' => 'ẓ',
+ 'Ẕ' => 'Ẕ',
+ 'ẕ' => 'ẕ',
+ 'ẖ' => 'ẖ',
+ 'ẗ' => 'ẗ',
+ 'ẘ' => 'ẘ',
+ 'ẙ' => 'ẙ',
+ 'ẛ' => 'ẛ',
+ 'Ạ' => 'Ạ',
+ 'ạ' => 'ạ',
+ 'Ả' => 'Ả',
+ 'ả' => 'ả',
+ 'Ấ' => 'Ấ',
+ 'ấ' => 'ấ',
+ 'Ầ' => 'Ầ',
+ 'ầ' => 'ầ',
+ 'Ẩ' => 'Ẩ',
+ 'ẩ' => 'ẩ',
+ 'Ẫ' => 'Ẫ',
+ 'ẫ' => 'ẫ',
+ 'Ậ' => 'Ậ',
+ 'ậ' => 'ậ',
+ 'Ắ' => 'Ắ',
+ 'ắ' => 'ắ',
+ 'Ằ' => 'Ằ',
+ 'ằ' => 'ằ',
+ 'Ẳ' => 'Ẳ',
+ 'ẳ' => 'ẳ',
+ 'Ẵ' => 'Ẵ',
+ 'ẵ' => 'ẵ',
+ 'Ặ' => 'Ặ',
+ 'ặ' => 'ặ',
+ 'Ẹ' => 'Ẹ',
+ 'ẹ' => 'ẹ',
+ 'Ẻ' => 'Ẻ',
+ 'ẻ' => 'ẻ',
+ 'Ẽ' => 'Ẽ',
+ 'ẽ' => 'ẽ',
+ 'Ế' => 'Ế',
+ 'ế' => 'ế',
+ 'Ề' => 'Ề',
+ 'ề' => 'ề',
+ 'Ể' => 'Ể',
+ 'ể' => 'ể',
+ 'Ễ' => 'Ễ',
+ 'ễ' => 'ễ',
+ 'Ệ' => 'Ệ',
+ 'ệ' => 'ệ',
+ 'Ỉ' => 'Ỉ',
+ 'ỉ' => 'ỉ',
+ 'Ị' => 'Ị',
+ 'ị' => 'ị',
+ 'Ọ' => 'Ọ',
+ 'ọ' => 'ọ',
+ 'Ỏ' => 'Ỏ',
+ 'ỏ' => 'ỏ',
+ 'Ố' => 'Ố',
+ 'ố' => 'ố',
+ 'Ồ' => 'Ồ',
+ 'ồ' => 'ồ',
+ 'Ổ' => 'Ổ',
+ 'ổ' => 'ổ',
+ 'Ỗ' => 'Ỗ',
+ 'ỗ' => 'ỗ',
+ 'Ộ' => 'Ộ',
+ 'ộ' => 'ộ',
+ 'Ớ' => 'Ớ',
+ 'ớ' => 'ớ',
+ 'Ờ' => 'Ờ',
+ 'ờ' => 'ờ',
+ 'Ở' => 'Ở',
+ 'ở' => 'ở',
+ 'Ỡ' => 'Ỡ',
+ 'ỡ' => 'ỡ',
+ 'Ợ' => 'Ợ',
+ 'ợ' => 'ợ',
+ 'Ụ' => 'Ụ',
+ 'ụ' => 'ụ',
+ 'Ủ' => 'Ủ',
+ 'ủ' => 'ủ',
+ 'Ứ' => 'Ứ',
+ 'ứ' => 'ứ',
+ 'Ừ' => 'Ừ',
+ 'ừ' => 'ừ',
+ 'Ử' => 'Ử',
+ 'ử' => 'ử',
+ 'Ữ' => 'Ữ',
+ 'ữ' => 'ữ',
+ 'Ự' => 'Ự',
+ 'ự' => 'ự',
+ 'Ỳ' => 'Ỳ',
+ 'ỳ' => 'ỳ',
+ 'Ỵ' => 'Ỵ',
+ 'ỵ' => 'ỵ',
+ 'Ỷ' => 'Ỷ',
+ 'ỷ' => 'ỷ',
+ 'Ỹ' => 'Ỹ',
+ 'ỹ' => 'ỹ',
+ 'ἀ' => 'ἀ',
+ 'ἁ' => 'ἁ',
+ 'ἂ' => 'ἂ',
+ 'ἃ' => 'ἃ',
+ 'ἄ' => 'ἄ',
+ 'ἅ' => 'ἅ',
+ 'ἆ' => 'ἆ',
+ 'ἇ' => 'ἇ',
+ 'Ἀ' => 'Ἀ',
+ 'Ἁ' => 'Ἁ',
+ 'Ἂ' => 'Ἂ',
+ 'Ἃ' => 'Ἃ',
+ 'Ἄ' => 'Ἄ',
+ 'Ἅ' => 'Ἅ',
+ 'Ἆ' => 'Ἆ',
+ 'Ἇ' => 'Ἇ',
+ 'ἐ' => 'ἐ',
+ 'ἑ' => 'ἑ',
+ 'ἒ' => 'ἒ',
+ 'ἓ' => 'ἓ',
+ 'ἔ' => 'ἔ',
+ 'ἕ' => 'ἕ',
+ 'Ἐ' => 'Ἐ',
+ 'Ἑ' => 'Ἑ',
+ 'Ἒ' => 'Ἒ',
+ 'Ἓ' => 'Ἓ',
+ 'Ἔ' => 'Ἔ',
+ 'Ἕ' => 'Ἕ',
+ 'ἠ' => 'ἠ',
+ 'ἡ' => 'ἡ',
+ 'ἢ' => 'ἢ',
+ 'ἣ' => 'ἣ',
+ 'ἤ' => 'ἤ',
+ 'ἥ' => 'ἥ',
+ 'ἦ' => 'ἦ',
+ 'ἧ' => 'ἧ',
+ 'Ἠ' => 'Ἠ',
+ 'Ἡ' => 'Ἡ',
+ 'Ἢ' => 'Ἢ',
+ 'Ἣ' => 'Ἣ',
+ 'Ἤ' => 'Ἤ',
+ 'Ἥ' => 'Ἥ',
+ 'Ἦ' => 'Ἦ',
+ 'Ἧ' => 'Ἧ',
+ 'ἰ' => 'ἰ',
+ 'ἱ' => 'ἱ',
+ 'ἲ' => 'ἲ',
+ 'ἳ' => 'ἳ',
+ 'ἴ' => 'ἴ',
+ 'ἵ' => 'ἵ',
+ 'ἶ' => 'ἶ',
+ 'ἷ' => 'ἷ',
+ 'Ἰ' => 'Ἰ',
+ 'Ἱ' => 'Ἱ',
+ 'Ἲ' => 'Ἲ',
+ 'Ἳ' => 'Ἳ',
+ 'Ἴ' => 'Ἴ',
+ 'Ἵ' => 'Ἵ',
+ 'Ἶ' => 'Ἶ',
+ 'Ἷ' => 'Ἷ',
+ 'ὀ' => 'ὀ',
+ 'ὁ' => 'ὁ',
+ 'ὂ' => 'ὂ',
+ 'ὃ' => 'ὃ',
+ 'ὄ' => 'ὄ',
+ 'ὅ' => 'ὅ',
+ 'Ὀ' => 'Ὀ',
+ 'Ὁ' => 'Ὁ',
+ 'Ὂ' => 'Ὂ',
+ 'Ὃ' => 'Ὃ',
+ 'Ὄ' => 'Ὄ',
+ 'Ὅ' => 'Ὅ',
+ 'ὐ' => 'ὐ',
+ 'ὑ' => 'ὑ',
+ 'ὒ' => 'ὒ',
+ 'ὓ' => 'ὓ',
+ 'ὔ' => 'ὔ',
+ 'ὕ' => 'ὕ',
+ 'ὖ' => 'ὖ',
+ 'ὗ' => 'ὗ',
+ 'Ὑ' => 'Ὑ',
+ 'Ὓ' => 'Ὓ',
+ 'Ὕ' => 'Ὕ',
+ 'Ὗ' => 'Ὗ',
+ 'ὠ' => 'ὠ',
+ 'ὡ' => 'ὡ',
+ 'ὢ' => 'ὢ',
+ 'ὣ' => 'ὣ',
+ 'ὤ' => 'ὤ',
+ 'ὥ' => 'ὥ',
+ 'ὦ' => 'ὦ',
+ 'ὧ' => 'ὧ',
+ 'Ὠ' => 'Ὠ',
+ 'Ὡ' => 'Ὡ',
+ 'Ὢ' => 'Ὢ',
+ 'Ὣ' => 'Ὣ',
+ 'Ὤ' => 'Ὤ',
+ 'Ὥ' => 'Ὥ',
+ 'Ὦ' => 'Ὦ',
+ 'Ὧ' => 'Ὧ',
+ 'ὰ' => 'ὰ',
+ 'ά' => 'ά',
+ 'ὲ' => 'ὲ',
+ 'έ' => 'έ',
+ 'ὴ' => 'ὴ',
+ 'ή' => 'ή',
+ 'ὶ' => 'ὶ',
+ 'ί' => 'ί',
+ 'ὸ' => 'ὸ',
+ 'ό' => 'ό',
+ 'ὺ' => 'ὺ',
+ 'ύ' => 'ύ',
+ 'ὼ' => 'ὼ',
+ 'ώ' => 'ώ',
+ 'ᾀ' => 'ᾀ',
+ 'ᾁ' => 'ᾁ',
+ 'ᾂ' => 'ᾂ',
+ 'ᾃ' => 'ᾃ',
+ 'ᾄ' => 'ᾄ',
+ 'ᾅ' => 'ᾅ',
+ 'ᾆ' => 'ᾆ',
+ 'ᾇ' => 'ᾇ',
+ 'ᾈ' => 'ᾈ',
+ 'ᾉ' => 'ᾉ',
+ 'ᾊ' => 'ᾊ',
+ 'ᾋ' => 'ᾋ',
+ 'ᾌ' => 'ᾌ',
+ 'ᾍ' => 'ᾍ',
+ 'ᾎ' => 'ᾎ',
+ 'ᾏ' => 'ᾏ',
+ 'ᾐ' => 'ᾐ',
+ 'ᾑ' => 'ᾑ',
+ 'ᾒ' => 'ᾒ',
+ 'ᾓ' => 'ᾓ',
+ 'ᾔ' => 'ᾔ',
+ 'ᾕ' => 'ᾕ',
+ 'ᾖ' => 'ᾖ',
+ 'ᾗ' => 'ᾗ',
+ 'ᾘ' => 'ᾘ',
+ 'ᾙ' => 'ᾙ',
+ 'ᾚ' => 'ᾚ',
+ 'ᾛ' => 'ᾛ',
+ 'ᾜ' => 'ᾜ',
+ 'ᾝ' => 'ᾝ',
+ 'ᾞ' => 'ᾞ',
+ 'ᾟ' => 'ᾟ',
+ 'ᾠ' => 'ᾠ',
+ 'ᾡ' => 'ᾡ',
+ 'ᾢ' => 'ᾢ',
+ 'ᾣ' => 'ᾣ',
+ 'ᾤ' => 'ᾤ',
+ 'ᾥ' => 'ᾥ',
+ 'ᾦ' => 'ᾦ',
+ 'ᾧ' => 'ᾧ',
+ 'ᾨ' => 'ᾨ',
+ 'ᾩ' => 'ᾩ',
+ 'ᾪ' => 'ᾪ',
+ 'ᾫ' => 'ᾫ',
+ 'ᾬ' => 'ᾬ',
+ 'ᾭ' => 'ᾭ',
+ 'ᾮ' => 'ᾮ',
+ 'ᾯ' => 'ᾯ',
+ 'ᾰ' => 'ᾰ',
+ 'ᾱ' => 'ᾱ',
+ 'ᾲ' => 'ᾲ',
+ 'ᾳ' => 'ᾳ',
+ 'ᾴ' => 'ᾴ',
+ 'ᾶ' => 'ᾶ',
+ 'ᾷ' => 'ᾷ',
+ 'Ᾰ' => 'Ᾰ',
+ 'Ᾱ' => 'Ᾱ',
+ 'Ὰ' => 'Ὰ',
+ 'Ά' => 'Ά',
+ 'ᾼ' => 'ᾼ',
+ 'ι' => 'ι',
+ '῁' => '῁',
+ 'ῂ' => 'ῂ',
+ 'ῃ' => 'ῃ',
+ 'ῄ' => 'ῄ',
+ 'ῆ' => 'ῆ',
+ 'ῇ' => 'ῇ',
+ 'Ὲ' => 'Ὲ',
+ 'Έ' => 'Έ',
+ 'Ὴ' => 'Ὴ',
+ 'Ή' => 'Ή',
+ 'ῌ' => 'ῌ',
+ '῍' => '῍',
+ '῎' => '῎',
+ '῏' => '῏',
+ 'ῐ' => 'ῐ',
+ 'ῑ' => 'ῑ',
+ 'ῒ' => 'ῒ',
+ 'ΐ' => 'ΐ',
+ 'ῖ' => 'ῖ',
+ 'ῗ' => 'ῗ',
+ 'Ῐ' => 'Ῐ',
+ 'Ῑ' => 'Ῑ',
+ 'Ὶ' => 'Ὶ',
+ 'Ί' => 'Ί',
+ '῝' => '῝',
+ '῞' => '῞',
+ '῟' => '῟',
+ 'ῠ' => 'ῠ',
+ 'ῡ' => 'ῡ',
+ 'ῢ' => 'ῢ',
+ 'ΰ' => 'ΰ',
+ 'ῤ' => 'ῤ',
+ 'ῥ' => 'ῥ',
+ 'ῦ' => 'ῦ',
+ 'ῧ' => 'ῧ',
+ 'Ῠ' => 'Ῠ',
+ 'Ῡ' => 'Ῡ',
+ 'Ὺ' => 'Ὺ',
+ 'Ύ' => 'Ύ',
+ 'Ῥ' => 'Ῥ',
+ '῭' => '῭',
+ '΅' => '΅',
+ '`' => '`',
+ 'ῲ' => 'ῲ',
+ 'ῳ' => 'ῳ',
+ 'ῴ' => 'ῴ',
+ 'ῶ' => 'ῶ',
+ 'ῷ' => 'ῷ',
+ 'Ὸ' => 'Ὸ',
+ 'Ό' => 'Ό',
+ 'Ὼ' => 'Ὼ',
+ 'Ώ' => 'Ώ',
+ 'ῼ' => 'ῼ',
+ '´' => '´',
+ ' ' => ' ',
+ ' ' => ' ',
+ 'Ω' => 'Ω',
+ 'K' => 'K',
+ 'Å' => 'Å',
+ '↚' => '↚',
+ '↛' => '↛',
+ '↮' => '↮',
+ '⇍' => '⇍',
+ '⇎' => '⇎',
+ '⇏' => '⇏',
+ '∄' => '∄',
+ '∉' => '∉',
+ '∌' => '∌',
+ '∤' => '∤',
+ '∦' => '∦',
+ '≁' => '≁',
+ '≄' => '≄',
+ '≇' => '≇',
+ '≉' => '≉',
+ '≠' => '≠',
+ '≢' => '≢',
+ '≭' => '≭',
+ '≮' => '≮',
+ '≯' => '≯',
+ '≰' => '≰',
+ '≱' => '≱',
+ '≴' => '≴',
+ '≵' => '≵',
+ '≸' => '≸',
+ '≹' => '≹',
+ '⊀' => '⊀',
+ '⊁' => '⊁',
+ '⊄' => '⊄',
+ '⊅' => '⊅',
+ '⊈' => '⊈',
+ '⊉' => '⊉',
+ '⊬' => '⊬',
+ '⊭' => '⊭',
+ '⊮' => '⊮',
+ '⊯' => '⊯',
+ '⋠' => '⋠',
+ '⋡' => '⋡',
+ '⋢' => '⋢',
+ '⋣' => '⋣',
+ '⋪' => '⋪',
+ '⋫' => '⋫',
+ '⋬' => '⋬',
+ '⋭' => '⋭',
+ '〈' => '〈',
+ '〉' => '〉',
+ '⫝̸' => '⫝̸',
+ 'が' => 'が',
+ 'ぎ' => 'ぎ',
+ 'ぐ' => 'ぐ',
+ 'げ' => 'げ',
+ 'ご' => 'ご',
+ 'ざ' => 'ざ',
+ 'じ' => 'じ',
+ 'ず' => 'ず',
+ 'ぜ' => 'ぜ',
+ 'ぞ' => 'ぞ',
+ 'だ' => 'だ',
+ 'ぢ' => 'ぢ',
+ 'づ' => 'づ',
+ 'で' => 'で',
+ 'ど' => 'ど',
+ 'ば' => 'ば',
+ 'ぱ' => 'ぱ',
+ 'び' => 'び',
+ 'ぴ' => 'ぴ',
+ 'ぶ' => 'ぶ',
+ 'ぷ' => 'ぷ',
+ 'べ' => 'べ',
+ 'ぺ' => 'ぺ',
+ 'ぼ' => 'ぼ',
+ 'ぽ' => 'ぽ',
+ 'ゔ' => 'ゔ',
+ 'ゞ' => 'ゞ',
+ 'ガ' => 'ガ',
+ 'ギ' => 'ギ',
+ 'グ' => 'グ',
+ 'ゲ' => 'ゲ',
+ 'ゴ' => 'ゴ',
+ 'ザ' => 'ザ',
+ 'ジ' => 'ジ',
+ 'ズ' => 'ズ',
+ 'ゼ' => 'ゼ',
+ 'ゾ' => 'ゾ',
+ 'ダ' => 'ダ',
+ 'ヂ' => 'ヂ',
+ 'ヅ' => 'ヅ',
+ 'デ' => 'デ',
+ 'ド' => 'ド',
+ 'バ' => 'バ',
+ 'パ' => 'パ',
+ 'ビ' => 'ビ',
+ 'ピ' => 'ピ',
+ 'ブ' => 'ブ',
+ 'プ' => 'プ',
+ 'ベ' => 'ベ',
+ 'ペ' => 'ペ',
+ 'ボ' => 'ボ',
+ 'ポ' => 'ポ',
+ 'ヴ' => 'ヴ',
+ 'ヷ' => 'ヷ',
+ 'ヸ' => 'ヸ',
+ 'ヹ' => 'ヹ',
+ 'ヺ' => 'ヺ',
+ 'ヾ' => 'ヾ',
+ '豈' => '豈',
+ '更' => '更',
+ '車' => '車',
+ '賈' => '賈',
+ '滑' => '滑',
+ '串' => '串',
+ '句' => '句',
+ '龜' => '龜',
+ '龜' => '龜',
+ '契' => '契',
+ '金' => '金',
+ '喇' => '喇',
+ '奈' => '奈',
+ '懶' => '懶',
+ '癩' => '癩',
+ '羅' => '羅',
+ '蘿' => '蘿',
+ '螺' => '螺',
+ '裸' => '裸',
+ '邏' => '邏',
+ '樂' => '樂',
+ '洛' => '洛',
+ '烙' => '烙',
+ '珞' => '珞',
+ '落' => '落',
+ '酪' => '酪',
+ '駱' => '駱',
+ '亂' => '亂',
+ '卵' => '卵',
+ '欄' => '欄',
+ '爛' => '爛',
+ '蘭' => '蘭',
+ '鸞' => '鸞',
+ '嵐' => '嵐',
+ '濫' => '濫',
+ '藍' => '藍',
+ '襤' => '襤',
+ '拉' => '拉',
+ '臘' => '臘',
+ '蠟' => '蠟',
+ '廊' => '廊',
+ '朗' => '朗',
+ '浪' => '浪',
+ '狼' => '狼',
+ '郎' => '郎',
+ '來' => '來',
+ '冷' => '冷',
+ '勞' => '勞',
+ '擄' => '擄',
+ '櫓' => '櫓',
+ '爐' => '爐',
+ '盧' => '盧',
+ '老' => '老',
+ '蘆' => '蘆',
+ '虜' => '虜',
+ '路' => '路',
+ '露' => '露',
+ '魯' => '魯',
+ '鷺' => '鷺',
+ '碌' => '碌',
+ '祿' => '祿',
+ '綠' => '綠',
+ '菉' => '菉',
+ '錄' => '錄',
+ '鹿' => '鹿',
+ '論' => '論',
+ '壟' => '壟',
+ '弄' => '弄',
+ '籠' => '籠',
+ '聾' => '聾',
+ '牢' => '牢',
+ '磊' => '磊',
+ '賂' => '賂',
+ '雷' => '雷',
+ '壘' => '壘',
+ '屢' => '屢',
+ '樓' => '樓',
+ '淚' => '淚',
+ '漏' => '漏',
+ '累' => '累',
+ '縷' => '縷',
+ '陋' => '陋',
+ '勒' => '勒',
+ '肋' => '肋',
+ '凜' => '凜',
+ '凌' => '凌',
+ '稜' => '稜',
+ '綾' => '綾',
+ '菱' => '菱',
+ '陵' => '陵',
+ '讀' => '讀',
+ '拏' => '拏',
+ '樂' => '樂',
+ '諾' => '諾',
+ '丹' => '丹',
+ '寧' => '寧',
+ '怒' => '怒',
+ '率' => '率',
+ '異' => '異',
+ '北' => '北',
+ '磻' => '磻',
+ '便' => '便',
+ '復' => '復',
+ '不' => '不',
+ '泌' => '泌',
+ '數' => '數',
+ '索' => '索',
+ '參' => '參',
+ '塞' => '塞',
+ '省' => '省',
+ '葉' => '葉',
+ '說' => '說',
+ '殺' => '殺',
+ '辰' => '辰',
+ '沈' => '沈',
+ '拾' => '拾',
+ '若' => '若',
+ '掠' => '掠',
+ '略' => '略',
+ '亮' => '亮',
+ '兩' => '兩',
+ '凉' => '凉',
+ '梁' => '梁',
+ '糧' => '糧',
+ '良' => '良',
+ '諒' => '諒',
+ '量' => '量',
+ '勵' => '勵',
+ '呂' => '呂',
+ '女' => '女',
+ '廬' => '廬',
+ '旅' => '旅',
+ '濾' => '濾',
+ '礪' => '礪',
+ '閭' => '閭',
+ '驪' => '驪',
+ '麗' => '麗',
+ '黎' => '黎',
+ '力' => '力',
+ '曆' => '曆',
+ '歷' => '歷',
+ '轢' => '轢',
+ '年' => '年',
+ '憐' => '憐',
+ '戀' => '戀',
+ '撚' => '撚',
+ '漣' => '漣',
+ '煉' => '煉',
+ '璉' => '璉',
+ '秊' => '秊',
+ '練' => '練',
+ '聯' => '聯',
+ '輦' => '輦',
+ '蓮' => '蓮',
+ '連' => '連',
+ '鍊' => '鍊',
+ '列' => '列',
+ '劣' => '劣',
+ '咽' => '咽',
+ '烈' => '烈',
+ '裂' => '裂',
+ '說' => '說',
+ '廉' => '廉',
+ '念' => '念',
+ '捻' => '捻',
+ '殮' => '殮',
+ '簾' => '簾',
+ '獵' => '獵',
+ '令' => '令',
+ '囹' => '囹',
+ '寧' => '寧',
+ '嶺' => '嶺',
+ '怜' => '怜',
+ '玲' => '玲',
+ '瑩' => '瑩',
+ '羚' => '羚',
+ '聆' => '聆',
+ '鈴' => '鈴',
+ '零' => '零',
+ '靈' => '靈',
+ '領' => '領',
+ '例' => '例',
+ '禮' => '禮',
+ '醴' => '醴',
+ '隸' => '隸',
+ '惡' => '惡',
+ '了' => '了',
+ '僚' => '僚',
+ '寮' => '寮',
+ '尿' => '尿',
+ '料' => '料',
+ '樂' => '樂',
+ '燎' => '燎',
+ '療' => '療',
+ '蓼' => '蓼',
+ '遼' => '遼',
+ '龍' => '龍',
+ '暈' => '暈',
+ '阮' => '阮',
+ '劉' => '劉',
+ '杻' => '杻',
+ '柳' => '柳',
+ '流' => '流',
+ '溜' => '溜',
+ '琉' => '琉',
+ '留' => '留',
+ '硫' => '硫',
+ '紐' => '紐',
+ '類' => '類',
+ '六' => '六',
+ '戮' => '戮',
+ '陸' => '陸',
+ '倫' => '倫',
+ '崙' => '崙',
+ '淪' => '淪',
+ '輪' => '輪',
+ '律' => '律',
+ '慄' => '慄',
+ '栗' => '栗',
+ '率' => '率',
+ '隆' => '隆',
+ '利' => '利',
+ '吏' => '吏',
+ '履' => '履',
+ '易' => '易',
+ '李' => '李',
+ '梨' => '梨',
+ '泥' => '泥',
+ '理' => '理',
+ '痢' => '痢',
+ '罹' => '罹',
+ '裏' => '裏',
+ '裡' => '裡',
+ '里' => '里',
+ '離' => '離',
+ '匿' => '匿',
+ '溺' => '溺',
+ '吝' => '吝',
+ '燐' => '燐',
+ '璘' => '璘',
+ '藺' => '藺',
+ '隣' => '隣',
+ '鱗' => '鱗',
+ '麟' => '麟',
+ '林' => '林',
+ '淋' => '淋',
+ '臨' => '臨',
+ '立' => '立',
+ '笠' => '笠',
+ '粒' => '粒',
+ '狀' => '狀',
+ '炙' => '炙',
+ '識' => '識',
+ '什' => '什',
+ '茶' => '茶',
+ '刺' => '刺',
+ '切' => '切',
+ '度' => '度',
+ '拓' => '拓',
+ '糖' => '糖',
+ '宅' => '宅',
+ '洞' => '洞',
+ '暴' => '暴',
+ '輻' => '輻',
+ '行' => '行',
+ '降' => '降',
+ '見' => '見',
+ '廓' => '廓',
+ '兀' => '兀',
+ '嗀' => '嗀',
+ '塚' => '塚',
+ '晴' => '晴',
+ '凞' => '凞',
+ '猪' => '猪',
+ '益' => '益',
+ '礼' => '礼',
+ '神' => '神',
+ '祥' => '祥',
+ '福' => '福',
+ '靖' => '靖',
+ '精' => '精',
+ '羽' => '羽',
+ '蘒' => '蘒',
+ '諸' => '諸',
+ '逸' => '逸',
+ '都' => '都',
+ '飯' => '飯',
+ '飼' => '飼',
+ '館' => '館',
+ '鶴' => '鶴',
+ '郞' => '郞',
+ '隷' => '隷',
+ '侮' => '侮',
+ '僧' => '僧',
+ '免' => '免',
+ '勉' => '勉',
+ '勤' => '勤',
+ '卑' => '卑',
+ '喝' => '喝',
+ '嘆' => '嘆',
+ '器' => '器',
+ '塀' => '塀',
+ '墨' => '墨',
+ '層' => '層',
+ '屮' => '屮',
+ '悔' => '悔',
+ '慨' => '慨',
+ '憎' => '憎',
+ '懲' => '懲',
+ '敏' => '敏',
+ '既' => '既',
+ '暑' => '暑',
+ '梅' => '梅',
+ '海' => '海',
+ '渚' => '渚',
+ '漢' => '漢',
+ '煮' => '煮',
+ '爫' => '爫',
+ '琢' => '琢',
+ '碑' => '碑',
+ '社' => '社',
+ '祉' => '祉',
+ '祈' => '祈',
+ '祐' => '祐',
+ '祖' => '祖',
+ '祝' => '祝',
+ '禍' => '禍',
+ '禎' => '禎',
+ '穀' => '穀',
+ '突' => '突',
+ '節' => '節',
+ '練' => '練',
+ '縉' => '縉',
+ '繁' => '繁',
+ '署' => '署',
+ '者' => '者',
+ '臭' => '臭',
+ '艹' => '艹',
+ '艹' => '艹',
+ '著' => '著',
+ '褐' => '褐',
+ '視' => '視',
+ '謁' => '謁',
+ '謹' => '謹',
+ '賓' => '賓',
+ '贈' => '贈',
+ '辶' => '辶',
+ '逸' => '逸',
+ '難' => '難',
+ '響' => '響',
+ '頻' => '頻',
+ '恵' => '恵',
+ '𤋮' => '𤋮',
+ '舘' => '舘',
+ '並' => '並',
+ '况' => '况',
+ '全' => '全',
+ '侀' => '侀',
+ '充' => '充',
+ '冀' => '冀',
+ '勇' => '勇',
+ '勺' => '勺',
+ '喝' => '喝',
+ '啕' => '啕',
+ '喙' => '喙',
+ '嗢' => '嗢',
+ '塚' => '塚',
+ '墳' => '墳',
+ '奄' => '奄',
+ '奔' => '奔',
+ '婢' => '婢',
+ '嬨' => '嬨',
+ '廒' => '廒',
+ '廙' => '廙',
+ '彩' => '彩',
+ '徭' => '徭',
+ '惘' => '惘',
+ '慎' => '慎',
+ '愈' => '愈',
+ '憎' => '憎',
+ '慠' => '慠',
+ '懲' => '懲',
+ '戴' => '戴',
+ '揄' => '揄',
+ '搜' => '搜',
+ '摒' => '摒',
+ '敖' => '敖',
+ '晴' => '晴',
+ '朗' => '朗',
+ '望' => '望',
+ '杖' => '杖',
+ '歹' => '歹',
+ '殺' => '殺',
+ '流' => '流',
+ '滛' => '滛',
+ '滋' => '滋',
+ '漢' => '漢',
+ '瀞' => '瀞',
+ '煮' => '煮',
+ '瞧' => '瞧',
+ '爵' => '爵',
+ '犯' => '犯',
+ '猪' => '猪',
+ '瑱' => '瑱',
+ '甆' => '甆',
+ '画' => '画',
+ '瘝' => '瘝',
+ '瘟' => '瘟',
+ '益' => '益',
+ '盛' => '盛',
+ '直' => '直',
+ '睊' => '睊',
+ '着' => '着',
+ '磌' => '磌',
+ '窱' => '窱',
+ '節' => '節',
+ '类' => '类',
+ '絛' => '絛',
+ '練' => '練',
+ '缾' => '缾',
+ '者' => '者',
+ '荒' => '荒',
+ '華' => '華',
+ '蝹' => '蝹',
+ '襁' => '襁',
+ '覆' => '覆',
+ '視' => '視',
+ '調' => '調',
+ '諸' => '諸',
+ '請' => '請',
+ '謁' => '謁',
+ '諾' => '諾',
+ '諭' => '諭',
+ '謹' => '謹',
+ '變' => '變',
+ '贈' => '贈',
+ '輸' => '輸',
+ '遲' => '遲',
+ '醙' => '醙',
+ '鉶' => '鉶',
+ '陼' => '陼',
+ '難' => '難',
+ '靖' => '靖',
+ '韛' => '韛',
+ '響' => '響',
+ '頋' => '頋',
+ '頻' => '頻',
+ '鬒' => '鬒',
+ '龜' => '龜',
+ '𢡊' => '𢡊',
+ '𢡄' => '𢡄',
+ '𣏕' => '𣏕',
+ '㮝' => '㮝',
+ '䀘' => '䀘',
+ '䀹' => '䀹',
+ '𥉉' => '𥉉',
+ '𥳐' => '𥳐',
+ '𧻓' => '𧻓',
+ '齃' => '齃',
+ '龎' => '龎',
+ 'יִ' => 'יִ',
+ 'ײַ' => 'ײַ',
+ 'שׁ' => 'שׁ',
+ 'שׂ' => 'שׂ',
+ 'שּׁ' => 'שּׁ',
+ 'שּׂ' => 'שּׂ',
+ 'אַ' => 'אַ',
+ 'אָ' => 'אָ',
+ 'אּ' => 'אּ',
+ 'בּ' => 'בּ',
+ 'גּ' => 'גּ',
+ 'דּ' => 'דּ',
+ 'הּ' => 'הּ',
+ 'וּ' => 'וּ',
+ 'זּ' => 'זּ',
+ 'טּ' => 'טּ',
+ 'יּ' => 'יּ',
+ 'ךּ' => 'ךּ',
+ 'כּ' => 'כּ',
+ 'לּ' => 'לּ',
+ 'מּ' => 'מּ',
+ 'נּ' => 'נּ',
+ 'סּ' => 'סּ',
+ 'ףּ' => 'ףּ',
+ 'פּ' => 'פּ',
+ 'צּ' => 'צּ',
+ 'קּ' => 'קּ',
+ 'רּ' => 'רּ',
+ 'שּ' => 'שּ',
+ 'תּ' => 'תּ',
+ 'וֹ' => 'וֹ',
+ 'בֿ' => 'בֿ',
+ 'כֿ' => 'כֿ',
+ 'פֿ' => 'פֿ',
+ '𑂚' => '𑂚',
+ '𑂜' => '𑂜',
+ '𑂫' => '𑂫',
+ '𑄮' => '𑄮',
+ '𑄯' => '𑄯',
+ '𑍋' => '𑍋',
+ '𑍌' => '𑍌',
+ '𑒻' => '𑒻',
+ '𑒼' => '𑒼',
+ '𑒾' => '𑒾',
+ '𑖺' => '𑖺',
+ '𑖻' => '𑖻',
+ '𑤸' => '𑤸',
+ '𝅗𝅥' => '𝅗𝅥',
+ '𝅘𝅥' => '𝅘𝅥',
+ '𝅘𝅥𝅮' => '𝅘𝅥𝅮',
+ '𝅘𝅥𝅯' => '𝅘𝅥𝅯',
+ '𝅘𝅥𝅰' => '𝅘𝅥𝅰',
+ '𝅘𝅥𝅱' => '𝅘𝅥𝅱',
+ '𝅘𝅥𝅲' => '𝅘𝅥𝅲',
+ '𝆹𝅥' => '𝆹𝅥',
+ '𝆺𝅥' => '𝆺𝅥',
+ '𝆹𝅥𝅮' => '𝆹𝅥𝅮',
+ '𝆺𝅥𝅮' => '𝆺𝅥𝅮',
+ '𝆹𝅥𝅯' => '𝆹𝅥𝅯',
+ '𝆺𝅥𝅯' => '𝆺𝅥𝅯',
+ '丽' => '丽',
+ '丸' => '丸',
+ '乁' => '乁',
+ '𠄢' => '𠄢',
+ '你' => '你',
+ '侮' => '侮',
+ '侻' => '侻',
+ '倂' => '倂',
+ '偺' => '偺',
+ '備' => '備',
+ '僧' => '僧',
+ '像' => '像',
+ '㒞' => '㒞',
+ '𠘺' => '𠘺',
+ '免' => '免',
+ '兔' => '兔',
+ '兤' => '兤',
+ '具' => '具',
+ '𠔜' => '𠔜',
+ '㒹' => '㒹',
+ '內' => '內',
+ '再' => '再',
+ '𠕋' => '𠕋',
+ '冗' => '冗',
+ '冤' => '冤',
+ '仌' => '仌',
+ '冬' => '冬',
+ '况' => '况',
+ '𩇟' => '𩇟',
+ '凵' => '凵',
+ '刃' => '刃',
+ '㓟' => '㓟',
+ '刻' => '刻',
+ '剆' => '剆',
+ '割' => '割',
+ '剷' => '剷',
+ '㔕' => '㔕',
+ '勇' => '勇',
+ '勉' => '勉',
+ '勤' => '勤',
+ '勺' => '勺',
+ '包' => '包',
+ '匆' => '匆',
+ '北' => '北',
+ '卉' => '卉',
+ '卑' => '卑',
+ '博' => '博',
+ '即' => '即',
+ '卽' => '卽',
+ '卿' => '卿',
+ '卿' => '卿',
+ '卿' => '卿',
+ '𠨬' => '𠨬',
+ '灰' => '灰',
+ '及' => '及',
+ '叟' => '叟',
+ '𠭣' => '𠭣',
+ '叫' => '叫',
+ '叱' => '叱',
+ '吆' => '吆',
+ '咞' => '咞',
+ '吸' => '吸',
+ '呈' => '呈',
+ '周' => '周',
+ '咢' => '咢',
+ '哶' => '哶',
+ '唐' => '唐',
+ '啓' => '啓',
+ '啣' => '啣',
+ '善' => '善',
+ '善' => '善',
+ '喙' => '喙',
+ '喫' => '喫',
+ '喳' => '喳',
+ '嗂' => '嗂',
+ '圖' => '圖',
+ '嘆' => '嘆',
+ '圗' => '圗',
+ '噑' => '噑',
+ '噴' => '噴',
+ '切' => '切',
+ '壮' => '壮',
+ '城' => '城',
+ '埴' => '埴',
+ '堍' => '堍',
+ '型' => '型',
+ '堲' => '堲',
+ '報' => '報',
+ '墬' => '墬',
+ '𡓤' => '𡓤',
+ '売' => '売',
+ '壷' => '壷',
+ '夆' => '夆',
+ '多' => '多',
+ '夢' => '夢',
+ '奢' => '奢',
+ '𡚨' => '𡚨',
+ '𡛪' => '𡛪',
+ '姬' => '姬',
+ '娛' => '娛',
+ '娧' => '娧',
+ '姘' => '姘',
+ '婦' => '婦',
+ '㛮' => '㛮',
+ '㛼' => '㛼',
+ '嬈' => '嬈',
+ '嬾' => '嬾',
+ '嬾' => '嬾',
+ '𡧈' => '𡧈',
+ '寃' => '寃',
+ '寘' => '寘',
+ '寧' => '寧',
+ '寳' => '寳',
+ '𡬘' => '𡬘',
+ '寿' => '寿',
+ '将' => '将',
+ '当' => '当',
+ '尢' => '尢',
+ '㞁' => '㞁',
+ '屠' => '屠',
+ '屮' => '屮',
+ '峀' => '峀',
+ '岍' => '岍',
+ '𡷤' => '𡷤',
+ '嵃' => '嵃',
+ '𡷦' => '𡷦',
+ '嵮' => '嵮',
+ '嵫' => '嵫',
+ '嵼' => '嵼',
+ '巡' => '巡',
+ '巢' => '巢',
+ '㠯' => '㠯',
+ '巽' => '巽',
+ '帨' => '帨',
+ '帽' => '帽',
+ '幩' => '幩',
+ '㡢' => '㡢',
+ '𢆃' => '𢆃',
+ '㡼' => '㡼',
+ '庰' => '庰',
+ '庳' => '庳',
+ '庶' => '庶',
+ '廊' => '廊',
+ '𪎒' => '𪎒',
+ '廾' => '廾',
+ '𢌱' => '𢌱',
+ '𢌱' => '𢌱',
+ '舁' => '舁',
+ '弢' => '弢',
+ '弢' => '弢',
+ '㣇' => '㣇',
+ '𣊸' => '𣊸',
+ '𦇚' => '𦇚',
+ '形' => '形',
+ '彫' => '彫',
+ '㣣' => '㣣',
+ '徚' => '徚',
+ '忍' => '忍',
+ '志' => '志',
+ '忹' => '忹',
+ '悁' => '悁',
+ '㤺' => '㤺',
+ '㤜' => '㤜',
+ '悔' => '悔',
+ '𢛔' => '𢛔',
+ '惇' => '惇',
+ '慈' => '慈',
+ '慌' => '慌',
+ '慎' => '慎',
+ '慌' => '慌',
+ '慺' => '慺',
+ '憎' => '憎',
+ '憲' => '憲',
+ '憤' => '憤',
+ '憯' => '憯',
+ '懞' => '懞',
+ '懲' => '懲',
+ '懶' => '懶',
+ '成' => '成',
+ '戛' => '戛',
+ '扝' => '扝',
+ '抱' => '抱',
+ '拔' => '拔',
+ '捐' => '捐',
+ '𢬌' => '𢬌',
+ '挽' => '挽',
+ '拼' => '拼',
+ '捨' => '捨',
+ '掃' => '掃',
+ '揤' => '揤',
+ '𢯱' => '𢯱',
+ '搢' => '搢',
+ '揅' => '揅',
+ '掩' => '掩',
+ '㨮' => '㨮',
+ '摩' => '摩',
+ '摾' => '摾',
+ '撝' => '撝',
+ '摷' => '摷',
+ '㩬' => '㩬',
+ '敏' => '敏',
+ '敬' => '敬',
+ '𣀊' => '𣀊',
+ '旣' => '旣',
+ '書' => '書',
+ '晉' => '晉',
+ '㬙' => '㬙',
+ '暑' => '暑',
+ '㬈' => '㬈',
+ '㫤' => '㫤',
+ '冒' => '冒',
+ '冕' => '冕',
+ '最' => '最',
+ '暜' => '暜',
+ '肭' => '肭',
+ '䏙' => '䏙',
+ '朗' => '朗',
+ '望' => '望',
+ '朡' => '朡',
+ '杞' => '杞',
+ '杓' => '杓',
+ '𣏃' => '𣏃',
+ '㭉' => '㭉',
+ '柺' => '柺',
+ '枅' => '枅',
+ '桒' => '桒',
+ '梅' => '梅',
+ '𣑭' => '𣑭',
+ '梎' => '梎',
+ '栟' => '栟',
+ '椔' => '椔',
+ '㮝' => '㮝',
+ '楂' => '楂',
+ '榣' => '榣',
+ '槪' => '槪',
+ '檨' => '檨',
+ '𣚣' => '𣚣',
+ '櫛' => '櫛',
+ '㰘' => '㰘',
+ '次' => '次',
+ '𣢧' => '𣢧',
+ '歔' => '歔',
+ '㱎' => '㱎',
+ '歲' => '歲',
+ '殟' => '殟',
+ '殺' => '殺',
+ '殻' => '殻',
+ '𣪍' => '𣪍',
+ '𡴋' => '𡴋',
+ '𣫺' => '𣫺',
+ '汎' => '汎',
+ '𣲼' => '𣲼',
+ '沿' => '沿',
+ '泍' => '泍',
+ '汧' => '汧',
+ '洖' => '洖',
+ '派' => '派',
+ '海' => '海',
+ '流' => '流',
+ '浩' => '浩',
+ '浸' => '浸',
+ '涅' => '涅',
+ '𣴞' => '𣴞',
+ '洴' => '洴',
+ '港' => '港',
+ '湮' => '湮',
+ '㴳' => '㴳',
+ '滋' => '滋',
+ '滇' => '滇',
+ '𣻑' => '𣻑',
+ '淹' => '淹',
+ '潮' => '潮',
+ '𣽞' => '𣽞',
+ '𣾎' => '𣾎',
+ '濆' => '濆',
+ '瀹' => '瀹',
+ '瀞' => '瀞',
+ '瀛' => '瀛',
+ '㶖' => '㶖',
+ '灊' => '灊',
+ '災' => '災',
+ '灷' => '灷',
+ '炭' => '炭',
+ '𠔥' => '𠔥',
+ '煅' => '煅',
+ '𤉣' => '𤉣',
+ '熜' => '熜',
+ '𤎫' => '𤎫',
+ '爨' => '爨',
+ '爵' => '爵',
+ '牐' => '牐',
+ '𤘈' => '𤘈',
+ '犀' => '犀',
+ '犕' => '犕',
+ '𤜵' => '𤜵',
+ '𤠔' => '𤠔',
+ '獺' => '獺',
+ '王' => '王',
+ '㺬' => '㺬',
+ '玥' => '玥',
+ '㺸' => '㺸',
+ '㺸' => '㺸',
+ '瑇' => '瑇',
+ '瑜' => '瑜',
+ '瑱' => '瑱',
+ '璅' => '璅',
+ '瓊' => '瓊',
+ '㼛' => '㼛',
+ '甤' => '甤',
+ '𤰶' => '𤰶',
+ '甾' => '甾',
+ '𤲒' => '𤲒',
+ '異' => '異',
+ '𢆟' => '𢆟',
+ '瘐' => '瘐',
+ '𤾡' => '𤾡',
+ '𤾸' => '𤾸',
+ '𥁄' => '𥁄',
+ '㿼' => '㿼',
+ '䀈' => '䀈',
+ '直' => '直',
+ '𥃳' => '𥃳',
+ '𥃲' => '𥃲',
+ '𥄙' => '𥄙',
+ '𥄳' => '𥄳',
+ '眞' => '眞',
+ '真' => '真',
+ '真' => '真',
+ '睊' => '睊',
+ '䀹' => '䀹',
+ '瞋' => '瞋',
+ '䁆' => '䁆',
+ '䂖' => '䂖',
+ '𥐝' => '𥐝',
+ '硎' => '硎',
+ '碌' => '碌',
+ '磌' => '磌',
+ '䃣' => '䃣',
+ '𥘦' => '𥘦',
+ '祖' => '祖',
+ '𥚚' => '𥚚',
+ '𥛅' => '𥛅',
+ '福' => '福',
+ '秫' => '秫',
+ '䄯' => '䄯',
+ '穀' => '穀',
+ '穊' => '穊',
+ '穏' => '穏',
+ '𥥼' => '𥥼',
+ '𥪧' => '𥪧',
+ '𥪧' => '𥪧',
+ '竮' => '竮',
+ '䈂' => '䈂',
+ '𥮫' => '𥮫',
+ '篆' => '篆',
+ '築' => '築',
+ '䈧' => '䈧',
+ '𥲀' => '𥲀',
+ '糒' => '糒',
+ '䊠' => '䊠',
+ '糨' => '糨',
+ '糣' => '糣',
+ '紀' => '紀',
+ '𥾆' => '𥾆',
+ '絣' => '絣',
+ '䌁' => '䌁',
+ '緇' => '緇',
+ '縂' => '縂',
+ '繅' => '繅',
+ '䌴' => '䌴',
+ '𦈨' => '𦈨',
+ '𦉇' => '𦉇',
+ '䍙' => '䍙',
+ '𦋙' => '𦋙',
+ '罺' => '罺',
+ '𦌾' => '𦌾',
+ '羕' => '羕',
+ '翺' => '翺',
+ '者' => '者',
+ '𦓚' => '𦓚',
+ '𦔣' => '𦔣',
+ '聠' => '聠',
+ '𦖨' => '𦖨',
+ '聰' => '聰',
+ '𣍟' => '𣍟',
+ '䏕' => '䏕',
+ '育' => '育',
+ '脃' => '脃',
+ '䐋' => '䐋',
+ '脾' => '脾',
+ '媵' => '媵',
+ '𦞧' => '𦞧',
+ '𦞵' => '𦞵',
+ '𣎓' => '𣎓',
+ '𣎜' => '𣎜',
+ '舁' => '舁',
+ '舄' => '舄',
+ '辞' => '辞',
+ '䑫' => '䑫',
+ '芑' => '芑',
+ '芋' => '芋',
+ '芝' => '芝',
+ '劳' => '劳',
+ '花' => '花',
+ '芳' => '芳',
+ '芽' => '芽',
+ '苦' => '苦',
+ '𦬼' => '𦬼',
+ '若' => '若',
+ '茝' => '茝',
+ '荣' => '荣',
+ '莭' => '莭',
+ '茣' => '茣',
+ '莽' => '莽',
+ '菧' => '菧',
+ '著' => '著',
+ '荓' => '荓',
+ '菊' => '菊',
+ '菌' => '菌',
+ '菜' => '菜',
+ '𦰶' => '𦰶',
+ '𦵫' => '𦵫',
+ '𦳕' => '𦳕',
+ '䔫' => '䔫',
+ '蓱' => '蓱',
+ '蓳' => '蓳',
+ '蔖' => '蔖',
+ '𧏊' => '𧏊',
+ '蕤' => '蕤',
+ '𦼬' => '𦼬',
+ '䕝' => '䕝',
+ '䕡' => '䕡',
+ '𦾱' => '𦾱',
+ '𧃒' => '𧃒',
+ '䕫' => '䕫',
+ '虐' => '虐',
+ '虜' => '虜',
+ '虧' => '虧',
+ '虩' => '虩',
+ '蚩' => '蚩',
+ '蚈' => '蚈',
+ '蜎' => '蜎',
+ '蛢' => '蛢',
+ '蝹' => '蝹',
+ '蜨' => '蜨',
+ '蝫' => '蝫',
+ '螆' => '螆',
+ '䗗' => '䗗',
+ '蟡' => '蟡',
+ '蠁' => '蠁',
+ '䗹' => '䗹',
+ '衠' => '衠',
+ '衣' => '衣',
+ '𧙧' => '𧙧',
+ '裗' => '裗',
+ '裞' => '裞',
+ '䘵' => '䘵',
+ '裺' => '裺',
+ '㒻' => '㒻',
+ '𧢮' => '𧢮',
+ '𧥦' => '𧥦',
+ '䚾' => '䚾',
+ '䛇' => '䛇',
+ '誠' => '誠',
+ '諭' => '諭',
+ '變' => '變',
+ '豕' => '豕',
+ '𧲨' => '𧲨',
+ '貫' => '貫',
+ '賁' => '賁',
+ '贛' => '贛',
+ '起' => '起',
+ '𧼯' => '𧼯',
+ '𠠄' => '𠠄',
+ '跋' => '跋',
+ '趼' => '趼',
+ '跰' => '跰',
+ '𠣞' => '𠣞',
+ '軔' => '軔',
+ '輸' => '輸',
+ '𨗒' => '𨗒',
+ '𨗭' => '𨗭',
+ '邔' => '邔',
+ '郱' => '郱',
+ '鄑' => '鄑',
+ '𨜮' => '𨜮',
+ '鄛' => '鄛',
+ '鈸' => '鈸',
+ '鋗' => '鋗',
+ '鋘' => '鋘',
+ '鉼' => '鉼',
+ '鏹' => '鏹',
+ '鐕' => '鐕',
+ '𨯺' => '𨯺',
+ '開' => '開',
+ '䦕' => '䦕',
+ '閷' => '閷',
+ '𨵷' => '𨵷',
+ '䧦' => '䧦',
+ '雃' => '雃',
+ '嶲' => '嶲',
+ '霣' => '霣',
+ '𩅅' => '𩅅',
+ '𩈚' => '𩈚',
+ '䩮' => '䩮',
+ '䩶' => '䩶',
+ '韠' => '韠',
+ '𩐊' => '𩐊',
+ '䪲' => '䪲',
+ '𩒖' => '𩒖',
+ '頋' => '頋',
+ '頋' => '頋',
+ '頩' => '頩',
+ '𩖶' => '𩖶',
+ '飢' => '飢',
+ '䬳' => '䬳',
+ '餩' => '餩',
+ '馧' => '馧',
+ '駂' => '駂',
+ '駾' => '駾',
+ '䯎' => '䯎',
+ '𩬰' => '𩬰',
+ '鬒' => '鬒',
+ '鱀' => '鱀',
+ '鳽' => '鳽',
+ '䳎' => '䳎',
+ '䳭' => '䳭',
+ '鵧' => '鵧',
+ '𪃎' => '𪃎',
+ '䳸' => '䳸',
+ '𪄅' => '𪄅',
+ '𪈎' => '𪈎',
+ '𪊑' => '𪊑',
+ '麻' => '麻',
+ '䵖' => '䵖',
+ '黹' => '黹',
+ '黾' => '黾',
+ '鼅' => '鼅',
+ '鼏' => '鼏',
+ '鼖' => '鼖',
+ '鼻' => '鼻',
+ '𪘀' => '𪘀',
+);
diff --git a/Server/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php b/Server/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php
new file mode 100755
index 000000000..ec90f36eb
--- /dev/null
+++ b/Server/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php
@@ -0,0 +1,876 @@
+ 230,
+ '́' => 230,
+ '̂' => 230,
+ '̃' => 230,
+ '̄' => 230,
+ '̅' => 230,
+ '̆' => 230,
+ '̇' => 230,
+ '̈' => 230,
+ '̉' => 230,
+ '̊' => 230,
+ '̋' => 230,
+ '̌' => 230,
+ '̍' => 230,
+ '̎' => 230,
+ '̏' => 230,
+ '̐' => 230,
+ '̑' => 230,
+ '̒' => 230,
+ '̓' => 230,
+ '̔' => 230,
+ '̕' => 232,
+ '̖' => 220,
+ '̗' => 220,
+ '̘' => 220,
+ '̙' => 220,
+ '̚' => 232,
+ '̛' => 216,
+ '̜' => 220,
+ '̝' => 220,
+ '̞' => 220,
+ '̟' => 220,
+ '̠' => 220,
+ '̡' => 202,
+ '̢' => 202,
+ '̣' => 220,
+ '̤' => 220,
+ '̥' => 220,
+ '̦' => 220,
+ '̧' => 202,
+ '̨' => 202,
+ '̩' => 220,
+ '̪' => 220,
+ '̫' => 220,
+ '̬' => 220,
+ '̭' => 220,
+ '̮' => 220,
+ '̯' => 220,
+ '̰' => 220,
+ '̱' => 220,
+ '̲' => 220,
+ '̳' => 220,
+ '̴' => 1,
+ '̵' => 1,
+ '̶' => 1,
+ '̷' => 1,
+ '̸' => 1,
+ '̹' => 220,
+ '̺' => 220,
+ '̻' => 220,
+ '̼' => 220,
+ '̽' => 230,
+ '̾' => 230,
+ '̿' => 230,
+ '̀' => 230,
+ '́' => 230,
+ '͂' => 230,
+ '̓' => 230,
+ '̈́' => 230,
+ 'ͅ' => 240,
+ '͆' => 230,
+ '͇' => 220,
+ '͈' => 220,
+ '͉' => 220,
+ '͊' => 230,
+ '͋' => 230,
+ '͌' => 230,
+ '͍' => 220,
+ '͎' => 220,
+ '͐' => 230,
+ '͑' => 230,
+ '͒' => 230,
+ '͓' => 220,
+ '͔' => 220,
+ '͕' => 220,
+ '͖' => 220,
+ '͗' => 230,
+ '͘' => 232,
+ '͙' => 220,
+ '͚' => 220,
+ '͛' => 230,
+ '͜' => 233,
+ '͝' => 234,
+ '͞' => 234,
+ '͟' => 233,
+ '͠' => 234,
+ '͡' => 234,
+ '͢' => 233,
+ 'ͣ' => 230,
+ 'ͤ' => 230,
+ 'ͥ' => 230,
+ 'ͦ' => 230,
+ 'ͧ' => 230,
+ 'ͨ' => 230,
+ 'ͩ' => 230,
+ 'ͪ' => 230,
+ 'ͫ' => 230,
+ 'ͬ' => 230,
+ 'ͭ' => 230,
+ 'ͮ' => 230,
+ 'ͯ' => 230,
+ '҃' => 230,
+ '҄' => 230,
+ '҅' => 230,
+ '҆' => 230,
+ '҇' => 230,
+ '֑' => 220,
+ '֒' => 230,
+ '֓' => 230,
+ '֔' => 230,
+ '֕' => 230,
+ '֖' => 220,
+ '֗' => 230,
+ '֘' => 230,
+ '֙' => 230,
+ '֚' => 222,
+ '֛' => 220,
+ '֜' => 230,
+ '֝' => 230,
+ '֞' => 230,
+ '֟' => 230,
+ '֠' => 230,
+ '֡' => 230,
+ '֢' => 220,
+ '֣' => 220,
+ '֤' => 220,
+ '֥' => 220,
+ '֦' => 220,
+ '֧' => 220,
+ '֨' => 230,
+ '֩' => 230,
+ '֪' => 220,
+ '֫' => 230,
+ '֬' => 230,
+ '֭' => 222,
+ '֮' => 228,
+ '֯' => 230,
+ 'ְ' => 10,
+ 'ֱ' => 11,
+ 'ֲ' => 12,
+ 'ֳ' => 13,
+ 'ִ' => 14,
+ 'ֵ' => 15,
+ 'ֶ' => 16,
+ 'ַ' => 17,
+ 'ָ' => 18,
+ 'ֹ' => 19,
+ 'ֺ' => 19,
+ 'ֻ' => 20,
+ 'ּ' => 21,
+ 'ֽ' => 22,
+ 'ֿ' => 23,
+ 'ׁ' => 24,
+ 'ׂ' => 25,
+ 'ׄ' => 230,
+ 'ׅ' => 220,
+ 'ׇ' => 18,
+ 'ؐ' => 230,
+ 'ؑ' => 230,
+ 'ؒ' => 230,
+ 'ؓ' => 230,
+ 'ؔ' => 230,
+ 'ؕ' => 230,
+ 'ؖ' => 230,
+ 'ؗ' => 230,
+ 'ؘ' => 30,
+ 'ؙ' => 31,
+ 'ؚ' => 32,
+ 'ً' => 27,
+ 'ٌ' => 28,
+ 'ٍ' => 29,
+ 'َ' => 30,
+ 'ُ' => 31,
+ 'ِ' => 32,
+ 'ّ' => 33,
+ 'ْ' => 34,
+ 'ٓ' => 230,
+ 'ٔ' => 230,
+ 'ٕ' => 220,
+ 'ٖ' => 220,
+ 'ٗ' => 230,
+ '٘' => 230,
+ 'ٙ' => 230,
+ 'ٚ' => 230,
+ 'ٛ' => 230,
+ 'ٜ' => 220,
+ 'ٝ' => 230,
+ 'ٞ' => 230,
+ 'ٟ' => 220,
+ 'ٰ' => 35,
+ 'ۖ' => 230,
+ 'ۗ' => 230,
+ 'ۘ' => 230,
+ 'ۙ' => 230,
+ 'ۚ' => 230,
+ 'ۛ' => 230,
+ 'ۜ' => 230,
+ '۟' => 230,
+ '۠' => 230,
+ 'ۡ' => 230,
+ 'ۢ' => 230,
+ 'ۣ' => 220,
+ 'ۤ' => 230,
+ 'ۧ' => 230,
+ 'ۨ' => 230,
+ '۪' => 220,
+ '۫' => 230,
+ '۬' => 230,
+ 'ۭ' => 220,
+ 'ܑ' => 36,
+ 'ܰ' => 230,
+ 'ܱ' => 220,
+ 'ܲ' => 230,
+ 'ܳ' => 230,
+ 'ܴ' => 220,
+ 'ܵ' => 230,
+ 'ܶ' => 230,
+ 'ܷ' => 220,
+ 'ܸ' => 220,
+ 'ܹ' => 220,
+ 'ܺ' => 230,
+ 'ܻ' => 220,
+ 'ܼ' => 220,
+ 'ܽ' => 230,
+ 'ܾ' => 220,
+ 'ܿ' => 230,
+ '݀' => 230,
+ '݁' => 230,
+ '݂' => 220,
+ '݃' => 230,
+ '݄' => 220,
+ '݅' => 230,
+ '݆' => 220,
+ '݇' => 230,
+ '݈' => 220,
+ '݉' => 230,
+ '݊' => 230,
+ '߫' => 230,
+ '߬' => 230,
+ '߭' => 230,
+ '߮' => 230,
+ '߯' => 230,
+ '߰' => 230,
+ '߱' => 230,
+ '߲' => 220,
+ '߳' => 230,
+ '߽' => 220,
+ 'ࠖ' => 230,
+ 'ࠗ' => 230,
+ '࠘' => 230,
+ '࠙' => 230,
+ 'ࠛ' => 230,
+ 'ࠜ' => 230,
+ 'ࠝ' => 230,
+ 'ࠞ' => 230,
+ 'ࠟ' => 230,
+ 'ࠠ' => 230,
+ 'ࠡ' => 230,
+ 'ࠢ' => 230,
+ 'ࠣ' => 230,
+ 'ࠥ' => 230,
+ 'ࠦ' => 230,
+ 'ࠧ' => 230,
+ 'ࠩ' => 230,
+ 'ࠪ' => 230,
+ 'ࠫ' => 230,
+ 'ࠬ' => 230,
+ '࠭' => 230,
+ '࡙' => 220,
+ '࡚' => 220,
+ '࡛' => 220,
+ '࣓' => 220,
+ 'ࣔ' => 230,
+ 'ࣕ' => 230,
+ 'ࣖ' => 230,
+ 'ࣗ' => 230,
+ 'ࣘ' => 230,
+ 'ࣙ' => 230,
+ 'ࣚ' => 230,
+ 'ࣛ' => 230,
+ 'ࣜ' => 230,
+ 'ࣝ' => 230,
+ 'ࣞ' => 230,
+ 'ࣟ' => 230,
+ '࣠' => 230,
+ '࣡' => 230,
+ 'ࣣ' => 220,
+ 'ࣤ' => 230,
+ 'ࣥ' => 230,
+ 'ࣦ' => 220,
+ 'ࣧ' => 230,
+ 'ࣨ' => 230,
+ 'ࣩ' => 220,
+ '࣪' => 230,
+ '࣫' => 230,
+ '࣬' => 230,
+ '࣭' => 220,
+ '࣮' => 220,
+ '࣯' => 220,
+ 'ࣰ' => 27,
+ 'ࣱ' => 28,
+ 'ࣲ' => 29,
+ 'ࣳ' => 230,
+ 'ࣴ' => 230,
+ 'ࣵ' => 230,
+ 'ࣶ' => 220,
+ 'ࣷ' => 230,
+ 'ࣸ' => 230,
+ 'ࣹ' => 220,
+ 'ࣺ' => 220,
+ 'ࣻ' => 230,
+ 'ࣼ' => 230,
+ 'ࣽ' => 230,
+ 'ࣾ' => 230,
+ 'ࣿ' => 230,
+ '़' => 7,
+ '्' => 9,
+ '॑' => 230,
+ '॒' => 220,
+ '॓' => 230,
+ '॔' => 230,
+ '়' => 7,
+ '্' => 9,
+ '৾' => 230,
+ '਼' => 7,
+ '੍' => 9,
+ '઼' => 7,
+ '્' => 9,
+ '଼' => 7,
+ '୍' => 9,
+ '்' => 9,
+ '్' => 9,
+ 'ౕ' => 84,
+ 'ౖ' => 91,
+ '಼' => 7,
+ '್' => 9,
+ '഻' => 9,
+ '഼' => 9,
+ '്' => 9,
+ '්' => 9,
+ 'ุ' => 103,
+ 'ู' => 103,
+ 'ฺ' => 9,
+ '่' => 107,
+ '้' => 107,
+ '๊' => 107,
+ '๋' => 107,
+ 'ຸ' => 118,
+ 'ູ' => 118,
+ '຺' => 9,
+ '່' => 122,
+ '້' => 122,
+ '໊' => 122,
+ '໋' => 122,
+ '༘' => 220,
+ '༙' => 220,
+ '༵' => 220,
+ '༷' => 220,
+ '༹' => 216,
+ 'ཱ' => 129,
+ 'ི' => 130,
+ 'ུ' => 132,
+ 'ེ' => 130,
+ 'ཻ' => 130,
+ 'ོ' => 130,
+ 'ཽ' => 130,
+ 'ྀ' => 130,
+ 'ྂ' => 230,
+ 'ྃ' => 230,
+ '྄' => 9,
+ '྆' => 230,
+ '྇' => 230,
+ '࿆' => 220,
+ '့' => 7,
+ '္' => 9,
+ '်' => 9,
+ 'ႍ' => 220,
+ '፝' => 230,
+ '፞' => 230,
+ '፟' => 230,
+ '᜔' => 9,
+ '᜴' => 9,
+ '្' => 9,
+ '៝' => 230,
+ 'ᢩ' => 228,
+ '᤹' => 222,
+ '᤺' => 230,
+ '᤻' => 220,
+ 'ᨗ' => 230,
+ 'ᨘ' => 220,
+ '᩠' => 9,
+ '᩵' => 230,
+ '᩶' => 230,
+ '᩷' => 230,
+ '᩸' => 230,
+ '᩹' => 230,
+ '᩺' => 230,
+ '᩻' => 230,
+ '᩼' => 230,
+ '᩿' => 220,
+ '᪰' => 230,
+ '᪱' => 230,
+ '᪲' => 230,
+ '᪳' => 230,
+ '᪴' => 230,
+ '᪵' => 220,
+ '᪶' => 220,
+ '᪷' => 220,
+ '᪸' => 220,
+ '᪹' => 220,
+ '᪺' => 220,
+ '᪻' => 230,
+ '᪼' => 230,
+ '᪽' => 220,
+ 'ᪿ' => 220,
+ 'ᫀ' => 220,
+ '᬴' => 7,
+ '᭄' => 9,
+ '᭫' => 230,
+ '᭬' => 220,
+ '᭭' => 230,
+ '᭮' => 230,
+ '᭯' => 230,
+ '᭰' => 230,
+ '᭱' => 230,
+ '᭲' => 230,
+ '᭳' => 230,
+ '᮪' => 9,
+ '᮫' => 9,
+ '᯦' => 7,
+ '᯲' => 9,
+ '᯳' => 9,
+ '᰷' => 7,
+ '᳐' => 230,
+ '᳑' => 230,
+ '᳒' => 230,
+ '᳔' => 1,
+ '᳕' => 220,
+ '᳖' => 220,
+ '᳗' => 220,
+ '᳘' => 220,
+ '᳙' => 220,
+ '᳚' => 230,
+ '᳛' => 230,
+ '᳜' => 220,
+ '᳝' => 220,
+ '᳞' => 220,
+ '᳟' => 220,
+ '᳠' => 230,
+ '᳢' => 1,
+ '᳣' => 1,
+ '᳤' => 1,
+ '᳥' => 1,
+ '᳦' => 1,
+ '᳧' => 1,
+ '᳨' => 1,
+ '᳭' => 220,
+ '᳴' => 230,
+ '᳸' => 230,
+ '᳹' => 230,
+ '᷀' => 230,
+ '᷁' => 230,
+ '᷂' => 220,
+ '᷃' => 230,
+ '᷄' => 230,
+ '᷅' => 230,
+ '᷆' => 230,
+ '᷇' => 230,
+ '᷈' => 230,
+ '᷉' => 230,
+ '᷊' => 220,
+ '᷋' => 230,
+ '᷌' => 230,
+ '᷍' => 234,
+ '᷎' => 214,
+ '᷏' => 220,
+ '᷐' => 202,
+ '᷑' => 230,
+ '᷒' => 230,
+ 'ᷓ' => 230,
+ 'ᷔ' => 230,
+ 'ᷕ' => 230,
+ 'ᷖ' => 230,
+ 'ᷗ' => 230,
+ 'ᷘ' => 230,
+ 'ᷙ' => 230,
+ 'ᷚ' => 230,
+ 'ᷛ' => 230,
+ 'ᷜ' => 230,
+ 'ᷝ' => 230,
+ 'ᷞ' => 230,
+ 'ᷟ' => 230,
+ 'ᷠ' => 230,
+ 'ᷡ' => 230,
+ 'ᷢ' => 230,
+ 'ᷣ' => 230,
+ 'ᷤ' => 230,
+ 'ᷥ' => 230,
+ 'ᷦ' => 230,
+ 'ᷧ' => 230,
+ 'ᷨ' => 230,
+ 'ᷩ' => 230,
+ 'ᷪ' => 230,
+ 'ᷫ' => 230,
+ 'ᷬ' => 230,
+ 'ᷭ' => 230,
+ 'ᷮ' => 230,
+ 'ᷯ' => 230,
+ 'ᷰ' => 230,
+ 'ᷱ' => 230,
+ 'ᷲ' => 230,
+ 'ᷳ' => 230,
+ 'ᷴ' => 230,
+ '᷵' => 230,
+ '᷶' => 232,
+ '᷷' => 228,
+ '᷸' => 228,
+ '᷹' => 220,
+ '᷻' => 230,
+ '᷼' => 233,
+ '᷽' => 220,
+ '᷾' => 230,
+ '᷿' => 220,
+ '⃐' => 230,
+ '⃑' => 230,
+ '⃒' => 1,
+ '⃓' => 1,
+ '⃔' => 230,
+ '⃕' => 230,
+ '⃖' => 230,
+ '⃗' => 230,
+ '⃘' => 1,
+ '⃙' => 1,
+ '⃚' => 1,
+ '⃛' => 230,
+ '⃜' => 230,
+ '⃡' => 230,
+ '⃥' => 1,
+ '⃦' => 1,
+ '⃧' => 230,
+ '⃨' => 220,
+ '⃩' => 230,
+ '⃪' => 1,
+ '⃫' => 1,
+ '⃬' => 220,
+ '⃭' => 220,
+ '⃮' => 220,
+ '⃯' => 220,
+ '⃰' => 230,
+ '⳯' => 230,
+ '⳰' => 230,
+ '⳱' => 230,
+ '⵿' => 9,
+ 'ⷠ' => 230,
+ 'ⷡ' => 230,
+ 'ⷢ' => 230,
+ 'ⷣ' => 230,
+ 'ⷤ' => 230,
+ 'ⷥ' => 230,
+ 'ⷦ' => 230,
+ 'ⷧ' => 230,
+ 'ⷨ' => 230,
+ 'ⷩ' => 230,
+ 'ⷪ' => 230,
+ 'ⷫ' => 230,
+ 'ⷬ' => 230,
+ 'ⷭ' => 230,
+ 'ⷮ' => 230,
+ 'ⷯ' => 230,
+ 'ⷰ' => 230,
+ 'ⷱ' => 230,
+ 'ⷲ' => 230,
+ 'ⷳ' => 230,
+ 'ⷴ' => 230,
+ 'ⷵ' => 230,
+ 'ⷶ' => 230,
+ 'ⷷ' => 230,
+ 'ⷸ' => 230,
+ 'ⷹ' => 230,
+ 'ⷺ' => 230,
+ 'ⷻ' => 230,
+ 'ⷼ' => 230,
+ 'ⷽ' => 230,
+ 'ⷾ' => 230,
+ 'ⷿ' => 230,
+ '〪' => 218,
+ '〫' => 228,
+ '〬' => 232,
+ '〭' => 222,
+ '〮' => 224,
+ '〯' => 224,
+ '゙' => 8,
+ '゚' => 8,
+ '꙯' => 230,
+ 'ꙴ' => 230,
+ 'ꙵ' => 230,
+ 'ꙶ' => 230,
+ 'ꙷ' => 230,
+ 'ꙸ' => 230,
+ 'ꙹ' => 230,
+ 'ꙺ' => 230,
+ 'ꙻ' => 230,
+ '꙼' => 230,
+ '꙽' => 230,
+ 'ꚞ' => 230,
+ 'ꚟ' => 230,
+ '꛰' => 230,
+ '꛱' => 230,
+ '꠆' => 9,
+ '꠬' => 9,
+ '꣄' => 9,
+ '꣠' => 230,
+ '꣡' => 230,
+ '꣢' => 230,
+ '꣣' => 230,
+ '꣤' => 230,
+ '꣥' => 230,
+ '꣦' => 230,
+ '꣧' => 230,
+ '꣨' => 230,
+ '꣩' => 230,
+ '꣪' => 230,
+ '꣫' => 230,
+ '꣬' => 230,
+ '꣭' => 230,
+ '꣮' => 230,
+ '꣯' => 230,
+ '꣰' => 230,
+ '꣱' => 230,
+ '꤫' => 220,
+ '꤬' => 220,
+ '꤭' => 220,
+ '꥓' => 9,
+ '꦳' => 7,
+ '꧀' => 9,
+ 'ꪰ' => 230,
+ 'ꪲ' => 230,
+ 'ꪳ' => 230,
+ 'ꪴ' => 220,
+ 'ꪷ' => 230,
+ 'ꪸ' => 230,
+ 'ꪾ' => 230,
+ '꪿' => 230,
+ '꫁' => 230,
+ '꫶' => 9,
+ '꯭' => 9,
+ 'ﬞ' => 26,
+ '︠' => 230,
+ '︡' => 230,
+ '︢' => 230,
+ '︣' => 230,
+ '︤' => 230,
+ '︥' => 230,
+ '︦' => 230,
+ '︧' => 220,
+ '︨' => 220,
+ '︩' => 220,
+ '︪' => 220,
+ '︫' => 220,
+ '︬' => 220,
+ '︭' => 220,
+ '︮' => 230,
+ '︯' => 230,
+ '𐇽' => 220,
+ '𐋠' => 220,
+ '𐍶' => 230,
+ '𐍷' => 230,
+ '𐍸' => 230,
+ '𐍹' => 230,
+ '𐍺' => 230,
+ '𐨍' => 220,
+ '𐨏' => 230,
+ '𐨸' => 230,
+ '𐨹' => 1,
+ '𐨺' => 220,
+ '𐨿' => 9,
+ '𐫥' => 230,
+ '𐫦' => 220,
+ '𐴤' => 230,
+ '𐴥' => 230,
+ '𐴦' => 230,
+ '𐴧' => 230,
+ '𐺫' => 230,
+ '𐺬' => 230,
+ '𐽆' => 220,
+ '𐽇' => 220,
+ '𐽈' => 230,
+ '𐽉' => 230,
+ '𐽊' => 230,
+ '𐽋' => 220,
+ '𐽌' => 230,
+ '𐽍' => 220,
+ '𐽎' => 220,
+ '𐽏' => 220,
+ '𐽐' => 220,
+ '𑁆' => 9,
+ '𑁿' => 9,
+ '𑂹' => 9,
+ '𑂺' => 7,
+ '𑄀' => 230,
+ '𑄁' => 230,
+ '𑄂' => 230,
+ '𑄳' => 9,
+ '𑄴' => 9,
+ '𑅳' => 7,
+ '𑇀' => 9,
+ '𑇊' => 7,
+ '𑈵' => 9,
+ '𑈶' => 7,
+ '𑋩' => 7,
+ '𑋪' => 9,
+ '𑌻' => 7,
+ '𑌼' => 7,
+ '𑍍' => 9,
+ '𑍦' => 230,
+ '𑍧' => 230,
+ '𑍨' => 230,
+ '𑍩' => 230,
+ '𑍪' => 230,
+ '𑍫' => 230,
+ '𑍬' => 230,
+ '𑍰' => 230,
+ '𑍱' => 230,
+ '𑍲' => 230,
+ '𑍳' => 230,
+ '𑍴' => 230,
+ '𑑂' => 9,
+ '𑑆' => 7,
+ '𑑞' => 230,
+ '𑓂' => 9,
+ '𑓃' => 7,
+ '𑖿' => 9,
+ '𑗀' => 7,
+ '𑘿' => 9,
+ '𑚶' => 9,
+ '𑚷' => 7,
+ '𑜫' => 9,
+ '𑠹' => 9,
+ '𑠺' => 7,
+ '𑤽' => 9,
+ '𑤾' => 9,
+ '𑥃' => 7,
+ '𑧠' => 9,
+ '𑨴' => 9,
+ '𑩇' => 9,
+ '𑪙' => 9,
+ '𑰿' => 9,
+ '𑵂' => 7,
+ '𑵄' => 9,
+ '𑵅' => 9,
+ '𑶗' => 9,
+ '𖫰' => 1,
+ '𖫱' => 1,
+ '𖫲' => 1,
+ '𖫳' => 1,
+ '𖫴' => 1,
+ '𖬰' => 230,
+ '𖬱' => 230,
+ '𖬲' => 230,
+ '𖬳' => 230,
+ '𖬴' => 230,
+ '𖬵' => 230,
+ '𖬶' => 230,
+ '𖿰' => 6,
+ '𖿱' => 6,
+ '𛲞' => 1,
+ '𝅥' => 216,
+ '𝅦' => 216,
+ '𝅧' => 1,
+ '𝅨' => 1,
+ '𝅩' => 1,
+ '𝅭' => 226,
+ '𝅮' => 216,
+ '𝅯' => 216,
+ '𝅰' => 216,
+ '𝅱' => 216,
+ '𝅲' => 216,
+ '𝅻' => 220,
+ '𝅼' => 220,
+ '𝅽' => 220,
+ '𝅾' => 220,
+ '𝅿' => 220,
+ '𝆀' => 220,
+ '𝆁' => 220,
+ '𝆂' => 220,
+ '𝆅' => 230,
+ '𝆆' => 230,
+ '𝆇' => 230,
+ '𝆈' => 230,
+ '𝆉' => 230,
+ '𝆊' => 220,
+ '𝆋' => 220,
+ '𝆪' => 230,
+ '𝆫' => 230,
+ '𝆬' => 230,
+ '𝆭' => 230,
+ '𝉂' => 230,
+ '𝉃' => 230,
+ '𝉄' => 230,
+ '𞀀' => 230,
+ '𞀁' => 230,
+ '𞀂' => 230,
+ '𞀃' => 230,
+ '𞀄' => 230,
+ '𞀅' => 230,
+ '𞀆' => 230,
+ '𞀈' => 230,
+ '𞀉' => 230,
+ '𞀊' => 230,
+ '𞀋' => 230,
+ '𞀌' => 230,
+ '𞀍' => 230,
+ '𞀎' => 230,
+ '𞀏' => 230,
+ '𞀐' => 230,
+ '𞀑' => 230,
+ '𞀒' => 230,
+ '𞀓' => 230,
+ '𞀔' => 230,
+ '𞀕' => 230,
+ '𞀖' => 230,
+ '𞀗' => 230,
+ '𞀘' => 230,
+ '𞀛' => 230,
+ '𞀜' => 230,
+ '𞀝' => 230,
+ '𞀞' => 230,
+ '𞀟' => 230,
+ '𞀠' => 230,
+ '𞀡' => 230,
+ '𞀣' => 230,
+ '𞀤' => 230,
+ '𞀦' => 230,
+ '𞀧' => 230,
+ '𞀨' => 230,
+ '𞀩' => 230,
+ '𞀪' => 230,
+ '𞄰' => 230,
+ '𞄱' => 230,
+ '𞄲' => 230,
+ '𞄳' => 230,
+ '𞄴' => 230,
+ '𞄵' => 230,
+ '𞄶' => 230,
+ '𞋬' => 230,
+ '𞋭' => 230,
+ '𞋮' => 230,
+ '𞋯' => 230,
+ '𞣐' => 220,
+ '𞣑' => 220,
+ '𞣒' => 220,
+ '𞣓' => 220,
+ '𞣔' => 220,
+ '𞣕' => 220,
+ '𞣖' => 220,
+ '𞥄' => 230,
+ '𞥅' => 230,
+ '𞥆' => 230,
+ '𞥇' => 230,
+ '𞥈' => 230,
+ '𞥉' => 230,
+ '𞥊' => 7,
+);
diff --git a/Server/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php b/Server/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php
new file mode 100755
index 000000000..157490289
--- /dev/null
+++ b/Server/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php
@@ -0,0 +1,3695 @@
+ ' ',
+ '¨' => ' ̈',
+ 'ª' => 'a',
+ '¯' => ' ̄',
+ '²' => '2',
+ '³' => '3',
+ '´' => ' ́',
+ 'µ' => 'μ',
+ '¸' => ' ̧',
+ '¹' => '1',
+ 'º' => 'o',
+ '¼' => '1⁄4',
+ '½' => '1⁄2',
+ '¾' => '3⁄4',
+ 'IJ' => 'IJ',
+ 'ij' => 'ij',
+ 'Ŀ' => 'L·',
+ 'ŀ' => 'l·',
+ 'ʼn' => 'ʼn',
+ 'ſ' => 's',
+ 'DŽ' => 'DŽ',
+ 'Dž' => 'Dž',
+ 'dž' => 'dž',
+ 'LJ' => 'LJ',
+ 'Lj' => 'Lj',
+ 'lj' => 'lj',
+ 'NJ' => 'NJ',
+ 'Nj' => 'Nj',
+ 'nj' => 'nj',
+ 'DZ' => 'DZ',
+ 'Dz' => 'Dz',
+ 'dz' => 'dz',
+ 'ʰ' => 'h',
+ 'ʱ' => 'ɦ',
+ 'ʲ' => 'j',
+ 'ʳ' => 'r',
+ 'ʴ' => 'ɹ',
+ 'ʵ' => 'ɻ',
+ 'ʶ' => 'ʁ',
+ 'ʷ' => 'w',
+ 'ʸ' => 'y',
+ '˘' => ' ̆',
+ '˙' => ' ̇',
+ '˚' => ' ̊',
+ '˛' => ' ̨',
+ '˜' => ' ̃',
+ '˝' => ' ̋',
+ 'ˠ' => 'ɣ',
+ 'ˡ' => 'l',
+ 'ˢ' => 's',
+ 'ˣ' => 'x',
+ 'ˤ' => 'ʕ',
+ 'ͺ' => ' ͅ',
+ '΄' => ' ́',
+ '΅' => ' ̈́',
+ 'ϐ' => 'β',
+ 'ϑ' => 'θ',
+ 'ϒ' => 'Υ',
+ 'ϓ' => 'Ύ',
+ 'ϔ' => 'Ϋ',
+ 'ϕ' => 'φ',
+ 'ϖ' => 'π',
+ 'ϰ' => 'κ',
+ 'ϱ' => 'ρ',
+ 'ϲ' => 'ς',
+ 'ϴ' => 'Θ',
+ 'ϵ' => 'ε',
+ 'Ϲ' => 'Σ',
+ 'և' => 'եւ',
+ 'ٵ' => 'اٴ',
+ 'ٶ' => 'وٴ',
+ 'ٷ' => 'ۇٴ',
+ 'ٸ' => 'يٴ',
+ 'ำ' => 'ํา',
+ 'ຳ' => 'ໍາ',
+ 'ໜ' => 'ຫນ',
+ 'ໝ' => 'ຫມ',
+ '༌' => '་',
+ 'ཷ' => 'ྲཱྀ',
+ 'ཹ' => 'ླཱྀ',
+ 'ჼ' => 'ნ',
+ 'ᴬ' => 'A',
+ 'ᴭ' => 'Æ',
+ 'ᴮ' => 'B',
+ 'ᴰ' => 'D',
+ 'ᴱ' => 'E',
+ 'ᴲ' => 'Ǝ',
+ 'ᴳ' => 'G',
+ 'ᴴ' => 'H',
+ 'ᴵ' => 'I',
+ 'ᴶ' => 'J',
+ 'ᴷ' => 'K',
+ 'ᴸ' => 'L',
+ 'ᴹ' => 'M',
+ 'ᴺ' => 'N',
+ 'ᴼ' => 'O',
+ 'ᴽ' => 'Ȣ',
+ 'ᴾ' => 'P',
+ 'ᴿ' => 'R',
+ 'ᵀ' => 'T',
+ 'ᵁ' => 'U',
+ 'ᵂ' => 'W',
+ 'ᵃ' => 'a',
+ 'ᵄ' => 'ɐ',
+ 'ᵅ' => 'ɑ',
+ 'ᵆ' => 'ᴂ',
+ 'ᵇ' => 'b',
+ 'ᵈ' => 'd',
+ 'ᵉ' => 'e',
+ 'ᵊ' => 'ə',
+ 'ᵋ' => 'ɛ',
+ 'ᵌ' => 'ɜ',
+ 'ᵍ' => 'g',
+ 'ᵏ' => 'k',
+ 'ᵐ' => 'm',
+ 'ᵑ' => 'ŋ',
+ 'ᵒ' => 'o',
+ 'ᵓ' => 'ɔ',
+ 'ᵔ' => 'ᴖ',
+ 'ᵕ' => 'ᴗ',
+ 'ᵖ' => 'p',
+ 'ᵗ' => 't',
+ 'ᵘ' => 'u',
+ 'ᵙ' => 'ᴝ',
+ 'ᵚ' => 'ɯ',
+ 'ᵛ' => 'v',
+ 'ᵜ' => 'ᴥ',
+ 'ᵝ' => 'β',
+ 'ᵞ' => 'γ',
+ 'ᵟ' => 'δ',
+ 'ᵠ' => 'φ',
+ 'ᵡ' => 'χ',
+ 'ᵢ' => 'i',
+ 'ᵣ' => 'r',
+ 'ᵤ' => 'u',
+ 'ᵥ' => 'v',
+ 'ᵦ' => 'β',
+ 'ᵧ' => 'γ',
+ 'ᵨ' => 'ρ',
+ 'ᵩ' => 'φ',
+ 'ᵪ' => 'χ',
+ 'ᵸ' => 'н',
+ 'ᶛ' => 'ɒ',
+ 'ᶜ' => 'c',
+ 'ᶝ' => 'ɕ',
+ 'ᶞ' => 'ð',
+ 'ᶟ' => 'ɜ',
+ 'ᶠ' => 'f',
+ 'ᶡ' => 'ɟ',
+ 'ᶢ' => 'ɡ',
+ 'ᶣ' => 'ɥ',
+ 'ᶤ' => 'ɨ',
+ 'ᶥ' => 'ɩ',
+ 'ᶦ' => 'ɪ',
+ 'ᶧ' => 'ᵻ',
+ 'ᶨ' => 'ʝ',
+ 'ᶩ' => 'ɭ',
+ 'ᶪ' => 'ᶅ',
+ 'ᶫ' => 'ʟ',
+ 'ᶬ' => 'ɱ',
+ 'ᶭ' => 'ɰ',
+ 'ᶮ' => 'ɲ',
+ 'ᶯ' => 'ɳ',
+ 'ᶰ' => 'ɴ',
+ 'ᶱ' => 'ɵ',
+ 'ᶲ' => 'ɸ',
+ 'ᶳ' => 'ʂ',
+ 'ᶴ' => 'ʃ',
+ 'ᶵ' => 'ƫ',
+ 'ᶶ' => 'ʉ',
+ 'ᶷ' => 'ʊ',
+ 'ᶸ' => 'ᴜ',
+ 'ᶹ' => 'ʋ',
+ 'ᶺ' => 'ʌ',
+ 'ᶻ' => 'z',
+ 'ᶼ' => 'ʐ',
+ 'ᶽ' => 'ʑ',
+ 'ᶾ' => 'ʒ',
+ 'ᶿ' => 'θ',
+ 'ẚ' => 'aʾ',
+ 'ẛ' => 'ṡ',
+ '᾽' => ' ̓',
+ '᾿' => ' ̓',
+ '῀' => ' ͂',
+ '῁' => ' ̈͂',
+ '῍' => ' ̓̀',
+ '῎' => ' ̓́',
+ '῏' => ' ̓͂',
+ '῝' => ' ̔̀',
+ '῞' => ' ̔́',
+ '῟' => ' ̔͂',
+ '῭' => ' ̈̀',
+ '΅' => ' ̈́',
+ '´' => ' ́',
+ '῾' => ' ̔',
+ ' ' => ' ',
+ ' ' => ' ',
+ ' ' => ' ',
+ ' ' => ' ',
+ ' ' => ' ',
+ ' ' => ' ',
+ ' ' => ' ',
+ ' ' => ' ',
+ ' ' => ' ',
+ ' ' => ' ',
+ ' ' => ' ',
+ '‑' => '‐',
+ '‗' => ' ̳',
+ '․' => '.',
+ '‥' => '..',
+ '…' => '...',
+ ' ' => ' ',
+ '″' => '′′',
+ '‴' => '′′′',
+ '‶' => '‵‵',
+ '‷' => '‵‵‵',
+ '‼' => '!!',
+ '‾' => ' ̅',
+ '⁇' => '??',
+ '⁈' => '?!',
+ '⁉' => '!?',
+ '⁗' => '′′′′',
+ ' ' => ' ',
+ '⁰' => '0',
+ 'ⁱ' => 'i',
+ '⁴' => '4',
+ '⁵' => '5',
+ '⁶' => '6',
+ '⁷' => '7',
+ '⁸' => '8',
+ '⁹' => '9',
+ '⁺' => '+',
+ '⁻' => '−',
+ '⁼' => '=',
+ '⁽' => '(',
+ '⁾' => ')',
+ 'ⁿ' => 'n',
+ '₀' => '0',
+ '₁' => '1',
+ '₂' => '2',
+ '₃' => '3',
+ '₄' => '4',
+ '₅' => '5',
+ '₆' => '6',
+ '₇' => '7',
+ '₈' => '8',
+ '₉' => '9',
+ '₊' => '+',
+ '₋' => '−',
+ '₌' => '=',
+ '₍' => '(',
+ '₎' => ')',
+ 'ₐ' => 'a',
+ 'ₑ' => 'e',
+ 'ₒ' => 'o',
+ 'ₓ' => 'x',
+ 'ₔ' => 'ə',
+ 'ₕ' => 'h',
+ 'ₖ' => 'k',
+ 'ₗ' => 'l',
+ 'ₘ' => 'm',
+ 'ₙ' => 'n',
+ 'ₚ' => 'p',
+ 'ₛ' => 's',
+ 'ₜ' => 't',
+ '₨' => 'Rs',
+ '℀' => 'a/c',
+ '℁' => 'a/s',
+ 'ℂ' => 'C',
+ '℃' => '°C',
+ '℅' => 'c/o',
+ '℆' => 'c/u',
+ 'ℇ' => 'Ɛ',
+ '℉' => '°F',
+ 'ℊ' => 'g',
+ 'ℋ' => 'H',
+ 'ℌ' => 'H',
+ 'ℍ' => 'H',
+ 'ℎ' => 'h',
+ 'ℏ' => 'ħ',
+ 'ℐ' => 'I',
+ 'ℑ' => 'I',
+ 'ℒ' => 'L',
+ 'ℓ' => 'l',
+ 'ℕ' => 'N',
+ '№' => 'No',
+ 'ℙ' => 'P',
+ 'ℚ' => 'Q',
+ 'ℛ' => 'R',
+ 'ℜ' => 'R',
+ 'ℝ' => 'R',
+ '℠' => 'SM',
+ '℡' => 'TEL',
+ '™' => 'TM',
+ 'ℤ' => 'Z',
+ 'ℨ' => 'Z',
+ 'ℬ' => 'B',
+ 'ℭ' => 'C',
+ 'ℯ' => 'e',
+ 'ℰ' => 'E',
+ 'ℱ' => 'F',
+ 'ℳ' => 'M',
+ 'ℴ' => 'o',
+ 'ℵ' => 'א',
+ 'ℶ' => 'ב',
+ 'ℷ' => 'ג',
+ 'ℸ' => 'ד',
+ 'ℹ' => 'i',
+ '℻' => 'FAX',
+ 'ℼ' => 'π',
+ 'ℽ' => 'γ',
+ 'ℾ' => 'Γ',
+ 'ℿ' => 'Π',
+ '⅀' => '∑',
+ 'ⅅ' => 'D',
+ 'ⅆ' => 'd',
+ 'ⅇ' => 'e',
+ 'ⅈ' => 'i',
+ 'ⅉ' => 'j',
+ '⅐' => '1⁄7',
+ '⅑' => '1⁄9',
+ '⅒' => '1⁄10',
+ '⅓' => '1⁄3',
+ '⅔' => '2⁄3',
+ '⅕' => '1⁄5',
+ '⅖' => '2⁄5',
+ '⅗' => '3⁄5',
+ '⅘' => '4⁄5',
+ '⅙' => '1⁄6',
+ '⅚' => '5⁄6',
+ '⅛' => '1⁄8',
+ '⅜' => '3⁄8',
+ '⅝' => '5⁄8',
+ '⅞' => '7⁄8',
+ '⅟' => '1⁄',
+ 'Ⅰ' => 'I',
+ 'Ⅱ' => 'II',
+ 'Ⅲ' => 'III',
+ 'Ⅳ' => 'IV',
+ 'Ⅴ' => 'V',
+ 'Ⅵ' => 'VI',
+ 'Ⅶ' => 'VII',
+ 'Ⅷ' => 'VIII',
+ 'Ⅸ' => 'IX',
+ 'Ⅹ' => 'X',
+ 'Ⅺ' => 'XI',
+ 'Ⅻ' => 'XII',
+ 'Ⅼ' => 'L',
+ 'Ⅽ' => 'C',
+ 'Ⅾ' => 'D',
+ 'Ⅿ' => 'M',
+ 'ⅰ' => 'i',
+ 'ⅱ' => 'ii',
+ 'ⅲ' => 'iii',
+ 'ⅳ' => 'iv',
+ 'ⅴ' => 'v',
+ 'ⅵ' => 'vi',
+ 'ⅶ' => 'vii',
+ 'ⅷ' => 'viii',
+ 'ⅸ' => 'ix',
+ 'ⅹ' => 'x',
+ 'ⅺ' => 'xi',
+ 'ⅻ' => 'xii',
+ 'ⅼ' => 'l',
+ 'ⅽ' => 'c',
+ 'ⅾ' => 'd',
+ 'ⅿ' => 'm',
+ '↉' => '0⁄3',
+ '∬' => '∫∫',
+ '∭' => '∫∫∫',
+ '∯' => '∮∮',
+ '∰' => '∮∮∮',
+ '①' => '1',
+ '②' => '2',
+ '③' => '3',
+ '④' => '4',
+ '⑤' => '5',
+ '⑥' => '6',
+ '⑦' => '7',
+ '⑧' => '8',
+ '⑨' => '9',
+ '⑩' => '10',
+ '⑪' => '11',
+ '⑫' => '12',
+ '⑬' => '13',
+ '⑭' => '14',
+ '⑮' => '15',
+ '⑯' => '16',
+ '⑰' => '17',
+ '⑱' => '18',
+ '⑲' => '19',
+ '⑳' => '20',
+ '⑴' => '(1)',
+ '⑵' => '(2)',
+ '⑶' => '(3)',
+ '⑷' => '(4)',
+ '⑸' => '(5)',
+ '⑹' => '(6)',
+ '⑺' => '(7)',
+ '⑻' => '(8)',
+ '⑼' => '(9)',
+ '⑽' => '(10)',
+ '⑾' => '(11)',
+ '⑿' => '(12)',
+ '⒀' => '(13)',
+ '⒁' => '(14)',
+ '⒂' => '(15)',
+ '⒃' => '(16)',
+ '⒄' => '(17)',
+ '⒅' => '(18)',
+ '⒆' => '(19)',
+ '⒇' => '(20)',
+ '⒈' => '1.',
+ '⒉' => '2.',
+ '⒊' => '3.',
+ '⒋' => '4.',
+ '⒌' => '5.',
+ '⒍' => '6.',
+ '⒎' => '7.',
+ '⒏' => '8.',
+ '⒐' => '9.',
+ '⒑' => '10.',
+ '⒒' => '11.',
+ '⒓' => '12.',
+ '⒔' => '13.',
+ '⒕' => '14.',
+ '⒖' => '15.',
+ '⒗' => '16.',
+ '⒘' => '17.',
+ '⒙' => '18.',
+ '⒚' => '19.',
+ '⒛' => '20.',
+ '⒜' => '(a)',
+ '⒝' => '(b)',
+ '⒞' => '(c)',
+ '⒟' => '(d)',
+ '⒠' => '(e)',
+ '⒡' => '(f)',
+ '⒢' => '(g)',
+ '⒣' => '(h)',
+ '⒤' => '(i)',
+ '⒥' => '(j)',
+ '⒦' => '(k)',
+ '⒧' => '(l)',
+ '⒨' => '(m)',
+ '⒩' => '(n)',
+ '⒪' => '(o)',
+ '⒫' => '(p)',
+ '⒬' => '(q)',
+ '⒭' => '(r)',
+ '⒮' => '(s)',
+ '⒯' => '(t)',
+ '⒰' => '(u)',
+ '⒱' => '(v)',
+ '⒲' => '(w)',
+ '⒳' => '(x)',
+ '⒴' => '(y)',
+ '⒵' => '(z)',
+ 'Ⓐ' => 'A',
+ 'Ⓑ' => 'B',
+ 'Ⓒ' => 'C',
+ 'Ⓓ' => 'D',
+ 'Ⓔ' => 'E',
+ 'Ⓕ' => 'F',
+ 'Ⓖ' => 'G',
+ 'Ⓗ' => 'H',
+ 'Ⓘ' => 'I',
+ 'Ⓙ' => 'J',
+ 'Ⓚ' => 'K',
+ 'Ⓛ' => 'L',
+ 'Ⓜ' => 'M',
+ 'Ⓝ' => 'N',
+ 'Ⓞ' => 'O',
+ 'Ⓟ' => 'P',
+ 'Ⓠ' => 'Q',
+ 'Ⓡ' => 'R',
+ 'Ⓢ' => 'S',
+ 'Ⓣ' => 'T',
+ 'Ⓤ' => 'U',
+ 'Ⓥ' => 'V',
+ 'Ⓦ' => 'W',
+ 'Ⓧ' => 'X',
+ 'Ⓨ' => 'Y',
+ 'Ⓩ' => 'Z',
+ 'ⓐ' => 'a',
+ 'ⓑ' => 'b',
+ 'ⓒ' => 'c',
+ 'ⓓ' => 'd',
+ 'ⓔ' => 'e',
+ 'ⓕ' => 'f',
+ 'ⓖ' => 'g',
+ 'ⓗ' => 'h',
+ 'ⓘ' => 'i',
+ 'ⓙ' => 'j',
+ 'ⓚ' => 'k',
+ 'ⓛ' => 'l',
+ 'ⓜ' => 'm',
+ 'ⓝ' => 'n',
+ 'ⓞ' => 'o',
+ 'ⓟ' => 'p',
+ 'ⓠ' => 'q',
+ 'ⓡ' => 'r',
+ 'ⓢ' => 's',
+ 'ⓣ' => 't',
+ 'ⓤ' => 'u',
+ 'ⓥ' => 'v',
+ 'ⓦ' => 'w',
+ 'ⓧ' => 'x',
+ 'ⓨ' => 'y',
+ 'ⓩ' => 'z',
+ '⓪' => '0',
+ '⨌' => '∫∫∫∫',
+ '⩴' => '::=',
+ '⩵' => '==',
+ '⩶' => '===',
+ 'ⱼ' => 'j',
+ 'ⱽ' => 'V',
+ 'ⵯ' => 'ⵡ',
+ '⺟' => '母',
+ '⻳' => '龟',
+ '⼀' => '一',
+ '⼁' => '丨',
+ '⼂' => '丶',
+ '⼃' => '丿',
+ '⼄' => '乙',
+ '⼅' => '亅',
+ '⼆' => '二',
+ '⼇' => '亠',
+ '⼈' => '人',
+ '⼉' => '儿',
+ '⼊' => '入',
+ '⼋' => '八',
+ '⼌' => '冂',
+ '⼍' => '冖',
+ '⼎' => '冫',
+ '⼏' => '几',
+ '⼐' => '凵',
+ '⼑' => '刀',
+ '⼒' => '力',
+ '⼓' => '勹',
+ '⼔' => '匕',
+ '⼕' => '匚',
+ '⼖' => '匸',
+ '⼗' => '十',
+ '⼘' => '卜',
+ '⼙' => '卩',
+ '⼚' => '厂',
+ '⼛' => '厶',
+ '⼜' => '又',
+ '⼝' => '口',
+ '⼞' => '囗',
+ '⼟' => '土',
+ '⼠' => '士',
+ '⼡' => '夂',
+ '⼢' => '夊',
+ '⼣' => '夕',
+ '⼤' => '大',
+ '⼥' => '女',
+ '⼦' => '子',
+ '⼧' => '宀',
+ '⼨' => '寸',
+ '⼩' => '小',
+ '⼪' => '尢',
+ '⼫' => '尸',
+ '⼬' => '屮',
+ '⼭' => '山',
+ '⼮' => '巛',
+ '⼯' => '工',
+ '⼰' => '己',
+ '⼱' => '巾',
+ '⼲' => '干',
+ '⼳' => '幺',
+ '⼴' => '广',
+ '⼵' => '廴',
+ '⼶' => '廾',
+ '⼷' => '弋',
+ '⼸' => '弓',
+ '⼹' => '彐',
+ '⼺' => '彡',
+ '⼻' => '彳',
+ '⼼' => '心',
+ '⼽' => '戈',
+ '⼾' => '戶',
+ '⼿' => '手',
+ '⽀' => '支',
+ '⽁' => '攴',
+ '⽂' => '文',
+ '⽃' => '斗',
+ '⽄' => '斤',
+ '⽅' => '方',
+ '⽆' => '无',
+ '⽇' => '日',
+ '⽈' => '曰',
+ '⽉' => '月',
+ '⽊' => '木',
+ '⽋' => '欠',
+ '⽌' => '止',
+ '⽍' => '歹',
+ '⽎' => '殳',
+ '⽏' => '毋',
+ '⽐' => '比',
+ '⽑' => '毛',
+ '⽒' => '氏',
+ '⽓' => '气',
+ '⽔' => '水',
+ '⽕' => '火',
+ '⽖' => '爪',
+ '⽗' => '父',
+ '⽘' => '爻',
+ '⽙' => '爿',
+ '⽚' => '片',
+ '⽛' => '牙',
+ '⽜' => '牛',
+ '⽝' => '犬',
+ '⽞' => '玄',
+ '⽟' => '玉',
+ '⽠' => '瓜',
+ '⽡' => '瓦',
+ '⽢' => '甘',
+ '⽣' => '生',
+ '⽤' => '用',
+ '⽥' => '田',
+ '⽦' => '疋',
+ '⽧' => '疒',
+ '⽨' => '癶',
+ '⽩' => '白',
+ '⽪' => '皮',
+ '⽫' => '皿',
+ '⽬' => '目',
+ '⽭' => '矛',
+ '⽮' => '矢',
+ '⽯' => '石',
+ '⽰' => '示',
+ '⽱' => '禸',
+ '⽲' => '禾',
+ '⽳' => '穴',
+ '⽴' => '立',
+ '⽵' => '竹',
+ '⽶' => '米',
+ '⽷' => '糸',
+ '⽸' => '缶',
+ '⽹' => '网',
+ '⽺' => '羊',
+ '⽻' => '羽',
+ '⽼' => '老',
+ '⽽' => '而',
+ '⽾' => '耒',
+ '⽿' => '耳',
+ '⾀' => '聿',
+ '⾁' => '肉',
+ '⾂' => '臣',
+ '⾃' => '自',
+ '⾄' => '至',
+ '⾅' => '臼',
+ '⾆' => '舌',
+ '⾇' => '舛',
+ '⾈' => '舟',
+ '⾉' => '艮',
+ '⾊' => '色',
+ '⾋' => '艸',
+ '⾌' => '虍',
+ '⾍' => '虫',
+ '⾎' => '血',
+ '⾏' => '行',
+ '⾐' => '衣',
+ '⾑' => '襾',
+ '⾒' => '見',
+ '⾓' => '角',
+ '⾔' => '言',
+ '⾕' => '谷',
+ '⾖' => '豆',
+ '⾗' => '豕',
+ '⾘' => '豸',
+ '⾙' => '貝',
+ '⾚' => '赤',
+ '⾛' => '走',
+ '⾜' => '足',
+ '⾝' => '身',
+ '⾞' => '車',
+ '⾟' => '辛',
+ '⾠' => '辰',
+ '⾡' => '辵',
+ '⾢' => '邑',
+ '⾣' => '酉',
+ '⾤' => '釆',
+ '⾥' => '里',
+ '⾦' => '金',
+ '⾧' => '長',
+ '⾨' => '門',
+ '⾩' => '阜',
+ '⾪' => '隶',
+ '⾫' => '隹',
+ '⾬' => '雨',
+ '⾭' => '靑',
+ '⾮' => '非',
+ '⾯' => '面',
+ '⾰' => '革',
+ '⾱' => '韋',
+ '⾲' => '韭',
+ '⾳' => '音',
+ '⾴' => '頁',
+ '⾵' => '風',
+ '⾶' => '飛',
+ '⾷' => '食',
+ '⾸' => '首',
+ '⾹' => '香',
+ '⾺' => '馬',
+ '⾻' => '骨',
+ '⾼' => '高',
+ '⾽' => '髟',
+ '⾾' => '鬥',
+ '⾿' => '鬯',
+ '⿀' => '鬲',
+ '⿁' => '鬼',
+ '⿂' => '魚',
+ '⿃' => '鳥',
+ '⿄' => '鹵',
+ '⿅' => '鹿',
+ '⿆' => '麥',
+ '⿇' => '麻',
+ '⿈' => '黃',
+ '⿉' => '黍',
+ '⿊' => '黑',
+ '⿋' => '黹',
+ '⿌' => '黽',
+ '⿍' => '鼎',
+ '⿎' => '鼓',
+ '⿏' => '鼠',
+ '⿐' => '鼻',
+ '⿑' => '齊',
+ '⿒' => '齒',
+ '⿓' => '龍',
+ '⿔' => '龜',
+ '⿕' => '龠',
+ ' ' => ' ',
+ '〶' => '〒',
+ '〸' => '十',
+ '〹' => '卄',
+ '〺' => '卅',
+ '゛' => ' ゙',
+ '゜' => ' ゚',
+ 'ゟ' => 'より',
+ 'ヿ' => 'コト',
+ 'ㄱ' => 'ᄀ',
+ 'ㄲ' => 'ᄁ',
+ 'ㄳ' => 'ᆪ',
+ 'ㄴ' => 'ᄂ',
+ 'ㄵ' => 'ᆬ',
+ 'ㄶ' => 'ᆭ',
+ 'ㄷ' => 'ᄃ',
+ 'ㄸ' => 'ᄄ',
+ 'ㄹ' => 'ᄅ',
+ 'ㄺ' => 'ᆰ',
+ 'ㄻ' => 'ᆱ',
+ 'ㄼ' => 'ᆲ',
+ 'ㄽ' => 'ᆳ',
+ 'ㄾ' => 'ᆴ',
+ 'ㄿ' => 'ᆵ',
+ 'ㅀ' => 'ᄚ',
+ 'ㅁ' => 'ᄆ',
+ 'ㅂ' => 'ᄇ',
+ 'ㅃ' => 'ᄈ',
+ 'ㅄ' => 'ᄡ',
+ 'ㅅ' => 'ᄉ',
+ 'ㅆ' => 'ᄊ',
+ 'ㅇ' => 'ᄋ',
+ 'ㅈ' => 'ᄌ',
+ 'ㅉ' => 'ᄍ',
+ 'ㅊ' => 'ᄎ',
+ 'ㅋ' => 'ᄏ',
+ 'ㅌ' => 'ᄐ',
+ 'ㅍ' => 'ᄑ',
+ 'ㅎ' => 'ᄒ',
+ 'ㅏ' => 'ᅡ',
+ 'ㅐ' => 'ᅢ',
+ 'ㅑ' => 'ᅣ',
+ 'ㅒ' => 'ᅤ',
+ 'ㅓ' => 'ᅥ',
+ 'ㅔ' => 'ᅦ',
+ 'ㅕ' => 'ᅧ',
+ 'ㅖ' => 'ᅨ',
+ 'ㅗ' => 'ᅩ',
+ 'ㅘ' => 'ᅪ',
+ 'ㅙ' => 'ᅫ',
+ 'ㅚ' => 'ᅬ',
+ 'ㅛ' => 'ᅭ',
+ 'ㅜ' => 'ᅮ',
+ 'ㅝ' => 'ᅯ',
+ 'ㅞ' => 'ᅰ',
+ 'ㅟ' => 'ᅱ',
+ 'ㅠ' => 'ᅲ',
+ 'ㅡ' => 'ᅳ',
+ 'ㅢ' => 'ᅴ',
+ 'ㅣ' => 'ᅵ',
+ 'ㅤ' => 'ᅠ',
+ 'ㅥ' => 'ᄔ',
+ 'ㅦ' => 'ᄕ',
+ 'ㅧ' => 'ᇇ',
+ 'ㅨ' => 'ᇈ',
+ 'ㅩ' => 'ᇌ',
+ 'ㅪ' => 'ᇎ',
+ 'ㅫ' => 'ᇓ',
+ 'ㅬ' => 'ᇗ',
+ 'ㅭ' => 'ᇙ',
+ 'ㅮ' => 'ᄜ',
+ 'ㅯ' => 'ᇝ',
+ 'ㅰ' => 'ᇟ',
+ 'ㅱ' => 'ᄝ',
+ 'ㅲ' => 'ᄞ',
+ 'ㅳ' => 'ᄠ',
+ 'ㅴ' => 'ᄢ',
+ 'ㅵ' => 'ᄣ',
+ 'ㅶ' => 'ᄧ',
+ 'ㅷ' => 'ᄩ',
+ 'ㅸ' => 'ᄫ',
+ 'ㅹ' => 'ᄬ',
+ 'ㅺ' => 'ᄭ',
+ 'ㅻ' => 'ᄮ',
+ 'ㅼ' => 'ᄯ',
+ 'ㅽ' => 'ᄲ',
+ 'ㅾ' => 'ᄶ',
+ 'ㅿ' => 'ᅀ',
+ 'ㆀ' => 'ᅇ',
+ 'ㆁ' => 'ᅌ',
+ 'ㆂ' => 'ᇱ',
+ 'ㆃ' => 'ᇲ',
+ 'ㆄ' => 'ᅗ',
+ 'ㆅ' => 'ᅘ',
+ 'ㆆ' => 'ᅙ',
+ 'ㆇ' => 'ᆄ',
+ 'ㆈ' => 'ᆅ',
+ 'ㆉ' => 'ᆈ',
+ 'ㆊ' => 'ᆑ',
+ 'ㆋ' => 'ᆒ',
+ 'ㆌ' => 'ᆔ',
+ 'ㆍ' => 'ᆞ',
+ 'ㆎ' => 'ᆡ',
+ '㆒' => '一',
+ '㆓' => '二',
+ '㆔' => '三',
+ '㆕' => '四',
+ '㆖' => '上',
+ '㆗' => '中',
+ '㆘' => '下',
+ '㆙' => '甲',
+ '㆚' => '乙',
+ '㆛' => '丙',
+ '㆜' => '丁',
+ '㆝' => '天',
+ '㆞' => '地',
+ '㆟' => '人',
+ '㈀' => '(ᄀ)',
+ '㈁' => '(ᄂ)',
+ '㈂' => '(ᄃ)',
+ '㈃' => '(ᄅ)',
+ '㈄' => '(ᄆ)',
+ '㈅' => '(ᄇ)',
+ '㈆' => '(ᄉ)',
+ '㈇' => '(ᄋ)',
+ '㈈' => '(ᄌ)',
+ '㈉' => '(ᄎ)',
+ '㈊' => '(ᄏ)',
+ '㈋' => '(ᄐ)',
+ '㈌' => '(ᄑ)',
+ '㈍' => '(ᄒ)',
+ '㈎' => '(가)',
+ '㈏' => '(나)',
+ '㈐' => '(다)',
+ '㈑' => '(라)',
+ '㈒' => '(마)',
+ '㈓' => '(바)',
+ '㈔' => '(사)',
+ '㈕' => '(아)',
+ '㈖' => '(자)',
+ '㈗' => '(차)',
+ '㈘' => '(카)',
+ '㈙' => '(타)',
+ '㈚' => '(파)',
+ '㈛' => '(하)',
+ '㈜' => '(주)',
+ '㈝' => '(오전)',
+ '㈞' => '(오후)',
+ '㈠' => '(一)',
+ '㈡' => '(二)',
+ '㈢' => '(三)',
+ '㈣' => '(四)',
+ '㈤' => '(五)',
+ '㈥' => '(六)',
+ '㈦' => '(七)',
+ '㈧' => '(八)',
+ '㈨' => '(九)',
+ '㈩' => '(十)',
+ '㈪' => '(月)',
+ '㈫' => '(火)',
+ '㈬' => '(水)',
+ '㈭' => '(木)',
+ '㈮' => '(金)',
+ '㈯' => '(土)',
+ '㈰' => '(日)',
+ '㈱' => '(株)',
+ '㈲' => '(有)',
+ '㈳' => '(社)',
+ '㈴' => '(名)',
+ '㈵' => '(特)',
+ '㈶' => '(財)',
+ '㈷' => '(祝)',
+ '㈸' => '(労)',
+ '㈹' => '(代)',
+ '㈺' => '(呼)',
+ '㈻' => '(学)',
+ '㈼' => '(監)',
+ '㈽' => '(企)',
+ '㈾' => '(資)',
+ '㈿' => '(協)',
+ '㉀' => '(祭)',
+ '㉁' => '(休)',
+ '㉂' => '(自)',
+ '㉃' => '(至)',
+ '㉄' => '問',
+ '㉅' => '幼',
+ '㉆' => '文',
+ '㉇' => '箏',
+ '㉐' => 'PTE',
+ '㉑' => '21',
+ '㉒' => '22',
+ '㉓' => '23',
+ '㉔' => '24',
+ '㉕' => '25',
+ '㉖' => '26',
+ '㉗' => '27',
+ '㉘' => '28',
+ '㉙' => '29',
+ '㉚' => '30',
+ '㉛' => '31',
+ '㉜' => '32',
+ '㉝' => '33',
+ '㉞' => '34',
+ '㉟' => '35',
+ '㉠' => 'ᄀ',
+ '㉡' => 'ᄂ',
+ '㉢' => 'ᄃ',
+ '㉣' => 'ᄅ',
+ '㉤' => 'ᄆ',
+ '㉥' => 'ᄇ',
+ '㉦' => 'ᄉ',
+ '㉧' => 'ᄋ',
+ '㉨' => 'ᄌ',
+ '㉩' => 'ᄎ',
+ '㉪' => 'ᄏ',
+ '㉫' => 'ᄐ',
+ '㉬' => 'ᄑ',
+ '㉭' => 'ᄒ',
+ '㉮' => '가',
+ '㉯' => '나',
+ '㉰' => '다',
+ '㉱' => '라',
+ '㉲' => '마',
+ '㉳' => '바',
+ '㉴' => '사',
+ '㉵' => '아',
+ '㉶' => '자',
+ '㉷' => '차',
+ '㉸' => '카',
+ '㉹' => '타',
+ '㉺' => '파',
+ '㉻' => '하',
+ '㉼' => '참고',
+ '㉽' => '주의',
+ '㉾' => '우',
+ '㊀' => '一',
+ '㊁' => '二',
+ '㊂' => '三',
+ '㊃' => '四',
+ '㊄' => '五',
+ '㊅' => '六',
+ '㊆' => '七',
+ '㊇' => '八',
+ '㊈' => '九',
+ '㊉' => '十',
+ '㊊' => '月',
+ '㊋' => '火',
+ '㊌' => '水',
+ '㊍' => '木',
+ '㊎' => '金',
+ '㊏' => '土',
+ '㊐' => '日',
+ '㊑' => '株',
+ '㊒' => '有',
+ '㊓' => '社',
+ '㊔' => '名',
+ '㊕' => '特',
+ '㊖' => '財',
+ '㊗' => '祝',
+ '㊘' => '労',
+ '㊙' => '秘',
+ '㊚' => '男',
+ '㊛' => '女',
+ '㊜' => '適',
+ '㊝' => '優',
+ '㊞' => '印',
+ '㊟' => '注',
+ '㊠' => '項',
+ '㊡' => '休',
+ '㊢' => '写',
+ '㊣' => '正',
+ '㊤' => '上',
+ '㊥' => '中',
+ '㊦' => '下',
+ '㊧' => '左',
+ '㊨' => '右',
+ '㊩' => '医',
+ '㊪' => '宗',
+ '㊫' => '学',
+ '㊬' => '監',
+ '㊭' => '企',
+ '㊮' => '資',
+ '㊯' => '協',
+ '㊰' => '夜',
+ '㊱' => '36',
+ '㊲' => '37',
+ '㊳' => '38',
+ '㊴' => '39',
+ '㊵' => '40',
+ '㊶' => '41',
+ '㊷' => '42',
+ '㊸' => '43',
+ '㊹' => '44',
+ '㊺' => '45',
+ '㊻' => '46',
+ '㊼' => '47',
+ '㊽' => '48',
+ '㊾' => '49',
+ '㊿' => '50',
+ '㋀' => '1月',
+ '㋁' => '2月',
+ '㋂' => '3月',
+ '㋃' => '4月',
+ '㋄' => '5月',
+ '㋅' => '6月',
+ '㋆' => '7月',
+ '㋇' => '8月',
+ '㋈' => '9月',
+ '㋉' => '10月',
+ '㋊' => '11月',
+ '㋋' => '12月',
+ '㋌' => 'Hg',
+ '㋍' => 'erg',
+ '㋎' => 'eV',
+ '㋏' => 'LTD',
+ '㋐' => 'ア',
+ '㋑' => 'イ',
+ '㋒' => 'ウ',
+ '㋓' => 'エ',
+ '㋔' => 'オ',
+ '㋕' => 'カ',
+ '㋖' => 'キ',
+ '㋗' => 'ク',
+ '㋘' => 'ケ',
+ '㋙' => 'コ',
+ '㋚' => 'サ',
+ '㋛' => 'シ',
+ '㋜' => 'ス',
+ '㋝' => 'セ',
+ '㋞' => 'ソ',
+ '㋟' => 'タ',
+ '㋠' => 'チ',
+ '㋡' => 'ツ',
+ '㋢' => 'テ',
+ '㋣' => 'ト',
+ '㋤' => 'ナ',
+ '㋥' => 'ニ',
+ '㋦' => 'ヌ',
+ '㋧' => 'ネ',
+ '㋨' => 'ノ',
+ '㋩' => 'ハ',
+ '㋪' => 'ヒ',
+ '㋫' => 'フ',
+ '㋬' => 'ヘ',
+ '㋭' => 'ホ',
+ '㋮' => 'マ',
+ '㋯' => 'ミ',
+ '㋰' => 'ム',
+ '㋱' => 'メ',
+ '㋲' => 'モ',
+ '㋳' => 'ヤ',
+ '㋴' => 'ユ',
+ '㋵' => 'ヨ',
+ '㋶' => 'ラ',
+ '㋷' => 'リ',
+ '㋸' => 'ル',
+ '㋹' => 'レ',
+ '㋺' => 'ロ',
+ '㋻' => 'ワ',
+ '㋼' => 'ヰ',
+ '㋽' => 'ヱ',
+ '㋾' => 'ヲ',
+ '㋿' => '令和',
+ '㌀' => 'アパート',
+ '㌁' => 'アルファ',
+ '㌂' => 'アンペア',
+ '㌃' => 'アール',
+ '㌄' => 'イニング',
+ '㌅' => 'インチ',
+ '㌆' => 'ウォン',
+ '㌇' => 'エスクード',
+ '㌈' => 'エーカー',
+ '㌉' => 'オンス',
+ '㌊' => 'オーム',
+ '㌋' => 'カイリ',
+ '㌌' => 'カラット',
+ '㌍' => 'カロリー',
+ '㌎' => 'ガロン',
+ '㌏' => 'ガンマ',
+ '㌐' => 'ギガ',
+ '㌑' => 'ギニー',
+ '㌒' => 'キュリー',
+ '㌓' => 'ギルダー',
+ '㌔' => 'キロ',
+ '㌕' => 'キログラム',
+ '㌖' => 'キロメートル',
+ '㌗' => 'キロワット',
+ '㌘' => 'グラム',
+ '㌙' => 'グラムトン',
+ '㌚' => 'クルゼイロ',
+ '㌛' => 'クローネ',
+ '㌜' => 'ケース',
+ '㌝' => 'コルナ',
+ '㌞' => 'コーポ',
+ '㌟' => 'サイクル',
+ '㌠' => 'サンチーム',
+ '㌡' => 'シリング',
+ '㌢' => 'センチ',
+ '㌣' => 'セント',
+ '㌤' => 'ダース',
+ '㌥' => 'デシ',
+ '㌦' => 'ドル',
+ '㌧' => 'トン',
+ '㌨' => 'ナノ',
+ '㌩' => 'ノット',
+ '㌪' => 'ハイツ',
+ '㌫' => 'パーセント',
+ '㌬' => 'パーツ',
+ '㌭' => 'バーレル',
+ '㌮' => 'ピアストル',
+ '㌯' => 'ピクル',
+ '㌰' => 'ピコ',
+ '㌱' => 'ビル',
+ '㌲' => 'ファラッド',
+ '㌳' => 'フィート',
+ '㌴' => 'ブッシェル',
+ '㌵' => 'フラン',
+ '㌶' => 'ヘクタール',
+ '㌷' => 'ペソ',
+ '㌸' => 'ペニヒ',
+ '㌹' => 'ヘルツ',
+ '㌺' => 'ペンス',
+ '㌻' => 'ページ',
+ '㌼' => 'ベータ',
+ '㌽' => 'ポイント',
+ '㌾' => 'ボルト',
+ '㌿' => 'ホン',
+ '㍀' => 'ポンド',
+ '㍁' => 'ホール',
+ '㍂' => 'ホーン',
+ '㍃' => 'マイクロ',
+ '㍄' => 'マイル',
+ '㍅' => 'マッハ',
+ '㍆' => 'マルク',
+ '㍇' => 'マンション',
+ '㍈' => 'ミクロン',
+ '㍉' => 'ミリ',
+ '㍊' => 'ミリバール',
+ '㍋' => 'メガ',
+ '㍌' => 'メガトン',
+ '㍍' => 'メートル',
+ '㍎' => 'ヤード',
+ '㍏' => 'ヤール',
+ '㍐' => 'ユアン',
+ '㍑' => 'リットル',
+ '㍒' => 'リラ',
+ '㍓' => 'ルピー',
+ '㍔' => 'ルーブル',
+ '㍕' => 'レム',
+ '㍖' => 'レントゲン',
+ '㍗' => 'ワット',
+ '㍘' => '0点',
+ '㍙' => '1点',
+ '㍚' => '2点',
+ '㍛' => '3点',
+ '㍜' => '4点',
+ '㍝' => '5点',
+ '㍞' => '6点',
+ '㍟' => '7点',
+ '㍠' => '8点',
+ '㍡' => '9点',
+ '㍢' => '10点',
+ '㍣' => '11点',
+ '㍤' => '12点',
+ '㍥' => '13点',
+ '㍦' => '14点',
+ '㍧' => '15点',
+ '㍨' => '16点',
+ '㍩' => '17点',
+ '㍪' => '18点',
+ '㍫' => '19点',
+ '㍬' => '20点',
+ '㍭' => '21点',
+ '㍮' => '22点',
+ '㍯' => '23点',
+ '㍰' => '24点',
+ '㍱' => 'hPa',
+ '㍲' => 'da',
+ '㍳' => 'AU',
+ '㍴' => 'bar',
+ '㍵' => 'oV',
+ '㍶' => 'pc',
+ '㍷' => 'dm',
+ '㍸' => 'dm2',
+ '㍹' => 'dm3',
+ '㍺' => 'IU',
+ '㍻' => '平成',
+ '㍼' => '昭和',
+ '㍽' => '大正',
+ '㍾' => '明治',
+ '㍿' => '株式会社',
+ '㎀' => 'pA',
+ '㎁' => 'nA',
+ '㎂' => 'μA',
+ '㎃' => 'mA',
+ '㎄' => 'kA',
+ '㎅' => 'KB',
+ '㎆' => 'MB',
+ '㎇' => 'GB',
+ '㎈' => 'cal',
+ '㎉' => 'kcal',
+ '㎊' => 'pF',
+ '㎋' => 'nF',
+ '㎌' => 'μF',
+ '㎍' => 'μg',
+ '㎎' => 'mg',
+ '㎏' => 'kg',
+ '㎐' => 'Hz',
+ '㎑' => 'kHz',
+ '㎒' => 'MHz',
+ '㎓' => 'GHz',
+ '㎔' => 'THz',
+ '㎕' => 'μl',
+ '㎖' => 'ml',
+ '㎗' => 'dl',
+ '㎘' => 'kl',
+ '㎙' => 'fm',
+ '㎚' => 'nm',
+ '㎛' => 'μm',
+ '㎜' => 'mm',
+ '㎝' => 'cm',
+ '㎞' => 'km',
+ '㎟' => 'mm2',
+ '㎠' => 'cm2',
+ '㎡' => 'm2',
+ '㎢' => 'km2',
+ '㎣' => 'mm3',
+ '㎤' => 'cm3',
+ '㎥' => 'm3',
+ '㎦' => 'km3',
+ '㎧' => 'm∕s',
+ '㎨' => 'm∕s2',
+ '㎩' => 'Pa',
+ '㎪' => 'kPa',
+ '㎫' => 'MPa',
+ '㎬' => 'GPa',
+ '㎭' => 'rad',
+ '㎮' => 'rad∕s',
+ '㎯' => 'rad∕s2',
+ '㎰' => 'ps',
+ '㎱' => 'ns',
+ '㎲' => 'μs',
+ '㎳' => 'ms',
+ '㎴' => 'pV',
+ '㎵' => 'nV',
+ '㎶' => 'μV',
+ '㎷' => 'mV',
+ '㎸' => 'kV',
+ '㎹' => 'MV',
+ '㎺' => 'pW',
+ '㎻' => 'nW',
+ '㎼' => 'μW',
+ '㎽' => 'mW',
+ '㎾' => 'kW',
+ '㎿' => 'MW',
+ '㏀' => 'kΩ',
+ '㏁' => 'MΩ',
+ '㏂' => 'a.m.',
+ '㏃' => 'Bq',
+ '㏄' => 'cc',
+ '㏅' => 'cd',
+ '㏆' => 'C∕kg',
+ '㏇' => 'Co.',
+ '㏈' => 'dB',
+ '㏉' => 'Gy',
+ '㏊' => 'ha',
+ '㏋' => 'HP',
+ '㏌' => 'in',
+ '㏍' => 'KK',
+ '㏎' => 'KM',
+ '㏏' => 'kt',
+ '㏐' => 'lm',
+ '㏑' => 'ln',
+ '㏒' => 'log',
+ '㏓' => 'lx',
+ '㏔' => 'mb',
+ '㏕' => 'mil',
+ '㏖' => 'mol',
+ '㏗' => 'PH',
+ '㏘' => 'p.m.',
+ '㏙' => 'PPM',
+ '㏚' => 'PR',
+ '㏛' => 'sr',
+ '㏜' => 'Sv',
+ '㏝' => 'Wb',
+ '㏞' => 'V∕m',
+ '㏟' => 'A∕m',
+ '㏠' => '1日',
+ '㏡' => '2日',
+ '㏢' => '3日',
+ '㏣' => '4日',
+ '㏤' => '5日',
+ '㏥' => '6日',
+ '㏦' => '7日',
+ '㏧' => '8日',
+ '㏨' => '9日',
+ '㏩' => '10日',
+ '㏪' => '11日',
+ '㏫' => '12日',
+ '㏬' => '13日',
+ '㏭' => '14日',
+ '㏮' => '15日',
+ '㏯' => '16日',
+ '㏰' => '17日',
+ '㏱' => '18日',
+ '㏲' => '19日',
+ '㏳' => '20日',
+ '㏴' => '21日',
+ '㏵' => '22日',
+ '㏶' => '23日',
+ '㏷' => '24日',
+ '㏸' => '25日',
+ '㏹' => '26日',
+ '㏺' => '27日',
+ '㏻' => '28日',
+ '㏼' => '29日',
+ '㏽' => '30日',
+ '㏾' => '31日',
+ '㏿' => 'gal',
+ 'ꚜ' => 'ъ',
+ 'ꚝ' => 'ь',
+ 'ꝰ' => 'ꝯ',
+ 'ꟸ' => 'Ħ',
+ 'ꟹ' => 'œ',
+ 'ꭜ' => 'ꜧ',
+ 'ꭝ' => 'ꬷ',
+ 'ꭞ' => 'ɫ',
+ 'ꭟ' => 'ꭒ',
+ 'ꭩ' => 'ʍ',
+ 'ff' => 'ff',
+ 'fi' => 'fi',
+ 'fl' => 'fl',
+ 'ffi' => 'ffi',
+ 'ffl' => 'ffl',
+ 'ſt' => 'st',
+ 'st' => 'st',
+ 'ﬓ' => 'մն',
+ 'ﬔ' => 'մե',
+ 'ﬕ' => 'մի',
+ 'ﬖ' => 'վն',
+ 'ﬗ' => 'մխ',
+ 'ﬠ' => 'ע',
+ 'ﬡ' => 'א',
+ 'ﬢ' => 'ד',
+ 'ﬣ' => 'ה',
+ 'ﬤ' => 'כ',
+ 'ﬥ' => 'ל',
+ 'ﬦ' => 'ם',
+ 'ﬧ' => 'ר',
+ 'ﬨ' => 'ת',
+ '﬩' => '+',
+ 'ﭏ' => 'אל',
+ 'ﭐ' => 'ٱ',
+ 'ﭑ' => 'ٱ',
+ 'ﭒ' => 'ٻ',
+ 'ﭓ' => 'ٻ',
+ 'ﭔ' => 'ٻ',
+ 'ﭕ' => 'ٻ',
+ 'ﭖ' => 'پ',
+ 'ﭗ' => 'پ',
+ 'ﭘ' => 'پ',
+ 'ﭙ' => 'پ',
+ 'ﭚ' => 'ڀ',
+ 'ﭛ' => 'ڀ',
+ 'ﭜ' => 'ڀ',
+ 'ﭝ' => 'ڀ',
+ 'ﭞ' => 'ٺ',
+ 'ﭟ' => 'ٺ',
+ 'ﭠ' => 'ٺ',
+ 'ﭡ' => 'ٺ',
+ 'ﭢ' => 'ٿ',
+ 'ﭣ' => 'ٿ',
+ 'ﭤ' => 'ٿ',
+ 'ﭥ' => 'ٿ',
+ 'ﭦ' => 'ٹ',
+ 'ﭧ' => 'ٹ',
+ 'ﭨ' => 'ٹ',
+ 'ﭩ' => 'ٹ',
+ 'ﭪ' => 'ڤ',
+ 'ﭫ' => 'ڤ',
+ 'ﭬ' => 'ڤ',
+ 'ﭭ' => 'ڤ',
+ 'ﭮ' => 'ڦ',
+ 'ﭯ' => 'ڦ',
+ 'ﭰ' => 'ڦ',
+ 'ﭱ' => 'ڦ',
+ 'ﭲ' => 'ڄ',
+ 'ﭳ' => 'ڄ',
+ 'ﭴ' => 'ڄ',
+ 'ﭵ' => 'ڄ',
+ 'ﭶ' => 'ڃ',
+ 'ﭷ' => 'ڃ',
+ 'ﭸ' => 'ڃ',
+ 'ﭹ' => 'ڃ',
+ 'ﭺ' => 'چ',
+ 'ﭻ' => 'چ',
+ 'ﭼ' => 'چ',
+ 'ﭽ' => 'چ',
+ 'ﭾ' => 'ڇ',
+ 'ﭿ' => 'ڇ',
+ 'ﮀ' => 'ڇ',
+ 'ﮁ' => 'ڇ',
+ 'ﮂ' => 'ڍ',
+ 'ﮃ' => 'ڍ',
+ 'ﮄ' => 'ڌ',
+ 'ﮅ' => 'ڌ',
+ 'ﮆ' => 'ڎ',
+ 'ﮇ' => 'ڎ',
+ 'ﮈ' => 'ڈ',
+ 'ﮉ' => 'ڈ',
+ 'ﮊ' => 'ژ',
+ 'ﮋ' => 'ژ',
+ 'ﮌ' => 'ڑ',
+ 'ﮍ' => 'ڑ',
+ 'ﮎ' => 'ک',
+ 'ﮏ' => 'ک',
+ 'ﮐ' => 'ک',
+ 'ﮑ' => 'ک',
+ 'ﮒ' => 'گ',
+ 'ﮓ' => 'گ',
+ 'ﮔ' => 'گ',
+ 'ﮕ' => 'گ',
+ 'ﮖ' => 'ڳ',
+ 'ﮗ' => 'ڳ',
+ 'ﮘ' => 'ڳ',
+ 'ﮙ' => 'ڳ',
+ 'ﮚ' => 'ڱ',
+ 'ﮛ' => 'ڱ',
+ 'ﮜ' => 'ڱ',
+ 'ﮝ' => 'ڱ',
+ 'ﮞ' => 'ں',
+ 'ﮟ' => 'ں',
+ 'ﮠ' => 'ڻ',
+ 'ﮡ' => 'ڻ',
+ 'ﮢ' => 'ڻ',
+ 'ﮣ' => 'ڻ',
+ 'ﮤ' => 'ۀ',
+ 'ﮥ' => 'ۀ',
+ 'ﮦ' => 'ہ',
+ 'ﮧ' => 'ہ',
+ 'ﮨ' => 'ہ',
+ 'ﮩ' => 'ہ',
+ 'ﮪ' => 'ھ',
+ 'ﮫ' => 'ھ',
+ 'ﮬ' => 'ھ',
+ 'ﮭ' => 'ھ',
+ 'ﮮ' => 'ے',
+ 'ﮯ' => 'ے',
+ 'ﮰ' => 'ۓ',
+ 'ﮱ' => 'ۓ',
+ 'ﯓ' => 'ڭ',
+ 'ﯔ' => 'ڭ',
+ 'ﯕ' => 'ڭ',
+ 'ﯖ' => 'ڭ',
+ 'ﯗ' => 'ۇ',
+ 'ﯘ' => 'ۇ',
+ 'ﯙ' => 'ۆ',
+ 'ﯚ' => 'ۆ',
+ 'ﯛ' => 'ۈ',
+ 'ﯜ' => 'ۈ',
+ 'ﯝ' => 'ۇٴ',
+ 'ﯞ' => 'ۋ',
+ 'ﯟ' => 'ۋ',
+ 'ﯠ' => 'ۅ',
+ 'ﯡ' => 'ۅ',
+ 'ﯢ' => 'ۉ',
+ 'ﯣ' => 'ۉ',
+ 'ﯤ' => 'ې',
+ 'ﯥ' => 'ې',
+ 'ﯦ' => 'ې',
+ 'ﯧ' => 'ې',
+ 'ﯨ' => 'ى',
+ 'ﯩ' => 'ى',
+ 'ﯪ' => 'ئا',
+ 'ﯫ' => 'ئا',
+ 'ﯬ' => 'ئە',
+ 'ﯭ' => 'ئە',
+ 'ﯮ' => 'ئو',
+ 'ﯯ' => 'ئو',
+ 'ﯰ' => 'ئۇ',
+ 'ﯱ' => 'ئۇ',
+ 'ﯲ' => 'ئۆ',
+ 'ﯳ' => 'ئۆ',
+ 'ﯴ' => 'ئۈ',
+ 'ﯵ' => 'ئۈ',
+ 'ﯶ' => 'ئې',
+ 'ﯷ' => 'ئې',
+ 'ﯸ' => 'ئې',
+ 'ﯹ' => 'ئى',
+ 'ﯺ' => 'ئى',
+ 'ﯻ' => 'ئى',
+ 'ﯼ' => 'ی',
+ 'ﯽ' => 'ی',
+ 'ﯾ' => 'ی',
+ 'ﯿ' => 'ی',
+ 'ﰀ' => 'ئج',
+ 'ﰁ' => 'ئح',
+ 'ﰂ' => 'ئم',
+ 'ﰃ' => 'ئى',
+ 'ﰄ' => 'ئي',
+ 'ﰅ' => 'بج',
+ 'ﰆ' => 'بح',
+ 'ﰇ' => 'بخ',
+ 'ﰈ' => 'بم',
+ 'ﰉ' => 'بى',
+ 'ﰊ' => 'بي',
+ 'ﰋ' => 'تج',
+ 'ﰌ' => 'تح',
+ 'ﰍ' => 'تخ',
+ 'ﰎ' => 'تم',
+ 'ﰏ' => 'تى',
+ 'ﰐ' => 'تي',
+ 'ﰑ' => 'ثج',
+ 'ﰒ' => 'ثم',
+ 'ﰓ' => 'ثى',
+ 'ﰔ' => 'ثي',
+ 'ﰕ' => 'جح',
+ 'ﰖ' => 'جم',
+ 'ﰗ' => 'حج',
+ 'ﰘ' => 'حم',
+ 'ﰙ' => 'خج',
+ 'ﰚ' => 'خح',
+ 'ﰛ' => 'خم',
+ 'ﰜ' => 'سج',
+ 'ﰝ' => 'سح',
+ 'ﰞ' => 'سخ',
+ 'ﰟ' => 'سم',
+ 'ﰠ' => 'صح',
+ 'ﰡ' => 'صم',
+ 'ﰢ' => 'ضج',
+ 'ﰣ' => 'ضح',
+ 'ﰤ' => 'ضخ',
+ 'ﰥ' => 'ضم',
+ 'ﰦ' => 'طح',
+ 'ﰧ' => 'طم',
+ 'ﰨ' => 'ظم',
+ 'ﰩ' => 'عج',
+ 'ﰪ' => 'عم',
+ 'ﰫ' => 'غج',
+ 'ﰬ' => 'غم',
+ 'ﰭ' => 'فج',
+ 'ﰮ' => 'فح',
+ 'ﰯ' => 'فخ',
+ 'ﰰ' => 'فم',
+ 'ﰱ' => 'فى',
+ 'ﰲ' => 'في',
+ 'ﰳ' => 'قح',
+ 'ﰴ' => 'قم',
+ 'ﰵ' => 'قى',
+ 'ﰶ' => 'قي',
+ 'ﰷ' => 'كا',
+ 'ﰸ' => 'كج',
+ 'ﰹ' => 'كح',
+ 'ﰺ' => 'كخ',
+ 'ﰻ' => 'كل',
+ 'ﰼ' => 'كم',
+ 'ﰽ' => 'كى',
+ 'ﰾ' => 'كي',
+ 'ﰿ' => 'لج',
+ 'ﱀ' => 'لح',
+ 'ﱁ' => 'لخ',
+ 'ﱂ' => 'لم',
+ 'ﱃ' => 'لى',
+ 'ﱄ' => 'لي',
+ 'ﱅ' => 'مج',
+ 'ﱆ' => 'مح',
+ 'ﱇ' => 'مخ',
+ 'ﱈ' => 'مم',
+ 'ﱉ' => 'مى',
+ 'ﱊ' => 'مي',
+ 'ﱋ' => 'نج',
+ 'ﱌ' => 'نح',
+ 'ﱍ' => 'نخ',
+ 'ﱎ' => 'نم',
+ 'ﱏ' => 'نى',
+ 'ﱐ' => 'ني',
+ 'ﱑ' => 'هج',
+ 'ﱒ' => 'هم',
+ 'ﱓ' => 'هى',
+ 'ﱔ' => 'هي',
+ 'ﱕ' => 'يج',
+ 'ﱖ' => 'يح',
+ 'ﱗ' => 'يخ',
+ 'ﱘ' => 'يم',
+ 'ﱙ' => 'يى',
+ 'ﱚ' => 'يي',
+ 'ﱛ' => 'ذٰ',
+ 'ﱜ' => 'رٰ',
+ 'ﱝ' => 'ىٰ',
+ 'ﱞ' => ' ٌّ',
+ 'ﱟ' => ' ٍّ',
+ 'ﱠ' => ' َّ',
+ 'ﱡ' => ' ُّ',
+ 'ﱢ' => ' ِّ',
+ 'ﱣ' => ' ّٰ',
+ 'ﱤ' => 'ئر',
+ 'ﱥ' => 'ئز',
+ 'ﱦ' => 'ئم',
+ 'ﱧ' => 'ئن',
+ 'ﱨ' => 'ئى',
+ 'ﱩ' => 'ئي',
+ 'ﱪ' => 'بر',
+ 'ﱫ' => 'بز',
+ 'ﱬ' => 'بم',
+ 'ﱭ' => 'بن',
+ 'ﱮ' => 'بى',
+ 'ﱯ' => 'بي',
+ 'ﱰ' => 'تر',
+ 'ﱱ' => 'تز',
+ 'ﱲ' => 'تم',
+ 'ﱳ' => 'تن',
+ 'ﱴ' => 'تى',
+ 'ﱵ' => 'تي',
+ 'ﱶ' => 'ثر',
+ 'ﱷ' => 'ثز',
+ 'ﱸ' => 'ثم',
+ 'ﱹ' => 'ثن',
+ 'ﱺ' => 'ثى',
+ 'ﱻ' => 'ثي',
+ 'ﱼ' => 'فى',
+ 'ﱽ' => 'في',
+ 'ﱾ' => 'قى',
+ 'ﱿ' => 'قي',
+ 'ﲀ' => 'كا',
+ 'ﲁ' => 'كل',
+ 'ﲂ' => 'كم',
+ 'ﲃ' => 'كى',
+ 'ﲄ' => 'كي',
+ 'ﲅ' => 'لم',
+ 'ﲆ' => 'لى',
+ 'ﲇ' => 'لي',
+ 'ﲈ' => 'ما',
+ 'ﲉ' => 'مم',
+ 'ﲊ' => 'نر',
+ 'ﲋ' => 'نز',
+ 'ﲌ' => 'نم',
+ 'ﲍ' => 'نن',
+ 'ﲎ' => 'نى',
+ 'ﲏ' => 'ني',
+ 'ﲐ' => 'ىٰ',
+ 'ﲑ' => 'ير',
+ 'ﲒ' => 'يز',
+ 'ﲓ' => 'يم',
+ 'ﲔ' => 'ين',
+ 'ﲕ' => 'يى',
+ 'ﲖ' => 'يي',
+ 'ﲗ' => 'ئج',
+ 'ﲘ' => 'ئح',
+ 'ﲙ' => 'ئخ',
+ 'ﲚ' => 'ئم',
+ 'ﲛ' => 'ئه',
+ 'ﲜ' => 'بج',
+ 'ﲝ' => 'بح',
+ 'ﲞ' => 'بخ',
+ 'ﲟ' => 'بم',
+ 'ﲠ' => 'به',
+ 'ﲡ' => 'تج',
+ 'ﲢ' => 'تح',
+ 'ﲣ' => 'تخ',
+ 'ﲤ' => 'تم',
+ 'ﲥ' => 'ته',
+ 'ﲦ' => 'ثم',
+ 'ﲧ' => 'جح',
+ 'ﲨ' => 'جم',
+ 'ﲩ' => 'حج',
+ 'ﲪ' => 'حم',
+ 'ﲫ' => 'خج',
+ 'ﲬ' => 'خم',
+ 'ﲭ' => 'سج',
+ 'ﲮ' => 'سح',
+ 'ﲯ' => 'سخ',
+ 'ﲰ' => 'سم',
+ 'ﲱ' => 'صح',
+ 'ﲲ' => 'صخ',
+ 'ﲳ' => 'صم',
+ 'ﲴ' => 'ضج',
+ 'ﲵ' => 'ضح',
+ 'ﲶ' => 'ضخ',
+ 'ﲷ' => 'ضم',
+ 'ﲸ' => 'طح',
+ 'ﲹ' => 'ظم',
+ 'ﲺ' => 'عج',
+ 'ﲻ' => 'عم',
+ 'ﲼ' => 'غج',
+ 'ﲽ' => 'غم',
+ 'ﲾ' => 'فج',
+ 'ﲿ' => 'فح',
+ 'ﳀ' => 'فخ',
+ 'ﳁ' => 'فم',
+ 'ﳂ' => 'قح',
+ 'ﳃ' => 'قم',
+ 'ﳄ' => 'كج',
+ 'ﳅ' => 'كح',
+ 'ﳆ' => 'كخ',
+ 'ﳇ' => 'كل',
+ 'ﳈ' => 'كم',
+ 'ﳉ' => 'لج',
+ 'ﳊ' => 'لح',
+ 'ﳋ' => 'لخ',
+ 'ﳌ' => 'لم',
+ 'ﳍ' => 'له',
+ 'ﳎ' => 'مج',
+ 'ﳏ' => 'مح',
+ 'ﳐ' => 'مخ',
+ 'ﳑ' => 'مم',
+ 'ﳒ' => 'نج',
+ 'ﳓ' => 'نح',
+ 'ﳔ' => 'نخ',
+ 'ﳕ' => 'نم',
+ 'ﳖ' => 'نه',
+ 'ﳗ' => 'هج',
+ 'ﳘ' => 'هم',
+ 'ﳙ' => 'هٰ',
+ 'ﳚ' => 'يج',
+ 'ﳛ' => 'يح',
+ 'ﳜ' => 'يخ',
+ 'ﳝ' => 'يم',
+ 'ﳞ' => 'يه',
+ 'ﳟ' => 'ئم',
+ 'ﳠ' => 'ئه',
+ 'ﳡ' => 'بم',
+ 'ﳢ' => 'به',
+ 'ﳣ' => 'تم',
+ 'ﳤ' => 'ته',
+ 'ﳥ' => 'ثم',
+ 'ﳦ' => 'ثه',
+ 'ﳧ' => 'سم',
+ 'ﳨ' => 'سه',
+ 'ﳩ' => 'شم',
+ 'ﳪ' => 'شه',
+ 'ﳫ' => 'كل',
+ 'ﳬ' => 'كم',
+ 'ﳭ' => 'لم',
+ 'ﳮ' => 'نم',
+ 'ﳯ' => 'نه',
+ 'ﳰ' => 'يم',
+ 'ﳱ' => 'يه',
+ 'ﳲ' => 'ـَّ',
+ 'ﳳ' => 'ـُّ',
+ 'ﳴ' => 'ـِّ',
+ 'ﳵ' => 'طى',
+ 'ﳶ' => 'طي',
+ 'ﳷ' => 'عى',
+ 'ﳸ' => 'عي',
+ 'ﳹ' => 'غى',
+ 'ﳺ' => 'غي',
+ 'ﳻ' => 'سى',
+ 'ﳼ' => 'سي',
+ 'ﳽ' => 'شى',
+ 'ﳾ' => 'شي',
+ 'ﳿ' => 'حى',
+ 'ﴀ' => 'حي',
+ 'ﴁ' => 'جى',
+ 'ﴂ' => 'جي',
+ 'ﴃ' => 'خى',
+ 'ﴄ' => 'خي',
+ 'ﴅ' => 'صى',
+ 'ﴆ' => 'صي',
+ 'ﴇ' => 'ضى',
+ 'ﴈ' => 'ضي',
+ 'ﴉ' => 'شج',
+ 'ﴊ' => 'شح',
+ 'ﴋ' => 'شخ',
+ 'ﴌ' => 'شم',
+ 'ﴍ' => 'شر',
+ 'ﴎ' => 'سر',
+ 'ﴏ' => 'صر',
+ 'ﴐ' => 'ضر',
+ 'ﴑ' => 'طى',
+ 'ﴒ' => 'طي',
+ 'ﴓ' => 'عى',
+ 'ﴔ' => 'عي',
+ 'ﴕ' => 'غى',
+ 'ﴖ' => 'غي',
+ 'ﴗ' => 'سى',
+ 'ﴘ' => 'سي',
+ 'ﴙ' => 'شى',
+ 'ﴚ' => 'شي',
+ 'ﴛ' => 'حى',
+ 'ﴜ' => 'حي',
+ 'ﴝ' => 'جى',
+ 'ﴞ' => 'جي',
+ 'ﴟ' => 'خى',
+ 'ﴠ' => 'خي',
+ 'ﴡ' => 'صى',
+ 'ﴢ' => 'صي',
+ 'ﴣ' => 'ضى',
+ 'ﴤ' => 'ضي',
+ 'ﴥ' => 'شج',
+ 'ﴦ' => 'شح',
+ 'ﴧ' => 'شخ',
+ 'ﴨ' => 'شم',
+ 'ﴩ' => 'شر',
+ 'ﴪ' => 'سر',
+ 'ﴫ' => 'صر',
+ 'ﴬ' => 'ضر',
+ 'ﴭ' => 'شج',
+ 'ﴮ' => 'شح',
+ 'ﴯ' => 'شخ',
+ 'ﴰ' => 'شم',
+ 'ﴱ' => 'سه',
+ 'ﴲ' => 'شه',
+ 'ﴳ' => 'طم',
+ 'ﴴ' => 'سج',
+ 'ﴵ' => 'سح',
+ 'ﴶ' => 'سخ',
+ 'ﴷ' => 'شج',
+ 'ﴸ' => 'شح',
+ 'ﴹ' => 'شخ',
+ 'ﴺ' => 'طم',
+ 'ﴻ' => 'ظم',
+ 'ﴼ' => 'اً',
+ 'ﴽ' => 'اً',
+ 'ﵐ' => 'تجم',
+ 'ﵑ' => 'تحج',
+ 'ﵒ' => 'تحج',
+ 'ﵓ' => 'تحم',
+ 'ﵔ' => 'تخم',
+ 'ﵕ' => 'تمج',
+ 'ﵖ' => 'تمح',
+ 'ﵗ' => 'تمخ',
+ 'ﵘ' => 'جمح',
+ 'ﵙ' => 'جمح',
+ 'ﵚ' => 'حمي',
+ 'ﵛ' => 'حمى',
+ 'ﵜ' => 'سحج',
+ 'ﵝ' => 'سجح',
+ 'ﵞ' => 'سجى',
+ 'ﵟ' => 'سمح',
+ 'ﵠ' => 'سمح',
+ 'ﵡ' => 'سمج',
+ 'ﵢ' => 'سمم',
+ 'ﵣ' => 'سمم',
+ 'ﵤ' => 'صحح',
+ 'ﵥ' => 'صحح',
+ 'ﵦ' => 'صمم',
+ 'ﵧ' => 'شحم',
+ 'ﵨ' => 'شحم',
+ 'ﵩ' => 'شجي',
+ 'ﵪ' => 'شمخ',
+ 'ﵫ' => 'شمخ',
+ 'ﵬ' => 'شمم',
+ 'ﵭ' => 'شمم',
+ 'ﵮ' => 'ضحى',
+ 'ﵯ' => 'ضخم',
+ 'ﵰ' => 'ضخم',
+ 'ﵱ' => 'طمح',
+ 'ﵲ' => 'طمح',
+ 'ﵳ' => 'طمم',
+ 'ﵴ' => 'طمي',
+ 'ﵵ' => 'عجم',
+ 'ﵶ' => 'عمم',
+ 'ﵷ' => 'عمم',
+ 'ﵸ' => 'عمى',
+ 'ﵹ' => 'غمم',
+ 'ﵺ' => 'غمي',
+ 'ﵻ' => 'غمى',
+ 'ﵼ' => 'فخم',
+ 'ﵽ' => 'فخم',
+ 'ﵾ' => 'قمح',
+ 'ﵿ' => 'قمم',
+ 'ﶀ' => 'لحم',
+ 'ﶁ' => 'لحي',
+ 'ﶂ' => 'لحى',
+ 'ﶃ' => 'لجج',
+ 'ﶄ' => 'لجج',
+ 'ﶅ' => 'لخم',
+ 'ﶆ' => 'لخم',
+ 'ﶇ' => 'لمح',
+ 'ﶈ' => 'لمح',
+ 'ﶉ' => 'محج',
+ 'ﶊ' => 'محم',
+ 'ﶋ' => 'محي',
+ 'ﶌ' => 'مجح',
+ 'ﶍ' => 'مجم',
+ 'ﶎ' => 'مخج',
+ 'ﶏ' => 'مخم',
+ 'ﶒ' => 'مجخ',
+ 'ﶓ' => 'همج',
+ 'ﶔ' => 'همم',
+ 'ﶕ' => 'نحم',
+ 'ﶖ' => 'نحى',
+ 'ﶗ' => 'نجم',
+ 'ﶘ' => 'نجم',
+ 'ﶙ' => 'نجى',
+ 'ﶚ' => 'نمي',
+ 'ﶛ' => 'نمى',
+ 'ﶜ' => 'يمم',
+ 'ﶝ' => 'يمم',
+ 'ﶞ' => 'بخي',
+ 'ﶟ' => 'تجي',
+ 'ﶠ' => 'تجى',
+ 'ﶡ' => 'تخي',
+ 'ﶢ' => 'تخى',
+ 'ﶣ' => 'تمي',
+ 'ﶤ' => 'تمى',
+ 'ﶥ' => 'جمي',
+ 'ﶦ' => 'جحى',
+ 'ﶧ' => 'جمى',
+ 'ﶨ' => 'سخى',
+ 'ﶩ' => 'صحي',
+ 'ﶪ' => 'شحي',
+ 'ﶫ' => 'ضحي',
+ 'ﶬ' => 'لجي',
+ 'ﶭ' => 'لمي',
+ 'ﶮ' => 'يحي',
+ 'ﶯ' => 'يجي',
+ 'ﶰ' => 'يمي',
+ 'ﶱ' => 'ممي',
+ 'ﶲ' => 'قمي',
+ 'ﶳ' => 'نحي',
+ 'ﶴ' => 'قمح',
+ 'ﶵ' => 'لحم',
+ 'ﶶ' => 'عمي',
+ 'ﶷ' => 'كمي',
+ 'ﶸ' => 'نجح',
+ 'ﶹ' => 'مخي',
+ 'ﶺ' => 'لجم',
+ 'ﶻ' => 'كمم',
+ 'ﶼ' => 'لجم',
+ 'ﶽ' => 'نجح',
+ 'ﶾ' => 'جحي',
+ 'ﶿ' => 'حجي',
+ 'ﷀ' => 'مجي',
+ 'ﷁ' => 'فمي',
+ 'ﷂ' => 'بحي',
+ 'ﷃ' => 'كمم',
+ 'ﷄ' => 'عجم',
+ 'ﷅ' => 'صمم',
+ 'ﷆ' => 'سخي',
+ 'ﷇ' => 'نجي',
+ 'ﷰ' => 'صلے',
+ 'ﷱ' => 'قلے',
+ 'ﷲ' => 'الله',
+ 'ﷳ' => 'اكبر',
+ 'ﷴ' => 'محمد',
+ 'ﷵ' => 'صلعم',
+ 'ﷶ' => 'رسول',
+ 'ﷷ' => 'عليه',
+ 'ﷸ' => 'وسلم',
+ 'ﷹ' => 'صلى',
+ 'ﷺ' => 'صلى الله عليه وسلم',
+ 'ﷻ' => 'جل جلاله',
+ '﷼' => 'ریال',
+ '︐' => ',',
+ '︑' => '、',
+ '︒' => '。',
+ '︓' => ':',
+ '︔' => ';',
+ '︕' => '!',
+ '︖' => '?',
+ '︗' => '〖',
+ '︘' => '〗',
+ '︙' => '...',
+ '︰' => '..',
+ '︱' => '—',
+ '︲' => '–',
+ '︳' => '_',
+ '︴' => '_',
+ '︵' => '(',
+ '︶' => ')',
+ '︷' => '{',
+ '︸' => '}',
+ '︹' => '〔',
+ '︺' => '〕',
+ '︻' => '【',
+ '︼' => '】',
+ '︽' => '《',
+ '︾' => '》',
+ '︿' => '〈',
+ '﹀' => '〉',
+ '﹁' => '「',
+ '﹂' => '」',
+ '﹃' => '『',
+ '﹄' => '』',
+ '﹇' => '[',
+ '﹈' => ']',
+ '﹉' => ' ̅',
+ '﹊' => ' ̅',
+ '﹋' => ' ̅',
+ '﹌' => ' ̅',
+ '﹍' => '_',
+ '﹎' => '_',
+ '﹏' => '_',
+ '﹐' => ',',
+ '﹑' => '、',
+ '﹒' => '.',
+ '﹔' => ';',
+ '﹕' => ':',
+ '﹖' => '?',
+ '﹗' => '!',
+ '﹘' => '—',
+ '﹙' => '(',
+ '﹚' => ')',
+ '﹛' => '{',
+ '﹜' => '}',
+ '﹝' => '〔',
+ '﹞' => '〕',
+ '﹟' => '#',
+ '﹠' => '&',
+ '﹡' => '*',
+ '﹢' => '+',
+ '﹣' => '-',
+ '﹤' => '<',
+ '﹥' => '>',
+ '﹦' => '=',
+ '﹨' => '\\',
+ '﹩' => '$',
+ '﹪' => '%',
+ '﹫' => '@',
+ 'ﹰ' => ' ً',
+ 'ﹱ' => 'ـً',
+ 'ﹲ' => ' ٌ',
+ 'ﹴ' => ' ٍ',
+ 'ﹶ' => ' َ',
+ 'ﹷ' => 'ـَ',
+ 'ﹸ' => ' ُ',
+ 'ﹹ' => 'ـُ',
+ 'ﹺ' => ' ِ',
+ 'ﹻ' => 'ـِ',
+ 'ﹼ' => ' ّ',
+ 'ﹽ' => 'ـّ',
+ 'ﹾ' => ' ْ',
+ 'ﹿ' => 'ـْ',
+ 'ﺀ' => 'ء',
+ 'ﺁ' => 'آ',
+ 'ﺂ' => 'آ',
+ 'ﺃ' => 'أ',
+ 'ﺄ' => 'أ',
+ 'ﺅ' => 'ؤ',
+ 'ﺆ' => 'ؤ',
+ 'ﺇ' => 'إ',
+ 'ﺈ' => 'إ',
+ 'ﺉ' => 'ئ',
+ 'ﺊ' => 'ئ',
+ 'ﺋ' => 'ئ',
+ 'ﺌ' => 'ئ',
+ 'ﺍ' => 'ا',
+ 'ﺎ' => 'ا',
+ 'ﺏ' => 'ب',
+ 'ﺐ' => 'ب',
+ 'ﺑ' => 'ب',
+ 'ﺒ' => 'ب',
+ 'ﺓ' => 'ة',
+ 'ﺔ' => 'ة',
+ 'ﺕ' => 'ت',
+ 'ﺖ' => 'ت',
+ 'ﺗ' => 'ت',
+ 'ﺘ' => 'ت',
+ 'ﺙ' => 'ث',
+ 'ﺚ' => 'ث',
+ 'ﺛ' => 'ث',
+ 'ﺜ' => 'ث',
+ 'ﺝ' => 'ج',
+ 'ﺞ' => 'ج',
+ 'ﺟ' => 'ج',
+ 'ﺠ' => 'ج',
+ 'ﺡ' => 'ح',
+ 'ﺢ' => 'ح',
+ 'ﺣ' => 'ح',
+ 'ﺤ' => 'ح',
+ 'ﺥ' => 'خ',
+ 'ﺦ' => 'خ',
+ 'ﺧ' => 'خ',
+ 'ﺨ' => 'خ',
+ 'ﺩ' => 'د',
+ 'ﺪ' => 'د',
+ 'ﺫ' => 'ذ',
+ 'ﺬ' => 'ذ',
+ 'ﺭ' => 'ر',
+ 'ﺮ' => 'ر',
+ 'ﺯ' => 'ز',
+ 'ﺰ' => 'ز',
+ 'ﺱ' => 'س',
+ 'ﺲ' => 'س',
+ 'ﺳ' => 'س',
+ 'ﺴ' => 'س',
+ 'ﺵ' => 'ش',
+ 'ﺶ' => 'ش',
+ 'ﺷ' => 'ش',
+ 'ﺸ' => 'ش',
+ 'ﺹ' => 'ص',
+ 'ﺺ' => 'ص',
+ 'ﺻ' => 'ص',
+ 'ﺼ' => 'ص',
+ 'ﺽ' => 'ض',
+ 'ﺾ' => 'ض',
+ 'ﺿ' => 'ض',
+ 'ﻀ' => 'ض',
+ 'ﻁ' => 'ط',
+ 'ﻂ' => 'ط',
+ 'ﻃ' => 'ط',
+ 'ﻄ' => 'ط',
+ 'ﻅ' => 'ظ',
+ 'ﻆ' => 'ظ',
+ 'ﻇ' => 'ظ',
+ 'ﻈ' => 'ظ',
+ 'ﻉ' => 'ع',
+ 'ﻊ' => 'ع',
+ 'ﻋ' => 'ع',
+ 'ﻌ' => 'ع',
+ 'ﻍ' => 'غ',
+ 'ﻎ' => 'غ',
+ 'ﻏ' => 'غ',
+ 'ﻐ' => 'غ',
+ 'ﻑ' => 'ف',
+ 'ﻒ' => 'ف',
+ 'ﻓ' => 'ف',
+ 'ﻔ' => 'ف',
+ 'ﻕ' => 'ق',
+ 'ﻖ' => 'ق',
+ 'ﻗ' => 'ق',
+ 'ﻘ' => 'ق',
+ 'ﻙ' => 'ك',
+ 'ﻚ' => 'ك',
+ 'ﻛ' => 'ك',
+ 'ﻜ' => 'ك',
+ 'ﻝ' => 'ل',
+ 'ﻞ' => 'ل',
+ 'ﻟ' => 'ل',
+ 'ﻠ' => 'ل',
+ 'ﻡ' => 'م',
+ 'ﻢ' => 'م',
+ 'ﻣ' => 'م',
+ 'ﻤ' => 'م',
+ 'ﻥ' => 'ن',
+ 'ﻦ' => 'ن',
+ 'ﻧ' => 'ن',
+ 'ﻨ' => 'ن',
+ 'ﻩ' => 'ه',
+ 'ﻪ' => 'ه',
+ 'ﻫ' => 'ه',
+ 'ﻬ' => 'ه',
+ 'ﻭ' => 'و',
+ 'ﻮ' => 'و',
+ 'ﻯ' => 'ى',
+ 'ﻰ' => 'ى',
+ 'ﻱ' => 'ي',
+ 'ﻲ' => 'ي',
+ 'ﻳ' => 'ي',
+ 'ﻴ' => 'ي',
+ 'ﻵ' => 'لآ',
+ 'ﻶ' => 'لآ',
+ 'ﻷ' => 'لأ',
+ 'ﻸ' => 'لأ',
+ 'ﻹ' => 'لإ',
+ 'ﻺ' => 'لإ',
+ 'ﻻ' => 'لا',
+ 'ﻼ' => 'لا',
+ '!' => '!',
+ '"' => '"',
+ '#' => '#',
+ '$' => '$',
+ '%' => '%',
+ '&' => '&',
+ ''' => '\'',
+ '(' => '(',
+ ')' => ')',
+ '*' => '*',
+ '+' => '+',
+ ',' => ',',
+ '-' => '-',
+ '.' => '.',
+ '/' => '/',
+ '0' => '0',
+ '1' => '1',
+ '2' => '2',
+ '3' => '3',
+ '4' => '4',
+ '5' => '5',
+ '6' => '6',
+ '7' => '7',
+ '8' => '8',
+ '9' => '9',
+ ':' => ':',
+ ';' => ';',
+ '<' => '<',
+ '=' => '=',
+ '>' => '>',
+ '?' => '?',
+ '@' => '@',
+ 'A' => 'A',
+ 'B' => 'B',
+ 'C' => 'C',
+ 'D' => 'D',
+ 'E' => 'E',
+ 'F' => 'F',
+ 'G' => 'G',
+ 'H' => 'H',
+ 'I' => 'I',
+ 'J' => 'J',
+ 'K' => 'K',
+ 'L' => 'L',
+ 'M' => 'M',
+ 'N' => 'N',
+ 'O' => 'O',
+ 'P' => 'P',
+ 'Q' => 'Q',
+ 'R' => 'R',
+ 'S' => 'S',
+ 'T' => 'T',
+ 'U' => 'U',
+ 'V' => 'V',
+ 'W' => 'W',
+ 'X' => 'X',
+ 'Y' => 'Y',
+ 'Z' => 'Z',
+ '[' => '[',
+ '\' => '\\',
+ ']' => ']',
+ '^' => '^',
+ '_' => '_',
+ '`' => '`',
+ 'a' => 'a',
+ 'b' => 'b',
+ 'c' => 'c',
+ 'd' => 'd',
+ 'e' => 'e',
+ 'f' => 'f',
+ 'g' => 'g',
+ 'h' => 'h',
+ 'i' => 'i',
+ 'j' => 'j',
+ 'k' => 'k',
+ 'l' => 'l',
+ 'm' => 'm',
+ 'n' => 'n',
+ 'o' => 'o',
+ 'p' => 'p',
+ 'q' => 'q',
+ 'r' => 'r',
+ 's' => 's',
+ 't' => 't',
+ 'u' => 'u',
+ 'v' => 'v',
+ 'w' => 'w',
+ 'x' => 'x',
+ 'y' => 'y',
+ 'z' => 'z',
+ '{' => '{',
+ '|' => '|',
+ '}' => '}',
+ '~' => '~',
+ '⦅' => '⦅',
+ '⦆' => '⦆',
+ '。' => '。',
+ '「' => '「',
+ '」' => '」',
+ '、' => '、',
+ '・' => '・',
+ 'ヲ' => 'ヲ',
+ 'ァ' => 'ァ',
+ 'ィ' => 'ィ',
+ 'ゥ' => 'ゥ',
+ 'ェ' => 'ェ',
+ 'ォ' => 'ォ',
+ 'ャ' => 'ャ',
+ 'ュ' => 'ュ',
+ 'ョ' => 'ョ',
+ 'ッ' => 'ッ',
+ 'ー' => 'ー',
+ 'ア' => 'ア',
+ 'イ' => 'イ',
+ 'ウ' => 'ウ',
+ 'エ' => 'エ',
+ 'オ' => 'オ',
+ 'カ' => 'カ',
+ 'キ' => 'キ',
+ 'ク' => 'ク',
+ 'ケ' => 'ケ',
+ 'コ' => 'コ',
+ 'サ' => 'サ',
+ 'シ' => 'シ',
+ 'ス' => 'ス',
+ 'セ' => 'セ',
+ 'ソ' => 'ソ',
+ 'タ' => 'タ',
+ 'チ' => 'チ',
+ 'ツ' => 'ツ',
+ 'テ' => 'テ',
+ 'ト' => 'ト',
+ 'ナ' => 'ナ',
+ 'ニ' => 'ニ',
+ 'ヌ' => 'ヌ',
+ 'ネ' => 'ネ',
+ 'ノ' => 'ノ',
+ 'ハ' => 'ハ',
+ 'ヒ' => 'ヒ',
+ 'フ' => 'フ',
+ 'ヘ' => 'ヘ',
+ 'ホ' => 'ホ',
+ 'マ' => 'マ',
+ 'ミ' => 'ミ',
+ 'ム' => 'ム',
+ 'メ' => 'メ',
+ 'モ' => 'モ',
+ 'ヤ' => 'ヤ',
+ 'ユ' => 'ユ',
+ 'ヨ' => 'ヨ',
+ 'ラ' => 'ラ',
+ 'リ' => 'リ',
+ 'ル' => 'ル',
+ 'レ' => 'レ',
+ 'ロ' => 'ロ',
+ 'ワ' => 'ワ',
+ 'ン' => 'ン',
+ '゙' => '゙',
+ '゚' => '゚',
+ 'ᅠ' => 'ᅠ',
+ 'ᄀ' => 'ᄀ',
+ 'ᄁ' => 'ᄁ',
+ 'ᆪ' => 'ᆪ',
+ 'ᄂ' => 'ᄂ',
+ 'ᆬ' => 'ᆬ',
+ 'ᆭ' => 'ᆭ',
+ 'ᄃ' => 'ᄃ',
+ 'ᄄ' => 'ᄄ',
+ 'ᄅ' => 'ᄅ',
+ 'ᆰ' => 'ᆰ',
+ 'ᆱ' => 'ᆱ',
+ 'ᆲ' => 'ᆲ',
+ 'ᆳ' => 'ᆳ',
+ 'ᆴ' => 'ᆴ',
+ 'ᆵ' => 'ᆵ',
+ 'ᄚ' => 'ᄚ',
+ 'ᄆ' => 'ᄆ',
+ 'ᄇ' => 'ᄇ',
+ 'ᄈ' => 'ᄈ',
+ 'ᄡ' => 'ᄡ',
+ 'ᄉ' => 'ᄉ',
+ 'ᄊ' => 'ᄊ',
+ 'ᄋ' => 'ᄋ',
+ 'ᄌ' => 'ᄌ',
+ 'ᄍ' => 'ᄍ',
+ 'ᄎ' => 'ᄎ',
+ 'ᄏ' => 'ᄏ',
+ 'ᄐ' => 'ᄐ',
+ 'ᄑ' => 'ᄑ',
+ 'ᄒ' => 'ᄒ',
+ 'ᅡ' => 'ᅡ',
+ 'ᅢ' => 'ᅢ',
+ 'ᅣ' => 'ᅣ',
+ 'ᅤ' => 'ᅤ',
+ 'ᅥ' => 'ᅥ',
+ 'ᅦ' => 'ᅦ',
+ 'ᅧ' => 'ᅧ',
+ 'ᅨ' => 'ᅨ',
+ 'ᅩ' => 'ᅩ',
+ 'ᅪ' => 'ᅪ',
+ 'ᅫ' => 'ᅫ',
+ 'ᅬ' => 'ᅬ',
+ 'ᅭ' => 'ᅭ',
+ 'ᅮ' => 'ᅮ',
+ 'ᅯ' => 'ᅯ',
+ 'ᅰ' => 'ᅰ',
+ 'ᅱ' => 'ᅱ',
+ 'ᅲ' => 'ᅲ',
+ 'ᅳ' => 'ᅳ',
+ 'ᅴ' => 'ᅴ',
+ 'ᅵ' => 'ᅵ',
+ '¢' => '¢',
+ '£' => '£',
+ '¬' => '¬',
+ ' ̄' => ' ̄',
+ '¦' => '¦',
+ '¥' => '¥',
+ '₩' => '₩',
+ '│' => '│',
+ '←' => '←',
+ '↑' => '↑',
+ '→' => '→',
+ '↓' => '↓',
+ '■' => '■',
+ '○' => '○',
+ '𝐀' => 'A',
+ '𝐁' => 'B',
+ '𝐂' => 'C',
+ '𝐃' => 'D',
+ '𝐄' => 'E',
+ '𝐅' => 'F',
+ '𝐆' => 'G',
+ '𝐇' => 'H',
+ '𝐈' => 'I',
+ '𝐉' => 'J',
+ '𝐊' => 'K',
+ '𝐋' => 'L',
+ '𝐌' => 'M',
+ '𝐍' => 'N',
+ '𝐎' => 'O',
+ '𝐏' => 'P',
+ '𝐐' => 'Q',
+ '𝐑' => 'R',
+ '𝐒' => 'S',
+ '𝐓' => 'T',
+ '𝐔' => 'U',
+ '𝐕' => 'V',
+ '𝐖' => 'W',
+ '𝐗' => 'X',
+ '𝐘' => 'Y',
+ '𝐙' => 'Z',
+ '𝐚' => 'a',
+ '𝐛' => 'b',
+ '𝐜' => 'c',
+ '𝐝' => 'd',
+ '𝐞' => 'e',
+ '𝐟' => 'f',
+ '𝐠' => 'g',
+ '𝐡' => 'h',
+ '𝐢' => 'i',
+ '𝐣' => 'j',
+ '𝐤' => 'k',
+ '𝐥' => 'l',
+ '𝐦' => 'm',
+ '𝐧' => 'n',
+ '𝐨' => 'o',
+ '𝐩' => 'p',
+ '𝐪' => 'q',
+ '𝐫' => 'r',
+ '𝐬' => 's',
+ '𝐭' => 't',
+ '𝐮' => 'u',
+ '𝐯' => 'v',
+ '𝐰' => 'w',
+ '𝐱' => 'x',
+ '𝐲' => 'y',
+ '𝐳' => 'z',
+ '𝐴' => 'A',
+ '𝐵' => 'B',
+ '𝐶' => 'C',
+ '𝐷' => 'D',
+ '𝐸' => 'E',
+ '𝐹' => 'F',
+ '𝐺' => 'G',
+ '𝐻' => 'H',
+ '𝐼' => 'I',
+ '𝐽' => 'J',
+ '𝐾' => 'K',
+ '𝐿' => 'L',
+ '𝑀' => 'M',
+ '𝑁' => 'N',
+ '𝑂' => 'O',
+ '𝑃' => 'P',
+ '𝑄' => 'Q',
+ '𝑅' => 'R',
+ '𝑆' => 'S',
+ '𝑇' => 'T',
+ '𝑈' => 'U',
+ '𝑉' => 'V',
+ '𝑊' => 'W',
+ '𝑋' => 'X',
+ '𝑌' => 'Y',
+ '𝑍' => 'Z',
+ '𝑎' => 'a',
+ '𝑏' => 'b',
+ '𝑐' => 'c',
+ '𝑑' => 'd',
+ '𝑒' => 'e',
+ '𝑓' => 'f',
+ '𝑔' => 'g',
+ '𝑖' => 'i',
+ '𝑗' => 'j',
+ '𝑘' => 'k',
+ '𝑙' => 'l',
+ '𝑚' => 'm',
+ '𝑛' => 'n',
+ '𝑜' => 'o',
+ '𝑝' => 'p',
+ '𝑞' => 'q',
+ '𝑟' => 'r',
+ '𝑠' => 's',
+ '𝑡' => 't',
+ '𝑢' => 'u',
+ '𝑣' => 'v',
+ '𝑤' => 'w',
+ '𝑥' => 'x',
+ '𝑦' => 'y',
+ '𝑧' => 'z',
+ '𝑨' => 'A',
+ '𝑩' => 'B',
+ '𝑪' => 'C',
+ '𝑫' => 'D',
+ '𝑬' => 'E',
+ '𝑭' => 'F',
+ '𝑮' => 'G',
+ '𝑯' => 'H',
+ '𝑰' => 'I',
+ '𝑱' => 'J',
+ '𝑲' => 'K',
+ '𝑳' => 'L',
+ '𝑴' => 'M',
+ '𝑵' => 'N',
+ '𝑶' => 'O',
+ '𝑷' => 'P',
+ '𝑸' => 'Q',
+ '𝑹' => 'R',
+ '𝑺' => 'S',
+ '𝑻' => 'T',
+ '𝑼' => 'U',
+ '𝑽' => 'V',
+ '𝑾' => 'W',
+ '𝑿' => 'X',
+ '𝒀' => 'Y',
+ '𝒁' => 'Z',
+ '𝒂' => 'a',
+ '𝒃' => 'b',
+ '𝒄' => 'c',
+ '𝒅' => 'd',
+ '𝒆' => 'e',
+ '𝒇' => 'f',
+ '𝒈' => 'g',
+ '𝒉' => 'h',
+ '𝒊' => 'i',
+ '𝒋' => 'j',
+ '𝒌' => 'k',
+ '𝒍' => 'l',
+ '𝒎' => 'm',
+ '𝒏' => 'n',
+ '𝒐' => 'o',
+ '𝒑' => 'p',
+ '𝒒' => 'q',
+ '𝒓' => 'r',
+ '𝒔' => 's',
+ '𝒕' => 't',
+ '𝒖' => 'u',
+ '𝒗' => 'v',
+ '𝒘' => 'w',
+ '𝒙' => 'x',
+ '𝒚' => 'y',
+ '𝒛' => 'z',
+ '𝒜' => 'A',
+ '𝒞' => 'C',
+ '𝒟' => 'D',
+ '𝒢' => 'G',
+ '𝒥' => 'J',
+ '𝒦' => 'K',
+ '𝒩' => 'N',
+ '𝒪' => 'O',
+ '𝒫' => 'P',
+ '𝒬' => 'Q',
+ '𝒮' => 'S',
+ '𝒯' => 'T',
+ '𝒰' => 'U',
+ '𝒱' => 'V',
+ '𝒲' => 'W',
+ '𝒳' => 'X',
+ '𝒴' => 'Y',
+ '𝒵' => 'Z',
+ '𝒶' => 'a',
+ '𝒷' => 'b',
+ '𝒸' => 'c',
+ '𝒹' => 'd',
+ '𝒻' => 'f',
+ '𝒽' => 'h',
+ '𝒾' => 'i',
+ '𝒿' => 'j',
+ '𝓀' => 'k',
+ '𝓁' => 'l',
+ '𝓂' => 'm',
+ '𝓃' => 'n',
+ '𝓅' => 'p',
+ '𝓆' => 'q',
+ '𝓇' => 'r',
+ '𝓈' => 's',
+ '𝓉' => 't',
+ '𝓊' => 'u',
+ '𝓋' => 'v',
+ '𝓌' => 'w',
+ '𝓍' => 'x',
+ '𝓎' => 'y',
+ '𝓏' => 'z',
+ '𝓐' => 'A',
+ '𝓑' => 'B',
+ '𝓒' => 'C',
+ '𝓓' => 'D',
+ '𝓔' => 'E',
+ '𝓕' => 'F',
+ '𝓖' => 'G',
+ '𝓗' => 'H',
+ '𝓘' => 'I',
+ '𝓙' => 'J',
+ '𝓚' => 'K',
+ '𝓛' => 'L',
+ '𝓜' => 'M',
+ '𝓝' => 'N',
+ '𝓞' => 'O',
+ '𝓟' => 'P',
+ '𝓠' => 'Q',
+ '𝓡' => 'R',
+ '𝓢' => 'S',
+ '𝓣' => 'T',
+ '𝓤' => 'U',
+ '𝓥' => 'V',
+ '𝓦' => 'W',
+ '𝓧' => 'X',
+ '𝓨' => 'Y',
+ '𝓩' => 'Z',
+ '𝓪' => 'a',
+ '𝓫' => 'b',
+ '𝓬' => 'c',
+ '𝓭' => 'd',
+ '𝓮' => 'e',
+ '𝓯' => 'f',
+ '𝓰' => 'g',
+ '𝓱' => 'h',
+ '𝓲' => 'i',
+ '𝓳' => 'j',
+ '𝓴' => 'k',
+ '𝓵' => 'l',
+ '𝓶' => 'm',
+ '𝓷' => 'n',
+ '𝓸' => 'o',
+ '𝓹' => 'p',
+ '𝓺' => 'q',
+ '𝓻' => 'r',
+ '𝓼' => 's',
+ '𝓽' => 't',
+ '𝓾' => 'u',
+ '𝓿' => 'v',
+ '𝔀' => 'w',
+ '𝔁' => 'x',
+ '𝔂' => 'y',
+ '𝔃' => 'z',
+ '𝔄' => 'A',
+ '𝔅' => 'B',
+ '𝔇' => 'D',
+ '𝔈' => 'E',
+ '𝔉' => 'F',
+ '𝔊' => 'G',
+ '𝔍' => 'J',
+ '𝔎' => 'K',
+ '𝔏' => 'L',
+ '𝔐' => 'M',
+ '𝔑' => 'N',
+ '𝔒' => 'O',
+ '𝔓' => 'P',
+ '𝔔' => 'Q',
+ '𝔖' => 'S',
+ '𝔗' => 'T',
+ '𝔘' => 'U',
+ '𝔙' => 'V',
+ '𝔚' => 'W',
+ '𝔛' => 'X',
+ '𝔜' => 'Y',
+ '𝔞' => 'a',
+ '𝔟' => 'b',
+ '𝔠' => 'c',
+ '𝔡' => 'd',
+ '𝔢' => 'e',
+ '𝔣' => 'f',
+ '𝔤' => 'g',
+ '𝔥' => 'h',
+ '𝔦' => 'i',
+ '𝔧' => 'j',
+ '𝔨' => 'k',
+ '𝔩' => 'l',
+ '𝔪' => 'm',
+ '𝔫' => 'n',
+ '𝔬' => 'o',
+ '𝔭' => 'p',
+ '𝔮' => 'q',
+ '𝔯' => 'r',
+ '𝔰' => 's',
+ '𝔱' => 't',
+ '𝔲' => 'u',
+ '𝔳' => 'v',
+ '𝔴' => 'w',
+ '𝔵' => 'x',
+ '𝔶' => 'y',
+ '𝔷' => 'z',
+ '𝔸' => 'A',
+ '𝔹' => 'B',
+ '𝔻' => 'D',
+ '𝔼' => 'E',
+ '𝔽' => 'F',
+ '𝔾' => 'G',
+ '𝕀' => 'I',
+ '𝕁' => 'J',
+ '𝕂' => 'K',
+ '𝕃' => 'L',
+ '𝕄' => 'M',
+ '𝕆' => 'O',
+ '𝕊' => 'S',
+ '𝕋' => 'T',
+ '𝕌' => 'U',
+ '𝕍' => 'V',
+ '𝕎' => 'W',
+ '𝕏' => 'X',
+ '𝕐' => 'Y',
+ '𝕒' => 'a',
+ '𝕓' => 'b',
+ '𝕔' => 'c',
+ '𝕕' => 'd',
+ '𝕖' => 'e',
+ '𝕗' => 'f',
+ '𝕘' => 'g',
+ '𝕙' => 'h',
+ '𝕚' => 'i',
+ '𝕛' => 'j',
+ '𝕜' => 'k',
+ '𝕝' => 'l',
+ '𝕞' => 'm',
+ '𝕟' => 'n',
+ '𝕠' => 'o',
+ '𝕡' => 'p',
+ '𝕢' => 'q',
+ '𝕣' => 'r',
+ '𝕤' => 's',
+ '𝕥' => 't',
+ '𝕦' => 'u',
+ '𝕧' => 'v',
+ '𝕨' => 'w',
+ '𝕩' => 'x',
+ '𝕪' => 'y',
+ '𝕫' => 'z',
+ '𝕬' => 'A',
+ '𝕭' => 'B',
+ '𝕮' => 'C',
+ '𝕯' => 'D',
+ '𝕰' => 'E',
+ '𝕱' => 'F',
+ '𝕲' => 'G',
+ '𝕳' => 'H',
+ '𝕴' => 'I',
+ '𝕵' => 'J',
+ '𝕶' => 'K',
+ '𝕷' => 'L',
+ '𝕸' => 'M',
+ '𝕹' => 'N',
+ '𝕺' => 'O',
+ '𝕻' => 'P',
+ '𝕼' => 'Q',
+ '𝕽' => 'R',
+ '𝕾' => 'S',
+ '𝕿' => 'T',
+ '𝖀' => 'U',
+ '𝖁' => 'V',
+ '𝖂' => 'W',
+ '𝖃' => 'X',
+ '𝖄' => 'Y',
+ '𝖅' => 'Z',
+ '𝖆' => 'a',
+ '𝖇' => 'b',
+ '𝖈' => 'c',
+ '𝖉' => 'd',
+ '𝖊' => 'e',
+ '𝖋' => 'f',
+ '𝖌' => 'g',
+ '𝖍' => 'h',
+ '𝖎' => 'i',
+ '𝖏' => 'j',
+ '𝖐' => 'k',
+ '𝖑' => 'l',
+ '𝖒' => 'm',
+ '𝖓' => 'n',
+ '𝖔' => 'o',
+ '𝖕' => 'p',
+ '𝖖' => 'q',
+ '𝖗' => 'r',
+ '𝖘' => 's',
+ '𝖙' => 't',
+ '𝖚' => 'u',
+ '𝖛' => 'v',
+ '𝖜' => 'w',
+ '𝖝' => 'x',
+ '𝖞' => 'y',
+ '𝖟' => 'z',
+ '𝖠' => 'A',
+ '𝖡' => 'B',
+ '𝖢' => 'C',
+ '𝖣' => 'D',
+ '𝖤' => 'E',
+ '𝖥' => 'F',
+ '𝖦' => 'G',
+ '𝖧' => 'H',
+ '𝖨' => 'I',
+ '𝖩' => 'J',
+ '𝖪' => 'K',
+ '𝖫' => 'L',
+ '𝖬' => 'M',
+ '𝖭' => 'N',
+ '𝖮' => 'O',
+ '𝖯' => 'P',
+ '𝖰' => 'Q',
+ '𝖱' => 'R',
+ '𝖲' => 'S',
+ '𝖳' => 'T',
+ '𝖴' => 'U',
+ '𝖵' => 'V',
+ '𝖶' => 'W',
+ '𝖷' => 'X',
+ '𝖸' => 'Y',
+ '𝖹' => 'Z',
+ '𝖺' => 'a',
+ '𝖻' => 'b',
+ '𝖼' => 'c',
+ '𝖽' => 'd',
+ '𝖾' => 'e',
+ '𝖿' => 'f',
+ '𝗀' => 'g',
+ '𝗁' => 'h',
+ '𝗂' => 'i',
+ '𝗃' => 'j',
+ '𝗄' => 'k',
+ '𝗅' => 'l',
+ '𝗆' => 'm',
+ '𝗇' => 'n',
+ '𝗈' => 'o',
+ '𝗉' => 'p',
+ '𝗊' => 'q',
+ '𝗋' => 'r',
+ '𝗌' => 's',
+ '𝗍' => 't',
+ '𝗎' => 'u',
+ '𝗏' => 'v',
+ '𝗐' => 'w',
+ '𝗑' => 'x',
+ '𝗒' => 'y',
+ '𝗓' => 'z',
+ '𝗔' => 'A',
+ '𝗕' => 'B',
+ '𝗖' => 'C',
+ '𝗗' => 'D',
+ '𝗘' => 'E',
+ '𝗙' => 'F',
+ '𝗚' => 'G',
+ '𝗛' => 'H',
+ '𝗜' => 'I',
+ '𝗝' => 'J',
+ '𝗞' => 'K',
+ '𝗟' => 'L',
+ '𝗠' => 'M',
+ '𝗡' => 'N',
+ '𝗢' => 'O',
+ '𝗣' => 'P',
+ '𝗤' => 'Q',
+ '𝗥' => 'R',
+ '𝗦' => 'S',
+ '𝗧' => 'T',
+ '𝗨' => 'U',
+ '𝗩' => 'V',
+ '𝗪' => 'W',
+ '𝗫' => 'X',
+ '𝗬' => 'Y',
+ '𝗭' => 'Z',
+ '𝗮' => 'a',
+ '𝗯' => 'b',
+ '𝗰' => 'c',
+ '𝗱' => 'd',
+ '𝗲' => 'e',
+ '𝗳' => 'f',
+ '𝗴' => 'g',
+ '𝗵' => 'h',
+ '𝗶' => 'i',
+ '𝗷' => 'j',
+ '𝗸' => 'k',
+ '𝗹' => 'l',
+ '𝗺' => 'm',
+ '𝗻' => 'n',
+ '𝗼' => 'o',
+ '𝗽' => 'p',
+ '𝗾' => 'q',
+ '𝗿' => 'r',
+ '𝘀' => 's',
+ '𝘁' => 't',
+ '𝘂' => 'u',
+ '𝘃' => 'v',
+ '𝘄' => 'w',
+ '𝘅' => 'x',
+ '𝘆' => 'y',
+ '𝘇' => 'z',
+ '𝘈' => 'A',
+ '𝘉' => 'B',
+ '𝘊' => 'C',
+ '𝘋' => 'D',
+ '𝘌' => 'E',
+ '𝘍' => 'F',
+ '𝘎' => 'G',
+ '𝘏' => 'H',
+ '𝘐' => 'I',
+ '𝘑' => 'J',
+ '𝘒' => 'K',
+ '𝘓' => 'L',
+ '𝘔' => 'M',
+ '𝘕' => 'N',
+ '𝘖' => 'O',
+ '𝘗' => 'P',
+ '𝘘' => 'Q',
+ '𝘙' => 'R',
+ '𝘚' => 'S',
+ '𝘛' => 'T',
+ '𝘜' => 'U',
+ '𝘝' => 'V',
+ '𝘞' => 'W',
+ '𝘟' => 'X',
+ '𝘠' => 'Y',
+ '𝘡' => 'Z',
+ '𝘢' => 'a',
+ '𝘣' => 'b',
+ '𝘤' => 'c',
+ '𝘥' => 'd',
+ '𝘦' => 'e',
+ '𝘧' => 'f',
+ '𝘨' => 'g',
+ '𝘩' => 'h',
+ '𝘪' => 'i',
+ '𝘫' => 'j',
+ '𝘬' => 'k',
+ '𝘭' => 'l',
+ '𝘮' => 'm',
+ '𝘯' => 'n',
+ '𝘰' => 'o',
+ '𝘱' => 'p',
+ '𝘲' => 'q',
+ '𝘳' => 'r',
+ '𝘴' => 's',
+ '𝘵' => 't',
+ '𝘶' => 'u',
+ '𝘷' => 'v',
+ '𝘸' => 'w',
+ '𝘹' => 'x',
+ '𝘺' => 'y',
+ '𝘻' => 'z',
+ '𝘼' => 'A',
+ '𝘽' => 'B',
+ '𝘾' => 'C',
+ '𝘿' => 'D',
+ '𝙀' => 'E',
+ '𝙁' => 'F',
+ '𝙂' => 'G',
+ '𝙃' => 'H',
+ '𝙄' => 'I',
+ '𝙅' => 'J',
+ '𝙆' => 'K',
+ '𝙇' => 'L',
+ '𝙈' => 'M',
+ '𝙉' => 'N',
+ '𝙊' => 'O',
+ '𝙋' => 'P',
+ '𝙌' => 'Q',
+ '𝙍' => 'R',
+ '𝙎' => 'S',
+ '𝙏' => 'T',
+ '𝙐' => 'U',
+ '𝙑' => 'V',
+ '𝙒' => 'W',
+ '𝙓' => 'X',
+ '𝙔' => 'Y',
+ '𝙕' => 'Z',
+ '𝙖' => 'a',
+ '𝙗' => 'b',
+ '𝙘' => 'c',
+ '𝙙' => 'd',
+ '𝙚' => 'e',
+ '𝙛' => 'f',
+ '𝙜' => 'g',
+ '𝙝' => 'h',
+ '𝙞' => 'i',
+ '𝙟' => 'j',
+ '𝙠' => 'k',
+ '𝙡' => 'l',
+ '𝙢' => 'm',
+ '𝙣' => 'n',
+ '𝙤' => 'o',
+ '𝙥' => 'p',
+ '𝙦' => 'q',
+ '𝙧' => 'r',
+ '𝙨' => 's',
+ '𝙩' => 't',
+ '𝙪' => 'u',
+ '𝙫' => 'v',
+ '𝙬' => 'w',
+ '𝙭' => 'x',
+ '𝙮' => 'y',
+ '𝙯' => 'z',
+ '𝙰' => 'A',
+ '𝙱' => 'B',
+ '𝙲' => 'C',
+ '𝙳' => 'D',
+ '𝙴' => 'E',
+ '𝙵' => 'F',
+ '𝙶' => 'G',
+ '𝙷' => 'H',
+ '𝙸' => 'I',
+ '𝙹' => 'J',
+ '𝙺' => 'K',
+ '𝙻' => 'L',
+ '𝙼' => 'M',
+ '𝙽' => 'N',
+ '𝙾' => 'O',
+ '𝙿' => 'P',
+ '𝚀' => 'Q',
+ '𝚁' => 'R',
+ '𝚂' => 'S',
+ '𝚃' => 'T',
+ '𝚄' => 'U',
+ '𝚅' => 'V',
+ '𝚆' => 'W',
+ '𝚇' => 'X',
+ '𝚈' => 'Y',
+ '𝚉' => 'Z',
+ '𝚊' => 'a',
+ '𝚋' => 'b',
+ '𝚌' => 'c',
+ '𝚍' => 'd',
+ '𝚎' => 'e',
+ '𝚏' => 'f',
+ '𝚐' => 'g',
+ '𝚑' => 'h',
+ '𝚒' => 'i',
+ '𝚓' => 'j',
+ '𝚔' => 'k',
+ '𝚕' => 'l',
+ '𝚖' => 'm',
+ '𝚗' => 'n',
+ '𝚘' => 'o',
+ '𝚙' => 'p',
+ '𝚚' => 'q',
+ '𝚛' => 'r',
+ '𝚜' => 's',
+ '𝚝' => 't',
+ '𝚞' => 'u',
+ '𝚟' => 'v',
+ '𝚠' => 'w',
+ '𝚡' => 'x',
+ '𝚢' => 'y',
+ '𝚣' => 'z',
+ '𝚤' => 'ı',
+ '𝚥' => 'ȷ',
+ '𝚨' => 'Α',
+ '𝚩' => 'Β',
+ '𝚪' => 'Γ',
+ '𝚫' => 'Δ',
+ '𝚬' => 'Ε',
+ '𝚭' => 'Ζ',
+ '𝚮' => 'Η',
+ '𝚯' => 'Θ',
+ '𝚰' => 'Ι',
+ '𝚱' => 'Κ',
+ '𝚲' => 'Λ',
+ '𝚳' => 'Μ',
+ '𝚴' => 'Ν',
+ '𝚵' => 'Ξ',
+ '𝚶' => 'Ο',
+ '𝚷' => 'Π',
+ '𝚸' => 'Ρ',
+ '𝚹' => 'Θ',
+ '𝚺' => 'Σ',
+ '𝚻' => 'Τ',
+ '𝚼' => 'Υ',
+ '𝚽' => 'Φ',
+ '𝚾' => 'Χ',
+ '𝚿' => 'Ψ',
+ '𝛀' => 'Ω',
+ '𝛁' => '∇',
+ '𝛂' => 'α',
+ '𝛃' => 'β',
+ '𝛄' => 'γ',
+ '𝛅' => 'δ',
+ '𝛆' => 'ε',
+ '𝛇' => 'ζ',
+ '𝛈' => 'η',
+ '𝛉' => 'θ',
+ '𝛊' => 'ι',
+ '𝛋' => 'κ',
+ '𝛌' => 'λ',
+ '𝛍' => 'μ',
+ '𝛎' => 'ν',
+ '𝛏' => 'ξ',
+ '𝛐' => 'ο',
+ '𝛑' => 'π',
+ '𝛒' => 'ρ',
+ '𝛓' => 'ς',
+ '𝛔' => 'σ',
+ '𝛕' => 'τ',
+ '𝛖' => 'υ',
+ '𝛗' => 'φ',
+ '𝛘' => 'χ',
+ '𝛙' => 'ψ',
+ '𝛚' => 'ω',
+ '𝛛' => '∂',
+ '𝛜' => 'ε',
+ '𝛝' => 'θ',
+ '𝛞' => 'κ',
+ '𝛟' => 'φ',
+ '𝛠' => 'ρ',
+ '𝛡' => 'π',
+ '𝛢' => 'Α',
+ '𝛣' => 'Β',
+ '𝛤' => 'Γ',
+ '𝛥' => 'Δ',
+ '𝛦' => 'Ε',
+ '𝛧' => 'Ζ',
+ '𝛨' => 'Η',
+ '𝛩' => 'Θ',
+ '𝛪' => 'Ι',
+ '𝛫' => 'Κ',
+ '𝛬' => 'Λ',
+ '𝛭' => 'Μ',
+ '𝛮' => 'Ν',
+ '𝛯' => 'Ξ',
+ '𝛰' => 'Ο',
+ '𝛱' => 'Π',
+ '𝛲' => 'Ρ',
+ '𝛳' => 'Θ',
+ '𝛴' => 'Σ',
+ '𝛵' => 'Τ',
+ '𝛶' => 'Υ',
+ '𝛷' => 'Φ',
+ '𝛸' => 'Χ',
+ '𝛹' => 'Ψ',
+ '𝛺' => 'Ω',
+ '𝛻' => '∇',
+ '𝛼' => 'α',
+ '𝛽' => 'β',
+ '𝛾' => 'γ',
+ '𝛿' => 'δ',
+ '𝜀' => 'ε',
+ '𝜁' => 'ζ',
+ '𝜂' => 'η',
+ '𝜃' => 'θ',
+ '𝜄' => 'ι',
+ '𝜅' => 'κ',
+ '𝜆' => 'λ',
+ '𝜇' => 'μ',
+ '𝜈' => 'ν',
+ '𝜉' => 'ξ',
+ '𝜊' => 'ο',
+ '𝜋' => 'π',
+ '𝜌' => 'ρ',
+ '𝜍' => 'ς',
+ '𝜎' => 'σ',
+ '𝜏' => 'τ',
+ '𝜐' => 'υ',
+ '𝜑' => 'φ',
+ '𝜒' => 'χ',
+ '𝜓' => 'ψ',
+ '𝜔' => 'ω',
+ '𝜕' => '∂',
+ '𝜖' => 'ε',
+ '𝜗' => 'θ',
+ '𝜘' => 'κ',
+ '𝜙' => 'φ',
+ '𝜚' => 'ρ',
+ '𝜛' => 'π',
+ '𝜜' => 'Α',
+ '𝜝' => 'Β',
+ '𝜞' => 'Γ',
+ '𝜟' => 'Δ',
+ '𝜠' => 'Ε',
+ '𝜡' => 'Ζ',
+ '𝜢' => 'Η',
+ '𝜣' => 'Θ',
+ '𝜤' => 'Ι',
+ '𝜥' => 'Κ',
+ '𝜦' => 'Λ',
+ '𝜧' => 'Μ',
+ '𝜨' => 'Ν',
+ '𝜩' => 'Ξ',
+ '𝜪' => 'Ο',
+ '𝜫' => 'Π',
+ '𝜬' => 'Ρ',
+ '𝜭' => 'Θ',
+ '𝜮' => 'Σ',
+ '𝜯' => 'Τ',
+ '𝜰' => 'Υ',
+ '𝜱' => 'Φ',
+ '𝜲' => 'Χ',
+ '𝜳' => 'Ψ',
+ '𝜴' => 'Ω',
+ '𝜵' => '∇',
+ '𝜶' => 'α',
+ '𝜷' => 'β',
+ '𝜸' => 'γ',
+ '𝜹' => 'δ',
+ '𝜺' => 'ε',
+ '𝜻' => 'ζ',
+ '𝜼' => 'η',
+ '𝜽' => 'θ',
+ '𝜾' => 'ι',
+ '𝜿' => 'κ',
+ '𝝀' => 'λ',
+ '𝝁' => 'μ',
+ '𝝂' => 'ν',
+ '𝝃' => 'ξ',
+ '𝝄' => 'ο',
+ '𝝅' => 'π',
+ '𝝆' => 'ρ',
+ '𝝇' => 'ς',
+ '𝝈' => 'σ',
+ '𝝉' => 'τ',
+ '𝝊' => 'υ',
+ '𝝋' => 'φ',
+ '𝝌' => 'χ',
+ '𝝍' => 'ψ',
+ '𝝎' => 'ω',
+ '𝝏' => '∂',
+ '𝝐' => 'ε',
+ '𝝑' => 'θ',
+ '𝝒' => 'κ',
+ '𝝓' => 'φ',
+ '𝝔' => 'ρ',
+ '𝝕' => 'π',
+ '𝝖' => 'Α',
+ '𝝗' => 'Β',
+ '𝝘' => 'Γ',
+ '𝝙' => 'Δ',
+ '𝝚' => 'Ε',
+ '𝝛' => 'Ζ',
+ '𝝜' => 'Η',
+ '𝝝' => 'Θ',
+ '𝝞' => 'Ι',
+ '𝝟' => 'Κ',
+ '𝝠' => 'Λ',
+ '𝝡' => 'Μ',
+ '𝝢' => 'Ν',
+ '𝝣' => 'Ξ',
+ '𝝤' => 'Ο',
+ '𝝥' => 'Π',
+ '𝝦' => 'Ρ',
+ '𝝧' => 'Θ',
+ '𝝨' => 'Σ',
+ '𝝩' => 'Τ',
+ '𝝪' => 'Υ',
+ '𝝫' => 'Φ',
+ '𝝬' => 'Χ',
+ '𝝭' => 'Ψ',
+ '𝝮' => 'Ω',
+ '𝝯' => '∇',
+ '𝝰' => 'α',
+ '𝝱' => 'β',
+ '𝝲' => 'γ',
+ '𝝳' => 'δ',
+ '𝝴' => 'ε',
+ '𝝵' => 'ζ',
+ '𝝶' => 'η',
+ '𝝷' => 'θ',
+ '𝝸' => 'ι',
+ '𝝹' => 'κ',
+ '𝝺' => 'λ',
+ '𝝻' => 'μ',
+ '𝝼' => 'ν',
+ '𝝽' => 'ξ',
+ '𝝾' => 'ο',
+ '𝝿' => 'π',
+ '𝞀' => 'ρ',
+ '𝞁' => 'ς',
+ '𝞂' => 'σ',
+ '𝞃' => 'τ',
+ '𝞄' => 'υ',
+ '𝞅' => 'φ',
+ '𝞆' => 'χ',
+ '𝞇' => 'ψ',
+ '𝞈' => 'ω',
+ '𝞉' => '∂',
+ '𝞊' => 'ε',
+ '𝞋' => 'θ',
+ '𝞌' => 'κ',
+ '𝞍' => 'φ',
+ '𝞎' => 'ρ',
+ '𝞏' => 'π',
+ '𝞐' => 'Α',
+ '𝞑' => 'Β',
+ '𝞒' => 'Γ',
+ '𝞓' => 'Δ',
+ '𝞔' => 'Ε',
+ '𝞕' => 'Ζ',
+ '𝞖' => 'Η',
+ '𝞗' => 'Θ',
+ '𝞘' => 'Ι',
+ '𝞙' => 'Κ',
+ '𝞚' => 'Λ',
+ '𝞛' => 'Μ',
+ '𝞜' => 'Ν',
+ '𝞝' => 'Ξ',
+ '𝞞' => 'Ο',
+ '𝞟' => 'Π',
+ '𝞠' => 'Ρ',
+ '𝞡' => 'Θ',
+ '𝞢' => 'Σ',
+ '𝞣' => 'Τ',
+ '𝞤' => 'Υ',
+ '𝞥' => 'Φ',
+ '𝞦' => 'Χ',
+ '𝞧' => 'Ψ',
+ '𝞨' => 'Ω',
+ '𝞩' => '∇',
+ '𝞪' => 'α',
+ '𝞫' => 'β',
+ '𝞬' => 'γ',
+ '𝞭' => 'δ',
+ '𝞮' => 'ε',
+ '𝞯' => 'ζ',
+ '𝞰' => 'η',
+ '𝞱' => 'θ',
+ '𝞲' => 'ι',
+ '𝞳' => 'κ',
+ '𝞴' => 'λ',
+ '𝞵' => 'μ',
+ '𝞶' => 'ν',
+ '𝞷' => 'ξ',
+ '𝞸' => 'ο',
+ '𝞹' => 'π',
+ '𝞺' => 'ρ',
+ '𝞻' => 'ς',
+ '𝞼' => 'σ',
+ '𝞽' => 'τ',
+ '𝞾' => 'υ',
+ '𝞿' => 'φ',
+ '𝟀' => 'χ',
+ '𝟁' => 'ψ',
+ '𝟂' => 'ω',
+ '𝟃' => '∂',
+ '𝟄' => 'ε',
+ '𝟅' => 'θ',
+ '𝟆' => 'κ',
+ '𝟇' => 'φ',
+ '𝟈' => 'ρ',
+ '𝟉' => 'π',
+ '𝟊' => 'Ϝ',
+ '𝟋' => 'ϝ',
+ '𝟎' => '0',
+ '𝟏' => '1',
+ '𝟐' => '2',
+ '𝟑' => '3',
+ '𝟒' => '4',
+ '𝟓' => '5',
+ '𝟔' => '6',
+ '𝟕' => '7',
+ '𝟖' => '8',
+ '𝟗' => '9',
+ '𝟘' => '0',
+ '𝟙' => '1',
+ '𝟚' => '2',
+ '𝟛' => '3',
+ '𝟜' => '4',
+ '𝟝' => '5',
+ '𝟞' => '6',
+ '𝟟' => '7',
+ '𝟠' => '8',
+ '𝟡' => '9',
+ '𝟢' => '0',
+ '𝟣' => '1',
+ '𝟤' => '2',
+ '𝟥' => '3',
+ '𝟦' => '4',
+ '𝟧' => '5',
+ '𝟨' => '6',
+ '𝟩' => '7',
+ '𝟪' => '8',
+ '𝟫' => '9',
+ '𝟬' => '0',
+ '𝟭' => '1',
+ '𝟮' => '2',
+ '𝟯' => '3',
+ '𝟰' => '4',
+ '𝟱' => '5',
+ '𝟲' => '6',
+ '𝟳' => '7',
+ '𝟴' => '8',
+ '𝟵' => '9',
+ '𝟶' => '0',
+ '𝟷' => '1',
+ '𝟸' => '2',
+ '𝟹' => '3',
+ '𝟺' => '4',
+ '𝟻' => '5',
+ '𝟼' => '6',
+ '𝟽' => '7',
+ '𝟾' => '8',
+ '𝟿' => '9',
+ '𞸀' => 'ا',
+ '𞸁' => 'ب',
+ '𞸂' => 'ج',
+ '𞸃' => 'د',
+ '𞸅' => 'و',
+ '𞸆' => 'ز',
+ '𞸇' => 'ح',
+ '𞸈' => 'ط',
+ '𞸉' => 'ي',
+ '𞸊' => 'ك',
+ '𞸋' => 'ل',
+ '𞸌' => 'م',
+ '𞸍' => 'ن',
+ '𞸎' => 'س',
+ '𞸏' => 'ع',
+ '𞸐' => 'ف',
+ '𞸑' => 'ص',
+ '𞸒' => 'ق',
+ '𞸓' => 'ر',
+ '𞸔' => 'ش',
+ '𞸕' => 'ت',
+ '𞸖' => 'ث',
+ '𞸗' => 'خ',
+ '𞸘' => 'ذ',
+ '𞸙' => 'ض',
+ '𞸚' => 'ظ',
+ '𞸛' => 'غ',
+ '𞸜' => 'ٮ',
+ '𞸝' => 'ں',
+ '𞸞' => 'ڡ',
+ '𞸟' => 'ٯ',
+ '𞸡' => 'ب',
+ '𞸢' => 'ج',
+ '𞸤' => 'ه',
+ '𞸧' => 'ح',
+ '𞸩' => 'ي',
+ '𞸪' => 'ك',
+ '𞸫' => 'ل',
+ '𞸬' => 'م',
+ '𞸭' => 'ن',
+ '𞸮' => 'س',
+ '𞸯' => 'ع',
+ '𞸰' => 'ف',
+ '𞸱' => 'ص',
+ '𞸲' => 'ق',
+ '𞸴' => 'ش',
+ '𞸵' => 'ت',
+ '𞸶' => 'ث',
+ '𞸷' => 'خ',
+ '𞸹' => 'ض',
+ '𞸻' => 'غ',
+ '𞹂' => 'ج',
+ '𞹇' => 'ح',
+ '𞹉' => 'ي',
+ '𞹋' => 'ل',
+ '𞹍' => 'ن',
+ '𞹎' => 'س',
+ '𞹏' => 'ع',
+ '𞹑' => 'ص',
+ '𞹒' => 'ق',
+ '𞹔' => 'ش',
+ '𞹗' => 'خ',
+ '𞹙' => 'ض',
+ '𞹛' => 'غ',
+ '𞹝' => 'ں',
+ '𞹟' => 'ٯ',
+ '𞹡' => 'ب',
+ '𞹢' => 'ج',
+ '𞹤' => 'ه',
+ '𞹧' => 'ح',
+ '𞹨' => 'ط',
+ '𞹩' => 'ي',
+ '𞹪' => 'ك',
+ '𞹬' => 'م',
+ '𞹭' => 'ن',
+ '𞹮' => 'س',
+ '𞹯' => 'ع',
+ '𞹰' => 'ف',
+ '𞹱' => 'ص',
+ '𞹲' => 'ق',
+ '𞹴' => 'ش',
+ '𞹵' => 'ت',
+ '𞹶' => 'ث',
+ '𞹷' => 'خ',
+ '𞹹' => 'ض',
+ '𞹺' => 'ظ',
+ '𞹻' => 'غ',
+ '𞹼' => 'ٮ',
+ '𞹾' => 'ڡ',
+ '𞺀' => 'ا',
+ '𞺁' => 'ب',
+ '𞺂' => 'ج',
+ '𞺃' => 'د',
+ '𞺄' => 'ه',
+ '𞺅' => 'و',
+ '𞺆' => 'ز',
+ '𞺇' => 'ح',
+ '𞺈' => 'ط',
+ '𞺉' => 'ي',
+ '𞺋' => 'ل',
+ '𞺌' => 'م',
+ '𞺍' => 'ن',
+ '𞺎' => 'س',
+ '𞺏' => 'ع',
+ '𞺐' => 'ف',
+ '𞺑' => 'ص',
+ '𞺒' => 'ق',
+ '𞺓' => 'ر',
+ '𞺔' => 'ش',
+ '𞺕' => 'ت',
+ '𞺖' => 'ث',
+ '𞺗' => 'خ',
+ '𞺘' => 'ذ',
+ '𞺙' => 'ض',
+ '𞺚' => 'ظ',
+ '𞺛' => 'غ',
+ '𞺡' => 'ب',
+ '𞺢' => 'ج',
+ '𞺣' => 'د',
+ '𞺥' => 'و',
+ '𞺦' => 'ز',
+ '𞺧' => 'ح',
+ '𞺨' => 'ط',
+ '𞺩' => 'ي',
+ '𞺫' => 'ل',
+ '𞺬' => 'م',
+ '𞺭' => 'ن',
+ '𞺮' => 'س',
+ '𞺯' => 'ع',
+ '𞺰' => 'ف',
+ '𞺱' => 'ص',
+ '𞺲' => 'ق',
+ '𞺳' => 'ر',
+ '𞺴' => 'ش',
+ '𞺵' => 'ت',
+ '𞺶' => 'ث',
+ '𞺷' => 'خ',
+ '𞺸' => 'ذ',
+ '𞺹' => 'ض',
+ '𞺺' => 'ظ',
+ '𞺻' => 'غ',
+ '🄀' => '0.',
+ '🄁' => '0,',
+ '🄂' => '1,',
+ '🄃' => '2,',
+ '🄄' => '3,',
+ '🄅' => '4,',
+ '🄆' => '5,',
+ '🄇' => '6,',
+ '🄈' => '7,',
+ '🄉' => '8,',
+ '🄊' => '9,',
+ '🄐' => '(A)',
+ '🄑' => '(B)',
+ '🄒' => '(C)',
+ '🄓' => '(D)',
+ '🄔' => '(E)',
+ '🄕' => '(F)',
+ '🄖' => '(G)',
+ '🄗' => '(H)',
+ '🄘' => '(I)',
+ '🄙' => '(J)',
+ '🄚' => '(K)',
+ '🄛' => '(L)',
+ '🄜' => '(M)',
+ '🄝' => '(N)',
+ '🄞' => '(O)',
+ '🄟' => '(P)',
+ '🄠' => '(Q)',
+ '🄡' => '(R)',
+ '🄢' => '(S)',
+ '🄣' => '(T)',
+ '🄤' => '(U)',
+ '🄥' => '(V)',
+ '🄦' => '(W)',
+ '🄧' => '(X)',
+ '🄨' => '(Y)',
+ '🄩' => '(Z)',
+ '🄪' => '〔S〕',
+ '🄫' => 'C',
+ '🄬' => 'R',
+ '🄭' => 'CD',
+ '🄮' => 'WZ',
+ '🄰' => 'A',
+ '🄱' => 'B',
+ '🄲' => 'C',
+ '🄳' => 'D',
+ '🄴' => 'E',
+ '🄵' => 'F',
+ '🄶' => 'G',
+ '🄷' => 'H',
+ '🄸' => 'I',
+ '🄹' => 'J',
+ '🄺' => 'K',
+ '🄻' => 'L',
+ '🄼' => 'M',
+ '🄽' => 'N',
+ '🄾' => 'O',
+ '🄿' => 'P',
+ '🅀' => 'Q',
+ '🅁' => 'R',
+ '🅂' => 'S',
+ '🅃' => 'T',
+ '🅄' => 'U',
+ '🅅' => 'V',
+ '🅆' => 'W',
+ '🅇' => 'X',
+ '🅈' => 'Y',
+ '🅉' => 'Z',
+ '🅊' => 'HV',
+ '🅋' => 'MV',
+ '🅌' => 'SD',
+ '🅍' => 'SS',
+ '🅎' => 'PPV',
+ '🅏' => 'WC',
+ '🅪' => 'MC',
+ '🅫' => 'MD',
+ '🅬' => 'MR',
+ '🆐' => 'DJ',
+ '🈀' => 'ほか',
+ '🈁' => 'ココ',
+ '🈂' => 'サ',
+ '🈐' => '手',
+ '🈑' => '字',
+ '🈒' => '双',
+ '🈓' => 'デ',
+ '🈔' => '二',
+ '🈕' => '多',
+ '🈖' => '解',
+ '🈗' => '天',
+ '🈘' => '交',
+ '🈙' => '映',
+ '🈚' => '無',
+ '🈛' => '料',
+ '🈜' => '前',
+ '🈝' => '後',
+ '🈞' => '再',
+ '🈟' => '新',
+ '🈠' => '初',
+ '🈡' => '終',
+ '🈢' => '生',
+ '🈣' => '販',
+ '🈤' => '声',
+ '🈥' => '吹',
+ '🈦' => '演',
+ '🈧' => '投',
+ '🈨' => '捕',
+ '🈩' => '一',
+ '🈪' => '三',
+ '🈫' => '遊',
+ '🈬' => '左',
+ '🈭' => '中',
+ '🈮' => '右',
+ '🈯' => '指',
+ '🈰' => '走',
+ '🈱' => '打',
+ '🈲' => '禁',
+ '🈳' => '空',
+ '🈴' => '合',
+ '🈵' => '満',
+ '🈶' => '有',
+ '🈷' => '月',
+ '🈸' => '申',
+ '🈹' => '割',
+ '🈺' => '営',
+ '🈻' => '配',
+ '🉀' => '〔本〕',
+ '🉁' => '〔三〕',
+ '🉂' => '〔二〕',
+ '🉃' => '〔安〕',
+ '🉄' => '〔点〕',
+ '🉅' => '〔打〕',
+ '🉆' => '〔盗〕',
+ '🉇' => '〔勝〕',
+ '🉈' => '〔敗〕',
+ '🉐' => '得',
+ '🉑' => '可',
+ '🯰' => '0',
+ '🯱' => '1',
+ '🯲' => '2',
+ '🯳' => '3',
+ '🯴' => '4',
+ '🯵' => '5',
+ '🯶' => '6',
+ '🯷' => '7',
+ '🯸' => '8',
+ '🯹' => '9',
+);
diff --git a/Server/vendor/symfony/polyfill-intl-normalizer/bootstrap.php b/Server/vendor/symfony/polyfill-intl-normalizer/bootstrap.php
new file mode 100755
index 000000000..3608e5c05
--- /dev/null
+++ b/Server/vendor/symfony/polyfill-intl-normalizer/bootstrap.php
@@ -0,0 +1,23 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Polyfill\Intl\Normalizer as p;
+
+if (\PHP_VERSION_ID >= 80000) {
+ return require __DIR__.'/bootstrap80.php';
+}
+
+if (!function_exists('normalizer_is_normalized')) {
+ function normalizer_is_normalized($string, $form = p\Normalizer::FORM_C) { return p\Normalizer::isNormalized($string, $form); }
+}
+if (!function_exists('normalizer_normalize')) {
+ function normalizer_normalize($string, $form = p\Normalizer::FORM_C) { return p\Normalizer::normalize($string, $form); }
+}
diff --git a/Server/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php b/Server/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php
new file mode 100755
index 000000000..e36d1a947
--- /dev/null
+++ b/Server/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php
@@ -0,0 +1,19 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Polyfill\Intl\Normalizer as p;
+
+if (!function_exists('normalizer_is_normalized')) {
+ function normalizer_is_normalized(?string $string, ?int $form = p\Normalizer::FORM_C): bool { return p\Normalizer::isNormalized((string) $string, (int) $form); }
+}
+if (!function_exists('normalizer_normalize')) {
+ function normalizer_normalize(?string $string, ?int $form = p\Normalizer::FORM_C): string|false { return p\Normalizer::normalize((string) $string, (int) $form); }
+}
diff --git a/Server/vendor/symfony/polyfill-intl-normalizer/composer.json b/Server/vendor/symfony/polyfill-intl-normalizer/composer.json
new file mode 100755
index 000000000..eb452bfd4
--- /dev/null
+++ b/Server/vendor/symfony/polyfill-intl-normalizer/composer.json
@@ -0,0 +1,39 @@
+{
+ "name": "symfony/polyfill-intl-normalizer",
+ "type": "library",
+ "description": "Symfony polyfill for intl's Normalizer class and related functions",
+ "keywords": ["polyfill", "shim", "compatibility", "portable", "intl", "normalizer"],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=7.1"
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Polyfill\\Intl\\Normalizer\\": "" },
+ "files": [ "bootstrap.php" ],
+ "classmap": [ "Resources/stubs" ]
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.26-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ }
+}
diff --git a/Server/vendor/symfony/polyfill-php72/LICENSE b/Server/vendor/symfony/polyfill-php72/LICENSE
new file mode 100755
index 000000000..4cd8bdd30
--- /dev/null
+++ b/Server/vendor/symfony/polyfill-php72/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2015-2019 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/Server/vendor/symfony/polyfill-php72/Php72.php b/Server/vendor/symfony/polyfill-php72/Php72.php
new file mode 100755
index 000000000..5e20d5bf8
--- /dev/null
+++ b/Server/vendor/symfony/polyfill-php72/Php72.php
@@ -0,0 +1,217 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Polyfill\Php72;
+
+/**
+ * @author Nicolas Grekas
+ * @author Dariusz Rumiński
+ */
+class PropertyAccessor implements PropertyAccessorInterface
+{
+ /**
+ * @internal
+ */
+ const VALUE = 0;
+
+ /**
+ * @internal
+ */
+ const REF = 1;
+
+ /**
+ * @internal
+ */
+ const IS_REF_CHAINED = 2;
+
+ /**
+ * @internal
+ */
+ const ACCESS_HAS_PROPERTY = 0;
+
+ /**
+ * @internal
+ */
+ const ACCESS_TYPE = 1;
+
+ /**
+ * @internal
+ */
+ const ACCESS_NAME = 2;
+
+ /**
+ * @internal
+ */
+ const ACCESS_REF = 3;
+
+ /**
+ * @internal
+ */
+ const ACCESS_ADDER = 4;
+
+ /**
+ * @internal
+ */
+ const ACCESS_REMOVER = 5;
+
+ /**
+ * @internal
+ */
+ const ACCESS_TYPE_METHOD = 0;
+
+ /**
+ * @internal
+ */
+ const ACCESS_TYPE_PROPERTY = 1;
+
+ /**
+ * @internal
+ */
+ const ACCESS_TYPE_MAGIC = 2;
+
+ /**
+ * @internal
+ */
+ const ACCESS_TYPE_ADDER_AND_REMOVER = 3;
+
+ /**
+ * @internal
+ */
+ const ACCESS_TYPE_NOT_FOUND = 4;
+
+ private $magicCall;
+ private $ignoreInvalidIndices;
+ private $readPropertyCache = array();
+ private $writePropertyCache = array();
+
+ private static $previousErrorHandler = false;
+ private static $errorHandler = array(__CLASS__, 'handleError');
+ private static $resultProto = array(self::VALUE => null);
+
+ /**
+ * Should not be used by application code. Use
+ * {@link PropertyAccess::createPropertyAccessor()} instead.
+ *
+ * @param bool $magicCall
+ * @param bool $throwExceptionOnInvalidIndex
+ */
+ public function __construct($magicCall = false, $throwExceptionOnInvalidIndex = false)
+ {
+ $this->magicCall = $magicCall;
+ $this->ignoreInvalidIndices = !$throwExceptionOnInvalidIndex;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getValue($objectOrArray, $propertyPath)
+ {
+ if (!$propertyPath instanceof PropertyPathInterface) {
+ $propertyPath = new PropertyPath($propertyPath);
+ }
+
+ $zval = array(
+ self::VALUE => $objectOrArray,
+ );
+ $propertyValues = $this->readPropertiesUntil($zval, $propertyPath, $propertyPath->getLength(), $this->ignoreInvalidIndices);
+
+ return $propertyValues[\count($propertyValues) - 1][self::VALUE];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setValue(&$objectOrArray, $propertyPath, $value)
+ {
+ if (!$propertyPath instanceof PropertyPathInterface) {
+ $propertyPath = new PropertyPath($propertyPath);
+ }
+
+ $zval = array(
+ self::VALUE => $objectOrArray,
+ self::REF => &$objectOrArray,
+ );
+ $propertyValues = $this->readPropertiesUntil($zval, $propertyPath, $propertyPath->getLength() - 1);
+ $overwrite = true;
+
+ try {
+ if (\PHP_VERSION_ID < 70000 && false === self::$previousErrorHandler) {
+ self::$previousErrorHandler = set_error_handler(self::$errorHandler);
+ }
+
+ for ($i = \count($propertyValues) - 1; 0 <= $i; --$i) {
+ $zval = $propertyValues[$i];
+ unset($propertyValues[$i]);
+
+ // You only need set value for current element if:
+ // 1. it's the parent of the last index element
+ // OR
+ // 2. its child is not passed by reference
+ //
+ // This may avoid uncessary value setting process for array elements.
+ // For example:
+ // '[a][b][c]' => 'old-value'
+ // If you want to change its value to 'new-value',
+ // you only need set value for '[a][b][c]' and it's safe to ignore '[a][b]' and '[a]'
+ if ($overwrite) {
+ $property = $propertyPath->getElement($i);
+
+ if ($propertyPath->isIndex($i)) {
+ if ($overwrite = !isset($zval[self::REF])) {
+ $ref = &$zval[self::REF];
+ $ref = $zval[self::VALUE];
+ }
+ $this->writeIndex($zval, $property, $value);
+ if ($overwrite) {
+ $zval[self::VALUE] = $zval[self::REF];
+ }
+ } else {
+ $this->writeProperty($zval, $property, $value);
+ }
+
+ // if current element is an object
+ // OR
+ // if current element's reference chain is not broken - current element
+ // as well as all its ancients in the property path are all passed by reference,
+ // then there is no need to continue the value setting process
+ if (\is_object($zval[self::VALUE]) || isset($zval[self::IS_REF_CHAINED])) {
+ break;
+ }
+ }
+
+ $value = $zval[self::VALUE];
+ }
+ } catch (\TypeError $e) {
+ try {
+ self::throwInvalidArgumentException($e->getMessage(), $e->getTrace(), 0);
+ } catch (InvalidArgumentException $e) {
+ }
+ } catch (\Exception $e) {
+ } catch (\Throwable $e) {
+ }
+
+ if (\PHP_VERSION_ID < 70000 && false !== self::$previousErrorHandler) {
+ restore_error_handler();
+ self::$previousErrorHandler = false;
+ }
+ if (isset($e)) {
+ throw $e;
+ }
+ }
+
+ /**
+ * @internal
+ */
+ public static function handleError($type, $message, $file, $line, $context)
+ {
+ if (E_RECOVERABLE_ERROR === $type) {
+ self::throwInvalidArgumentException($message, debug_backtrace(false), 1);
+ }
+
+ return null !== self::$previousErrorHandler && false !== \call_user_func(self::$previousErrorHandler, $type, $message, $file, $line, $context);
+ }
+
+ private static function throwInvalidArgumentException($message, $trace, $i)
+ {
+ // the type mismatch is not caused by invalid arguments (but e.g. by an incompatible return type hint of the writer method)
+ if (0 !== strpos($message, 'Argument ')) {
+ return;
+ }
+
+ if (isset($trace[$i]['file']) && __FILE__ === $trace[$i]['file'] && array_key_exists(0, $trace[$i]['args'])) {
+ $pos = strpos($message, $delim = 'must be of the type ') ?: (strpos($message, $delim = 'must be an instance of ') ?: strpos($message, $delim = 'must implement interface '));
+ $pos += \strlen($delim);
+ $type = $trace[$i]['args'][0];
+ $type = \is_object($type) ? \get_class($type) : \gettype($type);
+
+ throw new InvalidArgumentException(sprintf('Expected argument of type "%s", "%s" given', substr($message, $pos, strpos($message, ',', $pos) - $pos), $type));
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isReadable($objectOrArray, $propertyPath)
+ {
+ if (!$propertyPath instanceof PropertyPathInterface) {
+ $propertyPath = new PropertyPath($propertyPath);
+ }
+
+ try {
+ $zval = array(
+ self::VALUE => $objectOrArray,
+ );
+ $this->readPropertiesUntil($zval, $propertyPath, $propertyPath->getLength(), $this->ignoreInvalidIndices);
+
+ return true;
+ } catch (AccessException $e) {
+ return false;
+ } catch (UnexpectedTypeException $e) {
+ return false;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isWritable($objectOrArray, $propertyPath)
+ {
+ if (!$propertyPath instanceof PropertyPathInterface) {
+ $propertyPath = new PropertyPath($propertyPath);
+ }
+
+ try {
+ $zval = array(
+ self::VALUE => $objectOrArray,
+ );
+ $propertyValues = $this->readPropertiesUntil($zval, $propertyPath, $propertyPath->getLength() - 1);
+
+ for ($i = \count($propertyValues) - 1; 0 <= $i; --$i) {
+ $zval = $propertyValues[$i];
+ unset($propertyValues[$i]);
+
+ if ($propertyPath->isIndex($i)) {
+ if (!$zval[self::VALUE] instanceof \ArrayAccess && !\is_array($zval[self::VALUE])) {
+ return false;
+ }
+ } else {
+ if (!$this->isPropertyWritable($zval[self::VALUE], $propertyPath->getElement($i))) {
+ return false;
+ }
+ }
+
+ if (\is_object($zval[self::VALUE])) {
+ return true;
+ }
+ }
+
+ return true;
+ } catch (AccessException $e) {
+ return false;
+ } catch (UnexpectedTypeException $e) {
+ return false;
+ }
+ }
+
+ /**
+ * Reads the path from an object up to a given path index.
+ *
+ * @param array $zval The array containing the object or array to read from
+ * @param PropertyPathInterface $propertyPath The property path to read
+ * @param int $lastIndex The index up to which should be read
+ * @param bool $ignoreInvalidIndices Whether to ignore invalid indices or throw an exception
+ *
+ * @return array The values read in the path
+ *
+ * @throws UnexpectedTypeException if a value within the path is neither object nor array
+ * @throws NoSuchIndexException If a non-existing index is accessed
+ */
+ private function readPropertiesUntil($zval, PropertyPathInterface $propertyPath, $lastIndex, $ignoreInvalidIndices = true)
+ {
+ if (!\is_object($zval[self::VALUE]) && !\is_array($zval[self::VALUE])) {
+ throw new UnexpectedTypeException($zval[self::VALUE], $propertyPath, 0);
+ }
+
+ // Add the root object to the list
+ $propertyValues = array($zval);
+
+ for ($i = 0; $i < $lastIndex; ++$i) {
+ $property = $propertyPath->getElement($i);
+ $isIndex = $propertyPath->isIndex($i);
+
+ if ($isIndex) {
+ // Create missing nested arrays on demand
+ if (($zval[self::VALUE] instanceof \ArrayAccess && !$zval[self::VALUE]->offsetExists($property)) ||
+ (\is_array($zval[self::VALUE]) && !isset($zval[self::VALUE][$property]) && !array_key_exists($property, $zval[self::VALUE]))
+ ) {
+ if (!$ignoreInvalidIndices) {
+ if (!\is_array($zval[self::VALUE])) {
+ if (!$zval[self::VALUE] instanceof \Traversable) {
+ throw new NoSuchIndexException(sprintf('Cannot read index "%s" while trying to traverse path "%s".', $property, (string) $propertyPath));
+ }
+
+ $zval[self::VALUE] = iterator_to_array($zval[self::VALUE]);
+ }
+
+ throw new NoSuchIndexException(sprintf('Cannot read index "%s" while trying to traverse path "%s". Available indices are "%s".', $property, (string) $propertyPath, print_r(array_keys($zval[self::VALUE]), true)));
+ }
+
+ if ($i + 1 < $propertyPath->getLength()) {
+ if (isset($zval[self::REF])) {
+ $zval[self::VALUE][$property] = array();
+ $zval[self::REF] = $zval[self::VALUE];
+ } else {
+ $zval[self::VALUE] = array($property => array());
+ }
+ }
+ }
+
+ $zval = $this->readIndex($zval, $property);
+ } else {
+ $zval = $this->readProperty($zval, $property);
+ }
+
+ // the final value of the path must not be validated
+ if ($i + 1 < $propertyPath->getLength() && !\is_object($zval[self::VALUE]) && !\is_array($zval[self::VALUE])) {
+ throw new UnexpectedTypeException($zval[self::VALUE], $propertyPath, $i + 1);
+ }
+
+ if (isset($zval[self::REF]) && (0 === $i || isset($propertyValues[$i - 1][self::IS_REF_CHAINED]))) {
+ // Set the IS_REF_CHAINED flag to true if:
+ // current property is passed by reference and
+ // it is the first element in the property path or
+ // the IS_REF_CHAINED flag of its parent element is true
+ // Basically, this flag is true only when the reference chain from the top element to current element is not broken
+ $zval[self::IS_REF_CHAINED] = true;
+ }
+
+ $propertyValues[] = $zval;
+ }
+
+ return $propertyValues;
+ }
+
+ /**
+ * Reads a key from an array-like structure.
+ *
+ * @param array $zval The array containing the array or \ArrayAccess object to read from
+ * @param string|int $index The key to read
+ *
+ * @return array The array containing the value of the key
+ *
+ * @throws NoSuchIndexException If the array does not implement \ArrayAccess or it is not an array
+ */
+ private function readIndex($zval, $index)
+ {
+ if (!$zval[self::VALUE] instanceof \ArrayAccess && !\is_array($zval[self::VALUE])) {
+ throw new NoSuchIndexException(sprintf('Cannot read index "%s" from object of type "%s" because it doesn\'t implement \ArrayAccess.', $index, \get_class($zval[self::VALUE])));
+ }
+
+ $result = self::$resultProto;
+
+ if (isset($zval[self::VALUE][$index])) {
+ $result[self::VALUE] = $zval[self::VALUE][$index];
+
+ if (!isset($zval[self::REF])) {
+ // Save creating references when doing read-only lookups
+ } elseif (\is_array($zval[self::VALUE])) {
+ $result[self::REF] = &$zval[self::REF][$index];
+ } elseif (\is_object($result[self::VALUE])) {
+ $result[self::REF] = $result[self::VALUE];
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Reads the a property from an object.
+ *
+ * @param array $zval The array containing the object to read from
+ * @param string $property The property to read
+ *
+ * @return array The array containing the value of the property
+ *
+ * @throws NoSuchPropertyException if the property does not exist or is not public
+ */
+ private function readProperty($zval, $property)
+ {
+ if (!\is_object($zval[self::VALUE])) {
+ throw new NoSuchPropertyException(sprintf('Cannot read property "%s" from an array. Maybe you intended to write the property path as "[%1$s]" instead.', $property));
+ }
+
+ $result = self::$resultProto;
+ $object = $zval[self::VALUE];
+ $access = $this->getReadAccessInfo(\get_class($object), $property);
+
+ if (self::ACCESS_TYPE_METHOD === $access[self::ACCESS_TYPE]) {
+ $result[self::VALUE] = $object->{$access[self::ACCESS_NAME]}();
+ } elseif (self::ACCESS_TYPE_PROPERTY === $access[self::ACCESS_TYPE]) {
+ $result[self::VALUE] = $object->{$access[self::ACCESS_NAME]};
+
+ if ($access[self::ACCESS_REF] && isset($zval[self::REF])) {
+ $result[self::REF] = &$object->{$access[self::ACCESS_NAME]};
+ }
+ } elseif (!$access[self::ACCESS_HAS_PROPERTY] && property_exists($object, $property)) {
+ // Needed to support \stdClass instances. We need to explicitly
+ // exclude $access[self::ACCESS_HAS_PROPERTY], otherwise if
+ // a *protected* property was found on the class, property_exists()
+ // returns true, consequently the following line will result in a
+ // fatal error.
+
+ $result[self::VALUE] = $object->$property;
+ if (isset($zval[self::REF])) {
+ $result[self::REF] = &$object->$property;
+ }
+ } elseif (self::ACCESS_TYPE_MAGIC === $access[self::ACCESS_TYPE]) {
+ // we call the getter and hope the __call do the job
+ $result[self::VALUE] = $object->{$access[self::ACCESS_NAME]}();
+ } else {
+ throw new NoSuchPropertyException($access[self::ACCESS_NAME]);
+ }
+
+ // Objects are always passed around by reference
+ if (isset($zval[self::REF]) && \is_object($result[self::VALUE])) {
+ $result[self::REF] = $result[self::VALUE];
+ }
+
+ return $result;
+ }
+
+ /**
+ * Guesses how to read the property value.
+ *
+ * @param string $class
+ * @param string $property
+ *
+ * @return array
+ */
+ private function getReadAccessInfo($class, $property)
+ {
+ $key = $class.'::'.$property;
+
+ if (isset($this->readPropertyCache[$key])) {
+ $access = $this->readPropertyCache[$key];
+ } else {
+ $access = array();
+
+ $reflClass = new \ReflectionClass($class);
+ $access[self::ACCESS_HAS_PROPERTY] = $reflClass->hasProperty($property);
+ $camelProp = $this->camelize($property);
+ $getter = 'get'.$camelProp;
+ $getsetter = lcfirst($camelProp); // jQuery style, e.g. read: last(), write: last($item)
+ $isser = 'is'.$camelProp;
+ $hasser = 'has'.$camelProp;
+
+ if ($reflClass->hasMethod($getter) && $reflClass->getMethod($getter)->isPublic()) {
+ $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_METHOD;
+ $access[self::ACCESS_NAME] = $getter;
+ } elseif ($reflClass->hasMethod($getsetter) && $reflClass->getMethod($getsetter)->isPublic()) {
+ $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_METHOD;
+ $access[self::ACCESS_NAME] = $getsetter;
+ } elseif ($reflClass->hasMethod($isser) && $reflClass->getMethod($isser)->isPublic()) {
+ $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_METHOD;
+ $access[self::ACCESS_NAME] = $isser;
+ } elseif ($reflClass->hasMethod($hasser) && $reflClass->getMethod($hasser)->isPublic()) {
+ $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_METHOD;
+ $access[self::ACCESS_NAME] = $hasser;
+ } elseif ($reflClass->hasMethod('__get') && $reflClass->getMethod('__get')->isPublic()) {
+ $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_PROPERTY;
+ $access[self::ACCESS_NAME] = $property;
+ $access[self::ACCESS_REF] = false;
+ } elseif ($access[self::ACCESS_HAS_PROPERTY] && $reflClass->getProperty($property)->isPublic()) {
+ $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_PROPERTY;
+ $access[self::ACCESS_NAME] = $property;
+ $access[self::ACCESS_REF] = true;
+ } elseif ($this->magicCall && $reflClass->hasMethod('__call') && $reflClass->getMethod('__call')->isPublic()) {
+ // we call the getter and hope the __call do the job
+ $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_MAGIC;
+ $access[self::ACCESS_NAME] = $getter;
+ } else {
+ $methods = array($getter, $getsetter, $isser, $hasser, '__get');
+ if ($this->magicCall) {
+ $methods[] = '__call';
+ }
+
+ $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_NOT_FOUND;
+ $access[self::ACCESS_NAME] = sprintf(
+ 'Neither the property "%s" nor one of the methods "%s()" '.
+ 'exist and have public access in class "%s".',
+ $property,
+ implode('()", "', $methods),
+ $reflClass->name
+ );
+ }
+
+ $this->readPropertyCache[$key] = $access;
+ }
+
+ return $access;
+ }
+
+ /**
+ * Sets the value of an index in a given array-accessible value.
+ *
+ * @param array $zval The array containing the array or \ArrayAccess object to write to
+ * @param string|int $index The index to write at
+ * @param mixed $value The value to write
+ *
+ * @throws NoSuchIndexException If the array does not implement \ArrayAccess or it is not an array
+ */
+ private function writeIndex($zval, $index, $value)
+ {
+ if (!$zval[self::VALUE] instanceof \ArrayAccess && !\is_array($zval[self::VALUE])) {
+ throw new NoSuchIndexException(sprintf('Cannot modify index "%s" in object of type "%s" because it doesn\'t implement \ArrayAccess', $index, \get_class($zval[self::VALUE])));
+ }
+
+ $zval[self::REF][$index] = $value;
+ }
+
+ /**
+ * Sets the value of a property in the given object.
+ *
+ * @param array $zval The array containing the object to write to
+ * @param string $property The property to write
+ * @param mixed $value The value to write
+ *
+ * @throws NoSuchPropertyException if the property does not exist or is not public
+ */
+ private function writeProperty($zval, $property, $value)
+ {
+ if (!\is_object($zval[self::VALUE])) {
+ throw new NoSuchPropertyException(sprintf('Cannot write property "%s" to an array. Maybe you should write the property path as "[%1$s]" instead?', $property));
+ }
+
+ $object = $zval[self::VALUE];
+ $access = $this->getWriteAccessInfo(\get_class($object), $property, $value);
+
+ if (self::ACCESS_TYPE_METHOD === $access[self::ACCESS_TYPE]) {
+ $object->{$access[self::ACCESS_NAME]}($value);
+ } elseif (self::ACCESS_TYPE_PROPERTY === $access[self::ACCESS_TYPE]) {
+ $object->{$access[self::ACCESS_NAME]} = $value;
+ } elseif (self::ACCESS_TYPE_ADDER_AND_REMOVER === $access[self::ACCESS_TYPE]) {
+ $this->writeCollection($zval, $property, $value, $access[self::ACCESS_ADDER], $access[self::ACCESS_REMOVER]);
+ } elseif (!$access[self::ACCESS_HAS_PROPERTY] && property_exists($object, $property)) {
+ // Needed to support \stdClass instances. We need to explicitly
+ // exclude $access[self::ACCESS_HAS_PROPERTY], otherwise if
+ // a *protected* property was found on the class, property_exists()
+ // returns true, consequently the following line will result in a
+ // fatal error.
+
+ $object->$property = $value;
+ } elseif (self::ACCESS_TYPE_MAGIC === $access[self::ACCESS_TYPE]) {
+ $object->{$access[self::ACCESS_NAME]}($value);
+ } else {
+ throw new NoSuchPropertyException($access[self::ACCESS_NAME]);
+ }
+ }
+
+ /**
+ * Adjusts a collection-valued property by calling add*() and remove*() methods.
+ *
+ * @param array $zval The array containing the object to write to
+ * @param string $property The property to write
+ * @param iterable $collection The collection to write
+ * @param string $addMethod The add*() method
+ * @param string $removeMethod The remove*() method
+ */
+ private function writeCollection($zval, $property, $collection, $addMethod, $removeMethod)
+ {
+ // At this point the add and remove methods have been found
+ $previousValue = $this->readProperty($zval, $property);
+ $previousValue = $previousValue[self::VALUE];
+
+ if ($previousValue instanceof \Traversable) {
+ $previousValue = iterator_to_array($previousValue);
+ }
+ if ($previousValue && \is_array($previousValue)) {
+ if (\is_object($collection)) {
+ $collection = iterator_to_array($collection);
+ }
+ foreach ($previousValue as $key => $item) {
+ if (!\in_array($item, $collection, true)) {
+ unset($previousValue[$key]);
+ $zval[self::VALUE]->{$removeMethod}($item);
+ }
+ }
+ } else {
+ $previousValue = false;
+ }
+
+ foreach ($collection as $item) {
+ if (!$previousValue || !\in_array($item, $previousValue, true)) {
+ $zval[self::VALUE]->{$addMethod}($item);
+ }
+ }
+ }
+
+ /**
+ * Guesses how to write the property value.
+ *
+ * @param string $class
+ * @param string $property
+ * @param mixed $value
+ *
+ * @return array
+ */
+ private function getWriteAccessInfo($class, $property, $value)
+ {
+ $key = $class.'::'.$property;
+
+ if (isset($this->writePropertyCache[$key])) {
+ $access = $this->writePropertyCache[$key];
+ } else {
+ $access = array();
+
+ $reflClass = new \ReflectionClass($class);
+ $access[self::ACCESS_HAS_PROPERTY] = $reflClass->hasProperty($property);
+ $camelized = $this->camelize($property);
+ $singulars = (array) StringUtil::singularify($camelized);
+
+ if (\is_array($value) || $value instanceof \Traversable) {
+ $methods = $this->findAdderAndRemover($reflClass, $singulars);
+
+ if (null !== $methods) {
+ $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_ADDER_AND_REMOVER;
+ $access[self::ACCESS_ADDER] = $methods[0];
+ $access[self::ACCESS_REMOVER] = $methods[1];
+ }
+ }
+
+ if (!isset($access[self::ACCESS_TYPE])) {
+ $setter = 'set'.$camelized;
+ $getsetter = lcfirst($camelized); // jQuery style, e.g. read: last(), write: last($item)
+
+ if ($this->isMethodAccessible($reflClass, $setter, 1)) {
+ $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_METHOD;
+ $access[self::ACCESS_NAME] = $setter;
+ } elseif ($this->isMethodAccessible($reflClass, $getsetter, 1)) {
+ $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_METHOD;
+ $access[self::ACCESS_NAME] = $getsetter;
+ } elseif ($this->isMethodAccessible($reflClass, '__set', 2)) {
+ $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_PROPERTY;
+ $access[self::ACCESS_NAME] = $property;
+ } elseif ($access[self::ACCESS_HAS_PROPERTY] && $reflClass->getProperty($property)->isPublic()) {
+ $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_PROPERTY;
+ $access[self::ACCESS_NAME] = $property;
+ } elseif ($this->magicCall && $this->isMethodAccessible($reflClass, '__call', 2)) {
+ // we call the getter and hope the __call do the job
+ $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_MAGIC;
+ $access[self::ACCESS_NAME] = $setter;
+ } elseif (null !== $methods = $this->findAdderAndRemover($reflClass, $singulars)) {
+ $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_NOT_FOUND;
+ $access[self::ACCESS_NAME] = sprintf(
+ 'The property "%s" in class "%s" can be defined with the methods "%s()" but '.
+ 'the new value must be an array or an instance of \Traversable, '.
+ '"%s" given.',
+ $property,
+ $reflClass->name,
+ implode('()", "', $methods),
+ \is_object($value) ? \get_class($value) : \gettype($value)
+ );
+ } else {
+ $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_NOT_FOUND;
+ $access[self::ACCESS_NAME] = sprintf(
+ 'Neither the property "%s" nor one of the methods %s"%s()", "%s()", '.
+ '"__set()" or "__call()" exist and have public access in class "%s".',
+ $property,
+ implode('', array_map(function ($singular) {
+ return '"add'.$singular.'()"/"remove'.$singular.'()", ';
+ }, $singulars)),
+ $setter,
+ $getsetter,
+ $reflClass->name
+ );
+ }
+ }
+
+ $this->writePropertyCache[$key] = $access;
+ }
+
+ return $access;
+ }
+
+ /**
+ * Returns whether a property is writable in the given object.
+ *
+ * @param object $object The object to write to
+ * @param string $property The property to write
+ *
+ * @return bool Whether the property is writable
+ */
+ private function isPropertyWritable($object, $property)
+ {
+ if (!\is_object($object)) {
+ return false;
+ }
+
+ $access = $this->getWriteAccessInfo(\get_class($object), $property, array());
+
+ return self::ACCESS_TYPE_METHOD === $access[self::ACCESS_TYPE]
+ || self::ACCESS_TYPE_PROPERTY === $access[self::ACCESS_TYPE]
+ || self::ACCESS_TYPE_ADDER_AND_REMOVER === $access[self::ACCESS_TYPE]
+ || (!$access[self::ACCESS_HAS_PROPERTY] && property_exists($object, $property))
+ || self::ACCESS_TYPE_MAGIC === $access[self::ACCESS_TYPE];
+ }
+
+ /**
+ * Camelizes a given string.
+ *
+ * @param string $string Some string
+ *
+ * @return string The camelized version of the string
+ */
+ private function camelize($string)
+ {
+ return str_replace(' ', '', ucwords(str_replace('_', ' ', $string)));
+ }
+
+ /**
+ * Searches for add and remove methods.
+ *
+ * @param \ReflectionClass $reflClass The reflection class for the given object
+ * @param array $singulars The singular form of the property name or null
+ *
+ * @return array|null An array containing the adder and remover when found, null otherwise
+ */
+ private function findAdderAndRemover(\ReflectionClass $reflClass, array $singulars)
+ {
+ foreach ($singulars as $singular) {
+ $addMethod = 'add'.$singular;
+ $removeMethod = 'remove'.$singular;
+
+ $addMethodFound = $this->isMethodAccessible($reflClass, $addMethod, 1);
+ $removeMethodFound = $this->isMethodAccessible($reflClass, $removeMethod, 1);
+
+ if ($addMethodFound && $removeMethodFound) {
+ return array($addMethod, $removeMethod);
+ }
+ }
+ }
+
+ /**
+ * Returns whether a method is public and has the number of required parameters.
+ *
+ * @param \ReflectionClass $class The class of the method
+ * @param string $methodName The method name
+ * @param int $parameters The number of parameters
+ *
+ * @return bool Whether the method is public and has $parameters required parameters
+ */
+ private function isMethodAccessible(\ReflectionClass $class, $methodName, $parameters)
+ {
+ if ($class->hasMethod($methodName)) {
+ $method = $class->getMethod($methodName);
+
+ if ($method->isPublic()
+ && $method->getNumberOfRequiredParameters() <= $parameters
+ && $method->getNumberOfParameters() >= $parameters) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/Server/vendor/symfony/property-access/PropertyAccessorBuilder.php b/Server/vendor/symfony/property-access/PropertyAccessorBuilder.php
new file mode 100755
index 000000000..4b3ad6930
--- /dev/null
+++ b/Server/vendor/symfony/property-access/PropertyAccessorBuilder.php
@@ -0,0 +1,102 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\PropertyAccess;
+
+/**
+ * A configurable builder to create a PropertyAccessor.
+ *
+ * @author Jérémie Augustin
';
+ $this->summaryInformation = count($this->props) - 1;
+ }
+
+ // Additional Document Summary information
+ if ($name == chr(5) . 'DocumentSummaryInformation') {
+// echo 'Document Summary Information
';
+ $this->documentSummaryInformation = count($this->props) - 1;
+ }
+
+ $offset += self::PROPERTY_STORAGE_BLOCK_SIZE;
+ }
+ }
+
+ /**
+ * Read 4 bytes of data at specified position
+ *
+ * @param string $data
+ * @param int $pos
+ * @return int
+ */
+ private static function getInt4d($data, $pos)
+ {
+ // FIX: represent numbers correctly on 64-bit system
+ // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334
+ // Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems
+ $_or_24 = ord($data[$pos + 3]);
+ if ($_or_24 >= 128) {
+ // negative number
+ $_ord_24 = -abs((256 - $_or_24) << 24);
+ } else {
+ $_ord_24 = ($_or_24 & 127) << 24;
+ }
+ return ord($data[$pos]) | (ord($data[$pos + 1]) << 8) | (ord($data[$pos + 2]) << 16) | $_ord_24;
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/PCLZip/gnu-lgpl.txt b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/PCLZip/gnu-lgpl.txt
new file mode 100755
index 000000000..b1e3f5a26
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/PCLZip/gnu-lgpl.txt
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+
+ * $objPHPExcel->getActiveSheet()->getStyle('B2')->applyFromArray(
+ * array(
+ * 'font' => array(
+ * 'name' => 'Arial',
+ * 'bold' => true,
+ * 'italic' => false,
+ * 'underline' => PHPExcel_Style_Font::UNDERLINE_DOUBLE,
+ * 'strike' => false,
+ * 'color' => array(
+ * 'rgb' => '808080'
+ * )
+ * ),
+ * 'borders' => array(
+ * 'bottom' => array(
+ * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
+ * 'color' => array(
+ * 'rgb' => '808080'
+ * )
+ * ),
+ * 'top' => array(
+ * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
+ * 'color' => array(
+ * 'rgb' => '808080'
+ * )
+ * )
+ * ),
+ * 'quotePrefix' => true
+ * )
+ * );
+ *
+ *
+ * @param array $pStyles Array containing style information
+ * @param boolean $pAdvanced Advanced mode for setting borders.
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Style
+ */
+ public function applyFromArray($pStyles = null, $pAdvanced = true)
+ {
+ if (is_array($pStyles)) {
+ if ($this->isSupervisor) {
+ $pRange = $this->getSelectedCells();
+
+ // Uppercase coordinate
+ $pRange = strtoupper($pRange);
+
+ // Is it a cell range or a single cell?
+ if (strpos($pRange, ':') === false) {
+ $rangeA = $pRange;
+ $rangeB = $pRange;
+ } else {
+ list($rangeA, $rangeB) = explode(':', $pRange);
+ }
+
+ // Calculate range outer borders
+ $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA);
+ $rangeEnd = PHPExcel_Cell::coordinateFromString($rangeB);
+
+ // Translate column into index
+ $rangeStart[0] = PHPExcel_Cell::columnIndexFromString($rangeStart[0]) - 1;
+ $rangeEnd[0] = PHPExcel_Cell::columnIndexFromString($rangeEnd[0]) - 1;
+
+ // Make sure we can loop upwards on rows and columns
+ if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) {
+ $tmp = $rangeStart;
+ $rangeStart = $rangeEnd;
+ $rangeEnd = $tmp;
+ }
+
+ // ADVANCED MODE:
+ if ($pAdvanced && isset($pStyles['borders'])) {
+ // 'allborders' is a shorthand property for 'outline' and 'inside' and
+ // it applies to components that have not been set explicitly
+ if (isset($pStyles['borders']['allborders'])) {
+ foreach (array('outline', 'inside') as $component) {
+ if (!isset($pStyles['borders'][$component])) {
+ $pStyles['borders'][$component] = $pStyles['borders']['allborders'];
+ }
+ }
+ unset($pStyles['borders']['allborders']); // not needed any more
+ }
+ // 'outline' is a shorthand property for 'top', 'right', 'bottom', 'left'
+ // it applies to components that have not been set explicitly
+ if (isset($pStyles['borders']['outline'])) {
+ foreach (array('top', 'right', 'bottom', 'left') as $component) {
+ if (!isset($pStyles['borders'][$component])) {
+ $pStyles['borders'][$component] = $pStyles['borders']['outline'];
+ }
+ }
+ unset($pStyles['borders']['outline']); // not needed any more
+ }
+ // 'inside' is a shorthand property for 'vertical' and 'horizontal'
+ // it applies to components that have not been set explicitly
+ if (isset($pStyles['borders']['inside'])) {
+ foreach (array('vertical', 'horizontal') as $component) {
+ if (!isset($pStyles['borders'][$component])) {
+ $pStyles['borders'][$component] = $pStyles['borders']['inside'];
+ }
+ }
+ unset($pStyles['borders']['inside']); // not needed any more
+ }
+ // width and height characteristics of selection, 1, 2, or 3 (for 3 or more)
+ $xMax = min($rangeEnd[0] - $rangeStart[0] + 1, 3);
+ $yMax = min($rangeEnd[1] - $rangeStart[1] + 1, 3);
+
+ // loop through up to 3 x 3 = 9 regions
+ for ($x = 1; $x <= $xMax; ++$x) {
+ // start column index for region
+ $colStart = ($x == 3) ?
+ PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0])
+ : PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] + $x - 1);
+ // end column index for region
+ $colEnd = ($x == 1) ?
+ PHPExcel_Cell::stringFromColumnIndex($rangeStart[0])
+ : PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0] - $xMax + $x);
+
+ for ($y = 1; $y <= $yMax; ++$y) {
+ // which edges are touching the region
+ $edges = array();
+ if ($x == 1) {
+ // are we at left edge
+ $edges[] = 'left';
+ }
+ if ($x == $xMax) {
+ // are we at right edge
+ $edges[] = 'right';
+ }
+ if ($y == 1) {
+ // are we at top edge?
+ $edges[] = 'top';
+ }
+ if ($y == $yMax) {
+ // are we at bottom edge?
+ $edges[] = 'bottom';
+ }
+
+ // start row index for region
+ $rowStart = ($y == 3) ?
+ $rangeEnd[1] : $rangeStart[1] + $y - 1;
+
+ // end row index for region
+ $rowEnd = ($y == 1) ?
+ $rangeStart[1] : $rangeEnd[1] - $yMax + $y;
+
+ // build range for region
+ $range = $colStart . $rowStart . ':' . $colEnd . $rowEnd;
+
+ // retrieve relevant style array for region
+ $regionStyles = $pStyles;
+ unset($regionStyles['borders']['inside']);
+
+ // what are the inner edges of the region when looking at the selection
+ $innerEdges = array_diff(array('top', 'right', 'bottom', 'left'), $edges);
+
+ // inner edges that are not touching the region should take the 'inside' border properties if they have been set
+ foreach ($innerEdges as $innerEdge) {
+ switch ($innerEdge) {
+ case 'top':
+ case 'bottom':
+ // should pick up 'horizontal' border property if set
+ if (isset($pStyles['borders']['horizontal'])) {
+ $regionStyles['borders'][$innerEdge] = $pStyles['borders']['horizontal'];
+ } else {
+ unset($regionStyles['borders'][$innerEdge]);
+ }
+ break;
+ case 'left':
+ case 'right':
+ // should pick up 'vertical' border property if set
+ if (isset($pStyles['borders']['vertical'])) {
+ $regionStyles['borders'][$innerEdge] = $pStyles['borders']['vertical'];
+ } else {
+ unset($regionStyles['borders'][$innerEdge]);
+ }
+ break;
+ }
+ }
+
+ // apply region style to region by calling applyFromArray() in simple mode
+ $this->getActiveSheet()->getStyle($range)->applyFromArray($regionStyles, false);
+ }
+ }
+ return $this;
+ }
+
+ // SIMPLE MODE:
+ // Selection type, inspect
+ if (preg_match('/^[A-Z]+1:[A-Z]+1048576$/', $pRange)) {
+ $selectionType = 'COLUMN';
+ } elseif (preg_match('/^A[0-9]+:XFD[0-9]+$/', $pRange)) {
+ $selectionType = 'ROW';
+ } else {
+ $selectionType = 'CELL';
+ }
+
+ // First loop through columns, rows, or cells to find out which styles are affected by this operation
+ switch ($selectionType) {
+ case 'COLUMN':
+ $oldXfIndexes = array();
+ for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
+ $oldXfIndexes[$this->getActiveSheet()->getColumnDimensionByColumn($col)->getXfIndex()] = true;
+ }
+ break;
+ case 'ROW':
+ $oldXfIndexes = array();
+ for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
+ if ($this->getActiveSheet()->getRowDimension($row)->getXfIndex() == null) {
+ $oldXfIndexes[0] = true; // row without explicit style should be formatted based on default style
+ } else {
+ $oldXfIndexes[$this->getActiveSheet()->getRowDimension($row)->getXfIndex()] = true;
+ }
+ }
+ break;
+ case 'CELL':
+ $oldXfIndexes = array();
+ for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
+ for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
+ $oldXfIndexes[$this->getActiveSheet()->getCellByColumnAndRow($col, $row)->getXfIndex()] = true;
+ }
+ }
+ break;
+ }
+
+ // clone each of the affected styles, apply the style array, and add the new styles to the workbook
+ $workbook = $this->getActiveSheet()->getParent();
+ foreach ($oldXfIndexes as $oldXfIndex => $dummy) {
+ $style = $workbook->getCellXfByIndex($oldXfIndex);
+ $newStyle = clone $style;
+ $newStyle->applyFromArray($pStyles);
+
+ if ($existingStyle = $workbook->getCellXfByHashCode($newStyle->getHashCode())) {
+ // there is already such cell Xf in our collection
+ $newXfIndexes[$oldXfIndex] = $existingStyle->getIndex();
+ } else {
+ // we don't have such a cell Xf, need to add
+ $workbook->addCellXf($newStyle);
+ $newXfIndexes[$oldXfIndex] = $newStyle->getIndex();
+ }
+ }
+
+ // Loop through columns, rows, or cells again and update the XF index
+ switch ($selectionType) {
+ case 'COLUMN':
+ for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
+ $columnDimension = $this->getActiveSheet()->getColumnDimensionByColumn($col);
+ $oldXfIndex = $columnDimension->getXfIndex();
+ $columnDimension->setXfIndex($newXfIndexes[$oldXfIndex]);
+ }
+ break;
+
+ case 'ROW':
+ for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
+ $rowDimension = $this->getActiveSheet()->getRowDimension($row);
+ $oldXfIndex = $rowDimension->getXfIndex() === null ?
+ 0 : $rowDimension->getXfIndex(); // row without explicit style should be formatted based on default style
+ $rowDimension->setXfIndex($newXfIndexes[$oldXfIndex]);
+ }
+ break;
+
+ case 'CELL':
+ for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
+ for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
+ $cell = $this->getActiveSheet()->getCellByColumnAndRow($col, $row);
+ $oldXfIndex = $cell->getXfIndex();
+ $cell->setXfIndex($newXfIndexes[$oldXfIndex]);
+ }
+ }
+ break;
+ }
+
+ } else {
+ // not a supervisor, just apply the style array directly on style object
+ if (array_key_exists('fill', $pStyles)) {
+ $this->getFill()->applyFromArray($pStyles['fill']);
+ }
+ if (array_key_exists('font', $pStyles)) {
+ $this->getFont()->applyFromArray($pStyles['font']);
+ }
+ if (array_key_exists('borders', $pStyles)) {
+ $this->getBorders()->applyFromArray($pStyles['borders']);
+ }
+ if (array_key_exists('alignment', $pStyles)) {
+ $this->getAlignment()->applyFromArray($pStyles['alignment']);
+ }
+ if (array_key_exists('numberformat', $pStyles)) {
+ $this->getNumberFormat()->applyFromArray($pStyles['numberformat']);
+ }
+ if (array_key_exists('protection', $pStyles)) {
+ $this->getProtection()->applyFromArray($pStyles['protection']);
+ }
+ if (array_key_exists('quotePrefix', $pStyles)) {
+ $this->quotePrefix = $pStyles['quotePrefix'];
+ }
+ }
+ } else {
+ throw new PHPExcel_Exception("Invalid style array passed.");
+ }
+ return $this;
+ }
+
+ /**
+ * Get Fill
+ *
+ * @return PHPExcel_Style_Fill
+ */
+ public function getFill()
+ {
+ return $this->fill;
+ }
+
+ /**
+ * Get Font
+ *
+ * @return PHPExcel_Style_Font
+ */
+ public function getFont()
+ {
+ return $this->font;
+ }
+
+ /**
+ * Set font
+ *
+ * @param PHPExcel_Style_Font $font
+ * @return PHPExcel_Style
+ */
+ public function setFont(PHPExcel_Style_Font $font)
+ {
+ $this->font = $font;
+ return $this;
+ }
+
+ /**
+ * Get Borders
+ *
+ * @return PHPExcel_Style_Borders
+ */
+ public function getBorders()
+ {
+ return $this->borders;
+ }
+
+ /**
+ * Get Alignment
+ *
+ * @return PHPExcel_Style_Alignment
+ */
+ public function getAlignment()
+ {
+ return $this->alignment;
+ }
+
+ /**
+ * Get Number Format
+ *
+ * @return PHPExcel_Style_NumberFormat
+ */
+ public function getNumberFormat()
+ {
+ return $this->numberFormat;
+ }
+
+ /**
+ * Get Conditional Styles. Only used on supervisor.
+ *
+ * @return PHPExcel_Style_Conditional[]
+ */
+ public function getConditionalStyles()
+ {
+ return $this->getActiveSheet()->getConditionalStyles($this->getActiveCell());
+ }
+
+ /**
+ * Set Conditional Styles. Only used on supervisor.
+ *
+ * @param PHPExcel_Style_Conditional[] $pValue Array of condtional styles
+ * @return PHPExcel_Style
+ */
+ public function setConditionalStyles($pValue = null)
+ {
+ if (is_array($pValue)) {
+ $this->getActiveSheet()->setConditionalStyles($this->getSelectedCells(), $pValue);
+ }
+ return $this;
+ }
+
+ /**
+ * Get Protection
+ *
+ * @return PHPExcel_Style_Protection
+ */
+ public function getProtection()
+ {
+ return $this->protection;
+ }
+
+ /**
+ * Get quote prefix
+ *
+ * @return boolean
+ */
+ public function getQuotePrefix()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getQuotePrefix();
+ }
+ return $this->quotePrefix;
+ }
+
+ /**
+ * Set quote prefix
+ *
+ * @param boolean $pValue
+ */
+ public function setQuotePrefix($pValue)
+ {
+ if ($pValue == '') {
+ $pValue = false;
+ }
+ if ($this->isSupervisor) {
+ $styleArray = array('quotePrefix' => $pValue);
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->quotePrefix = (boolean) $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get hash code
+ *
+ * @return string Hash code
+ */
+ public function getHashCode()
+ {
+ $hashConditionals = '';
+ foreach ($this->conditionalStyles as $conditional) {
+ $hashConditionals .= $conditional->getHashCode();
+ }
+
+ return md5(
+ $this->fill->getHashCode() .
+ $this->font->getHashCode() .
+ $this->borders->getHashCode() .
+ $this->alignment->getHashCode() .
+ $this->numberFormat->getHashCode() .
+ $hashConditionals .
+ $this->protection->getHashCode() .
+ ($this->quotePrefix ? 't' : 'f') .
+ __CLASS__
+ );
+ }
+
+ /**
+ * Get own index in style collection
+ *
+ * @return int
+ */
+ public function getIndex()
+ {
+ return $this->index;
+ }
+
+ /**
+ * Set own index in style collection
+ *
+ * @param int $pValue
+ */
+ public function setIndex($pValue)
+ {
+ $this->index = $pValue;
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Alignment.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Alignment.php
new file mode 100755
index 000000000..bfc494771
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Alignment.php
@@ -0,0 +1,464 @@
+horizontal = null;
+ $this->vertical = null;
+ $this->textRotation = null;
+ }
+ }
+
+ /**
+ * Get the shared style component for the currently active cell in currently active sheet.
+ * Only used for style supervisor
+ *
+ * @return PHPExcel_Style_Alignment
+ */
+ public function getSharedComponent()
+ {
+ return $this->parent->getSharedComponent()->getAlignment();
+ }
+
+ /**
+ * Build style array from subcomponents
+ *
+ * @param array $array
+ * @return array
+ */
+ public function getStyleArray($array)
+ {
+ return array('alignment' => $array);
+ }
+
+ /**
+ * Apply styles from array
+ *
+ *
+ * $objPHPExcel->getActiveSheet()->getStyle('B2')->getAlignment()->applyFromArray(
+ * array(
+ * 'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER,
+ * 'vertical' => PHPExcel_Style_Alignment::VERTICAL_CENTER,
+ * 'rotation' => 0,
+ * 'wrap' => TRUE
+ * )
+ * );
+ *
+ *
+ * @param array $pStyles Array containing style information
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Style_Alignment
+ */
+ public function applyFromArray($pStyles = null)
+ {
+ if (is_array($pStyles)) {
+ if ($this->isSupervisor) {
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())
+ ->applyFromArray($this->getStyleArray($pStyles));
+ } else {
+ if (isset($pStyles['horizontal'])) {
+ $this->setHorizontal($pStyles['horizontal']);
+ }
+ if (isset($pStyles['vertical'])) {
+ $this->setVertical($pStyles['vertical']);
+ }
+ if (isset($pStyles['rotation'])) {
+ $this->setTextRotation($pStyles['rotation']);
+ }
+ if (isset($pStyles['wrap'])) {
+ $this->setWrapText($pStyles['wrap']);
+ }
+ if (isset($pStyles['shrinkToFit'])) {
+ $this->setShrinkToFit($pStyles['shrinkToFit']);
+ }
+ if (isset($pStyles['indent'])) {
+ $this->setIndent($pStyles['indent']);
+ }
+ if (isset($pStyles['readorder'])) {
+ $this->setReadorder($pStyles['readorder']);
+ }
+ }
+ } else {
+ throw new PHPExcel_Exception("Invalid style array passed.");
+ }
+ return $this;
+ }
+
+ /**
+ * Get Horizontal
+ *
+ * @return string
+ */
+ public function getHorizontal()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getHorizontal();
+ }
+ return $this->horizontal;
+ }
+
+ /**
+ * Set Horizontal
+ *
+ * @param string $pValue
+ * @return PHPExcel_Style_Alignment
+ */
+ public function setHorizontal($pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL)
+ {
+ if ($pValue == '') {
+ $pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL;
+ }
+
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('horizontal' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->horizontal = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get Vertical
+ *
+ * @return string
+ */
+ public function getVertical()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getVertical();
+ }
+ return $this->vertical;
+ }
+
+ /**
+ * Set Vertical
+ *
+ * @param string $pValue
+ * @return PHPExcel_Style_Alignment
+ */
+ public function setVertical($pValue = PHPExcel_Style_Alignment::VERTICAL_BOTTOM)
+ {
+ if ($pValue == '') {
+ $pValue = PHPExcel_Style_Alignment::VERTICAL_BOTTOM;
+ }
+
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('vertical' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->vertical = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get TextRotation
+ *
+ * @return int
+ */
+ public function getTextRotation()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getTextRotation();
+ }
+ return $this->textRotation;
+ }
+
+ /**
+ * Set TextRotation
+ *
+ * @param int $pValue
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Style_Alignment
+ */
+ public function setTextRotation($pValue = 0)
+ {
+ // Excel2007 value 255 => PHPExcel value -165
+ if ($pValue == 255) {
+ $pValue = -165;
+ }
+
+ // Set rotation
+ if (($pValue >= -90 && $pValue <= 90) || $pValue == -165) {
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('rotation' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->textRotation = $pValue;
+ }
+ } else {
+ throw new PHPExcel_Exception("Text rotation should be a value between -90 and 90.");
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get Wrap Text
+ *
+ * @return boolean
+ */
+ public function getWrapText()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getWrapText();
+ }
+ return $this->wrapText;
+ }
+
+ /**
+ * Set Wrap Text
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Style_Alignment
+ */
+ public function setWrapText($pValue = false)
+ {
+ if ($pValue == '') {
+ $pValue = false;
+ }
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('wrap' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->wrapText = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get Shrink to fit
+ *
+ * @return boolean
+ */
+ public function getShrinkToFit()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getShrinkToFit();
+ }
+ return $this->shrinkToFit;
+ }
+
+ /**
+ * Set Shrink to fit
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Style_Alignment
+ */
+ public function setShrinkToFit($pValue = false)
+ {
+ if ($pValue == '') {
+ $pValue = false;
+ }
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('shrinkToFit' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->shrinkToFit = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get indent
+ *
+ * @return int
+ */
+ public function getIndent()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getIndent();
+ }
+ return $this->indent;
+ }
+
+ /**
+ * Set indent
+ *
+ * @param int $pValue
+ * @return PHPExcel_Style_Alignment
+ */
+ public function setIndent($pValue = 0)
+ {
+ if ($pValue > 0) {
+ if ($this->getHorizontal() != self::HORIZONTAL_GENERAL &&
+ $this->getHorizontal() != self::HORIZONTAL_LEFT &&
+ $this->getHorizontal() != self::HORIZONTAL_RIGHT) {
+ $pValue = 0; // indent not supported
+ }
+ }
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('indent' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->indent = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get read order
+ *
+ * @return integer
+ */
+ public function getReadorder()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getReadorder();
+ }
+ return $this->readorder;
+ }
+
+ /**
+ * Set read order
+ *
+ * @param int $pValue
+ * @return PHPExcel_Style_Alignment
+ */
+ public function setReadorder($pValue = 0)
+ {
+ if ($pValue < 0 || $pValue > 2) {
+ $pValue = 0;
+ }
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('readorder' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->readorder = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get hash code
+ *
+ * @return string Hash code
+ */
+ public function getHashCode()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getHashCode();
+ }
+ return md5(
+ $this->horizontal .
+ $this->vertical .
+ $this->textRotation .
+ ($this->wrapText ? 't' : 'f') .
+ ($this->shrinkToFit ? 't' : 'f') .
+ $this->indent .
+ $this->readorder .
+ __CLASS__
+ );
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Border.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Border.php
new file mode 100755
index 000000000..55efc501e
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Border.php
@@ -0,0 +1,282 @@
+color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor);
+
+ // bind parent if we are a supervisor
+ if ($isSupervisor) {
+ $this->color->bindParent($this, 'color');
+ }
+ }
+
+ /**
+ * Bind parent. Only used for supervisor
+ *
+ * @param PHPExcel_Style_Borders $parent
+ * @param string $parentPropertyName
+ * @return PHPExcel_Style_Border
+ */
+ public function bindParent($parent, $parentPropertyName = null)
+ {
+ $this->parent = $parent;
+ $this->parentPropertyName = $parentPropertyName;
+ return $this;
+ }
+
+ /**
+ * Get the shared style component for the currently active cell in currently active sheet.
+ * Only used for style supervisor
+ *
+ * @return PHPExcel_Style_Border
+ * @throws PHPExcel_Exception
+ */
+ public function getSharedComponent()
+ {
+ switch ($this->parentPropertyName) {
+ case 'allBorders':
+ case 'horizontal':
+ case 'inside':
+ case 'outline':
+ case 'vertical':
+ throw new PHPExcel_Exception('Cannot get shared component for a pseudo-border.');
+ break;
+ case 'bottom':
+ return $this->parent->getSharedComponent()->getBottom();
+ case 'diagonal':
+ return $this->parent->getSharedComponent()->getDiagonal();
+ case 'left':
+ return $this->parent->getSharedComponent()->getLeft();
+ case 'right':
+ return $this->parent->getSharedComponent()->getRight();
+ case 'top':
+ return $this->parent->getSharedComponent()->getTop();
+ }
+ }
+
+ /**
+ * Build style array from subcomponents
+ *
+ * @param array $array
+ * @return array
+ */
+ public function getStyleArray($array)
+ {
+ switch ($this->parentPropertyName) {
+ case 'allBorders':
+ case 'bottom':
+ case 'diagonal':
+ case 'horizontal':
+ case 'inside':
+ case 'left':
+ case 'outline':
+ case 'right':
+ case 'top':
+ case 'vertical':
+ $key = strtolower('vertical');
+ break;
+ }
+ return $this->parent->getStyleArray(array($key => $array));
+ }
+
+ /**
+ * Apply styles from array
+ *
+ *
+ * $objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->getTop()->applyFromArray(
+ * array(
+ * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
+ * 'color' => array(
+ * 'rgb' => '808080'
+ * )
+ * )
+ * );
+ *
+ *
+ * @param array $pStyles Array containing style information
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Style_Border
+ */
+ public function applyFromArray($pStyles = null)
+ {
+ if (is_array($pStyles)) {
+ if ($this->isSupervisor) {
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
+ } else {
+ if (isset($pStyles['style'])) {
+ $this->setBorderStyle($pStyles['style']);
+ }
+ if (isset($pStyles['color'])) {
+ $this->getColor()->applyFromArray($pStyles['color']);
+ }
+ }
+ } else {
+ throw new PHPExcel_Exception("Invalid style array passed.");
+ }
+ return $this;
+ }
+
+ /**
+ * Get Border style
+ *
+ * @return string
+ */
+ public function getBorderStyle()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getBorderStyle();
+ }
+ return $this->borderStyle;
+ }
+
+ /**
+ * Set Border style
+ *
+ * @param string|boolean $pValue
+ * When passing a boolean, FALSE equates PHPExcel_Style_Border::BORDER_NONE
+ * and TRUE to PHPExcel_Style_Border::BORDER_MEDIUM
+ * @return PHPExcel_Style_Border
+ */
+ public function setBorderStyle($pValue = PHPExcel_Style_Border::BORDER_NONE)
+ {
+
+ if (empty($pValue)) {
+ $pValue = PHPExcel_Style_Border::BORDER_NONE;
+ } elseif (is_bool($pValue) && $pValue) {
+ $pValue = PHPExcel_Style_Border::BORDER_MEDIUM;
+ }
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('style' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->borderStyle = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get Border Color
+ *
+ * @return PHPExcel_Style_Color
+ */
+ public function getColor()
+ {
+ return $this->color;
+ }
+
+ /**
+ * Set Border Color
+ *
+ * @param PHPExcel_Style_Color $pValue
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Style_Border
+ */
+ public function setColor(PHPExcel_Style_Color $pValue = null)
+ {
+ // make sure parameter is a real color and not a supervisor
+ $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;
+
+ if ($this->isSupervisor) {
+ $styleArray = $this->getColor()->getStyleArray(array('argb' => $color->getARGB()));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->color = $color;
+ }
+ return $this;
+ }
+
+ /**
+ * Get hash code
+ *
+ * @return string Hash code
+ */
+ public function getHashCode()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getHashCode();
+ }
+ return md5(
+ $this->borderStyle .
+ $this->color->getHashCode() .
+ __CLASS__
+ );
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Borders.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Borders.php
new file mode 100755
index 000000000..27c40a48e
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Borders.php
@@ -0,0 +1,429 @@
+left = new PHPExcel_Style_Border($isSupervisor, $isConditional);
+ $this->right = new PHPExcel_Style_Border($isSupervisor, $isConditional);
+ $this->top = new PHPExcel_Style_Border($isSupervisor, $isConditional);
+ $this->bottom = new PHPExcel_Style_Border($isSupervisor, $isConditional);
+ $this->diagonal = new PHPExcel_Style_Border($isSupervisor, $isConditional);
+ $this->diagonalDirection = PHPExcel_Style_Borders::DIAGONAL_NONE;
+
+ // Specially for supervisor
+ if ($isSupervisor) {
+ // Initialize pseudo-borders
+ $this->allBorders = new PHPExcel_Style_Border(true);
+ $this->outline = new PHPExcel_Style_Border(true);
+ $this->inside = new PHPExcel_Style_Border(true);
+ $this->vertical = new PHPExcel_Style_Border(true);
+ $this->horizontal = new PHPExcel_Style_Border(true);
+
+ // bind parent if we are a supervisor
+ $this->left->bindParent($this, 'left');
+ $this->right->bindParent($this, 'right');
+ $this->top->bindParent($this, 'top');
+ $this->bottom->bindParent($this, 'bottom');
+ $this->diagonal->bindParent($this, 'diagonal');
+ $this->allBorders->bindParent($this, 'allBorders');
+ $this->outline->bindParent($this, 'outline');
+ $this->inside->bindParent($this, 'inside');
+ $this->vertical->bindParent($this, 'vertical');
+ $this->horizontal->bindParent($this, 'horizontal');
+ }
+ }
+
+ /**
+ * Get the shared style component for the currently active cell in currently active sheet.
+ * Only used for style supervisor
+ *
+ * @return PHPExcel_Style_Borders
+ */
+ public function getSharedComponent()
+ {
+ return $this->parent->getSharedComponent()->getBorders();
+ }
+
+ /**
+ * Build style array from subcomponents
+ *
+ * @param array $array
+ * @return array
+ */
+ public function getStyleArray($array)
+ {
+ return array('borders' => $array);
+ }
+
+ /**
+ * Apply styles from array
+ *
+ *
+ * $objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->applyFromArray(
+ * array(
+ * 'bottom' => array(
+ * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
+ * 'color' => array(
+ * 'rgb' => '808080'
+ * )
+ * ),
+ * 'top' => array(
+ * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
+ * 'color' => array(
+ * 'rgb' => '808080'
+ * )
+ * )
+ * )
+ * );
+ *
+ *
+ * $objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->applyFromArray(
+ * array(
+ * 'allborders' => array(
+ * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
+ * 'color' => array(
+ * 'rgb' => '808080'
+ * )
+ * )
+ * )
+ * );
+ *
+ *
+ * @param array $pStyles Array containing style information
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Style_Borders
+ */
+ public function applyFromArray($pStyles = null)
+ {
+ if (is_array($pStyles)) {
+ if ($this->isSupervisor) {
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
+ } else {
+ if (array_key_exists('left', $pStyles)) {
+ $this->getLeft()->applyFromArray($pStyles['left']);
+ }
+ if (array_key_exists('right', $pStyles)) {
+ $this->getRight()->applyFromArray($pStyles['right']);
+ }
+ if (array_key_exists('top', $pStyles)) {
+ $this->getTop()->applyFromArray($pStyles['top']);
+ }
+ if (array_key_exists('bottom', $pStyles)) {
+ $this->getBottom()->applyFromArray($pStyles['bottom']);
+ }
+ if (array_key_exists('diagonal', $pStyles)) {
+ $this->getDiagonal()->applyFromArray($pStyles['diagonal']);
+ }
+ if (array_key_exists('diagonaldirection', $pStyles)) {
+ $this->setDiagonalDirection($pStyles['diagonaldirection']);
+ }
+ if (array_key_exists('allborders', $pStyles)) {
+ $this->getLeft()->applyFromArray($pStyles['allborders']);
+ $this->getRight()->applyFromArray($pStyles['allborders']);
+ $this->getTop()->applyFromArray($pStyles['allborders']);
+ $this->getBottom()->applyFromArray($pStyles['allborders']);
+ }
+ }
+ } else {
+ throw new PHPExcel_Exception("Invalid style array passed.");
+ }
+ return $this;
+ }
+
+ /**
+ * Get Left
+ *
+ * @return PHPExcel_Style_Border
+ */
+ public function getLeft()
+ {
+ return $this->left;
+ }
+
+ /**
+ * Get Right
+ *
+ * @return PHPExcel_Style_Border
+ */
+ public function getRight()
+ {
+ return $this->right;
+ }
+
+ /**
+ * Get Top
+ *
+ * @return PHPExcel_Style_Border
+ */
+ public function getTop()
+ {
+ return $this->top;
+ }
+
+ /**
+ * Get Bottom
+ *
+ * @return PHPExcel_Style_Border
+ */
+ public function getBottom()
+ {
+ return $this->bottom;
+ }
+
+ /**
+ * Get Diagonal
+ *
+ * @return PHPExcel_Style_Border
+ */
+ public function getDiagonal()
+ {
+ return $this->diagonal;
+ }
+
+ /**
+ * Get AllBorders (pseudo-border). Only applies to supervisor.
+ *
+ * @return PHPExcel_Style_Border
+ * @throws PHPExcel_Exception
+ */
+ public function getAllBorders()
+ {
+ if (!$this->isSupervisor) {
+ throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.');
+ }
+ return $this->allBorders;
+ }
+
+ /**
+ * Get Outline (pseudo-border). Only applies to supervisor.
+ *
+ * @return boolean
+ * @throws PHPExcel_Exception
+ */
+ public function getOutline()
+ {
+ if (!$this->isSupervisor) {
+ throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.');
+ }
+ return $this->outline;
+ }
+
+ /**
+ * Get Inside (pseudo-border). Only applies to supervisor.
+ *
+ * @return boolean
+ * @throws PHPExcel_Exception
+ */
+ public function getInside()
+ {
+ if (!$this->isSupervisor) {
+ throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.');
+ }
+ return $this->inside;
+ }
+
+ /**
+ * Get Vertical (pseudo-border). Only applies to supervisor.
+ *
+ * @return PHPExcel_Style_Border
+ * @throws PHPExcel_Exception
+ */
+ public function getVertical()
+ {
+ if (!$this->isSupervisor) {
+ throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.');
+ }
+ return $this->vertical;
+ }
+
+ /**
+ * Get Horizontal (pseudo-border). Only applies to supervisor.
+ *
+ * @return PHPExcel_Style_Border
+ * @throws PHPExcel_Exception
+ */
+ public function getHorizontal()
+ {
+ if (!$this->isSupervisor) {
+ throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.');
+ }
+ return $this->horizontal;
+ }
+
+ /**
+ * Get DiagonalDirection
+ *
+ * @return int
+ */
+ public function getDiagonalDirection()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getDiagonalDirection();
+ }
+ return $this->diagonalDirection;
+ }
+
+ /**
+ * Set DiagonalDirection
+ *
+ * @param int $pValue
+ * @return PHPExcel_Style_Borders
+ */
+ public function setDiagonalDirection($pValue = PHPExcel_Style_Borders::DIAGONAL_NONE)
+ {
+ if ($pValue == '') {
+ $pValue = PHPExcel_Style_Borders::DIAGONAL_NONE;
+ }
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('diagonaldirection' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->diagonalDirection = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get hash code
+ *
+ * @return string Hash code
+ */
+ public function getHashCode()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getHashcode();
+ }
+ return md5(
+ $this->getLeft()->getHashCode() .
+ $this->getRight()->getHashCode() .
+ $this->getTop()->getHashCode() .
+ $this->getBottom()->getHashCode() .
+ $this->getDiagonal()->getHashCode() .
+ $this->getDiagonalDirection() .
+ __CLASS__
+ );
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Color.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Color.php
new file mode 100755
index 000000000..9c7790f00
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Color.php
@@ -0,0 +1,443 @@
+argb = $pARGB;
+ }
+ }
+
+ /**
+ * Bind parent. Only used for supervisor
+ *
+ * @param mixed $parent
+ * @param string $parentPropertyName
+ * @return PHPExcel_Style_Color
+ */
+ public function bindParent($parent, $parentPropertyName = null)
+ {
+ $this->parent = $parent;
+ $this->parentPropertyName = $parentPropertyName;
+ return $this;
+ }
+
+ /**
+ * Get the shared style component for the currently active cell in currently active sheet.
+ * Only used for style supervisor
+ *
+ * @return PHPExcel_Style_Color
+ */
+ public function getSharedComponent()
+ {
+ switch ($this->parentPropertyName) {
+ case 'endColor':
+ return $this->parent->getSharedComponent()->getEndColor();
+ case 'color':
+ return $this->parent->getSharedComponent()->getColor();
+ case 'startColor':
+ return $this->parent->getSharedComponent()->getStartColor();
+ }
+ }
+
+ /**
+ * Build style array from subcomponents
+ *
+ * @param array $array
+ * @return array
+ */
+ public function getStyleArray($array)
+ {
+ switch ($this->parentPropertyName) {
+ case 'endColor':
+ $key = 'endcolor';
+ break;
+ case 'color':
+ $key = 'color';
+ break;
+ case 'startColor':
+ $key = 'startcolor';
+ break;
+
+ }
+ return $this->parent->getStyleArray(array($key => $array));
+ }
+
+ /**
+ * Apply styles from array
+ *
+ *
+ * $objPHPExcel->getActiveSheet()->getStyle('B2')->getFont()->getColor()->applyFromArray( array('rgb' => '808080') );
+ *
+ *
+ * @param array $pStyles Array containing style information
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Style_Color
+ */
+ public function applyFromArray($pStyles = null)
+ {
+ if (is_array($pStyles)) {
+ if ($this->isSupervisor) {
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
+ } else {
+ if (array_key_exists('rgb', $pStyles)) {
+ $this->setRGB($pStyles['rgb']);
+ }
+ if (array_key_exists('argb', $pStyles)) {
+ $this->setARGB($pStyles['argb']);
+ }
+ }
+ } else {
+ throw new PHPExcel_Exception("Invalid style array passed.");
+ }
+ return $this;
+ }
+
+ /**
+ * Get ARGB
+ *
+ * @return string
+ */
+ public function getARGB()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getARGB();
+ }
+ return $this->argb;
+ }
+
+ /**
+ * Set ARGB
+ *
+ * @param string $pValue
+ * @return PHPExcel_Style_Color
+ */
+ public function setARGB($pValue = PHPExcel_Style_Color::COLOR_BLACK)
+ {
+ if ($pValue == '') {
+ $pValue = PHPExcel_Style_Color::COLOR_BLACK;
+ }
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('argb' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->argb = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get RGB
+ *
+ * @return string
+ */
+ public function getRGB()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getRGB();
+ }
+ return substr($this->argb, 2);
+ }
+
+ /**
+ * Set RGB
+ *
+ * @param string $pValue RGB value
+ * @return PHPExcel_Style_Color
+ */
+ public function setRGB($pValue = '000000')
+ {
+ if ($pValue == '') {
+ $pValue = '000000';
+ }
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('argb' => 'FF' . $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->argb = 'FF' . $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get a specified colour component of an RGB value
+ *
+ * @private
+ * @param string $RGB The colour as an RGB value (e.g. FF00CCCC or CCDDEE
+ * @param int $offset Position within the RGB value to extract
+ * @param boolean $hex Flag indicating whether the component should be returned as a hex or a
+ * decimal value
+ * @return string The extracted colour component
+ */
+ private static function getColourComponent($RGB, $offset, $hex = true)
+ {
+ $colour = substr($RGB, $offset, 2);
+ if (!$hex) {
+ $colour = hexdec($colour);
+ }
+ return $colour;
+ }
+
+ /**
+ * Get the red colour component of an RGB value
+ *
+ * @param string $RGB The colour as an RGB value (e.g. FF00CCCC or CCDDEE
+ * @param boolean $hex Flag indicating whether the component should be returned as a hex or a
+ * decimal value
+ * @return string The red colour component
+ */
+ public static function getRed($RGB, $hex = true)
+ {
+ return self::getColourComponent($RGB, strlen($RGB) - 6, $hex);
+ }
+
+ /**
+ * Get the green colour component of an RGB value
+ *
+ * @param string $RGB The colour as an RGB value (e.g. FF00CCCC or CCDDEE
+ * @param boolean $hex Flag indicating whether the component should be returned as a hex or a
+ * decimal value
+ * @return string The green colour component
+ */
+ public static function getGreen($RGB, $hex = true)
+ {
+ return self::getColourComponent($RGB, strlen($RGB) - 4, $hex);
+ }
+
+ /**
+ * Get the blue colour component of an RGB value
+ *
+ * @param string $RGB The colour as an RGB value (e.g. FF00CCCC or CCDDEE
+ * @param boolean $hex Flag indicating whether the component should be returned as a hex or a
+ * decimal value
+ * @return string The blue colour component
+ */
+ public static function getBlue($RGB, $hex = true)
+ {
+ return self::getColourComponent($RGB, strlen($RGB) - 2, $hex);
+ }
+
+ /**
+ * Adjust the brightness of a color
+ *
+ * @param string $hex The colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE)
+ * @param float $adjustPercentage The percentage by which to adjust the colour as a float from -1 to 1
+ * @return string The adjusted colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE)
+ */
+ public static function changeBrightness($hex, $adjustPercentage)
+ {
+ $rgba = (strlen($hex) == 8);
+
+ $red = self::getRed($hex, false);
+ $green = self::getGreen($hex, false);
+ $blue = self::getBlue($hex, false);
+ if ($adjustPercentage > 0) {
+ $red += (255 - $red) * $adjustPercentage;
+ $green += (255 - $green) * $adjustPercentage;
+ $blue += (255 - $blue) * $adjustPercentage;
+ } else {
+ $red += $red * $adjustPercentage;
+ $green += $green * $adjustPercentage;
+ $blue += $blue * $adjustPercentage;
+ }
+
+ if ($red < 0) {
+ $red = 0;
+ } elseif ($red > 255) {
+ $red = 255;
+ }
+ if ($green < 0) {
+ $green = 0;
+ } elseif ($green > 255) {
+ $green = 255;
+ }
+ if ($blue < 0) {
+ $blue = 0;
+ } elseif ($blue > 255) {
+ $blue = 255;
+ }
+
+ $rgb = strtoupper(
+ str_pad(dechex($red), 2, '0', 0) .
+ str_pad(dechex($green), 2, '0', 0) .
+ str_pad(dechex($blue), 2, '0', 0)
+ );
+ return (($rgba) ? 'FF' : '') . $rgb;
+ }
+
+ /**
+ * Get indexed color
+ *
+ * @param int $pIndex Index entry point into the colour array
+ * @param boolean $background Flag to indicate whether default background or foreground colour
+ * should be returned if the indexed colour doesn't exist
+ * @return PHPExcel_Style_Color
+ */
+ public static function indexedColor($pIndex, $background = false)
+ {
+ // Clean parameter
+ $pIndex = intval($pIndex);
+
+ // Indexed colors
+ if (is_null(self::$indexedColors)) {
+ self::$indexedColors = array(
+ 1 => 'FF000000', // System Colour #1 - Black
+ 2 => 'FFFFFFFF', // System Colour #2 - White
+ 3 => 'FFFF0000', // System Colour #3 - Red
+ 4 => 'FF00FF00', // System Colour #4 - Green
+ 5 => 'FF0000FF', // System Colour #5 - Blue
+ 6 => 'FFFFFF00', // System Colour #6 - Yellow
+ 7 => 'FFFF00FF', // System Colour #7- Magenta
+ 8 => 'FF00FFFF', // System Colour #8- Cyan
+ 9 => 'FF800000', // Standard Colour #9
+ 10 => 'FF008000', // Standard Colour #10
+ 11 => 'FF000080', // Standard Colour #11
+ 12 => 'FF808000', // Standard Colour #12
+ 13 => 'FF800080', // Standard Colour #13
+ 14 => 'FF008080', // Standard Colour #14
+ 15 => 'FFC0C0C0', // Standard Colour #15
+ 16 => 'FF808080', // Standard Colour #16
+ 17 => 'FF9999FF', // Chart Fill Colour #17
+ 18 => 'FF993366', // Chart Fill Colour #18
+ 19 => 'FFFFFFCC', // Chart Fill Colour #19
+ 20 => 'FFCCFFFF', // Chart Fill Colour #20
+ 21 => 'FF660066', // Chart Fill Colour #21
+ 22 => 'FFFF8080', // Chart Fill Colour #22
+ 23 => 'FF0066CC', // Chart Fill Colour #23
+ 24 => 'FFCCCCFF', // Chart Fill Colour #24
+ 25 => 'FF000080', // Chart Line Colour #25
+ 26 => 'FFFF00FF', // Chart Line Colour #26
+ 27 => 'FFFFFF00', // Chart Line Colour #27
+ 28 => 'FF00FFFF', // Chart Line Colour #28
+ 29 => 'FF800080', // Chart Line Colour #29
+ 30 => 'FF800000', // Chart Line Colour #30
+ 31 => 'FF008080', // Chart Line Colour #31
+ 32 => 'FF0000FF', // Chart Line Colour #32
+ 33 => 'FF00CCFF', // Standard Colour #33
+ 34 => 'FFCCFFFF', // Standard Colour #34
+ 35 => 'FFCCFFCC', // Standard Colour #35
+ 36 => 'FFFFFF99', // Standard Colour #36
+ 37 => 'FF99CCFF', // Standard Colour #37
+ 38 => 'FFFF99CC', // Standard Colour #38
+ 39 => 'FFCC99FF', // Standard Colour #39
+ 40 => 'FFFFCC99', // Standard Colour #40
+ 41 => 'FF3366FF', // Standard Colour #41
+ 42 => 'FF33CCCC', // Standard Colour #42
+ 43 => 'FF99CC00', // Standard Colour #43
+ 44 => 'FFFFCC00', // Standard Colour #44
+ 45 => 'FFFF9900', // Standard Colour #45
+ 46 => 'FFFF6600', // Standard Colour #46
+ 47 => 'FF666699', // Standard Colour #47
+ 48 => 'FF969696', // Standard Colour #48
+ 49 => 'FF003366', // Standard Colour #49
+ 50 => 'FF339966', // Standard Colour #50
+ 51 => 'FF003300', // Standard Colour #51
+ 52 => 'FF333300', // Standard Colour #52
+ 53 => 'FF993300', // Standard Colour #53
+ 54 => 'FF993366', // Standard Colour #54
+ 55 => 'FF333399', // Standard Colour #55
+ 56 => 'FF333333' // Standard Colour #56
+ );
+ }
+
+ if (array_key_exists($pIndex, self::$indexedColors)) {
+ return new PHPExcel_Style_Color(self::$indexedColors[$pIndex]);
+ }
+
+ if ($background) {
+ return new PHPExcel_Style_Color(self::COLOR_WHITE);
+ }
+ return new PHPExcel_Style_Color(self::COLOR_BLACK);
+ }
+
+ /**
+ * Get hash code
+ *
+ * @return string Hash code
+ */
+ public function getHashCode()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getHashCode();
+ }
+ return md5(
+ $this->argb .
+ __CLASS__
+ );
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Conditional.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Conditional.php
new file mode 100755
index 000000000..331362b42
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Conditional.php
@@ -0,0 +1,293 @@
+conditionType = PHPExcel_Style_Conditional::CONDITION_NONE;
+ $this->operatorType = PHPExcel_Style_Conditional::OPERATOR_NONE;
+ $this->text = null;
+ $this->condition = array();
+ $this->style = new PHPExcel_Style(false, true);
+ }
+
+ /**
+ * Get Condition type
+ *
+ * @return string
+ */
+ public function getConditionType()
+ {
+ return $this->conditionType;
+ }
+
+ /**
+ * Set Condition type
+ *
+ * @param string $pValue PHPExcel_Style_Conditional condition type
+ * @return PHPExcel_Style_Conditional
+ */
+ public function setConditionType($pValue = PHPExcel_Style_Conditional::CONDITION_NONE)
+ {
+ $this->conditionType = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Operator type
+ *
+ * @return string
+ */
+ public function getOperatorType()
+ {
+ return $this->operatorType;
+ }
+
+ /**
+ * Set Operator type
+ *
+ * @param string $pValue PHPExcel_Style_Conditional operator type
+ * @return PHPExcel_Style_Conditional
+ */
+ public function setOperatorType($pValue = PHPExcel_Style_Conditional::OPERATOR_NONE)
+ {
+ $this->operatorType = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get text
+ *
+ * @return string
+ */
+ public function getText()
+ {
+ return $this->text;
+ }
+
+ /**
+ * Set text
+ *
+ * @param string $value
+ * @return PHPExcel_Style_Conditional
+ */
+ public function setText($value = null)
+ {
+ $this->text = $value;
+ return $this;
+ }
+
+ /**
+ * Get Condition
+ *
+ * @deprecated Deprecated, use getConditions instead
+ * @return string
+ */
+ public function getCondition()
+ {
+ if (isset($this->condition[0])) {
+ return $this->condition[0];
+ }
+
+ return '';
+ }
+
+ /**
+ * Set Condition
+ *
+ * @deprecated Deprecated, use setConditions instead
+ * @param string $pValue Condition
+ * @return PHPExcel_Style_Conditional
+ */
+ public function setCondition($pValue = '')
+ {
+ if (!is_array($pValue)) {
+ $pValue = array($pValue);
+ }
+
+ return $this->setConditions($pValue);
+ }
+
+ /**
+ * Get Conditions
+ *
+ * @return string[]
+ */
+ public function getConditions()
+ {
+ return $this->condition;
+ }
+
+ /**
+ * Set Conditions
+ *
+ * @param string[] $pValue Condition
+ * @return PHPExcel_Style_Conditional
+ */
+ public function setConditions($pValue)
+ {
+ if (!is_array($pValue)) {
+ $pValue = array($pValue);
+ }
+ $this->condition = $pValue;
+ return $this;
+ }
+
+ /**
+ * Add Condition
+ *
+ * @param string $pValue Condition
+ * @return PHPExcel_Style_Conditional
+ */
+ public function addCondition($pValue = '')
+ {
+ $this->condition[] = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Style
+ *
+ * @return PHPExcel_Style
+ */
+ public function getStyle()
+ {
+ return $this->style;
+ }
+
+ /**
+ * Set Style
+ *
+ * @param PHPExcel_Style $pValue
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Style_Conditional
+ */
+ public function setStyle(PHPExcel_Style $pValue = null)
+ {
+ $this->style = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get hash code
+ *
+ * @return string Hash code
+ */
+ public function getHashCode()
+ {
+ return md5(
+ $this->conditionType .
+ $this->operatorType .
+ implode(';', $this->condition) .
+ $this->style->getHashCode() .
+ __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) {
+ if (is_object($value)) {
+ $this->$key = clone $value;
+ } else {
+ $this->$key = $value;
+ }
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Fill.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Fill.php
new file mode 100755
index 000000000..26343ff5a
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Fill.php
@@ -0,0 +1,322 @@
+fillType = null;
+ }
+ $this->startColor = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_WHITE, $isSupervisor, $isConditional);
+ $this->endColor = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor, $isConditional);
+
+ // bind parent if we are a supervisor
+ if ($isSupervisor) {
+ $this->startColor->bindParent($this, 'startColor');
+ $this->endColor->bindParent($this, 'endColor');
+ }
+ }
+
+ /**
+ * Get the shared style component for the currently active cell in currently active sheet.
+ * Only used for style supervisor
+ *
+ * @return PHPExcel_Style_Fill
+ */
+ public function getSharedComponent()
+ {
+ return $this->parent->getSharedComponent()->getFill();
+ }
+
+ /**
+ * Build style array from subcomponents
+ *
+ * @param array $array
+ * @return array
+ */
+ public function getStyleArray($array)
+ {
+ return array('fill' => $array);
+ }
+
+ /**
+ * Apply styles from array
+ *
+ *
+ * $objPHPExcel->getActiveSheet()->getStyle('B2')->getFill()->applyFromArray(
+ * array(
+ * 'type' => PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR,
+ * 'rotation' => 0,
+ * 'startcolor' => array(
+ * 'rgb' => '000000'
+ * ),
+ * 'endcolor' => array(
+ * 'argb' => 'FFFFFFFF'
+ * )
+ * )
+ * );
+ *
+ *
+ * @param array $pStyles Array containing style information
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Style_Fill
+ */
+ public function applyFromArray($pStyles = null)
+ {
+ if (is_array($pStyles)) {
+ if ($this->isSupervisor) {
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
+ } else {
+ if (array_key_exists('type', $pStyles)) {
+ $this->setFillType($pStyles['type']);
+ }
+ if (array_key_exists('rotation', $pStyles)) {
+ $this->setRotation($pStyles['rotation']);
+ }
+ if (array_key_exists('startcolor', $pStyles)) {
+ $this->getStartColor()->applyFromArray($pStyles['startcolor']);
+ }
+ if (array_key_exists('endcolor', $pStyles)) {
+ $this->getEndColor()->applyFromArray($pStyles['endcolor']);
+ }
+ if (array_key_exists('color', $pStyles)) {
+ $this->getStartColor()->applyFromArray($pStyles['color']);
+ }
+ }
+ } else {
+ throw new PHPExcel_Exception("Invalid style array passed.");
+ }
+ return $this;
+ }
+
+ /**
+ * Get Fill Type
+ *
+ * @return string
+ */
+ public function getFillType()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getFillType();
+ }
+ return $this->fillType;
+ }
+
+ /**
+ * Set Fill Type
+ *
+ * @param string $pValue PHPExcel_Style_Fill fill type
+ * @return PHPExcel_Style_Fill
+ */
+ public function setFillType($pValue = PHPExcel_Style_Fill::FILL_NONE)
+ {
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('type' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->fillType = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get Rotation
+ *
+ * @return double
+ */
+ public function getRotation()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getRotation();
+ }
+ return $this->rotation;
+ }
+
+ /**
+ * Set Rotation
+ *
+ * @param double $pValue
+ * @return PHPExcel_Style_Fill
+ */
+ public function setRotation($pValue = 0)
+ {
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('rotation' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->rotation = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get Start Color
+ *
+ * @return PHPExcel_Style_Color
+ */
+ public function getStartColor()
+ {
+ return $this->startColor;
+ }
+
+ /**
+ * Set Start Color
+ *
+ * @param PHPExcel_Style_Color $pValue
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Style_Fill
+ */
+ public function setStartColor(PHPExcel_Style_Color $pValue = null)
+ {
+ // make sure parameter is a real color and not a supervisor
+ $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;
+
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStartColor()->getStyleArray(array('argb' => $color->getARGB()));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->startColor = $color;
+ }
+ return $this;
+ }
+
+ /**
+ * Get End Color
+ *
+ * @return PHPExcel_Style_Color
+ */
+ public function getEndColor()
+ {
+ return $this->endColor;
+ }
+
+ /**
+ * Set End Color
+ *
+ * @param PHPExcel_Style_Color $pValue
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Style_Fill
+ */
+ public function setEndColor(PHPExcel_Style_Color $pValue = null)
+ {
+ // make sure parameter is a real color and not a supervisor
+ $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;
+
+ if ($this->isSupervisor) {
+ $styleArray = $this->getEndColor()->getStyleArray(array('argb' => $color->getARGB()));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->endColor = $color;
+ }
+ return $this;
+ }
+
+ /**
+ * Get hash code
+ *
+ * @return string Hash code
+ */
+ public function getHashCode()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getHashCode();
+ }
+ return md5(
+ $this->getFillType() .
+ $this->getRotation() .
+ $this->getStartColor()->getHashCode() .
+ $this->getEndColor()->getHashCode() .
+ __CLASS__
+ );
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Font.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Font.php
new file mode 100755
index 000000000..9566e1dfa
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Font.php
@@ -0,0 +1,543 @@
+name = null;
+ $this->size = null;
+ $this->bold = null;
+ $this->italic = null;
+ $this->superScript = null;
+ $this->subScript = null;
+ $this->underline = null;
+ $this->strikethrough = null;
+ $this->color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor, $isConditional);
+ } else {
+ $this->color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor);
+ }
+ // bind parent if we are a supervisor
+ if ($isSupervisor) {
+ $this->color->bindParent($this, 'color');
+ }
+ }
+
+ /**
+ * Get the shared style component for the currently active cell in currently active sheet.
+ * Only used for style supervisor
+ *
+ * @return PHPExcel_Style_Font
+ */
+ public function getSharedComponent()
+ {
+ return $this->parent->getSharedComponent()->getFont();
+ }
+
+ /**
+ * Build style array from subcomponents
+ *
+ * @param array $array
+ * @return array
+ */
+ public function getStyleArray($array)
+ {
+ return array('font' => $array);
+ }
+
+ /**
+ * Apply styles from array
+ *
+ *
+ * $objPHPExcel->getActiveSheet()->getStyle('B2')->getFont()->applyFromArray(
+ * array(
+ * 'name' => 'Arial',
+ * 'bold' => TRUE,
+ * 'italic' => FALSE,
+ * 'underline' => PHPExcel_Style_Font::UNDERLINE_DOUBLE,
+ * 'strike' => FALSE,
+ * 'color' => array(
+ * 'rgb' => '808080'
+ * )
+ * )
+ * );
+ *
+ *
+ * @param array $pStyles Array containing style information
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Style_Font
+ */
+ public function applyFromArray($pStyles = null)
+ {
+ if (is_array($pStyles)) {
+ if ($this->isSupervisor) {
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
+ } else {
+ if (array_key_exists('name', $pStyles)) {
+ $this->setName($pStyles['name']);
+ }
+ if (array_key_exists('bold', $pStyles)) {
+ $this->setBold($pStyles['bold']);
+ }
+ if (array_key_exists('italic', $pStyles)) {
+ $this->setItalic($pStyles['italic']);
+ }
+ if (array_key_exists('superScript', $pStyles)) {
+ $this->setSuperScript($pStyles['superScript']);
+ }
+ if (array_key_exists('subScript', $pStyles)) {
+ $this->setSubScript($pStyles['subScript']);
+ }
+ if (array_key_exists('underline', $pStyles)) {
+ $this->setUnderline($pStyles['underline']);
+ }
+ if (array_key_exists('strike', $pStyles)) {
+ $this->setStrikethrough($pStyles['strike']);
+ }
+ if (array_key_exists('color', $pStyles)) {
+ $this->getColor()->applyFromArray($pStyles['color']);
+ }
+ if (array_key_exists('size', $pStyles)) {
+ $this->setSize($pStyles['size']);
+ }
+ }
+ } else {
+ throw new PHPExcel_Exception("Invalid style array passed.");
+ }
+ return $this;
+ }
+
+ /**
+ * Get Name
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getName();
+ }
+ return $this->name;
+ }
+
+ /**
+ * Set Name
+ *
+ * @param string $pValue
+ * @return PHPExcel_Style_Font
+ */
+ public function setName($pValue = 'Calibri')
+ {
+ if ($pValue == '') {
+ $pValue = 'Calibri';
+ }
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('name' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->name = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get Size
+ *
+ * @return double
+ */
+ public function getSize()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getSize();
+ }
+ return $this->size;
+ }
+
+ /**
+ * Set Size
+ *
+ * @param double $pValue
+ * @return PHPExcel_Style_Font
+ */
+ public function setSize($pValue = 10)
+ {
+ if ($pValue == '') {
+ $pValue = 10;
+ }
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('size' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->size = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get Bold
+ *
+ * @return boolean
+ */
+ public function getBold()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getBold();
+ }
+ return $this->bold;
+ }
+
+ /**
+ * Set Bold
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Style_Font
+ */
+ public function setBold($pValue = false)
+ {
+ if ($pValue == '') {
+ $pValue = false;
+ }
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('bold' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->bold = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get Italic
+ *
+ * @return boolean
+ */
+ public function getItalic()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getItalic();
+ }
+ return $this->italic;
+ }
+
+ /**
+ * Set Italic
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Style_Font
+ */
+ public function setItalic($pValue = false)
+ {
+ if ($pValue == '') {
+ $pValue = false;
+ }
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('italic' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->italic = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get SuperScript
+ *
+ * @return boolean
+ */
+ public function getSuperScript()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getSuperScript();
+ }
+ return $this->superScript;
+ }
+
+ /**
+ * Set SuperScript
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Style_Font
+ */
+ public function setSuperScript($pValue = false)
+ {
+ if ($pValue == '') {
+ $pValue = false;
+ }
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('superScript' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->superScript = $pValue;
+ $this->subScript = !$pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get SubScript
+ *
+ * @return boolean
+ */
+ public function getSubScript()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getSubScript();
+ }
+ return $this->subScript;
+ }
+
+ /**
+ * Set SubScript
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Style_Font
+ */
+ public function setSubScript($pValue = false)
+ {
+ if ($pValue == '') {
+ $pValue = false;
+ }
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('subScript' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->subScript = $pValue;
+ $this->superScript = !$pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get Underline
+ *
+ * @return string
+ */
+ public function getUnderline()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getUnderline();
+ }
+ return $this->underline;
+ }
+
+ /**
+ * Set Underline
+ *
+ * @param string|boolean $pValue PHPExcel_Style_Font underline type
+ * If a boolean is passed, then TRUE equates to UNDERLINE_SINGLE,
+ * false equates to UNDERLINE_NONE
+ * @return PHPExcel_Style_Font
+ */
+ public function setUnderline($pValue = self::UNDERLINE_NONE)
+ {
+ if (is_bool($pValue)) {
+ $pValue = ($pValue) ? self::UNDERLINE_SINGLE : self::UNDERLINE_NONE;
+ } elseif ($pValue == '') {
+ $pValue = self::UNDERLINE_NONE;
+ }
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('underline' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->underline = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get Strikethrough
+ *
+ * @return boolean
+ */
+ public function getStrikethrough()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getStrikethrough();
+ }
+ return $this->strikethrough;
+ }
+
+ /**
+ * Set Strikethrough
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Style_Font
+ */
+ public function setStrikethrough($pValue = false)
+ {
+ if ($pValue == '') {
+ $pValue = false;
+ }
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('strike' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->strikethrough = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get Color
+ *
+ * @return PHPExcel_Style_Color
+ */
+ public function getColor()
+ {
+ return $this->color;
+ }
+
+ /**
+ * Set Color
+ *
+ * @param PHPExcel_Style_Color $pValue
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Style_Font
+ */
+ public function setColor(PHPExcel_Style_Color $pValue = null)
+ {
+ // make sure parameter is a real color and not a supervisor
+ $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;
+
+ if ($this->isSupervisor) {
+ $styleArray = $this->getColor()->getStyleArray(array('argb' => $color->getARGB()));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->color = $color;
+ }
+ return $this;
+ }
+
+ /**
+ * Get hash code
+ *
+ * @return string Hash code
+ */
+ public function getHashCode()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getHashCode();
+ }
+ return md5(
+ $this->name .
+ $this->size .
+ ($this->bold ? 't' : 'f') .
+ ($this->italic ? 't' : 'f') .
+ ($this->superScript ? 't' : 'f') .
+ ($this->subScript ? 't' : 'f') .
+ $this->underline .
+ ($this->strikethrough ? 't' : 'f') .
+ $this->color->getHashCode() .
+ __CLASS__
+ );
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/NumberFormat.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/NumberFormat.php
new file mode 100755
index 000000000..1b72cda92
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/NumberFormat.php
@@ -0,0 +1,751 @@
+formatCode = null;
+ $this->builtInFormatCode = false;
+ }
+ }
+
+ /**
+ * Get the shared style component for the currently active cell in currently active sheet.
+ * Only used for style supervisor
+ *
+ * @return PHPExcel_Style_NumberFormat
+ */
+ public function getSharedComponent()
+ {
+ return $this->parent->getSharedComponent()->getNumberFormat();
+ }
+
+ /**
+ * Build style array from subcomponents
+ *
+ * @param array $array
+ * @return array
+ */
+ public function getStyleArray($array)
+ {
+ return array('numberformat' => $array);
+ }
+
+ /**
+ * Apply styles from array
+ *
+ *
+ * $objPHPExcel->getActiveSheet()->getStyle('B2')->getNumberFormat()->applyFromArray(
+ * array(
+ * 'code' => PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE
+ * )
+ * );
+ *
+ *
+ * @param array $pStyles Array containing style information
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Style_NumberFormat
+ */
+ public function applyFromArray($pStyles = null)
+ {
+ if (is_array($pStyles)) {
+ if ($this->isSupervisor) {
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
+ } else {
+ if (array_key_exists('code', $pStyles)) {
+ $this->setFormatCode($pStyles['code']);
+ }
+ }
+ } else {
+ throw new PHPExcel_Exception("Invalid style array passed.");
+ }
+ return $this;
+ }
+
+ /**
+ * Get Format Code
+ *
+ * @return string
+ */
+ public function getFormatCode()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getFormatCode();
+ }
+ if ($this->builtInFormatCode !== false) {
+ return self::builtInFormatCode($this->builtInFormatCode);
+ }
+ return $this->formatCode;
+ }
+
+ /**
+ * Set Format Code
+ *
+ * @param string $pValue
+ * @return PHPExcel_Style_NumberFormat
+ */
+ public function setFormatCode($pValue = PHPExcel_Style_NumberFormat::FORMAT_GENERAL)
+ {
+ if ($pValue == '') {
+ $pValue = PHPExcel_Style_NumberFormat::FORMAT_GENERAL;
+ }
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('code' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->formatCode = $pValue;
+ $this->builtInFormatCode = self::builtInFormatCodeIndex($pValue);
+ }
+ return $this;
+ }
+
+ /**
+ * Get Built-In Format Code
+ *
+ * @return int
+ */
+ public function getBuiltInFormatCode()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getBuiltInFormatCode();
+ }
+ return $this->builtInFormatCode;
+ }
+
+ /**
+ * Set Built-In Format Code
+ *
+ * @param int $pValue
+ * @return PHPExcel_Style_NumberFormat
+ */
+ public function setBuiltInFormatCode($pValue = 0)
+ {
+
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('code' => self::builtInFormatCode($pValue)));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->builtInFormatCode = $pValue;
+ $this->formatCode = self::builtInFormatCode($pValue);
+ }
+ return $this;
+ }
+
+ /**
+ * Fill built-in format codes
+ */
+ private static function fillBuiltInFormatCodes()
+ {
+ // [MS-OI29500: Microsoft Office Implementation Information for ISO/IEC-29500 Standard Compliance]
+ // 18.8.30. numFmt (Number Format)
+ //
+ // The ECMA standard defines built-in format IDs
+ // 14: "mm-dd-yy"
+ // 22: "m/d/yy h:mm"
+ // 37: "#,##0 ;(#,##0)"
+ // 38: "#,##0 ;[Red](#,##0)"
+ // 39: "#,##0.00;(#,##0.00)"
+ // 40: "#,##0.00;[Red](#,##0.00)"
+ // 47: "mmss.0"
+ // KOR fmt 55: "yyyy-mm-dd"
+ // Excel defines built-in format IDs
+ // 14: "m/d/yyyy"
+ // 22: "m/d/yyyy h:mm"
+ // 37: "#,##0_);(#,##0)"
+ // 38: "#,##0_);[Red](#,##0)"
+ // 39: "#,##0.00_);(#,##0.00)"
+ // 40: "#,##0.00_);[Red](#,##0.00)"
+ // 47: "mm:ss.0"
+ // KOR fmt 55: "yyyy/mm/dd"
+
+ // Built-in format codes
+ if (is_null(self::$builtInFormats)) {
+ self::$builtInFormats = array();
+
+ // General
+ self::$builtInFormats[0] = PHPExcel_Style_NumberFormat::FORMAT_GENERAL;
+ self::$builtInFormats[1] = '0';
+ self::$builtInFormats[2] = '0.00';
+ self::$builtInFormats[3] = '#,##0';
+ self::$builtInFormats[4] = '#,##0.00';
+
+ self::$builtInFormats[9] = '0%';
+ self::$builtInFormats[10] = '0.00%';
+ self::$builtInFormats[11] = '0.00E+00';
+ self::$builtInFormats[12] = '# ?/?';
+ self::$builtInFormats[13] = '# ??/??';
+ self::$builtInFormats[14] = 'm/d/yyyy'; // Despite ECMA 'mm-dd-yy';
+ self::$builtInFormats[15] = 'd-mmm-yy';
+ self::$builtInFormats[16] = 'd-mmm';
+ self::$builtInFormats[17] = 'mmm-yy';
+ self::$builtInFormats[18] = 'h:mm AM/PM';
+ self::$builtInFormats[19] = 'h:mm:ss AM/PM';
+ self::$builtInFormats[20] = 'h:mm';
+ self::$builtInFormats[21] = 'h:mm:ss';
+ self::$builtInFormats[22] = 'm/d/yyyy h:mm'; // Despite ECMA 'm/d/yy h:mm';
+
+ self::$builtInFormats[37] = '#,##0_);(#,##0)'; // Despite ECMA '#,##0 ;(#,##0)';
+ self::$builtInFormats[38] = '#,##0_);[Red](#,##0)'; // Despite ECMA '#,##0 ;[Red](#,##0)';
+ self::$builtInFormats[39] = '#,##0.00_);(#,##0.00)'; // Despite ECMA '#,##0.00;(#,##0.00)';
+ self::$builtInFormats[40] = '#,##0.00_);[Red](#,##0.00)'; // Despite ECMA '#,##0.00;[Red](#,##0.00)';
+
+ self::$builtInFormats[44] = '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)';
+ self::$builtInFormats[45] = 'mm:ss';
+ self::$builtInFormats[46] = '[h]:mm:ss';
+ self::$builtInFormats[47] = 'mm:ss.0'; // Despite ECMA 'mmss.0';
+ self::$builtInFormats[48] = '##0.0E+0';
+ self::$builtInFormats[49] = '@';
+
+ // CHT
+ self::$builtInFormats[27] = '[$-404]e/m/d';
+ self::$builtInFormats[30] = 'm/d/yy';
+ self::$builtInFormats[36] = '[$-404]e/m/d';
+ self::$builtInFormats[50] = '[$-404]e/m/d';
+ self::$builtInFormats[57] = '[$-404]e/m/d';
+
+ // THA
+ self::$builtInFormats[59] = 't0';
+ self::$builtInFormats[60] = 't0.00';
+ self::$builtInFormats[61] = 't#,##0';
+ self::$builtInFormats[62] = 't#,##0.00';
+ self::$builtInFormats[67] = 't0%';
+ self::$builtInFormats[68] = 't0.00%';
+ self::$builtInFormats[69] = 't# ?/?';
+ self::$builtInFormats[70] = 't# ??/??';
+
+ // Flip array (for faster lookups)
+ self::$flippedBuiltInFormats = array_flip(self::$builtInFormats);
+ }
+ }
+
+ /**
+ * Get built-in format code
+ *
+ * @param int $pIndex
+ * @return string
+ */
+ public static function builtInFormatCode($pIndex)
+ {
+ // Clean parameter
+ $pIndex = intval($pIndex);
+
+ // Ensure built-in format codes are available
+ self::fillBuiltInFormatCodes();
+ // Lookup format code
+ if (isset(self::$builtInFormats[$pIndex])) {
+ return self::$builtInFormats[$pIndex];
+ }
+
+ return '';
+ }
+
+ /**
+ * Get built-in format code index
+ *
+ * @param string $formatCode
+ * @return int|boolean
+ */
+ public static function builtInFormatCodeIndex($formatCode)
+ {
+ // Ensure built-in format codes are available
+ self::fillBuiltInFormatCodes();
+
+ // Lookup format code
+ if (isset(self::$flippedBuiltInFormats[$formatCode])) {
+ return self::$flippedBuiltInFormats[$formatCode];
+ }
+
+ return false;
+ }
+
+ /**
+ * Get hash code
+ *
+ * @return string Hash code
+ */
+ public function getHashCode()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getHashCode();
+ }
+ return md5(
+ $this->formatCode .
+ $this->builtInFormatCode .
+ __CLASS__
+ );
+ }
+
+ /**
+ * Search/replace values to convert Excel date/time format masks to PHP format masks
+ *
+ * @var array
+ */
+ private static $dateFormatReplacements = array(
+ // first remove escapes related to non-format characters
+ '\\' => '',
+ // 12-hour suffix
+ 'am/pm' => 'A',
+ // 4-digit year
+ 'e' => 'Y',
+ 'yyyy' => 'Y',
+ // 2-digit year
+ 'yy' => 'y',
+ // first letter of month - no php equivalent
+ 'mmmmm' => 'M',
+ // full month name
+ 'mmmm' => 'F',
+ // short month name
+ 'mmm' => 'M',
+ // mm is minutes if time, but can also be month w/leading zero
+ // so we try to identify times be the inclusion of a : separator in the mask
+ // It isn't perfect, but the best way I know how
+ ':mm' => ':i',
+ 'mm:' => 'i:',
+ // month leading zero
+ 'mm' => 'm',
+ // month no leading zero
+ 'm' => 'n',
+ // full day of week name
+ 'dddd' => 'l',
+ // short day of week name
+ 'ddd' => 'D',
+ // days leading zero
+ 'dd' => 'd',
+ // days no leading zero
+ 'd' => 'j',
+ // seconds
+ 'ss' => 's',
+ // fractional seconds - no php equivalent
+ '.s' => ''
+ );
+ /**
+ * Search/replace values to convert Excel date/time format masks hours to PHP format masks (24 hr clock)
+ *
+ * @var array
+ */
+ private static $dateFormatReplacements24 = array(
+ 'hh' => 'H',
+ 'h' => 'G'
+ );
+ /**
+ * Search/replace values to convert Excel date/time format masks hours to PHP format masks (12 hr clock)
+ *
+ * @var array
+ */
+ private static $dateFormatReplacements12 = array(
+ 'hh' => 'h',
+ 'h' => 'g'
+ );
+
+ private static function setLowercaseCallback($matches) {
+ return mb_strtolower($matches[0]);
+ }
+
+ private static function escapeQuotesCallback($matches) {
+ return '\\' . implode('\\', str_split($matches[1]));
+ }
+
+ private static function formatAsDate(&$value, &$format)
+ {
+ // strip off first part containing e.g. [$-F800] or [$USD-409]
+ // general syntax: [$
';
+ if ($value != (int)$value) {
+ self::formatAsFraction($value, $format);
+ }
+
+ } else {
+ // Handle the number itself
+
+ // scale number
+ $value = $value / $scale;
+
+ // Strip #
+ $format = preg_replace('/\\#/', '0', $format);
+
+ $n = "/\[[^\]]+\]/";
+ $m = preg_replace($n, '', $format);
+ $number_regex = "/(0+)(\.?)(0*)/";
+ if (preg_match($number_regex, $m, $matches)) {
+ $left = $matches[1];
+ $dec = $matches[2];
+ $right = $matches[3];
+
+ // minimun width of formatted number (including dot)
+ $minWidth = strlen($left) + strlen($dec) + strlen($right);
+ if ($useThousands) {
+ $value = number_format(
+ $value,
+ strlen($right),
+ PHPExcel_Shared_String::getDecimalSeparator(),
+ PHPExcel_Shared_String::getThousandsSeparator()
+ );
+ $value = preg_replace($number_regex, $value, $format);
+ } else {
+ if (preg_match('/[0#]E[+-]0/i', $format)) {
+ // Scientific format
+ $value = sprintf('%5.2E', $value);
+ } elseif (preg_match('/0([^\d\.]+)0/', $format)) {
+ $value = self::complexNumberFormatMask($value, $format);
+ } else {
+ $sprintf_pattern = "%0$minWidth." . strlen($right) . "f";
+ $value = sprintf($sprintf_pattern, $value);
+ $value = preg_replace($number_regex, $value, $format);
+ }
+ }
+ }
+ }
+ if (preg_match('/\[\$(.*)\]/u', $format, $m)) {
+ // Currency or Accounting
+ $currencyFormat = $m[0];
+ $currencyCode = $m[1];
+ list($currencyCode) = explode('-', $currencyCode);
+ if ($currencyCode == '') {
+ $currencyCode = PHPExcel_Shared_String::getCurrencyCode();
+ }
+ $value = preg_replace('/\[\$([^\]]*)\]/u', $currencyCode, $value);
+ }
+ }
+ }
+
+ // Escape any escaped slashes to a single slash
+ $format = preg_replace("/\\\\/u", '\\', $format);
+
+ // Additional formatting provided by callback function
+ if ($callBack !== null) {
+ list($writerInstance, $function) = $callBack;
+ $value = $writerInstance->$function($value, $formatColor);
+ }
+
+ return $value;
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Protection.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Protection.php
new file mode 100755
index 000000000..d5568f655
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Protection.php
@@ -0,0 +1,204 @@
+locked = self::PROTECTION_INHERIT;
+ $this->hidden = self::PROTECTION_INHERIT;
+ }
+ }
+
+ /**
+ * Get the shared style component for the currently active cell in currently active sheet.
+ * Only used for style supervisor
+ *
+ * @return PHPExcel_Style_Protection
+ */
+ public function getSharedComponent()
+ {
+ return $this->parent->getSharedComponent()->getProtection();
+ }
+
+ /**
+ * Build style array from subcomponents
+ *
+ * @param array $array
+ * @return array
+ */
+ public function getStyleArray($array)
+ {
+ return array('protection' => $array);
+ }
+
+ /**
+ * Apply styles from array
+ *
+ *
+ * $objPHPExcel->getActiveSheet()->getStyle('B2')->getLocked()->applyFromArray(
+ * array(
+ * 'locked' => TRUE,
+ * 'hidden' => FALSE
+ * )
+ * );
+ *
+ *
+ * @param array $pStyles Array containing style information
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Style_Protection
+ */
+ public function applyFromArray($pStyles = null)
+ {
+ if (is_array($pStyles)) {
+ if ($this->isSupervisor) {
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
+ } else {
+ if (isset($pStyles['locked'])) {
+ $this->setLocked($pStyles['locked']);
+ }
+ if (isset($pStyles['hidden'])) {
+ $this->setHidden($pStyles['hidden']);
+ }
+ }
+ } else {
+ throw new PHPExcel_Exception("Invalid style array passed.");
+ }
+ return $this;
+ }
+
+ /**
+ * Get locked
+ *
+ * @return string
+ */
+ public function getLocked()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getLocked();
+ }
+ return $this->locked;
+ }
+
+ /**
+ * Set locked
+ *
+ * @param string $pValue
+ * @return PHPExcel_Style_Protection
+ */
+ public function setLocked($pValue = self::PROTECTION_INHERIT)
+ {
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('locked' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->locked = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get hidden
+ *
+ * @return string
+ */
+ public function getHidden()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getHidden();
+ }
+ return $this->hidden;
+ }
+
+ /**
+ * Set hidden
+ *
+ * @param string $pValue
+ * @return PHPExcel_Style_Protection
+ */
+ public function setHidden($pValue = self::PROTECTION_INHERIT)
+ {
+ if ($this->isSupervisor) {
+ $styleArray = $this->getStyleArray(array('hidden' => $pValue));
+ $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+ } else {
+ $this->hidden = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get hash code
+ *
+ * @return string Hash code
+ */
+ public function getHashCode()
+ {
+ if ($this->isSupervisor) {
+ return $this->getSharedComponent()->getHashCode();
+ }
+ return md5(
+ $this->locked .
+ $this->hidden .
+ __CLASS__
+ );
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Supervisor.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Supervisor.php
new file mode 100755
index 000000000..a90e1c6a9
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Supervisor.php
@@ -0,0 +1,125 @@
+isSupervisor = $isSupervisor;
+ }
+
+ /**
+ * Bind parent. Only used for supervisor
+ *
+ * @param PHPExcel $parent
+ * @return PHPExcel_Style_Supervisor
+ */
+ public function bindParent($parent, $parentPropertyName = null)
+ {
+ $this->parent = $parent;
+ return $this;
+ }
+
+ /**
+ * Is this a supervisor or a cell style component?
+ *
+ * @return boolean
+ */
+ public function getIsSupervisor()
+ {
+ return $this->isSupervisor;
+ }
+
+ /**
+ * Get the currently active sheet. Only used for supervisor
+ *
+ * @return PHPExcel_Worksheet
+ */
+ public function getActiveSheet()
+ {
+ return $this->parent->getActiveSheet();
+ }
+
+ /**
+ * Get the currently active cell coordinate in currently active sheet.
+ * Only used for supervisor
+ *
+ * @return string E.g. 'A1'
+ */
+ public function getSelectedCells()
+ {
+ return $this->getActiveSheet()->getSelectedCells();
+ }
+
+ /**
+ * Get the currently active cell coordinate in currently active sheet.
+ * Only used for supervisor
+ *
+ * @return string E.g. 'A1'
+ */
+ public function getActiveCell()
+ {
+ return $this->getActiveSheet()->getActiveCell();
+ }
+
+ /**
+ * 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)) && ($key != 'parent')) {
+ $this->$key = clone $value;
+ } else {
+ $this->$key = $value;
+ }
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet.php
new file mode 100755
index 000000000..483aa0021
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet.php
@@ -0,0 +1,2968 @@
+parent = $pParent;
+ $this->setTitle($pTitle, false);
+ // setTitle can change $pTitle
+ $this->setCodeName($this->getTitle());
+ $this->setSheetState(PHPExcel_Worksheet::SHEETSTATE_VISIBLE);
+
+ $this->cellCollection = PHPExcel_CachedObjectStorageFactory::getInstance($this);
+ // Set page setup
+ $this->pageSetup = new PHPExcel_Worksheet_PageSetup();
+ // Set page margins
+ $this->pageMargins = new PHPExcel_Worksheet_PageMargins();
+ // Set page header/footer
+ $this->headerFooter = new PHPExcel_Worksheet_HeaderFooter();
+ // Set sheet view
+ $this->sheetView = new PHPExcel_Worksheet_SheetView();
+ // Drawing collection
+ $this->drawingCollection = new ArrayObject();
+ // Chart collection
+ $this->chartCollection = new ArrayObject();
+ // Protection
+ $this->protection = new PHPExcel_Worksheet_Protection();
+ // Default row dimension
+ $this->defaultRowDimension = new PHPExcel_Worksheet_RowDimension(null);
+ // Default column dimension
+ $this->defaultColumnDimension = new PHPExcel_Worksheet_ColumnDimension(null);
+ $this->autoFilter = new PHPExcel_Worksheet_AutoFilter(null, $this);
+ }
+
+
+ /**
+ * Disconnect all cells from this PHPExcel_Worksheet object,
+ * typically so that the worksheet object can be unset
+ *
+ */
+ public function disconnectCells()
+ {
+ if ($this->cellCollection !== null) {
+ $this->cellCollection->unsetWorksheetCells();
+ $this->cellCollection = null;
+ }
+ // detach ourself from the workbook, so that it can then delete this worksheet successfully
+ $this->parent = null;
+ }
+
+ /**
+ * Code to execute when this worksheet is unset()
+ *
+ */
+ public function __destruct()
+ {
+ PHPExcel_Calculation::getInstance($this->parent)->clearCalculationCacheForWorksheet($this->title);
+
+ $this->disconnectCells();
+ }
+
+ /**
+ * Return the cache controller for the cell collection
+ *
+ * @return PHPExcel_CachedObjectStorage_xxx
+ */
+ public function getCellCacheController()
+ {
+ return $this->cellCollection;
+ }
+
+
+ /**
+ * Get array of invalid characters for sheet title
+ *
+ * @return array
+ */
+ public static function getInvalidCharacters()
+ {
+ return self::$invalidCharacters;
+ }
+
+ /**
+ * Check sheet code name for valid Excel syntax
+ *
+ * @param string $pValue The string to check
+ * @return string The valid string
+ * @throws Exception
+ */
+ private static function checkSheetCodeName($pValue)
+ {
+ $CharCount = PHPExcel_Shared_String::CountCharacters($pValue);
+ if ($CharCount == 0) {
+ throw new PHPExcel_Exception('Sheet code name cannot be empty.');
+ }
+ // Some of the printable ASCII characters are invalid: * : / \ ? [ ] and first and last characters cannot be a "'"
+ if ((str_replace(self::$invalidCharacters, '', $pValue) !== $pValue) ||
+ (PHPExcel_Shared_String::Substring($pValue, -1, 1)=='\'') ||
+ (PHPExcel_Shared_String::Substring($pValue, 0, 1)=='\'')) {
+ throw new PHPExcel_Exception('Invalid character found in sheet code name');
+ }
+
+ // Maximum 31 characters allowed for sheet title
+ if ($CharCount > 31) {
+ throw new PHPExcel_Exception('Maximum 31 characters allowed in sheet code name.');
+ }
+
+ return $pValue;
+ }
+
+ /**
+ * Check sheet title for valid Excel syntax
+ *
+ * @param string $pValue The string to check
+ * @return string The valid string
+ * @throws PHPExcel_Exception
+ */
+ private static function checkSheetTitle($pValue)
+ {
+ // Some of the printable ASCII characters are invalid: * : / \ ? [ ]
+ if (str_replace(self::$invalidCharacters, '', $pValue) !== $pValue) {
+ throw new PHPExcel_Exception('Invalid character found in sheet title');
+ }
+
+ // Maximum 31 characters allowed for sheet title
+ if (PHPExcel_Shared_String::CountCharacters($pValue) > 31) {
+ throw new PHPExcel_Exception('Maximum 31 characters allowed in sheet title.');
+ }
+
+ return $pValue;
+ }
+
+ /**
+ * Get collection of cells
+ *
+ * @param boolean $pSorted Also sort the cell collection?
+ * @return PHPExcel_Cell[]
+ */
+ public function getCellCollection($pSorted = true)
+ {
+ if ($pSorted) {
+ // Re-order cell collection
+ return $this->sortCellCollection();
+ }
+ if ($this->cellCollection !== null) {
+ return $this->cellCollection->getCellList();
+ }
+ return array();
+ }
+
+ /**
+ * Sort collection of cells
+ *
+ * @return PHPExcel_Worksheet
+ */
+ public function sortCellCollection()
+ {
+ if ($this->cellCollection !== null) {
+ return $this->cellCollection->getSortedCellList();
+ }
+ return array();
+ }
+
+ /**
+ * Get collection of row dimensions
+ *
+ * @return PHPExcel_Worksheet_RowDimension[]
+ */
+ public function getRowDimensions()
+ {
+ return $this->rowDimensions;
+ }
+
+ /**
+ * Get default row dimension
+ *
+ * @return PHPExcel_Worksheet_RowDimension
+ */
+ public function getDefaultRowDimension()
+ {
+ return $this->defaultRowDimension;
+ }
+
+ /**
+ * Get collection of column dimensions
+ *
+ * @return PHPExcel_Worksheet_ColumnDimension[]
+ */
+ public function getColumnDimensions()
+ {
+ return $this->columnDimensions;
+ }
+
+ /**
+ * Get default column dimension
+ *
+ * @return PHPExcel_Worksheet_ColumnDimension
+ */
+ public function getDefaultColumnDimension()
+ {
+ return $this->defaultColumnDimension;
+ }
+
+ /**
+ * Get collection of drawings
+ *
+ * @return PHPExcel_Worksheet_BaseDrawing[]
+ */
+ public function getDrawingCollection()
+ {
+ return $this->drawingCollection;
+ }
+
+ /**
+ * Get collection of charts
+ *
+ * @return PHPExcel_Chart[]
+ */
+ public function getChartCollection()
+ {
+ return $this->chartCollection;
+ }
+
+ /**
+ * Add chart
+ *
+ * @param PHPExcel_Chart $pChart
+ * @param int|null $iChartIndex Index where chart should go (0,1,..., or null for last)
+ * @return PHPExcel_Chart
+ */
+ public function addChart(PHPExcel_Chart $pChart = null, $iChartIndex = null)
+ {
+ $pChart->setWorksheet($this);
+ if (is_null($iChartIndex)) {
+ $this->chartCollection[] = $pChart;
+ } else {
+ // Insert the chart at the requested index
+ array_splice($this->chartCollection, $iChartIndex, 0, array($pChart));
+ }
+
+ return $pChart;
+ }
+
+ /**
+ * Return the count of charts on this worksheet
+ *
+ * @return int The number of charts
+ */
+ public function getChartCount()
+ {
+ return count($this->chartCollection);
+ }
+
+ /**
+ * Get a chart by its index position
+ *
+ * @param string $index Chart index position
+ * @return false|PHPExcel_Chart
+ * @throws PHPExcel_Exception
+ */
+ public function getChartByIndex($index = null)
+ {
+ $chartCount = count($this->chartCollection);
+ if ($chartCount == 0) {
+ return false;
+ }
+ if (is_null($index)) {
+ $index = --$chartCount;
+ }
+ if (!isset($this->chartCollection[$index])) {
+ return false;
+ }
+
+ return $this->chartCollection[$index];
+ }
+
+ /**
+ * Return an array of the names of charts on this worksheet
+ *
+ * @return string[] The names of charts
+ * @throws PHPExcel_Exception
+ */
+ public function getChartNames()
+ {
+ $chartNames = array();
+ foreach ($this->chartCollection as $chart) {
+ $chartNames[] = $chart->getName();
+ }
+ return $chartNames;
+ }
+
+ /**
+ * Get a chart by name
+ *
+ * @param string $chartName Chart name
+ * @return false|PHPExcel_Chart
+ * @throws PHPExcel_Exception
+ */
+ public function getChartByName($chartName = '')
+ {
+ $chartCount = count($this->chartCollection);
+ if ($chartCount == 0) {
+ return false;
+ }
+ foreach ($this->chartCollection as $index => $chart) {
+ if ($chart->getName() == $chartName) {
+ return $this->chartCollection[$index];
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Refresh column dimensions
+ *
+ * @return PHPExcel_Worksheet
+ */
+ public function refreshColumnDimensions()
+ {
+ $currentColumnDimensions = $this->getColumnDimensions();
+ $newColumnDimensions = array();
+
+ foreach ($currentColumnDimensions as $objColumnDimension) {
+ $newColumnDimensions[$objColumnDimension->getColumnIndex()] = $objColumnDimension;
+ }
+
+ $this->columnDimensions = $newColumnDimensions;
+
+ return $this;
+ }
+
+ /**
+ * Refresh row dimensions
+ *
+ * @return PHPExcel_Worksheet
+ */
+ public function refreshRowDimensions()
+ {
+ $currentRowDimensions = $this->getRowDimensions();
+ $newRowDimensions = array();
+
+ foreach ($currentRowDimensions as $objRowDimension) {
+ $newRowDimensions[$objRowDimension->getRowIndex()] = $objRowDimension;
+ }
+
+ $this->rowDimensions = $newRowDimensions;
+
+ return $this;
+ }
+
+ /**
+ * Calculate worksheet dimension
+ *
+ * @return string String containing the dimension of this worksheet
+ */
+ public function calculateWorksheetDimension()
+ {
+ // Return
+ return 'A1' . ':' . $this->getHighestColumn() . $this->getHighestRow();
+ }
+
+ /**
+ * Calculate worksheet data dimension
+ *
+ * @return string String containing the dimension of this worksheet that actually contain data
+ */
+ public function calculateWorksheetDataDimension()
+ {
+ // Return
+ return 'A1' . ':' . $this->getHighestDataColumn() . $this->getHighestDataRow();
+ }
+
+ /**
+ * Calculate widths for auto-size columns
+ *
+ * @param boolean $calculateMergeCells Calculate merge cell width
+ * @return PHPExcel_Worksheet;
+ */
+ public function calculateColumnWidths($calculateMergeCells = false)
+ {
+ // initialize $autoSizes array
+ $autoSizes = array();
+ foreach ($this->getColumnDimensions() as $colDimension) {
+ if ($colDimension->getAutoSize()) {
+ $autoSizes[$colDimension->getColumnIndex()] = -1;
+ }
+ }
+
+ // There is only something to do if there are some auto-size columns
+ if (!empty($autoSizes)) {
+ // build list of cells references that participate in a merge
+ $isMergeCell = array();
+ foreach ($this->getMergeCells() as $cells) {
+ foreach (PHPExcel_Cell::extractAllCellReferencesInRange($cells) as $cellReference) {
+ $isMergeCell[$cellReference] = true;
+ }
+ }
+
+ // loop through all cells in the worksheet
+ foreach ($this->getCellCollection(false) as $cellID) {
+ $cell = $this->getCell($cellID, false);
+ if ($cell !== null && isset($autoSizes[$this->cellCollection->getCurrentColumn()])) {
+ // Determine width if cell does not participate in a merge
+ if (!isset($isMergeCell[$this->cellCollection->getCurrentAddress()])) {
+ // Calculated value
+ // To formatted string
+ $cellValue = PHPExcel_Style_NumberFormat::toFormattedString(
+ $cell->getCalculatedValue(),
+ $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode()
+ );
+
+ $autoSizes[$this->cellCollection->getCurrentColumn()] = max(
+ (float) $autoSizes[$this->cellCollection->getCurrentColumn()],
+ (float)PHPExcel_Shared_Font::calculateColumnWidth(
+ $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont(),
+ $cellValue,
+ $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getAlignment()->getTextRotation(),
+ $this->getDefaultStyle()->getFont()
+ )
+ );
+ }
+ }
+ }
+
+ // adjust column widths
+ foreach ($autoSizes as $columnIndex => $width) {
+ if ($width == -1) {
+ $width = $this->getDefaultColumnDimension()->getWidth();
+ }
+ $this->getColumnDimension($columnIndex)->setWidth($width);
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get parent
+ *
+ * @return PHPExcel
+ */
+ public function getParent()
+ {
+ return $this->parent;
+ }
+
+ /**
+ * Re-bind parent
+ *
+ * @param PHPExcel $parent
+ * @return PHPExcel_Worksheet
+ */
+ public function rebindParent(PHPExcel $parent)
+ {
+ if ($this->parent !== null) {
+ $namedRanges = $this->parent->getNamedRanges();
+ foreach ($namedRanges as $namedRange) {
+ $parent->addNamedRange($namedRange);
+ }
+
+ $this->parent->removeSheetByIndex(
+ $this->parent->getIndex($this)
+ );
+ }
+ $this->parent = $parent;
+
+ return $this;
+ }
+
+ /**
+ * Get title
+ *
+ * @return string
+ */
+ public function getTitle()
+ {
+ return $this->title;
+ }
+
+ /**
+ * Set title
+ *
+ * @param string $pValue String containing the dimension of this worksheet
+ * @param string $updateFormulaCellReferences boolean Flag indicating whether cell references in formulae should
+ * be updated to reflect the new sheet name.
+ * This should be left as the default true, unless you are
+ * certain that no formula cells on any worksheet contain
+ * references to this worksheet
+ * @return PHPExcel_Worksheet
+ */
+ public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = true)
+ {
+ // Is this a 'rename' or not?
+ if ($this->getTitle() == $pValue) {
+ return $this;
+ }
+
+ // Syntax check
+ self::checkSheetTitle($pValue);
+
+ // Old title
+ $oldTitle = $this->getTitle();
+
+ if ($this->parent) {
+ // Is there already such sheet name?
+ if ($this->parent->sheetNameExists($pValue)) {
+ // Use name, but append with lowest possible integer
+
+ if (PHPExcel_Shared_String::CountCharacters($pValue) > 29) {
+ $pValue = PHPExcel_Shared_String::Substring($pValue, 0, 29);
+ }
+ $i = 1;
+ while ($this->parent->sheetNameExists($pValue . ' ' . $i)) {
+ ++$i;
+ if ($i == 10) {
+ if (PHPExcel_Shared_String::CountCharacters($pValue) > 28) {
+ $pValue = PHPExcel_Shared_String::Substring($pValue, 0, 28);
+ }
+ } elseif ($i == 100) {
+ if (PHPExcel_Shared_String::CountCharacters($pValue) > 27) {
+ $pValue = PHPExcel_Shared_String::Substring($pValue, 0, 27);
+ }
+ }
+ }
+
+ $altTitle = $pValue . ' ' . $i;
+ return $this->setTitle($altTitle, $updateFormulaCellReferences);
+ }
+ }
+
+ // Set title
+ $this->title = $pValue;
+ $this->dirty = true;
+
+ if ($this->parent && $this->parent->getCalculationEngine()) {
+ // New title
+ $newTitle = $this->getTitle();
+ $this->parent->getCalculationEngine()
+ ->renameCalculationCacheForWorksheet($oldTitle, $newTitle);
+ if ($updateFormulaCellReferences) {
+ PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->parent, $oldTitle, $newTitle);
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get sheet state
+ *
+ * @return string Sheet state (visible, hidden, veryHidden)
+ */
+ public function getSheetState()
+ {
+ return $this->sheetState;
+ }
+
+ /**
+ * Set sheet state
+ *
+ * @param string $value Sheet state (visible, hidden, veryHidden)
+ * @return PHPExcel_Worksheet
+ */
+ public function setSheetState($value = PHPExcel_Worksheet::SHEETSTATE_VISIBLE)
+ {
+ $this->sheetState = $value;
+ return $this;
+ }
+
+ /**
+ * Get page setup
+ *
+ * @return PHPExcel_Worksheet_PageSetup
+ */
+ public function getPageSetup()
+ {
+ return $this->pageSetup;
+ }
+
+ /**
+ * Set page setup
+ *
+ * @param PHPExcel_Worksheet_PageSetup $pValue
+ * @return PHPExcel_Worksheet
+ */
+ public function setPageSetup(PHPExcel_Worksheet_PageSetup $pValue)
+ {
+ $this->pageSetup = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get page margins
+ *
+ * @return PHPExcel_Worksheet_PageMargins
+ */
+ public function getPageMargins()
+ {
+ return $this->pageMargins;
+ }
+
+ /**
+ * Set page margins
+ *
+ * @param PHPExcel_Worksheet_PageMargins $pValue
+ * @return PHPExcel_Worksheet
+ */
+ public function setPageMargins(PHPExcel_Worksheet_PageMargins $pValue)
+ {
+ $this->pageMargins = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get page header/footer
+ *
+ * @return PHPExcel_Worksheet_HeaderFooter
+ */
+ public function getHeaderFooter()
+ {
+ return $this->headerFooter;
+ }
+
+ /**
+ * Set page header/footer
+ *
+ * @param PHPExcel_Worksheet_HeaderFooter $pValue
+ * @return PHPExcel_Worksheet
+ */
+ public function setHeaderFooter(PHPExcel_Worksheet_HeaderFooter $pValue)
+ {
+ $this->headerFooter = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get sheet view
+ *
+ * @return PHPExcel_Worksheet_SheetView
+ */
+ public function getSheetView()
+ {
+ return $this->sheetView;
+ }
+
+ /**
+ * Set sheet view
+ *
+ * @param PHPExcel_Worksheet_SheetView $pValue
+ * @return PHPExcel_Worksheet
+ */
+ public function setSheetView(PHPExcel_Worksheet_SheetView $pValue)
+ {
+ $this->sheetView = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Protection
+ *
+ * @return PHPExcel_Worksheet_Protection
+ */
+ public function getProtection()
+ {
+ return $this->protection;
+ }
+
+ /**
+ * Set Protection
+ *
+ * @param PHPExcel_Worksheet_Protection $pValue
+ * @return PHPExcel_Worksheet
+ */
+ public function setProtection(PHPExcel_Worksheet_Protection $pValue)
+ {
+ $this->protection = $pValue;
+ $this->dirty = true;
+
+ return $this;
+ }
+
+ /**
+ * Get highest worksheet column
+ *
+ * @param string $row Return the data highest column for the specified row,
+ * or the highest column of any row if no row number is passed
+ * @return string Highest column name
+ */
+ public function getHighestColumn($row = null)
+ {
+ if ($row == null) {
+ return $this->cachedHighestColumn;
+ }
+ return $this->getHighestDataColumn($row);
+ }
+
+ /**
+ * Get highest worksheet column that contains data
+ *
+ * @param string $row Return the highest data column for the specified row,
+ * or the highest data column of any row if no row number is passed
+ * @return string Highest column name that contains data
+ */
+ public function getHighestDataColumn($row = null)
+ {
+ return $this->cellCollection->getHighestColumn($row);
+ }
+
+ /**
+ * Get highest worksheet row
+ *
+ * @param string $column Return the highest data row for the specified column,
+ * or the highest row of any column if no column letter is passed
+ * @return int Highest row number
+ */
+ public function getHighestRow($column = null)
+ {
+ if ($column == null) {
+ return $this->cachedHighestRow;
+ }
+ return $this->getHighestDataRow($column);
+ }
+
+ /**
+ * Get highest worksheet row that contains data
+ *
+ * @param string $column Return the highest data row for the specified column,
+ * or the highest data row of any column if no column letter is passed
+ * @return string Highest row number that contains data
+ */
+ public function getHighestDataRow($column = null)
+ {
+ return $this->cellCollection->getHighestRow($column);
+ }
+
+ /**
+ * Get highest worksheet column and highest row that have cell records
+ *
+ * @return array Highest column name and highest row number
+ */
+ public function getHighestRowAndColumn()
+ {
+ return $this->cellCollection->getHighestRowAndColumn();
+ }
+
+ /**
+ * Set a cell value
+ *
+ * @param string $pCoordinate Coordinate of the cell
+ * @param mixed $pValue Value of the cell
+ * @param bool $returnCell Return the worksheet (false, default) or the cell (true)
+ * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified
+ */
+ public function setCellValue($pCoordinate = 'A1', $pValue = null, $returnCell = false)
+ {
+ $cell = $this->getCell(strtoupper($pCoordinate))->setValue($pValue);
+ return ($returnCell) ? $cell : $this;
+ }
+
+ /**
+ * Set a cell value by using numeric cell coordinates
+ *
+ * @param string $pColumn Numeric column coordinate of the cell (A = 0)
+ * @param string $pRow Numeric row coordinate of the cell
+ * @param mixed $pValue Value of the cell
+ * @param bool $returnCell Return the worksheet (false, default) or the cell (true)
+ * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified
+ */
+ public function setCellValueByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $returnCell = false)
+ {
+ $cell = $this->getCellByColumnAndRow($pColumn, $pRow)->setValue($pValue);
+ return ($returnCell) ? $cell : $this;
+ }
+
+ /**
+ * Set a cell value
+ *
+ * @param string $pCoordinate Coordinate of the cell
+ * @param mixed $pValue Value of the cell
+ * @param string $pDataType Explicit data type
+ * @param bool $returnCell Return the worksheet (false, default) or the cell (true)
+ * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified
+ */
+ public function setCellValueExplicit($pCoordinate = 'A1', $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING, $returnCell = false)
+ {
+ // Set value
+ $cell = $this->getCell(strtoupper($pCoordinate))->setValueExplicit($pValue, $pDataType);
+ return ($returnCell) ? $cell : $this;
+ }
+
+ /**
+ * Set a cell value by using numeric cell coordinates
+ *
+ * @param string $pColumn Numeric column coordinate of the cell
+ * @param string $pRow Numeric row coordinate of the cell
+ * @param mixed $pValue Value of the cell
+ * @param string $pDataType Explicit data type
+ * @param bool $returnCell Return the worksheet (false, default) or the cell (true)
+ * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified
+ */
+ public function setCellValueExplicitByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING, $returnCell = false)
+ {
+ $cell = $this->getCellByColumnAndRow($pColumn, $pRow)->setValueExplicit($pValue, $pDataType);
+ return ($returnCell) ? $cell : $this;
+ }
+
+ /**
+ * Get cell at a specific coordinate
+ *
+ * @param string $pCoordinate Coordinate of the cell
+ * @param boolean $createIfNotExists Flag indicating whether a new cell should be created if it doesn't
+ * already exist, or a null should be returned instead
+ * @throws PHPExcel_Exception
+ * @return null|PHPExcel_Cell Cell that was found/created or null
+ */
+ public function getCell($pCoordinate = 'A1', $createIfNotExists = true)
+ {
+ // Check cell collection
+ if ($this->cellCollection->isDataSet(strtoupper($pCoordinate))) {
+ return $this->cellCollection->getCacheData($pCoordinate);
+ }
+
+ // Worksheet reference?
+ if (strpos($pCoordinate, '!') !== false) {
+ $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true);
+ return $this->parent->getSheetByName($worksheetReference[0])->getCell(strtoupper($worksheetReference[1]), $createIfNotExists);
+ }
+
+ // Named range?
+ if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $pCoordinate, $matches)) &&
+ (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $pCoordinate, $matches))) {
+ $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this);
+ if ($namedRange !== null) {
+ $pCoordinate = $namedRange->getRange();
+ return $namedRange->getWorksheet()->getCell($pCoordinate, $createIfNotExists);
+ }
+ }
+
+ // Uppercase coordinate
+ $pCoordinate = strtoupper($pCoordinate);
+
+ if (strpos($pCoordinate, ':') !== false || strpos($pCoordinate, ',') !== false) {
+ throw new PHPExcel_Exception('Cell coordinate can not be a range of cells.');
+ } elseif (strpos($pCoordinate, '$') !== false) {
+ throw new PHPExcel_Exception('Cell coordinate must not be absolute.');
+ }
+
+ // Create new cell object, if required
+ return $createIfNotExists ? $this->createNewCell($pCoordinate) : null;
+ }
+
+ /**
+ * Get cell at a specific coordinate by using numeric cell coordinates
+ *
+ * @param string $pColumn Numeric column coordinate of the cell (starting from 0)
+ * @param string $pRow Numeric row coordinate of the cell
+ * @param boolean $createIfNotExists Flag indicating whether a new cell should be created if it doesn't
+ * already exist, or a null should be returned instead
+ * @return null|PHPExcel_Cell Cell that was found/created or null
+ */
+ public function getCellByColumnAndRow($pColumn = 0, $pRow = 1, $createIfNotExists = true)
+ {
+ $columnLetter = PHPExcel_Cell::stringFromColumnIndex($pColumn);
+ $coordinate = $columnLetter . $pRow;
+
+ if ($this->cellCollection->isDataSet($coordinate)) {
+ return $this->cellCollection->getCacheData($coordinate);
+ }
+
+ // Create new cell object, if required
+ return $createIfNotExists ? $this->createNewCell($coordinate) : null;
+ }
+
+ /**
+ * Create a new cell at the specified coordinate
+ *
+ * @param string $pCoordinate Coordinate of the cell
+ * @return PHPExcel_Cell Cell that was created
+ */
+ private function createNewCell($pCoordinate)
+ {
+ $cell = $this->cellCollection->addCacheData(
+ $pCoordinate,
+ new PHPExcel_Cell(null, PHPExcel_Cell_DataType::TYPE_NULL, $this)
+ );
+ $this->cellCollectionIsSorted = false;
+
+ // Coordinates
+ $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate);
+ if (PHPExcel_Cell::columnIndexFromString($this->cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($aCoordinates[0])) {
+ $this->cachedHighestColumn = $aCoordinates[0];
+ }
+ $this->cachedHighestRow = max($this->cachedHighestRow, $aCoordinates[1]);
+
+ // Cell needs appropriate xfIndex from dimensions records
+ // but don't create dimension records if they don't already exist
+ $rowDimension = $this->getRowDimension($aCoordinates[1], false);
+ $columnDimension = $this->getColumnDimension($aCoordinates[0], false);
+
+ if ($rowDimension !== null && $rowDimension->getXfIndex() > 0) {
+ // then there is a row dimension with explicit style, assign it to the cell
+ $cell->setXfIndex($rowDimension->getXfIndex());
+ } elseif ($columnDimension !== null && $columnDimension->getXfIndex() > 0) {
+ // then there is a column dimension, assign it to the cell
+ $cell->setXfIndex($columnDimension->getXfIndex());
+ }
+
+ return $cell;
+ }
+
+ /**
+ * Does the cell at a specific coordinate exist?
+ *
+ * @param string $pCoordinate Coordinate of the cell
+ * @throws PHPExcel_Exception
+ * @return boolean
+ */
+ public function cellExists($pCoordinate = 'A1')
+ {
+ // Worksheet reference?
+ if (strpos($pCoordinate, '!') !== false) {
+ $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true);
+ return $this->parent->getSheetByName($worksheetReference[0])->cellExists(strtoupper($worksheetReference[1]));
+ }
+
+ // Named range?
+ if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $pCoordinate, $matches)) &&
+ (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $pCoordinate, $matches))) {
+ $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this);
+ if ($namedRange !== null) {
+ $pCoordinate = $namedRange->getRange();
+ if ($this->getHashCode() != $namedRange->getWorksheet()->getHashCode()) {
+ if (!$namedRange->getLocalOnly()) {
+ return $namedRange->getWorksheet()->cellExists($pCoordinate);
+ } else {
+ throw new PHPExcel_Exception('Named range ' . $namedRange->getName() . ' is not accessible from within sheet ' . $this->getTitle());
+ }
+ }
+ } else {
+ return false;
+ }
+ }
+
+ // Uppercase coordinate
+ $pCoordinate = strtoupper($pCoordinate);
+
+ if (strpos($pCoordinate, ':') !== false || strpos($pCoordinate, ',') !== false) {
+ throw new PHPExcel_Exception('Cell coordinate can not be a range of cells.');
+ } elseif (strpos($pCoordinate, '$') !== false) {
+ throw new PHPExcel_Exception('Cell coordinate must not be absolute.');
+ } else {
+ // Coordinates
+ $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate);
+
+ // Cell exists?
+ return $this->cellCollection->isDataSet($pCoordinate);
+ }
+ }
+
+ /**
+ * Cell at a specific coordinate by using numeric cell coordinates exists?
+ *
+ * @param string $pColumn Numeric column coordinate of the cell
+ * @param string $pRow Numeric row coordinate of the cell
+ * @return boolean
+ */
+ public function cellExistsByColumnAndRow($pColumn = 0, $pRow = 1)
+ {
+ return $this->cellExists(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);
+ }
+
+ /**
+ * Get row dimension at a specific row
+ *
+ * @param int $pRow Numeric index of the row
+ * @return PHPExcel_Worksheet_RowDimension
+ */
+ public function getRowDimension($pRow = 1, $create = true)
+ {
+ // Found
+ $found = null;
+
+ // Get row dimension
+ if (!isset($this->rowDimensions[$pRow])) {
+ if (!$create) {
+ return null;
+ }
+ $this->rowDimensions[$pRow] = new PHPExcel_Worksheet_RowDimension($pRow);
+
+ $this->cachedHighestRow = max($this->cachedHighestRow, $pRow);
+ }
+ return $this->rowDimensions[$pRow];
+ }
+
+ /**
+ * Get column dimension at a specific column
+ *
+ * @param string $pColumn String index of the column
+ * @return PHPExcel_Worksheet_ColumnDimension
+ */
+ public function getColumnDimension($pColumn = 'A', $create = true)
+ {
+ // Uppercase coordinate
+ $pColumn = strtoupper($pColumn);
+
+ // Fetch dimensions
+ if (!isset($this->columnDimensions[$pColumn])) {
+ if (!$create) {
+ return null;
+ }
+ $this->columnDimensions[$pColumn] = new PHPExcel_Worksheet_ColumnDimension($pColumn);
+
+ if (PHPExcel_Cell::columnIndexFromString($this->cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($pColumn)) {
+ $this->cachedHighestColumn = $pColumn;
+ }
+ }
+ return $this->columnDimensions[$pColumn];
+ }
+
+ /**
+ * Get column dimension at a specific column by using numeric cell coordinates
+ *
+ * @param string $pColumn Numeric column coordinate of the cell
+ * @return PHPExcel_Worksheet_ColumnDimension
+ */
+ public function getColumnDimensionByColumn($pColumn = 0)
+ {
+ return $this->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($pColumn));
+ }
+
+ /**
+ * Get styles
+ *
+ * @return PHPExcel_Style[]
+ */
+ public function getStyles()
+ {
+ return $this->styles;
+ }
+
+ /**
+ * Get default style of workbook.
+ *
+ * @deprecated
+ * @return PHPExcel_Style
+ * @throws PHPExcel_Exception
+ */
+ public function getDefaultStyle()
+ {
+ return $this->parent->getDefaultStyle();
+ }
+
+ /**
+ * Set default style - should only be used by PHPExcel_IReader implementations!
+ *
+ * @deprecated
+ * @param PHPExcel_Style $pValue
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function setDefaultStyle(PHPExcel_Style $pValue)
+ {
+ $this->parent->getDefaultStyle()->applyFromArray(array(
+ 'font' => array(
+ 'name' => $pValue->getFont()->getName(),
+ 'size' => $pValue->getFont()->getSize(),
+ ),
+ ));
+ return $this;
+ }
+
+ /**
+ * Get style for cell
+ *
+ * @param string $pCellCoordinate Cell coordinate (or range) to get style for
+ * @return PHPExcel_Style
+ * @throws PHPExcel_Exception
+ */
+ public function getStyle($pCellCoordinate = 'A1')
+ {
+ // set this sheet as active
+ $this->parent->setActiveSheetIndex($this->parent->getIndex($this));
+
+ // set cell coordinate as active
+ $this->setSelectedCells(strtoupper($pCellCoordinate));
+
+ return $this->parent->getCellXfSupervisor();
+ }
+
+ /**
+ * Get conditional styles for a cell
+ *
+ * @param string $pCoordinate
+ * @return PHPExcel_Style_Conditional[]
+ */
+ public function getConditionalStyles($pCoordinate = 'A1')
+ {
+ $pCoordinate = strtoupper($pCoordinate);
+ if (!isset($this->conditionalStylesCollection[$pCoordinate])) {
+ $this->conditionalStylesCollection[$pCoordinate] = array();
+ }
+ return $this->conditionalStylesCollection[$pCoordinate];
+ }
+
+ /**
+ * Do conditional styles exist for this cell?
+ *
+ * @param string $pCoordinate
+ * @return boolean
+ */
+ public function conditionalStylesExists($pCoordinate = 'A1')
+ {
+ if (isset($this->conditionalStylesCollection[strtoupper($pCoordinate)])) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Removes conditional styles for a cell
+ *
+ * @param string $pCoordinate
+ * @return PHPExcel_Worksheet
+ */
+ public function removeConditionalStyles($pCoordinate = 'A1')
+ {
+ unset($this->conditionalStylesCollection[strtoupper($pCoordinate)]);
+ return $this;
+ }
+
+ /**
+ * Get collection of conditional styles
+ *
+ * @return array
+ */
+ public function getConditionalStylesCollection()
+ {
+ return $this->conditionalStylesCollection;
+ }
+
+ /**
+ * Set conditional styles
+ *
+ * @param $pCoordinate string E.g. 'A1'
+ * @param $pValue PHPExcel_Style_Conditional[]
+ * @return PHPExcel_Worksheet
+ */
+ public function setConditionalStyles($pCoordinate = 'A1', $pValue)
+ {
+ $this->conditionalStylesCollection[strtoupper($pCoordinate)] = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get style for cell by using numeric cell coordinates
+ *
+ * @param int $pColumn Numeric column coordinate of the cell
+ * @param int $pRow Numeric row coordinate of the cell
+ * @param int pColumn2 Numeric column coordinate of the range cell
+ * @param int pRow2 Numeric row coordinate of the range cell
+ * @return PHPExcel_Style
+ */
+ public function getStyleByColumnAndRow($pColumn = 0, $pRow = 1, $pColumn2 = null, $pRow2 = null)
+ {
+ if (!is_null($pColumn2) && !is_null($pRow2)) {
+ $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2;
+ return $this->getStyle($cellRange);
+ }
+
+ return $this->getStyle(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);
+ }
+
+ /**
+ * Set shared cell style to a range of cells
+ *
+ * Please note that this will overwrite existing cell styles for cells in range!
+ *
+ * @deprecated
+ * @param PHPExcel_Style $pSharedCellStyle Cell style to share
+ * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function setSharedStyle(PHPExcel_Style $pSharedCellStyle = null, $pRange = '')
+ {
+ $this->duplicateStyle($pSharedCellStyle, $pRange);
+ return $this;
+ }
+
+ /**
+ * Duplicate cell style to a range of cells
+ *
+ * Please note that this will overwrite existing cell styles for cells in range!
+ *
+ * @param PHPExcel_Style $pCellStyle Cell style to duplicate
+ * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function duplicateStyle(PHPExcel_Style $pCellStyle = null, $pRange = '')
+ {
+ // make sure we have a real style and not supervisor
+ $style = $pCellStyle->getIsSupervisor() ? $pCellStyle->getSharedComponent() : $pCellStyle;
+
+ // Add the style to the workbook if necessary
+ $workbook = $this->parent;
+ if ($existingStyle = $this->parent->getCellXfByHashCode($pCellStyle->getHashCode())) {
+ // there is already such cell Xf in our collection
+ $xfIndex = $existingStyle->getIndex();
+ } else {
+ // we don't have such a cell Xf, need to add
+ $workbook->addCellXf($pCellStyle);
+ $xfIndex = $pCellStyle->getIndex();
+ }
+
+ // Calculate range outer borders
+ list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange . ':' . $pRange);
+
+ // Make sure we can loop upwards on rows and columns
+ if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) {
+ $tmp = $rangeStart;
+ $rangeStart = $rangeEnd;
+ $rangeEnd = $tmp;
+ }
+
+ // Loop through cells and apply styles
+ for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
+ for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
+ $this->getCell(PHPExcel_Cell::stringFromColumnIndex($col - 1) . $row)->setXfIndex($xfIndex);
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Duplicate conditional style to a range of cells
+ *
+ * Please note that this will overwrite existing cell styles for cells in range!
+ *
+ * @param array of PHPExcel_Style_Conditional $pCellStyle Cell style to duplicate
+ * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function duplicateConditionalStyle(array $pCellStyle = null, $pRange = '')
+ {
+ foreach ($pCellStyle as $cellStyle) {
+ if (!($cellStyle instanceof PHPExcel_Style_Conditional)) {
+ throw new PHPExcel_Exception('Style is not a conditional style');
+ }
+ }
+
+ // Calculate range outer borders
+ list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange . ':' . $pRange);
+
+ // Make sure we can loop upwards on rows and columns
+ if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) {
+ $tmp = $rangeStart;
+ $rangeStart = $rangeEnd;
+ $rangeEnd = $tmp;
+ }
+
+ // Loop through cells and apply styles
+ for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
+ for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
+ $this->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($col - 1) . $row, $pCellStyle);
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Duplicate cell style array to a range of cells
+ *
+ * Please note that this will overwrite existing cell styles for cells in range,
+ * if they are in the styles array. For example, if you decide to set a range of
+ * cells to font bold, only include font bold in the styles array.
+ *
+ * @deprecated
+ * @param array $pStyles Array containing style information
+ * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
+ * @param boolean $pAdvanced Advanced mode for setting borders.
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function duplicateStyleArray($pStyles = null, $pRange = '', $pAdvanced = true)
+ {
+ $this->getStyle($pRange)->applyFromArray($pStyles, $pAdvanced);
+ return $this;
+ }
+
+ /**
+ * Set break on a cell
+ *
+ * @param string $pCell Cell coordinate (e.g. A1)
+ * @param int $pBreak Break type (type of PHPExcel_Worksheet::BREAK_*)
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function setBreak($pCell = 'A1', $pBreak = PHPExcel_Worksheet::BREAK_NONE)
+ {
+ // Uppercase coordinate
+ $pCell = strtoupper($pCell);
+
+ if ($pCell != '') {
+ if ($pBreak == PHPExcel_Worksheet::BREAK_NONE) {
+ if (isset($this->breaks[$pCell])) {
+ unset($this->breaks[$pCell]);
+ }
+ } else {
+ $this->breaks[$pCell] = $pBreak;
+ }
+ } else {
+ throw new PHPExcel_Exception('No cell coordinate specified.');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Set break on a cell by using numeric cell coordinates
+ *
+ * @param integer $pColumn Numeric column coordinate of the cell
+ * @param integer $pRow Numeric row coordinate of the cell
+ * @param integer $pBreak Break type (type of PHPExcel_Worksheet::BREAK_*)
+ * @return PHPExcel_Worksheet
+ */
+ public function setBreakByColumnAndRow($pColumn = 0, $pRow = 1, $pBreak = PHPExcel_Worksheet::BREAK_NONE)
+ {
+ return $this->setBreak(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow, $pBreak);
+ }
+
+ /**
+ * Get breaks
+ *
+ * @return array[]
+ */
+ public function getBreaks()
+ {
+ return $this->breaks;
+ }
+
+ /**
+ * Set merge on a cell range
+ *
+ * @param string $pRange Cell range (e.g. A1:E1)
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function mergeCells($pRange = 'A1:A1')
+ {
+ // Uppercase coordinate
+ $pRange = strtoupper($pRange);
+
+ if (strpos($pRange, ':') !== false) {
+ $this->mergeCells[$pRange] = $pRange;
+
+ // make sure cells are created
+
+ // get the cells in the range
+ $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange);
+
+ // create upper left cell if it does not already exist
+ $upperLeft = $aReferences[0];
+ if (!$this->cellExists($upperLeft)) {
+ $this->getCell($upperLeft)->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL);
+ }
+
+ // Blank out the rest of the cells in the range (if they exist)
+ $count = count($aReferences);
+ for ($i = 1; $i < $count; $i++) {
+ if ($this->cellExists($aReferences[$i])) {
+ $this->getCell($aReferences[$i])->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL);
+ }
+ }
+ } else {
+ throw new PHPExcel_Exception('Merge must be set on a range of cells.');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Set merge on a cell range by using numeric cell coordinates
+ *
+ * @param int $pColumn1 Numeric column coordinate of the first cell
+ * @param int $pRow1 Numeric row coordinate of the first cell
+ * @param int $pColumn2 Numeric column coordinate of the last cell
+ * @param int $pRow2 Numeric row coordinate of the last cell
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function mergeCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1)
+ {
+ $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2;
+ return $this->mergeCells($cellRange);
+ }
+
+ /**
+ * Remove merge on a cell range
+ *
+ * @param string $pRange Cell range (e.g. A1:E1)
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function unmergeCells($pRange = 'A1:A1')
+ {
+ // Uppercase coordinate
+ $pRange = strtoupper($pRange);
+
+ if (strpos($pRange, ':') !== false) {
+ if (isset($this->mergeCells[$pRange])) {
+ unset($this->mergeCells[$pRange]);
+ } else {
+ throw new PHPExcel_Exception('Cell range ' . $pRange . ' not known as merged.');
+ }
+ } else {
+ throw new PHPExcel_Exception('Merge can only be removed from a range of cells.');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Remove merge on a cell range by using numeric cell coordinates
+ *
+ * @param int $pColumn1 Numeric column coordinate of the first cell
+ * @param int $pRow1 Numeric row coordinate of the first cell
+ * @param int $pColumn2 Numeric column coordinate of the last cell
+ * @param int $pRow2 Numeric row coordinate of the last cell
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function unmergeCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1)
+ {
+ $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2;
+ return $this->unmergeCells($cellRange);
+ }
+
+ /**
+ * Get merge cells array.
+ *
+ * @return array[]
+ */
+ public function getMergeCells()
+ {
+ return $this->mergeCells;
+ }
+
+ /**
+ * Set merge cells array for the entire sheet. Use instead mergeCells() to merge
+ * a single cell range.
+ *
+ * @param array
+ */
+ public function setMergeCells($pValue = array())
+ {
+ $this->mergeCells = $pValue;
+ return $this;
+ }
+
+ /**
+ * Set protection on a cell range
+ *
+ * @param string $pRange Cell (e.g. A1) or cell range (e.g. A1:E1)
+ * @param string $pPassword Password to unlock the protection
+ * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function protectCells($pRange = 'A1', $pPassword = '', $pAlreadyHashed = false)
+ {
+ // Uppercase coordinate
+ $pRange = strtoupper($pRange);
+
+ if (!$pAlreadyHashed) {
+ $pPassword = PHPExcel_Shared_PasswordHasher::hashPassword($pPassword);
+ }
+ $this->protectedCells[$pRange] = $pPassword;
+
+ return $this;
+ }
+
+ /**
+ * Set protection on a cell range by using numeric cell coordinates
+ *
+ * @param int $pColumn1 Numeric column coordinate of the first cell
+ * @param int $pRow1 Numeric row coordinate of the first cell
+ * @param int $pColumn2 Numeric column coordinate of the last cell
+ * @param int $pRow2 Numeric row coordinate of the last cell
+ * @param string $pPassword Password to unlock the protection
+ * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function protectCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1, $pPassword = '', $pAlreadyHashed = false)
+ {
+ $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2;
+ return $this->protectCells($cellRange, $pPassword, $pAlreadyHashed);
+ }
+
+ /**
+ * Remove protection on a cell range
+ *
+ * @param string $pRange Cell (e.g. A1) or cell range (e.g. A1:E1)
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function unprotectCells($pRange = 'A1')
+ {
+ // Uppercase coordinate
+ $pRange = strtoupper($pRange);
+
+ if (isset($this->protectedCells[$pRange])) {
+ unset($this->protectedCells[$pRange]);
+ } else {
+ throw new PHPExcel_Exception('Cell range ' . $pRange . ' not known as protected.');
+ }
+ return $this;
+ }
+
+ /**
+ * Remove protection on a cell range by using numeric cell coordinates
+ *
+ * @param int $pColumn1 Numeric column coordinate of the first cell
+ * @param int $pRow1 Numeric row coordinate of the first cell
+ * @param int $pColumn2 Numeric column coordinate of the last cell
+ * @param int $pRow2 Numeric row coordinate of the last cell
+ * @param string $pPassword Password to unlock the protection
+ * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function unprotectCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1, $pPassword = '', $pAlreadyHashed = false)
+ {
+ $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2;
+ return $this->unprotectCells($cellRange, $pPassword, $pAlreadyHashed);
+ }
+
+ /**
+ * Get protected cells
+ *
+ * @return array[]
+ */
+ public function getProtectedCells()
+ {
+ return $this->protectedCells;
+ }
+
+ /**
+ * Get Autofilter
+ *
+ * @return PHPExcel_Worksheet_AutoFilter
+ */
+ public function getAutoFilter()
+ {
+ return $this->autoFilter;
+ }
+
+ /**
+ * Set AutoFilter
+ *
+ * @param PHPExcel_Worksheet_AutoFilter|string $pValue
+ * A simple string containing a Cell range like 'A1:E10' is permitted for backward compatibility
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function setAutoFilter($pValue)
+ {
+ $pRange = strtoupper($pValue);
+ if (is_string($pValue)) {
+ $this->autoFilter->setRange($pValue);
+ } elseif (is_object($pValue) && ($pValue instanceof PHPExcel_Worksheet_AutoFilter)) {
+ $this->autoFilter = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Set Autofilter Range by using numeric cell coordinates
+ *
+ * @param integer $pColumn1 Numeric column coordinate of the first cell
+ * @param integer $pRow1 Numeric row coordinate of the first cell
+ * @param integer $pColumn2 Numeric column coordinate of the second cell
+ * @param integer $pRow2 Numeric row coordinate of the second cell
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function setAutoFilterByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1)
+ {
+ return $this->setAutoFilter(
+ PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1
+ . ':' .
+ PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2
+ );
+ }
+
+ /**
+ * Remove autofilter
+ *
+ * @return PHPExcel_Worksheet
+ */
+ public function removeAutoFilter()
+ {
+ $this->autoFilter->setRange(null);
+ return $this;
+ }
+
+ /**
+ * Get Freeze Pane
+ *
+ * @return string
+ */
+ public function getFreezePane()
+ {
+ return $this->freezePane;
+ }
+
+ /**
+ * Freeze Pane
+ *
+ * @param string $pCell Cell (i.e. A2)
+ * Examples:
+ * A2 will freeze the rows above cell A2 (i.e row 1)
+ * B1 will freeze the columns to the left of cell B1 (i.e column A)
+ * B2 will freeze the rows above and to the left of cell A2
+ * (i.e row 1 and column A)
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function freezePane($pCell = '')
+ {
+ // Uppercase coordinate
+ $pCell = strtoupper($pCell);
+ if (strpos($pCell, ':') === false && strpos($pCell, ',') === false) {
+ $this->freezePane = $pCell;
+ } else {
+ throw new PHPExcel_Exception('Freeze pane can not be set on a range of cells.');
+ }
+ return $this;
+ }
+
+ /**
+ * Freeze Pane by using numeric cell coordinates
+ *
+ * @param int $pColumn Numeric column coordinate of the cell
+ * @param int $pRow Numeric row coordinate of the cell
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function freezePaneByColumnAndRow($pColumn = 0, $pRow = 1)
+ {
+ return $this->freezePane(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);
+ }
+
+ /**
+ * Unfreeze Pane
+ *
+ * @return PHPExcel_Worksheet
+ */
+ public function unfreezePane()
+ {
+ return $this->freezePane('');
+ }
+
+ /**
+ * Insert a new row, updating all possible related data
+ *
+ * @param int $pBefore Insert before this one
+ * @param int $pNumRows Number of rows to insert
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function insertNewRowBefore($pBefore = 1, $pNumRows = 1)
+ {
+ if ($pBefore >= 1) {
+ $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance();
+ $objReferenceHelper->insertNewBefore('A' . $pBefore, 0, $pNumRows, $this);
+ } else {
+ throw new PHPExcel_Exception("Rows can only be inserted before at least row 1.");
+ }
+ return $this;
+ }
+
+ /**
+ * Insert a new column, updating all possible related data
+ *
+ * @param int $pBefore Insert before this one
+ * @param int $pNumCols Number of columns to insert
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function insertNewColumnBefore($pBefore = 'A', $pNumCols = 1)
+ {
+ if (!is_numeric($pBefore)) {
+ $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance();
+ $objReferenceHelper->insertNewBefore($pBefore . '1', $pNumCols, 0, $this);
+ } else {
+ throw new PHPExcel_Exception("Column references should not be numeric.");
+ }
+ return $this;
+ }
+
+ /**
+ * Insert a new column, updating all possible related data
+ *
+ * @param int $pBefore Insert before this one (numeric column coordinate of the cell)
+ * @param int $pNumCols Number of columns to insert
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function insertNewColumnBeforeByIndex($pBefore = 0, $pNumCols = 1)
+ {
+ if ($pBefore >= 0) {
+ return $this->insertNewColumnBefore(PHPExcel_Cell::stringFromColumnIndex($pBefore), $pNumCols);
+ } else {
+ throw new PHPExcel_Exception("Columns can only be inserted before at least column A (0).");
+ }
+ }
+
+ /**
+ * Delete a row, updating all possible related data
+ *
+ * @param int $pRow Remove starting with this one
+ * @param int $pNumRows Number of rows to remove
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function removeRow($pRow = 1, $pNumRows = 1)
+ {
+ if ($pRow >= 1) {
+ $highestRow = $this->getHighestDataRow();
+ $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance();
+ $objReferenceHelper->insertNewBefore('A' . ($pRow + $pNumRows), 0, -$pNumRows, $this);
+ for ($r = 0; $r < $pNumRows; ++$r) {
+ $this->getCellCacheController()->removeRow($highestRow);
+ --$highestRow;
+ }
+ } else {
+ throw new PHPExcel_Exception("Rows to be deleted should at least start from row 1.");
+ }
+ return $this;
+ }
+
+ /**
+ * Remove a column, updating all possible related data
+ *
+ * @param string $pColumn Remove starting with this one
+ * @param int $pNumCols Number of columns to remove
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function removeColumn($pColumn = 'A', $pNumCols = 1)
+ {
+ if (!is_numeric($pColumn)) {
+ $highestColumn = $this->getHighestDataColumn();
+ $pColumn = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($pColumn) - 1 + $pNumCols);
+ $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance();
+ $objReferenceHelper->insertNewBefore($pColumn . '1', -$pNumCols, 0, $this);
+ for ($c = 0; $c < $pNumCols; ++$c) {
+ $this->getCellCacheController()->removeColumn($highestColumn);
+ $highestColumn = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($highestColumn) - 2);
+ }
+ } else {
+ throw new PHPExcel_Exception("Column references should not be numeric.");
+ }
+ return $this;
+ }
+
+ /**
+ * Remove a column, updating all possible related data
+ *
+ * @param int $pColumn Remove starting with this one (numeric column coordinate of the cell)
+ * @param int $pNumCols Number of columns to remove
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function removeColumnByIndex($pColumn = 0, $pNumCols = 1)
+ {
+ if ($pColumn >= 0) {
+ return $this->removeColumn(PHPExcel_Cell::stringFromColumnIndex($pColumn), $pNumCols);
+ } else {
+ throw new PHPExcel_Exception("Columns to be deleted should at least start from column 0");
+ }
+ }
+
+ /**
+ * Show gridlines?
+ *
+ * @return boolean
+ */
+ public function getShowGridlines()
+ {
+ return $this->showGridlines;
+ }
+
+ /**
+ * Set show gridlines
+ *
+ * @param boolean $pValue Show gridlines (true/false)
+ * @return PHPExcel_Worksheet
+ */
+ public function setShowGridlines($pValue = false)
+ {
+ $this->showGridlines = $pValue;
+ return $this;
+ }
+
+ /**
+ * Print gridlines?
+ *
+ * @return boolean
+ */
+ public function getPrintGridlines()
+ {
+ return $this->printGridlines;
+ }
+
+ /**
+ * Set print gridlines
+ *
+ * @param boolean $pValue Print gridlines (true/false)
+ * @return PHPExcel_Worksheet
+ */
+ public function setPrintGridlines($pValue = false)
+ {
+ $this->printGridlines = $pValue;
+ return $this;
+ }
+
+ /**
+ * Show row and column headers?
+ *
+ * @return boolean
+ */
+ public function getShowRowColHeaders()
+ {
+ return $this->showRowColHeaders;
+ }
+
+ /**
+ * Set show row and column headers
+ *
+ * @param boolean $pValue Show row and column headers (true/false)
+ * @return PHPExcel_Worksheet
+ */
+ public function setShowRowColHeaders($pValue = false)
+ {
+ $this->showRowColHeaders = $pValue;
+ return $this;
+ }
+
+ /**
+ * Show summary below? (Row/Column outlining)
+ *
+ * @return boolean
+ */
+ public function getShowSummaryBelow()
+ {
+ return $this->showSummaryBelow;
+ }
+
+ /**
+ * Set show summary below
+ *
+ * @param boolean $pValue Show summary below (true/false)
+ * @return PHPExcel_Worksheet
+ */
+ public function setShowSummaryBelow($pValue = true)
+ {
+ $this->showSummaryBelow = $pValue;
+ return $this;
+ }
+
+ /**
+ * Show summary right? (Row/Column outlining)
+ *
+ * @return boolean
+ */
+ public function getShowSummaryRight()
+ {
+ return $this->showSummaryRight;
+ }
+
+ /**
+ * Set show summary right
+ *
+ * @param boolean $pValue Show summary right (true/false)
+ * @return PHPExcel_Worksheet
+ */
+ public function setShowSummaryRight($pValue = true)
+ {
+ $this->showSummaryRight = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get comments
+ *
+ * @return PHPExcel_Comment[]
+ */
+ public function getComments()
+ {
+ return $this->comments;
+ }
+
+ /**
+ * Set comments array for the entire sheet.
+ *
+ * @param array of PHPExcel_Comment
+ * @return PHPExcel_Worksheet
+ */
+ public function setComments($pValue = array())
+ {
+ $this->comments = $pValue;
+
+ return $this;
+ }
+
+ /**
+ * Get comment for cell
+ *
+ * @param string $pCellCoordinate Cell coordinate to get comment for
+ * @return PHPExcel_Comment
+ * @throws PHPExcel_Exception
+ */
+ public function getComment($pCellCoordinate = 'A1')
+ {
+ // Uppercase coordinate
+ $pCellCoordinate = strtoupper($pCellCoordinate);
+
+ if (strpos($pCellCoordinate, ':') !== false || strpos($pCellCoordinate, ',') !== false) {
+ throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells.');
+ } elseif (strpos($pCellCoordinate, '$') !== false) {
+ throw new PHPExcel_Exception('Cell coordinate string must not be absolute.');
+ } elseif ($pCellCoordinate == '') {
+ throw new PHPExcel_Exception('Cell coordinate can not be zero-length string.');
+ } else {
+ // Check if we already have a comment for this cell.
+ // If not, create a new comment.
+ if (isset($this->comments[$pCellCoordinate])) {
+ return $this->comments[$pCellCoordinate];
+ } else {
+ $newComment = new PHPExcel_Comment();
+ $this->comments[$pCellCoordinate] = $newComment;
+ return $newComment;
+ }
+ }
+ }
+
+ /**
+ * Get comment for cell by using numeric cell coordinates
+ *
+ * @param int $pColumn Numeric column coordinate of the cell
+ * @param int $pRow Numeric row coordinate of the cell
+ * @return PHPExcel_Comment
+ */
+ public function getCommentByColumnAndRow($pColumn = 0, $pRow = 1)
+ {
+ return $this->getComment(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);
+ }
+
+ /**
+ * Get selected cell
+ *
+ * @deprecated
+ * @return string
+ */
+ public function getSelectedCell()
+ {
+ return $this->getSelectedCells();
+ }
+
+ /**
+ * Get active cell
+ *
+ * @return string Example: 'A1'
+ */
+ public function getActiveCell()
+ {
+ return $this->activeCell;
+ }
+
+ /**
+ * Get selected cells
+ *
+ * @return string
+ */
+ public function getSelectedCells()
+ {
+ return $this->selectedCells;
+ }
+
+ /**
+ * Selected cell
+ *
+ * @param string $pCoordinate Cell (i.e. A1)
+ * @return PHPExcel_Worksheet
+ */
+ public function setSelectedCell($pCoordinate = 'A1')
+ {
+ return $this->setSelectedCells($pCoordinate);
+ }
+
+ /**
+ * Select a range of cells.
+ *
+ * @param string $pCoordinate Cell range, examples: 'A1', 'B2:G5', 'A:C', '3:6'
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function setSelectedCells($pCoordinate = 'A1')
+ {
+ // Uppercase coordinate
+ $pCoordinate = strtoupper($pCoordinate);
+
+ // Convert 'A' to 'A:A'
+ $pCoordinate = preg_replace('/^([A-Z]+)$/', '${1}:${1}', $pCoordinate);
+
+ // Convert '1' to '1:1'
+ $pCoordinate = preg_replace('/^([0-9]+)$/', '${1}:${1}', $pCoordinate);
+
+ // Convert 'A:C' to 'A1:C1048576'
+ $pCoordinate = preg_replace('/^([A-Z]+):([A-Z]+)$/', '${1}1:${2}1048576', $pCoordinate);
+
+ // Convert '1:3' to 'A1:XFD3'
+ $pCoordinate = preg_replace('/^([0-9]+):([0-9]+)$/', 'A${1}:XFD${2}', $pCoordinate);
+
+ if (strpos($pCoordinate, ':') !== false || strpos($pCoordinate, ',') !== false) {
+ list($first, ) = PHPExcel_Cell::splitRange($pCoordinate);
+ $this->activeCell = $first[0];
+ } else {
+ $this->activeCell = $pCoordinate;
+ }
+ $this->selectedCells = $pCoordinate;
+ return $this;
+ }
+
+ /**
+ * Selected cell by using numeric cell coordinates
+ *
+ * @param int $pColumn Numeric column coordinate of the cell
+ * @param int $pRow Numeric row coordinate of the cell
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function setSelectedCellByColumnAndRow($pColumn = 0, $pRow = 1)
+ {
+ return $this->setSelectedCells(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);
+ }
+
+ /**
+ * Get right-to-left
+ *
+ * @return boolean
+ */
+ public function getRightToLeft()
+ {
+ return $this->rightToLeft;
+ }
+
+ /**
+ * Set right-to-left
+ *
+ * @param boolean $value Right-to-left true/false
+ * @return PHPExcel_Worksheet
+ */
+ public function setRightToLeft($value = false)
+ {
+ $this->rightToLeft = $value;
+ return $this;
+ }
+
+ /**
+ * Fill worksheet from values in array
+ *
+ * @param array $source Source array
+ * @param mixed $nullValue Value in source array that stands for blank cell
+ * @param string $startCell Insert array starting from this cell address as the top left coordinate
+ * @param boolean $strictNullComparison Apply strict comparison when testing for null values in the array
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet
+ */
+ public function fromArray($source = null, $nullValue = null, $startCell = 'A1', $strictNullComparison = false)
+ {
+ if (is_array($source)) {
+ // Convert a 1-D array to 2-D (for ease of looping)
+ if (!is_array(end($source))) {
+ $source = array($source);
+ }
+
+ // start coordinate
+ list ($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($startCell);
+
+ // Loop through $source
+ foreach ($source as $rowData) {
+ $currentColumn = $startColumn;
+ foreach ($rowData as $cellValue) {
+ if ($strictNullComparison) {
+ if ($cellValue !== $nullValue) {
+ // Set cell value
+ $this->getCell($currentColumn . $startRow)->setValue($cellValue);
+ }
+ } else {
+ if ($cellValue != $nullValue) {
+ // Set cell value
+ $this->getCell($currentColumn . $startRow)->setValue($cellValue);
+ }
+ }
+ ++$currentColumn;
+ }
+ ++$startRow;
+ }
+ } else {
+ throw new PHPExcel_Exception("Parameter \$source should be an array.");
+ }
+ return $this;
+ }
+
+ /**
+ * Create array from a range of cells
+ *
+ * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
+ * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist
+ * @param boolean $calculateFormulas Should formulas be calculated?
+ * @param boolean $formatData Should formatting be applied to cell values?
+ * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero
+ * True - Return rows and columns indexed by their actual row and column IDs
+ * @return array
+ */
+ public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false)
+ {
+ // Returnvalue
+ $returnValue = array();
+ // Identify the range that we need to extract from the worksheet
+ list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange);
+ $minCol = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] -1);
+ $minRow = $rangeStart[1];
+ $maxCol = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0] -1);
+ $maxRow = $rangeEnd[1];
+
+ $maxCol++;
+ // Loop through rows
+ $r = -1;
+ for ($row = $minRow; $row <= $maxRow; ++$row) {
+ $rRef = ($returnCellRef) ? $row : ++$r;
+ $c = -1;
+ // Loop through columns in the current row
+ for ($col = $minCol; $col != $maxCol; ++$col) {
+ $cRef = ($returnCellRef) ? $col : ++$c;
+ // Using getCell() will create a new cell if it doesn't already exist. We don't want that to happen
+ // so we test and retrieve directly against cellCollection
+ if ($this->cellCollection->isDataSet($col.$row)) {
+ // Cell exists
+ $cell = $this->cellCollection->getCacheData($col.$row);
+ if ($cell->getValue() !== null) {
+ if ($cell->getValue() instanceof PHPExcel_RichText) {
+ $returnValue[$rRef][$cRef] = $cell->getValue()->getPlainText();
+ } else {
+ if ($calculateFormulas) {
+ $returnValue[$rRef][$cRef] = $cell->getCalculatedValue();
+ } else {
+ $returnValue[$rRef][$cRef] = $cell->getValue();
+ }
+ }
+
+ if ($formatData) {
+ $style = $this->parent->getCellXfByIndex($cell->getXfIndex());
+ $returnValue[$rRef][$cRef] = PHPExcel_Style_NumberFormat::toFormattedString(
+ $returnValue[$rRef][$cRef],
+ ($style && $style->getNumberFormat()) ? $style->getNumberFormat()->getFormatCode() : PHPExcel_Style_NumberFormat::FORMAT_GENERAL
+ );
+ }
+ } else {
+ // Cell holds a NULL
+ $returnValue[$rRef][$cRef] = $nullValue;
+ }
+ } else {
+ // Cell doesn't exist
+ $returnValue[$rRef][$cRef] = $nullValue;
+ }
+ }
+ }
+
+ // Return
+ return $returnValue;
+ }
+
+
+ /**
+ * Create array from a range of cells
+ *
+ * @param string $pNamedRange Name of the Named Range
+ * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist
+ * @param boolean $calculateFormulas Should formulas be calculated?
+ * @param boolean $formatData Should formatting be applied to cell values?
+ * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero
+ * True - Return rows and columns indexed by their actual row and column IDs
+ * @return array
+ * @throws PHPExcel_Exception
+ */
+ public function namedRangeToArray($pNamedRange = '', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false)
+ {
+ $namedRange = PHPExcel_NamedRange::resolveRange($pNamedRange, $this);
+ if ($namedRange !== null) {
+ $pWorkSheet = $namedRange->getWorksheet();
+ $pCellRange = $namedRange->getRange();
+
+ return $pWorkSheet->rangeToArray($pCellRange, $nullValue, $calculateFormulas, $formatData, $returnCellRef);
+ }
+
+ throw new PHPExcel_Exception('Named Range '.$pNamedRange.' does not exist.');
+ }
+
+
+ /**
+ * Create array from worksheet
+ *
+ * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist
+ * @param boolean $calculateFormulas Should formulas be calculated?
+ * @param boolean $formatData Should formatting be applied to cell values?
+ * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero
+ * True - Return rows and columns indexed by their actual row and column IDs
+ * @return array
+ */
+ public function toArray($nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false)
+ {
+ // Garbage collect...
+ $this->garbageCollect();
+
+ // Identify the range that we need to extract from the worksheet
+ $maxCol = $this->getHighestColumn();
+ $maxRow = $this->getHighestRow();
+ // Return
+ return $this->rangeToArray('A1:'.$maxCol.$maxRow, $nullValue, $calculateFormulas, $formatData, $returnCellRef);
+ }
+
+ /**
+ * Get row iterator
+ *
+ * @param integer $startRow The row number at which to start iterating
+ * @param integer $endRow The row number at which to stop iterating
+ *
+ * @return PHPExcel_Worksheet_RowIterator
+ */
+ public function getRowIterator($startRow = 1, $endRow = null)
+ {
+ return new PHPExcel_Worksheet_RowIterator($this, $startRow, $endRow);
+ }
+
+ /**
+ * Get column iterator
+ *
+ * @param string $startColumn The column address at which to start iterating
+ * @param string $endColumn The column address at which to stop iterating
+ *
+ * @return PHPExcel_Worksheet_ColumnIterator
+ */
+ public function getColumnIterator($startColumn = 'A', $endColumn = null)
+ {
+ return new PHPExcel_Worksheet_ColumnIterator($this, $startColumn, $endColumn);
+ }
+
+ /**
+ * Run PHPExcel garabage collector.
+ *
+ * @return PHPExcel_Worksheet
+ */
+ public function garbageCollect()
+ {
+ // Flush cache
+ $this->cellCollection->getCacheData('A1');
+ // Build a reference table from images
+// $imageCoordinates = array();
+// $iterator = $this->getDrawingCollection()->getIterator();
+// while ($iterator->valid()) {
+// $imageCoordinates[$iterator->current()->getCoordinates()] = true;
+//
+// $iterator->next();
+// }
+//
+ // Lookup highest column and highest row if cells are cleaned
+ $colRow = $this->cellCollection->getHighestRowAndColumn();
+ $highestRow = $colRow['row'];
+ $highestColumn = PHPExcel_Cell::columnIndexFromString($colRow['column']);
+
+ // Loop through column dimensions
+ foreach ($this->columnDimensions as $dimension) {
+ $highestColumn = max($highestColumn, PHPExcel_Cell::columnIndexFromString($dimension->getColumnIndex()));
+ }
+
+ // Loop through row dimensions
+ foreach ($this->rowDimensions as $dimension) {
+ $highestRow = max($highestRow, $dimension->getRowIndex());
+ }
+
+ // Cache values
+ if ($highestColumn < 0) {
+ $this->cachedHighestColumn = 'A';
+ } else {
+ $this->cachedHighestColumn = PHPExcel_Cell::stringFromColumnIndex(--$highestColumn);
+ }
+ $this->cachedHighestRow = $highestRow;
+
+ // Return
+ return $this;
+ }
+
+ /**
+ * Get hash code
+ *
+ * @return string Hash code
+ */
+ public function getHashCode()
+ {
+ if ($this->dirty) {
+ $this->hash = md5($this->title . $this->autoFilter . ($this->protection->isProtectionEnabled() ? 't' : 'f') . __CLASS__);
+ $this->dirty = false;
+ }
+ return $this->hash;
+ }
+
+ /**
+ * Extract worksheet title from range.
+ *
+ * Example: extractSheetTitle("testSheet!A1") ==> 'A1'
+ * Example: extractSheetTitle("'testSheet 1'!A1", true) ==> array('testSheet 1', 'A1');
+ *
+ * @param string $pRange Range to extract title from
+ * @param bool $returnRange Return range? (see example)
+ * @return mixed
+ */
+ public static function extractSheetTitle($pRange, $returnRange = false)
+ {
+ // Sheet title included?
+ if (($sep = strpos($pRange, '!')) === false) {
+ return '';
+ }
+
+ if ($returnRange) {
+ return array(trim(substr($pRange, 0, $sep), "'"), substr($pRange, $sep + 1));
+ }
+
+ return substr($pRange, $sep + 1);
+ }
+
+ /**
+ * Get hyperlink
+ *
+ * @param string $pCellCoordinate Cell coordinate to get hyperlink for
+ */
+ public function getHyperlink($pCellCoordinate = 'A1')
+ {
+ // return hyperlink if we already have one
+ if (isset($this->hyperlinkCollection[$pCellCoordinate])) {
+ return $this->hyperlinkCollection[$pCellCoordinate];
+ }
+
+ // else create hyperlink
+ $this->hyperlinkCollection[$pCellCoordinate] = new PHPExcel_Cell_Hyperlink();
+ return $this->hyperlinkCollection[$pCellCoordinate];
+ }
+
+ /**
+ * Set hyperlnk
+ *
+ * @param string $pCellCoordinate Cell coordinate to insert hyperlink
+ * @param PHPExcel_Cell_Hyperlink $pHyperlink
+ * @return PHPExcel_Worksheet
+ */
+ public function setHyperlink($pCellCoordinate = 'A1', PHPExcel_Cell_Hyperlink $pHyperlink = null)
+ {
+ if ($pHyperlink === null) {
+ unset($this->hyperlinkCollection[$pCellCoordinate]);
+ } else {
+ $this->hyperlinkCollection[$pCellCoordinate] = $pHyperlink;
+ }
+ return $this;
+ }
+
+ /**
+ * Hyperlink at a specific coordinate exists?
+ *
+ * @param string $pCoordinate
+ * @return boolean
+ */
+ public function hyperlinkExists($pCoordinate = 'A1')
+ {
+ return isset($this->hyperlinkCollection[$pCoordinate]);
+ }
+
+ /**
+ * Get collection of hyperlinks
+ *
+ * @return PHPExcel_Cell_Hyperlink[]
+ */
+ public function getHyperlinkCollection()
+ {
+ return $this->hyperlinkCollection;
+ }
+
+ /**
+ * Get data validation
+ *
+ * @param string $pCellCoordinate Cell coordinate to get data validation for
+ */
+ public function getDataValidation($pCellCoordinate = 'A1')
+ {
+ // return data validation if we already have one
+ if (isset($this->dataValidationCollection[$pCellCoordinate])) {
+ return $this->dataValidationCollection[$pCellCoordinate];
+ }
+
+ // else create data validation
+ $this->dataValidationCollection[$pCellCoordinate] = new PHPExcel_Cell_DataValidation();
+ return $this->dataValidationCollection[$pCellCoordinate];
+ }
+
+ /**
+ * Set data validation
+ *
+ * @param string $pCellCoordinate Cell coordinate to insert data validation
+ * @param PHPExcel_Cell_DataValidation $pDataValidation
+ * @return PHPExcel_Worksheet
+ */
+ public function setDataValidation($pCellCoordinate = 'A1', PHPExcel_Cell_DataValidation $pDataValidation = null)
+ {
+ if ($pDataValidation === null) {
+ unset($this->dataValidationCollection[$pCellCoordinate]);
+ } else {
+ $this->dataValidationCollection[$pCellCoordinate] = $pDataValidation;
+ }
+ return $this;
+ }
+
+ /**
+ * Data validation at a specific coordinate exists?
+ *
+ * @param string $pCoordinate
+ * @return boolean
+ */
+ public function dataValidationExists($pCoordinate = 'A1')
+ {
+ return isset($this->dataValidationCollection[$pCoordinate]);
+ }
+
+ /**
+ * Get collection of data validations
+ *
+ * @return PHPExcel_Cell_DataValidation[]
+ */
+ public function getDataValidationCollection()
+ {
+ return $this->dataValidationCollection;
+ }
+
+ /**
+ * Accepts a range, returning it as a range that falls within the current highest row and column of the worksheet
+ *
+ * @param string $range
+ * @return string Adjusted range value
+ */
+ public function shrinkRangeToFit($range)
+ {
+ $maxCol = $this->getHighestColumn();
+ $maxRow = $this->getHighestRow();
+ $maxCol = PHPExcel_Cell::columnIndexFromString($maxCol);
+
+ $rangeBlocks = explode(' ', $range);
+ foreach ($rangeBlocks as &$rangeSet) {
+ $rangeBoundaries = PHPExcel_Cell::getRangeBoundaries($rangeSet);
+
+ if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[0][0]) > $maxCol) {
+ $rangeBoundaries[0][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol);
+ }
+ if ($rangeBoundaries[0][1] > $maxRow) {
+ $rangeBoundaries[0][1] = $maxRow;
+ }
+ if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[1][0]) > $maxCol) {
+ $rangeBoundaries[1][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol);
+ }
+ if ($rangeBoundaries[1][1] > $maxRow) {
+ $rangeBoundaries[1][1] = $maxRow;
+ }
+ $rangeSet = $rangeBoundaries[0][0].$rangeBoundaries[0][1].':'.$rangeBoundaries[1][0].$rangeBoundaries[1][1];
+ }
+ unset($rangeSet);
+ $stRange = implode(' ', $rangeBlocks);
+
+ return $stRange;
+ }
+
+ /**
+ * Get tab color
+ *
+ * @return PHPExcel_Style_Color
+ */
+ public function getTabColor()
+ {
+ if ($this->tabColor === null) {
+ $this->tabColor = new PHPExcel_Style_Color();
+ }
+ return $this->tabColor;
+ }
+
+ /**
+ * Reset tab color
+ *
+ * @return PHPExcel_Worksheet
+ */
+ public function resetTabColor()
+ {
+ $this->tabColor = null;
+ unset($this->tabColor);
+
+ return $this;
+ }
+
+ /**
+ * Tab color set?
+ *
+ * @return boolean
+ */
+ public function isTabColorSet()
+ {
+ return ($this->tabColor !== null);
+ }
+
+ /**
+ * Copy worksheet (!= clone!)
+ *
+ * @return PHPExcel_Worksheet
+ */
+ public function copy()
+ {
+ $copied = clone $this;
+
+ return $copied;
+ }
+
+ /**
+ * Implement PHP __clone to create a deep clone, not just a shallow copy.
+ */
+ public function __clone()
+ {
+ foreach ($this as $key => $val) {
+ if ($key == 'parent') {
+ continue;
+ }
+
+ if (is_object($val) || (is_array($val))) {
+ if ($key == 'cellCollection') {
+ $newCollection = clone $this->cellCollection;
+ $newCollection->copyCellCollection($this);
+ $this->cellCollection = $newCollection;
+ } elseif ($key == 'drawingCollection') {
+ $newCollection = clone $this->drawingCollection;
+ $this->drawingCollection = $newCollection;
+ } elseif (($key == 'autoFilter') && ($this->autoFilter instanceof PHPExcel_Worksheet_AutoFilter)) {
+ $newAutoFilter = clone $this->autoFilter;
+ $this->autoFilter = $newAutoFilter;
+ $this->autoFilter->setParent($this);
+ } else {
+ $this->{$key} = unserialize(serialize($val));
+ }
+ }
+ }
+ }
+/**
+ * Define the code name of the sheet
+ *
+ * @param null|string Same rule as Title minus space not allowed (but, like Excel, change silently space to underscore)
+ * @return objWorksheet
+ * @throws PHPExcel_Exception
+ */
+ public function setCodeName($pValue = null)
+ {
+ // Is this a 'rename' or not?
+ if ($this->getCodeName() == $pValue) {
+ return $this;
+ }
+ $pValue = str_replace(' ', '_', $pValue);//Excel does this automatically without flinching, we are doing the same
+ // Syntax check
+ // throw an exception if not valid
+ self::checkSheetCodeName($pValue);
+
+ // We use the same code that setTitle to find a valid codeName else not using a space (Excel don't like) but a '_'
+
+ if ($this->getParent()) {
+ // Is there already such sheet name?
+ if ($this->getParent()->sheetCodeNameExists($pValue)) {
+ // Use name, but append with lowest possible integer
+
+ if (PHPExcel_Shared_String::CountCharacters($pValue) > 29) {
+ $pValue = PHPExcel_Shared_String::Substring($pValue, 0, 29);
+ }
+ $i = 1;
+ while ($this->getParent()->sheetCodeNameExists($pValue . '_' . $i)) {
+ ++$i;
+ if ($i == 10) {
+ if (PHPExcel_Shared_String::CountCharacters($pValue) > 28) {
+ $pValue = PHPExcel_Shared_String::Substring($pValue, 0, 28);
+ }
+ } elseif ($i == 100) {
+ if (PHPExcel_Shared_String::CountCharacters($pValue) > 27) {
+ $pValue = PHPExcel_Shared_String::Substring($pValue, 0, 27);
+ }
+ }
+ }
+
+ $pValue = $pValue . '_' . $i;// ok, we have a valid name
+ //codeName is'nt used in formula : no need to call for an update
+ //return $this->setTitle($altTitle, $updateFormulaCellReferences);
+ }
+ }
+
+ $this->codeName=$pValue;
+ return $this;
+ }
+ /**
+ * Return the code name of the sheet
+ *
+ * @return null|string
+ */
+ public function getCodeName()
+ {
+ return $this->codeName;
+ }
+ /**
+ * Sheet has a code name ?
+ * @return boolean
+ */
+ public function hasCodeName()
+ {
+ return !(is_null($this->codeName));
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/AutoFilter.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/AutoFilter.php
new file mode 100755
index 000000000..6ec8a4466
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/AutoFilter.php
@@ -0,0 +1,846 @@
+range = $pRange;
+ $this->workSheet = $pSheet;
+ }
+
+ /**
+ * Get AutoFilter Parent Worksheet
+ *
+ * @return PHPExcel_Worksheet
+ */
+ public function getParent()
+ {
+ return $this->workSheet;
+ }
+
+ /**
+ * Set AutoFilter Parent Worksheet
+ *
+ * @param PHPExcel_Worksheet $pSheet
+ * @return PHPExcel_Worksheet_AutoFilter
+ */
+ public function setParent(PHPExcel_Worksheet $pSheet = null)
+ {
+ $this->workSheet = $pSheet;
+
+ return $this;
+ }
+
+ /**
+ * Get AutoFilter Range
+ *
+ * @return string
+ */
+ public function getRange()
+ {
+ return $this->range;
+ }
+
+ /**
+ * Set AutoFilter Range
+ *
+ * @param string $pRange Cell range (i.e. A1:E10)
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_AutoFilter
+ */
+ public function setRange($pRange = '')
+ {
+ // Uppercase coordinate
+ $cellAddress = explode('!', strtoupper($pRange));
+ if (count($cellAddress) > 1) {
+ list($worksheet, $pRange) = $cellAddress;
+ }
+
+ if (strpos($pRange, ':') !== false) {
+ $this->range = $pRange;
+ } elseif (empty($pRange)) {
+ $this->range = '';
+ } else {
+ throw new PHPExcel_Exception('Autofilter must be set on a range of cells.');
+ }
+
+ if (empty($pRange)) {
+ // Discard all column rules
+ $this->columns = array();
+ } else {
+ // Discard any column rules that are no longer valid within this range
+ list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->range);
+ foreach ($this->columns as $key => $value) {
+ $colIndex = PHPExcel_Cell::columnIndexFromString($key);
+ if (($rangeStart[0] > $colIndex) || ($rangeEnd[0] < $colIndex)) {
+ unset($this->columns[$key]);
+ }
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get all AutoFilter Columns
+ *
+ * @throws PHPExcel_Exception
+ * @return array of PHPExcel_Worksheet_AutoFilter_Column
+ */
+ public function getColumns()
+ {
+ return $this->columns;
+ }
+
+ /**
+ * Validate that the specified column is in the AutoFilter range
+ *
+ * @param string $column Column name (e.g. A)
+ * @throws PHPExcel_Exception
+ * @return integer The column offset within the autofilter range
+ */
+ public function testColumnInRange($column)
+ {
+ if (empty($this->range)) {
+ throw new PHPExcel_Exception("No autofilter range is defined.");
+ }
+
+ $columnIndex = PHPExcel_Cell::columnIndexFromString($column);
+ list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->range);
+ if (($rangeStart[0] > $columnIndex) || ($rangeEnd[0] < $columnIndex)) {
+ throw new PHPExcel_Exception("Column is outside of current autofilter range.");
+ }
+
+ return $columnIndex - $rangeStart[0];
+ }
+
+ /**
+ * Get a specified AutoFilter Column Offset within the defined AutoFilter range
+ *
+ * @param string $pColumn Column name (e.g. A)
+ * @throws PHPExcel_Exception
+ * @return integer The offset of the specified column within the autofilter range
+ */
+ public function getColumnOffset($pColumn)
+ {
+ return $this->testColumnInRange($pColumn);
+ }
+
+ /**
+ * Get a specified AutoFilter Column
+ *
+ * @param string $pColumn Column name (e.g. A)
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_AutoFilter_Column
+ */
+ public function getColumn($pColumn)
+ {
+ $this->testColumnInRange($pColumn);
+
+ if (!isset($this->columns[$pColumn])) {
+ $this->columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this);
+ }
+
+ return $this->columns[$pColumn];
+ }
+
+ /**
+ * Get a specified AutoFilter Column by it's offset
+ *
+ * @param integer $pColumnOffset Column offset within range (starting from 0)
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_AutoFilter_Column
+ */
+ public function getColumnByOffset($pColumnOffset = 0)
+ {
+ list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->range);
+ $pColumn = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] + $pColumnOffset - 1);
+
+ return $this->getColumn($pColumn);
+ }
+
+ /**
+ * Set AutoFilter
+ *
+ * @param PHPExcel_Worksheet_AutoFilter_Column|string $pColumn
+ * A simple string containing a Column ID like 'A' is permitted
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_AutoFilter
+ */
+ public function setColumn($pColumn)
+ {
+ if ((is_string($pColumn)) && (!empty($pColumn))) {
+ $column = $pColumn;
+ } elseif (is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) {
+ $column = $pColumn->getColumnIndex();
+ } else {
+ throw new PHPExcel_Exception("Column is not within the autofilter range.");
+ }
+ $this->testColumnInRange($column);
+
+ if (is_string($pColumn)) {
+ $this->columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this);
+ } elseif (is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) {
+ $pColumn->setParent($this);
+ $this->columns[$column] = $pColumn;
+ }
+ ksort($this->columns);
+
+ return $this;
+ }
+
+ /**
+ * Clear a specified AutoFilter Column
+ *
+ * @param string $pColumn Column name (e.g. A)
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_AutoFilter
+ */
+ public function clearColumn($pColumn)
+ {
+ $this->testColumnInRange($pColumn);
+
+ if (isset($this->columns[$pColumn])) {
+ unset($this->columns[$pColumn]);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Shift an AutoFilter Column Rule to a different column
+ *
+ * Note: This method bypasses validation of the destination column to ensure it is within this AutoFilter range.
+ * Nor does it verify whether any column rule already exists at $toColumn, but will simply overrideany existing value.
+ * Use with caution.
+ *
+ * @param string $fromColumn Column name (e.g. A)
+ * @param string $toColumn Column name (e.g. B)
+ * @return PHPExcel_Worksheet_AutoFilter
+ */
+ public function shiftColumn($fromColumn = null, $toColumn = null)
+ {
+ $fromColumn = strtoupper($fromColumn);
+ $toColumn = strtoupper($toColumn);
+
+ if (($fromColumn !== null) && (isset($this->columns[$fromColumn])) && ($toColumn !== null)) {
+ $this->columns[$fromColumn]->setParent();
+ $this->columns[$fromColumn]->setColumnIndex($toColumn);
+ $this->columns[$toColumn] = $this->columns[$fromColumn];
+ $this->columns[$toColumn]->setParent($this);
+ unset($this->columns[$fromColumn]);
+
+ ksort($this->columns);
+ }
+
+ return $this;
+ }
+
+
+ /**
+ * Test if cell value is in the defined set of values
+ *
+ * @param mixed $cellValue
+ * @param mixed[] $dataSet
+ * @return boolean
+ */
+ private static function filterTestInSimpleDataSet($cellValue, $dataSet)
+ {
+ $dataSetValues = $dataSet['filterValues'];
+ $blanks = $dataSet['blanks'];
+ if (($cellValue == '') || ($cellValue === null)) {
+ return $blanks;
+ }
+ return in_array($cellValue, $dataSetValues);
+ }
+
+ /**
+ * Test if cell value is in the defined set of Excel date values
+ *
+ * @param mixed $cellValue
+ * @param mixed[] $dataSet
+ * @return boolean
+ */
+ private static function filterTestInDateGroupSet($cellValue, $dataSet)
+ {
+ $dateSet = $dataSet['filterValues'];
+ $blanks = $dataSet['blanks'];
+ if (($cellValue == '') || ($cellValue === null)) {
+ return $blanks;
+ }
+
+ if (is_numeric($cellValue)) {
+ $dateValue = PHPExcel_Shared_Date::ExcelToPHP($cellValue);
+ if ($cellValue < 1) {
+ // Just the time part
+ $dtVal = date('His', $dateValue);
+ $dateSet = $dateSet['time'];
+ } elseif ($cellValue == floor($cellValue)) {
+ // Just the date part
+ $dtVal = date('Ymd', $dateValue);
+ $dateSet = $dateSet['date'];
+ } else {
+ // date and time parts
+ $dtVal = date('YmdHis', $dateValue);
+ $dateSet = $dateSet['dateTime'];
+ }
+ foreach ($dateSet as $dateValue) {
+ // Use of substr to extract value at the appropriate group level
+ if (substr($dtVal, 0, strlen($dateValue)) == $dateValue) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Test if cell value is within a set of values defined by a ruleset
+ *
+ * @param mixed $cellValue
+ * @param mixed[] $ruleSet
+ * @return boolean
+ */
+ private static function filterTestInCustomDataSet($cellValue, $ruleSet)
+ {
+ $dataSet = $ruleSet['filterRules'];
+ $join = $ruleSet['join'];
+ $customRuleForBlanks = isset($ruleSet['customRuleForBlanks']) ? $ruleSet['customRuleForBlanks'] : false;
+
+ if (!$customRuleForBlanks) {
+ // Blank cells are always ignored, so return a FALSE
+ if (($cellValue == '') || ($cellValue === null)) {
+ return false;
+ }
+ }
+ $returnVal = ($join == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND);
+ foreach ($dataSet as $rule) {
+ if (is_numeric($rule['value'])) {
+ // Numeric values are tested using the appropriate operator
+ switch ($rule['operator']) {
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL:
+ $retVal = ($cellValue == $rule['value']);
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL:
+ $retVal = ($cellValue != $rule['value']);
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN:
+ $retVal = ($cellValue > $rule['value']);
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL:
+ $retVal = ($cellValue >= $rule['value']);
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN:
+ $retVal = ($cellValue < $rule['value']);
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL:
+ $retVal = ($cellValue <= $rule['value']);
+ break;
+ }
+ } elseif ($rule['value'] == '') {
+ switch ($rule['operator']) {
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL:
+ $retVal = (($cellValue == '') || ($cellValue === null));
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL:
+ $retVal = (($cellValue != '') && ($cellValue !== null));
+ break;
+ default:
+ $retVal = true;
+ break;
+ }
+ } else {
+ // String values are always tested for equality, factoring in for wildcards (hence a regexp test)
+ $retVal = preg_match('/^'.$rule['value'].'$/i', $cellValue);
+ }
+ // If there are multiple conditions, then we need to test both using the appropriate join operator
+ switch ($join) {
+ case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR:
+ $returnVal = $returnVal || $retVal;
+ // Break as soon as we have a TRUE match for OR joins,
+ // to avoid unnecessary additional code execution
+ if ($returnVal) {
+ return $returnVal;
+ }
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND:
+ $returnVal = $returnVal && $retVal;
+ break;
+ }
+ }
+
+ return $returnVal;
+ }
+
+ /**
+ * Test if cell date value is matches a set of values defined by a set of months
+ *
+ * @param mixed $cellValue
+ * @param mixed[] $monthSet
+ * @return boolean
+ */
+ private static function filterTestInPeriodDateSet($cellValue, $monthSet)
+ {
+ // Blank cells are always ignored, so return a FALSE
+ if (($cellValue == '') || ($cellValue === null)) {
+ return false;
+ }
+
+ if (is_numeric($cellValue)) {
+ $dateValue = date('m', PHPExcel_Shared_Date::ExcelToPHP($cellValue));
+ if (in_array($dateValue, $monthSet)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Search/Replace arrays to convert Excel wildcard syntax to a regexp syntax for preg_matching
+ *
+ * @var array
+ */
+ private static $fromReplace = array('\*', '\?', '~~', '~.*', '~.?');
+ private static $toReplace = array('.*', '.', '~', '\*', '\?');
+
+
+ /**
+ * Convert a dynamic rule daterange to a custom filter range expression for ease of calculation
+ *
+ * @param string $dynamicRuleType
+ * @param PHPExcel_Worksheet_AutoFilter_Column &$filterColumn
+ * @return mixed[]
+ */
+ private function dynamicFilterDateRange($dynamicRuleType, &$filterColumn)
+ {
+ $rDateType = PHPExcel_Calculation_Functions::getReturnDateType();
+ PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC);
+ $val = $maxVal = null;
+
+ $ruleValues = array();
+ $baseDate = PHPExcel_Calculation_DateTime::DATENOW();
+ // Calculate start/end dates for the required date range based on current date
+ switch ($dynamicRuleType) {
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK:
+ $baseDate = strtotime('-7 days', $baseDate);
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK:
+ $baseDate = strtotime('-7 days', $baseDate);
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH:
+ $baseDate = strtotime('-1 month', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH:
+ $baseDate = strtotime('+1 month', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER:
+ $baseDate = strtotime('-3 month', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER:
+ $baseDate = strtotime('+3 month', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR:
+ $baseDate = strtotime('-1 year', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR:
+ $baseDate = strtotime('+1 year', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
+ break;
+ }
+
+ switch ($dynamicRuleType) {
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TODAY:
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY:
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW:
+ $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day', $baseDate));
+ $val = (int) PHPExcel_Shared_Date::PHPToExcel($baseDate);
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE:
+ $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day', $baseDate));
+ $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0, 0, 0, 1, 1, date('Y', $baseDate)));
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR:
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR:
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR:
+ $maxVal = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0, 0, 0, 31, 12, date('Y', $baseDate)));
+ ++$maxVal;
+ $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0, 0, 0, 1, 1, date('Y', $baseDate)));
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER:
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER:
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER:
+ $thisMonth = date('m', $baseDate);
+ $thisQuarter = floor(--$thisMonth / 3);
+ $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0, 0, 0, date('t', $baseDate), (1+$thisQuarter)*3, date('Y', $baseDate)));
+ ++$maxVal;
+ $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0, 0, 0, 1, 1+$thisQuarter*3, date('Y', $baseDate)));
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH:
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH:
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH:
+ $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0, 0, 0, date('t', $baseDate), date('m', $baseDate), date('Y', $baseDate)));
+ ++$maxVal;
+ $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK:
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK:
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK:
+ $dayOfWeek = date('w', $baseDate);
+ $val = (int) PHPExcel_Shared_Date::PHPToExcel($baseDate) - $dayOfWeek;
+ $maxVal = $val + 7;
+ break;
+ }
+
+ switch ($dynamicRuleType) {
+ // Adjust Today dates for Yesterday and Tomorrow
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY:
+ --$maxVal;
+ --$val;
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW:
+ ++$maxVal;
+ ++$val;
+ break;
+ }
+
+ // Set the filter column rule attributes ready for writing
+ $filterColumn->setAttributes(array('val' => $val, 'maxVal' => $maxVal));
+
+ // Set the rules for identifying rows for hide/show
+ $ruleValues[] = array('operator' => PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL, 'value' => $val);
+ $ruleValues[] = array('operator' => PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN, 'value' => $maxVal);
+ PHPExcel_Calculation_Functions::setReturnDateType($rDateType);
+
+ return array('method' => 'filterTestInCustomDataSet', 'arguments' => array('filterRules' => $ruleValues, 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND));
+ }
+
+ private function calculateTopTenValue($columnID, $startRow, $endRow, $ruleType, $ruleValue)
+ {
+ $range = $columnID.$startRow.':'.$columnID.$endRow;
+ $dataValues = PHPExcel_Calculation_Functions::flattenArray($this->workSheet->rangeToArray($range, null, true, false));
+
+ $dataValues = array_filter($dataValues);
+ if ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) {
+ rsort($dataValues);
+ } else {
+ sort($dataValues);
+ }
+
+ return array_pop(array_slice($dataValues, 0, $ruleValue));
+ }
+
+ /**
+ * Apply the AutoFilter rules to the AutoFilter Range
+ *
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_AutoFilter
+ */
+ public function showHideRows()
+ {
+ list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->range);
+
+ // The heading row should always be visible
+// echo 'AutoFilter Heading Row ', $rangeStart[1],' is always SHOWN',PHP_EOL;
+ $this->workSheet->getRowDimension($rangeStart[1])->setVisible(true);
+
+ $columnFilterTests = array();
+ foreach ($this->columns as $columnID => $filterColumn) {
+ $rules = $filterColumn->getRules();
+ switch ($filterColumn->getFilterType()) {
+ case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER:
+ $ruleValues = array();
+ // Build a list of the filter value selections
+ foreach ($rules as $rule) {
+ $ruleType = $rule->getRuleType();
+ $ruleValues[] = $rule->getValue();
+ }
+ // Test if we want to include blanks in our filter criteria
+ $blanks = false;
+ $ruleDataSet = array_filter($ruleValues);
+ if (count($ruleValues) != count($ruleDataSet)) {
+ $blanks = true;
+ }
+ if ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER) {
+ // Filter on absolute values
+ $columnFilterTests[$columnID] = array(
+ 'method' => 'filterTestInSimpleDataSet',
+ 'arguments' => array('filterValues' => $ruleDataSet, 'blanks' => $blanks)
+ );
+ } else {
+ // Filter on date group values
+ $arguments = array(
+ 'date' => array(),
+ 'time' => array(),
+ 'dateTime' => array(),
+ );
+ foreach ($ruleDataSet as $ruleValue) {
+ $date = $time = '';
+ if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR])) &&
+ ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR] !== '')) {
+ $date .= sprintf('%04d', $ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR]);
+ }
+ if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH])) &&
+ ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH] != '')) {
+ $date .= sprintf('%02d', $ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH]);
+ }
+ if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY])) &&
+ ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY] !== '')) {
+ $date .= sprintf('%02d', $ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY]);
+ }
+ if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR])) &&
+ ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR] !== '')) {
+ $time .= sprintf('%02d', $ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR]);
+ }
+ if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE])) &&
+ ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE] !== '')) {
+ $time .= sprintf('%02d', $ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE]);
+ }
+ if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND])) &&
+ ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND] !== '')) {
+ $time .= sprintf('%02d', $ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND]);
+ }
+ $dateTime = $date . $time;
+ $arguments['date'][] = $date;
+ $arguments['time'][] = $time;
+ $arguments['dateTime'][] = $dateTime;
+ }
+ // Remove empty elements
+ $arguments['date'] = array_filter($arguments['date']);
+ $arguments['time'] = array_filter($arguments['time']);
+ $arguments['dateTime'] = array_filter($arguments['dateTime']);
+ $columnFilterTests[$columnID] = array(
+ 'method' => 'filterTestInDateGroupSet',
+ 'arguments' => array('filterValues' => $arguments, 'blanks' => $blanks)
+ );
+ }
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER:
+ $customRuleForBlanks = false;
+ $ruleValues = array();
+ // Build a list of the filter value selections
+ foreach ($rules as $rule) {
+ $ruleType = $rule->getRuleType();
+ $ruleValue = $rule->getValue();
+ if (!is_numeric($ruleValue)) {
+ // Convert to a regexp allowing for regexp reserved characters, wildcards and escaped wildcards
+ $ruleValue = preg_quote($ruleValue);
+ $ruleValue = str_replace(self::$fromReplace, self::$toReplace, $ruleValue);
+ if (trim($ruleValue) == '') {
+ $customRuleForBlanks = true;
+ $ruleValue = trim($ruleValue);
+ }
+ }
+ $ruleValues[] = array('operator' => $rule->getOperator(), 'value' => $ruleValue);
+ }
+ $join = $filterColumn->getJoin();
+ $columnFilterTests[$columnID] = array(
+ 'method' => 'filterTestInCustomDataSet',
+ 'arguments' => array('filterRules' => $ruleValues, 'join' => $join, 'customRuleForBlanks' => $customRuleForBlanks)
+ );
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER:
+ $ruleValues = array();
+ foreach ($rules as $rule) {
+ // We should only ever have one Dynamic Filter Rule anyway
+ $dynamicRuleType = $rule->getGrouping();
+ if (($dynamicRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) ||
+ ($dynamicRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE)) {
+ // Number (Average) based
+ // Calculate the average
+ $averageFormula = '=AVERAGE('.$columnID.($rangeStart[1]+1).':'.$columnID.$rangeEnd[1].')';
+ $average = PHPExcel_Calculation::getInstance()->calculateFormula($averageFormula, null, $this->workSheet->getCell('A1'));
+ // Set above/below rule based on greaterThan or LessTan
+ $operator = ($dynamicRuleType === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE)
+ ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN
+ : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN;
+ $ruleValues[] = array('operator' => $operator,
+ 'value' => $average
+ );
+ $columnFilterTests[$columnID] = array(
+ 'method' => 'filterTestInCustomDataSet',
+ 'arguments' => array('filterRules' => $ruleValues, 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR)
+ );
+ } else {
+ // Date based
+ if ($dynamicRuleType{0} == 'M' || $dynamicRuleType{0} == 'Q') {
+ // Month or Quarter
+ sscanf($dynamicRuleType, '%[A-Z]%d', $periodType, $period);
+ if ($periodType == 'M') {
+ $ruleValues = array($period);
+ } else {
+ --$period;
+ $periodEnd = (1+$period)*3;
+ $periodStart = 1+$period*3;
+ $ruleValues = range($periodStart, $periodEnd);
+ }
+ $columnFilterTests[$columnID] = array(
+ 'method' => 'filterTestInPeriodDateSet',
+ 'arguments' => $ruleValues
+ );
+ $filterColumn->setAttributes(array());
+ } else {
+ // Date Range
+ $columnFilterTests[$columnID] = $this->dynamicFilterDateRange($dynamicRuleType, $filterColumn);
+ break;
+ }
+ }
+ }
+ break;
+ case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER:
+ $ruleValues = array();
+ $dataRowCount = $rangeEnd[1] - $rangeStart[1];
+ foreach ($rules as $rule) {
+ // We should only ever have one Dynamic Filter Rule anyway
+ $toptenRuleType = $rule->getGrouping();
+ $ruleValue = $rule->getValue();
+ $ruleOperator = $rule->getOperator();
+ }
+ if ($ruleOperator === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) {
+ $ruleValue = floor($ruleValue * ($dataRowCount / 100));
+ }
+ if ($ruleValue < 1) {
+ $ruleValue = 1;
+ }
+ if ($ruleValue > 500) {
+ $ruleValue = 500;
+ }
+
+ $maxVal = $this->calculateTopTenValue($columnID, $rangeStart[1]+1, $rangeEnd[1], $toptenRuleType, $ruleValue);
+
+ $operator = ($toptenRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP)
+ ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL
+ : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL;
+ $ruleValues[] = array('operator' => $operator, 'value' => $maxVal);
+ $columnFilterTests[$columnID] = array(
+ 'method' => 'filterTestInCustomDataSet',
+ 'arguments' => array('filterRules' => $ruleValues, 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR)
+ );
+ $filterColumn->setAttributes(array('maxVal' => $maxVal));
+ break;
+ }
+ }
+
+// echo 'Column Filter Test CRITERIA',PHP_EOL;
+// var_dump($columnFilterTests);
+//
+ // Execute the column tests for each row in the autoFilter range to determine show/hide,
+ for ($row = $rangeStart[1]+1; $row <= $rangeEnd[1]; ++$row) {
+// echo 'Testing Row = ', $row,PHP_EOL;
+ $result = true;
+ foreach ($columnFilterTests as $columnID => $columnFilterTest) {
+// echo 'Testing cell ', $columnID.$row,PHP_EOL;
+ $cellValue = $this->workSheet->getCell($columnID.$row)->getCalculatedValue();
+// echo 'Value is ', $cellValue,PHP_EOL;
+ // Execute the filter test
+ $result = $result &&
+ call_user_func_array(
+ array('PHPExcel_Worksheet_AutoFilter', $columnFilterTest['method']),
+ array($cellValue, $columnFilterTest['arguments'])
+ );
+// echo (($result) ? 'VALID' : 'INVALID'),PHP_EOL;
+ // If filter test has resulted in FALSE, exit the loop straightaway rather than running any more tests
+ if (!$result) {
+ break;
+ }
+ }
+ // Set show/hide for the row based on the result of the autoFilter result
+// echo (($result) ? 'SHOW' : 'HIDE'),PHP_EOL;
+ $this->workSheet->getRowDimension($row)->setVisible($result);
+ }
+
+ return $this;
+ }
+
+
+ /**
+ * 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)) {
+ if ($key == 'workSheet') {
+ // Detach from worksheet
+ $this->{$key} = null;
+ } else {
+ $this->{$key} = clone $value;
+ }
+ } elseif ((is_array($value)) && ($key == 'columns')) {
+ // The columns array of PHPExcel_Worksheet_AutoFilter objects
+ $this->{$key} = array();
+ foreach ($value as $k => $v) {
+ $this->{$key}[$k] = clone $v;
+ // attach the new cloned Column to this new cloned Autofilter object
+ $this->{$key}[$k]->setParent($this);
+ }
+ } else {
+ $this->{$key} = $value;
+ }
+ }
+ }
+
+ /**
+ * toString method replicates previous behavior by returning the range if object is
+ * referenced as a property of its parent.
+ */
+ public function __toString()
+ {
+ return (string) $this->range;
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/AutoFilter/Column.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/AutoFilter/Column.php
new file mode 100755
index 000000000..d64fd8165
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/AutoFilter/Column.php
@@ -0,0 +1,405 @@
+columnIndex = $pColumn;
+ $this->parent = $pParent;
+ }
+
+ /**
+ * Get AutoFilter Column Index
+ *
+ * @return string
+ */
+ public function getColumnIndex()
+ {
+ return $this->columnIndex;
+ }
+
+ /**
+ * Set AutoFilter Column Index
+ *
+ * @param string $pColumn Column (e.g. A)
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_AutoFilter_Column
+ */
+ public function setColumnIndex($pColumn)
+ {
+ // Uppercase coordinate
+ $pColumn = strtoupper($pColumn);
+ if ($this->parent !== null) {
+ $this->parent->testColumnInRange($pColumn);
+ }
+
+ $this->columnIndex = $pColumn;
+
+ return $this;
+ }
+
+ /**
+ * Get this Column's AutoFilter Parent
+ *
+ * @return PHPExcel_Worksheet_AutoFilter
+ */
+ public function getParent()
+ {
+ return $this->parent;
+ }
+
+ /**
+ * Set this Column's AutoFilter Parent
+ *
+ * @param PHPExcel_Worksheet_AutoFilter
+ * @return PHPExcel_Worksheet_AutoFilter_Column
+ */
+ public function setParent(PHPExcel_Worksheet_AutoFilter $pParent = null)
+ {
+ $this->parent = $pParent;
+
+ return $this;
+ }
+
+ /**
+ * Get AutoFilter Type
+ *
+ * @return string
+ */
+ public function getFilterType()
+ {
+ return $this->filterType;
+ }
+
+ /**
+ * Set AutoFilter Type
+ *
+ * @param string $pFilterType
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_AutoFilter_Column
+ */
+ public function setFilterType($pFilterType = self::AUTOFILTER_FILTERTYPE_FILTER)
+ {
+ if (!in_array($pFilterType, self::$filterTypes)) {
+ throw new PHPExcel_Exception('Invalid filter type for column AutoFilter.');
+ }
+
+ $this->filterType = $pFilterType;
+
+ return $this;
+ }
+
+ /**
+ * Get AutoFilter Multiple Rules And/Or Join
+ *
+ * @return string
+ */
+ public function getJoin()
+ {
+ return $this->join;
+ }
+
+ /**
+ * Set AutoFilter Multiple Rules And/Or
+ *
+ * @param string $pJoin And/Or
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_AutoFilter_Column
+ */
+ public function setJoin($pJoin = self::AUTOFILTER_COLUMN_JOIN_OR)
+ {
+ // Lowercase And/Or
+ $pJoin = strtolower($pJoin);
+ if (!in_array($pJoin, self::$ruleJoins)) {
+ throw new PHPExcel_Exception('Invalid rule connection for column AutoFilter.');
+ }
+
+ $this->join = $pJoin;
+
+ return $this;
+ }
+
+ /**
+ * Set AutoFilter Attributes
+ *
+ * @param string[] $pAttributes
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_AutoFilter_Column
+ */
+ public function setAttributes($pAttributes = array())
+ {
+ $this->attributes = $pAttributes;
+
+ return $this;
+ }
+
+ /**
+ * Set An AutoFilter Attribute
+ *
+ * @param string $pName Attribute Name
+ * @param string $pValue Attribute Value
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_AutoFilter_Column
+ */
+ public function setAttribute($pName, $pValue)
+ {
+ $this->attributes[$pName] = $pValue;
+
+ return $this;
+ }
+
+ /**
+ * Get AutoFilter Column Attributes
+ *
+ * @return string
+ */
+ public function getAttributes()
+ {
+ return $this->attributes;
+ }
+
+ /**
+ * Get specific AutoFilter Column Attribute
+ *
+ * @param string $pName Attribute Name
+ * @return string
+ */
+ public function getAttribute($pName)
+ {
+ if (isset($this->attributes[$pName])) {
+ return $this->attributes[$pName];
+ }
+ return null;
+ }
+
+ /**
+ * Get all AutoFilter Column Rules
+ *
+ * @throws PHPExcel_Exception
+ * @return array of PHPExcel_Worksheet_AutoFilter_Column_Rule
+ */
+ public function getRules()
+ {
+ return $this->ruleset;
+ }
+
+ /**
+ * Get a specified AutoFilter Column Rule
+ *
+ * @param integer $pIndex Rule index in the ruleset array
+ * @return PHPExcel_Worksheet_AutoFilter_Column_Rule
+ */
+ public function getRule($pIndex)
+ {
+ if (!isset($this->ruleset[$pIndex])) {
+ $this->ruleset[$pIndex] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this);
+ }
+ return $this->ruleset[$pIndex];
+ }
+
+ /**
+ * Create a new AutoFilter Column Rule in the ruleset
+ *
+ * @return PHPExcel_Worksheet_AutoFilter_Column_Rule
+ */
+ public function createRule()
+ {
+ $this->ruleset[] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this);
+
+ return end($this->ruleset);
+ }
+
+ /**
+ * Add a new AutoFilter Column Rule to the ruleset
+ *
+ * @param PHPExcel_Worksheet_AutoFilter_Column_Rule $pRule
+ * @param boolean $returnRule Flag indicating whether the rule object or the column object should be returned
+ * @return PHPExcel_Worksheet_AutoFilter_Column|PHPExcel_Worksheet_AutoFilter_Column_Rule
+ */
+ public function addRule(PHPExcel_Worksheet_AutoFilter_Column_Rule $pRule, $returnRule = true)
+ {
+ $pRule->setParent($this);
+ $this->ruleset[] = $pRule;
+
+ return ($returnRule) ? $pRule : $this;
+ }
+
+ /**
+ * Delete a specified AutoFilter Column Rule
+ * If the number of rules is reduced to 1, then we reset And/Or logic to Or
+ *
+ * @param integer $pIndex Rule index in the ruleset array
+ * @return PHPExcel_Worksheet_AutoFilter_Column
+ */
+ public function deleteRule($pIndex)
+ {
+ if (isset($this->ruleset[$pIndex])) {
+ unset($this->ruleset[$pIndex]);
+ // If we've just deleted down to a single rule, then reset And/Or joining to Or
+ if (count($this->ruleset) <= 1) {
+ $this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR);
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Delete all AutoFilter Column Rules
+ *
+ * @return PHPExcel_Worksheet_AutoFilter_Column
+ */
+ public function clearRules()
+ {
+ $this->ruleset = array();
+ $this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR);
+
+ return $this;
+ }
+
+ /**
+ * 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)) {
+ if ($key == 'parent') {
+ // Detach from autofilter parent
+ $this->$key = null;
+ } else {
+ $this->$key = clone $value;
+ }
+ } elseif ((is_array($value)) && ($key == 'ruleset')) {
+ // The columns array of PHPExcel_Worksheet_AutoFilter objects
+ $this->$key = array();
+ foreach ($value as $k => $v) {
+ $this->$key[$k] = clone $v;
+ // attach the new cloned Rule to this new cloned Autofilter Cloned object
+ $this->$key[$k]->setParent($this);
+ }
+ } else {
+ $this->$key = $value;
+ }
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php
new file mode 100755
index 000000000..39ad18bf3
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php
@@ -0,0 +1,468 @@
+
+ *
+ * $objDrawing->setResizeProportional(true);
+ * $objDrawing->setWidthAndHeight(160,120);
+ *
+ *
+ * @author Vincent@luo MSN:kele_100@hotmail.com
+ * @param int $width
+ * @param int $height
+ * @return PHPExcel_Worksheet_BaseDrawing
+ */
+ public function setWidthAndHeight($width = 0, $height = 0)
+ {
+ $xratio = $width / ($this->width != 0 ? $this->width : 1);
+ $yratio = $height / ($this->height != 0 ? $this->height : 1);
+ if ($this->resizeProportional && !($width == 0 || $height == 0)) {
+ if (($xratio * $this->height) < $height) {
+ $this->height = ceil($xratio * $this->height);
+ $this->width = $width;
+ } else {
+ $this->width = ceil($yratio * $this->width);
+ $this->height = $height;
+ }
+ } else {
+ $this->width = $width;
+ $this->height = $height;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get ResizeProportional
+ *
+ * @return boolean
+ */
+ public function getResizeProportional()
+ {
+ return $this->resizeProportional;
+ }
+
+ /**
+ * Set ResizeProportional
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_BaseDrawing
+ */
+ public function setResizeProportional($pValue = true)
+ {
+ $this->resizeProportional = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Rotation
+ *
+ * @return int
+ */
+ public function getRotation()
+ {
+ return $this->rotation;
+ }
+
+ /**
+ * Set Rotation
+ *
+ * @param int $pValue
+ * @return PHPExcel_Worksheet_BaseDrawing
+ */
+ public function setRotation($pValue = 0)
+ {
+ $this->rotation = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Shadow
+ *
+ * @return PHPExcel_Worksheet_Drawing_Shadow
+ */
+ public function getShadow()
+ {
+ return $this->shadow;
+ }
+
+ /**
+ * Set Shadow
+ *
+ * @param PHPExcel_Worksheet_Drawing_Shadow $pValue
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_BaseDrawing
+ */
+ public function setShadow(PHPExcel_Worksheet_Drawing_Shadow $pValue = null)
+ {
+ $this->shadow = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get hash code
+ *
+ * @return string Hash code
+ */
+ public function getHashCode()
+ {
+ return md5(
+ $this->name .
+ $this->description .
+ $this->worksheet->getHashCode() .
+ $this->coordinates .
+ $this->offsetX .
+ $this->offsetY .
+ $this->width .
+ $this->height .
+ $this->rotation .
+ $this->shadow->getHashCode() .
+ __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) {
+ if (is_object($value)) {
+ $this->$key = clone $value;
+ } else {
+ $this->$key = $value;
+ }
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/CellIterator.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/CellIterator.php
new file mode 100755
index 000000000..53cf7bf31
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/CellIterator.php
@@ -0,0 +1,88 @@
+subject);
+ }
+
+ /**
+ * Get loop only existing cells
+ *
+ * @return boolean
+ */
+ public function getIterateOnlyExistingCells()
+ {
+ return $this->onlyExistingCells;
+ }
+
+ /**
+ * Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary
+ *
+ * @throws PHPExcel_Exception
+ */
+ abstract protected function adjustForExistingOnlyRange();
+
+ /**
+ * Set the iterator to loop only existing cells
+ *
+ * @param boolean $value
+ * @throws PHPExcel_Exception
+ */
+ public function setIterateOnlyExistingCells($value = true)
+ {
+ $this->onlyExistingCells = (boolean) $value;
+
+ $this->adjustForExistingOnlyRange();
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Column.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Column.php
new file mode 100755
index 000000000..6d3f36d17
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Column.php
@@ -0,0 +1,86 @@
+parent = $parent;
+ $this->columnIndex = $columnIndex;
+ }
+
+ /**
+ * Destructor
+ */
+ public function __destruct()
+ {
+ unset($this->parent);
+ }
+
+ /**
+ * Get column index
+ *
+ * @return string
+ */
+ public function getColumnIndex()
+ {
+ return $this->columnIndex;
+ }
+
+ /**
+ * Get cell iterator
+ *
+ * @param integer $startRow The row number at which to start iterating
+ * @param integer $endRow Optionally, the row number at which to stop iterating
+ * @return PHPExcel_Worksheet_CellIterator
+ */
+ public function getCellIterator($startRow = 1, $endRow = null)
+ {
+ return new PHPExcel_Worksheet_ColumnCellIterator($this->parent, $this->columnIndex, $startRow, $endRow);
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/ColumnCellIterator.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/ColumnCellIterator.php
new file mode 100755
index 000000000..7b8c2190a
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/ColumnCellIterator.php
@@ -0,0 +1,216 @@
+subject = $subject;
+ $this->columnIndex = PHPExcel_Cell::columnIndexFromString($columnIndex) - 1;
+ $this->resetEnd($endRow);
+ $this->resetStart($startRow);
+ }
+
+ /**
+ * Destructor
+ */
+ public function __destruct()
+ {
+ unset($this->subject);
+ }
+
+ /**
+ * (Re)Set the start row and the current row pointer
+ *
+ * @param integer $startRow The row number at which to start iterating
+ * @return PHPExcel_Worksheet_ColumnCellIterator
+ * @throws PHPExcel_Exception
+ */
+ public function resetStart($startRow = 1)
+ {
+ $this->startRow = $startRow;
+ $this->adjustForExistingOnlyRange();
+ $this->seek($startRow);
+
+ return $this;
+ }
+
+ /**
+ * (Re)Set the end row
+ *
+ * @param integer $endRow The row number at which to stop iterating
+ * @return PHPExcel_Worksheet_ColumnCellIterator
+ * @throws PHPExcel_Exception
+ */
+ public function resetEnd($endRow = null)
+ {
+ $this->endRow = ($endRow) ? $endRow : $this->subject->getHighestRow();
+ $this->adjustForExistingOnlyRange();
+
+ return $this;
+ }
+
+ /**
+ * Set the row pointer to the selected row
+ *
+ * @param integer $row The row number to set the current pointer at
+ * @return PHPExcel_Worksheet_ColumnCellIterator
+ * @throws PHPExcel_Exception
+ */
+ public function seek($row = 1)
+ {
+ if (($row < $this->startRow) || ($row > $this->endRow)) {
+ throw new PHPExcel_Exception("Row $row is out of range ({$this->startRow} - {$this->endRow})");
+ } elseif ($this->onlyExistingCells && !($this->subject->cellExistsByColumnAndRow($this->columnIndex, $row))) {
+ throw new PHPExcel_Exception('In "IterateOnlyExistingCells" mode and Cell does not exist');
+ }
+ $this->position = $row;
+
+ return $this;
+ }
+
+ /**
+ * Rewind the iterator to the starting row
+ */
+ public function rewind()
+ {
+ $this->position = $this->startRow;
+ }
+
+ /**
+ * Return the current cell in this worksheet column
+ *
+ * @return PHPExcel_Worksheet_Row
+ */
+ public function current()
+ {
+ return $this->subject->getCellByColumnAndRow($this->columnIndex, $this->position);
+ }
+
+ /**
+ * Return the current iterator key
+ *
+ * @return int
+ */
+ public function key()
+ {
+ return $this->position;
+ }
+
+ /**
+ * Set the iterator to its next value
+ */
+ public function next()
+ {
+ do {
+ ++$this->position;
+ } while (($this->onlyExistingCells) &&
+ (!$this->subject->cellExistsByColumnAndRow($this->columnIndex, $this->position)) &&
+ ($this->position <= $this->endRow));
+ }
+
+ /**
+ * Set the iterator to its previous value
+ */
+ public function prev()
+ {
+ if ($this->position <= $this->startRow) {
+ throw new PHPExcel_Exception("Row is already at the beginning of range ({$this->startRow} - {$this->endRow})");
+ }
+
+ do {
+ --$this->position;
+ } while (($this->onlyExistingCells) &&
+ (!$this->subject->cellExistsByColumnAndRow($this->columnIndex, $this->position)) &&
+ ($this->position >= $this->startRow));
+ }
+
+ /**
+ * Indicate if more rows exist in the worksheet range of rows that we're iterating
+ *
+ * @return boolean
+ */
+ public function valid()
+ {
+ return $this->position <= $this->endRow;
+ }
+
+ /**
+ * Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary
+ *
+ * @throws PHPExcel_Exception
+ */
+ protected function adjustForExistingOnlyRange()
+ {
+ if ($this->onlyExistingCells) {
+ while ((!$this->subject->cellExistsByColumnAndRow($this->columnIndex, $this->startRow)) &&
+ ($this->startRow <= $this->endRow)) {
+ ++$this->startRow;
+ }
+ if ($this->startRow > $this->endRow) {
+ throw new PHPExcel_Exception('No cells exist within the specified range');
+ }
+ while ((!$this->subject->cellExistsByColumnAndRow($this->columnIndex, $this->endRow)) &&
+ ($this->endRow >= $this->startRow)) {
+ --$this->endRow;
+ }
+ if ($this->endRow < $this->startRow) {
+ throw new PHPExcel_Exception('No cells exist within the specified range');
+ }
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/ColumnDimension.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/ColumnDimension.php
new file mode 100755
index 000000000..405b8258e
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/ColumnDimension.php
@@ -0,0 +1,132 @@
+columnIndex = $pIndex;
+
+ // set dimension as unformatted by default
+ parent::__construct(0);
+ }
+
+ /**
+ * Get ColumnIndex
+ *
+ * @return string
+ */
+ public function getColumnIndex()
+ {
+ return $this->columnIndex;
+ }
+
+ /**
+ * Set ColumnIndex
+ *
+ * @param string $pValue
+ * @return PHPExcel_Worksheet_ColumnDimension
+ */
+ public function setColumnIndex($pValue)
+ {
+ $this->columnIndex = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Width
+ *
+ * @return double
+ */
+ public function getWidth()
+ {
+ return $this->width;
+ }
+
+ /**
+ * Set Width
+ *
+ * @param double $pValue
+ * @return PHPExcel_Worksheet_ColumnDimension
+ */
+ public function setWidth($pValue = -1)
+ {
+ $this->width = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Auto Size
+ *
+ * @return bool
+ */
+ public function getAutoSize()
+ {
+ return $this->autoSize;
+ }
+
+ /**
+ * Set Auto Size
+ *
+ * @param bool $pValue
+ * @return PHPExcel_Worksheet_ColumnDimension
+ */
+ public function setAutoSize($pValue = false)
+ {
+ $this->autoSize = $pValue;
+ return $this;
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/ColumnIterator.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/ColumnIterator.php
new file mode 100755
index 000000000..0db3e5347
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/ColumnIterator.php
@@ -0,0 +1,201 @@
+subject = $subject;
+ $this->resetEnd($endColumn);
+ $this->resetStart($startColumn);
+ }
+
+ /**
+ * Destructor
+ */
+ public function __destruct()
+ {
+ unset($this->subject);
+ }
+
+ /**
+ * (Re)Set the start column and the current column pointer
+ *
+ * @param integer $startColumn The column address at which to start iterating
+ * @return PHPExcel_Worksheet_ColumnIterator
+ * @throws PHPExcel_Exception
+ */
+ public function resetStart($startColumn = 'A')
+ {
+ $startColumnIndex = PHPExcel_Cell::columnIndexFromString($startColumn) - 1;
+ if ($startColumnIndex > PHPExcel_Cell::columnIndexFromString($this->subject->getHighestColumn()) - 1) {
+ throw new PHPExcel_Exception("Start column ({$startColumn}) is beyond highest column ({$this->subject->getHighestColumn()})");
+ }
+
+ $this->startColumn = $startColumnIndex;
+ if ($this->endColumn < $this->startColumn) {
+ $this->endColumn = $this->startColumn;
+ }
+ $this->seek($startColumn);
+
+ return $this;
+ }
+
+ /**
+ * (Re)Set the end column
+ *
+ * @param string $endColumn The column address at which to stop iterating
+ * @return PHPExcel_Worksheet_ColumnIterator
+ */
+ public function resetEnd($endColumn = null)
+ {
+ $endColumn = ($endColumn) ? $endColumn : $this->subject->getHighestColumn();
+ $this->endColumn = PHPExcel_Cell::columnIndexFromString($endColumn) - 1;
+
+ return $this;
+ }
+
+ /**
+ * Set the column pointer to the selected column
+ *
+ * @param string $column The column address to set the current pointer at
+ * @return PHPExcel_Worksheet_ColumnIterator
+ * @throws PHPExcel_Exception
+ */
+ public function seek($column = 'A')
+ {
+ $column = PHPExcel_Cell::columnIndexFromString($column) - 1;
+ if (($column < $this->startColumn) || ($column > $this->endColumn)) {
+ throw new PHPExcel_Exception("Column $column is out of range ({$this->startColumn} - {$this->endColumn})");
+ }
+ $this->position = $column;
+
+ return $this;
+ }
+
+ /**
+ * Rewind the iterator to the starting column
+ */
+ public function rewind()
+ {
+ $this->position = $this->startColumn;
+ }
+
+ /**
+ * Return the current column in this worksheet
+ *
+ * @return PHPExcel_Worksheet_Column
+ */
+ public function current()
+ {
+ return new PHPExcel_Worksheet_Column($this->subject, PHPExcel_Cell::stringFromColumnIndex($this->position));
+ }
+
+ /**
+ * Return the current iterator key
+ *
+ * @return string
+ */
+ public function key()
+ {
+ return PHPExcel_Cell::stringFromColumnIndex($this->position);
+ }
+
+ /**
+ * Set the iterator to its next value
+ */
+ public function next()
+ {
+ ++$this->position;
+ }
+
+ /**
+ * Set the iterator to its previous value
+ *
+ * @throws PHPExcel_Exception
+ */
+ public function prev()
+ {
+ if ($this->position <= $this->startColumn) {
+ throw new PHPExcel_Exception(
+ "Column is already at the beginning of range (" .
+ PHPExcel_Cell::stringFromColumnIndex($this->endColumn) . " - " .
+ PHPExcel_Cell::stringFromColumnIndex($this->endColumn) . ")"
+ );
+ }
+
+ --$this->position;
+ }
+
+ /**
+ * Indicate if more columns exist in the worksheet range of columns that we're iterating
+ *
+ * @return boolean
+ */
+ public function valid()
+ {
+ return $this->position <= $this->endColumn;
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Dimension.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Dimension.php
new file mode 100755
index 000000000..84f692cb5
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Dimension.php
@@ -0,0 +1,178 @@
+xfIndex = $initialValue;
+ }
+
+ /**
+ * Get Visible
+ *
+ * @return bool
+ */
+ public function getVisible()
+ {
+ return $this->visible;
+ }
+
+ /**
+ * Set Visible
+ *
+ * @param bool $pValue
+ * @return PHPExcel_Worksheet_Dimension
+ */
+ public function setVisible($pValue = true)
+ {
+ $this->visible = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Outline Level
+ *
+ * @return int
+ */
+ public function getOutlineLevel()
+ {
+ return $this->outlineLevel;
+ }
+
+ /**
+ * Set Outline Level
+ *
+ * Value must be between 0 and 7
+ *
+ * @param int $pValue
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_Dimension
+ */
+ public function setOutlineLevel($pValue)
+ {
+ if ($pValue < 0 || $pValue > 7) {
+ throw new PHPExcel_Exception("Outline level must range between 0 and 7.");
+ }
+
+ $this->outlineLevel = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Collapsed
+ *
+ * @return bool
+ */
+ public function getCollapsed()
+ {
+ return $this->collapsed;
+ }
+
+ /**
+ * Set Collapsed
+ *
+ * @param bool $pValue
+ * @return PHPExcel_Worksheet_Dimension
+ */
+ public function setCollapsed($pValue = true)
+ {
+ $this->collapsed = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get index to cellXf
+ *
+ * @return int
+ */
+ public function getXfIndex()
+ {
+ return $this->xfIndex;
+ }
+
+ /**
+ * Set index to cellXf
+ *
+ * @param int $pValue
+ * @return PHPExcel_Worksheet_Dimension
+ */
+ public function setXfIndex($pValue = 0)
+ {
+ $this->xfIndex = $pValue;
+ return $this;
+ }
+
+ /**
+ * 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;
+ }
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Drawing.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Drawing.php
new file mode 100755
index 000000000..e39d3eb91
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Drawing.php
@@ -0,0 +1,147 @@
+path = '';
+
+ // Initialize parent
+ parent::__construct();
+ }
+
+ /**
+ * Get Filename
+ *
+ * @return string
+ */
+ public function getFilename()
+ {
+ return basename($this->path);
+ }
+
+ /**
+ * Get indexed filename (using image index)
+ *
+ * @return string
+ */
+ public function getIndexedFilename()
+ {
+ $fileName = $this->getFilename();
+ $fileName = str_replace(' ', '_', $fileName);
+ return str_replace('.' . $this->getExtension(), '', $fileName) . $this->getImageIndex() . '.' . $this->getExtension();
+ }
+
+ /**
+ * Get Extension
+ *
+ * @return string
+ */
+ public function getExtension()
+ {
+ $exploded = explode(".", basename($this->path));
+ return $exploded[count($exploded) - 1];
+ }
+
+ /**
+ * Get Path
+ *
+ * @return string
+ */
+ public function getPath()
+ {
+ return $this->path;
+ }
+
+ /**
+ * Set Path
+ *
+ * @param string $pValue File path
+ * @param boolean $pVerifyFile Verify file
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_Drawing
+ */
+ public function setPath($pValue = '', $pVerifyFile = true)
+ {
+ if ($pVerifyFile) {
+ if (file_exists($pValue)) {
+ $this->path = $pValue;
+
+ if ($this->width == 0 && $this->height == 0) {
+ // Get width/height
+ list($this->width, $this->height) = getimagesize($pValue);
+ }
+ } else {
+ throw new PHPExcel_Exception("File $pValue not found!");
+ }
+ } else {
+ $this->path = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get hash code
+ *
+ * @return string Hash code
+ */
+ public function getHashCode()
+ {
+ return md5(
+ $this->path .
+ parent::getHashCode() .
+ __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) {
+ if (is_object($value)) {
+ $this->$key = clone $value;
+ } else {
+ $this->$key = $value;
+ }
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Drawing/Shadow.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Drawing/Shadow.php
new file mode 100755
index 000000000..84db91d57
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Drawing/Shadow.php
@@ -0,0 +1,296 @@
+visible = false;
+ $this->blurRadius = 6;
+ $this->distance = 2;
+ $this->direction = 0;
+ $this->alignment = PHPExcel_Worksheet_Drawing_Shadow::SHADOW_BOTTOM_RIGHT;
+ $this->color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK);
+ $this->alpha = 50;
+ }
+
+ /**
+ * Get Visible
+ *
+ * @return boolean
+ */
+ public function getVisible()
+ {
+ return $this->visible;
+ }
+
+ /**
+ * Set Visible
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_Drawing_Shadow
+ */
+ public function setVisible($pValue = false)
+ {
+ $this->visible = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Blur radius
+ *
+ * @return int
+ */
+ public function getBlurRadius()
+ {
+ return $this->blurRadius;
+ }
+
+ /**
+ * Set Blur radius
+ *
+ * @param int $pValue
+ * @return PHPExcel_Worksheet_Drawing_Shadow
+ */
+ public function setBlurRadius($pValue = 6)
+ {
+ $this->blurRadius = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Shadow distance
+ *
+ * @return int
+ */
+ public function getDistance()
+ {
+ return $this->distance;
+ }
+
+ /**
+ * Set Shadow distance
+ *
+ * @param int $pValue
+ * @return PHPExcel_Worksheet_Drawing_Shadow
+ */
+ public function setDistance($pValue = 2)
+ {
+ $this->distance = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Shadow direction (in degrees)
+ *
+ * @return int
+ */
+ public function getDirection()
+ {
+ return $this->direction;
+ }
+
+ /**
+ * Set Shadow direction (in degrees)
+ *
+ * @param int $pValue
+ * @return PHPExcel_Worksheet_Drawing_Shadow
+ */
+ public function setDirection($pValue = 0)
+ {
+ $this->direction = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Shadow alignment
+ *
+ * @return int
+ */
+ public function getAlignment()
+ {
+ return $this->alignment;
+ }
+
+ /**
+ * Set Shadow alignment
+ *
+ * @param int $pValue
+ * @return PHPExcel_Worksheet_Drawing_Shadow
+ */
+ public function setAlignment($pValue = 0)
+ {
+ $this->alignment = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Color
+ *
+ * @return PHPExcel_Style_Color
+ */
+ public function getColor()
+ {
+ return $this->color;
+ }
+
+ /**
+ * Set Color
+ *
+ * @param PHPExcel_Style_Color $pValue
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_Drawing_Shadow
+ */
+ public function setColor(PHPExcel_Style_Color $pValue = null)
+ {
+ $this->color = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Alpha
+ *
+ * @return int
+ */
+ public function getAlpha()
+ {
+ return $this->alpha;
+ }
+
+ /**
+ * Set Alpha
+ *
+ * @param int $pValue
+ * @return PHPExcel_Worksheet_Drawing_Shadow
+ */
+ public function setAlpha($pValue = 0)
+ {
+ $this->alpha = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get hash code
+ *
+ * @return string Hash code
+ */
+ public function getHashCode()
+ {
+ return md5(
+ ($this->visible ? 't' : 'f') .
+ $this->blurRadius .
+ $this->distance .
+ $this->direction .
+ $this->alignment .
+ $this->color->getHashCode() .
+ $this->alpha .
+ __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) {
+ if (is_object($value)) {
+ $this->$key = clone $value;
+ } else {
+ $this->$key = $value;
+ }
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/HeaderFooter.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/HeaderFooter.php
new file mode 100755
index 000000000..3a88923fc
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/HeaderFooter.php
@@ -0,0 +1,494 @@
+
+ * Header/Footer Formatting Syntax taken from Office Open XML Part 4 - Markup Language Reference, page 1970:
+ *
+ * There are a number of formatting codes that can be written inline with the actual header / footer text, which
+ * affect the formatting in the header or footer.
+ *
+ * Example: This example shows the text "Center Bold Header" on the first line (center section), and the date on
+ * the second line (center section).
+ * &CCenter &"-,Bold"Bold&"-,Regular"Header_x000A_&D
+ *
+ * General Rules:
+ * There is no required order in which these codes must appear.
+ *
+ * The first occurrence of the following codes turns the formatting ON, the second occurrence turns it OFF again:
+ * - strikethrough
+ * - superscript
+ * - subscript
+ * Superscript and subscript cannot both be ON at same time. Whichever comes first wins and the other is ignored,
+ * while the first is ON.
+ * &L - code for "left section" (there are three header / footer locations, "left", "center", and "right"). When
+ * two or more occurrences of this section marker exist, the contents from all markers are concatenated, in the
+ * order of appearance, and placed into the left section.
+ * &P - code for "current page #"
+ * &N - code for "total pages"
+ * &font size - code for "text font size", where font size is a font size in points.
+ * &K - code for "text font color"
+ * RGB Color is specified as RRGGBB
+ * Theme Color is specifed as TTSNN where TT is the theme color Id, S is either "+" or "-" of the tint/shade
+ * value, NN is the tint/shade value.
+ * &S - code for "text strikethrough" on / off
+ * &X - code for "text super script" on / off
+ * &Y - code for "text subscript" on / off
+ * &C - code for "center section". When two or more occurrences of this section marker exist, the contents
+ * from all markers are concatenated, in the order of appearance, and placed into the center section.
+ *
+ * &D - code for "date"
+ * &T - code for "time"
+ * &G - code for "picture as background"
+ * &U - code for "text single underline"
+ * &E - code for "double underline"
+ * &R - code for "right section". When two or more occurrences of this section marker exist, the contents
+ * from all markers are concatenated, in the order of appearance, and placed into the right section.
+ * &Z - code for "this workbook's file path"
+ * &F - code for "this workbook's file name"
+ * &A - code for "sheet tab name"
+ * &+ - code for add to page #.
+ * &- - code for subtract from page #.
+ * &"font name,font type" - code for "text font name" and "text font type", where font name and font type
+ * are strings specifying the name and type of the font, separated by a comma. When a hyphen appears in font
+ * name, it means "none specified". Both of font name and font type can be localized values.
+ * &"-,Bold" - code for "bold font style"
+ * &B - also means "bold font style".
+ * &"-,Regular" - code for "regular font style"
+ * &"-,Italic" - code for "italic font style"
+ * &I - also means "italic font style"
+ * &"-,Bold Italic" code for "bold italic font style"
+ * &O - code for "outline style"
+ * &H - code for "shadow style"
+ *
+ *
+ */
+class PHPExcel_Worksheet_HeaderFooter
+{
+ /* Header/footer image location */
+ const IMAGE_HEADER_LEFT = 'LH';
+ const IMAGE_HEADER_CENTER = 'CH';
+ const IMAGE_HEADER_RIGHT = 'RH';
+ const IMAGE_FOOTER_LEFT = 'LF';
+ const IMAGE_FOOTER_CENTER = 'CF';
+ const IMAGE_FOOTER_RIGHT = 'RF';
+
+ /**
+ * OddHeader
+ *
+ * @var string
+ */
+ private $oddHeader = '';
+
+ /**
+ * OddFooter
+ *
+ * @var string
+ */
+ private $oddFooter = '';
+
+ /**
+ * EvenHeader
+ *
+ * @var string
+ */
+ private $evenHeader = '';
+
+ /**
+ * EvenFooter
+ *
+ * @var string
+ */
+ private $evenFooter = '';
+
+ /**
+ * FirstHeader
+ *
+ * @var string
+ */
+ private $firstHeader = '';
+
+ /**
+ * FirstFooter
+ *
+ * @var string
+ */
+ private $firstFooter = '';
+
+ /**
+ * Different header for Odd/Even, defaults to false
+ *
+ * @var boolean
+ */
+ private $differentOddEven = false;
+
+ /**
+ * Different header for first page, defaults to false
+ *
+ * @var boolean
+ */
+ private $differentFirst = false;
+
+ /**
+ * Scale with document, defaults to true
+ *
+ * @var boolean
+ */
+ private $scaleWithDocument = true;
+
+ /**
+ * Align with margins, defaults to true
+ *
+ * @var boolean
+ */
+ private $alignWithMargins = true;
+
+ /**
+ * Header/footer images
+ *
+ * @var PHPExcel_Worksheet_HeaderFooterDrawing[]
+ */
+ private $headerFooterImages = array();
+
+ /**
+ * Create a new PHPExcel_Worksheet_HeaderFooter
+ */
+ public function __construct()
+ {
+ }
+
+ /**
+ * Get OddHeader
+ *
+ * @return string
+ */
+ public function getOddHeader()
+ {
+ return $this->oddHeader;
+ }
+
+ /**
+ * Set OddHeader
+ *
+ * @param string $pValue
+ * @return PHPExcel_Worksheet_HeaderFooter
+ */
+ public function setOddHeader($pValue)
+ {
+ $this->oddHeader = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get OddFooter
+ *
+ * @return string
+ */
+ public function getOddFooter()
+ {
+ return $this->oddFooter;
+ }
+
+ /**
+ * Set OddFooter
+ *
+ * @param string $pValue
+ * @return PHPExcel_Worksheet_HeaderFooter
+ */
+ public function setOddFooter($pValue)
+ {
+ $this->oddFooter = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get EvenHeader
+ *
+ * @return string
+ */
+ public function getEvenHeader()
+ {
+ return $this->evenHeader;
+ }
+
+ /**
+ * Set EvenHeader
+ *
+ * @param string $pValue
+ * @return PHPExcel_Worksheet_HeaderFooter
+ */
+ public function setEvenHeader($pValue)
+ {
+ $this->evenHeader = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get EvenFooter
+ *
+ * @return string
+ */
+ public function getEvenFooter()
+ {
+ return $this->evenFooter;
+ }
+
+ /**
+ * Set EvenFooter
+ *
+ * @param string $pValue
+ * @return PHPExcel_Worksheet_HeaderFooter
+ */
+ public function setEvenFooter($pValue)
+ {
+ $this->evenFooter = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get FirstHeader
+ *
+ * @return string
+ */
+ public function getFirstHeader()
+ {
+ return $this->firstHeader;
+ }
+
+ /**
+ * Set FirstHeader
+ *
+ * @param string $pValue
+ * @return PHPExcel_Worksheet_HeaderFooter
+ */
+ public function setFirstHeader($pValue)
+ {
+ $this->firstHeader = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get FirstFooter
+ *
+ * @return string
+ */
+ public function getFirstFooter()
+ {
+ return $this->firstFooter;
+ }
+
+ /**
+ * Set FirstFooter
+ *
+ * @param string $pValue
+ * @return PHPExcel_Worksheet_HeaderFooter
+ */
+ public function setFirstFooter($pValue)
+ {
+ $this->firstFooter = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get DifferentOddEven
+ *
+ * @return boolean
+ */
+ public function getDifferentOddEven()
+ {
+ return $this->differentOddEven;
+ }
+
+ /**
+ * Set DifferentOddEven
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_HeaderFooter
+ */
+ public function setDifferentOddEven($pValue = false)
+ {
+ $this->differentOddEven = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get DifferentFirst
+ *
+ * @return boolean
+ */
+ public function getDifferentFirst()
+ {
+ return $this->differentFirst;
+ }
+
+ /**
+ * Set DifferentFirst
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_HeaderFooter
+ */
+ public function setDifferentFirst($pValue = false)
+ {
+ $this->differentFirst = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get ScaleWithDocument
+ *
+ * @return boolean
+ */
+ public function getScaleWithDocument()
+ {
+ return $this->scaleWithDocument;
+ }
+
+ /**
+ * Set ScaleWithDocument
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_HeaderFooter
+ */
+ public function setScaleWithDocument($pValue = true)
+ {
+ $this->scaleWithDocument = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get AlignWithMargins
+ *
+ * @return boolean
+ */
+ public function getAlignWithMargins()
+ {
+ return $this->alignWithMargins;
+ }
+
+ /**
+ * Set AlignWithMargins
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_HeaderFooter
+ */
+ public function setAlignWithMargins($pValue = true)
+ {
+ $this->alignWithMargins = $pValue;
+ return $this;
+ }
+
+ /**
+ * Add header/footer image
+ *
+ * @param PHPExcel_Worksheet_HeaderFooterDrawing $image
+ * @param string $location
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_HeaderFooter
+ */
+ public function addImage(PHPExcel_Worksheet_HeaderFooterDrawing $image = null, $location = self::IMAGE_HEADER_LEFT)
+ {
+ $this->headerFooterImages[$location] = $image;
+ return $this;
+ }
+
+ /**
+ * Remove header/footer image
+ *
+ * @param string $location
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_HeaderFooter
+ */
+ public function removeImage($location = self::IMAGE_HEADER_LEFT)
+ {
+ if (isset($this->headerFooterImages[$location])) {
+ unset($this->headerFooterImages[$location]);
+ }
+ return $this;
+ }
+
+ /**
+ * Set header/footer images
+ *
+ * @param PHPExcel_Worksheet_HeaderFooterDrawing[] $images
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_HeaderFooter
+ */
+ public function setImages($images)
+ {
+ if (!is_array($images)) {
+ throw new PHPExcel_Exception('Invalid parameter!');
+ }
+
+ $this->headerFooterImages = $images;
+ return $this;
+ }
+
+ /**
+ * Get header/footer images
+ *
+ * @return PHPExcel_Worksheet_HeaderFooterDrawing[]
+ */
+ public function getImages()
+ {
+ // Sort array
+ $images = array();
+ if (isset($this->headerFooterImages[self::IMAGE_HEADER_LEFT])) {
+ $images[self::IMAGE_HEADER_LEFT] = $this->headerFooterImages[self::IMAGE_HEADER_LEFT];
+ }
+ if (isset($this->headerFooterImages[self::IMAGE_HEADER_CENTER])) {
+ $images[self::IMAGE_HEADER_CENTER] = $this->headerFooterImages[self::IMAGE_HEADER_CENTER];
+ }
+ if (isset($this->headerFooterImages[self::IMAGE_HEADER_RIGHT])) {
+ $images[self::IMAGE_HEADER_RIGHT] = $this->headerFooterImages[self::IMAGE_HEADER_RIGHT];
+ }
+ if (isset($this->headerFooterImages[self::IMAGE_FOOTER_LEFT])) {
+ $images[self::IMAGE_FOOTER_LEFT] = $this->headerFooterImages[self::IMAGE_FOOTER_LEFT];
+ }
+ if (isset($this->headerFooterImages[self::IMAGE_FOOTER_CENTER])) {
+ $images[self::IMAGE_FOOTER_CENTER] = $this->headerFooterImages[self::IMAGE_FOOTER_CENTER];
+ }
+ if (isset($this->headerFooterImages[self::IMAGE_FOOTER_RIGHT])) {
+ $images[self::IMAGE_FOOTER_RIGHT] = $this->headerFooterImages[self::IMAGE_FOOTER_RIGHT];
+ }
+ $this->headerFooterImages = $images;
+
+ return $this->headerFooterImages;
+ }
+
+ /**
+ * 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;
+ }
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php
new file mode 100755
index 000000000..a491f4ba6
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php
@@ -0,0 +1,361 @@
+path = '';
+ $this->name = '';
+ $this->offsetX = 0;
+ $this->offsetY = 0;
+ $this->width = 0;
+ $this->height = 0;
+ $this->resizeProportional = true;
+ }
+
+ /**
+ * Get Name
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Set Name
+ *
+ * @param string $pValue
+ * @return PHPExcel_Worksheet_HeaderFooterDrawing
+ */
+ public function setName($pValue = '')
+ {
+ $this->name = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get OffsetX
+ *
+ * @return int
+ */
+ public function getOffsetX()
+ {
+ return $this->offsetX;
+ }
+
+ /**
+ * Set OffsetX
+ *
+ * @param int $pValue
+ * @return PHPExcel_Worksheet_HeaderFooterDrawing
+ */
+ public function setOffsetX($pValue = 0)
+ {
+ $this->offsetX = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get OffsetY
+ *
+ * @return int
+ */
+ public function getOffsetY()
+ {
+ return $this->offsetY;
+ }
+
+ /**
+ * Set OffsetY
+ *
+ * @param int $pValue
+ * @return PHPExcel_Worksheet_HeaderFooterDrawing
+ */
+ public function setOffsetY($pValue = 0)
+ {
+ $this->offsetY = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Width
+ *
+ * @return int
+ */
+ public function getWidth()
+ {
+ return $this->width;
+ }
+
+ /**
+ * Set Width
+ *
+ * @param int $pValue
+ * @return PHPExcel_Worksheet_HeaderFooterDrawing
+ */
+ public function setWidth($pValue = 0)
+ {
+ // Resize proportional?
+ if ($this->resizeProportional && $pValue != 0) {
+ $ratio = $this->width / $this->height;
+ $this->height = round($ratio * $pValue);
+ }
+
+ // Set width
+ $this->width = $pValue;
+
+ return $this;
+ }
+
+ /**
+ * Get Height
+ *
+ * @return int
+ */
+ public function getHeight()
+ {
+ return $this->height;
+ }
+
+ /**
+ * Set Height
+ *
+ * @param int $pValue
+ * @return PHPExcel_Worksheet_HeaderFooterDrawing
+ */
+ public function setHeight($pValue = 0)
+ {
+ // Resize proportional?
+ if ($this->resizeProportional && $pValue != 0) {
+ $ratio = $this->width / $this->height;
+ $this->width = round($ratio * $pValue);
+ }
+
+ // Set height
+ $this->height = $pValue;
+
+ return $this;
+ }
+
+ /**
+ * Set width and height with proportional resize
+ * Example:
+ *
+ * $objDrawing->setResizeProportional(true);
+ * $objDrawing->setWidthAndHeight(160,120);
+ *
+ *
+ * @author Vincent@luo MSN:kele_100@hotmail.com
+ * @param int $width
+ * @param int $height
+ * @return PHPExcel_Worksheet_HeaderFooterDrawing
+ */
+ public function setWidthAndHeight($width = 0, $height = 0)
+ {
+ $xratio = $width / $this->width;
+ $yratio = $height / $this->height;
+ if ($this->resizeProportional && !($width == 0 || $height == 0)) {
+ if (($xratio * $this->height) < $height) {
+ $this->height = ceil($xratio * $this->height);
+ $this->width = $width;
+ } else {
+ $this->width = ceil($yratio * $this->width);
+ $this->height = $height;
+ }
+ }
+ return $this;
+ }
+
+ /**
+ * Get ResizeProportional
+ *
+ * @return boolean
+ */
+ public function getResizeProportional()
+ {
+ return $this->resizeProportional;
+ }
+
+ /**
+ * Set ResizeProportional
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_HeaderFooterDrawing
+ */
+ public function setResizeProportional($pValue = true)
+ {
+ $this->resizeProportional = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Filename
+ *
+ * @return string
+ */
+ public function getFilename()
+ {
+ return basename($this->path);
+ }
+
+ /**
+ * Get Extension
+ *
+ * @return string
+ */
+ public function getExtension()
+ {
+ $parts = explode(".", basename($this->path));
+ return end($parts);
+ }
+
+ /**
+ * Get Path
+ *
+ * @return string
+ */
+ public function getPath()
+ {
+ return $this->path;
+ }
+
+ /**
+ * Set Path
+ *
+ * @param string $pValue File path
+ * @param boolean $pVerifyFile Verify file
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_HeaderFooterDrawing
+ */
+ public function setPath($pValue = '', $pVerifyFile = true)
+ {
+ if ($pVerifyFile) {
+ if (file_exists($pValue)) {
+ $this->path = $pValue;
+
+ if ($this->width == 0 && $this->height == 0) {
+ // Get width/height
+ list($this->width, $this->height) = getimagesize($pValue);
+ }
+ } else {
+ throw new PHPExcel_Exception("File $pValue not found!");
+ }
+ } else {
+ $this->path = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Get hash code
+ *
+ * @return string Hash code
+ */
+ public function getHashCode()
+ {
+ return md5(
+ $this->path .
+ $this->name .
+ $this->offsetX .
+ $this->offsetY .
+ $this->width .
+ $this->height .
+ __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) {
+ if (is_object($value)) {
+ $this->$key = clone $value;
+ } else {
+ $this->$key = $value;
+ }
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/MemoryDrawing.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/MemoryDrawing.php
new file mode 100755
index 000000000..438ed2c58
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/MemoryDrawing.php
@@ -0,0 +1,201 @@
+imageResource = null;
+ $this->renderingFunction = self::RENDERING_DEFAULT;
+ $this->mimeType = self::MIMETYPE_DEFAULT;
+ $this->uniqueName = md5(rand(0, 9999). time() . rand(0, 9999));
+
+ // Initialize parent
+ parent::__construct();
+ }
+
+ /**
+ * Get image resource
+ *
+ * @return resource
+ */
+ public function getImageResource()
+ {
+ return $this->imageResource;
+ }
+
+ /**
+ * Set image resource
+ *
+ * @param $value resource
+ * @return PHPExcel_Worksheet_MemoryDrawing
+ */
+ public function setImageResource($value = null)
+ {
+ $this->imageResource = $value;
+
+ if (!is_null($this->imageResource)) {
+ // Get width/height
+ $this->width = imagesx($this->imageResource);
+ $this->height = imagesy($this->imageResource);
+ }
+ return $this;
+ }
+
+ /**
+ * Get rendering function
+ *
+ * @return string
+ */
+ public function getRenderingFunction()
+ {
+ return $this->renderingFunction;
+ }
+
+ /**
+ * Set rendering function
+ *
+ * @param string $value
+ * @return PHPExcel_Worksheet_MemoryDrawing
+ */
+ public function setRenderingFunction($value = PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT)
+ {
+ $this->renderingFunction = $value;
+ return $this;
+ }
+
+ /**
+ * Get mime type
+ *
+ * @return string
+ */
+ public function getMimeType()
+ {
+ return $this->mimeType;
+ }
+
+ /**
+ * Set mime type
+ *
+ * @param string $value
+ * @return PHPExcel_Worksheet_MemoryDrawing
+ */
+ public function setMimeType($value = PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT)
+ {
+ $this->mimeType = $value;
+ return $this;
+ }
+
+ /**
+ * Get indexed filename (using image index)
+ *
+ * @return string
+ */
+ public function getIndexedFilename()
+ {
+ $extension = strtolower($this->getMimeType());
+ $extension = explode('/', $extension);
+ $extension = $extension[1];
+
+ return $this->uniqueName . $this->getImageIndex() . '.' . $extension;
+ }
+
+ /**
+ * Get hash code
+ *
+ * @return string Hash code
+ */
+ public function getHashCode()
+ {
+ return md5(
+ $this->renderingFunction .
+ $this->mimeType .
+ $this->uniqueName .
+ parent::getHashCode() .
+ __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) {
+ if (is_object($value)) {
+ $this->$key = clone $value;
+ } else {
+ $this->$key = $value;
+ }
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/PageMargins.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/PageMargins.php
new file mode 100755
index 000000000..70f5ee0f5
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/PageMargins.php
@@ -0,0 +1,233 @@
+left;
+ }
+
+ /**
+ * Set Left
+ *
+ * @param double $pValue
+ * @return PHPExcel_Worksheet_PageMargins
+ */
+ public function setLeft($pValue)
+ {
+ $this->left = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Right
+ *
+ * @return double
+ */
+ public function getRight()
+ {
+ return $this->right;
+ }
+
+ /**
+ * Set Right
+ *
+ * @param double $pValue
+ * @return PHPExcel_Worksheet_PageMargins
+ */
+ public function setRight($pValue)
+ {
+ $this->right = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Top
+ *
+ * @return double
+ */
+ public function getTop()
+ {
+ return $this->top;
+ }
+
+ /**
+ * Set Top
+ *
+ * @param double $pValue
+ * @return PHPExcel_Worksheet_PageMargins
+ */
+ public function setTop($pValue)
+ {
+ $this->top = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Bottom
+ *
+ * @return double
+ */
+ public function getBottom()
+ {
+ return $this->bottom;
+ }
+
+ /**
+ * Set Bottom
+ *
+ * @param double $pValue
+ * @return PHPExcel_Worksheet_PageMargins
+ */
+ public function setBottom($pValue)
+ {
+ $this->bottom = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Header
+ *
+ * @return double
+ */
+ public function getHeader()
+ {
+ return $this->header;
+ }
+
+ /**
+ * Set Header
+ *
+ * @param double $pValue
+ * @return PHPExcel_Worksheet_PageMargins
+ */
+ public function setHeader($pValue)
+ {
+ $this->header = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Footer
+ *
+ * @return double
+ */
+ public function getFooter()
+ {
+ return $this->footer;
+ }
+
+ /**
+ * Set Footer
+ *
+ * @param double $pValue
+ * @return PHPExcel_Worksheet_PageMargins
+ */
+ public function setFooter($pValue)
+ {
+ $this->footer = $pValue;
+ return $this;
+ }
+
+ /**
+ * 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;
+ }
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/PageSetup.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/PageSetup.php
new file mode 100755
index 000000000..c67053e6b
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/PageSetup.php
@@ -0,0 +1,839 @@
+
+ * Paper size taken from Office Open XML Part 4 - Markup Language Reference, page 1988:
+ *
+ * 1 = Letter paper (8.5 in. by 11 in.)
+ * 2 = Letter small paper (8.5 in. by 11 in.)
+ * 3 = Tabloid paper (11 in. by 17 in.)
+ * 4 = Ledger paper (17 in. by 11 in.)
+ * 5 = Legal paper (8.5 in. by 14 in.)
+ * 6 = Statement paper (5.5 in. by 8.5 in.)
+ * 7 = Executive paper (7.25 in. by 10.5 in.)
+ * 8 = A3 paper (297 mm by 420 mm)
+ * 9 = A4 paper (210 mm by 297 mm)
+ * 10 = A4 small paper (210 mm by 297 mm)
+ * 11 = A5 paper (148 mm by 210 mm)
+ * 12 = B4 paper (250 mm by 353 mm)
+ * 13 = B5 paper (176 mm by 250 mm)
+ * 14 = Folio paper (8.5 in. by 13 in.)
+ * 15 = Quarto paper (215 mm by 275 mm)
+ * 16 = Standard paper (10 in. by 14 in.)
+ * 17 = Standard paper (11 in. by 17 in.)
+ * 18 = Note paper (8.5 in. by 11 in.)
+ * 19 = #9 envelope (3.875 in. by 8.875 in.)
+ * 20 = #10 envelope (4.125 in. by 9.5 in.)
+ * 21 = #11 envelope (4.5 in. by 10.375 in.)
+ * 22 = #12 envelope (4.75 in. by 11 in.)
+ * 23 = #14 envelope (5 in. by 11.5 in.)
+ * 24 = C paper (17 in. by 22 in.)
+ * 25 = D paper (22 in. by 34 in.)
+ * 26 = E paper (34 in. by 44 in.)
+ * 27 = DL envelope (110 mm by 220 mm)
+ * 28 = C5 envelope (162 mm by 229 mm)
+ * 29 = C3 envelope (324 mm by 458 mm)
+ * 30 = C4 envelope (229 mm by 324 mm)
+ * 31 = C6 envelope (114 mm by 162 mm)
+ * 32 = C65 envelope (114 mm by 229 mm)
+ * 33 = B4 envelope (250 mm by 353 mm)
+ * 34 = B5 envelope (176 mm by 250 mm)
+ * 35 = B6 envelope (176 mm by 125 mm)
+ * 36 = Italy envelope (110 mm by 230 mm)
+ * 37 = Monarch envelope (3.875 in. by 7.5 in.).
+ * 38 = 6 3/4 envelope (3.625 in. by 6.5 in.)
+ * 39 = US standard fanfold (14.875 in. by 11 in.)
+ * 40 = German standard fanfold (8.5 in. by 12 in.)
+ * 41 = German legal fanfold (8.5 in. by 13 in.)
+ * 42 = ISO B4 (250 mm by 353 mm)
+ * 43 = Japanese double postcard (200 mm by 148 mm)
+ * 44 = Standard paper (9 in. by 11 in.)
+ * 45 = Standard paper (10 in. by 11 in.)
+ * 46 = Standard paper (15 in. by 11 in.)
+ * 47 = Invite envelope (220 mm by 220 mm)
+ * 50 = Letter extra paper (9.275 in. by 12 in.)
+ * 51 = Legal extra paper (9.275 in. by 15 in.)
+ * 52 = Tabloid extra paper (11.69 in. by 18 in.)
+ * 53 = A4 extra paper (236 mm by 322 mm)
+ * 54 = Letter transverse paper (8.275 in. by 11 in.)
+ * 55 = A4 transverse paper (210 mm by 297 mm)
+ * 56 = Letter extra transverse paper (9.275 in. by 12 in.)
+ * 57 = SuperA/SuperA/A4 paper (227 mm by 356 mm)
+ * 58 = SuperB/SuperB/A3 paper (305 mm by 487 mm)
+ * 59 = Letter plus paper (8.5 in. by 12.69 in.)
+ * 60 = A4 plus paper (210 mm by 330 mm)
+ * 61 = A5 transverse paper (148 mm by 210 mm)
+ * 62 = JIS B5 transverse paper (182 mm by 257 mm)
+ * 63 = A3 extra paper (322 mm by 445 mm)
+ * 64 = A5 extra paper (174 mm by 235 mm)
+ * 65 = ISO B5 extra paper (201 mm by 276 mm)
+ * 66 = A2 paper (420 mm by 594 mm)
+ * 67 = A3 transverse paper (297 mm by 420 mm)
+ * 68 = A3 extra transverse paper (322 mm by 445 mm)
+ *
+ *
+ * @category PHPExcel
+ * @package PHPExcel_Worksheet
+ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
+ */
+class PHPExcel_Worksheet_PageSetup
+{
+ /* Paper size */
+ const PAPERSIZE_LETTER = 1;
+ const PAPERSIZE_LETTER_SMALL = 2;
+ const PAPERSIZE_TABLOID = 3;
+ const PAPERSIZE_LEDGER = 4;
+ const PAPERSIZE_LEGAL = 5;
+ const PAPERSIZE_STATEMENT = 6;
+ const PAPERSIZE_EXECUTIVE = 7;
+ const PAPERSIZE_A3 = 8;
+ const PAPERSIZE_A4 = 9;
+ const PAPERSIZE_A4_SMALL = 10;
+ const PAPERSIZE_A5 = 11;
+ const PAPERSIZE_B4 = 12;
+ const PAPERSIZE_B5 = 13;
+ const PAPERSIZE_FOLIO = 14;
+ const PAPERSIZE_QUARTO = 15;
+ const PAPERSIZE_STANDARD_1 = 16;
+ const PAPERSIZE_STANDARD_2 = 17;
+ const PAPERSIZE_NOTE = 18;
+ const PAPERSIZE_NO9_ENVELOPE = 19;
+ const PAPERSIZE_NO10_ENVELOPE = 20;
+ const PAPERSIZE_NO11_ENVELOPE = 21;
+ const PAPERSIZE_NO12_ENVELOPE = 22;
+ const PAPERSIZE_NO14_ENVELOPE = 23;
+ const PAPERSIZE_C = 24;
+ const PAPERSIZE_D = 25;
+ const PAPERSIZE_E = 26;
+ const PAPERSIZE_DL_ENVELOPE = 27;
+ const PAPERSIZE_C5_ENVELOPE = 28;
+ const PAPERSIZE_C3_ENVELOPE = 29;
+ const PAPERSIZE_C4_ENVELOPE = 30;
+ const PAPERSIZE_C6_ENVELOPE = 31;
+ const PAPERSIZE_C65_ENVELOPE = 32;
+ const PAPERSIZE_B4_ENVELOPE = 33;
+ const PAPERSIZE_B5_ENVELOPE = 34;
+ const PAPERSIZE_B6_ENVELOPE = 35;
+ const PAPERSIZE_ITALY_ENVELOPE = 36;
+ const PAPERSIZE_MONARCH_ENVELOPE = 37;
+ const PAPERSIZE_6_3_4_ENVELOPE = 38;
+ const PAPERSIZE_US_STANDARD_FANFOLD = 39;
+ const PAPERSIZE_GERMAN_STANDARD_FANFOLD = 40;
+ const PAPERSIZE_GERMAN_LEGAL_FANFOLD = 41;
+ const PAPERSIZE_ISO_B4 = 42;
+ const PAPERSIZE_JAPANESE_DOUBLE_POSTCARD = 43;
+ const PAPERSIZE_STANDARD_PAPER_1 = 44;
+ const PAPERSIZE_STANDARD_PAPER_2 = 45;
+ const PAPERSIZE_STANDARD_PAPER_3 = 46;
+ const PAPERSIZE_INVITE_ENVELOPE = 47;
+ const PAPERSIZE_LETTER_EXTRA_PAPER = 48;
+ const PAPERSIZE_LEGAL_EXTRA_PAPER = 49;
+ const PAPERSIZE_TABLOID_EXTRA_PAPER = 50;
+ const PAPERSIZE_A4_EXTRA_PAPER = 51;
+ const PAPERSIZE_LETTER_TRANSVERSE_PAPER = 52;
+ const PAPERSIZE_A4_TRANSVERSE_PAPER = 53;
+ const PAPERSIZE_LETTER_EXTRA_TRANSVERSE_PAPER = 54;
+ const PAPERSIZE_SUPERA_SUPERA_A4_PAPER = 55;
+ const PAPERSIZE_SUPERB_SUPERB_A3_PAPER = 56;
+ const PAPERSIZE_LETTER_PLUS_PAPER = 57;
+ const PAPERSIZE_A4_PLUS_PAPER = 58;
+ const PAPERSIZE_A5_TRANSVERSE_PAPER = 59;
+ const PAPERSIZE_JIS_B5_TRANSVERSE_PAPER = 60;
+ const PAPERSIZE_A3_EXTRA_PAPER = 61;
+ const PAPERSIZE_A5_EXTRA_PAPER = 62;
+ const PAPERSIZE_ISO_B5_EXTRA_PAPER = 63;
+ const PAPERSIZE_A2_PAPER = 64;
+ const PAPERSIZE_A3_TRANSVERSE_PAPER = 65;
+ const PAPERSIZE_A3_EXTRA_TRANSVERSE_PAPER = 66;
+
+ /* Page orientation */
+ const ORIENTATION_DEFAULT = 'default';
+ const ORIENTATION_LANDSCAPE = 'landscape';
+ const ORIENTATION_PORTRAIT = 'portrait';
+
+ /* Print Range Set Method */
+ const SETPRINTRANGE_OVERWRITE = 'O';
+ const SETPRINTRANGE_INSERT = 'I';
+
+
+ /**
+ * Paper size
+ *
+ * @var int
+ */
+ private $paperSize = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER;
+
+ /**
+ * Orientation
+ *
+ * @var string
+ */
+ private $orientation = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT;
+
+ /**
+ * Scale (Print Scale)
+ *
+ * Print scaling. Valid values range from 10 to 400
+ * This setting is overridden when fitToWidth and/or fitToHeight are in use
+ *
+ * @var int?
+ */
+ private $scale = 100;
+
+ /**
+ * Fit To Page
+ * Whether scale or fitToWith / fitToHeight applies
+ *
+ * @var boolean
+ */
+ private $fitToPage = false;
+
+ /**
+ * Fit To Height
+ * Number of vertical pages to fit on
+ *
+ * @var int?
+ */
+ private $fitToHeight = 1;
+
+ /**
+ * Fit To Width
+ * Number of horizontal pages to fit on
+ *
+ * @var int?
+ */
+ private $fitToWidth = 1;
+
+ /**
+ * Columns to repeat at left
+ *
+ * @var array Containing start column and end column, empty array if option unset
+ */
+ private $columnsToRepeatAtLeft = array('', '');
+
+ /**
+ * Rows to repeat at top
+ *
+ * @var array Containing start row number and end row number, empty array if option unset
+ */
+ private $rowsToRepeatAtTop = array(0, 0);
+
+ /**
+ * Center page horizontally
+ *
+ * @var boolean
+ */
+ private $horizontalCentered = false;
+
+ /**
+ * Center page vertically
+ *
+ * @var boolean
+ */
+ private $verticalCentered = false;
+
+ /**
+ * Print area
+ *
+ * @var string
+ */
+ private $printArea = null;
+
+ /**
+ * First page number
+ *
+ * @var int
+ */
+ private $firstPageNumber = null;
+
+ /**
+ * Create a new PHPExcel_Worksheet_PageSetup
+ */
+ public function __construct()
+ {
+ }
+
+ /**
+ * Get Paper Size
+ *
+ * @return int
+ */
+ public function getPaperSize()
+ {
+ return $this->paperSize;
+ }
+
+ /**
+ * Set Paper Size
+ *
+ * @param int $pValue
+ * @return PHPExcel_Worksheet_PageSetup
+ */
+ public function setPaperSize($pValue = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER)
+ {
+ $this->paperSize = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Orientation
+ *
+ * @return string
+ */
+ public function getOrientation()
+ {
+ return $this->orientation;
+ }
+
+ /**
+ * Set Orientation
+ *
+ * @param string $pValue
+ * @return PHPExcel_Worksheet_PageSetup
+ */
+ public function setOrientation($pValue = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT)
+ {
+ $this->orientation = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Scale
+ *
+ * @return int?
+ */
+ public function getScale()
+ {
+ return $this->scale;
+ }
+
+ /**
+ * Set Scale
+ *
+ * Print scaling. Valid values range from 10 to 400
+ * This setting is overridden when fitToWidth and/or fitToHeight are in use
+ *
+ * @param int? $pValue
+ * @param boolean $pUpdate Update fitToPage so scaling applies rather than fitToHeight / fitToWidth
+ * @return PHPExcel_Worksheet_PageSetup
+ * @throws PHPExcel_Exception
+ */
+ public function setScale($pValue = 100, $pUpdate = true)
+ {
+ // Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface,
+ // but it is apparently still able to handle any scale >= 0, where 0 results in 100
+ if (($pValue >= 0) || is_null($pValue)) {
+ $this->scale = $pValue;
+ if ($pUpdate) {
+ $this->fitToPage = false;
+ }
+ } else {
+ throw new PHPExcel_Exception("Scale must not be negative");
+ }
+ return $this;
+ }
+
+ /**
+ * Get Fit To Page
+ *
+ * @return boolean
+ */
+ public function getFitToPage()
+ {
+ return $this->fitToPage;
+ }
+
+ /**
+ * Set Fit To Page
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_PageSetup
+ */
+ public function setFitToPage($pValue = true)
+ {
+ $this->fitToPage = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Fit To Height
+ *
+ * @return int?
+ */
+ public function getFitToHeight()
+ {
+ return $this->fitToHeight;
+ }
+
+ /**
+ * Set Fit To Height
+ *
+ * @param int? $pValue
+ * @param boolean $pUpdate Update fitToPage so it applies rather than scaling
+ * @return PHPExcel_Worksheet_PageSetup
+ */
+ public function setFitToHeight($pValue = 1, $pUpdate = true)
+ {
+ $this->fitToHeight = $pValue;
+ if ($pUpdate) {
+ $this->fitToPage = true;
+ }
+ return $this;
+ }
+
+ /**
+ * Get Fit To Width
+ *
+ * @return int?
+ */
+ public function getFitToWidth()
+ {
+ return $this->fitToWidth;
+ }
+
+ /**
+ * Set Fit To Width
+ *
+ * @param int? $pValue
+ * @param boolean $pUpdate Update fitToPage so it applies rather than scaling
+ * @return PHPExcel_Worksheet_PageSetup
+ */
+ public function setFitToWidth($pValue = 1, $pUpdate = true)
+ {
+ $this->fitToWidth = $pValue;
+ if ($pUpdate) {
+ $this->fitToPage = true;
+ }
+ return $this;
+ }
+
+ /**
+ * Is Columns to repeat at left set?
+ *
+ * @return boolean
+ */
+ public function isColumnsToRepeatAtLeftSet()
+ {
+ if (is_array($this->columnsToRepeatAtLeft)) {
+ if ($this->columnsToRepeatAtLeft[0] != '' && $this->columnsToRepeatAtLeft[1] != '') {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Get Columns to repeat at left
+ *
+ * @return array Containing start column and end column, empty array if option unset
+ */
+ public function getColumnsToRepeatAtLeft()
+ {
+ return $this->columnsToRepeatAtLeft;
+ }
+
+ /**
+ * Set Columns to repeat at left
+ *
+ * @param array $pValue Containing start column and end column, empty array if option unset
+ * @return PHPExcel_Worksheet_PageSetup
+ */
+ public function setColumnsToRepeatAtLeft($pValue = null)
+ {
+ if (is_array($pValue)) {
+ $this->columnsToRepeatAtLeft = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Set Columns to repeat at left by start and end
+ *
+ * @param string $pStart
+ * @param string $pEnd
+ * @return PHPExcel_Worksheet_PageSetup
+ */
+ public function setColumnsToRepeatAtLeftByStartAndEnd($pStart = 'A', $pEnd = 'A')
+ {
+ $this->columnsToRepeatAtLeft = array($pStart, $pEnd);
+ return $this;
+ }
+
+ /**
+ * Is Rows to repeat at top set?
+ *
+ * @return boolean
+ */
+ public function isRowsToRepeatAtTopSet()
+ {
+ if (is_array($this->rowsToRepeatAtTop)) {
+ if ($this->rowsToRepeatAtTop[0] != 0 && $this->rowsToRepeatAtTop[1] != 0) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Get Rows to repeat at top
+ *
+ * @return array Containing start column and end column, empty array if option unset
+ */
+ public function getRowsToRepeatAtTop()
+ {
+ return $this->rowsToRepeatAtTop;
+ }
+
+ /**
+ * Set Rows to repeat at top
+ *
+ * @param array $pValue Containing start column and end column, empty array if option unset
+ * @return PHPExcel_Worksheet_PageSetup
+ */
+ public function setRowsToRepeatAtTop($pValue = null)
+ {
+ if (is_array($pValue)) {
+ $this->rowsToRepeatAtTop = $pValue;
+ }
+ return $this;
+ }
+
+ /**
+ * Set Rows to repeat at top by start and end
+ *
+ * @param int $pStart
+ * @param int $pEnd
+ * @return PHPExcel_Worksheet_PageSetup
+ */
+ public function setRowsToRepeatAtTopByStartAndEnd($pStart = 1, $pEnd = 1)
+ {
+ $this->rowsToRepeatAtTop = array($pStart, $pEnd);
+ return $this;
+ }
+
+ /**
+ * Get center page horizontally
+ *
+ * @return bool
+ */
+ public function getHorizontalCentered()
+ {
+ return $this->horizontalCentered;
+ }
+
+ /**
+ * Set center page horizontally
+ *
+ * @param bool $value
+ * @return PHPExcel_Worksheet_PageSetup
+ */
+ public function setHorizontalCentered($value = false)
+ {
+ $this->horizontalCentered = $value;
+ return $this;
+ }
+
+ /**
+ * Get center page vertically
+ *
+ * @return bool
+ */
+ public function getVerticalCentered()
+ {
+ return $this->verticalCentered;
+ }
+
+ /**
+ * Set center page vertically
+ *
+ * @param bool $value
+ * @return PHPExcel_Worksheet_PageSetup
+ */
+ public function setVerticalCentered($value = false)
+ {
+ $this->verticalCentered = $value;
+ return $this;
+ }
+
+ /**
+ * Get print area
+ *
+ * @param int $index Identifier for a specific print area range if several ranges have been set
+ * Default behaviour, or a index value of 0, will return all ranges as a comma-separated string
+ * Otherwise, the specific range identified by the value of $index will be returned
+ * Print areas are numbered from 1
+ * @throws PHPExcel_Exception
+ * @return string
+ */
+ public function getPrintArea($index = 0)
+ {
+ if ($index == 0) {
+ return $this->printArea;
+ }
+ $printAreas = explode(',', $this->printArea);
+ if (isset($printAreas[$index-1])) {
+ return $printAreas[$index-1];
+ }
+ throw new PHPExcel_Exception("Requested Print Area does not exist");
+ }
+
+ /**
+ * Is print area set?
+ *
+ * @param int $index Identifier for a specific print area range if several ranges have been set
+ * Default behaviour, or an index value of 0, will identify whether any print range is set
+ * Otherwise, existence of the range identified by the value of $index will be returned
+ * Print areas are numbered from 1
+ * @return boolean
+ */
+ public function isPrintAreaSet($index = 0)
+ {
+ if ($index == 0) {
+ return !is_null($this->printArea);
+ }
+ $printAreas = explode(',', $this->printArea);
+ return isset($printAreas[$index-1]);
+ }
+
+ /**
+ * Clear a print area
+ *
+ * @param int $index Identifier for a specific print area range if several ranges have been set
+ * Default behaviour, or an index value of 0, will clear all print ranges that are set
+ * Otherwise, the range identified by the value of $index will be removed from the series
+ * Print areas are numbered from 1
+ * @return PHPExcel_Worksheet_PageSetup
+ */
+ public function clearPrintArea($index = 0)
+ {
+ if ($index == 0) {
+ $this->printArea = null;
+ } else {
+ $printAreas = explode(',', $this->printArea);
+ if (isset($printAreas[$index-1])) {
+ unset($printAreas[$index-1]);
+ $this->printArea = implode(',', $printAreas);
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Set print area. e.g. 'A1:D10' or 'A1:D10,G5:M20'
+ *
+ * @param string $value
+ * @param int $index Identifier for a specific print area range allowing several ranges to be set
+ * When the method is "O"verwrite, then a positive integer index will overwrite that indexed
+ * entry in the print areas list; a negative index value will identify which entry to
+ * overwrite working bacward through the print area to the list, with the last entry as -1.
+ * Specifying an index value of 0, will overwrite all existing print ranges.
+ * When the method is "I"nsert, then a positive index will insert after that indexed entry in
+ * the print areas list, while a negative index will insert before the indexed entry.
+ * Specifying an index value of 0, will always append the new print range at the end of the
+ * list.
+ * Print areas are numbered from 1
+ * @param string $method Determines the method used when setting multiple print areas
+ * Default behaviour, or the "O" method, overwrites existing print area
+ * The "I" method, inserts the new print area before any specified index, or at the end of the list
+ * @return PHPExcel_Worksheet_PageSetup
+ * @throws PHPExcel_Exception
+ */
+ public function setPrintArea($value, $index = 0, $method = self::SETPRINTRANGE_OVERWRITE)
+ {
+ if (strpos($value, '!') !== false) {
+ throw new PHPExcel_Exception('Cell coordinate must not specify a worksheet.');
+ } elseif (strpos($value, ':') === false) {
+ throw new PHPExcel_Exception('Cell coordinate must be a range of cells.');
+ } elseif (strpos($value, '$') !== false) {
+ throw new PHPExcel_Exception('Cell coordinate must not be absolute.');
+ }
+ $value = strtoupper($value);
+
+ if ($method == self::SETPRINTRANGE_OVERWRITE) {
+ if ($index == 0) {
+ $this->printArea = $value;
+ } else {
+ $printAreas = explode(',', $this->printArea);
+ if ($index < 0) {
+ $index = count($printAreas) - abs($index) + 1;
+ }
+ if (($index <= 0) || ($index > count($printAreas))) {
+ throw new PHPExcel_Exception('Invalid index for setting print range.');
+ }
+ $printAreas[$index-1] = $value;
+ $this->printArea = implode(',', $printAreas);
+ }
+ } elseif ($method == self::SETPRINTRANGE_INSERT) {
+ if ($index == 0) {
+ $this->printArea .= ($this->printArea == '') ? $value : ','.$value;
+ } else {
+ $printAreas = explode(',', $this->printArea);
+ if ($index < 0) {
+ $index = abs($index) - 1;
+ }
+ if ($index > count($printAreas)) {
+ throw new PHPExcel_Exception('Invalid index for setting print range.');
+ }
+ $printAreas = array_merge(array_slice($printAreas, 0, $index), array($value), array_slice($printAreas, $index));
+ $this->printArea = implode(',', $printAreas);
+ }
+ } else {
+ throw new PHPExcel_Exception('Invalid method for setting print range.');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Add a new print area (e.g. 'A1:D10' or 'A1:D10,G5:M20') to the list of print areas
+ *
+ * @param string $value
+ * @param int $index Identifier for a specific print area range allowing several ranges to be set
+ * A positive index will insert after that indexed entry in the print areas list, while a
+ * negative index will insert before the indexed entry.
+ * Specifying an index value of 0, will always append the new print range at the end of the
+ * list.
+ * Print areas are numbered from 1
+ * @return PHPExcel_Worksheet_PageSetup
+ * @throws PHPExcel_Exception
+ */
+ public function addPrintArea($value, $index = -1)
+ {
+ return $this->setPrintArea($value, $index, self::SETPRINTRANGE_INSERT);
+ }
+
+ /**
+ * Set print area
+ *
+ * @param int $column1 Column 1
+ * @param int $row1 Row 1
+ * @param int $column2 Column 2
+ * @param int $row2 Row 2
+ * @param int $index Identifier for a specific print area range allowing several ranges to be set
+ * When the method is "O"verwrite, then a positive integer index will overwrite that indexed
+ * entry in the print areas list; a negative index value will identify which entry to
+ * overwrite working bacward through the print area to the list, with the last entry as -1.
+ * Specifying an index value of 0, will overwrite all existing print ranges.
+ * When the method is "I"nsert, then a positive index will insert after that indexed entry in
+ * the print areas list, while a negative index will insert before the indexed entry.
+ * Specifying an index value of 0, will always append the new print range at the end of the
+ * list.
+ * Print areas are numbered from 1
+ * @param string $method Determines the method used when setting multiple print areas
+ * Default behaviour, or the "O" method, overwrites existing print area
+ * The "I" method, inserts the new print area before any specified index, or at the end of the list
+ * @return PHPExcel_Worksheet_PageSetup
+ * @throws PHPExcel_Exception
+ */
+ public function setPrintAreaByColumnAndRow($column1, $row1, $column2, $row2, $index = 0, $method = self::SETPRINTRANGE_OVERWRITE)
+ {
+ return $this->setPrintArea(
+ PHPExcel_Cell::stringFromColumnIndex($column1) . $row1 . ':' . PHPExcel_Cell::stringFromColumnIndex($column2) . $row2,
+ $index,
+ $method
+ );
+ }
+
+ /**
+ * Add a new print area to the list of print areas
+ *
+ * @param int $column1 Start Column for the print area
+ * @param int $row1 Start Row for the print area
+ * @param int $column2 End Column for the print area
+ * @param int $row2 End Row for the print area
+ * @param int $index Identifier for a specific print area range allowing several ranges to be set
+ * A positive index will insert after that indexed entry in the print areas list, while a
+ * negative index will insert before the indexed entry.
+ * Specifying an index value of 0, will always append the new print range at the end of the
+ * list.
+ * Print areas are numbered from 1
+ * @return PHPExcel_Worksheet_PageSetup
+ * @throws PHPExcel_Exception
+ */
+ public function addPrintAreaByColumnAndRow($column1, $row1, $column2, $row2, $index = -1)
+ {
+ return $this->setPrintArea(
+ PHPExcel_Cell::stringFromColumnIndex($column1) . $row1 . ':' . PHPExcel_Cell::stringFromColumnIndex($column2) . $row2,
+ $index,
+ self::SETPRINTRANGE_INSERT
+ );
+ }
+
+ /**
+ * Get first page number
+ *
+ * @return int
+ */
+ public function getFirstPageNumber()
+ {
+ return $this->firstPageNumber;
+ }
+
+ /**
+ * Set first page number
+ *
+ * @param int $value
+ * @return PHPExcel_Worksheet_HeaderFooter
+ */
+ public function setFirstPageNumber($value = null)
+ {
+ $this->firstPageNumber = $value;
+ return $this;
+ }
+
+ /**
+ * Reset first page number
+ *
+ * @return PHPExcel_Worksheet_HeaderFooter
+ */
+ public function resetFirstPageNumber()
+ {
+ return $this->setFirstPageNumber(null);
+ }
+
+ /**
+ * 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;
+ }
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Protection.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Protection.php
new file mode 100755
index 000000000..00633eeb7
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Protection.php
@@ -0,0 +1,581 @@
+sheet ||
+ $this->objects ||
+ $this->scenarios ||
+ $this->formatCells ||
+ $this->formatColumns ||
+ $this->formatRows ||
+ $this->insertColumns ||
+ $this->insertRows ||
+ $this->insertHyperlinks ||
+ $this->deleteColumns ||
+ $this->deleteRows ||
+ $this->selectLockedCells ||
+ $this->sort ||
+ $this->autoFilter ||
+ $this->pivotTables ||
+ $this->selectUnlockedCells;
+ }
+
+ /**
+ * Get Sheet
+ *
+ * @return boolean
+ */
+ public function getSheet()
+ {
+ return $this->sheet;
+ }
+
+ /**
+ * Set Sheet
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_Protection
+ */
+ public function setSheet($pValue = false)
+ {
+ $this->sheet = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Objects
+ *
+ * @return boolean
+ */
+ public function getObjects()
+ {
+ return $this->objects;
+ }
+
+ /**
+ * Set Objects
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_Protection
+ */
+ public function setObjects($pValue = false)
+ {
+ $this->objects = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Scenarios
+ *
+ * @return boolean
+ */
+ public function getScenarios()
+ {
+ return $this->scenarios;
+ }
+
+ /**
+ * Set Scenarios
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_Protection
+ */
+ public function setScenarios($pValue = false)
+ {
+ $this->scenarios = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get FormatCells
+ *
+ * @return boolean
+ */
+ public function getFormatCells()
+ {
+ return $this->formatCells;
+ }
+
+ /**
+ * Set FormatCells
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_Protection
+ */
+ public function setFormatCells($pValue = false)
+ {
+ $this->formatCells = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get FormatColumns
+ *
+ * @return boolean
+ */
+ public function getFormatColumns()
+ {
+ return $this->formatColumns;
+ }
+
+ /**
+ * Set FormatColumns
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_Protection
+ */
+ public function setFormatColumns($pValue = false)
+ {
+ $this->formatColumns = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get FormatRows
+ *
+ * @return boolean
+ */
+ public function getFormatRows()
+ {
+ return $this->formatRows;
+ }
+
+ /**
+ * Set FormatRows
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_Protection
+ */
+ public function setFormatRows($pValue = false)
+ {
+ $this->formatRows = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get InsertColumns
+ *
+ * @return boolean
+ */
+ public function getInsertColumns()
+ {
+ return $this->insertColumns;
+ }
+
+ /**
+ * Set InsertColumns
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_Protection
+ */
+ public function setInsertColumns($pValue = false)
+ {
+ $this->insertColumns = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get InsertRows
+ *
+ * @return boolean
+ */
+ public function getInsertRows()
+ {
+ return $this->insertRows;
+ }
+
+ /**
+ * Set InsertRows
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_Protection
+ */
+ public function setInsertRows($pValue = false)
+ {
+ $this->insertRows = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get InsertHyperlinks
+ *
+ * @return boolean
+ */
+ public function getInsertHyperlinks()
+ {
+ return $this->insertHyperlinks;
+ }
+
+ /**
+ * Set InsertHyperlinks
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_Protection
+ */
+ public function setInsertHyperlinks($pValue = false)
+ {
+ $this->insertHyperlinks = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get DeleteColumns
+ *
+ * @return boolean
+ */
+ public function getDeleteColumns()
+ {
+ return $this->deleteColumns;
+ }
+
+ /**
+ * Set DeleteColumns
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_Protection
+ */
+ public function setDeleteColumns($pValue = false)
+ {
+ $this->deleteColumns = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get DeleteRows
+ *
+ * @return boolean
+ */
+ public function getDeleteRows()
+ {
+ return $this->deleteRows;
+ }
+
+ /**
+ * Set DeleteRows
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_Protection
+ */
+ public function setDeleteRows($pValue = false)
+ {
+ $this->deleteRows = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get SelectLockedCells
+ *
+ * @return boolean
+ */
+ public function getSelectLockedCells()
+ {
+ return $this->selectLockedCells;
+ }
+
+ /**
+ * Set SelectLockedCells
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_Protection
+ */
+ public function setSelectLockedCells($pValue = false)
+ {
+ $this->selectLockedCells = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Sort
+ *
+ * @return boolean
+ */
+ public function getSort()
+ {
+ return $this->sort;
+ }
+
+ /**
+ * Set Sort
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_Protection
+ */
+ public function setSort($pValue = false)
+ {
+ $this->sort = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get AutoFilter
+ *
+ * @return boolean
+ */
+ public function getAutoFilter()
+ {
+ return $this->autoFilter;
+ }
+
+ /**
+ * Set AutoFilter
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_Protection
+ */
+ public function setAutoFilter($pValue = false)
+ {
+ $this->autoFilter = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get PivotTables
+ *
+ * @return boolean
+ */
+ public function getPivotTables()
+ {
+ return $this->pivotTables;
+ }
+
+ /**
+ * Set PivotTables
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_Protection
+ */
+ public function setPivotTables($pValue = false)
+ {
+ $this->pivotTables = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get SelectUnlockedCells
+ *
+ * @return boolean
+ */
+ public function getSelectUnlockedCells()
+ {
+ return $this->selectUnlockedCells;
+ }
+
+ /**
+ * Set SelectUnlockedCells
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Worksheet_Protection
+ */
+ public function setSelectUnlockedCells($pValue = false)
+ {
+ $this->selectUnlockedCells = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Password (hashed)
+ *
+ * @return string
+ */
+ public function getPassword()
+ {
+ return $this->password;
+ }
+
+ /**
+ * Set Password
+ *
+ * @param string $pValue
+ * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true
+ * @return PHPExcel_Worksheet_Protection
+ */
+ public function setPassword($pValue = '', $pAlreadyHashed = false)
+ {
+ if (!$pAlreadyHashed) {
+ $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue);
+ }
+ $this->password = $pValue;
+ return $this;
+ }
+
+ /**
+ * 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;
+ }
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Row.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Row.php
new file mode 100755
index 000000000..4f6034f53
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Row.php
@@ -0,0 +1,86 @@
+parent = $parent;
+ $this->rowIndex = $rowIndex;
+ }
+
+ /**
+ * Destructor
+ */
+ public function __destruct()
+ {
+ unset($this->parent);
+ }
+
+ /**
+ * Get row index
+ *
+ * @return int
+ */
+ public function getRowIndex()
+ {
+ return $this->rowIndex;
+ }
+
+ /**
+ * Get cell iterator
+ *
+ * @param string $startColumn The column address at which to start iterating
+ * @param string $endColumn Optionally, the column address at which to stop iterating
+ * @return PHPExcel_Worksheet_CellIterator
+ */
+ public function getCellIterator($startColumn = 'A', $endColumn = null)
+ {
+ return new PHPExcel_Worksheet_RowCellIterator($this->parent, $this->rowIndex, $startColumn, $endColumn);
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/RowCellIterator.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/RowCellIterator.php
new file mode 100755
index 000000000..90eb9c9f2
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/RowCellIterator.php
@@ -0,0 +1,225 @@
+subject = $subject;
+ $this->rowIndex = $rowIndex;
+ $this->resetEnd($endColumn);
+ $this->resetStart($startColumn);
+ }
+
+ /**
+ * Destructor
+ */
+ public function __destruct()
+ {
+ unset($this->subject);
+ }
+
+ /**
+ * (Re)Set the start column and the current column pointer
+ *
+ * @param integer $startColumn The column address at which to start iterating
+ * @return PHPExcel_Worksheet_RowCellIterator
+ * @throws PHPExcel_Exception
+ */
+ public function resetStart($startColumn = 'A')
+ {
+ $startColumnIndex = PHPExcel_Cell::columnIndexFromString($startColumn) - 1;
+ $this->startColumn = $startColumnIndex;
+ $this->adjustForExistingOnlyRange();
+ $this->seek(PHPExcel_Cell::stringFromColumnIndex($this->startColumn));
+
+ return $this;
+ }
+
+ /**
+ * (Re)Set the end column
+ *
+ * @param string $endColumn The column address at which to stop iterating
+ * @return PHPExcel_Worksheet_RowCellIterator
+ * @throws PHPExcel_Exception
+ */
+ public function resetEnd($endColumn = null)
+ {
+ $endColumn = ($endColumn) ? $endColumn : $this->subject->getHighestColumn();
+ $this->endColumn = PHPExcel_Cell::columnIndexFromString($endColumn) - 1;
+ $this->adjustForExistingOnlyRange();
+
+ return $this;
+ }
+
+ /**
+ * Set the column pointer to the selected column
+ *
+ * @param string $column The column address to set the current pointer at
+ * @return PHPExcel_Worksheet_RowCellIterator
+ * @throws PHPExcel_Exception
+ */
+ public function seek($column = 'A')
+ {
+ $column = PHPExcel_Cell::columnIndexFromString($column) - 1;
+ if (($column < $this->startColumn) || ($column > $this->endColumn)) {
+ throw new PHPExcel_Exception("Column $column is out of range ({$this->startColumn} - {$this->endColumn})");
+ } elseif ($this->onlyExistingCells && !($this->subject->cellExistsByColumnAndRow($column, $this->rowIndex))) {
+ throw new PHPExcel_Exception('In "IterateOnlyExistingCells" mode and Cell does not exist');
+ }
+ $this->position = $column;
+
+ return $this;
+ }
+
+ /**
+ * Rewind the iterator to the starting column
+ */
+ public function rewind()
+ {
+ $this->position = $this->startColumn;
+ }
+
+ /**
+ * Return the current cell in this worksheet row
+ *
+ * @return PHPExcel_Cell
+ */
+ public function current()
+ {
+ return $this->subject->getCellByColumnAndRow($this->position, $this->rowIndex);
+ }
+
+ /**
+ * Return the current iterator key
+ *
+ * @return string
+ */
+ public function key()
+ {
+ return PHPExcel_Cell::stringFromColumnIndex($this->position);
+ }
+
+ /**
+ * Set the iterator to its next value
+ */
+ public function next()
+ {
+ do {
+ ++$this->position;
+ } while (($this->onlyExistingCells) &&
+ (!$this->subject->cellExistsByColumnAndRow($this->position, $this->rowIndex)) &&
+ ($this->position <= $this->endColumn));
+ }
+
+ /**
+ * Set the iterator to its previous value
+ *
+ * @throws PHPExcel_Exception
+ */
+ public function prev()
+ {
+ if ($this->position <= $this->startColumn) {
+ throw new PHPExcel_Exception(
+ "Column is already at the beginning of range (" .
+ PHPExcel_Cell::stringFromColumnIndex($this->endColumn) . " - " .
+ PHPExcel_Cell::stringFromColumnIndex($this->endColumn) . ")"
+ );
+ }
+
+ do {
+ --$this->position;
+ } while (($this->onlyExistingCells) &&
+ (!$this->subject->cellExistsByColumnAndRow($this->position, $this->rowIndex)) &&
+ ($this->position >= $this->startColumn));
+ }
+
+ /**
+ * Indicate if more columns exist in the worksheet range of columns that we're iterating
+ *
+ * @return boolean
+ */
+ public function valid()
+ {
+ return $this->position <= $this->endColumn;
+ }
+
+ /**
+ * Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary
+ *
+ * @throws PHPExcel_Exception
+ */
+ protected function adjustForExistingOnlyRange()
+ {
+ if ($this->onlyExistingCells) {
+ while ((!$this->subject->cellExistsByColumnAndRow($this->startColumn, $this->rowIndex)) &&
+ ($this->startColumn <= $this->endColumn)) {
+ ++$this->startColumn;
+ }
+ if ($this->startColumn > $this->endColumn) {
+ throw new PHPExcel_Exception('No cells exist within the specified range');
+ }
+ while ((!$this->subject->cellExistsByColumnAndRow($this->endColumn, $this->rowIndex)) &&
+ ($this->endColumn >= $this->startColumn)) {
+ --$this->endColumn;
+ }
+ if ($this->endColumn < $this->startColumn) {
+ throw new PHPExcel_Exception('No cells exist within the specified range');
+ }
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/RowDimension.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/RowDimension.php
new file mode 100755
index 000000000..c1474862c
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/RowDimension.php
@@ -0,0 +1,132 @@
+rowIndex = $pIndex;
+
+ // set dimension as unformatted by default
+ parent::__construct(null);
+ }
+
+ /**
+ * Get Row Index
+ *
+ * @return int
+ */
+ public function getRowIndex()
+ {
+ return $this->rowIndex;
+ }
+
+ /**
+ * Set Row Index
+ *
+ * @param int $pValue
+ * @return PHPExcel_Worksheet_RowDimension
+ */
+ public function setRowIndex($pValue)
+ {
+ $this->rowIndex = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Row Height
+ *
+ * @return double
+ */
+ public function getRowHeight()
+ {
+ return $this->height;
+ }
+
+ /**
+ * Set Row Height
+ *
+ * @param double $pValue
+ * @return PHPExcel_Worksheet_RowDimension
+ */
+ public function setRowHeight($pValue = -1)
+ {
+ $this->height = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get ZeroHeight
+ *
+ * @return bool
+ */
+ public function getZeroHeight()
+ {
+ return $this->zeroHeight;
+ }
+
+ /**
+ * Set ZeroHeight
+ *
+ * @param bool $pValue
+ * @return PHPExcel_Worksheet_RowDimension
+ */
+ public function setZeroHeight($pValue = false)
+ {
+ $this->zeroHeight = $pValue;
+ return $this;
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/RowIterator.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/RowIterator.php
new file mode 100755
index 000000000..9ddb3e030
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/RowIterator.php
@@ -0,0 +1,192 @@
+subject = $subject;
+ $this->resetEnd($endRow);
+ $this->resetStart($startRow);
+ }
+
+ /**
+ * Destructor
+ */
+ public function __destruct()
+ {
+ unset($this->subject);
+ }
+
+ /**
+ * (Re)Set the start row and the current row pointer
+ *
+ * @param integer $startRow The row number at which to start iterating
+ * @return PHPExcel_Worksheet_RowIterator
+ * @throws PHPExcel_Exception
+ */
+ public function resetStart($startRow = 1)
+ {
+ if ($startRow > $this->subject->getHighestRow()) {
+ throw new PHPExcel_Exception("Start row ({$startRow}) is beyond highest row ({$this->subject->getHighestRow()})");
+ }
+
+ $this->startRow = $startRow;
+ if ($this->endRow < $this->startRow) {
+ $this->endRow = $this->startRow;
+ }
+ $this->seek($startRow);
+
+ return $this;
+ }
+
+ /**
+ * (Re)Set the end row
+ *
+ * @param integer $endRow The row number at which to stop iterating
+ * @return PHPExcel_Worksheet_RowIterator
+ */
+ public function resetEnd($endRow = null)
+ {
+ $this->endRow = ($endRow) ? $endRow : $this->subject->getHighestRow();
+
+ return $this;
+ }
+
+ /**
+ * Set the row pointer to the selected row
+ *
+ * @param integer $row The row number to set the current pointer at
+ * @return PHPExcel_Worksheet_RowIterator
+ * @throws PHPExcel_Exception
+ */
+ public function seek($row = 1)
+ {
+ if (($row < $this->startRow) || ($row > $this->endRow)) {
+ throw new PHPExcel_Exception("Row $row is out of range ({$this->startRow} - {$this->endRow})");
+ }
+ $this->position = $row;
+
+ return $this;
+ }
+
+ /**
+ * Rewind the iterator to the starting row
+ */
+ public function rewind()
+ {
+ $this->position = $this->startRow;
+ }
+
+ /**
+ * Return the current row in this worksheet
+ *
+ * @return PHPExcel_Worksheet_Row
+ */
+ public function current()
+ {
+ return new PHPExcel_Worksheet_Row($this->subject, $this->position);
+ }
+
+ /**
+ * Return the current iterator key
+ *
+ * @return int
+ */
+ public function key()
+ {
+ return $this->position;
+ }
+
+ /**
+ * Set the iterator to its next value
+ */
+ public function next()
+ {
+ ++$this->position;
+ }
+
+ /**
+ * Set the iterator to its previous value
+ */
+ public function prev()
+ {
+ if ($this->position <= $this->startRow) {
+ throw new PHPExcel_Exception("Row is already at the beginning of range ({$this->startRow} - {$this->endRow})");
+ }
+
+ --$this->position;
+ }
+
+ /**
+ * Indicate if more rows exist in the worksheet range of rows that we're iterating
+ *
+ * @return boolean
+ */
+ public function valid()
+ {
+ return $this->position <= $this->endRow;
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/SheetView.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/SheetView.php
new file mode 100755
index 000000000..5aaef3ba3
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/SheetView.php
@@ -0,0 +1,187 @@
+zoomScale;
+ }
+
+ /**
+ * Set ZoomScale
+ *
+ * Valid values range from 10 to 400.
+ *
+ * @param int $pValue
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_SheetView
+ */
+ public function setZoomScale($pValue = 100)
+ {
+ // Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface,
+ // but it is apparently still able to handle any scale >= 1
+ if (($pValue >= 1) || is_null($pValue)) {
+ $this->zoomScale = $pValue;
+ } else {
+ throw new PHPExcel_Exception("Scale must be greater than or equal to 1.");
+ }
+ return $this;
+ }
+
+ /**
+ * Get ZoomScaleNormal
+ *
+ * @return int
+ */
+ public function getZoomScaleNormal()
+ {
+ return $this->zoomScaleNormal;
+ }
+
+ /**
+ * Set ZoomScale
+ *
+ * Valid values range from 10 to 400.
+ *
+ * @param int $pValue
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_SheetView
+ */
+ public function setZoomScaleNormal($pValue = 100)
+ {
+ if (($pValue >= 1) || is_null($pValue)) {
+ $this->zoomScaleNormal = $pValue;
+ } else {
+ throw new PHPExcel_Exception("Scale must be greater than or equal to 1.");
+ }
+ return $this;
+ }
+
+ /**
+ * Get View
+ *
+ * @return string
+ */
+ public function getView()
+ {
+ return $this->sheetviewType;
+ }
+
+ /**
+ * Set View
+ *
+ * Valid values are
+ * 'normal' self::SHEETVIEW_NORMAL
+ * 'pageLayout' self::SHEETVIEW_PAGE_LAYOUT
+ * 'pageBreakPreview' self::SHEETVIEW_PAGE_BREAK_PREVIEW
+ *
+ * @param string $pValue
+ * @throws PHPExcel_Exception
+ * @return PHPExcel_Worksheet_SheetView
+ */
+ public function setView($pValue = null)
+ {
+ // MS Excel 2007 allows setting the view to 'normal', 'pageLayout' or 'pageBreakPreview' via the user interface
+ if ($pValue === null) {
+ $pValue = self::SHEETVIEW_NORMAL;
+ }
+ if (in_array($pValue, self::$sheetViewTypes)) {
+ $this->sheetviewType = $pValue;
+ } else {
+ throw new PHPExcel_Exception("Invalid sheetview layout type.");
+ }
+
+ return $this;
+ }
+
+ /**
+ * 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;
+ }
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/WorksheetIterator.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/WorksheetIterator.php
new file mode 100755
index 000000000..cb1b28118
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/WorksheetIterator.php
@@ -0,0 +1,108 @@
+subject = $subject;
+ }
+
+ /**
+ * Destructor
+ */
+ public function __destruct()
+ {
+ unset($this->subject);
+ }
+
+ /**
+ * Rewind iterator
+ */
+ public function rewind()
+ {
+ $this->position = 0;
+ }
+
+ /**
+ * Current PHPExcel_Worksheet
+ *
+ * @return PHPExcel_Worksheet
+ */
+ public function current()
+ {
+ return $this->subject->getSheet($this->position);
+ }
+
+ /**
+ * Current key
+ *
+ * @return int
+ */
+ public function key()
+ {
+ return $this->position;
+ }
+
+ /**
+ * Next value
+ */
+ public function next()
+ {
+ ++$this->position;
+ }
+
+ /**
+ * More PHPExcel_Worksheet instances available?
+ *
+ * @return boolean
+ */
+ public function valid()
+ {
+ return $this->position < $this->subject->getSheetCount();
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Abstract.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Abstract.php
new file mode 100755
index 000000000..2a797a948
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Abstract.php
@@ -0,0 +1,157 @@
+includeCharts;
+ }
+
+ /**
+ * Set write charts in workbook
+ * Set to true, to advise the Writer to include any charts that exist in the PHPExcel object.
+ * Set to false (the default) to ignore charts.
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Writer_IWriter
+ */
+ public function setIncludeCharts($pValue = false)
+ {
+ $this->includeCharts = (boolean) $pValue;
+ return $this;
+ }
+
+ /**
+ * Get Pre-Calculate Formulas flag
+ * If this is true (the default), then the writer will recalculate all formulae in a workbook when saving,
+ * so that the pre-calculated values are immediately available to MS Excel or other office spreadsheet
+ * viewer when opening the file
+ * If false, then formulae are not calculated on save. This is faster for saving in PHPExcel, but slower
+ * when opening the resulting file in MS Excel, because Excel has to recalculate the formulae itself
+ *
+ * @return boolean
+ */
+ public function getPreCalculateFormulas()
+ {
+ return $this->preCalculateFormulas;
+ }
+
+ /**
+ * Set Pre-Calculate Formulas
+ * Set to true (the default) to advise the Writer to calculate all formulae on save
+ * Set to false to prevent precalculation of formulae on save.
+ *
+ * @param boolean $pValue Pre-Calculate Formulas?
+ * @return PHPExcel_Writer_IWriter
+ */
+ public function setPreCalculateFormulas($pValue = true)
+ {
+ $this->preCalculateFormulas = (boolean) $pValue;
+ return $this;
+ }
+
+ /**
+ * Get use disk caching where possible?
+ *
+ * @return boolean
+ */
+ public function getUseDiskCaching()
+ {
+ return $this->_useDiskCaching;
+ }
+
+ /**
+ * Set use disk caching where possible?
+ *
+ * @param boolean $pValue
+ * @param string $pDirectory Disk caching directory
+ * @throws PHPExcel_Writer_Exception when directory does not exist
+ * @return PHPExcel_Writer_Excel2007
+ */
+ public function setUseDiskCaching($pValue = false, $pDirectory = null)
+ {
+ $this->_useDiskCaching = $pValue;
+
+ if ($pDirectory !== null) {
+ if (is_dir($pDirectory)) {
+ $this->_diskCachingDirectory = $pDirectory;
+ } else {
+ throw new PHPExcel_Writer_Exception("Directory does not exist: $pDirectory");
+ }
+ }
+ return $this;
+ }
+
+ /**
+ * Get disk caching directory
+ *
+ * @return string
+ */
+ public function getDiskCachingDirectory()
+ {
+ return $this->_diskCachingDirectory;
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/CSV.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/CSV.php
new file mode 100755
index 000000000..e59c30130
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/CSV.php
@@ -0,0 +1,352 @@
+phpExcel = $phpExcel;
+ }
+
+ /**
+ * Save PHPExcel to file
+ *
+ * @param string $pFilename
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function save($pFilename = null)
+ {
+ // Fetch sheet
+ $sheet = $this->phpExcel->getSheet($this->sheetIndex);
+
+ $saveDebugLog = PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->getWriteDebugLog();
+ PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog(false);
+ $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType();
+ PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE);
+
+ // Open file
+ $fileHandle = fopen($pFilename, 'wb+');
+ if ($fileHandle === false) {
+ throw new PHPExcel_Writer_Exception("Could not open file $pFilename for writing.");
+ }
+
+ if ($this->excelCompatibility) {
+ $this->setUseBOM(true); // Enforce UTF-8 BOM Header
+ $this->setIncludeSeparatorLine(true); // Set separator line
+ $this->setEnclosure('"'); // Set enclosure to "
+ $this->setDelimiter(";"); // Set delimiter to a semi-colon
+ $this->setLineEnding("\r\n");
+ }
+ if ($this->useBOM) {
+ // Write the UTF-8 BOM code if required
+ fwrite($fileHandle, "\xEF\xBB\xBF");
+ }
+ if ($this->includeSeparatorLine) {
+ // Write the separator line if required
+ fwrite($fileHandle, 'sep=' . $this->getDelimiter() . $this->lineEnding);
+ }
+
+ // Identify the range that we need to extract from the worksheet
+ $maxCol = $sheet->getHighestDataColumn();
+ $maxRow = $sheet->getHighestDataRow();
+
+ // Write rows to file
+ for ($row = 1; $row <= $maxRow; ++$row) {
+ // Convert the row to an array...
+ $cellsArray = $sheet->rangeToArray('A'.$row.':'.$maxCol.$row, '', $this->preCalculateFormulas);
+ // ... and write to the file
+ $this->writeLine($fileHandle, $cellsArray[0]);
+ }
+
+ // Close file
+ fclose($fileHandle);
+
+ PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType);
+ PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog);
+ }
+
+ /**
+ * Get delimiter
+ *
+ * @return string
+ */
+ public function getDelimiter()
+ {
+ return $this->delimiter;
+ }
+
+ /**
+ * Set delimiter
+ *
+ * @param string $pValue Delimiter, defaults to ,
+ * @return PHPExcel_Writer_CSV
+ */
+ public function setDelimiter($pValue = ',')
+ {
+ $this->delimiter = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get enclosure
+ *
+ * @return string
+ */
+ public function getEnclosure()
+ {
+ return $this->enclosure;
+ }
+
+ /**
+ * Set enclosure
+ *
+ * @param string $pValue Enclosure, defaults to "
+ * @return PHPExcel_Writer_CSV
+ */
+ public function setEnclosure($pValue = '"')
+ {
+ if ($pValue == '') {
+ $pValue = null;
+ }
+ $this->enclosure = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get line ending
+ *
+ * @return string
+ */
+ public function getLineEnding()
+ {
+ return $this->lineEnding;
+ }
+
+ /**
+ * Set line ending
+ *
+ * @param string $pValue Line ending, defaults to OS line ending (PHP_EOL)
+ * @return PHPExcel_Writer_CSV
+ */
+ public function setLineEnding($pValue = PHP_EOL)
+ {
+ $this->lineEnding = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get whether BOM should be used
+ *
+ * @return boolean
+ */
+ public function getUseBOM()
+ {
+ return $this->useBOM;
+ }
+
+ /**
+ * Set whether BOM should be used
+ *
+ * @param boolean $pValue Use UTF-8 byte-order mark? Defaults to false
+ * @return PHPExcel_Writer_CSV
+ */
+ public function setUseBOM($pValue = false)
+ {
+ $this->useBOM = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get whether a separator line should be included
+ *
+ * @return boolean
+ */
+ public function getIncludeSeparatorLine()
+ {
+ return $this->includeSeparatorLine;
+ }
+
+ /**
+ * Set whether a separator line should be included as the first line of the file
+ *
+ * @param boolean $pValue Use separator line? Defaults to false
+ * @return PHPExcel_Writer_CSV
+ */
+ public function setIncludeSeparatorLine($pValue = false)
+ {
+ $this->includeSeparatorLine = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get whether the file should be saved with full Excel Compatibility
+ *
+ * @return boolean
+ */
+ public function getExcelCompatibility()
+ {
+ return $this->excelCompatibility;
+ }
+
+ /**
+ * Set whether the file should be saved with full Excel Compatibility
+ *
+ * @param boolean $pValue Set the file to be written as a fully Excel compatible csv file
+ * Note that this overrides other settings such as useBOM, enclosure and delimiter
+ * @return PHPExcel_Writer_CSV
+ */
+ public function setExcelCompatibility($pValue = false)
+ {
+ $this->excelCompatibility = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get sheet index
+ *
+ * @return int
+ */
+ public function getSheetIndex()
+ {
+ return $this->sheetIndex;
+ }
+
+ /**
+ * Set sheet index
+ *
+ * @param int $pValue Sheet index
+ * @return PHPExcel_Writer_CSV
+ */
+ public function setSheetIndex($pValue = 0)
+ {
+ $this->sheetIndex = $pValue;
+ return $this;
+ }
+
+ /**
+ * Write line to CSV file
+ *
+ * @param mixed $pFileHandle PHP filehandle
+ * @param array $pValues Array containing values in a row
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeLine($pFileHandle = null, $pValues = null)
+ {
+ if (is_array($pValues)) {
+ // No leading delimiter
+ $writeDelimiter = false;
+
+ // Build the line
+ $line = '';
+
+ foreach ($pValues as $element) {
+ // Escape enclosures
+ $element = str_replace($this->enclosure, $this->enclosure . $this->enclosure, $element);
+
+ // Add delimiter
+ if ($writeDelimiter) {
+ $line .= $this->delimiter;
+ } else {
+ $writeDelimiter = true;
+ }
+
+ // Add enclosed string
+ $line .= $this->enclosure . $element . $this->enclosure;
+ }
+
+ // Add line ending
+ $line .= $this->lineEnding;
+
+ // Write to file
+ fwrite($pFileHandle, $line);
+ } else {
+ throw new PHPExcel_Writer_Exception("Invalid data row passed to CSV writer.");
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007.php
new file mode 100755
index 000000000..11d354b4a
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007.php
@@ -0,0 +1,533 @@
+setPHPExcel($pPHPExcel);
+
+ $writerPartsArray = array( 'stringtable' => 'PHPExcel_Writer_Excel2007_StringTable',
+ 'contenttypes' => 'PHPExcel_Writer_Excel2007_ContentTypes',
+ 'docprops' => 'PHPExcel_Writer_Excel2007_DocProps',
+ 'rels' => 'PHPExcel_Writer_Excel2007_Rels',
+ 'theme' => 'PHPExcel_Writer_Excel2007_Theme',
+ 'style' => 'PHPExcel_Writer_Excel2007_Style',
+ 'workbook' => 'PHPExcel_Writer_Excel2007_Workbook',
+ 'worksheet' => 'PHPExcel_Writer_Excel2007_Worksheet',
+ 'drawing' => 'PHPExcel_Writer_Excel2007_Drawing',
+ 'comments' => 'PHPExcel_Writer_Excel2007_Comments',
+ 'chart' => 'PHPExcel_Writer_Excel2007_Chart',
+ 'relsvba' => 'PHPExcel_Writer_Excel2007_RelsVBA',
+ 'relsribbonobjects' => 'PHPExcel_Writer_Excel2007_RelsRibbon'
+ );
+
+ // Initialise writer parts
+ // and Assign their parent IWriters
+ foreach ($writerPartsArray as $writer => $class) {
+ $this->writerParts[$writer] = new $class($this);
+ }
+
+ $hashTablesArray = array( 'stylesConditionalHashTable', 'fillHashTable', 'fontHashTable',
+ 'bordersHashTable', 'numFmtHashTable', 'drawingHashTable',
+ 'styleHashTable'
+ );
+
+ // Set HashTable variables
+ foreach ($hashTablesArray as $tableName) {
+ $this->$tableName = new PHPExcel_HashTable();
+ }
+ }
+
+ /**
+ * Get writer part
+ *
+ * @param string $pPartName Writer part name
+ * @return PHPExcel_Writer_Excel2007_WriterPart
+ */
+ public function getWriterPart($pPartName = '')
+ {
+ if ($pPartName != '' && isset($this->writerParts[strtolower($pPartName)])) {
+ return $this->writerParts[strtolower($pPartName)];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Save PHPExcel to file
+ *
+ * @param string $pFilename
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function save($pFilename = null)
+ {
+ if ($this->spreadSheet !== null) {
+ // garbage collect
+ $this->spreadSheet->garbageCollect();
+
+ // If $pFilename is php://output or php://stdout, make it a temporary file...
+ $originalFilename = $pFilename;
+ if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
+ $pFilename = @tempnam(PHPExcel_Shared_File::sys_get_temp_dir(), 'phpxltmp');
+ if ($pFilename == '') {
+ $pFilename = $originalFilename;
+ }
+ }
+
+ $saveDebugLog = PHPExcel_Calculation::getInstance($this->spreadSheet)->getDebugLog()->getWriteDebugLog();
+ PHPExcel_Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog(false);
+ $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType();
+ PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);
+
+ // Create string lookup table
+ $this->stringTable = array();
+ for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
+ $this->stringTable = $this->getWriterPart('StringTable')->createStringTable($this->spreadSheet->getSheet($i), $this->stringTable);
+ }
+
+ // Create styles dictionaries
+ $this->styleHashTable->addFromSource($this->getWriterPart('Style')->allStyles($this->spreadSheet));
+ $this->stylesConditionalHashTable->addFromSource($this->getWriterPart('Style')->allConditionalStyles($this->spreadSheet));
+ $this->fillHashTable->addFromSource($this->getWriterPart('Style')->allFills($this->spreadSheet));
+ $this->fontHashTable->addFromSource($this->getWriterPart('Style')->allFonts($this->spreadSheet));
+ $this->bordersHashTable->addFromSource($this->getWriterPart('Style')->allBorders($this->spreadSheet));
+ $this->numFmtHashTable->addFromSource($this->getWriterPart('Style')->allNumberFormats($this->spreadSheet));
+
+ // Create drawing dictionary
+ $this->drawingHashTable->addFromSource($this->getWriterPart('Drawing')->allDrawings($this->spreadSheet));
+
+ // Create new ZIP file and open it for writing
+ $zipClass = PHPExcel_Settings::getZipClass();
+ $objZip = new $zipClass();
+
+ // Retrieve OVERWRITE and CREATE constants from the instantiated zip class
+ // This method of accessing constant values from a dynamic class should work with all appropriate versions of PHP
+ $ro = new ReflectionObject($objZip);
+ $zipOverWrite = $ro->getConstant('OVERWRITE');
+ $zipCreate = $ro->getConstant('CREATE');
+
+ if (file_exists($pFilename)) {
+ unlink($pFilename);
+ }
+ // Try opening the ZIP file
+ if ($objZip->open($pFilename, $zipOverWrite) !== true) {
+ if ($objZip->open($pFilename, $zipCreate) !== true) {
+ throw new PHPExcel_Writer_Exception("Could not open " . $pFilename . " for writing.");
+ }
+ }
+
+ // Add [Content_Types].xml to ZIP file
+ $objZip->addFromString('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->spreadSheet, $this->includeCharts));
+
+ //if hasMacros, add the vbaProject.bin file, Certificate file(if exists)
+ if ($this->spreadSheet->hasMacros()) {
+ $macrosCode=$this->spreadSheet->getMacrosCode();
+ if (!is_null($macrosCode)) {// we have the code ?
+ $objZip->addFromString('xl/vbaProject.bin', $macrosCode);//allways in 'xl', allways named vbaProject.bin
+ if ($this->spreadSheet->hasMacrosCertificate()) {//signed macros ?
+ // Yes : add the certificate file and the related rels file
+ $objZip->addFromString('xl/vbaProjectSignature.bin', $this->spreadSheet->getMacrosCertificate());
+ $objZip->addFromString('xl/_rels/vbaProject.bin.rels', $this->getWriterPart('RelsVBA')->writeVBARelationships($this->spreadSheet));
+ }
+ }
+ }
+ //a custom UI in this workbook ? add it ("base" xml and additional objects (pictures) and rels)
+ if ($this->spreadSheet->hasRibbon()) {
+ $tmpRibbonTarget=$this->spreadSheet->getRibbonXMLData('target');
+ $objZip->addFromString($tmpRibbonTarget, $this->spreadSheet->getRibbonXMLData('data'));
+ if ($this->spreadSheet->hasRibbonBinObjects()) {
+ $tmpRootPath=dirname($tmpRibbonTarget).'/';
+ $ribbonBinObjects=$this->spreadSheet->getRibbonBinObjects('data');//the files to write
+ foreach ($ribbonBinObjects as $aPath => $aContent) {
+ $objZip->addFromString($tmpRootPath.$aPath, $aContent);
+ }
+ //the rels for files
+ $objZip->addFromString($tmpRootPath.'_rels/'.basename($tmpRibbonTarget).'.rels', $this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->spreadSheet));
+ }
+ }
+
+ // Add relationships to ZIP file
+ $objZip->addFromString('_rels/.rels', $this->getWriterPart('Rels')->writeRelationships($this->spreadSheet));
+ $objZip->addFromString('xl/_rels/workbook.xml.rels', $this->getWriterPart('Rels')->writeWorkbookRelationships($this->spreadSheet));
+
+ // Add document properties to ZIP file
+ $objZip->addFromString('docProps/app.xml', $this->getWriterPart('DocProps')->writeDocPropsApp($this->spreadSheet));
+ $objZip->addFromString('docProps/core.xml', $this->getWriterPart('DocProps')->writeDocPropsCore($this->spreadSheet));
+ $customPropertiesPart = $this->getWriterPart('DocProps')->writeDocPropsCustom($this->spreadSheet);
+ if ($customPropertiesPart !== null) {
+ $objZip->addFromString('docProps/custom.xml', $customPropertiesPart);
+ }
+
+ // Add theme to ZIP file
+ $objZip->addFromString('xl/theme/theme1.xml', $this->getWriterPart('Theme')->writeTheme($this->spreadSheet));
+
+ // Add string table to ZIP file
+ $objZip->addFromString('xl/sharedStrings.xml', $this->getWriterPart('StringTable')->writeStringTable($this->stringTable));
+
+ // Add styles to ZIP file
+ $objZip->addFromString('xl/styles.xml', $this->getWriterPart('Style')->writeStyles($this->spreadSheet));
+
+ // Add workbook to ZIP file
+ $objZip->addFromString('xl/workbook.xml', $this->getWriterPart('Workbook')->writeWorkbook($this->spreadSheet, $this->preCalculateFormulas));
+
+ $chartCount = 0;
+ // Add worksheets
+ for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
+ $objZip->addFromString('xl/worksheets/sheet' . ($i + 1) . '.xml', $this->getWriterPart('Worksheet')->writeWorksheet($this->spreadSheet->getSheet($i), $this->stringTable, $this->includeCharts));
+ if ($this->includeCharts) {
+ $charts = $this->spreadSheet->getSheet($i)->getChartCollection();
+ if (count($charts) > 0) {
+ foreach ($charts as $chart) {
+ $objZip->addFromString('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart, $this->preCalculateFormulas));
+ $chartCount++;
+ }
+ }
+ }
+ }
+
+ $chartRef1 = $chartRef2 = 0;
+ // Add worksheet relationships (drawings, ...)
+ for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
+ // Add relationships
+ $objZip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->spreadSheet->getSheet($i), ($i + 1), $this->includeCharts));
+
+ $drawings = $this->spreadSheet->getSheet($i)->getDrawingCollection();
+ $drawingCount = count($drawings);
+ if ($this->includeCharts) {
+ $chartCount = $this->spreadSheet->getSheet($i)->getChartCount();
+ }
+
+ // Add drawing and image relationship parts
+ if (($drawingCount > 0) || ($chartCount > 0)) {
+ // Drawing relationships
+ $objZip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->spreadSheet->getSheet($i), $chartRef1, $this->includeCharts));
+
+ // Drawings
+ $objZip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $chartRef2, $this->includeCharts));
+ }
+
+ // Add comment relationship parts
+ if (count($this->spreadSheet->getSheet($i)->getComments()) > 0) {
+ // VML Comments
+ $objZip->addFromString('xl/drawings/vmlDrawing' . ($i + 1) . '.vml', $this->getWriterPart('Comments')->writeVMLComments($this->spreadSheet->getSheet($i)));
+
+ // Comments
+ $objZip->addFromString('xl/comments' . ($i + 1) . '.xml', $this->getWriterPart('Comments')->writeComments($this->spreadSheet->getSheet($i)));
+ }
+
+ // Add header/footer relationship parts
+ if (count($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) {
+ // VML Drawings
+ $objZip->addFromString('xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml', $this->getWriterPart('Drawing')->writeVMLHeaderFooterImages($this->spreadSheet->getSheet($i)));
+
+ // VML Drawing relationships
+ $objZip->addFromString('xl/drawings/_rels/vmlDrawingHF' . ($i + 1) . '.vml.rels', $this->getWriterPart('Rels')->writeHeaderFooterDrawingRelationships($this->spreadSheet->getSheet($i)));
+
+ // Media
+ foreach ($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages() as $image) {
+ $objZip->addFromString('xl/media/' . $image->getIndexedFilename(), file_get_contents($image->getPath()));
+ }
+ }
+ }
+
+ // Add media
+ for ($i = 0; $i < $this->getDrawingHashTable()->count(); ++$i) {
+ if ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) {
+ $imageContents = null;
+ $imagePath = $this->getDrawingHashTable()->getByIndex($i)->getPath();
+ if (strpos($imagePath, 'zip://') !== false) {
+ $imagePath = substr($imagePath, 6);
+ $imagePathSplitted = explode('#', $imagePath);
+
+ $imageZip = new ZipArchive();
+ $imageZip->open($imagePathSplitted[0]);
+ $imageContents = $imageZip->getFromName($imagePathSplitted[1]);
+ $imageZip->close();
+ unset($imageZip);
+ } else {
+ $imageContents = file_get_contents($imagePath);
+ }
+
+ $objZip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents);
+ } elseif ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) {
+ ob_start();
+ call_user_func(
+ $this->getDrawingHashTable()->getByIndex($i)->getRenderingFunction(),
+ $this->getDrawingHashTable()->getByIndex($i)->getImageResource()
+ );
+ $imageContents = ob_get_contents();
+ ob_end_clean();
+
+ $objZip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents);
+ }
+ }
+
+ PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType);
+ PHPExcel_Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog);
+
+ // Close file
+ if ($objZip->close() === false) {
+ throw new PHPExcel_Writer_Exception("Could not close zip file $pFilename.");
+ }
+
+ // If a temporary file was used, copy it to the correct file stream
+ if ($originalFilename != $pFilename) {
+ if (copy($pFilename, $originalFilename) === false) {
+ throw new PHPExcel_Writer_Exception("Could not copy temporary zip file $pFilename to $originalFilename.");
+ }
+ @unlink($pFilename);
+ }
+ } else {
+ throw new PHPExcel_Writer_Exception("PHPExcel object unassigned.");
+ }
+ }
+
+ /**
+ * Get PHPExcel object
+ *
+ * @return PHPExcel
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function getPHPExcel()
+ {
+ if ($this->spreadSheet !== null) {
+ return $this->spreadSheet;
+ } else {
+ throw new PHPExcel_Writer_Exception("No PHPExcel object assigned.");
+ }
+ }
+
+ /**
+ * Set PHPExcel object
+ *
+ * @param PHPExcel $pPHPExcel PHPExcel object
+ * @throws PHPExcel_Writer_Exception
+ * @return PHPExcel_Writer_Excel2007
+ */
+ public function setPHPExcel(PHPExcel $pPHPExcel = null)
+ {
+ $this->spreadSheet = $pPHPExcel;
+ return $this;
+ }
+
+ /**
+ * Get string table
+ *
+ * @return string[]
+ */
+ public function getStringTable()
+ {
+ return $this->stringTable;
+ }
+
+ /**
+ * Get PHPExcel_Style HashTable
+ *
+ * @return PHPExcel_HashTable
+ */
+ public function getStyleHashTable()
+ {
+ return $this->styleHashTable;
+ }
+
+ /**
+ * Get PHPExcel_Style_Conditional HashTable
+ *
+ * @return PHPExcel_HashTable
+ */
+ public function getStylesConditionalHashTable()
+ {
+ return $this->stylesConditionalHashTable;
+ }
+
+ /**
+ * Get PHPExcel_Style_Fill HashTable
+ *
+ * @return PHPExcel_HashTable
+ */
+ public function getFillHashTable()
+ {
+ return $this->fillHashTable;
+ }
+
+ /**
+ * Get PHPExcel_Style_Font HashTable
+ *
+ * @return PHPExcel_HashTable
+ */
+ public function getFontHashTable()
+ {
+ return $this->fontHashTable;
+ }
+
+ /**
+ * Get PHPExcel_Style_Borders HashTable
+ *
+ * @return PHPExcel_HashTable
+ */
+ public function getBordersHashTable()
+ {
+ return $this->bordersHashTable;
+ }
+
+ /**
+ * Get PHPExcel_Style_NumberFormat HashTable
+ *
+ * @return PHPExcel_HashTable
+ */
+ public function getNumFmtHashTable()
+ {
+ return $this->numFmtHashTable;
+ }
+
+ /**
+ * Get PHPExcel_Worksheet_BaseDrawing HashTable
+ *
+ * @return PHPExcel_HashTable
+ */
+ public function getDrawingHashTable()
+ {
+ return $this->drawingHashTable;
+ }
+
+ /**
+ * Get Office2003 compatibility
+ *
+ * @return boolean
+ */
+ public function getOffice2003Compatibility()
+ {
+ return $this->office2003compatibility;
+ }
+
+ /**
+ * Set Office2003 compatibility
+ *
+ * @param boolean $pValue Office2003 compatibility?
+ * @return PHPExcel_Writer_Excel2007
+ */
+ public function setOffice2003Compatibility($pValue = false)
+ {
+ $this->office2003compatibility = $pValue;
+ return $this;
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Chart.php
new file mode 100755
index 000000000..92fa21506
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Chart.php
@@ -0,0 +1,1520 @@
+calculateCellValues = $calculateCellValues;
+
+ // Create XML writer
+ $objWriter = null;
+ if ($this->getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+ // Ensure that data series values are up-to-date before we save
+ if ($this->calculateCellValues) {
+ $pChart->refresh();
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // c:chartSpace
+ $objWriter->startElement('c:chartSpace');
+ $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
+ $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');
+ $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
+
+ $objWriter->startElement('c:date1904');
+ $objWriter->writeAttribute('val', 0);
+ $objWriter->endElement();
+ $objWriter->startElement('c:lang');
+ $objWriter->writeAttribute('val', "en-GB");
+ $objWriter->endElement();
+ $objWriter->startElement('c:roundedCorners');
+ $objWriter->writeAttribute('val', 0);
+ $objWriter->endElement();
+
+ $this->writeAlternateContent($objWriter);
+
+ $objWriter->startElement('c:chart');
+
+ $this->writeTitle($pChart->getTitle(), $objWriter);
+
+ $objWriter->startElement('c:autoTitleDeleted');
+ $objWriter->writeAttribute('val', 0);
+ $objWriter->endElement();
+
+ $this->writePlotArea($pChart->getPlotArea(), $pChart->getXAxisLabel(), $pChart->getYAxisLabel(), $objWriter, $pChart->getWorksheet(), $pChart->getChartAxisX(), $pChart->getChartAxisY(), $pChart->getMajorGridlines(), $pChart->getMinorGridlines());
+
+ $this->writeLegend($pChart->getLegend(), $objWriter);
+
+ $objWriter->startElement('c:plotVisOnly');
+ $objWriter->writeAttribute('val', 1);
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:dispBlanksAs');
+ $objWriter->writeAttribute('val', "gap");
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:showDLblsOverMax');
+ $objWriter->writeAttribute('val', 0);
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $this->writePrintSettings($objWriter);
+
+ $objWriter->endElement();
+
+ // Return
+ return $objWriter->getData();
+ }
+
+ /**
+ * Write Chart Title
+ *
+ * @param PHPExcel_Chart_Title $title
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ *
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeTitle(PHPExcel_Chart_Title $title = null, $objWriter)
+ {
+ if (is_null($title)) {
+ return;
+ }
+
+ $objWriter->startElement('c:title');
+ $objWriter->startElement('c:tx');
+ $objWriter->startElement('c:rich');
+
+ $objWriter->startElement('a:bodyPr');
+ $objWriter->endElement();
+
+ $objWriter->startElement('a:lstStyle');
+ $objWriter->endElement();
+
+ $objWriter->startElement('a:p');
+
+ $caption = $title->getCaption();
+ if ((is_array($caption)) && (count($caption) > 0)) {
+ $caption = $caption[0];
+ }
+ $this->getParentWriter()->getWriterPart('stringtable')->writeRichTextForCharts($objWriter, $caption, 'a');
+
+ $objWriter->endElement();
+ $objWriter->endElement();
+ $objWriter->endElement();
+
+ $this->writeLayout($title->getLayout(), $objWriter);
+
+ $objWriter->startElement('c:overlay');
+ $objWriter->writeAttribute('val', 0);
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write Chart Legend
+ *
+ * @param PHPExcel_Chart_Legend $legend
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ *
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeLegend(PHPExcel_Chart_Legend $legend = null, $objWriter)
+ {
+ if (is_null($legend)) {
+ return;
+ }
+
+ $objWriter->startElement('c:legend');
+
+ $objWriter->startElement('c:legendPos');
+ $objWriter->writeAttribute('val', $legend->getPosition());
+ $objWriter->endElement();
+
+ $this->writeLayout($legend->getLayout(), $objWriter);
+
+ $objWriter->startElement('c:overlay');
+ $objWriter->writeAttribute('val', ($legend->getOverlay()) ? '1' : '0');
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:txPr');
+ $objWriter->startElement('a:bodyPr');
+ $objWriter->endElement();
+
+ $objWriter->startElement('a:lstStyle');
+ $objWriter->endElement();
+
+ $objWriter->startElement('a:p');
+ $objWriter->startElement('a:pPr');
+ $objWriter->writeAttribute('rtl', 0);
+
+ $objWriter->startElement('a:defRPr');
+ $objWriter->endElement();
+ $objWriter->endElement();
+
+ $objWriter->startElement('a:endParaRPr');
+ $objWriter->writeAttribute('lang', "en-US");
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write Chart Plot Area
+ *
+ * @param PHPExcel_Chart_PlotArea $plotArea
+ * @param PHPExcel_Chart_Title $xAxisLabel
+ * @param PHPExcel_Chart_Title $yAxisLabel
+ * @param PHPExcel_Chart_Axis $xAxis
+ * @param PHPExcel_Chart_Axis $yAxis
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ *
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writePlotArea(PHPExcel_Chart_PlotArea $plotArea, PHPExcel_Chart_Title $xAxisLabel = null, PHPExcel_Chart_Title $yAxisLabel = null, $objWriter, PHPExcel_Worksheet $pSheet, PHPExcel_Chart_Axis $xAxis, PHPExcel_Chart_Axis $yAxis, PHPExcel_Chart_GridLines $majorGridlines, PHPExcel_Chart_GridLines $minorGridlines)
+ {
+ if (is_null($plotArea)) {
+ return;
+ }
+
+ $id1 = $id2 = 0;
+ $this->_seriesIndex = 0;
+ $objWriter->startElement('c:plotArea');
+
+ $layout = $plotArea->getLayout();
+
+ $this->writeLayout($layout, $objWriter);
+
+ $chartTypes = self::getChartType($plotArea);
+ $catIsMultiLevelSeries = $valIsMultiLevelSeries = false;
+ $plotGroupingType = '';
+ foreach ($chartTypes as $chartType) {
+ $objWriter->startElement('c:' . $chartType);
+
+ $groupCount = $plotArea->getPlotGroupCount();
+ for ($i = 0; $i < $groupCount; ++$i) {
+ $plotGroup = $plotArea->getPlotGroupByIndex($i);
+ $groupType = $plotGroup->getPlotType();
+ if ($groupType == $chartType) {
+ $plotStyle = $plotGroup->getPlotStyle();
+ if ($groupType === PHPExcel_Chart_DataSeries::TYPE_RADARCHART) {
+ $objWriter->startElement('c:radarStyle');
+ $objWriter->writeAttribute('val', $plotStyle);
+ $objWriter->endElement();
+ } elseif ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART) {
+ $objWriter->startElement('c:scatterStyle');
+ $objWriter->writeAttribute('val', $plotStyle);
+ $objWriter->endElement();
+ }
+
+ $this->writePlotGroup($plotGroup, $chartType, $objWriter, $catIsMultiLevelSeries, $valIsMultiLevelSeries, $plotGroupingType, $pSheet);
+ }
+ }
+
+ $this->writeDataLabels($objWriter, $layout);
+
+ if ($chartType === PHPExcel_Chart_DataSeries::TYPE_LINECHART) {
+ // Line only, Line3D can't be smoothed
+
+ $objWriter->startElement('c:smooth');
+ $objWriter->writeAttribute('val', (integer) $plotGroup->getSmoothLine());
+ $objWriter->endElement();
+ } elseif (($chartType === PHPExcel_Chart_DataSeries::TYPE_BARCHART) ||($chartType === PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D)) {
+ $objWriter->startElement('c:gapWidth');
+ $objWriter->writeAttribute('val', 150);
+ $objWriter->endElement();
+
+ if ($plotGroupingType == 'percentStacked' || $plotGroupingType == 'stacked') {
+ $objWriter->startElement('c:overlap');
+ $objWriter->writeAttribute('val', 100);
+ $objWriter->endElement();
+ }
+ } elseif ($chartType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) {
+ $objWriter->startElement('c:bubbleScale');
+ $objWriter->writeAttribute('val', 25);
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:showNegBubbles');
+ $objWriter->writeAttribute('val', 0);
+ $objWriter->endElement();
+ } elseif ($chartType === PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) {
+ $objWriter->startElement('c:hiLowLines');
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:upDownBars');
+
+ $objWriter->startElement('c:gapWidth');
+ $objWriter->writeAttribute('val', 300);
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:upBars');
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:downBars');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+
+ // Generate 2 unique numbers to use for axId values
+ // $id1 = $id2 = rand(10000000,99999999);
+ // do {
+ // $id2 = rand(10000000,99999999);
+ // } while ($id1 == $id2);
+ $id1 = '75091328';
+ $id2 = '75089408';
+
+ if (($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART) && ($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && ($chartType !== PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) {
+ $objWriter->startElement('c:axId');
+ $objWriter->writeAttribute('val', $id1);
+ $objWriter->endElement();
+ $objWriter->startElement('c:axId');
+ $objWriter->writeAttribute('val', $id2);
+ $objWriter->endElement();
+ } else {
+ $objWriter->startElement('c:firstSliceAng');
+ $objWriter->writeAttribute('val', 0);
+ $objWriter->endElement();
+
+ if ($chartType === PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) {
+ $objWriter->startElement('c:holeSize');
+ $objWriter->writeAttribute('val', 50);
+ $objWriter->endElement();
+ }
+ }
+
+ $objWriter->endElement();
+ }
+
+ if (($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART) && ($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && ($chartType !== PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) {
+ if ($chartType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) {
+ $this->writeValueAxis($objWriter, $plotArea, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines);
+ } else {
+ $this->writeCategoryAxis($objWriter, $plotArea, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $yAxis);
+ }
+
+ $this->writeValueAxis($objWriter, $plotArea, $yAxisLabel, $chartType, $id1, $id2, $valIsMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines);
+ }
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write Data Labels
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Chart_Layout $chartLayout Chart layout
+ *
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeDataLabels($objWriter, $chartLayout)
+ {
+ $objWriter->startElement('c:dLbls');
+
+ $objWriter->startElement('c:showLegendKey');
+ $showLegendKey = (empty($chartLayout)) ? 0 : $chartLayout->getShowLegendKey();
+ $objWriter->writeAttribute('val', ((empty($showLegendKey)) ? 0 : 1));
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:showVal');
+ $showVal = (empty($chartLayout)) ? 0 : $chartLayout->getShowVal();
+ $objWriter->writeAttribute('val', ((empty($showVal)) ? 0 : 1));
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:showCatName');
+ $showCatName = (empty($chartLayout)) ? 0 : $chartLayout->getShowCatName();
+ $objWriter->writeAttribute('val', ((empty($showCatName)) ? 0 : 1));
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:showSerName');
+ $showSerName = (empty($chartLayout)) ? 0 : $chartLayout->getShowSerName();
+ $objWriter->writeAttribute('val', ((empty($showSerName)) ? 0 : 1));
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:showPercent');
+ $showPercent = (empty($chartLayout)) ? 0 : $chartLayout->getShowPercent();
+ $objWriter->writeAttribute('val', ((empty($showPercent)) ? 0 : 1));
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:showBubbleSize');
+ $showBubbleSize = (empty($chartLayout)) ? 0 : $chartLayout->getShowBubbleSize();
+ $objWriter->writeAttribute('val', ((empty($showBubbleSize)) ? 0 : 1));
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:showLeaderLines');
+ $showLeaderLines = (empty($chartLayout)) ? 1 : $chartLayout->getShowLeaderLines();
+ $objWriter->writeAttribute('val', ((empty($showLeaderLines)) ? 0 : 1));
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write Category Axis
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Chart_PlotArea $plotArea
+ * @param PHPExcel_Chart_Title $xAxisLabel
+ * @param string $groupType Chart type
+ * @param string $id1
+ * @param string $id2
+ * @param boolean $isMultiLevelSeries
+ *
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeCategoryAxis($objWriter, PHPExcel_Chart_PlotArea $plotArea, $xAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis)
+ {
+ $objWriter->startElement('c:catAx');
+
+ if ($id1 > 0) {
+ $objWriter->startElement('c:axId');
+ $objWriter->writeAttribute('val', $id1);
+ $objWriter->endElement();
+ }
+
+ $objWriter->startElement('c:scaling');
+ $objWriter->startElement('c:orientation');
+ $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('orientation'));
+ $objWriter->endElement();
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:delete');
+ $objWriter->writeAttribute('val', 0);
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:axPos');
+ $objWriter->writeAttribute('val', "b");
+ $objWriter->endElement();
+
+ if (!is_null($xAxisLabel)) {
+ $objWriter->startElement('c:title');
+ $objWriter->startElement('c:tx');
+ $objWriter->startElement('c:rich');
+
+ $objWriter->startElement('a:bodyPr');
+ $objWriter->endElement();
+
+ $objWriter->startElement('a:lstStyle');
+ $objWriter->endElement();
+
+ $objWriter->startElement('a:p');
+ $objWriter->startElement('a:r');
+
+ $caption = $xAxisLabel->getCaption();
+ if (is_array($caption)) {
+ $caption = $caption[0];
+ }
+ $objWriter->startElement('a:t');
+ // $objWriter->writeAttribute('xml:space', 'preserve');
+ $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($caption));
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ $objWriter->endElement();
+ $objWriter->endElement();
+ $objWriter->endElement();
+
+ $layout = $xAxisLabel->getLayout();
+ $this->writeLayout($layout, $objWriter);
+
+ $objWriter->startElement('c:overlay');
+ $objWriter->writeAttribute('val', 0);
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+
+ $objWriter->startElement('c:numFmt');
+ $objWriter->writeAttribute('formatCode', $yAxis->getAxisNumberFormat());
+ $objWriter->writeAttribute('sourceLinked', $yAxis->getAxisNumberSourceLinked());
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:majorTickMark');
+ $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('major_tick_mark'));
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:minorTickMark');
+ $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('minor_tick_mark'));
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:tickLblPos');
+ $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('axis_labels'));
+ $objWriter->endElement();
+
+ if ($id2 > 0) {
+ $objWriter->startElement('c:crossAx');
+ $objWriter->writeAttribute('val', $id2);
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:crosses');
+ $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('horizontal_crosses'));
+ $objWriter->endElement();
+ }
+
+ $objWriter->startElement('c:auto');
+ $objWriter->writeAttribute('val', 1);
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:lblAlgn');
+ $objWriter->writeAttribute('val', "ctr");
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:lblOffset');
+ $objWriter->writeAttribute('val', 100);
+ $objWriter->endElement();
+
+ if ($isMultiLevelSeries) {
+ $objWriter->startElement('c:noMultiLvlLbl');
+ $objWriter->writeAttribute('val', 0);
+ $objWriter->endElement();
+ }
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write Value Axis
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Chart_PlotArea $plotArea
+ * @param PHPExcel_Chart_Title $yAxisLabel
+ * @param string $groupType Chart type
+ * @param string $id1
+ * @param string $id2
+ * @param boolean $isMultiLevelSeries
+ *
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeValueAxis($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines)
+ {
+ $objWriter->startElement('c:valAx');
+
+ if ($id2 > 0) {
+ $objWriter->startElement('c:axId');
+ $objWriter->writeAttribute('val', $id2);
+ $objWriter->endElement();
+ }
+
+ $objWriter->startElement('c:scaling');
+
+ if (!is_null($xAxis->getAxisOptionsProperty('maximum'))) {
+ $objWriter->startElement('c:max');
+ $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('maximum'));
+ $objWriter->endElement();
+ }
+
+ if (!is_null($xAxis->getAxisOptionsProperty('minimum'))) {
+ $objWriter->startElement('c:min');
+ $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minimum'));
+ $objWriter->endElement();
+ }
+
+ $objWriter->startElement('c:orientation');
+ $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('orientation'));
+
+
+ $objWriter->endElement();
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:delete');
+ $objWriter->writeAttribute('val', 0);
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:axPos');
+ $objWriter->writeAttribute('val', "l");
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:majorGridlines');
+ $objWriter->startElement('c:spPr');
+
+ if (!is_null($majorGridlines->getLineColorProperty('value'))) {
+ $objWriter->startElement('a:ln');
+ $objWriter->writeAttribute('w', $majorGridlines->getLineStyleProperty('width'));
+ $objWriter->startElement('a:solidFill');
+ $objWriter->startElement("a:{$majorGridlines->getLineColorProperty('type')}");
+ $objWriter->writeAttribute('val', $majorGridlines->getLineColorProperty('value'));
+ $objWriter->startElement('a:alpha');
+ $objWriter->writeAttribute('val', $majorGridlines->getLineColorProperty('alpha'));
+ $objWriter->endElement(); //end alpha
+ $objWriter->endElement(); //end srgbClr
+ $objWriter->endElement(); //end solidFill
+
+ $objWriter->startElement('a:prstDash');
+ $objWriter->writeAttribute('val', $majorGridlines->getLineStyleProperty('dash'));
+ $objWriter->endElement();
+
+ if ($majorGridlines->getLineStyleProperty('join') == 'miter') {
+ $objWriter->startElement('a:miter');
+ $objWriter->writeAttribute('lim', '800000');
+ $objWriter->endElement();
+ } else {
+ $objWriter->startElement('a:bevel');
+ $objWriter->endElement();
+ }
+
+ if (!is_null($majorGridlines->getLineStyleProperty(array('arrow', 'head', 'type')))) {
+ $objWriter->startElement('a:headEnd');
+ $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(array('arrow', 'head', 'type')));
+ $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('head', 'w'));
+ $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('head', 'len'));
+ $objWriter->endElement();
+ }
+
+ if (!is_null($majorGridlines->getLineStyleProperty(array('arrow', 'end', 'type')))) {
+ $objWriter->startElement('a:tailEnd');
+ $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(array('arrow', 'end', 'type')));
+ $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('end', 'w'));
+ $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('end', 'len'));
+ $objWriter->endElement();
+ }
+ $objWriter->endElement(); //end ln
+ }
+ $objWriter->startElement('a:effectLst');
+
+ if (!is_null($majorGridlines->getGlowSize())) {
+ $objWriter->startElement('a:glow');
+ $objWriter->writeAttribute('rad', $majorGridlines->getGlowSize());
+ $objWriter->startElement("a:{$majorGridlines->getGlowColor('type')}");
+ $objWriter->writeAttribute('val', $majorGridlines->getGlowColor('value'));
+ $objWriter->startElement('a:alpha');
+ $objWriter->writeAttribute('val', $majorGridlines->getGlowColor('alpha'));
+ $objWriter->endElement(); //end alpha
+ $objWriter->endElement(); //end schemeClr
+ $objWriter->endElement(); //end glow
+ }
+
+ if (!is_null($majorGridlines->getShadowProperty('presets'))) {
+ $objWriter->startElement("a:{$majorGridlines->getShadowProperty('effect')}");
+ if (!is_null($majorGridlines->getShadowProperty('blur'))) {
+ $objWriter->writeAttribute('blurRad', $majorGridlines->getShadowProperty('blur'));
+ }
+ if (!is_null($majorGridlines->getShadowProperty('distance'))) {
+ $objWriter->writeAttribute('dist', $majorGridlines->getShadowProperty('distance'));
+ }
+ if (!is_null($majorGridlines->getShadowProperty('direction'))) {
+ $objWriter->writeAttribute('dir', $majorGridlines->getShadowProperty('direction'));
+ }
+ if (!is_null($majorGridlines->getShadowProperty('algn'))) {
+ $objWriter->writeAttribute('algn', $majorGridlines->getShadowProperty('algn'));
+ }
+ if (!is_null($majorGridlines->getShadowProperty(array('size', 'sx')))) {
+ $objWriter->writeAttribute('sx', $majorGridlines->getShadowProperty(array('size', 'sx')));
+ }
+ if (!is_null($majorGridlines->getShadowProperty(array('size', 'sy')))) {
+ $objWriter->writeAttribute('sy', $majorGridlines->getShadowProperty(array('size', 'sy')));
+ }
+ if (!is_null($majorGridlines->getShadowProperty(array('size', 'kx')))) {
+ $objWriter->writeAttribute('kx', $majorGridlines->getShadowProperty(array('size', 'kx')));
+ }
+ if (!is_null($majorGridlines->getShadowProperty('rotWithShape'))) {
+ $objWriter->writeAttribute('rotWithShape', $majorGridlines->getShadowProperty('rotWithShape'));
+ }
+ $objWriter->startElement("a:{$majorGridlines->getShadowProperty(array('color', 'type'))}");
+ $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(array('color', 'value')));
+
+ $objWriter->startElement('a:alpha');
+ $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(array('color', 'alpha')));
+ $objWriter->endElement(); //end alpha
+
+ $objWriter->endElement(); //end color:type
+ $objWriter->endElement(); //end shadow
+ }
+
+ if (!is_null($majorGridlines->getSoftEdgesSize())) {
+ $objWriter->startElement('a:softEdge');
+ $objWriter->writeAttribute('rad', $majorGridlines->getSoftEdgesSize());
+ $objWriter->endElement(); //end softEdge
+ }
+
+ $objWriter->endElement(); //end effectLst
+ $objWriter->endElement(); //end spPr
+ $objWriter->endElement(); //end majorGridLines
+
+ if ($minorGridlines->getObjectState()) {
+ $objWriter->startElement('c:minorGridlines');
+ $objWriter->startElement('c:spPr');
+
+ if (!is_null($minorGridlines->getLineColorProperty('value'))) {
+ $objWriter->startElement('a:ln');
+ $objWriter->writeAttribute('w', $minorGridlines->getLineStyleProperty('width'));
+ $objWriter->startElement('a:solidFill');
+ $objWriter->startElement("a:{$minorGridlines->getLineColorProperty('type')}");
+ $objWriter->writeAttribute('val', $minorGridlines->getLineColorProperty('value'));
+ $objWriter->startElement('a:alpha');
+ $objWriter->writeAttribute('val', $minorGridlines->getLineColorProperty('alpha'));
+ $objWriter->endElement(); //end alpha
+ $objWriter->endElement(); //end srgbClr
+ $objWriter->endElement(); //end solidFill
+
+ $objWriter->startElement('a:prstDash');
+ $objWriter->writeAttribute('val', $minorGridlines->getLineStyleProperty('dash'));
+ $objWriter->endElement();
+
+ if ($minorGridlines->getLineStyleProperty('join') == 'miter') {
+ $objWriter->startElement('a:miter');
+ $objWriter->writeAttribute('lim', '800000');
+ $objWriter->endElement();
+ } else {
+ $objWriter->startElement('a:bevel');
+ $objWriter->endElement();
+ }
+
+ if (!is_null($minorGridlines->getLineStyleProperty(array('arrow', 'head', 'type')))) {
+ $objWriter->startElement('a:headEnd');
+ $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(array('arrow', 'head', 'type')));
+ $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('head', 'w'));
+ $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('head', 'len'));
+ $objWriter->endElement();
+ }
+
+ if (!is_null($minorGridlines->getLineStyleProperty(array('arrow', 'end', 'type')))) {
+ $objWriter->startElement('a:tailEnd');
+ $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(array('arrow', 'end', 'type')));
+ $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('end', 'w'));
+ $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('end', 'len'));
+ $objWriter->endElement();
+ }
+ $objWriter->endElement(); //end ln
+ }
+
+ $objWriter->startElement('a:effectLst');
+
+ if (!is_null($minorGridlines->getGlowSize())) {
+ $objWriter->startElement('a:glow');
+ $objWriter->writeAttribute('rad', $minorGridlines->getGlowSize());
+ $objWriter->startElement("a:{$minorGridlines->getGlowColor('type')}");
+ $objWriter->writeAttribute('val', $minorGridlines->getGlowColor('value'));
+ $objWriter->startElement('a:alpha');
+ $objWriter->writeAttribute('val', $minorGridlines->getGlowColor('alpha'));
+ $objWriter->endElement(); //end alpha
+ $objWriter->endElement(); //end schemeClr
+ $objWriter->endElement(); //end glow
+ }
+
+ if (!is_null($minorGridlines->getShadowProperty('presets'))) {
+ $objWriter->startElement("a:{$minorGridlines->getShadowProperty('effect')}");
+ if (!is_null($minorGridlines->getShadowProperty('blur'))) {
+ $objWriter->writeAttribute('blurRad', $minorGridlines->getShadowProperty('blur'));
+ }
+ if (!is_null($minorGridlines->getShadowProperty('distance'))) {
+ $objWriter->writeAttribute('dist', $minorGridlines->getShadowProperty('distance'));
+ }
+ if (!is_null($minorGridlines->getShadowProperty('direction'))) {
+ $objWriter->writeAttribute('dir', $minorGridlines->getShadowProperty('direction'));
+ }
+ if (!is_null($minorGridlines->getShadowProperty('algn'))) {
+ $objWriter->writeAttribute('algn', $minorGridlines->getShadowProperty('algn'));
+ }
+ if (!is_null($minorGridlines->getShadowProperty(array('size', 'sx')))) {
+ $objWriter->writeAttribute('sx', $minorGridlines->getShadowProperty(array('size', 'sx')));
+ }
+ if (!is_null($minorGridlines->getShadowProperty(array('size', 'sy')))) {
+ $objWriter->writeAttribute('sy', $minorGridlines->getShadowProperty(array('size', 'sy')));
+ }
+ if (!is_null($minorGridlines->getShadowProperty(array('size', 'kx')))) {
+ $objWriter->writeAttribute('kx', $minorGridlines->getShadowProperty(array('size', 'kx')));
+ }
+ if (!is_null($minorGridlines->getShadowProperty('rotWithShape'))) {
+ $objWriter->writeAttribute('rotWithShape', $minorGridlines->getShadowProperty('rotWithShape'));
+ }
+ $objWriter->startElement("a:{$minorGridlines->getShadowProperty(array('color', 'type'))}");
+ $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(array('color', 'value')));
+ $objWriter->startElement('a:alpha');
+ $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(array('color', 'alpha')));
+ $objWriter->endElement(); //end alpha
+ $objWriter->endElement(); //end color:type
+ $objWriter->endElement(); //end shadow
+ }
+
+ if (!is_null($minorGridlines->getSoftEdgesSize())) {
+ $objWriter->startElement('a:softEdge');
+ $objWriter->writeAttribute('rad', $minorGridlines->getSoftEdgesSize());
+ $objWriter->endElement(); //end softEdge
+ }
+
+ $objWriter->endElement(); //end effectLst
+ $objWriter->endElement(); //end spPr
+ $objWriter->endElement(); //end minorGridLines
+ }
+
+ if (!is_null($yAxisLabel)) {
+ $objWriter->startElement('c:title');
+ $objWriter->startElement('c:tx');
+ $objWriter->startElement('c:rich');
+
+ $objWriter->startElement('a:bodyPr');
+ $objWriter->endElement();
+
+ $objWriter->startElement('a:lstStyle');
+ $objWriter->endElement();
+
+ $objWriter->startElement('a:p');
+ $objWriter->startElement('a:r');
+
+ $caption = $yAxisLabel->getCaption();
+ if (is_array($caption)) {
+ $caption = $caption[0];
+ }
+
+ $objWriter->startElement('a:t');
+ // $objWriter->writeAttribute('xml:space', 'preserve');
+ $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($caption));
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ $objWriter->endElement();
+ $objWriter->endElement();
+ $objWriter->endElement();
+
+ if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) {
+ $layout = $yAxisLabel->getLayout();
+ $this->writeLayout($layout, $objWriter);
+ }
+
+ $objWriter->startElement('c:overlay');
+ $objWriter->writeAttribute('val', 0);
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+
+ $objWriter->startElement('c:numFmt');
+ $objWriter->writeAttribute('formatCode', $xAxis->getAxisNumberFormat());
+ $objWriter->writeAttribute('sourceLinked', $xAxis->getAxisNumberSourceLinked());
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:majorTickMark');
+ $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('major_tick_mark'));
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:minorTickMark');
+ $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minor_tick_mark'));
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:tickLblPos');
+ $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('axis_labels'));
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:spPr');
+
+ if (!is_null($xAxis->getFillProperty('value'))) {
+ $objWriter->startElement('a:solidFill');
+ $objWriter->startElement("a:" . $xAxis->getFillProperty('type'));
+ $objWriter->writeAttribute('val', $xAxis->getFillProperty('value'));
+ $objWriter->startElement('a:alpha');
+ $objWriter->writeAttribute('val', $xAxis->getFillProperty('alpha'));
+ $objWriter->endElement();
+ $objWriter->endElement();
+ $objWriter->endElement();
+ }
+
+ $objWriter->startElement('a:ln');
+
+ $objWriter->writeAttribute('w', $xAxis->getLineStyleProperty('width'));
+ $objWriter->writeAttribute('cap', $xAxis->getLineStyleProperty('cap'));
+ $objWriter->writeAttribute('cmpd', $xAxis->getLineStyleProperty('compound'));
+
+ if (!is_null($xAxis->getLineProperty('value'))) {
+ $objWriter->startElement('a:solidFill');
+ $objWriter->startElement("a:" . $xAxis->getLineProperty('type'));
+ $objWriter->writeAttribute('val', $xAxis->getLineProperty('value'));
+ $objWriter->startElement('a:alpha');
+ $objWriter->writeAttribute('val', $xAxis->getLineProperty('alpha'));
+ $objWriter->endElement();
+ $objWriter->endElement();
+ $objWriter->endElement();
+ }
+
+ $objWriter->startElement('a:prstDash');
+ $objWriter->writeAttribute('val', $xAxis->getLineStyleProperty('dash'));
+ $objWriter->endElement();
+
+ if ($xAxis->getLineStyleProperty('join') == 'miter') {
+ $objWriter->startElement('a:miter');
+ $objWriter->writeAttribute('lim', '800000');
+ $objWriter->endElement();
+ } else {
+ $objWriter->startElement('a:bevel');
+ $objWriter->endElement();
+ }
+
+ if (!is_null($xAxis->getLineStyleProperty(array('arrow', 'head', 'type')))) {
+ $objWriter->startElement('a:headEnd');
+ $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(array('arrow', 'head', 'type')));
+ $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('head'));
+ $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('head'));
+ $objWriter->endElement();
+ }
+
+ if (!is_null($xAxis->getLineStyleProperty(array('arrow', 'end', 'type')))) {
+ $objWriter->startElement('a:tailEnd');
+ $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(array('arrow', 'end', 'type')));
+ $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('end'));
+ $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('end'));
+ $objWriter->endElement();
+ }
+
+ $objWriter->endElement();
+
+ $objWriter->startElement('a:effectLst');
+
+ if (!is_null($xAxis->getGlowProperty('size'))) {
+ $objWriter->startElement('a:glow');
+ $objWriter->writeAttribute('rad', $xAxis->getGlowProperty('size'));
+ $objWriter->startElement("a:{$xAxis->getGlowProperty(array('color','type'))}");
+ $objWriter->writeAttribute('val', $xAxis->getGlowProperty(array('color','value')));
+ $objWriter->startElement('a:alpha');
+ $objWriter->writeAttribute('val', $xAxis->getGlowProperty(array('color','alpha')));
+ $objWriter->endElement();
+ $objWriter->endElement();
+ $objWriter->endElement();
+ }
+
+ if (!is_null($xAxis->getShadowProperty('presets'))) {
+ $objWriter->startElement("a:{$xAxis->getShadowProperty('effect')}");
+
+ if (!is_null($xAxis->getShadowProperty('blur'))) {
+ $objWriter->writeAttribute('blurRad', $xAxis->getShadowProperty('blur'));
+ }
+ if (!is_null($xAxis->getShadowProperty('distance'))) {
+ $objWriter->writeAttribute('dist', $xAxis->getShadowProperty('distance'));
+ }
+ if (!is_null($xAxis->getShadowProperty('direction'))) {
+ $objWriter->writeAttribute('dir', $xAxis->getShadowProperty('direction'));
+ }
+ if (!is_null($xAxis->getShadowProperty('algn'))) {
+ $objWriter->writeAttribute('algn', $xAxis->getShadowProperty('algn'));
+ }
+ if (!is_null($xAxis->getShadowProperty(array('size','sx')))) {
+ $objWriter->writeAttribute('sx', $xAxis->getShadowProperty(array('size','sx')));
+ }
+ if (!is_null($xAxis->getShadowProperty(array('size','sy')))) {
+ $objWriter->writeAttribute('sy', $xAxis->getShadowProperty(array('size','sy')));
+ }
+ if (!is_null($xAxis->getShadowProperty(array('size','kx')))) {
+ $objWriter->writeAttribute('kx', $xAxis->getShadowProperty(array('size','kx')));
+ }
+ if (!is_null($xAxis->getShadowProperty('rotWithShape'))) {
+ $objWriter->writeAttribute('rotWithShape', $xAxis->getShadowProperty('rotWithShape'));
+ }
+
+ $objWriter->startElement("a:{$xAxis->getShadowProperty(array('color','type'))}");
+ $objWriter->writeAttribute('val', $xAxis->getShadowProperty(array('color','value')));
+ $objWriter->startElement('a:alpha');
+ $objWriter->writeAttribute('val', $xAxis->getShadowProperty(array('color','alpha')));
+ $objWriter->endElement();
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+
+ if (!is_null($xAxis->getSoftEdgesSize())) {
+ $objWriter->startElement('a:softEdge');
+ $objWriter->writeAttribute('rad', $xAxis->getSoftEdgesSize());
+ $objWriter->endElement();
+ }
+
+ $objWriter->endElement(); //effectList
+ $objWriter->endElement(); //end spPr
+
+ if ($id1 > 0) {
+ $objWriter->startElement('c:crossAx');
+ $objWriter->writeAttribute('val', $id2);
+ $objWriter->endElement();
+
+ if (!is_null($xAxis->getAxisOptionsProperty('horizontal_crosses_value'))) {
+ $objWriter->startElement('c:crossesAt');
+ $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('horizontal_crosses_value'));
+ $objWriter->endElement();
+ } else {
+ $objWriter->startElement('c:crosses');
+ $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('horizontal_crosses'));
+ $objWriter->endElement();
+ }
+
+ $objWriter->startElement('c:crossBetween');
+ $objWriter->writeAttribute('val', "midCat");
+ $objWriter->endElement();
+
+ if (!is_null($xAxis->getAxisOptionsProperty('major_unit'))) {
+ $objWriter->startElement('c:majorUnit');
+ $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('major_unit'));
+ $objWriter->endElement();
+ }
+
+ if (!is_null($xAxis->getAxisOptionsProperty('minor_unit'))) {
+ $objWriter->startElement('c:minorUnit');
+ $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minor_unit'));
+ $objWriter->endElement();
+ }
+ }
+
+ if ($isMultiLevelSeries) {
+ if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) {
+ $objWriter->startElement('c:noMultiLvlLbl');
+ $objWriter->writeAttribute('val', 0);
+ $objWriter->endElement();
+ }
+ }
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Get the data series type(s) for a chart plot series
+ *
+ * @param PHPExcel_Chart_PlotArea $plotArea
+ *
+ * @return string|array
+ * @throws PHPExcel_Writer_Exception
+ */
+ private static function getChartType($plotArea)
+ {
+ $groupCount = $plotArea->getPlotGroupCount();
+
+ if ($groupCount == 1) {
+ $chartType = array($plotArea->getPlotGroupByIndex(0)->getPlotType());
+ } else {
+ $chartTypes = array();
+ for ($i = 0; $i < $groupCount; ++$i) {
+ $chartTypes[] = $plotArea->getPlotGroupByIndex($i)->getPlotType();
+ }
+ $chartType = array_unique($chartTypes);
+ if (count($chartTypes) == 0) {
+ throw new PHPExcel_Writer_Exception('Chart is not yet implemented');
+ }
+ }
+
+ return $chartType;
+ }
+
+ /**
+ * Write Plot Group (series of related plots)
+ *
+ * @param PHPExcel_Chart_DataSeries $plotGroup
+ * @param string $groupType Type of plot for dataseries
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param boolean &$catIsMultiLevelSeries Is category a multi-series category
+ * @param boolean &$valIsMultiLevelSeries Is value set a multi-series set
+ * @param string &$plotGroupingType Type of grouping for multi-series values
+ * @param PHPExcel_Worksheet $pSheet
+ *
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writePlotGroup($plotGroup, $groupType, $objWriter, &$catIsMultiLevelSeries, &$valIsMultiLevelSeries, &$plotGroupingType, PHPExcel_Worksheet $pSheet)
+ {
+ if (is_null($plotGroup)) {
+ return;
+ }
+
+ if (($groupType == PHPExcel_Chart_DataSeries::TYPE_BARCHART) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D)) {
+ $objWriter->startElement('c:barDir');
+ $objWriter->writeAttribute('val', $plotGroup->getPlotDirection());
+ $objWriter->endElement();
+ }
+
+ if (!is_null($plotGroup->getPlotGrouping())) {
+ $plotGroupingType = $plotGroup->getPlotGrouping();
+ $objWriter->startElement('c:grouping');
+ $objWriter->writeAttribute('val', $plotGroupingType);
+ $objWriter->endElement();
+ }
+
+ // Get these details before the loop, because we can use the count to check for varyColors
+ $plotSeriesOrder = $plotGroup->getPlotOrder();
+ $plotSeriesCount = count($plotSeriesOrder);
+
+ if (($groupType !== PHPExcel_Chart_DataSeries::TYPE_RADARCHART) && ($groupType !== PHPExcel_Chart_DataSeries::TYPE_STOCKCHART)) {
+ if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_LINECHART) {
+ if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) || ($plotSeriesCount > 1)) {
+ $objWriter->startElement('c:varyColors');
+ $objWriter->writeAttribute('val', 1);
+ $objWriter->endElement();
+ } else {
+ $objWriter->startElement('c:varyColors');
+ $objWriter->writeAttribute('val', 0);
+ $objWriter->endElement();
+ }
+ }
+ }
+
+ foreach ($plotSeriesOrder as $plotSeriesIdx => $plotSeriesRef) {
+ $objWriter->startElement('c:ser');
+
+ $objWriter->startElement('c:idx');
+ $objWriter->writeAttribute('val', $this->_seriesIndex + $plotSeriesIdx);
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:order');
+ $objWriter->writeAttribute('val', $this->_seriesIndex + $plotSeriesRef);
+ $objWriter->endElement();
+
+ if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) {
+ $objWriter->startElement('c:dPt');
+ $objWriter->startElement('c:idx');
+ $objWriter->writeAttribute('val', 3);
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:bubble3D');
+ $objWriter->writeAttribute('val', 0);
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:spPr');
+ $objWriter->startElement('a:solidFill');
+ $objWriter->startElement('a:srgbClr');
+ $objWriter->writeAttribute('val', 'FF9900');
+ $objWriter->endElement();
+ $objWriter->endElement();
+ $objWriter->endElement();
+ $objWriter->endElement();
+ }
+
+ // Labels
+ $plotSeriesLabel = $plotGroup->getPlotLabelByIndex($plotSeriesRef);
+ if ($plotSeriesLabel && ($plotSeriesLabel->getPointCount() > 0)) {
+ $objWriter->startElement('c:tx');
+ $objWriter->startElement('c:strRef');
+ $this->writePlotSeriesLabel($plotSeriesLabel, $objWriter);
+ $objWriter->endElement();
+ $objWriter->endElement();
+ }
+
+ // Formatting for the points
+ if (($groupType == PHPExcel_Chart_DataSeries::TYPE_LINECHART) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART)) {
+ $objWriter->startElement('c:spPr');
+ $objWriter->startElement('a:ln');
+ $objWriter->writeAttribute('w', 12700);
+ if ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) {
+ $objWriter->startElement('a:noFill');
+ $objWriter->endElement();
+ }
+ $objWriter->endElement();
+ $objWriter->endElement();
+ }
+
+ $plotSeriesValues = $plotGroup->getPlotValuesByIndex($plotSeriesRef);
+ if ($plotSeriesValues) {
+ $plotSeriesMarker = $plotSeriesValues->getPointMarker();
+ if ($plotSeriesMarker) {
+ $objWriter->startElement('c:marker');
+ $objWriter->startElement('c:symbol');
+ $objWriter->writeAttribute('val', $plotSeriesMarker);
+ $objWriter->endElement();
+
+ if ($plotSeriesMarker !== 'none') {
+ $objWriter->startElement('c:size');
+ $objWriter->writeAttribute('val', 3);
+ $objWriter->endElement();
+ }
+
+ $objWriter->endElement();
+ }
+ }
+
+ if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BARCHART) || ($groupType === PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D) || ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART)) {
+ $objWriter->startElement('c:invertIfNegative');
+ $objWriter->writeAttribute('val', 0);
+ $objWriter->endElement();
+ }
+
+ // Category Labels
+ $plotSeriesCategory = $plotGroup->getPlotCategoryByIndex($plotSeriesRef);
+ if ($plotSeriesCategory && ($plotSeriesCategory->getPointCount() > 0)) {
+ $catIsMultiLevelSeries = $catIsMultiLevelSeries || $plotSeriesCategory->isMultiLevelSeries();
+
+ if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) {
+ if (!is_null($plotGroup->getPlotStyle())) {
+ $plotStyle = $plotGroup->getPlotStyle();
+ if ($plotStyle) {
+ $objWriter->startElement('c:explosion');
+ $objWriter->writeAttribute('val', 25);
+ $objWriter->endElement();
+ }
+ }
+ }
+
+ if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) || ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART)) {
+ $objWriter->startElement('c:xVal');
+ } else {
+ $objWriter->startElement('c:cat');
+ }
+
+ $this->writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'str', $pSheet);
+ $objWriter->endElement();
+ }
+
+ // Values
+ if ($plotSeriesValues) {
+ $valIsMultiLevelSeries = $valIsMultiLevelSeries || $plotSeriesValues->isMultiLevelSeries();
+
+ if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) || ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART)) {
+ $objWriter->startElement('c:yVal');
+ } else {
+ $objWriter->startElement('c:val');
+ }
+
+ $this->writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, 'num', $pSheet);
+ $objWriter->endElement();
+ }
+
+ if ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) {
+ $this->writeBubbles($plotSeriesValues, $objWriter, $pSheet);
+ }
+
+ $objWriter->endElement();
+ }
+
+ $this->_seriesIndex += $plotSeriesIdx + 1;
+ }
+
+ /**
+ * Write Plot Series Label
+ *
+ * @param PHPExcel_Chart_DataSeriesValues $plotSeriesLabel
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ *
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writePlotSeriesLabel($plotSeriesLabel, $objWriter)
+ {
+ if (is_null($plotSeriesLabel)) {
+ return;
+ }
+
+ $objWriter->startElement('c:f');
+ $objWriter->writeRawData($plotSeriesLabel->getDataSource());
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:strCache');
+ $objWriter->startElement('c:ptCount');
+ $objWriter->writeAttribute('val', $plotSeriesLabel->getPointCount());
+ $objWriter->endElement();
+
+ foreach ($plotSeriesLabel->getDataValues() as $plotLabelKey => $plotLabelValue) {
+ $objWriter->startElement('c:pt');
+ $objWriter->writeAttribute('idx', $plotLabelKey);
+
+ $objWriter->startElement('c:v');
+ $objWriter->writeRawData($plotLabelValue);
+ $objWriter->endElement();
+ $objWriter->endElement();
+ }
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write Plot Series Values
+ *
+ * @param PHPExcel_Chart_DataSeriesValues $plotSeriesValues
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param string $groupType Type of plot for dataseries
+ * @param string $dataType Datatype of series values
+ * @param PHPExcel_Worksheet $pSheet
+ *
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, $dataType = 'str', PHPExcel_Worksheet $pSheet)
+ {
+ if (is_null($plotSeriesValues)) {
+ return;
+ }
+
+ if ($plotSeriesValues->isMultiLevelSeries()) {
+ $levelCount = $plotSeriesValues->multiLevelCount();
+
+ $objWriter->startElement('c:multiLvlStrRef');
+
+ $objWriter->startElement('c:f');
+ $objWriter->writeRawData($plotSeriesValues->getDataSource());
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:multiLvlStrCache');
+
+ $objWriter->startElement('c:ptCount');
+ $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount());
+ $objWriter->endElement();
+
+ for ($level = 0; $level < $levelCount; ++$level) {
+ $objWriter->startElement('c:lvl');
+
+ foreach ($plotSeriesValues->getDataValues() as $plotSeriesKey => $plotSeriesValue) {
+ if (isset($plotSeriesValue[$level])) {
+ $objWriter->startElement('c:pt');
+ $objWriter->writeAttribute('idx', $plotSeriesKey);
+
+ $objWriter->startElement('c:v');
+ $objWriter->writeRawData($plotSeriesValue[$level]);
+ $objWriter->endElement();
+ $objWriter->endElement();
+ }
+ }
+
+ $objWriter->endElement();
+ }
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ } else {
+ $objWriter->startElement('c:' . $dataType . 'Ref');
+
+ $objWriter->startElement('c:f');
+ $objWriter->writeRawData($plotSeriesValues->getDataSource());
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:' . $dataType . 'Cache');
+
+ if (($groupType != PHPExcel_Chart_DataSeries::TYPE_PIECHART) && ($groupType != PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && ($groupType != PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) {
+ if (($plotSeriesValues->getFormatCode() !== null) && ($plotSeriesValues->getFormatCode() !== '')) {
+ $objWriter->startElement('c:formatCode');
+ $objWriter->writeRawData($plotSeriesValues->getFormatCode());
+ $objWriter->endElement();
+ }
+ }
+
+ $objWriter->startElement('c:ptCount');
+ $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount());
+ $objWriter->endElement();
+
+ $dataValues = $plotSeriesValues->getDataValues();
+ if (!empty($dataValues)) {
+ if (is_array($dataValues)) {
+ foreach ($dataValues as $plotSeriesKey => $plotSeriesValue) {
+ $objWriter->startElement('c:pt');
+ $objWriter->writeAttribute('idx', $plotSeriesKey);
+
+ $objWriter->startElement('c:v');
+ $objWriter->writeRawData($plotSeriesValue);
+ $objWriter->endElement();
+ $objWriter->endElement();
+ }
+ }
+ }
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+ }
+
+ /**
+ * Write Bubble Chart Details
+ *
+ * @param PHPExcel_Chart_DataSeriesValues $plotSeriesValues
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ *
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeBubbles($plotSeriesValues, $objWriter, PHPExcel_Worksheet $pSheet)
+ {
+ if (is_null($plotSeriesValues)) {
+ return;
+ }
+
+ $objWriter->startElement('c:bubbleSize');
+ $objWriter->startElement('c:numLit');
+
+ $objWriter->startElement('c:formatCode');
+ $objWriter->writeRawData('General');
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:ptCount');
+ $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount());
+ $objWriter->endElement();
+
+ $dataValues = $plotSeriesValues->getDataValues();
+ if (!empty($dataValues)) {
+ if (is_array($dataValues)) {
+ foreach ($dataValues as $plotSeriesKey => $plotSeriesValue) {
+ $objWriter->startElement('c:pt');
+ $objWriter->writeAttribute('idx', $plotSeriesKey);
+ $objWriter->startElement('c:v');
+ $objWriter->writeRawData(1);
+ $objWriter->endElement();
+ $objWriter->endElement();
+ }
+ }
+ }
+
+ $objWriter->endElement();
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:bubble3D');
+ $objWriter->writeAttribute('val', 0);
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write Layout
+ *
+ * @param PHPExcel_Chart_Layout $layout
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ *
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeLayout(PHPExcel_Chart_Layout $layout = null, $objWriter)
+ {
+ $objWriter->startElement('c:layout');
+
+ if (!is_null($layout)) {
+ $objWriter->startElement('c:manualLayout');
+
+ $layoutTarget = $layout->getLayoutTarget();
+ if (!is_null($layoutTarget)) {
+ $objWriter->startElement('c:layoutTarget');
+ $objWriter->writeAttribute('val', $layoutTarget);
+ $objWriter->endElement();
+ }
+
+ $xMode = $layout->getXMode();
+ if (!is_null($xMode)) {
+ $objWriter->startElement('c:xMode');
+ $objWriter->writeAttribute('val', $xMode);
+ $objWriter->endElement();
+ }
+
+ $yMode = $layout->getYMode();
+ if (!is_null($yMode)) {
+ $objWriter->startElement('c:yMode');
+ $objWriter->writeAttribute('val', $yMode);
+ $objWriter->endElement();
+ }
+
+ $x = $layout->getXPosition();
+ if (!is_null($x)) {
+ $objWriter->startElement('c:x');
+ $objWriter->writeAttribute('val', $x);
+ $objWriter->endElement();
+ }
+
+ $y = $layout->getYPosition();
+ if (!is_null($y)) {
+ $objWriter->startElement('c:y');
+ $objWriter->writeAttribute('val', $y);
+ $objWriter->endElement();
+ }
+
+ $w = $layout->getWidth();
+ if (!is_null($w)) {
+ $objWriter->startElement('c:w');
+ $objWriter->writeAttribute('val', $w);
+ $objWriter->endElement();
+ }
+
+ $h = $layout->getHeight();
+ if (!is_null($h)) {
+ $objWriter->startElement('c:h');
+ $objWriter->writeAttribute('val', $h);
+ $objWriter->endElement();
+ }
+
+ $objWriter->endElement();
+ }
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write Alternate Content block
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ *
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeAlternateContent($objWriter)
+ {
+ $objWriter->startElement('mc:AlternateContent');
+ $objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006');
+
+ $objWriter->startElement('mc:Choice');
+ $objWriter->writeAttribute('xmlns:c14', 'http://schemas.microsoft.com/office/drawing/2007/8/2/chart');
+ $objWriter->writeAttribute('Requires', 'c14');
+
+ $objWriter->startElement('c14:style');
+ $objWriter->writeAttribute('val', '102');
+ $objWriter->endElement();
+ $objWriter->endElement();
+
+ $objWriter->startElement('mc:Fallback');
+ $objWriter->startElement('c:style');
+ $objWriter->writeAttribute('val', '2');
+ $objWriter->endElement();
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write Printer Settings
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ *
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writePrintSettings($objWriter)
+ {
+ $objWriter->startElement('c:printSettings');
+
+ $objWriter->startElement('c:headerFooter');
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:pageMargins');
+ $objWriter->writeAttribute('footer', 0.3);
+ $objWriter->writeAttribute('header', 0.3);
+ $objWriter->writeAttribute('r', 0.7);
+ $objWriter->writeAttribute('l', 0.7);
+ $objWriter->writeAttribute('t', 0.75);
+ $objWriter->writeAttribute('b', 0.75);
+ $objWriter->endElement();
+
+ $objWriter->startElement('c:pageSetup');
+ $objWriter->writeAttribute('orientation', "portrait");
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Comments.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Comments.php
new file mode 100755
index 000000000..7139f6c49
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Comments.php
@@ -0,0 +1,260 @@
+getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // Comments cache
+ $comments = $pWorksheet->getComments();
+
+ // Authors cache
+ $authors = array();
+ $authorId = 0;
+ foreach ($comments as $comment) {
+ if (!isset($authors[$comment->getAuthor()])) {
+ $authors[$comment->getAuthor()] = $authorId++;
+ }
+ }
+
+ // comments
+ $objWriter->startElement('comments');
+ $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
+
+ // Loop through authors
+ $objWriter->startElement('authors');
+ foreach ($authors as $author => $index) {
+ $objWriter->writeElement('author', $author);
+ }
+ $objWriter->endElement();
+
+ // Loop through comments
+ $objWriter->startElement('commentList');
+ foreach ($comments as $key => $value) {
+ $this->writeComment($objWriter, $key, $value, $authors);
+ }
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // Return
+ return $objWriter->getData();
+ }
+
+ /**
+ * Write comment to XML format
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param string $pCellReference Cell reference
+ * @param PHPExcel_Comment $pComment Comment
+ * @param array $pAuthors Array of authors
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeComment(PHPExcel_Shared_XMLWriter $objWriter = null, $pCellReference = 'A1', PHPExcel_Comment $pComment = null, $pAuthors = null)
+ {
+ // comment
+ $objWriter->startElement('comment');
+ $objWriter->writeAttribute('ref', $pCellReference);
+ $objWriter->writeAttribute('authorId', $pAuthors[$pComment->getAuthor()]);
+
+ // text
+ $objWriter->startElement('text');
+ $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $pComment->getText());
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write VML comments to XML format
+ *
+ * @param PHPExcel_Worksheet $pWorksheet
+ * @return string XML Output
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function writeVMLComments(PHPExcel_Worksheet $pWorksheet = null)
+ {
+ // Create XML writer
+ $objWriter = null;
+ if ($this->getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // Comments cache
+ $comments = $pWorksheet->getComments();
+
+ // xml
+ $objWriter->startElement('xml');
+ $objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml');
+ $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office');
+ $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel');
+
+ // o:shapelayout
+ $objWriter->startElement('o:shapelayout');
+ $objWriter->writeAttribute('v:ext', 'edit');
+
+ // o:idmap
+ $objWriter->startElement('o:idmap');
+ $objWriter->writeAttribute('v:ext', 'edit');
+ $objWriter->writeAttribute('data', '1');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // v:shapetype
+ $objWriter->startElement('v:shapetype');
+ $objWriter->writeAttribute('id', '_x0000_t202');
+ $objWriter->writeAttribute('coordsize', '21600,21600');
+ $objWriter->writeAttribute('o:spt', '202');
+ $objWriter->writeAttribute('path', 'm,l,21600r21600,l21600,xe');
+
+ // v:stroke
+ $objWriter->startElement('v:stroke');
+ $objWriter->writeAttribute('joinstyle', 'miter');
+ $objWriter->endElement();
+
+ // v:path
+ $objWriter->startElement('v:path');
+ $objWriter->writeAttribute('gradientshapeok', 't');
+ $objWriter->writeAttribute('o:connecttype', 'rect');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // Loop through comments
+ foreach ($comments as $key => $value) {
+ $this->writeVMLComment($objWriter, $key, $value);
+ }
+
+ $objWriter->endElement();
+
+ // Return
+ return $objWriter->getData();
+ }
+
+ /**
+ * Write VML comment to XML format
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param string $pCellReference Cell reference
+ * @param PHPExcel_Comment $pComment Comment
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeVMLComment(PHPExcel_Shared_XMLWriter $objWriter = null, $pCellReference = 'A1', PHPExcel_Comment $pComment = null)
+ {
+ // Metadata
+ list($column, $row) = PHPExcel_Cell::coordinateFromString($pCellReference);
+ $column = PHPExcel_Cell::columnIndexFromString($column);
+ $id = 1024 + $column + $row;
+ $id = substr($id, 0, 4);
+
+ // v:shape
+ $objWriter->startElement('v:shape');
+ $objWriter->writeAttribute('id', '_x0000_s' . $id);
+ $objWriter->writeAttribute('type', '#_x0000_t202');
+ $objWriter->writeAttribute('style', 'position:absolute;margin-left:' . $pComment->getMarginLeft() . ';margin-top:' . $pComment->getMarginTop() . ';width:' . $pComment->getWidth() . ';height:' . $pComment->getHeight() . ';z-index:1;visibility:' . ($pComment->getVisible() ? 'visible' : 'hidden'));
+ $objWriter->writeAttribute('fillcolor', '#' . $pComment->getFillColor()->getRGB());
+ $objWriter->writeAttribute('o:insetmode', 'auto');
+
+ // v:fill
+ $objWriter->startElement('v:fill');
+ $objWriter->writeAttribute('color2', '#' . $pComment->getFillColor()->getRGB());
+ $objWriter->endElement();
+
+ // v:shadow
+ $objWriter->startElement('v:shadow');
+ $objWriter->writeAttribute('on', 't');
+ $objWriter->writeAttribute('color', 'black');
+ $objWriter->writeAttribute('obscured', 't');
+ $objWriter->endElement();
+
+ // v:path
+ $objWriter->startElement('v:path');
+ $objWriter->writeAttribute('o:connecttype', 'none');
+ $objWriter->endElement();
+
+ // v:textbox
+ $objWriter->startElement('v:textbox');
+ $objWriter->writeAttribute('style', 'mso-direction-alt:auto');
+
+ // div
+ $objWriter->startElement('div');
+ $objWriter->writeAttribute('style', 'text-align:left');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // x:ClientData
+ $objWriter->startElement('x:ClientData');
+ $objWriter->writeAttribute('ObjectType', 'Note');
+
+ // x:MoveWithCells
+ $objWriter->writeElement('x:MoveWithCells', '');
+
+ // x:SizeWithCells
+ $objWriter->writeElement('x:SizeWithCells', '');
+
+ // x:Anchor
+ //$objWriter->writeElement('x:Anchor', $column . ', 15, ' . ($row - 2) . ', 10, ' . ($column + 4) . ', 15, ' . ($row + 5) . ', 18');
+
+ // x:AutoFill
+ $objWriter->writeElement('x:AutoFill', 'False');
+
+ // x:Row
+ $objWriter->writeElement('x:Row', ($row - 1));
+
+ // x:Column
+ $objWriter->writeElement('x:Column', ($column - 1));
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php
new file mode 100755
index 000000000..0d9118990
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php
@@ -0,0 +1,240 @@
+getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // Types
+ $objWriter->startElement('Types');
+ $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/content-types');
+
+ // Theme
+ $this->writeOverrideContentType($objWriter, '/xl/theme/theme1.xml', 'application/vnd.openxmlformats-officedocument.theme+xml');
+
+ // Styles
+ $this->writeOverrideContentType($objWriter, '/xl/styles.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml');
+
+ // Rels
+ $this->writeDefaultContentType($objWriter, 'rels', 'application/vnd.openxmlformats-package.relationships+xml');
+
+ // XML
+ $this->writeDefaultContentType($objWriter, 'xml', 'application/xml');
+
+ // VML
+ $this->writeDefaultContentType($objWriter, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing');
+
+ // Workbook
+ if ($pPHPExcel->hasMacros()) { //Macros in workbook ?
+ // Yes : not standard content but "macroEnabled"
+ $this->writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.ms-excel.sheet.macroEnabled.main+xml');
+ //... and define a new type for the VBA project
+ $this->writeDefaultContentType($objWriter, 'bin', 'application/vnd.ms-office.vbaProject');
+ if ($pPHPExcel->hasMacrosCertificate()) {// signed macros ?
+ // Yes : add needed information
+ $this->writeOverrideContentType($objWriter, '/xl/vbaProjectSignature.bin', 'application/vnd.ms-office.vbaProjectSignature');
+ }
+ } else {// no macros in workbook, so standard type
+ $this->writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml');
+ }
+
+ // DocProps
+ $this->writeOverrideContentType($objWriter, '/docProps/app.xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml');
+
+ $this->writeOverrideContentType($objWriter, '/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml');
+
+ $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties();
+ if (!empty($customPropertyList)) {
+ $this->writeOverrideContentType($objWriter, '/docProps/custom.xml', 'application/vnd.openxmlformats-officedocument.custom-properties+xml');
+ }
+
+ // Worksheets
+ $sheetCount = $pPHPExcel->getSheetCount();
+ for ($i = 0; $i < $sheetCount; ++$i) {
+ $this->writeOverrideContentType($objWriter, '/xl/worksheets/sheet' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml');
+ }
+
+ // Shared strings
+ $this->writeOverrideContentType($objWriter, '/xl/sharedStrings.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml');
+
+ // Add worksheet relationship content types
+ $chart = 1;
+ for ($i = 0; $i < $sheetCount; ++$i) {
+ $drawings = $pPHPExcel->getSheet($i)->getDrawingCollection();
+ $drawingCount = count($drawings);
+ $chartCount = ($includeCharts) ? $pPHPExcel->getSheet($i)->getChartCount() : 0;
+
+ // We need a drawing relationship for the worksheet if we have either drawings or charts
+ if (($drawingCount > 0) || ($chartCount > 0)) {
+ $this->writeOverrideContentType($objWriter, '/xl/drawings/drawing' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.drawing+xml');
+ }
+
+ // If we have charts, then we need a chart relationship for every individual chart
+ if ($chartCount > 0) {
+ for ($c = 0; $c < $chartCount; ++$c) {
+ $this->writeOverrideContentType($objWriter, '/xl/charts/chart' . $chart++ . '.xml', 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml');
+ }
+ }
+ }
+
+ // Comments
+ for ($i = 0; $i < $sheetCount; ++$i) {
+ if (count($pPHPExcel->getSheet($i)->getComments()) > 0) {
+ $this->writeOverrideContentType($objWriter, '/xl/comments' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml');
+ }
+ }
+
+ // Add media content-types
+ $aMediaContentTypes = array();
+ $mediaCount = $this->getParentWriter()->getDrawingHashTable()->count();
+ for ($i = 0; $i < $mediaCount; ++$i) {
+ $extension = '';
+ $mimeType = '';
+
+ if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) {
+ $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getExtension());
+ $mimeType = $this->getImageMimeType($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getPath());
+ } elseif ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) {
+ $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType());
+ $extension = explode('/', $extension);
+ $extension = $extension[1];
+
+ $mimeType = $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType();
+ }
+
+ if (!isset( $aMediaContentTypes[$extension])) {
+ $aMediaContentTypes[$extension] = $mimeType;
+
+ $this->writeDefaultContentType($objWriter, $extension, $mimeType);
+ }
+ }
+ if ($pPHPExcel->hasRibbonBinObjects()) {
+ // Some additional objects in the ribbon ?
+ // we need to write "Extension" but not already write for media content
+ $tabRibbonTypes=array_diff($pPHPExcel->getRibbonBinObjects('types'), array_keys($aMediaContentTypes));
+ foreach ($tabRibbonTypes as $aRibbonType) {
+ $mimeType='image/.'.$aRibbonType;//we wrote $mimeType like customUI Editor
+ $this->writeDefaultContentType($objWriter, $aRibbonType, $mimeType);
+ }
+ }
+ $sheetCount = $pPHPExcel->getSheetCount();
+ for ($i = 0; $i < $sheetCount; ++$i) {
+ if (count($pPHPExcel->getSheet()->getHeaderFooter()->getImages()) > 0) {
+ foreach ($pPHPExcel->getSheet()->getHeaderFooter()->getImages() as $image) {
+ if (!isset( $aMediaContentTypes[strtolower($image->getExtension())])) {
+ $aMediaContentTypes[strtolower($image->getExtension())] = $this->getImageMimeType($image->getPath());
+
+ $this->writeDefaultContentType($objWriter, strtolower($image->getExtension()), $aMediaContentTypes[strtolower($image->getExtension())]);
+ }
+ }
+ }
+ }
+
+ $objWriter->endElement();
+
+ // Return
+ return $objWriter->getData();
+ }
+
+ /**
+ * Get image mime type
+ *
+ * @param string $pFile Filename
+ * @return string Mime Type
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function getImageMimeType($pFile = '')
+ {
+ if (PHPExcel_Shared_File::file_exists($pFile)) {
+ $image = getimagesize($pFile);
+ return image_type_to_mime_type($image[2]);
+ } else {
+ throw new PHPExcel_Writer_Exception("File $pFile does not exist");
+ }
+ }
+
+ /**
+ * Write Default content type
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param string $pPartname Part name
+ * @param string $pContentType Content type
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeDefaultContentType(PHPExcel_Shared_XMLWriter $objWriter = null, $pPartname = '', $pContentType = '')
+ {
+ if ($pPartname != '' && $pContentType != '') {
+ // Write content type
+ $objWriter->startElement('Default');
+ $objWriter->writeAttribute('Extension', $pPartname);
+ $objWriter->writeAttribute('ContentType', $pContentType);
+ $objWriter->endElement();
+ } else {
+ throw new PHPExcel_Writer_Exception("Invalid parameters passed.");
+ }
+ }
+
+ /**
+ * Write Override content type
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param string $pPartname Part name
+ * @param string $pContentType Content type
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeOverrideContentType(PHPExcel_Shared_XMLWriter $objWriter = null, $pPartname = '', $pContentType = '')
+ {
+ if ($pPartname != '' && $pContentType != '') {
+ // Write content type
+ $objWriter->startElement('Override');
+ $objWriter->writeAttribute('PartName', $pPartname);
+ $objWriter->writeAttribute('ContentType', $pContentType);
+ $objWriter->endElement();
+ } else {
+ throw new PHPExcel_Writer_Exception("Invalid parameters passed.");
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/DocProps.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/DocProps.php
new file mode 100755
index 000000000..fef3d9371
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/DocProps.php
@@ -0,0 +1,262 @@
+getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // Properties
+ $objWriter->startElement('Properties');
+ $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/extended-properties');
+ $objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes');
+
+ // Application
+ $objWriter->writeElement('Application', 'Microsoft Excel');
+
+ // DocSecurity
+ $objWriter->writeElement('DocSecurity', '0');
+
+ // ScaleCrop
+ $objWriter->writeElement('ScaleCrop', 'false');
+
+ // HeadingPairs
+ $objWriter->startElement('HeadingPairs');
+
+ // Vector
+ $objWriter->startElement('vt:vector');
+ $objWriter->writeAttribute('size', '2');
+ $objWriter->writeAttribute('baseType', 'variant');
+
+ // Variant
+ $objWriter->startElement('vt:variant');
+ $objWriter->writeElement('vt:lpstr', 'Worksheets');
+ $objWriter->endElement();
+
+ // Variant
+ $objWriter->startElement('vt:variant');
+ $objWriter->writeElement('vt:i4', $pPHPExcel->getSheetCount());
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // TitlesOfParts
+ $objWriter->startElement('TitlesOfParts');
+
+ // Vector
+ $objWriter->startElement('vt:vector');
+ $objWriter->writeAttribute('size', $pPHPExcel->getSheetCount());
+ $objWriter->writeAttribute('baseType', 'lpstr');
+
+ $sheetCount = $pPHPExcel->getSheetCount();
+ for ($i = 0; $i < $sheetCount; ++$i) {
+ $objWriter->writeElement('vt:lpstr', $pPHPExcel->getSheet($i)->getTitle());
+ }
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // Company
+ $objWriter->writeElement('Company', $pPHPExcel->getProperties()->getCompany());
+
+ // Company
+ $objWriter->writeElement('Manager', $pPHPExcel->getProperties()->getManager());
+
+ // LinksUpToDate
+ $objWriter->writeElement('LinksUpToDate', 'false');
+
+ // SharedDoc
+ $objWriter->writeElement('SharedDoc', 'false');
+
+ // HyperlinksChanged
+ $objWriter->writeElement('HyperlinksChanged', 'false');
+
+ // AppVersion
+ $objWriter->writeElement('AppVersion', '12.0000');
+
+ $objWriter->endElement();
+
+ // Return
+ return $objWriter->getData();
+ }
+
+ /**
+ * Write docProps/core.xml to XML format
+ *
+ * @param PHPExcel $pPHPExcel
+ * @return string XML Output
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function writeDocPropsCore(PHPExcel $pPHPExcel = null)
+ {
+ // Create XML writer
+ $objWriter = null;
+ if ($this->getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // cp:coreProperties
+ $objWriter->startElement('cp:coreProperties');
+ $objWriter->writeAttribute('xmlns:cp', 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties');
+ $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');
+ $objWriter->writeAttribute('xmlns:dcterms', 'http://purl.org/dc/terms/');
+ $objWriter->writeAttribute('xmlns:dcmitype', 'http://purl.org/dc/dcmitype/');
+ $objWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
+
+ // dc:creator
+ $objWriter->writeElement('dc:creator', $pPHPExcel->getProperties()->getCreator());
+
+ // cp:lastModifiedBy
+ $objWriter->writeElement('cp:lastModifiedBy', $pPHPExcel->getProperties()->getLastModifiedBy());
+
+ // dcterms:created
+ $objWriter->startElement('dcterms:created');
+ $objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF');
+ $objWriter->writeRawData(date(DATE_W3C, $pPHPExcel->getProperties()->getCreated()));
+ $objWriter->endElement();
+
+ // dcterms:modified
+ $objWriter->startElement('dcterms:modified');
+ $objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF');
+ $objWriter->writeRawData(date(DATE_W3C, $pPHPExcel->getProperties()->getModified()));
+ $objWriter->endElement();
+
+ // dc:title
+ $objWriter->writeElement('dc:title', $pPHPExcel->getProperties()->getTitle());
+
+ // dc:description
+ $objWriter->writeElement('dc:description', $pPHPExcel->getProperties()->getDescription());
+
+ // dc:subject
+ $objWriter->writeElement('dc:subject', $pPHPExcel->getProperties()->getSubject());
+
+ // cp:keywords
+ $objWriter->writeElement('cp:keywords', $pPHPExcel->getProperties()->getKeywords());
+
+ // cp:category
+ $objWriter->writeElement('cp:category', $pPHPExcel->getProperties()->getCategory());
+
+ $objWriter->endElement();
+
+ // Return
+ return $objWriter->getData();
+ }
+
+ /**
+ * Write docProps/custom.xml to XML format
+ *
+ * @param PHPExcel $pPHPExcel
+ * @return string XML Output
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function writeDocPropsCustom(PHPExcel $pPHPExcel = null)
+ {
+ $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties();
+ if (empty($customPropertyList)) {
+ return;
+ }
+
+ // Create XML writer
+ $objWriter = null;
+ if ($this->getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // cp:coreProperties
+ $objWriter->startElement('Properties');
+ $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/custom-properties');
+ $objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes');
+
+
+ foreach ($customPropertyList as $key => $customProperty) {
+ $propertyValue = $pPHPExcel->getProperties()->getCustomPropertyValue($customProperty);
+ $propertyType = $pPHPExcel->getProperties()->getCustomPropertyType($customProperty);
+
+ $objWriter->startElement('property');
+ $objWriter->writeAttribute('fmtid', '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}');
+ $objWriter->writeAttribute('pid', $key+2);
+ $objWriter->writeAttribute('name', $customProperty);
+
+ switch ($propertyType) {
+ case 'i':
+ $objWriter->writeElement('vt:i4', $propertyValue);
+ break;
+ case 'f':
+ $objWriter->writeElement('vt:r8', $propertyValue);
+ break;
+ case 'b':
+ $objWriter->writeElement('vt:bool', ($propertyValue) ? 'true' : 'false');
+ break;
+ case 'd':
+ $objWriter->startElement('vt:filetime');
+ $objWriter->writeRawData(date(DATE_W3C, $propertyValue));
+ $objWriter->endElement();
+ break;
+ default:
+ $objWriter->writeElement('vt:lpwstr', $propertyValue);
+ break;
+ }
+
+ $objWriter->endElement();
+ }
+
+
+ $objWriter->endElement();
+
+ return $objWriter->getData();
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Drawing.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Drawing.php
new file mode 100755
index 000000000..281438889
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Drawing.php
@@ -0,0 +1,589 @@
+getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // xdr:wsDr
+ $objWriter->startElement('xdr:wsDr');
+ $objWriter->writeAttribute('xmlns:xdr', 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing');
+ $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');
+
+ // Loop through images and write drawings
+ $i = 1;
+ $iterator = $pWorksheet->getDrawingCollection()->getIterator();
+ while ($iterator->valid()) {
+ $this->writeDrawing($objWriter, $iterator->current(), $i);
+
+ $iterator->next();
+ ++$i;
+ }
+
+ if ($includeCharts) {
+ $chartCount = $pWorksheet->getChartCount();
+ // Loop through charts and write the chart position
+ if ($chartCount > 0) {
+ for ($c = 0; $c < $chartCount; ++$c) {
+ $this->writeChart($objWriter, $pWorksheet->getChartByIndex($c), $c+$i);
+ }
+ }
+ }
+
+ $objWriter->endElement();
+
+ // Return
+ return $objWriter->getData();
+ }
+
+ /**
+ * Write drawings to XML format
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Chart $pChart
+ * @param int $pRelationId
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function writeChart(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Chart $pChart = null, $pRelationId = -1)
+ {
+ $tl = $pChart->getTopLeftPosition();
+ $tl['colRow'] = PHPExcel_Cell::coordinateFromString($tl['cell']);
+ $br = $pChart->getBottomRightPosition();
+ $br['colRow'] = PHPExcel_Cell::coordinateFromString($br['cell']);
+
+ $objWriter->startElement('xdr:twoCellAnchor');
+
+ $objWriter->startElement('xdr:from');
+ $objWriter->writeElement('xdr:col', PHPExcel_Cell::columnIndexFromString($tl['colRow'][0]) - 1);
+ $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($tl['xOffset']));
+ $objWriter->writeElement('xdr:row', $tl['colRow'][1] - 1);
+ $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($tl['yOffset']));
+ $objWriter->endElement();
+ $objWriter->startElement('xdr:to');
+ $objWriter->writeElement('xdr:col', PHPExcel_Cell::columnIndexFromString($br['colRow'][0]) - 1);
+ $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($br['xOffset']));
+ $objWriter->writeElement('xdr:row', $br['colRow'][1] - 1);
+ $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($br['yOffset']));
+ $objWriter->endElement();
+
+ $objWriter->startElement('xdr:graphicFrame');
+ $objWriter->writeAttribute('macro', '');
+ $objWriter->startElement('xdr:nvGraphicFramePr');
+ $objWriter->startElement('xdr:cNvPr');
+ $objWriter->writeAttribute('name', 'Chart '.$pRelationId);
+ $objWriter->writeAttribute('id', 1025 * $pRelationId);
+ $objWriter->endElement();
+ $objWriter->startElement('xdr:cNvGraphicFramePr');
+ $objWriter->startElement('a:graphicFrameLocks');
+ $objWriter->endElement();
+ $objWriter->endElement();
+ $objWriter->endElement();
+
+ $objWriter->startElement('xdr:xfrm');
+ $objWriter->startElement('a:off');
+ $objWriter->writeAttribute('x', '0');
+ $objWriter->writeAttribute('y', '0');
+ $objWriter->endElement();
+ $objWriter->startElement('a:ext');
+ $objWriter->writeAttribute('cx', '0');
+ $objWriter->writeAttribute('cy', '0');
+ $objWriter->endElement();
+ $objWriter->endElement();
+
+ $objWriter->startElement('a:graphic');
+ $objWriter->startElement('a:graphicData');
+ $objWriter->writeAttribute('uri', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
+ $objWriter->startElement('c:chart');
+ $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
+ $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
+ $objWriter->writeAttribute('r:id', 'rId'.$pRelationId);
+ $objWriter->endElement();
+ $objWriter->endElement();
+ $objWriter->endElement();
+ $objWriter->endElement();
+
+ $objWriter->startElement('xdr:clientData');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write drawings to XML format
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet_BaseDrawing $pDrawing
+ * @param int $pRelationId
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function writeDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet_BaseDrawing $pDrawing = null, $pRelationId = -1)
+ {
+ if ($pRelationId >= 0) {
+ // xdr:oneCellAnchor
+ $objWriter->startElement('xdr:oneCellAnchor');
+ // Image location
+ $aCoordinates = PHPExcel_Cell::coordinateFromString($pDrawing->getCoordinates());
+ $aCoordinates[0] = PHPExcel_Cell::columnIndexFromString($aCoordinates[0]);
+
+ // xdr:from
+ $objWriter->startElement('xdr:from');
+ $objWriter->writeElement('xdr:col', $aCoordinates[0] - 1);
+ $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetX()));
+ $objWriter->writeElement('xdr:row', $aCoordinates[1] - 1);
+ $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetY()));
+ $objWriter->endElement();
+
+ // xdr:ext
+ $objWriter->startElement('xdr:ext');
+ $objWriter->writeAttribute('cx', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getWidth()));
+ $objWriter->writeAttribute('cy', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getHeight()));
+ $objWriter->endElement();
+
+ // xdr:pic
+ $objWriter->startElement('xdr:pic');
+
+ // xdr:nvPicPr
+ $objWriter->startElement('xdr:nvPicPr');
+
+ // xdr:cNvPr
+ $objWriter->startElement('xdr:cNvPr');
+ $objWriter->writeAttribute('id', $pRelationId);
+ $objWriter->writeAttribute('name', $pDrawing->getName());
+ $objWriter->writeAttribute('descr', $pDrawing->getDescription());
+ $objWriter->endElement();
+
+ // xdr:cNvPicPr
+ $objWriter->startElement('xdr:cNvPicPr');
+
+ // a:picLocks
+ $objWriter->startElement('a:picLocks');
+ $objWriter->writeAttribute('noChangeAspect', '1');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // xdr:blipFill
+ $objWriter->startElement('xdr:blipFill');
+
+ // a:blip
+ $objWriter->startElement('a:blip');
+ $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
+ $objWriter->writeAttribute('r:embed', 'rId' . $pRelationId);
+ $objWriter->endElement();
+
+ // a:stretch
+ $objWriter->startElement('a:stretch');
+ $objWriter->writeElement('a:fillRect', null);
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // xdr:spPr
+ $objWriter->startElement('xdr:spPr');
+
+ // a:xfrm
+ $objWriter->startElement('a:xfrm');
+ $objWriter->writeAttribute('rot', PHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getRotation()));
+ $objWriter->endElement();
+
+ // a:prstGeom
+ $objWriter->startElement('a:prstGeom');
+ $objWriter->writeAttribute('prst', 'rect');
+
+ // a:avLst
+ $objWriter->writeElement('a:avLst', null);
+
+ $objWriter->endElement();
+
+// // a:solidFill
+// $objWriter->startElement('a:solidFill');
+
+// // a:srgbClr
+// $objWriter->startElement('a:srgbClr');
+// $objWriter->writeAttribute('val', 'FFFFFF');
+
+///* SHADE
+// // a:shade
+// $objWriter->startElement('a:shade');
+// $objWriter->writeAttribute('val', '85000');
+// $objWriter->endElement();
+//*/
+
+// $objWriter->endElement();
+
+// $objWriter->endElement();
+/*
+ // a:ln
+ $objWriter->startElement('a:ln');
+ $objWriter->writeAttribute('w', '88900');
+ $objWriter->writeAttribute('cap', 'sq');
+
+ // a:solidFill
+ $objWriter->startElement('a:solidFill');
+
+ // a:srgbClr
+ $objWriter->startElement('a:srgbClr');
+ $objWriter->writeAttribute('val', 'FFFFFF');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:miter
+ $objWriter->startElement('a:miter');
+ $objWriter->writeAttribute('lim', '800000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+*/
+
+ if ($pDrawing->getShadow()->getVisible()) {
+ // a:effectLst
+ $objWriter->startElement('a:effectLst');
+
+ // a:outerShdw
+ $objWriter->startElement('a:outerShdw');
+ $objWriter->writeAttribute('blurRad', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getBlurRadius()));
+ $objWriter->writeAttribute('dist', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getDistance()));
+ $objWriter->writeAttribute('dir', PHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getShadow()->getDirection()));
+ $objWriter->writeAttribute('algn', $pDrawing->getShadow()->getAlignment());
+ $objWriter->writeAttribute('rotWithShape', '0');
+
+ // a:srgbClr
+ $objWriter->startElement('a:srgbClr');
+ $objWriter->writeAttribute('val', $pDrawing->getShadow()->getColor()->getRGB());
+
+ // a:alpha
+ $objWriter->startElement('a:alpha');
+ $objWriter->writeAttribute('val', $pDrawing->getShadow()->getAlpha() * 1000);
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+/*
+
+ // a:scene3d
+ $objWriter->startElement('a:scene3d');
+
+ // a:camera
+ $objWriter->startElement('a:camera');
+ $objWriter->writeAttribute('prst', 'orthographicFront');
+ $objWriter->endElement();
+
+ // a:lightRig
+ $objWriter->startElement('a:lightRig');
+ $objWriter->writeAttribute('rig', 'twoPt');
+ $objWriter->writeAttribute('dir', 't');
+
+ // a:rot
+ $objWriter->startElement('a:rot');
+ $objWriter->writeAttribute('lat', '0');
+ $objWriter->writeAttribute('lon', '0');
+ $objWriter->writeAttribute('rev', '0');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+*/
+/*
+ // a:sp3d
+ $objWriter->startElement('a:sp3d');
+
+ // a:bevelT
+ $objWriter->startElement('a:bevelT');
+ $objWriter->writeAttribute('w', '25400');
+ $objWriter->writeAttribute('h', '19050');
+ $objWriter->endElement();
+
+ // a:contourClr
+ $objWriter->startElement('a:contourClr');
+
+ // a:srgbClr
+ $objWriter->startElement('a:srgbClr');
+ $objWriter->writeAttribute('val', 'FFFFFF');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+*/
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // xdr:clientData
+ $objWriter->writeElement('xdr:clientData', null);
+
+ $objWriter->endElement();
+ } else {
+ throw new PHPExcel_Writer_Exception("Invalid parameters passed.");
+ }
+ }
+
+ /**
+ * Write VML header/footer images to XML format
+ *
+ * @param PHPExcel_Worksheet $pWorksheet
+ * @return string XML Output
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function writeVMLHeaderFooterImages(PHPExcel_Worksheet $pWorksheet = null)
+ {
+ // Create XML writer
+ $objWriter = null;
+ if ($this->getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // Header/footer images
+ $images = $pWorksheet->getHeaderFooter()->getImages();
+
+ // xml
+ $objWriter->startElement('xml');
+ $objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml');
+ $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office');
+ $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel');
+
+ // o:shapelayout
+ $objWriter->startElement('o:shapelayout');
+ $objWriter->writeAttribute('v:ext', 'edit');
+
+ // o:idmap
+ $objWriter->startElement('o:idmap');
+ $objWriter->writeAttribute('v:ext', 'edit');
+ $objWriter->writeAttribute('data', '1');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // v:shapetype
+ $objWriter->startElement('v:shapetype');
+ $objWriter->writeAttribute('id', '_x0000_t75');
+ $objWriter->writeAttribute('coordsize', '21600,21600');
+ $objWriter->writeAttribute('o:spt', '75');
+ $objWriter->writeAttribute('o:preferrelative', 't');
+ $objWriter->writeAttribute('path', 'm@4@5l@4@11@9@11@9@5xe');
+ $objWriter->writeAttribute('filled', 'f');
+ $objWriter->writeAttribute('stroked', 'f');
+
+ // v:stroke
+ $objWriter->startElement('v:stroke');
+ $objWriter->writeAttribute('joinstyle', 'miter');
+ $objWriter->endElement();
+
+ // v:formulas
+ $objWriter->startElement('v:formulas');
+
+ // v:f
+ $objWriter->startElement('v:f');
+ $objWriter->writeAttribute('eqn', 'if lineDrawn pixelLineWidth 0');
+ $objWriter->endElement();
+
+ // v:f
+ $objWriter->startElement('v:f');
+ $objWriter->writeAttribute('eqn', 'sum @0 1 0');
+ $objWriter->endElement();
+
+ // v:f
+ $objWriter->startElement('v:f');
+ $objWriter->writeAttribute('eqn', 'sum 0 0 @1');
+ $objWriter->endElement();
+
+ // v:f
+ $objWriter->startElement('v:f');
+ $objWriter->writeAttribute('eqn', 'prod @2 1 2');
+ $objWriter->endElement();
+
+ // v:f
+ $objWriter->startElement('v:f');
+ $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelWidth');
+ $objWriter->endElement();
+
+ // v:f
+ $objWriter->startElement('v:f');
+ $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelHeight');
+ $objWriter->endElement();
+
+ // v:f
+ $objWriter->startElement('v:f');
+ $objWriter->writeAttribute('eqn', 'sum @0 0 1');
+ $objWriter->endElement();
+
+ // v:f
+ $objWriter->startElement('v:f');
+ $objWriter->writeAttribute('eqn', 'prod @6 1 2');
+ $objWriter->endElement();
+
+ // v:f
+ $objWriter->startElement('v:f');
+ $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelWidth');
+ $objWriter->endElement();
+
+ // v:f
+ $objWriter->startElement('v:f');
+ $objWriter->writeAttribute('eqn', 'sum @8 21600 0');
+ $objWriter->endElement();
+
+ // v:f
+ $objWriter->startElement('v:f');
+ $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelHeight');
+ $objWriter->endElement();
+
+ // v:f
+ $objWriter->startElement('v:f');
+ $objWriter->writeAttribute('eqn', 'sum @10 21600 0');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // v:path
+ $objWriter->startElement('v:path');
+ $objWriter->writeAttribute('o:extrusionok', 'f');
+ $objWriter->writeAttribute('gradientshapeok', 't');
+ $objWriter->writeAttribute('o:connecttype', 'rect');
+ $objWriter->endElement();
+
+ // o:lock
+ $objWriter->startElement('o:lock');
+ $objWriter->writeAttribute('v:ext', 'edit');
+ $objWriter->writeAttribute('aspectratio', 't');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // Loop through images
+ foreach ($images as $key => $value) {
+ $this->writeVMLHeaderFooterImage($objWriter, $key, $value);
+ }
+
+ $objWriter->endElement();
+
+ // Return
+ return $objWriter->getData();
+ }
+
+ /**
+ * Write VML comment to XML format
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param string $pReference Reference
+ * @param PHPExcel_Worksheet_HeaderFooterDrawing $pImage Image
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeVMLHeaderFooterImage(PHPExcel_Shared_XMLWriter $objWriter = null, $pReference = '', PHPExcel_Worksheet_HeaderFooterDrawing $pImage = null)
+ {
+ // Calculate object id
+ preg_match('{(\d+)}', md5($pReference), $m);
+ $id = 1500 + (substr($m[1], 0, 2) * 1);
+
+ // Calculate offset
+ $width = $pImage->getWidth();
+ $height = $pImage->getHeight();
+ $marginLeft = $pImage->getOffsetX();
+ $marginTop = $pImage->getOffsetY();
+
+ // v:shape
+ $objWriter->startElement('v:shape');
+ $objWriter->writeAttribute('id', $pReference);
+ $objWriter->writeAttribute('o:spid', '_x0000_s' . $id);
+ $objWriter->writeAttribute('type', '#_x0000_t75');
+ $objWriter->writeAttribute('style', "position:absolute;margin-left:{$marginLeft}px;margin-top:{$marginTop}px;width:{$width}px;height:{$height}px;z-index:1");
+
+ // v:imagedata
+ $objWriter->startElement('v:imagedata');
+ $objWriter->writeAttribute('o:relid', 'rId' . $pReference);
+ $objWriter->writeAttribute('o:title', $pImage->getName());
+ $objWriter->endElement();
+
+ // o:lock
+ $objWriter->startElement('o:lock');
+ $objWriter->writeAttribute('v:ext', 'edit');
+ $objWriter->writeAttribute('rotation', 't');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+
+
+ /**
+ * Get an array of all drawings
+ *
+ * @param PHPExcel $pPHPExcel
+ * @return PHPExcel_Worksheet_Drawing[] All drawings in PHPExcel
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function allDrawings(PHPExcel $pPHPExcel = null)
+ {
+ // Get an array of all drawings
+ $aDrawings = array();
+
+ // Loop through PHPExcel
+ $sheetCount = $pPHPExcel->getSheetCount();
+ for ($i = 0; $i < $sheetCount; ++$i) {
+ // Loop through images and add to array
+ $iterator = $pPHPExcel->getSheet($i)->getDrawingCollection()->getIterator();
+ while ($iterator->valid()) {
+ $aDrawings[] = $iterator->current();
+
+ $iterator->next();
+ }
+ }
+
+ return $aDrawings;
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Rels.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Rels.php
new file mode 100755
index 000000000..14ff33710
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Rels.php
@@ -0,0 +1,424 @@
+getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // Relationships
+ $objWriter->startElement('Relationships');
+ $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
+
+ $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties();
+ if (!empty($customPropertyList)) {
+ // Relationship docProps/app.xml
+ $this->writeRelationship(
+ $objWriter,
+ 4,
+ 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties',
+ 'docProps/custom.xml'
+ );
+
+ }
+
+ // Relationship docProps/app.xml
+ $this->writeRelationship(
+ $objWriter,
+ 3,
+ 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties',
+ 'docProps/app.xml'
+ );
+
+ // Relationship docProps/core.xml
+ $this->writeRelationship(
+ $objWriter,
+ 2,
+ 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties',
+ 'docProps/core.xml'
+ );
+
+ // Relationship xl/workbook.xml
+ $this->writeRelationship(
+ $objWriter,
+ 1,
+ 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument',
+ 'xl/workbook.xml'
+ );
+ // a custom UI in workbook ?
+ if ($pPHPExcel->hasRibbon()) {
+ $this->writeRelationShip(
+ $objWriter,
+ 5,
+ 'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility',
+ $pPHPExcel->getRibbonXMLData('target')
+ );
+ }
+
+ $objWriter->endElement();
+
+ return $objWriter->getData();
+ }
+
+ /**
+ * Write workbook relationships to XML format
+ *
+ * @param PHPExcel $pPHPExcel
+ * @return string XML Output
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function writeWorkbookRelationships(PHPExcel $pPHPExcel = null)
+ {
+ // Create XML writer
+ $objWriter = null;
+ if ($this->getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // Relationships
+ $objWriter->startElement('Relationships');
+ $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
+
+ // Relationship styles.xml
+ $this->writeRelationship(
+ $objWriter,
+ 1,
+ 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles',
+ 'styles.xml'
+ );
+
+ // Relationship theme/theme1.xml
+ $this->writeRelationship(
+ $objWriter,
+ 2,
+ 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme',
+ 'theme/theme1.xml'
+ );
+
+ // Relationship sharedStrings.xml
+ $this->writeRelationship(
+ $objWriter,
+ 3,
+ 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings',
+ 'sharedStrings.xml'
+ );
+
+ // Relationships with sheets
+ $sheetCount = $pPHPExcel->getSheetCount();
+ for ($i = 0; $i < $sheetCount; ++$i) {
+ $this->writeRelationship(
+ $objWriter,
+ ($i + 1 + 3),
+ 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet',
+ 'worksheets/sheet' . ($i + 1) . '.xml'
+ );
+ }
+ // Relationships for vbaProject if needed
+ // id : just after the last sheet
+ if ($pPHPExcel->hasMacros()) {
+ $this->writeRelationShip(
+ $objWriter,
+ ($i + 1 + 3),
+ 'http://schemas.microsoft.com/office/2006/relationships/vbaProject',
+ 'vbaProject.bin'
+ );
+ ++$i;//increment i if needed for an another relation
+ }
+
+ $objWriter->endElement();
+
+ return $objWriter->getData();
+ }
+
+ /**
+ * Write worksheet relationships to XML format
+ *
+ * Numbering is as follows:
+ * rId1 - Drawings
+ * rId_hyperlink_x - Hyperlinks
+ *
+ * @param PHPExcel_Worksheet $pWorksheet
+ * @param int $pWorksheetId
+ * @param boolean $includeCharts Flag indicating if we should write charts
+ * @return string XML Output
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = null, $pWorksheetId = 1, $includeCharts = false)
+ {
+ // Create XML writer
+ $objWriter = null;
+ if ($this->getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // Relationships
+ $objWriter->startElement('Relationships');
+ $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
+
+ // Write drawing relationships?
+ $d = 0;
+ if ($includeCharts) {
+ $charts = $pWorksheet->getChartCollection();
+ } else {
+ $charts = array();
+ }
+ if (($pWorksheet->getDrawingCollection()->count() > 0) ||
+ (count($charts) > 0)) {
+ $this->writeRelationship(
+ $objWriter,
+ ++$d,
+ 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing',
+ '../drawings/drawing' . $pWorksheetId . '.xml'
+ );
+ }
+
+ // Write chart relationships?
+// $chartCount = 0;
+// $charts = $pWorksheet->getChartCollection();
+// echo 'Chart Rels: ' , count($charts) , '
';
+// if (count($charts) > 0) {
+// foreach ($charts as $chart) {
+// $this->writeRelationship(
+// $objWriter,
+// ++$d,
+// 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart',
+// '../charts/chart' . ++$chartCount . '.xml'
+// );
+// }
+// }
+//
+ // Write hyperlink relationships?
+ $i = 1;
+ foreach ($pWorksheet->getHyperlinkCollection() as $hyperlink) {
+ if (!$hyperlink->isInternal()) {
+ $this->writeRelationship(
+ $objWriter,
+ '_hyperlink_' . $i,
+ 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink',
+ $hyperlink->getUrl(),
+ 'External'
+ );
+
+ ++$i;
+ }
+ }
+
+ // Write comments relationship?
+ $i = 1;
+ if (count($pWorksheet->getComments()) > 0) {
+ $this->writeRelationship(
+ $objWriter,
+ '_comments_vml' . $i,
+ 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing',
+ '../drawings/vmlDrawing' . $pWorksheetId . '.vml'
+ );
+
+ $this->writeRelationship(
+ $objWriter,
+ '_comments' . $i,
+ 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments',
+ '../comments' . $pWorksheetId . '.xml'
+ );
+ }
+
+ // Write header/footer relationship?
+ $i = 1;
+ if (count($pWorksheet->getHeaderFooter()->getImages()) > 0) {
+ $this->writeRelationship(
+ $objWriter,
+ '_headerfooter_vml' . $i,
+ 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing',
+ '../drawings/vmlDrawingHF' . $pWorksheetId . '.vml'
+ );
+ }
+
+ $objWriter->endElement();
+
+ return $objWriter->getData();
+ }
+
+ /**
+ * Write drawing relationships to XML format
+ *
+ * @param PHPExcel_Worksheet $pWorksheet
+ * @param int &$chartRef Chart ID
+ * @param boolean $includeCharts Flag indicating if we should write charts
+ * @return string XML Output
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function writeDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, $includeCharts = false)
+ {
+ // Create XML writer
+ $objWriter = null;
+ if ($this->getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // Relationships
+ $objWriter->startElement('Relationships');
+ $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
+
+ // Loop through images and write relationships
+ $i = 1;
+ $iterator = $pWorksheet->getDrawingCollection()->getIterator();
+ while ($iterator->valid()) {
+ if ($iterator->current() instanceof PHPExcel_Worksheet_Drawing
+ || $iterator->current() instanceof PHPExcel_Worksheet_MemoryDrawing) {
+ // Write relationship for image drawing
+ $this->writeRelationship(
+ $objWriter,
+ $i,
+ 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
+ '../media/' . str_replace(' ', '', $iterator->current()->getIndexedFilename())
+ );
+ }
+
+ $iterator->next();
+ ++$i;
+ }
+
+ if ($includeCharts) {
+ // Loop through charts and write relationships
+ $chartCount = $pWorksheet->getChartCount();
+ if ($chartCount > 0) {
+ for ($c = 0; $c < $chartCount; ++$c) {
+ $this->writeRelationship(
+ $objWriter,
+ $i++,
+ 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart',
+ '../charts/chart' . ++$chartRef . '.xml'
+ );
+ }
+ }
+ }
+
+ $objWriter->endElement();
+
+ return $objWriter->getData();
+ }
+
+ /**
+ * Write header/footer drawing relationships to XML format
+ *
+ * @param PHPExcel_Worksheet $pWorksheet
+ * @return string XML Output
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function writeHeaderFooterDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null)
+ {
+ // Create XML writer
+ $objWriter = null;
+ if ($this->getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // Relationships
+ $objWriter->startElement('Relationships');
+ $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
+
+ // Loop through images and write relationships
+ foreach ($pWorksheet->getHeaderFooter()->getImages() as $key => $value) {
+ // Write relationship for image drawing
+ $this->writeRelationship(
+ $objWriter,
+ $key,
+ 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
+ '../media/' . $value->getIndexedFilename()
+ );
+ }
+
+ $objWriter->endElement();
+
+ return $objWriter->getData();
+ }
+
+ /**
+ * Write Override content type
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param int $pId Relationship ID. rId will be prepended!
+ * @param string $pType Relationship type
+ * @param string $pTarget Relationship target
+ * @param string $pTargetMode Relationship target mode
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeRelationship(PHPExcel_Shared_XMLWriter $objWriter = null, $pId = 1, $pType = '', $pTarget = '', $pTargetMode = '')
+ {
+ if ($pType != '' && $pTarget != '') {
+ // Write relationship
+ $objWriter->startElement('Relationship');
+ $objWriter->writeAttribute('Id', 'rId' . $pId);
+ $objWriter->writeAttribute('Type', $pType);
+ $objWriter->writeAttribute('Target', $pTarget);
+
+ if ($pTargetMode != '') {
+ $objWriter->writeAttribute('TargetMode', $pTargetMode);
+ }
+
+ $objWriter->endElement();
+ } else {
+ throw new PHPExcel_Writer_Exception("Invalid parameters passed.");
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php
new file mode 100755
index 000000000..5a4a9fc09
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php
@@ -0,0 +1,67 @@
+getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // Relationships
+ $objWriter->startElement('Relationships');
+ $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
+ $localRels = $pPHPExcel->getRibbonBinObjects('names');
+ if (is_array($localRels)) {
+ foreach ($localRels as $aId => $aTarget) {
+ $objWriter->startElement('Relationship');
+ $objWriter->writeAttribute('Id', $aId);
+ $objWriter->writeAttribute('Type', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image');
+ $objWriter->writeAttribute('Target', $aTarget);
+ $objWriter->endElement();
+ }
+ }
+ $objWriter->endElement();
+
+ return $objWriter->getData();
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php
new file mode 100755
index 000000000..bee0e6436
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php
@@ -0,0 +1,63 @@
+getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // Relationships
+ $objWriter->startElement('Relationships');
+ $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
+ $objWriter->startElement('Relationship');
+ $objWriter->writeAttribute('Id', 'rId1');
+ $objWriter->writeAttribute('Type', 'http://schemas.microsoft.com/office/2006/relationships/vbaProjectSignature');
+ $objWriter->writeAttribute('Target', 'vbaProjectSignature.bin');
+ $objWriter->endElement();
+ $objWriter->endElement();
+
+ return $objWriter->getData();
+
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/StringTable.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/StringTable.php
new file mode 100755
index 000000000..fccec669f
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/StringTable.php
@@ -0,0 +1,313 @@
+flipStringTable($aStringTable);
+
+ // Loop through cells
+ foreach ($pSheet->getCellCollection() as $cellID) {
+ $cell = $pSheet->getCell($cellID);
+ $cellValue = $cell->getValue();
+ if (!is_object($cellValue) &&
+ ($cellValue !== null) &&
+ $cellValue !== '' &&
+ !isset($aFlippedStringTable[$cellValue]) &&
+ ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_STRING || $cell->getDataType() == PHPExcel_Cell_DataType::TYPE_STRING2 || $cell->getDataType() == PHPExcel_Cell_DataType::TYPE_NULL)) {
+ $aStringTable[] = $cellValue;
+ $aFlippedStringTable[$cellValue] = true;
+ } elseif ($cellValue instanceof PHPExcel_RichText &&
+ ($cellValue !== null) &&
+ !isset($aFlippedStringTable[$cellValue->getHashCode()])) {
+ $aStringTable[] = $cellValue;
+ $aFlippedStringTable[$cellValue->getHashCode()] = true;
+ }
+ }
+
+ return $aStringTable;
+ } else {
+ throw new PHPExcel_Writer_Exception("Invalid PHPExcel_Worksheet object passed.");
+ }
+ }
+
+ /**
+ * Write string table to XML format
+ *
+ * @param string[] $pStringTable
+ * @return string XML Output
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function writeStringTable($pStringTable = null)
+ {
+ if ($pStringTable !== null) {
+ // Create XML writer
+ $objWriter = null;
+ if ($this->getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // String table
+ $objWriter->startElement('sst');
+ $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
+ $objWriter->writeAttribute('uniqueCount', count($pStringTable));
+
+ // Loop through string table
+ foreach ($pStringTable as $textElement) {
+ $objWriter->startElement('si');
+
+ if (! $textElement instanceof PHPExcel_RichText) {
+ $textToWrite = PHPExcel_Shared_String::ControlCharacterPHP2OOXML($textElement);
+ $objWriter->startElement('t');
+ if ($textToWrite !== trim($textToWrite)) {
+ $objWriter->writeAttribute('xml:space', 'preserve');
+ }
+ $objWriter->writeRawData($textToWrite);
+ $objWriter->endElement();
+ } elseif ($textElement instanceof PHPExcel_RichText) {
+ $this->writeRichText($objWriter, $textElement);
+ }
+
+ $objWriter->endElement();
+ }
+
+ $objWriter->endElement();
+
+ return $objWriter->getData();
+ } else {
+ throw new PHPExcel_Writer_Exception("Invalid string table array passed.");
+ }
+ }
+
+ /**
+ * Write Rich Text
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_RichText $pRichText Rich text
+ * @param string $prefix Optional Namespace prefix
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function writeRichText(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_RichText $pRichText = null, $prefix = null)
+ {
+ if ($prefix !== null) {
+ $prefix .= ':';
+ }
+
+ // Loop through rich text elements
+ $elements = $pRichText->getRichTextElements();
+ foreach ($elements as $element) {
+ // r
+ $objWriter->startElement($prefix.'r');
+
+ // rPr
+ if ($element instanceof PHPExcel_RichText_Run) {
+ // rPr
+ $objWriter->startElement($prefix.'rPr');
+
+ // rFont
+ $objWriter->startElement($prefix.'rFont');
+ $objWriter->writeAttribute('val', $element->getFont()->getName());
+ $objWriter->endElement();
+
+ // Bold
+ $objWriter->startElement($prefix.'b');
+ $objWriter->writeAttribute('val', ($element->getFont()->getBold() ? 'true' : 'false'));
+ $objWriter->endElement();
+
+ // Italic
+ $objWriter->startElement($prefix.'i');
+ $objWriter->writeAttribute('val', ($element->getFont()->getItalic() ? 'true' : 'false'));
+ $objWriter->endElement();
+
+ // Superscript / subscript
+ if ($element->getFont()->getSuperScript() || $element->getFont()->getSubScript()) {
+ $objWriter->startElement($prefix.'vertAlign');
+ if ($element->getFont()->getSuperScript()) {
+ $objWriter->writeAttribute('val', 'superscript');
+ } elseif ($element->getFont()->getSubScript()) {
+ $objWriter->writeAttribute('val', 'subscript');
+ }
+ $objWriter->endElement();
+ }
+
+ // Strikethrough
+ $objWriter->startElement($prefix.'strike');
+ $objWriter->writeAttribute('val', ($element->getFont()->getStrikethrough() ? 'true' : 'false'));
+ $objWriter->endElement();
+
+ // Color
+ $objWriter->startElement($prefix.'color');
+ $objWriter->writeAttribute('rgb', $element->getFont()->getColor()->getARGB());
+ $objWriter->endElement();
+
+ // Size
+ $objWriter->startElement($prefix.'sz');
+ $objWriter->writeAttribute('val', $element->getFont()->getSize());
+ $objWriter->endElement();
+
+ // Underline
+ $objWriter->startElement($prefix.'u');
+ $objWriter->writeAttribute('val', $element->getFont()->getUnderline());
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+
+ // t
+ $objWriter->startElement($prefix.'t');
+ $objWriter->writeAttribute('xml:space', 'preserve');
+ $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($element->getText()));
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+ }
+
+ /**
+ * Write Rich Text
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param string|PHPExcel_RichText $pRichText text string or Rich text
+ * @param string $prefix Optional Namespace prefix
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function writeRichTextForCharts(PHPExcel_Shared_XMLWriter $objWriter = null, $pRichText = null, $prefix = null)
+ {
+ if (!$pRichText instanceof PHPExcel_RichText) {
+ $textRun = $pRichText;
+ $pRichText = new PHPExcel_RichText();
+ $pRichText->createTextRun($textRun);
+ }
+
+ if ($prefix !== null) {
+ $prefix .= ':';
+ }
+
+ // Loop through rich text elements
+ $elements = $pRichText->getRichTextElements();
+ foreach ($elements as $element) {
+ // r
+ $objWriter->startElement($prefix.'r');
+
+ // rPr
+ $objWriter->startElement($prefix.'rPr');
+
+ // Bold
+ $objWriter->writeAttribute('b', ($element->getFont()->getBold() ? 1 : 0));
+ // Italic
+ $objWriter->writeAttribute('i', ($element->getFont()->getItalic() ? 1 : 0));
+ // Underline
+ $underlineType = $element->getFont()->getUnderline();
+ switch ($underlineType) {
+ case 'single':
+ $underlineType = 'sng';
+ break;
+ case 'double':
+ $underlineType = 'dbl';
+ break;
+ }
+ $objWriter->writeAttribute('u', $underlineType);
+ // Strikethrough
+ $objWriter->writeAttribute('strike', ($element->getFont()->getStrikethrough() ? 'sngStrike' : 'noStrike'));
+
+ // rFont
+ $objWriter->startElement($prefix.'latin');
+ $objWriter->writeAttribute('typeface', $element->getFont()->getName());
+ $objWriter->endElement();
+
+ // Superscript / subscript
+// if ($element->getFont()->getSuperScript() || $element->getFont()->getSubScript()) {
+// $objWriter->startElement($prefix.'vertAlign');
+// if ($element->getFont()->getSuperScript()) {
+// $objWriter->writeAttribute('val', 'superscript');
+// } elseif ($element->getFont()->getSubScript()) {
+// $objWriter->writeAttribute('val', 'subscript');
+// }
+// $objWriter->endElement();
+// }
+//
+ $objWriter->endElement();
+
+ // t
+ $objWriter->startElement($prefix.'t');
+// $objWriter->writeAttribute('xml:space', 'preserve'); // Excel2010 accepts, Excel2007 complains
+ $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($element->getText()));
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+ }
+
+ /**
+ * Flip string table (for index searching)
+ *
+ * @param array $stringTable Stringtable
+ * @return array
+ */
+ public function flipStringTable($stringTable = array())
+ {
+ // Return value
+ $returnValue = array();
+
+ // Loop through stringtable and add flipped items to $returnValue
+ foreach ($stringTable as $key => $value) {
+ if (! $value instanceof PHPExcel_RichText) {
+ $returnValue[$value] = $key;
+ } elseif ($value instanceof PHPExcel_RichText) {
+ $returnValue[$value->getHashCode()] = $key;
+ }
+ }
+
+ return $returnValue;
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Style.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Style.php
new file mode 100755
index 000000000..d3f0af7b2
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Style.php
@@ -0,0 +1,696 @@
+getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // styleSheet
+ $objWriter->startElement('styleSheet');
+ $objWriter->writeAttribute('xml:space', 'preserve');
+ $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
+
+ // numFmts
+ $objWriter->startElement('numFmts');
+ $objWriter->writeAttribute('count', $this->getParentWriter()->getNumFmtHashTable()->count());
+
+ // numFmt
+ for ($i = 0; $i < $this->getParentWriter()->getNumFmtHashTable()->count(); ++$i) {
+ $this->writeNumFmt($objWriter, $this->getParentWriter()->getNumFmtHashTable()->getByIndex($i), $i);
+ }
+
+ $objWriter->endElement();
+
+ // fonts
+ $objWriter->startElement('fonts');
+ $objWriter->writeAttribute('count', $this->getParentWriter()->getFontHashTable()->count());
+
+ // font
+ for ($i = 0; $i < $this->getParentWriter()->getFontHashTable()->count(); ++$i) {
+ $this->writeFont($objWriter, $this->getParentWriter()->getFontHashTable()->getByIndex($i));
+ }
+
+ $objWriter->endElement();
+
+ // fills
+ $objWriter->startElement('fills');
+ $objWriter->writeAttribute('count', $this->getParentWriter()->getFillHashTable()->count());
+
+ // fill
+ for ($i = 0; $i < $this->getParentWriter()->getFillHashTable()->count(); ++$i) {
+ $this->writeFill($objWriter, $this->getParentWriter()->getFillHashTable()->getByIndex($i));
+ }
+
+ $objWriter->endElement();
+
+ // borders
+ $objWriter->startElement('borders');
+ $objWriter->writeAttribute('count', $this->getParentWriter()->getBordersHashTable()->count());
+
+ // border
+ for ($i = 0; $i < $this->getParentWriter()->getBordersHashTable()->count(); ++$i) {
+ $this->writeBorder($objWriter, $this->getParentWriter()->getBordersHashTable()->getByIndex($i));
+ }
+
+ $objWriter->endElement();
+
+ // cellStyleXfs
+ $objWriter->startElement('cellStyleXfs');
+ $objWriter->writeAttribute('count', 1);
+
+ // xf
+ $objWriter->startElement('xf');
+ $objWriter->writeAttribute('numFmtId', 0);
+ $objWriter->writeAttribute('fontId', 0);
+ $objWriter->writeAttribute('fillId', 0);
+ $objWriter->writeAttribute('borderId', 0);
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // cellXfs
+ $objWriter->startElement('cellXfs');
+ $objWriter->writeAttribute('count', count($pPHPExcel->getCellXfCollection()));
+
+ // xf
+ foreach ($pPHPExcel->getCellXfCollection() as $cellXf) {
+ $this->writeCellStyleXf($objWriter, $cellXf, $pPHPExcel);
+ }
+
+ $objWriter->endElement();
+
+ // cellStyles
+ $objWriter->startElement('cellStyles');
+ $objWriter->writeAttribute('count', 1);
+
+ // cellStyle
+ $objWriter->startElement('cellStyle');
+ $objWriter->writeAttribute('name', 'Normal');
+ $objWriter->writeAttribute('xfId', 0);
+ $objWriter->writeAttribute('builtinId', 0);
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // dxfs
+ $objWriter->startElement('dxfs');
+ $objWriter->writeAttribute('count', $this->getParentWriter()->getStylesConditionalHashTable()->count());
+
+ // dxf
+ for ($i = 0; $i < $this->getParentWriter()->getStylesConditionalHashTable()->count(); ++$i) {
+ $this->writeCellStyleDxf($objWriter, $this->getParentWriter()->getStylesConditionalHashTable()->getByIndex($i)->getStyle());
+ }
+
+ $objWriter->endElement();
+
+ // tableStyles
+ $objWriter->startElement('tableStyles');
+ $objWriter->writeAttribute('defaultTableStyle', 'TableStyleMedium9');
+ $objWriter->writeAttribute('defaultPivotStyle', 'PivotTableStyle1');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // Return
+ return $objWriter->getData();
+ }
+
+ /**
+ * Write Fill
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Style_Fill $pFill Fill style
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null)
+ {
+ // Check if this is a pattern type or gradient type
+ if ($pFill->getFillType() === PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR ||
+ $pFill->getFillType() === PHPExcel_Style_Fill::FILL_GRADIENT_PATH) {
+ // Gradient fill
+ $this->writeGradientFill($objWriter, $pFill);
+ } elseif ($pFill->getFillType() !== null) {
+ // Pattern fill
+ $this->writePatternFill($objWriter, $pFill);
+ }
+ }
+
+ /**
+ * Write Gradient Fill
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Style_Fill $pFill Fill style
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeGradientFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null)
+ {
+ // fill
+ $objWriter->startElement('fill');
+
+ // gradientFill
+ $objWriter->startElement('gradientFill');
+ $objWriter->writeAttribute('type', $pFill->getFillType());
+ $objWriter->writeAttribute('degree', $pFill->getRotation());
+
+ // stop
+ $objWriter->startElement('stop');
+ $objWriter->writeAttribute('position', '0');
+
+ // color
+ $objWriter->startElement('color');
+ $objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB());
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // stop
+ $objWriter->startElement('stop');
+ $objWriter->writeAttribute('position', '1');
+
+ // color
+ $objWriter->startElement('color');
+ $objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB());
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write Pattern Fill
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Style_Fill $pFill Fill style
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writePatternFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null)
+ {
+ // fill
+ $objWriter->startElement('fill');
+
+ // patternFill
+ $objWriter->startElement('patternFill');
+ $objWriter->writeAttribute('patternType', $pFill->getFillType());
+
+ if ($pFill->getFillType() !== PHPExcel_Style_Fill::FILL_NONE) {
+ // fgColor
+ if ($pFill->getStartColor()->getARGB()) {
+ $objWriter->startElement('fgColor');
+ $objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB());
+ $objWriter->endElement();
+ }
+ }
+ if ($pFill->getFillType() !== PHPExcel_Style_Fill::FILL_NONE) {
+ // bgColor
+ if ($pFill->getEndColor()->getARGB()) {
+ $objWriter->startElement('bgColor');
+ $objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB());
+ $objWriter->endElement();
+ }
+ }
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write Font
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Style_Font $pFont Font style
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeFont(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Font $pFont = null)
+ {
+ // font
+ $objWriter->startElement('font');
+ // Weird! The order of these elements actually makes a difference when opening Excel2007
+ // files in Excel2003 with the compatibility pack. It's not documented behaviour,
+ // and makes for a real WTF!
+
+ // Bold. We explicitly write this element also when false (like MS Office Excel 2007 does
+ // for conditional formatting). Otherwise it will apparently not be picked up in conditional
+ // formatting style dialog
+ if ($pFont->getBold() !== null) {
+ $objWriter->startElement('b');
+ $objWriter->writeAttribute('val', $pFont->getBold() ? '1' : '0');
+ $objWriter->endElement();
+ }
+
+ // Italic
+ if ($pFont->getItalic() !== null) {
+ $objWriter->startElement('i');
+ $objWriter->writeAttribute('val', $pFont->getItalic() ? '1' : '0');
+ $objWriter->endElement();
+ }
+
+ // Strikethrough
+ if ($pFont->getStrikethrough() !== null) {
+ $objWriter->startElement('strike');
+ $objWriter->writeAttribute('val', $pFont->getStrikethrough() ? '1' : '0');
+ $objWriter->endElement();
+ }
+
+ // Underline
+ if ($pFont->getUnderline() !== null) {
+ $objWriter->startElement('u');
+ $objWriter->writeAttribute('val', $pFont->getUnderline());
+ $objWriter->endElement();
+ }
+
+ // Superscript / subscript
+ if ($pFont->getSuperScript() === true || $pFont->getSubScript() === true) {
+ $objWriter->startElement('vertAlign');
+ if ($pFont->getSuperScript() === true) {
+ $objWriter->writeAttribute('val', 'superscript');
+ } elseif ($pFont->getSubScript() === true) {
+ $objWriter->writeAttribute('val', 'subscript');
+ }
+ $objWriter->endElement();
+ }
+
+ // Size
+ if ($pFont->getSize() !== null) {
+ $objWriter->startElement('sz');
+ $objWriter->writeAttribute('val', $pFont->getSize());
+ $objWriter->endElement();
+ }
+
+ // Foreground color
+ if ($pFont->getColor()->getARGB() !== null) {
+ $objWriter->startElement('color');
+ $objWriter->writeAttribute('rgb', $pFont->getColor()->getARGB());
+ $objWriter->endElement();
+ }
+
+ // Name
+ if ($pFont->getName() !== null) {
+ $objWriter->startElement('name');
+ $objWriter->writeAttribute('val', $pFont->getName());
+ $objWriter->endElement();
+ }
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write Border
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Style_Borders $pBorders Borders style
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeBorder(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Borders $pBorders = null)
+ {
+ // Write border
+ $objWriter->startElement('border');
+ // Diagonal?
+ switch ($pBorders->getDiagonalDirection()) {
+ case PHPExcel_Style_Borders::DIAGONAL_UP:
+ $objWriter->writeAttribute('diagonalUp', 'true');
+ $objWriter->writeAttribute('diagonalDown', 'false');
+ break;
+ case PHPExcel_Style_Borders::DIAGONAL_DOWN:
+ $objWriter->writeAttribute('diagonalUp', 'false');
+ $objWriter->writeAttribute('diagonalDown', 'true');
+ break;
+ case PHPExcel_Style_Borders::DIAGONAL_BOTH:
+ $objWriter->writeAttribute('diagonalUp', 'true');
+ $objWriter->writeAttribute('diagonalDown', 'true');
+ break;
+ }
+
+ // BorderPr
+ $this->writeBorderPr($objWriter, 'left', $pBorders->getLeft());
+ $this->writeBorderPr($objWriter, 'right', $pBorders->getRight());
+ $this->writeBorderPr($objWriter, 'top', $pBorders->getTop());
+ $this->writeBorderPr($objWriter, 'bottom', $pBorders->getBottom());
+ $this->writeBorderPr($objWriter, 'diagonal', $pBorders->getDiagonal());
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write Cell Style Xf
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Style $pStyle Style
+ * @param PHPExcel $pPHPExcel Workbook
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeCellStyleXf(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style $pStyle = null, PHPExcel $pPHPExcel = null)
+ {
+ // xf
+ $objWriter->startElement('xf');
+ $objWriter->writeAttribute('xfId', 0);
+ $objWriter->writeAttribute('fontId', (int)$this->getParentWriter()->getFontHashTable()->getIndexForHashCode($pStyle->getFont()->getHashCode()));
+ if ($pStyle->getQuotePrefix()) {
+ $objWriter->writeAttribute('quotePrefix', 1);
+ }
+
+ if ($pStyle->getNumberFormat()->getBuiltInFormatCode() === false) {
+ $objWriter->writeAttribute('numFmtId', (int)($this->getParentWriter()->getNumFmtHashTable()->getIndexForHashCode($pStyle->getNumberFormat()->getHashCode()) + 164));
+ } else {
+ $objWriter->writeAttribute('numFmtId', (int)$pStyle->getNumberFormat()->getBuiltInFormatCode());
+ }
+
+ $objWriter->writeAttribute('fillId', (int)$this->getParentWriter()->getFillHashTable()->getIndexForHashCode($pStyle->getFill()->getHashCode()));
+ $objWriter->writeAttribute('borderId', (int)$this->getParentWriter()->getBordersHashTable()->getIndexForHashCode($pStyle->getBorders()->getHashCode()));
+
+ // Apply styles?
+ $objWriter->writeAttribute('applyFont', ($pPHPExcel->getDefaultStyle()->getFont()->getHashCode() != $pStyle->getFont()->getHashCode()) ? '1' : '0');
+ $objWriter->writeAttribute('applyNumberFormat', ($pPHPExcel->getDefaultStyle()->getNumberFormat()->getHashCode() != $pStyle->getNumberFormat()->getHashCode()) ? '1' : '0');
+ $objWriter->writeAttribute('applyFill', ($pPHPExcel->getDefaultStyle()->getFill()->getHashCode() != $pStyle->getFill()->getHashCode()) ? '1' : '0');
+ $objWriter->writeAttribute('applyBorder', ($pPHPExcel->getDefaultStyle()->getBorders()->getHashCode() != $pStyle->getBorders()->getHashCode()) ? '1' : '0');
+ $objWriter->writeAttribute('applyAlignment', ($pPHPExcel->getDefaultStyle()->getAlignment()->getHashCode() != $pStyle->getAlignment()->getHashCode()) ? '1' : '0');
+ if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) {
+ $objWriter->writeAttribute('applyProtection', 'true');
+ }
+
+ // alignment
+ $objWriter->startElement('alignment');
+ $objWriter->writeAttribute('horizontal', $pStyle->getAlignment()->getHorizontal());
+ $objWriter->writeAttribute('vertical', $pStyle->getAlignment()->getVertical());
+
+ $textRotation = 0;
+ if ($pStyle->getAlignment()->getTextRotation() >= 0) {
+ $textRotation = $pStyle->getAlignment()->getTextRotation();
+ } elseif ($pStyle->getAlignment()->getTextRotation() < 0) {
+ $textRotation = 90 - $pStyle->getAlignment()->getTextRotation();
+ }
+ $objWriter->writeAttribute('textRotation', $textRotation);
+
+ $objWriter->writeAttribute('wrapText', ($pStyle->getAlignment()->getWrapText() ? 'true' : 'false'));
+ $objWriter->writeAttribute('shrinkToFit', ($pStyle->getAlignment()->getShrinkToFit() ? 'true' : 'false'));
+
+ if ($pStyle->getAlignment()->getIndent() > 0) {
+ $objWriter->writeAttribute('indent', $pStyle->getAlignment()->getIndent());
+ }
+ if ($pStyle->getAlignment()->getReadorder() > 0) {
+ $objWriter->writeAttribute('readingOrder', $pStyle->getAlignment()->getReadorder());
+ }
+ $objWriter->endElement();
+
+ // protection
+ if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) {
+ $objWriter->startElement('protection');
+ if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT) {
+ $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false'));
+ }
+ if ($pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) {
+ $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false'));
+ }
+ $objWriter->endElement();
+ }
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write Cell Style Dxf
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Style $pStyle Style
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeCellStyleDxf(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style $pStyle = null)
+ {
+ // dxf
+ $objWriter->startElement('dxf');
+
+ // font
+ $this->writeFont($objWriter, $pStyle->getFont());
+
+ // numFmt
+ $this->writeNumFmt($objWriter, $pStyle->getNumberFormat());
+
+ // fill
+ $this->writeFill($objWriter, $pStyle->getFill());
+
+ // alignment
+ $objWriter->startElement('alignment');
+ if ($pStyle->getAlignment()->getHorizontal() !== null) {
+ $objWriter->writeAttribute('horizontal', $pStyle->getAlignment()->getHorizontal());
+ }
+ if ($pStyle->getAlignment()->getVertical() !== null) {
+ $objWriter->writeAttribute('vertical', $pStyle->getAlignment()->getVertical());
+ }
+
+ if ($pStyle->getAlignment()->getTextRotation() !== null) {
+ $textRotation = 0;
+ if ($pStyle->getAlignment()->getTextRotation() >= 0) {
+ $textRotation = $pStyle->getAlignment()->getTextRotation();
+ } elseif ($pStyle->getAlignment()->getTextRotation() < 0) {
+ $textRotation = 90 - $pStyle->getAlignment()->getTextRotation();
+ }
+ $objWriter->writeAttribute('textRotation', $textRotation);
+ }
+ $objWriter->endElement();
+
+ // border
+ $this->writeBorder($objWriter, $pStyle->getBorders());
+
+ // protection
+ if (($pStyle->getProtection()->getLocked() !== null) || ($pStyle->getProtection()->getHidden() !== null)) {
+ if ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT ||
+ $pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT) {
+ $objWriter->startElement('protection');
+ if (($pStyle->getProtection()->getLocked() !== null) &&
+ ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) {
+ $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false'));
+ }
+ if (($pStyle->getProtection()->getHidden() !== null) &&
+ ($pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) {
+ $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false'));
+ }
+ $objWriter->endElement();
+ }
+ }
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write BorderPr
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param string $pName Element name
+ * @param PHPExcel_Style_Border $pBorder Border style
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeBorderPr(PHPExcel_Shared_XMLWriter $objWriter = null, $pName = 'left', PHPExcel_Style_Border $pBorder = null)
+ {
+ // Write BorderPr
+ if ($pBorder->getBorderStyle() != PHPExcel_Style_Border::BORDER_NONE) {
+ $objWriter->startElement($pName);
+ $objWriter->writeAttribute('style', $pBorder->getBorderStyle());
+
+ // color
+ $objWriter->startElement('color');
+ $objWriter->writeAttribute('rgb', $pBorder->getColor()->getARGB());
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+ }
+
+ /**
+ * Write NumberFormat
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Style_NumberFormat $pNumberFormat Number Format
+ * @param int $pId Number Format identifier
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeNumFmt(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_NumberFormat $pNumberFormat = null, $pId = 0)
+ {
+ // Translate formatcode
+ $formatCode = $pNumberFormat->getFormatCode();
+
+ // numFmt
+ if ($formatCode !== null) {
+ $objWriter->startElement('numFmt');
+ $objWriter->writeAttribute('numFmtId', ($pId + 164));
+ $objWriter->writeAttribute('formatCode', $formatCode);
+ $objWriter->endElement();
+ }
+ }
+
+ /**
+ * Get an array of all styles
+ *
+ * @param PHPExcel $pPHPExcel
+ * @return PHPExcel_Style[] All styles in PHPExcel
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function allStyles(PHPExcel $pPHPExcel = null)
+ {
+ return $pPHPExcel->getCellXfCollection();
+ }
+
+ /**
+ * Get an array of all conditional styles
+ *
+ * @param PHPExcel $pPHPExcel
+ * @return PHPExcel_Style_Conditional[] All conditional styles in PHPExcel
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function allConditionalStyles(PHPExcel $pPHPExcel = null)
+ {
+ // Get an array of all styles
+ $aStyles = array();
+
+ $sheetCount = $pPHPExcel->getSheetCount();
+ for ($i = 0; $i < $sheetCount; ++$i) {
+ foreach ($pPHPExcel->getSheet($i)->getConditionalStylesCollection() as $conditionalStyles) {
+ foreach ($conditionalStyles as $conditionalStyle) {
+ $aStyles[] = $conditionalStyle;
+ }
+ }
+ }
+
+ return $aStyles;
+ }
+
+ /**
+ * Get an array of all fills
+ *
+ * @param PHPExcel $pPHPExcel
+ * @return PHPExcel_Style_Fill[] All fills in PHPExcel
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function allFills(PHPExcel $pPHPExcel = null)
+ {
+ // Get an array of unique fills
+ $aFills = array();
+
+ // Two first fills are predefined
+ $fill0 = new PHPExcel_Style_Fill();
+ $fill0->setFillType(PHPExcel_Style_Fill::FILL_NONE);
+ $aFills[] = $fill0;
+
+ $fill1 = new PHPExcel_Style_Fill();
+ $fill1->setFillType(PHPExcel_Style_Fill::FILL_PATTERN_GRAY125);
+ $aFills[] = $fill1;
+ // The remaining fills
+ $aStyles = $this->allStyles($pPHPExcel);
+ foreach ($aStyles as $style) {
+ if (!array_key_exists($style->getFill()->getHashCode(), $aFills)) {
+ $aFills[ $style->getFill()->getHashCode() ] = $style->getFill();
+ }
+ }
+
+ return $aFills;
+ }
+
+ /**
+ * Get an array of all fonts
+ *
+ * @param PHPExcel $pPHPExcel
+ * @return PHPExcel_Style_Font[] All fonts in PHPExcel
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function allFonts(PHPExcel $pPHPExcel = null)
+ {
+ // Get an array of unique fonts
+ $aFonts = array();
+ $aStyles = $this->allStyles($pPHPExcel);
+
+ foreach ($aStyles as $style) {
+ if (!array_key_exists($style->getFont()->getHashCode(), $aFonts)) {
+ $aFonts[ $style->getFont()->getHashCode() ] = $style->getFont();
+ }
+ }
+
+ return $aFonts;
+ }
+
+ /**
+ * Get an array of all borders
+ *
+ * @param PHPExcel $pPHPExcel
+ * @return PHPExcel_Style_Borders[] All borders in PHPExcel
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function allBorders(PHPExcel $pPHPExcel = null)
+ {
+ // Get an array of unique borders
+ $aBorders = array();
+ $aStyles = $this->allStyles($pPHPExcel);
+
+ foreach ($aStyles as $style) {
+ if (!array_key_exists($style->getBorders()->getHashCode(), $aBorders)) {
+ $aBorders[ $style->getBorders()->getHashCode() ] = $style->getBorders();
+ }
+ }
+
+ return $aBorders;
+ }
+
+ /**
+ * Get an array of all number formats
+ *
+ * @param PHPExcel $pPHPExcel
+ * @return PHPExcel_Style_NumberFormat[] All number formats in PHPExcel
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function allNumberFormats(PHPExcel $pPHPExcel = null)
+ {
+ // Get an array of unique number formats
+ $aNumFmts = array();
+ $aStyles = $this->allStyles($pPHPExcel);
+
+ foreach ($aStyles as $style) {
+ if ($style->getNumberFormat()->getBuiltInFormatCode() === false && !array_key_exists($style->getNumberFormat()->getHashCode(), $aNumFmts)) {
+ $aNumFmts[ $style->getNumberFormat()->getHashCode() ] = $style->getNumberFormat();
+ }
+ }
+
+ return $aNumFmts;
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Theme.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Theme.php
new file mode 100755
index 000000000..223e40241
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Theme.php
@@ -0,0 +1,869 @@
+ 'MS Pゴシック',
+ 'Hang' => '맑은 고딕',
+ 'Hans' => '宋体',
+ 'Hant' => '新細明體',
+ 'Arab' => 'Times New Roman',
+ 'Hebr' => 'Times New Roman',
+ 'Thai' => 'Tahoma',
+ 'Ethi' => 'Nyala',
+ 'Beng' => 'Vrinda',
+ 'Gujr' => 'Shruti',
+ 'Khmr' => 'MoolBoran',
+ 'Knda' => 'Tunga',
+ 'Guru' => 'Raavi',
+ 'Cans' => 'Euphemia',
+ 'Cher' => 'Plantagenet Cherokee',
+ 'Yiii' => 'Microsoft Yi Baiti',
+ 'Tibt' => 'Microsoft Himalaya',
+ 'Thaa' => 'MV Boli',
+ 'Deva' => 'Mangal',
+ 'Telu' => 'Gautami',
+ 'Taml' => 'Latha',
+ 'Syrc' => 'Estrangelo Edessa',
+ 'Orya' => 'Kalinga',
+ 'Mlym' => 'Kartika',
+ 'Laoo' => 'DokChampa',
+ 'Sinh' => 'Iskoola Pota',
+ 'Mong' => 'Mongolian Baiti',
+ 'Viet' => 'Times New Roman',
+ 'Uigh' => 'Microsoft Uighur',
+ 'Geor' => 'Sylfaen',
+ );
+
+ /**
+ * Map of Minor fonts to write
+ * @static array of string
+ *
+ */
+ private static $minorFonts = array(
+ 'Jpan' => 'MS Pゴシック',
+ 'Hang' => '맑은 고딕',
+ 'Hans' => '宋体',
+ 'Hant' => '新細明體',
+ 'Arab' => 'Arial',
+ 'Hebr' => 'Arial',
+ 'Thai' => 'Tahoma',
+ 'Ethi' => 'Nyala',
+ 'Beng' => 'Vrinda',
+ 'Gujr' => 'Shruti',
+ 'Khmr' => 'DaunPenh',
+ 'Knda' => 'Tunga',
+ 'Guru' => 'Raavi',
+ 'Cans' => 'Euphemia',
+ 'Cher' => 'Plantagenet Cherokee',
+ 'Yiii' => 'Microsoft Yi Baiti',
+ 'Tibt' => 'Microsoft Himalaya',
+ 'Thaa' => 'MV Boli',
+ 'Deva' => 'Mangal',
+ 'Telu' => 'Gautami',
+ 'Taml' => 'Latha',
+ 'Syrc' => 'Estrangelo Edessa',
+ 'Orya' => 'Kalinga',
+ 'Mlym' => 'Kartika',
+ 'Laoo' => 'DokChampa',
+ 'Sinh' => 'Iskoola Pota',
+ 'Mong' => 'Mongolian Baiti',
+ 'Viet' => 'Arial',
+ 'Uigh' => 'Microsoft Uighur',
+ 'Geor' => 'Sylfaen',
+ );
+
+ /**
+ * Map of core colours
+ * @static array of string
+ *
+ */
+ private static $colourScheme = array(
+ 'dk2' => '1F497D',
+ 'lt2' => 'EEECE1',
+ 'accent1' => '4F81BD',
+ 'accent2' => 'C0504D',
+ 'accent3' => '9BBB59',
+ 'accent4' => '8064A2',
+ 'accent5' => '4BACC6',
+ 'accent6' => 'F79646',
+ 'hlink' => '0000FF',
+ 'folHlink' => '800080',
+ );
+
+ /**
+ * Write theme to XML format
+ *
+ * @param PHPExcel $pPHPExcel
+ * @return string XML Output
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function writeTheme(PHPExcel $pPHPExcel = null)
+ {
+ // Create XML writer
+ $objWriter = null;
+ if ($this->getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // a:theme
+ $objWriter->startElement('a:theme');
+ $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');
+ $objWriter->writeAttribute('name', 'Office Theme');
+
+ // a:themeElements
+ $objWriter->startElement('a:themeElements');
+
+ // a:clrScheme
+ $objWriter->startElement('a:clrScheme');
+ $objWriter->writeAttribute('name', 'Office');
+
+ // a:dk1
+ $objWriter->startElement('a:dk1');
+
+ // a:sysClr
+ $objWriter->startElement('a:sysClr');
+ $objWriter->writeAttribute('val', 'windowText');
+ $objWriter->writeAttribute('lastClr', '000000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:lt1
+ $objWriter->startElement('a:lt1');
+
+ // a:sysClr
+ $objWriter->startElement('a:sysClr');
+ $objWriter->writeAttribute('val', 'window');
+ $objWriter->writeAttribute('lastClr', 'FFFFFF');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:dk2
+ $this->writeColourScheme($objWriter);
+
+ $objWriter->endElement();
+
+ // a:fontScheme
+ $objWriter->startElement('a:fontScheme');
+ $objWriter->writeAttribute('name', 'Office');
+
+ // a:majorFont
+ $objWriter->startElement('a:majorFont');
+ $this->writeFonts($objWriter, 'Cambria', self::$majorFonts);
+ $objWriter->endElement();
+
+ // a:minorFont
+ $objWriter->startElement('a:minorFont');
+ $this->writeFonts($objWriter, 'Calibri', self::$minorFonts);
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:fmtScheme
+ $objWriter->startElement('a:fmtScheme');
+ $objWriter->writeAttribute('name', 'Office');
+
+ // a:fillStyleLst
+ $objWriter->startElement('a:fillStyleLst');
+
+ // a:solidFill
+ $objWriter->startElement('a:solidFill');
+
+ // a:schemeClr
+ $objWriter->startElement('a:schemeClr');
+ $objWriter->writeAttribute('val', 'phClr');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:gradFill
+ $objWriter->startElement('a:gradFill');
+ $objWriter->writeAttribute('rotWithShape', '1');
+
+ // a:gsLst
+ $objWriter->startElement('a:gsLst');
+
+ // a:gs
+ $objWriter->startElement('a:gs');
+ $objWriter->writeAttribute('pos', '0');
+
+ // a:schemeClr
+ $objWriter->startElement('a:schemeClr');
+ $objWriter->writeAttribute('val', 'phClr');
+
+ // a:tint
+ $objWriter->startElement('a:tint');
+ $objWriter->writeAttribute('val', '50000');
+ $objWriter->endElement();
+
+ // a:satMod
+ $objWriter->startElement('a:satMod');
+ $objWriter->writeAttribute('val', '300000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:gs
+ $objWriter->startElement('a:gs');
+ $objWriter->writeAttribute('pos', '35000');
+
+ // a:schemeClr
+ $objWriter->startElement('a:schemeClr');
+ $objWriter->writeAttribute('val', 'phClr');
+
+ // a:tint
+ $objWriter->startElement('a:tint');
+ $objWriter->writeAttribute('val', '37000');
+ $objWriter->endElement();
+
+ // a:satMod
+ $objWriter->startElement('a:satMod');
+ $objWriter->writeAttribute('val', '300000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:gs
+ $objWriter->startElement('a:gs');
+ $objWriter->writeAttribute('pos', '100000');
+
+ // a:schemeClr
+ $objWriter->startElement('a:schemeClr');
+ $objWriter->writeAttribute('val', 'phClr');
+
+ // a:tint
+ $objWriter->startElement('a:tint');
+ $objWriter->writeAttribute('val', '15000');
+ $objWriter->endElement();
+
+ // a:satMod
+ $objWriter->startElement('a:satMod');
+ $objWriter->writeAttribute('val', '350000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:lin
+ $objWriter->startElement('a:lin');
+ $objWriter->writeAttribute('ang', '16200000');
+ $objWriter->writeAttribute('scaled', '1');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:gradFill
+ $objWriter->startElement('a:gradFill');
+ $objWriter->writeAttribute('rotWithShape', '1');
+
+ // a:gsLst
+ $objWriter->startElement('a:gsLst');
+
+ // a:gs
+ $objWriter->startElement('a:gs');
+ $objWriter->writeAttribute('pos', '0');
+
+ // a:schemeClr
+ $objWriter->startElement('a:schemeClr');
+ $objWriter->writeAttribute('val', 'phClr');
+
+ // a:shade
+ $objWriter->startElement('a:shade');
+ $objWriter->writeAttribute('val', '51000');
+ $objWriter->endElement();
+
+ // a:satMod
+ $objWriter->startElement('a:satMod');
+ $objWriter->writeAttribute('val', '130000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:gs
+ $objWriter->startElement('a:gs');
+ $objWriter->writeAttribute('pos', '80000');
+
+ // a:schemeClr
+ $objWriter->startElement('a:schemeClr');
+ $objWriter->writeAttribute('val', 'phClr');
+
+ // a:shade
+ $objWriter->startElement('a:shade');
+ $objWriter->writeAttribute('val', '93000');
+ $objWriter->endElement();
+
+ // a:satMod
+ $objWriter->startElement('a:satMod');
+ $objWriter->writeAttribute('val', '130000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:gs
+ $objWriter->startElement('a:gs');
+ $objWriter->writeAttribute('pos', '100000');
+
+ // a:schemeClr
+ $objWriter->startElement('a:schemeClr');
+ $objWriter->writeAttribute('val', 'phClr');
+
+ // a:shade
+ $objWriter->startElement('a:shade');
+ $objWriter->writeAttribute('val', '94000');
+ $objWriter->endElement();
+
+ // a:satMod
+ $objWriter->startElement('a:satMod');
+ $objWriter->writeAttribute('val', '135000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:lin
+ $objWriter->startElement('a:lin');
+ $objWriter->writeAttribute('ang', '16200000');
+ $objWriter->writeAttribute('scaled', '0');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:lnStyleLst
+ $objWriter->startElement('a:lnStyleLst');
+
+ // a:ln
+ $objWriter->startElement('a:ln');
+ $objWriter->writeAttribute('w', '9525');
+ $objWriter->writeAttribute('cap', 'flat');
+ $objWriter->writeAttribute('cmpd', 'sng');
+ $objWriter->writeAttribute('algn', 'ctr');
+
+ // a:solidFill
+ $objWriter->startElement('a:solidFill');
+
+ // a:schemeClr
+ $objWriter->startElement('a:schemeClr');
+ $objWriter->writeAttribute('val', 'phClr');
+
+ // a:shade
+ $objWriter->startElement('a:shade');
+ $objWriter->writeAttribute('val', '95000');
+ $objWriter->endElement();
+
+ // a:satMod
+ $objWriter->startElement('a:satMod');
+ $objWriter->writeAttribute('val', '105000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:prstDash
+ $objWriter->startElement('a:prstDash');
+ $objWriter->writeAttribute('val', 'solid');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:ln
+ $objWriter->startElement('a:ln');
+ $objWriter->writeAttribute('w', '25400');
+ $objWriter->writeAttribute('cap', 'flat');
+ $objWriter->writeAttribute('cmpd', 'sng');
+ $objWriter->writeAttribute('algn', 'ctr');
+
+ // a:solidFill
+ $objWriter->startElement('a:solidFill');
+
+ // a:schemeClr
+ $objWriter->startElement('a:schemeClr');
+ $objWriter->writeAttribute('val', 'phClr');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:prstDash
+ $objWriter->startElement('a:prstDash');
+ $objWriter->writeAttribute('val', 'solid');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:ln
+ $objWriter->startElement('a:ln');
+ $objWriter->writeAttribute('w', '38100');
+ $objWriter->writeAttribute('cap', 'flat');
+ $objWriter->writeAttribute('cmpd', 'sng');
+ $objWriter->writeAttribute('algn', 'ctr');
+
+ // a:solidFill
+ $objWriter->startElement('a:solidFill');
+
+ // a:schemeClr
+ $objWriter->startElement('a:schemeClr');
+ $objWriter->writeAttribute('val', 'phClr');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:prstDash
+ $objWriter->startElement('a:prstDash');
+ $objWriter->writeAttribute('val', 'solid');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+
+
+ // a:effectStyleLst
+ $objWriter->startElement('a:effectStyleLst');
+
+ // a:effectStyle
+ $objWriter->startElement('a:effectStyle');
+
+ // a:effectLst
+ $objWriter->startElement('a:effectLst');
+
+ // a:outerShdw
+ $objWriter->startElement('a:outerShdw');
+ $objWriter->writeAttribute('blurRad', '40000');
+ $objWriter->writeAttribute('dist', '20000');
+ $objWriter->writeAttribute('dir', '5400000');
+ $objWriter->writeAttribute('rotWithShape', '0');
+
+ // a:srgbClr
+ $objWriter->startElement('a:srgbClr');
+ $objWriter->writeAttribute('val', '000000');
+
+ // a:alpha
+ $objWriter->startElement('a:alpha');
+ $objWriter->writeAttribute('val', '38000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:effectStyle
+ $objWriter->startElement('a:effectStyle');
+
+ // a:effectLst
+ $objWriter->startElement('a:effectLst');
+
+ // a:outerShdw
+ $objWriter->startElement('a:outerShdw');
+ $objWriter->writeAttribute('blurRad', '40000');
+ $objWriter->writeAttribute('dist', '23000');
+ $objWriter->writeAttribute('dir', '5400000');
+ $objWriter->writeAttribute('rotWithShape', '0');
+
+ // a:srgbClr
+ $objWriter->startElement('a:srgbClr');
+ $objWriter->writeAttribute('val', '000000');
+
+ // a:alpha
+ $objWriter->startElement('a:alpha');
+ $objWriter->writeAttribute('val', '35000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:effectStyle
+ $objWriter->startElement('a:effectStyle');
+
+ // a:effectLst
+ $objWriter->startElement('a:effectLst');
+
+ // a:outerShdw
+ $objWriter->startElement('a:outerShdw');
+ $objWriter->writeAttribute('blurRad', '40000');
+ $objWriter->writeAttribute('dist', '23000');
+ $objWriter->writeAttribute('dir', '5400000');
+ $objWriter->writeAttribute('rotWithShape', '0');
+
+ // a:srgbClr
+ $objWriter->startElement('a:srgbClr');
+ $objWriter->writeAttribute('val', '000000');
+
+ // a:alpha
+ $objWriter->startElement('a:alpha');
+ $objWriter->writeAttribute('val', '35000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:scene3d
+ $objWriter->startElement('a:scene3d');
+
+ // a:camera
+ $objWriter->startElement('a:camera');
+ $objWriter->writeAttribute('prst', 'orthographicFront');
+
+ // a:rot
+ $objWriter->startElement('a:rot');
+ $objWriter->writeAttribute('lat', '0');
+ $objWriter->writeAttribute('lon', '0');
+ $objWriter->writeAttribute('rev', '0');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:lightRig
+ $objWriter->startElement('a:lightRig');
+ $objWriter->writeAttribute('rig', 'threePt');
+ $objWriter->writeAttribute('dir', 't');
+
+ // a:rot
+ $objWriter->startElement('a:rot');
+ $objWriter->writeAttribute('lat', '0');
+ $objWriter->writeAttribute('lon', '0');
+ $objWriter->writeAttribute('rev', '1200000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:sp3d
+ $objWriter->startElement('a:sp3d');
+
+ // a:bevelT
+ $objWriter->startElement('a:bevelT');
+ $objWriter->writeAttribute('w', '63500');
+ $objWriter->writeAttribute('h', '25400');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:bgFillStyleLst
+ $objWriter->startElement('a:bgFillStyleLst');
+
+ // a:solidFill
+ $objWriter->startElement('a:solidFill');
+
+ // a:schemeClr
+ $objWriter->startElement('a:schemeClr');
+ $objWriter->writeAttribute('val', 'phClr');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:gradFill
+ $objWriter->startElement('a:gradFill');
+ $objWriter->writeAttribute('rotWithShape', '1');
+
+ // a:gsLst
+ $objWriter->startElement('a:gsLst');
+
+ // a:gs
+ $objWriter->startElement('a:gs');
+ $objWriter->writeAttribute('pos', '0');
+
+ // a:schemeClr
+ $objWriter->startElement('a:schemeClr');
+ $objWriter->writeAttribute('val', 'phClr');
+
+ // a:tint
+ $objWriter->startElement('a:tint');
+ $objWriter->writeAttribute('val', '40000');
+ $objWriter->endElement();
+
+ // a:satMod
+ $objWriter->startElement('a:satMod');
+ $objWriter->writeAttribute('val', '350000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:gs
+ $objWriter->startElement('a:gs');
+ $objWriter->writeAttribute('pos', '40000');
+
+ // a:schemeClr
+ $objWriter->startElement('a:schemeClr');
+ $objWriter->writeAttribute('val', 'phClr');
+
+ // a:tint
+ $objWriter->startElement('a:tint');
+ $objWriter->writeAttribute('val', '45000');
+ $objWriter->endElement();
+
+ // a:shade
+ $objWriter->startElement('a:shade');
+ $objWriter->writeAttribute('val', '99000');
+ $objWriter->endElement();
+
+ // a:satMod
+ $objWriter->startElement('a:satMod');
+ $objWriter->writeAttribute('val', '350000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:gs
+ $objWriter->startElement('a:gs');
+ $objWriter->writeAttribute('pos', '100000');
+
+ // a:schemeClr
+ $objWriter->startElement('a:schemeClr');
+ $objWriter->writeAttribute('val', 'phClr');
+
+ // a:shade
+ $objWriter->startElement('a:shade');
+ $objWriter->writeAttribute('val', '20000');
+ $objWriter->endElement();
+
+ // a:satMod
+ $objWriter->startElement('a:satMod');
+ $objWriter->writeAttribute('val', '255000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:path
+ $objWriter->startElement('a:path');
+ $objWriter->writeAttribute('path', 'circle');
+
+ // a:fillToRect
+ $objWriter->startElement('a:fillToRect');
+ $objWriter->writeAttribute('l', '50000');
+ $objWriter->writeAttribute('t', '-80000');
+ $objWriter->writeAttribute('r', '50000');
+ $objWriter->writeAttribute('b', '180000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:gradFill
+ $objWriter->startElement('a:gradFill');
+ $objWriter->writeAttribute('rotWithShape', '1');
+
+ // a:gsLst
+ $objWriter->startElement('a:gsLst');
+
+ // a:gs
+ $objWriter->startElement('a:gs');
+ $objWriter->writeAttribute('pos', '0');
+
+ // a:schemeClr
+ $objWriter->startElement('a:schemeClr');
+ $objWriter->writeAttribute('val', 'phClr');
+
+ // a:tint
+ $objWriter->startElement('a:tint');
+ $objWriter->writeAttribute('val', '80000');
+ $objWriter->endElement();
+
+ // a:satMod
+ $objWriter->startElement('a:satMod');
+ $objWriter->writeAttribute('val', '300000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:gs
+ $objWriter->startElement('a:gs');
+ $objWriter->writeAttribute('pos', '100000');
+
+ // a:schemeClr
+ $objWriter->startElement('a:schemeClr');
+ $objWriter->writeAttribute('val', 'phClr');
+
+ // a:shade
+ $objWriter->startElement('a:shade');
+ $objWriter->writeAttribute('val', '30000');
+ $objWriter->endElement();
+
+ // a:satMod
+ $objWriter->startElement('a:satMod');
+ $objWriter->writeAttribute('val', '200000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:path
+ $objWriter->startElement('a:path');
+ $objWriter->writeAttribute('path', 'circle');
+
+ // a:fillToRect
+ $objWriter->startElement('a:fillToRect');
+ $objWriter->writeAttribute('l', '50000');
+ $objWriter->writeAttribute('t', '50000');
+ $objWriter->writeAttribute('r', '50000');
+ $objWriter->writeAttribute('b', '50000');
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+
+ // a:objectDefaults
+ $objWriter->writeElement('a:objectDefaults', null);
+
+ // a:extraClrSchemeLst
+ $objWriter->writeElement('a:extraClrSchemeLst', null);
+
+ $objWriter->endElement();
+
+ // Return
+ return $objWriter->getData();
+ }
+
+ /**
+ * Write fonts to XML format
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter
+ * @param string $latinFont
+ * @param array of string $fontSet
+ * @return string XML Output
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeFonts($objWriter, $latinFont, $fontSet)
+ {
+ // a:latin
+ $objWriter->startElement('a:latin');
+ $objWriter->writeAttribute('typeface', $latinFont);
+ $objWriter->endElement();
+
+ // a:ea
+ $objWriter->startElement('a:ea');
+ $objWriter->writeAttribute('typeface', '');
+ $objWriter->endElement();
+
+ // a:cs
+ $objWriter->startElement('a:cs');
+ $objWriter->writeAttribute('typeface', '');
+ $objWriter->endElement();
+
+ foreach ($fontSet as $fontScript => $typeface) {
+ $objWriter->startElement('a:font');
+ $objWriter->writeAttribute('script', $fontScript);
+ $objWriter->writeAttribute('typeface', $typeface);
+ $objWriter->endElement();
+ }
+ }
+
+ /**
+ * Write colour scheme to XML format
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter
+ * @return string XML Output
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeColourScheme($objWriter)
+ {
+ foreach (self::$colourScheme as $colourName => $colourValue) {
+ $objWriter->startElement('a:'.$colourName);
+
+ $objWriter->startElement('a:srgbClr');
+ $objWriter->writeAttribute('val', $colourValue);
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Workbook.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Workbook.php
new file mode 100755
index 000000000..87c877ea9
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Workbook.php
@@ -0,0 +1,448 @@
+getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // workbook
+ $objWriter->startElement('workbook');
+ $objWriter->writeAttribute('xml:space', 'preserve');
+ $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
+ $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
+
+ // fileVersion
+ $this->writeFileVersion($objWriter);
+
+ // workbookPr
+ $this->writeWorkbookPr($objWriter);
+
+ // workbookProtection
+ $this->writeWorkbookProtection($objWriter, $pPHPExcel);
+
+ // bookViews
+ if ($this->getParentWriter()->getOffice2003Compatibility() === false) {
+ $this->writeBookViews($objWriter, $pPHPExcel);
+ }
+
+ // sheets
+ $this->writeSheets($objWriter, $pPHPExcel);
+
+ // definedNames
+ $this->writeDefinedNames($objWriter, $pPHPExcel);
+
+ // calcPr
+ $this->writeCalcPr($objWriter, $recalcRequired);
+
+ $objWriter->endElement();
+
+ // Return
+ return $objWriter->getData();
+ }
+
+ /**
+ * Write file version
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeFileVersion(PHPExcel_Shared_XMLWriter $objWriter = null)
+ {
+ $objWriter->startElement('fileVersion');
+ $objWriter->writeAttribute('appName', 'xl');
+ $objWriter->writeAttribute('lastEdited', '4');
+ $objWriter->writeAttribute('lowestEdited', '4');
+ $objWriter->writeAttribute('rupBuild', '4505');
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write WorkbookPr
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeWorkbookPr(PHPExcel_Shared_XMLWriter $objWriter = null)
+ {
+ $objWriter->startElement('workbookPr');
+
+ if (PHPExcel_Shared_Date::getExcelCalendar() == PHPExcel_Shared_Date::CALENDAR_MAC_1904) {
+ $objWriter->writeAttribute('date1904', '1');
+ }
+
+ $objWriter->writeAttribute('codeName', 'ThisWorkbook');
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write BookViews
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel $pPHPExcel
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeBookViews(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null)
+ {
+ // bookViews
+ $objWriter->startElement('bookViews');
+
+ // workbookView
+ $objWriter->startElement('workbookView');
+
+ $objWriter->writeAttribute('activeTab', $pPHPExcel->getActiveSheetIndex());
+ $objWriter->writeAttribute('autoFilterDateGrouping', '1');
+ $objWriter->writeAttribute('firstSheet', '0');
+ $objWriter->writeAttribute('minimized', '0');
+ $objWriter->writeAttribute('showHorizontalScroll', '1');
+ $objWriter->writeAttribute('showSheetTabs', '1');
+ $objWriter->writeAttribute('showVerticalScroll', '1');
+ $objWriter->writeAttribute('tabRatio', '600');
+ $objWriter->writeAttribute('visibility', 'visible');
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write WorkbookProtection
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel $pPHPExcel
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeWorkbookProtection(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null)
+ {
+ if ($pPHPExcel->getSecurity()->isSecurityEnabled()) {
+ $objWriter->startElement('workbookProtection');
+ $objWriter->writeAttribute('lockRevision', ($pPHPExcel->getSecurity()->getLockRevision() ? 'true' : 'false'));
+ $objWriter->writeAttribute('lockStructure', ($pPHPExcel->getSecurity()->getLockStructure() ? 'true' : 'false'));
+ $objWriter->writeAttribute('lockWindows', ($pPHPExcel->getSecurity()->getLockWindows() ? 'true' : 'false'));
+
+ if ($pPHPExcel->getSecurity()->getRevisionsPassword() != '') {
+ $objWriter->writeAttribute('revisionsPassword', $pPHPExcel->getSecurity()->getRevisionsPassword());
+ }
+
+ if ($pPHPExcel->getSecurity()->getWorkbookPassword() != '') {
+ $objWriter->writeAttribute('workbookPassword', $pPHPExcel->getSecurity()->getWorkbookPassword());
+ }
+
+ $objWriter->endElement();
+ }
+ }
+
+ /**
+ * Write calcPr
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param boolean $recalcRequired Indicate whether formulas should be recalculated before writing
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeCalcPr(PHPExcel_Shared_XMLWriter $objWriter = null, $recalcRequired = true)
+ {
+ $objWriter->startElement('calcPr');
+
+ // Set the calcid to a higher value than Excel itself will use, otherwise Excel will always recalc
+ // If MS Excel does do a recalc, then users opening a file in MS Excel will be prompted to save on exit
+ // because the file has changed
+ $objWriter->writeAttribute('calcId', '999999');
+ $objWriter->writeAttribute('calcMode', 'auto');
+ // fullCalcOnLoad isn't needed if we've recalculating for the save
+ $objWriter->writeAttribute('calcCompleted', ($recalcRequired) ? 1 : 0);
+ $objWriter->writeAttribute('fullCalcOnLoad', ($recalcRequired) ? 0 : 1);
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write sheets
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel $pPHPExcel
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeSheets(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null)
+ {
+ // Write sheets
+ $objWriter->startElement('sheets');
+ $sheetCount = $pPHPExcel->getSheetCount();
+ for ($i = 0; $i < $sheetCount; ++$i) {
+ // sheet
+ $this->writeSheet(
+ $objWriter,
+ $pPHPExcel->getSheet($i)->getTitle(),
+ ($i + 1),
+ ($i + 1 + 3),
+ $pPHPExcel->getSheet($i)->getSheetState()
+ );
+ }
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write sheet
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param string $pSheetname Sheet name
+ * @param int $pSheetId Sheet id
+ * @param int $pRelId Relationship ID
+ * @param string $sheetState Sheet state (visible, hidden, veryHidden)
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeSheet(PHPExcel_Shared_XMLWriter $objWriter = null, $pSheetname = '', $pSheetId = 1, $pRelId = 1, $sheetState = 'visible')
+ {
+ if ($pSheetname != '') {
+ // Write sheet
+ $objWriter->startElement('sheet');
+ $objWriter->writeAttribute('name', $pSheetname);
+ $objWriter->writeAttribute('sheetId', $pSheetId);
+ if ($sheetState != 'visible' && $sheetState != '') {
+ $objWriter->writeAttribute('state', $sheetState);
+ }
+ $objWriter->writeAttribute('r:id', 'rId' . $pRelId);
+ $objWriter->endElement();
+ } else {
+ throw new PHPExcel_Writer_Exception("Invalid parameters passed.");
+ }
+ }
+
+ /**
+ * Write Defined Names
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel $pPHPExcel
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeDefinedNames(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null)
+ {
+ // Write defined names
+ $objWriter->startElement('definedNames');
+
+ // Named ranges
+ if (count($pPHPExcel->getNamedRanges()) > 0) {
+ // Named ranges
+ $this->writeNamedRanges($objWriter, $pPHPExcel);
+ }
+
+ // Other defined names
+ $sheetCount = $pPHPExcel->getSheetCount();
+ for ($i = 0; $i < $sheetCount; ++$i) {
+ // definedName for autoFilter
+ $this->writeDefinedNameForAutofilter($objWriter, $pPHPExcel->getSheet($i), $i);
+
+ // definedName for Print_Titles
+ $this->writeDefinedNameForPrintTitles($objWriter, $pPHPExcel->getSheet($i), $i);
+
+ // definedName for Print_Area
+ $this->writeDefinedNameForPrintArea($objWriter, $pPHPExcel->getSheet($i), $i);
+ }
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write named ranges
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel $pPHPExcel
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeNamedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel)
+ {
+ // Loop named ranges
+ $namedRanges = $pPHPExcel->getNamedRanges();
+ foreach ($namedRanges as $namedRange) {
+ $this->writeDefinedNameForNamedRange($objWriter, $namedRange);
+ }
+ }
+
+ /**
+ * Write Defined Name for named range
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_NamedRange $pNamedRange
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeDefinedNameForNamedRange(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_NamedRange $pNamedRange)
+ {
+ // definedName for named range
+ $objWriter->startElement('definedName');
+ $objWriter->writeAttribute('name', $pNamedRange->getName());
+ if ($pNamedRange->getLocalOnly()) {
+ $objWriter->writeAttribute('localSheetId', $pNamedRange->getScope()->getParent()->getIndex($pNamedRange->getScope()));
+ }
+
+ // Create absolute coordinate and write as raw text
+ $range = PHPExcel_Cell::splitRange($pNamedRange->getRange());
+ for ($i = 0; $i < count($range); $i++) {
+ $range[$i][0] = '\'' . str_replace("'", "''", $pNamedRange->getWorksheet()->getTitle()) . '\'!' . PHPExcel_Cell::absoluteReference($range[$i][0]);
+ if (isset($range[$i][1])) {
+ $range[$i][1] = PHPExcel_Cell::absoluteReference($range[$i][1]);
+ }
+ }
+ $range = PHPExcel_Cell::buildRange($range);
+
+ $objWriter->writeRawData($range);
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write Defined Name for autoFilter
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet
+ * @param int $pSheetId
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeDefinedNameForAutofilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0)
+ {
+ // definedName for autoFilter
+ $autoFilterRange = $pSheet->getAutoFilter()->getRange();
+ if (!empty($autoFilterRange)) {
+ $objWriter->startElement('definedName');
+ $objWriter->writeAttribute('name', '_xlnm._FilterDatabase');
+ $objWriter->writeAttribute('localSheetId', $pSheetId);
+ $objWriter->writeAttribute('hidden', '1');
+
+ // Create absolute coordinate and write as raw text
+ $range = PHPExcel_Cell::splitRange($autoFilterRange);
+ $range = $range[0];
+ // Strip any worksheet ref so we can make the cell ref absolute
+ if (strpos($range[0], '!') !== false) {
+ list($ws, $range[0]) = explode('!', $range[0]);
+ }
+
+ $range[0] = PHPExcel_Cell::absoluteCoordinate($range[0]);
+ $range[1] = PHPExcel_Cell::absoluteCoordinate($range[1]);
+ $range = implode(':', $range);
+
+ $objWriter->writeRawData('\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!' . $range);
+
+ $objWriter->endElement();
+ }
+ }
+
+ /**
+ * Write Defined Name for PrintTitles
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet
+ * @param int $pSheetId
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeDefinedNameForPrintTitles(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0)
+ {
+ // definedName for PrintTitles
+ if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet() || $pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) {
+ $objWriter->startElement('definedName');
+ $objWriter->writeAttribute('name', '_xlnm.Print_Titles');
+ $objWriter->writeAttribute('localSheetId', $pSheetId);
+
+ // Setting string
+ $settingString = '';
+
+ // Columns to repeat
+ if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) {
+ $repeat = $pSheet->getPageSetup()->getColumnsToRepeatAtLeft();
+
+ $settingString .= '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!$' . $repeat[0] . ':$' . $repeat[1];
+ }
+
+ // Rows to repeat
+ if ($pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) {
+ if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) {
+ $settingString .= ',';
+ }
+
+ $repeat = $pSheet->getPageSetup()->getRowsToRepeatAtTop();
+
+ $settingString .= '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!$' . $repeat[0] . ':$' . $repeat[1];
+ }
+
+ $objWriter->writeRawData($settingString);
+
+ $objWriter->endElement();
+ }
+ }
+
+ /**
+ * Write Defined Name for PrintTitles
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet
+ * @param int $pSheetId
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeDefinedNameForPrintArea(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0)
+ {
+ // definedName for PrintArea
+ if ($pSheet->getPageSetup()->isPrintAreaSet()) {
+ $objWriter->startElement('definedName');
+ $objWriter->writeAttribute('name', '_xlnm.Print_Area');
+ $objWriter->writeAttribute('localSheetId', $pSheetId);
+
+ // Setting string
+ $settingString = '';
+
+ // Print area
+ $printArea = PHPExcel_Cell::splitRange($pSheet->getPageSetup()->getPrintArea());
+
+ $chunks = array();
+ foreach ($printArea as $printAreaRect) {
+ $printAreaRect[0] = PHPExcel_Cell::absoluteReference($printAreaRect[0]);
+ $printAreaRect[1] = PHPExcel_Cell::absoluteReference($printAreaRect[1]);
+ $chunks[] = '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!' . implode(':', $printAreaRect);
+ }
+
+ $objWriter->writeRawData(implode(',', $chunks));
+
+ $objWriter->endElement();
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Worksheet.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Worksheet.php
new file mode 100755
index 000000000..c211403e3
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Worksheet.php
@@ -0,0 +1,1219 @@
+getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8', 'yes');
+
+ // Worksheet
+ $objWriter->startElement('worksheet');
+ $objWriter->writeAttribute('xml:space', 'preserve');
+ $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
+ $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
+
+ // sheetPr
+ $this->writeSheetPr($objWriter, $pSheet);
+
+ // Dimension
+ $this->writeDimension($objWriter, $pSheet);
+
+ // sheetViews
+ $this->writeSheetViews($objWriter, $pSheet);
+
+ // sheetFormatPr
+ $this->writeSheetFormatPr($objWriter, $pSheet);
+
+ // cols
+ $this->writeCols($objWriter, $pSheet);
+
+ // sheetData
+ $this->writeSheetData($objWriter, $pSheet, $pStringTable);
+
+ // sheetProtection
+ $this->writeSheetProtection($objWriter, $pSheet);
+
+ // protectedRanges
+ $this->writeProtectedRanges($objWriter, $pSheet);
+
+ // autoFilter
+ $this->writeAutoFilter($objWriter, $pSheet);
+
+ // mergeCells
+ $this->writeMergeCells($objWriter, $pSheet);
+
+ // conditionalFormatting
+ $this->writeConditionalFormatting($objWriter, $pSheet);
+
+ // dataValidations
+ $this->writeDataValidations($objWriter, $pSheet);
+
+ // hyperlinks
+ $this->writeHyperlinks($objWriter, $pSheet);
+
+ // Print options
+ $this->writePrintOptions($objWriter, $pSheet);
+
+ // Page margins
+ $this->writePageMargins($objWriter, $pSheet);
+
+ // Page setup
+ $this->writePageSetup($objWriter, $pSheet);
+
+ // Header / footer
+ $this->writeHeaderFooter($objWriter, $pSheet);
+
+ // Breaks
+ $this->writeBreaks($objWriter, $pSheet);
+
+ // Drawings and/or Charts
+ $this->writeDrawings($objWriter, $pSheet, $includeCharts);
+
+ // LegacyDrawing
+ $this->writeLegacyDrawing($objWriter, $pSheet);
+
+ // LegacyDrawingHF
+ $this->writeLegacyDrawingHF($objWriter, $pSheet);
+
+ $objWriter->endElement();
+
+ // Return
+ return $objWriter->getData();
+ } else {
+ throw new PHPExcel_Writer_Exception("Invalid PHPExcel_Worksheet object passed.");
+ }
+ }
+
+ /**
+ * Write SheetPr
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeSheetPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
+ {
+ // sheetPr
+ $objWriter->startElement('sheetPr');
+ //$objWriter->writeAttribute('codeName', $pSheet->getTitle());
+ if ($pSheet->getParent()->hasMacros()) {//if the workbook have macros, we need to have codeName for the sheet
+ if ($pSheet->hasCodeName()==false) {
+ $pSheet->setCodeName($pSheet->getTitle());
+ }
+ $objWriter->writeAttribute('codeName', $pSheet->getCodeName());
+ }
+ $autoFilterRange = $pSheet->getAutoFilter()->getRange();
+ if (!empty($autoFilterRange)) {
+ $objWriter->writeAttribute('filterMode', 1);
+ $pSheet->getAutoFilter()->showHideRows();
+ }
+
+ // tabColor
+ if ($pSheet->isTabColorSet()) {
+ $objWriter->startElement('tabColor');
+ $objWriter->writeAttribute('rgb', $pSheet->getTabColor()->getARGB());
+ $objWriter->endElement();
+ }
+
+ // outlinePr
+ $objWriter->startElement('outlinePr');
+ $objWriter->writeAttribute('summaryBelow', ($pSheet->getShowSummaryBelow() ? '1' : '0'));
+ $objWriter->writeAttribute('summaryRight', ($pSheet->getShowSummaryRight() ? '1' : '0'));
+ $objWriter->endElement();
+
+ // pageSetUpPr
+ if ($pSheet->getPageSetup()->getFitToPage()) {
+ $objWriter->startElement('pageSetUpPr');
+ $objWriter->writeAttribute('fitToPage', '1');
+ $objWriter->endElement();
+ }
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write Dimension
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeDimension(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
+ {
+ // dimension
+ $objWriter->startElement('dimension');
+ $objWriter->writeAttribute('ref', $pSheet->calculateWorksheetDimension());
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write SheetViews
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
+ {
+ // sheetViews
+ $objWriter->startElement('sheetViews');
+
+ // Sheet selected?
+ $sheetSelected = false;
+ if ($this->getParentWriter()->getPHPExcel()->getIndex($pSheet) == $this->getParentWriter()->getPHPExcel()->getActiveSheetIndex()) {
+ $sheetSelected = true;
+ }
+
+ // sheetView
+ $objWriter->startElement('sheetView');
+ $objWriter->writeAttribute('tabSelected', $sheetSelected ? '1' : '0');
+ $objWriter->writeAttribute('workbookViewId', '0');
+
+ // Zoom scales
+ if ($pSheet->getSheetView()->getZoomScale() != 100) {
+ $objWriter->writeAttribute('zoomScale', $pSheet->getSheetView()->getZoomScale());
+ }
+ if ($pSheet->getSheetView()->getZoomScaleNormal() != 100) {
+ $objWriter->writeAttribute('zoomScaleNormal', $pSheet->getSheetView()->getZoomScaleNormal());
+ }
+
+ // View Layout Type
+ if ($pSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL) {
+ $objWriter->writeAttribute('view', $pSheet->getSheetView()->getView());
+ }
+
+ // Gridlines
+ if ($pSheet->getShowGridlines()) {
+ $objWriter->writeAttribute('showGridLines', 'true');
+ } else {
+ $objWriter->writeAttribute('showGridLines', 'false');
+ }
+
+ // Row and column headers
+ if ($pSheet->getShowRowColHeaders()) {
+ $objWriter->writeAttribute('showRowColHeaders', '1');
+ } else {
+ $objWriter->writeAttribute('showRowColHeaders', '0');
+ }
+
+ // Right-to-left
+ if ($pSheet->getRightToLeft()) {
+ $objWriter->writeAttribute('rightToLeft', 'true');
+ }
+
+ $activeCell = $pSheet->getActiveCell();
+
+ // Pane
+ $pane = '';
+ $topLeftCell = $pSheet->getFreezePane();
+ if (($topLeftCell != '') && ($topLeftCell != 'A1')) {
+ $activeCell = empty($activeCell) ? $topLeftCell : $activeCell;
+ // Calculate freeze coordinates
+ $xSplit = $ySplit = 0;
+
+ list($xSplit, $ySplit) = PHPExcel_Cell::coordinateFromString($topLeftCell);
+ $xSplit = PHPExcel_Cell::columnIndexFromString($xSplit);
+
+ // pane
+ $pane = 'topRight';
+ $objWriter->startElement('pane');
+ if ($xSplit > 1) {
+ $objWriter->writeAttribute('xSplit', $xSplit - 1);
+ }
+ if ($ySplit > 1) {
+ $objWriter->writeAttribute('ySplit', $ySplit - 1);
+ $pane = ($xSplit > 1) ? 'bottomRight' : 'bottomLeft';
+ }
+ $objWriter->writeAttribute('topLeftCell', $topLeftCell);
+ $objWriter->writeAttribute('activePane', $pane);
+ $objWriter->writeAttribute('state', 'frozen');
+ $objWriter->endElement();
+
+ if (($xSplit > 1) && ($ySplit > 1)) {
+ // Write additional selections if more than two panes (ie both an X and a Y split)
+ $objWriter->startElement('selection');
+ $objWriter->writeAttribute('pane', 'topRight');
+ $objWriter->endElement();
+ $objWriter->startElement('selection');
+ $objWriter->writeAttribute('pane', 'bottomLeft');
+ $objWriter->endElement();
+ }
+ }
+
+ // Selection
+// if ($pane != '') {
+ // Only need to write selection element if we have a split pane
+ // We cheat a little by over-riding the active cell selection, setting it to the split cell
+ $objWriter->startElement('selection');
+ if ($pane != '') {
+ $objWriter->writeAttribute('pane', $pane);
+ }
+ $objWriter->writeAttribute('activeCell', $activeCell);
+ $objWriter->writeAttribute('sqref', $activeCell);
+ $objWriter->endElement();
+// }
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write SheetFormatPr
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeSheetFormatPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
+ {
+ // sheetFormatPr
+ $objWriter->startElement('sheetFormatPr');
+
+ // Default row height
+ if ($pSheet->getDefaultRowDimension()->getRowHeight() >= 0) {
+ $objWriter->writeAttribute('customHeight', 'true');
+ $objWriter->writeAttribute('defaultRowHeight', PHPExcel_Shared_String::FormatNumber($pSheet->getDefaultRowDimension()->getRowHeight()));
+ } else {
+ $objWriter->writeAttribute('defaultRowHeight', '14.4');
+ }
+
+ // Set Zero Height row
+ if ((string)$pSheet->getDefaultRowDimension()->getZeroHeight() == '1' ||
+ strtolower((string)$pSheet->getDefaultRowDimension()->getZeroHeight()) == 'true') {
+ $objWriter->writeAttribute('zeroHeight', '1');
+ }
+
+ // Default column width
+ if ($pSheet->getDefaultColumnDimension()->getWidth() >= 0) {
+ $objWriter->writeAttribute('defaultColWidth', PHPExcel_Shared_String::FormatNumber($pSheet->getDefaultColumnDimension()->getWidth()));
+ }
+
+ // Outline level - row
+ $outlineLevelRow = 0;
+ foreach ($pSheet->getRowDimensions() as $dimension) {
+ if ($dimension->getOutlineLevel() > $outlineLevelRow) {
+ $outlineLevelRow = $dimension->getOutlineLevel();
+ }
+ }
+ $objWriter->writeAttribute('outlineLevelRow', (int)$outlineLevelRow);
+
+ // Outline level - column
+ $outlineLevelCol = 0;
+ foreach ($pSheet->getColumnDimensions() as $dimension) {
+ if ($dimension->getOutlineLevel() > $outlineLevelCol) {
+ $outlineLevelCol = $dimension->getOutlineLevel();
+ }
+ }
+ $objWriter->writeAttribute('outlineLevelCol', (int)$outlineLevelCol);
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write Cols
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeCols(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
+ {
+ // cols
+ if (count($pSheet->getColumnDimensions()) > 0) {
+ $objWriter->startElement('cols');
+
+ $pSheet->calculateColumnWidths();
+
+ // Loop through column dimensions
+ foreach ($pSheet->getColumnDimensions() as $colDimension) {
+ // col
+ $objWriter->startElement('col');
+ $objWriter->writeAttribute('min', PHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex()));
+ $objWriter->writeAttribute('max', PHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex()));
+
+ if ($colDimension->getWidth() < 0) {
+ // No width set, apply default of 10
+ $objWriter->writeAttribute('width', '9.10');
+ } else {
+ // Width set
+ $objWriter->writeAttribute('width', PHPExcel_Shared_String::FormatNumber($colDimension->getWidth()));
+ }
+
+ // Column visibility
+ if ($colDimension->getVisible() == false) {
+ $objWriter->writeAttribute('hidden', 'true');
+ }
+
+ // Auto size?
+ if ($colDimension->getAutoSize()) {
+ $objWriter->writeAttribute('bestFit', 'true');
+ }
+
+ // Custom width?
+ if ($colDimension->getWidth() != $pSheet->getDefaultColumnDimension()->getWidth()) {
+ $objWriter->writeAttribute('customWidth', 'true');
+ }
+
+ // Collapsed
+ if ($colDimension->getCollapsed() == true) {
+ $objWriter->writeAttribute('collapsed', 'true');
+ }
+
+ // Outline level
+ if ($colDimension->getOutlineLevel() > 0) {
+ $objWriter->writeAttribute('outlineLevel', $colDimension->getOutlineLevel());
+ }
+
+ // Style
+ $objWriter->writeAttribute('style', $colDimension->getXfIndex());
+
+ $objWriter->endElement();
+ }
+
+ $objWriter->endElement();
+ }
+ }
+
+ /**
+ * Write SheetProtection
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeSheetProtection(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
+ {
+ // sheetProtection
+ $objWriter->startElement('sheetProtection');
+
+ if ($pSheet->getProtection()->getPassword() != '') {
+ $objWriter->writeAttribute('password', $pSheet->getProtection()->getPassword());
+ }
+
+ $objWriter->writeAttribute('sheet', ($pSheet->getProtection()->getSheet() ? 'true' : 'false'));
+ $objWriter->writeAttribute('objects', ($pSheet->getProtection()->getObjects() ? 'true' : 'false'));
+ $objWriter->writeAttribute('scenarios', ($pSheet->getProtection()->getScenarios() ? 'true' : 'false'));
+ $objWriter->writeAttribute('formatCells', ($pSheet->getProtection()->getFormatCells() ? 'true' : 'false'));
+ $objWriter->writeAttribute('formatColumns', ($pSheet->getProtection()->getFormatColumns() ? 'true' : 'false'));
+ $objWriter->writeAttribute('formatRows', ($pSheet->getProtection()->getFormatRows() ? 'true' : 'false'));
+ $objWriter->writeAttribute('insertColumns', ($pSheet->getProtection()->getInsertColumns() ? 'true' : 'false'));
+ $objWriter->writeAttribute('insertRows', ($pSheet->getProtection()->getInsertRows() ? 'true' : 'false'));
+ $objWriter->writeAttribute('insertHyperlinks', ($pSheet->getProtection()->getInsertHyperlinks() ? 'true' : 'false'));
+ $objWriter->writeAttribute('deleteColumns', ($pSheet->getProtection()->getDeleteColumns() ? 'true' : 'false'));
+ $objWriter->writeAttribute('deleteRows', ($pSheet->getProtection()->getDeleteRows() ? 'true' : 'false'));
+ $objWriter->writeAttribute('selectLockedCells', ($pSheet->getProtection()->getSelectLockedCells() ? 'true' : 'false'));
+ $objWriter->writeAttribute('sort', ($pSheet->getProtection()->getSort() ? 'true' : 'false'));
+ $objWriter->writeAttribute('autoFilter', ($pSheet->getProtection()->getAutoFilter() ? 'true' : 'false'));
+ $objWriter->writeAttribute('pivotTables', ($pSheet->getProtection()->getPivotTables() ? 'true' : 'false'));
+ $objWriter->writeAttribute('selectUnlockedCells', ($pSheet->getProtection()->getSelectUnlockedCells() ? 'true' : 'false'));
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write ConditionalFormatting
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeConditionalFormatting(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
+ {
+ // Conditional id
+ $id = 1;
+
+ // Loop through styles in the current worksheet
+ foreach ($pSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) {
+ foreach ($conditionalStyles as $conditional) {
+ // WHY was this again?
+ // if ($this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()) == '') {
+ // continue;
+ // }
+ if ($conditional->getConditionType() != PHPExcel_Style_Conditional::CONDITION_NONE) {
+ // conditionalFormatting
+ $objWriter->startElement('conditionalFormatting');
+ $objWriter->writeAttribute('sqref', $cellCoordinate);
+
+ // cfRule
+ $objWriter->startElement('cfRule');
+ $objWriter->writeAttribute('type', $conditional->getConditionType());
+ $objWriter->writeAttribute('dxfId', $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()));
+ $objWriter->writeAttribute('priority', $id++);
+
+ if (($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT)
+ && $conditional->getOperatorType() != PHPExcel_Style_Conditional::OPERATOR_NONE) {
+ $objWriter->writeAttribute('operator', $conditional->getOperatorType());
+ }
+
+ if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT
+ && !is_null($conditional->getText())) {
+ $objWriter->writeAttribute('text', $conditional->getText());
+ }
+
+ if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT
+ && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_CONTAINSTEXT
+ && !is_null($conditional->getText())) {
+ $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . ')))');
+ } elseif ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT
+ && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BEGINSWITH
+ && !is_null($conditional->getText())) {
+ $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"');
+ } elseif ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT
+ && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_ENDSWITH
+ && !is_null($conditional->getText())) {
+ $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"');
+ } elseif ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT
+ && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_NOTCONTAINS
+ && !is_null($conditional->getText())) {
+ $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . '))');
+ } elseif ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS
+ || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT
+ || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION) {
+ foreach ($conditional->getConditions() as $formula) {
+ // Formula
+ $objWriter->writeElement('formula', $formula);
+ }
+ }
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+ }
+ }
+ }
+
+ /**
+ * Write DataValidations
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeDataValidations(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
+ {
+ // Datavalidation collection
+ $dataValidationCollection = $pSheet->getDataValidationCollection();
+
+ // Write data validations?
+ if (!empty($dataValidationCollection)) {
+ $objWriter->startElement('dataValidations');
+ $objWriter->writeAttribute('count', count($dataValidationCollection));
+
+ foreach ($dataValidationCollection as $coordinate => $dv) {
+ $objWriter->startElement('dataValidation');
+
+ if ($dv->getType() != '') {
+ $objWriter->writeAttribute('type', $dv->getType());
+ }
+
+ if ($dv->getErrorStyle() != '') {
+ $objWriter->writeAttribute('errorStyle', $dv->getErrorStyle());
+ }
+
+ if ($dv->getOperator() != '') {
+ $objWriter->writeAttribute('operator', $dv->getOperator());
+ }
+
+ $objWriter->writeAttribute('allowBlank', ($dv->getAllowBlank() ? '1' : '0'));
+ $objWriter->writeAttribute('showDropDown', (!$dv->getShowDropDown() ? '1' : '0'));
+ $objWriter->writeAttribute('showInputMessage', ($dv->getShowInputMessage() ? '1' : '0'));
+ $objWriter->writeAttribute('showErrorMessage', ($dv->getShowErrorMessage() ? '1' : '0'));
+
+ if ($dv->getErrorTitle() !== '') {
+ $objWriter->writeAttribute('errorTitle', $dv->getErrorTitle());
+ }
+ if ($dv->getError() !== '') {
+ $objWriter->writeAttribute('error', $dv->getError());
+ }
+ if ($dv->getPromptTitle() !== '') {
+ $objWriter->writeAttribute('promptTitle', $dv->getPromptTitle());
+ }
+ if ($dv->getPrompt() !== '') {
+ $objWriter->writeAttribute('prompt', $dv->getPrompt());
+ }
+
+ $objWriter->writeAttribute('sqref', $coordinate);
+
+ if ($dv->getFormula1() !== '') {
+ $objWriter->writeElement('formula1', $dv->getFormula1());
+ }
+ if ($dv->getFormula2() !== '') {
+ $objWriter->writeElement('formula2', $dv->getFormula2());
+ }
+
+ $objWriter->endElement();
+ }
+
+ $objWriter->endElement();
+ }
+ }
+
+ /**
+ * Write Hyperlinks
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeHyperlinks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
+ {
+ // Hyperlink collection
+ $hyperlinkCollection = $pSheet->getHyperlinkCollection();
+
+ // Relation ID
+ $relationId = 1;
+
+ // Write hyperlinks?
+ if (!empty($hyperlinkCollection)) {
+ $objWriter->startElement('hyperlinks');
+
+ foreach ($hyperlinkCollection as $coordinate => $hyperlink) {
+ $objWriter->startElement('hyperlink');
+
+ $objWriter->writeAttribute('ref', $coordinate);
+ if (!$hyperlink->isInternal()) {
+ $objWriter->writeAttribute('r:id', 'rId_hyperlink_' . $relationId);
+ ++$relationId;
+ } else {
+ $objWriter->writeAttribute('location', str_replace('sheet://', '', $hyperlink->getUrl()));
+ }
+
+ if ($hyperlink->getTooltip() != '') {
+ $objWriter->writeAttribute('tooltip', $hyperlink->getTooltip());
+ }
+
+ $objWriter->endElement();
+ }
+
+ $objWriter->endElement();
+ }
+ }
+
+ /**
+ * Write ProtectedRanges
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeProtectedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
+ {
+ if (count($pSheet->getProtectedCells()) > 0) {
+ // protectedRanges
+ $objWriter->startElement('protectedRanges');
+
+ // Loop protectedRanges
+ foreach ($pSheet->getProtectedCells() as $protectedCell => $passwordHash) {
+ // protectedRange
+ $objWriter->startElement('protectedRange');
+ $objWriter->writeAttribute('name', 'p' . md5($protectedCell));
+ $objWriter->writeAttribute('sqref', $protectedCell);
+ if (!empty($passwordHash)) {
+ $objWriter->writeAttribute('password', $passwordHash);
+ }
+ $objWriter->endElement();
+ }
+
+ $objWriter->endElement();
+ }
+ }
+
+ /**
+ * Write MergeCells
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeMergeCells(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
+ {
+ if (count($pSheet->getMergeCells()) > 0) {
+ // mergeCells
+ $objWriter->startElement('mergeCells');
+
+ // Loop mergeCells
+ foreach ($pSheet->getMergeCells() as $mergeCell) {
+ // mergeCell
+ $objWriter->startElement('mergeCell');
+ $objWriter->writeAttribute('ref', $mergeCell);
+ $objWriter->endElement();
+ }
+
+ $objWriter->endElement();
+ }
+ }
+
+ /**
+ * Write PrintOptions
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writePrintOptions(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
+ {
+ // printOptions
+ $objWriter->startElement('printOptions');
+
+ $objWriter->writeAttribute('gridLines', ($pSheet->getPrintGridlines() ? 'true': 'false'));
+ $objWriter->writeAttribute('gridLinesSet', 'true');
+
+ if ($pSheet->getPageSetup()->getHorizontalCentered()) {
+ $objWriter->writeAttribute('horizontalCentered', 'true');
+ }
+
+ if ($pSheet->getPageSetup()->getVerticalCentered()) {
+ $objWriter->writeAttribute('verticalCentered', 'true');
+ }
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write PageMargins
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writePageMargins(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
+ {
+ // pageMargins
+ $objWriter->startElement('pageMargins');
+ $objWriter->writeAttribute('left', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft()));
+ $objWriter->writeAttribute('right', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight()));
+ $objWriter->writeAttribute('top', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop()));
+ $objWriter->writeAttribute('bottom', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom()));
+ $objWriter->writeAttribute('header', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getHeader()));
+ $objWriter->writeAttribute('footer', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getFooter()));
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write AutoFilter
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
+ {
+ $autoFilterRange = $pSheet->getAutoFilter()->getRange();
+ if (!empty($autoFilterRange)) {
+ // autoFilter
+ $objWriter->startElement('autoFilter');
+
+ // Strip any worksheet reference from the filter coordinates
+ $range = PHPExcel_Cell::splitRange($autoFilterRange);
+ $range = $range[0];
+ // Strip any worksheet ref
+ if (strpos($range[0], '!') !== false) {
+ list($ws, $range[0]) = explode('!', $range[0]);
+ }
+ $range = implode(':', $range);
+
+ $objWriter->writeAttribute('ref', str_replace('$', '', $range));
+
+ $columns = $pSheet->getAutoFilter()->getColumns();
+ if (count($columns > 0)) {
+ foreach ($columns as $columnID => $column) {
+ $rules = $column->getRules();
+ if (count($rules) > 0) {
+ $objWriter->startElement('filterColumn');
+ $objWriter->writeAttribute('colId', $pSheet->getAutoFilter()->getColumnOffset($columnID));
+
+ $objWriter->startElement($column->getFilterType());
+ if ($column->getJoin() == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND) {
+ $objWriter->writeAttribute('and', 1);
+ }
+
+ foreach ($rules as $rule) {
+ if (($column->getFilterType() === PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER) &&
+ ($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) &&
+ ($rule->getValue() === '')) {
+ // Filter rule for Blanks
+ $objWriter->writeAttribute('blank', 1);
+ } elseif ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) {
+ // Dynamic Filter Rule
+ $objWriter->writeAttribute('type', $rule->getGrouping());
+ $val = $column->getAttribute('val');
+ if ($val !== null) {
+ $objWriter->writeAttribute('val', $val);
+ }
+ $maxVal = $column->getAttribute('maxVal');
+ if ($maxVal !== null) {
+ $objWriter->writeAttribute('maxVal', $maxVal);
+ }
+ } elseif ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) {
+ // Top 10 Filter Rule
+ $objWriter->writeAttribute('val', $rule->getValue());
+ $objWriter->writeAttribute('percent', (($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0'));
+ $objWriter->writeAttribute('top', (($rule->getGrouping() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1': '0'));
+ } else {
+ // Filter, DateGroupItem or CustomFilter
+ $objWriter->startElement($rule->getRuleType());
+
+ if ($rule->getOperator() !== PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) {
+ $objWriter->writeAttribute('operator', $rule->getOperator());
+ }
+ if ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP) {
+ // Date Group filters
+ foreach ($rule->getValue() as $key => $value) {
+ if ($value > '') {
+ $objWriter->writeAttribute($key, $value);
+ }
+ }
+ $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping());
+ } else {
+ $objWriter->writeAttribute('val', $rule->getValue());
+ }
+
+ $objWriter->endElement();
+ }
+ }
+
+ $objWriter->endElement();
+
+ $objWriter->endElement();
+ }
+ }
+ }
+ $objWriter->endElement();
+ }
+ }
+
+ /**
+ * Write PageSetup
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writePageSetup(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
+ {
+ // pageSetup
+ $objWriter->startElement('pageSetup');
+ $objWriter->writeAttribute('paperSize', $pSheet->getPageSetup()->getPaperSize());
+ $objWriter->writeAttribute('orientation', $pSheet->getPageSetup()->getOrientation());
+
+ if (!is_null($pSheet->getPageSetup()->getScale())) {
+ $objWriter->writeAttribute('scale', $pSheet->getPageSetup()->getScale());
+ }
+ if (!is_null($pSheet->getPageSetup()->getFitToHeight())) {
+ $objWriter->writeAttribute('fitToHeight', $pSheet->getPageSetup()->getFitToHeight());
+ } else {
+ $objWriter->writeAttribute('fitToHeight', '0');
+ }
+ if (!is_null($pSheet->getPageSetup()->getFitToWidth())) {
+ $objWriter->writeAttribute('fitToWidth', $pSheet->getPageSetup()->getFitToWidth());
+ } else {
+ $objWriter->writeAttribute('fitToWidth', '0');
+ }
+ if (!is_null($pSheet->getPageSetup()->getFirstPageNumber())) {
+ $objWriter->writeAttribute('firstPageNumber', $pSheet->getPageSetup()->getFirstPageNumber());
+ $objWriter->writeAttribute('useFirstPageNumber', '1');
+ }
+
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write Header / Footer
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeHeaderFooter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
+ {
+ // headerFooter
+ $objWriter->startElement('headerFooter');
+ $objWriter->writeAttribute('differentOddEven', ($pSheet->getHeaderFooter()->getDifferentOddEven() ? 'true' : 'false'));
+ $objWriter->writeAttribute('differentFirst', ($pSheet->getHeaderFooter()->getDifferentFirst() ? 'true' : 'false'));
+ $objWriter->writeAttribute('scaleWithDoc', ($pSheet->getHeaderFooter()->getScaleWithDocument() ? 'true' : 'false'));
+ $objWriter->writeAttribute('alignWithMargins', ($pSheet->getHeaderFooter()->getAlignWithMargins() ? 'true' : 'false'));
+
+ $objWriter->writeElement('oddHeader', $pSheet->getHeaderFooter()->getOddHeader());
+ $objWriter->writeElement('oddFooter', $pSheet->getHeaderFooter()->getOddFooter());
+ $objWriter->writeElement('evenHeader', $pSheet->getHeaderFooter()->getEvenHeader());
+ $objWriter->writeElement('evenFooter', $pSheet->getHeaderFooter()->getEvenFooter());
+ $objWriter->writeElement('firstHeader', $pSheet->getHeaderFooter()->getFirstHeader());
+ $objWriter->writeElement('firstFooter', $pSheet->getHeaderFooter()->getFirstFooter());
+ $objWriter->endElement();
+ }
+
+ /**
+ * Write Breaks
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeBreaks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
+ {
+ // Get row and column breaks
+ $aRowBreaks = array();
+ $aColumnBreaks = array();
+ foreach ($pSheet->getBreaks() as $cell => $breakType) {
+ if ($breakType == PHPExcel_Worksheet::BREAK_ROW) {
+ $aRowBreaks[] = $cell;
+ } elseif ($breakType == PHPExcel_Worksheet::BREAK_COLUMN) {
+ $aColumnBreaks[] = $cell;
+ }
+ }
+
+ // rowBreaks
+ if (!empty($aRowBreaks)) {
+ $objWriter->startElement('rowBreaks');
+ $objWriter->writeAttribute('count', count($aRowBreaks));
+ $objWriter->writeAttribute('manualBreakCount', count($aRowBreaks));
+
+ foreach ($aRowBreaks as $cell) {
+ $coords = PHPExcel_Cell::coordinateFromString($cell);
+
+ $objWriter->startElement('brk');
+ $objWriter->writeAttribute('id', $coords[1]);
+ $objWriter->writeAttribute('man', '1');
+ $objWriter->endElement();
+ }
+
+ $objWriter->endElement();
+ }
+
+ // Second, write column breaks
+ if (!empty($aColumnBreaks)) {
+ $objWriter->startElement('colBreaks');
+ $objWriter->writeAttribute('count', count($aColumnBreaks));
+ $objWriter->writeAttribute('manualBreakCount', count($aColumnBreaks));
+
+ foreach ($aColumnBreaks as $cell) {
+ $coords = PHPExcel_Cell::coordinateFromString($cell);
+
+ $objWriter->startElement('brk');
+ $objWriter->writeAttribute('id', PHPExcel_Cell::columnIndexFromString($coords[0]) - 1);
+ $objWriter->writeAttribute('man', '1');
+ $objWriter->endElement();
+ }
+
+ $objWriter->endElement();
+ }
+ }
+
+ /**
+ * Write SheetData
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @param string[] $pStringTable String table
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeSheetData(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pStringTable = null)
+ {
+ if (is_array($pStringTable)) {
+ // Flipped stringtable, for faster index searching
+ $aFlippedStringTable = $this->getParentWriter()->getWriterPart('stringtable')->flipStringTable($pStringTable);
+
+ // sheetData
+ $objWriter->startElement('sheetData');
+
+ // Get column count
+ $colCount = PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn());
+
+ // Highest row number
+ $highestRow = $pSheet->getHighestRow();
+
+ // Loop through cells
+ $cellsByRow = array();
+ foreach ($pSheet->getCellCollection() as $cellID) {
+ $cellAddress = PHPExcel_Cell::coordinateFromString($cellID);
+ $cellsByRow[$cellAddress[1]][] = $cellID;
+ }
+
+ $currentRow = 0;
+ while ($currentRow++ < $highestRow) {
+ // Get row dimension
+ $rowDimension = $pSheet->getRowDimension($currentRow);
+
+ // Write current row?
+ $writeCurrentRow = isset($cellsByRow[$currentRow]) || $rowDimension->getRowHeight() >= 0 || $rowDimension->getVisible() == false || $rowDimension->getCollapsed() == true || $rowDimension->getOutlineLevel() > 0 || $rowDimension->getXfIndex() !== null;
+
+ if ($writeCurrentRow) {
+ // Start a new row
+ $objWriter->startElement('row');
+ $objWriter->writeAttribute('r', $currentRow);
+ $objWriter->writeAttribute('spans', '1:' . $colCount);
+
+ // Row dimensions
+ if ($rowDimension->getRowHeight() >= 0) {
+ $objWriter->writeAttribute('customHeight', '1');
+ $objWriter->writeAttribute('ht', PHPExcel_Shared_String::FormatNumber($rowDimension->getRowHeight()));
+ }
+
+ // Row visibility
+ if ($rowDimension->getVisible() == false) {
+ $objWriter->writeAttribute('hidden', 'true');
+ }
+
+ // Collapsed
+ if ($rowDimension->getCollapsed() == true) {
+ $objWriter->writeAttribute('collapsed', 'true');
+ }
+
+ // Outline level
+ if ($rowDimension->getOutlineLevel() > 0) {
+ $objWriter->writeAttribute('outlineLevel', $rowDimension->getOutlineLevel());
+ }
+
+ // Style
+ if ($rowDimension->getXfIndex() !== null) {
+ $objWriter->writeAttribute('s', $rowDimension->getXfIndex());
+ $objWriter->writeAttribute('customFormat', '1');
+ }
+
+ // Write cells
+ if (isset($cellsByRow[$currentRow])) {
+ foreach ($cellsByRow[$currentRow] as $cellAddress) {
+ // Write cell
+ $this->writeCell($objWriter, $pSheet, $cellAddress, $pStringTable, $aFlippedStringTable);
+ }
+ }
+
+ // End row
+ $objWriter->endElement();
+ }
+ }
+
+ $objWriter->endElement();
+ } else {
+ throw new PHPExcel_Writer_Exception("Invalid parameters passed.");
+ }
+ }
+
+ /**
+ * Write Cell
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @param PHPExcel_Cell $pCellAddress Cell Address
+ * @param string[] $pStringTable String table
+ * @param string[] $pFlippedStringTable String table (flipped), for faster index searching
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeCell(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pCellAddress = null, $pStringTable = null, $pFlippedStringTable = null)
+ {
+ if (is_array($pStringTable) && is_array($pFlippedStringTable)) {
+ // Cell
+ $pCell = $pSheet->getCell($pCellAddress);
+ $objWriter->startElement('c');
+ $objWriter->writeAttribute('r', $pCellAddress);
+
+ // Sheet styles
+ if ($pCell->getXfIndex() != '') {
+ $objWriter->writeAttribute('s', $pCell->getXfIndex());
+ }
+
+ // If cell value is supplied, write cell value
+ $cellValue = $pCell->getValue();
+ if (is_object($cellValue) || $cellValue !== '') {
+ // Map type
+ $mappedType = $pCell->getDataType();
+
+ // Write data type depending on its type
+ switch (strtolower($mappedType)) {
+ case 'inlinestr': // Inline string
+ case 's': // String
+ case 'b': // Boolean
+ $objWriter->writeAttribute('t', $mappedType);
+ break;
+ case 'f': // Formula
+ $calculatedValue = ($this->getParentWriter()->getPreCalculateFormulas()) ?
+ $pCell->getCalculatedValue() :
+ $cellValue;
+ if (is_string($calculatedValue)) {
+ $objWriter->writeAttribute('t', 'str');
+ }
+ break;
+ case 'e': // Error
+ $objWriter->writeAttribute('t', $mappedType);
+ }
+
+ // Write data depending on its type
+ switch (strtolower($mappedType)) {
+ case 'inlinestr': // Inline string
+ if (! $cellValue instanceof PHPExcel_RichText) {
+ $objWriter->writeElement('t', PHPExcel_Shared_String::ControlCharacterPHP2OOXML(htmlspecialchars($cellValue)));
+ } elseif ($cellValue instanceof PHPExcel_RichText) {
+ $objWriter->startElement('is');
+ $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $cellValue);
+ $objWriter->endElement();
+ }
+
+ break;
+ case 's': // String
+ if (! $cellValue instanceof PHPExcel_RichText) {
+ if (isset($pFlippedStringTable[$cellValue])) {
+ $objWriter->writeElement('v', $pFlippedStringTable[$cellValue]);
+ }
+ } elseif ($cellValue instanceof PHPExcel_RichText) {
+ $objWriter->writeElement('v', $pFlippedStringTable[$cellValue->getHashCode()]);
+ }
+
+ break;
+ case 'f': // Formula
+ $attributes = $pCell->getFormulaAttributes();
+ if ($attributes['t'] == 'array') {
+ $objWriter->startElement('f');
+ $objWriter->writeAttribute('t', 'array');
+ $objWriter->writeAttribute('ref', $pCellAddress);
+ $objWriter->writeAttribute('aca', '1');
+ $objWriter->writeAttribute('ca', '1');
+ $objWriter->text(substr($cellValue, 1));
+ $objWriter->endElement();
+ } else {
+ $objWriter->writeElement('f', substr($cellValue, 1));
+ }
+ if ($this->getParentWriter()->getOffice2003Compatibility() === false) {
+ if ($this->getParentWriter()->getPreCalculateFormulas()) {
+// $calculatedValue = $pCell->getCalculatedValue();
+ if (!is_array($calculatedValue) && substr($calculatedValue, 0, 1) != '#') {
+ $objWriter->writeElement('v', PHPExcel_Shared_String::FormatNumber($calculatedValue));
+ } else {
+ $objWriter->writeElement('v', '0');
+ }
+ } else {
+ $objWriter->writeElement('v', '0');
+ }
+ }
+ break;
+ case 'n': // Numeric
+ // force point as decimal separator in case current locale uses comma
+ $objWriter->writeElement('v', str_replace(',', '.', $cellValue));
+ break;
+ case 'b': // Boolean
+ $objWriter->writeElement('v', ($cellValue ? '1' : '0'));
+ break;
+ case 'e': // Error
+ if (substr($cellValue, 0, 1) == '=') {
+ $objWriter->writeElement('f', substr($cellValue, 1));
+ $objWriter->writeElement('v', substr($cellValue, 1));
+ } else {
+ $objWriter->writeElement('v', $cellValue);
+ }
+
+ break;
+ }
+ }
+
+ $objWriter->endElement();
+ } else {
+ throw new PHPExcel_Writer_Exception("Invalid parameters passed.");
+ }
+ }
+
+ /**
+ * Write Drawings
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @param boolean $includeCharts Flag indicating if we should include drawing details for charts
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeDrawings(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $includeCharts = false)
+ {
+ $chartCount = ($includeCharts) ? $pSheet->getChartCollection()->count() : 0;
+ // If sheet contains drawings, add the relationships
+ if (($pSheet->getDrawingCollection()->count() > 0) ||
+ ($chartCount > 0)) {
+ $objWriter->startElement('drawing');
+ $objWriter->writeAttribute('r:id', 'rId1');
+ $objWriter->endElement();
+ }
+ }
+
+ /**
+ * Write LegacyDrawing
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeLegacyDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
+ {
+ // If sheet contains comments, add the relationships
+ if (count($pSheet->getComments()) > 0) {
+ $objWriter->startElement('legacyDrawing');
+ $objWriter->writeAttribute('r:id', 'rId_comments_vml1');
+ $objWriter->endElement();
+ }
+ }
+
+ /**
+ * Write LegacyDrawingHF
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
+ * @param PHPExcel_Worksheet $pSheet Worksheet
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeLegacyDrawingHF(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
+ {
+ // If sheet contains images, add the relationships
+ if (count($pSheet->getHeaderFooter()->getImages()) > 0) {
+ $objWriter->startElement('legacyDrawingHF');
+ $objWriter->writeAttribute('r:id', 'rId_headerfooter_vml1');
+ $objWriter->endElement();
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/WriterPart.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/WriterPart.php
new file mode 100755
index 000000000..806ebe510
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/WriterPart.php
@@ -0,0 +1,75 @@
+parentWriter = $pWriter;
+ }
+
+ /**
+ * Get parent IWriter object
+ *
+ * @return PHPExcel_Writer_IWriter
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function getParentWriter()
+ {
+ if (!is_null($this->parentWriter)) {
+ return $this->parentWriter;
+ } else {
+ throw new PHPExcel_Writer_Exception("No parent PHPExcel_Writer_IWriter assigned.");
+ }
+ }
+
+ /**
+ * Set parent IWriter object
+ *
+ * @param PHPExcel_Writer_IWriter $pWriter
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function __construct(PHPExcel_Writer_IWriter $pWriter = null)
+ {
+ if (!is_null($pWriter)) {
+ $this->parentWriter = $pWriter;
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel5.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel5.php
new file mode 100755
index 000000000..2dede819a
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel5.php
@@ -0,0 +1,904 @@
+phpExcel = $phpExcel;
+
+ $this->parser = new PHPExcel_Writer_Excel5_Parser();
+ }
+
+ /**
+ * Save PHPExcel to file
+ *
+ * @param string $pFilename
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function save($pFilename = null)
+ {
+
+ // garbage collect
+ $this->phpExcel->garbageCollect();
+
+ $saveDebugLog = PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->getWriteDebugLog();
+ PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog(false);
+ $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType();
+ PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);
+
+ // initialize colors array
+ $this->colors = array();
+
+ // Initialise workbook writer
+ $this->writerWorkbook = new PHPExcel_Writer_Excel5_Workbook($this->phpExcel, $this->strTotal, $this->strUnique, $this->strTable, $this->colors, $this->parser);
+
+ // Initialise worksheet writers
+ $countSheets = $this->phpExcel->getSheetCount();
+ for ($i = 0; $i < $countSheets; ++$i) {
+ $this->writerWorksheets[$i] = new PHPExcel_Writer_Excel5_Worksheet($this->strTotal, $this->strUnique, $this->strTable, $this->colors, $this->parser, $this->preCalculateFormulas, $this->phpExcel->getSheet($i));
+ }
+
+ // build Escher objects. Escher objects for workbooks needs to be build before Escher object for workbook.
+ $this->buildWorksheetEschers();
+ $this->buildWorkbookEscher();
+
+ // add 15 identical cell style Xfs
+ // for now, we use the first cellXf instead of cellStyleXf
+ $cellXfCollection = $this->phpExcel->getCellXfCollection();
+ for ($i = 0; $i < 15; ++$i) {
+ $this->writerWorkbook->addXfWriter($cellXfCollection[0], true);
+ }
+
+ // add all the cell Xfs
+ foreach ($this->phpExcel->getCellXfCollection() as $style) {
+ $this->writerWorkbook->addXfWriter($style, false);
+ }
+
+ // add fonts from rich text eleemnts
+ for ($i = 0; $i < $countSheets; ++$i) {
+ foreach ($this->writerWorksheets[$i]->phpSheet->getCellCollection() as $cellID) {
+ $cell = $this->writerWorksheets[$i]->phpSheet->getCell($cellID);
+ $cVal = $cell->getValue();
+ if ($cVal instanceof PHPExcel_RichText) {
+ $elements = $cVal->getRichTextElements();
+ foreach ($elements as $element) {
+ if ($element instanceof PHPExcel_RichText_Run) {
+ $font = $element->getFont();
+ $this->writerWorksheets[$i]->fontHashIndex[$font->getHashCode()] = $this->writerWorkbook->addFont($font);
+ }
+ }
+ }
+ }
+ }
+
+ // initialize OLE file
+ $workbookStreamName = 'Workbook';
+ $OLE = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs($workbookStreamName));
+
+ // Write the worksheet streams before the global workbook stream,
+ // because the byte sizes of these are needed in the global workbook stream
+ $worksheetSizes = array();
+ for ($i = 0; $i < $countSheets; ++$i) {
+ $this->writerWorksheets[$i]->close();
+ $worksheetSizes[] = $this->writerWorksheets[$i]->_datasize;
+ }
+
+ // add binary data for global workbook stream
+ $OLE->append($this->writerWorkbook->writeWorkbook($worksheetSizes));
+
+ // add binary data for sheet streams
+ for ($i = 0; $i < $countSheets; ++$i) {
+ $OLE->append($this->writerWorksheets[$i]->getData());
+ }
+
+ $this->documentSummaryInformation = $this->writeDocumentSummaryInformation();
+ // initialize OLE Document Summary Information
+ if (isset($this->documentSummaryInformation) && !empty($this->documentSummaryInformation)) {
+ $OLE_DocumentSummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'DocumentSummaryInformation'));
+ $OLE_DocumentSummaryInformation->append($this->documentSummaryInformation);
+ }
+
+ $this->summaryInformation = $this->writeSummaryInformation();
+ // initialize OLE Summary Information
+ if (isset($this->summaryInformation) && !empty($this->summaryInformation)) {
+ $OLE_SummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'SummaryInformation'));
+ $OLE_SummaryInformation->append($this->summaryInformation);
+ }
+
+ // define OLE Parts
+ $arrRootData = array($OLE);
+ // initialize OLE Properties file
+ if (isset($OLE_SummaryInformation)) {
+ $arrRootData[] = $OLE_SummaryInformation;
+ }
+ // initialize OLE Extended Properties file
+ if (isset($OLE_DocumentSummaryInformation)) {
+ $arrRootData[] = $OLE_DocumentSummaryInformation;
+ }
+
+ $root = new PHPExcel_Shared_OLE_PPS_Root(time(), time(), $arrRootData);
+ // save the OLE file
+ $res = $root->save($pFilename);
+
+ PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType);
+ PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog);
+ }
+
+ /**
+ * Set temporary storage directory
+ *
+ * @deprecated
+ * @param string $pValue Temporary storage directory
+ * @throws PHPExcel_Writer_Exception when directory does not exist
+ * @return PHPExcel_Writer_Excel5
+ */
+ public function setTempDir($pValue = '')
+ {
+ return $this;
+ }
+
+ /**
+ * Build the Worksheet Escher objects
+ *
+ */
+ private function buildWorksheetEschers()
+ {
+ // 1-based index to BstoreContainer
+ $blipIndex = 0;
+ $lastReducedSpId = 0;
+ $lastSpId = 0;
+
+ foreach ($this->phpExcel->getAllsheets() as $sheet) {
+ // sheet index
+ $sheetIndex = $sheet->getParent()->getIndex($sheet);
+
+ $escher = null;
+
+ // check if there are any shapes for this sheet
+ $filterRange = $sheet->getAutoFilter()->getRange();
+ if (count($sheet->getDrawingCollection()) == 0 && empty($filterRange)) {
+ continue;
+ }
+
+ // create intermediate Escher object
+ $escher = new PHPExcel_Shared_Escher();
+
+ // dgContainer
+ $dgContainer = new PHPExcel_Shared_Escher_DgContainer();
+
+ // set the drawing index (we use sheet index + 1)
+ $dgId = $sheet->getParent()->getIndex($sheet) + 1;
+ $dgContainer->setDgId($dgId);
+ $escher->setDgContainer($dgContainer);
+
+ // spgrContainer
+ $spgrContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer();
+ $dgContainer->setSpgrContainer($spgrContainer);
+
+ // add one shape which is the group shape
+ $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer();
+ $spContainer->setSpgr(true);
+ $spContainer->setSpType(0);
+ $spContainer->setSpId(($sheet->getParent()->getIndex($sheet) + 1) << 10);
+ $spgrContainer->addChild($spContainer);
+
+ // add the shapes
+
+ $countShapes[$sheetIndex] = 0; // count number of shapes (minus group shape), in sheet
+
+ foreach ($sheet->getDrawingCollection() as $drawing) {
+ ++$blipIndex;
+
+ ++$countShapes[$sheetIndex];
+
+ // add the shape
+ $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer();
+
+ // set the shape type
+ $spContainer->setSpType(0x004B);
+ // set the shape flag
+ $spContainer->setSpFlag(0x02);
+
+ // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index)
+ $reducedSpId = $countShapes[$sheetIndex];
+ $spId = $reducedSpId
+ | ($sheet->getParent()->getIndex($sheet) + 1) << 10;
+ $spContainer->setSpId($spId);
+
+ // keep track of last reducedSpId
+ $lastReducedSpId = $reducedSpId;
+
+ // keep track of last spId
+ $lastSpId = $spId;
+
+ // set the BLIP index
+ $spContainer->setOPT(0x4104, $blipIndex);
+
+ // set coordinates and offsets, client anchor
+ $coordinates = $drawing->getCoordinates();
+ $offsetX = $drawing->getOffsetX();
+ $offsetY = $drawing->getOffsetY();
+ $width = $drawing->getWidth();
+ $height = $drawing->getHeight();
+
+ $twoAnchor = PHPExcel_Shared_Excel5::oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height);
+
+ $spContainer->setStartCoordinates($twoAnchor['startCoordinates']);
+ $spContainer->setStartOffsetX($twoAnchor['startOffsetX']);
+ $spContainer->setStartOffsetY($twoAnchor['startOffsetY']);
+ $spContainer->setEndCoordinates($twoAnchor['endCoordinates']);
+ $spContainer->setEndOffsetX($twoAnchor['endOffsetX']);
+ $spContainer->setEndOffsetY($twoAnchor['endOffsetY']);
+
+ $spgrContainer->addChild($spContainer);
+ }
+
+ // AutoFilters
+ if (!empty($filterRange)) {
+ $rangeBounds = PHPExcel_Cell::rangeBoundaries($filterRange);
+ $iNumColStart = $rangeBounds[0][0];
+ $iNumColEnd = $rangeBounds[1][0];
+
+ $iInc = $iNumColStart;
+ while ($iInc <= $iNumColEnd) {
+ ++$countShapes[$sheetIndex];
+
+ // create an Drawing Object for the dropdown
+ $oDrawing = new PHPExcel_Worksheet_BaseDrawing();
+ // get the coordinates of drawing
+ $cDrawing = PHPExcel_Cell::stringFromColumnIndex($iInc - 1) . $rangeBounds[0][1];
+ $oDrawing->setCoordinates($cDrawing);
+ $oDrawing->setWorksheet($sheet);
+
+ // add the shape
+ $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer();
+ // set the shape type
+ $spContainer->setSpType(0x00C9);
+ // set the shape flag
+ $spContainer->setSpFlag(0x01);
+
+ // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index)
+ $reducedSpId = $countShapes[$sheetIndex];
+ $spId = $reducedSpId
+ | ($sheet->getParent()->getIndex($sheet) + 1) << 10;
+ $spContainer->setSpId($spId);
+
+ // keep track of last reducedSpId
+ $lastReducedSpId = $reducedSpId;
+
+ // keep track of last spId
+ $lastSpId = $spId;
+
+ $spContainer->setOPT(0x007F, 0x01040104); // Protection -> fLockAgainstGrouping
+ $spContainer->setOPT(0x00BF, 0x00080008); // Text -> fFitTextToShape
+ $spContainer->setOPT(0x01BF, 0x00010000); // Fill Style -> fNoFillHitTest
+ $spContainer->setOPT(0x01FF, 0x00080000); // Line Style -> fNoLineDrawDash
+ $spContainer->setOPT(0x03BF, 0x000A0000); // Group Shape -> fPrint
+
+ // set coordinates and offsets, client anchor
+ $endCoordinates = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::stringFromColumnIndex($iInc - 1));
+ $endCoordinates .= $rangeBounds[0][1] + 1;
+
+ $spContainer->setStartCoordinates($cDrawing);
+ $spContainer->setStartOffsetX(0);
+ $spContainer->setStartOffsetY(0);
+ $spContainer->setEndCoordinates($endCoordinates);
+ $spContainer->setEndOffsetX(0);
+ $spContainer->setEndOffsetY(0);
+
+ $spgrContainer->addChild($spContainer);
+ $iInc++;
+ }
+ }
+
+ // identifier clusters, used for workbook Escher object
+ $this->IDCLs[$dgId] = $lastReducedSpId;
+
+ // set last shape index
+ $dgContainer->setLastSpId($lastSpId);
+
+ // set the Escher object
+ $this->writerWorksheets[$sheetIndex]->setEscher($escher);
+ }
+ }
+
+ /**
+ * Build the Escher object corresponding to the MSODRAWINGGROUP record
+ */
+ private function buildWorkbookEscher()
+ {
+ $escher = null;
+
+ // any drawings in this workbook?
+ $found = false;
+ foreach ($this->phpExcel->getAllSheets() as $sheet) {
+ if (count($sheet->getDrawingCollection()) > 0) {
+ $found = true;
+ break;
+ }
+ }
+
+ // nothing to do if there are no drawings
+ if (!$found) {
+ return;
+ }
+
+ // if we reach here, then there are drawings in the workbook
+ $escher = new PHPExcel_Shared_Escher();
+
+ // dggContainer
+ $dggContainer = new PHPExcel_Shared_Escher_DggContainer();
+ $escher->setDggContainer($dggContainer);
+
+ // set IDCLs (identifier clusters)
+ $dggContainer->setIDCLs($this->IDCLs);
+
+ // this loop is for determining maximum shape identifier of all drawing
+ $spIdMax = 0;
+ $totalCountShapes = 0;
+ $countDrawings = 0;
+
+ foreach ($this->phpExcel->getAllsheets() as $sheet) {
+ $sheetCountShapes = 0; // count number of shapes (minus group shape), in sheet
+
+ if (count($sheet->getDrawingCollection()) > 0) {
+ ++$countDrawings;
+
+ foreach ($sheet->getDrawingCollection() as $drawing) {
+ ++$sheetCountShapes;
+ ++$totalCountShapes;
+
+ $spId = $sheetCountShapes | ($this->phpExcel->getIndex($sheet) + 1) << 10;
+ $spIdMax = max($spId, $spIdMax);
+ }
+ }
+ }
+
+ $dggContainer->setSpIdMax($spIdMax + 1);
+ $dggContainer->setCDgSaved($countDrawings);
+ $dggContainer->setCSpSaved($totalCountShapes + $countDrawings); // total number of shapes incl. one group shapes per drawing
+
+ // bstoreContainer
+ $bstoreContainer = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer();
+ $dggContainer->setBstoreContainer($bstoreContainer);
+
+ // the BSE's (all the images)
+ foreach ($this->phpExcel->getAllsheets() as $sheet) {
+ foreach ($sheet->getDrawingCollection() as $drawing) {
+ if ($drawing instanceof PHPExcel_Worksheet_Drawing) {
+ $filename = $drawing->getPath();
+
+ list($imagesx, $imagesy, $imageFormat) = getimagesize($filename);
+
+ switch ($imageFormat) {
+ case 1: // GIF, not supported by BIFF8, we convert to PNG
+ $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG;
+ ob_start();
+ imagepng(imagecreatefromgif($filename));
+ $blipData = ob_get_contents();
+ ob_end_clean();
+ break;
+ case 2: // JPEG
+ $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG;
+ $blipData = file_get_contents($filename);
+ break;
+ case 3: // PNG
+ $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG;
+ $blipData = file_get_contents($filename);
+ break;
+ case 6: // Windows DIB (BMP), we convert to PNG
+ $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG;
+ ob_start();
+ imagepng(PHPExcel_Shared_Drawing::imagecreatefrombmp($filename));
+ $blipData = ob_get_contents();
+ ob_end_clean();
+ break;
+ default:
+ continue 2;
+ }
+
+ $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip();
+ $blip->setData($blipData);
+
+ $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE();
+ $BSE->setBlipType($blipType);
+ $BSE->setBlip($blip);
+
+ $bstoreContainer->addBSE($BSE);
+ } elseif ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) {
+ switch ($drawing->getRenderingFunction()) {
+ case PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG:
+ $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG;
+ $renderingFunction = 'imagejpeg';
+ break;
+ case PHPExcel_Worksheet_MemoryDrawing::RENDERING_GIF:
+ case PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG:
+ case PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT:
+ $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG;
+ $renderingFunction = 'imagepng';
+ break;
+ }
+
+ ob_start();
+ call_user_func($renderingFunction, $drawing->getImageResource());
+ $blipData = ob_get_contents();
+ ob_end_clean();
+
+ $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip();
+ $blip->setData($blipData);
+
+ $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE();
+ $BSE->setBlipType($blipType);
+ $BSE->setBlip($blip);
+
+ $bstoreContainer->addBSE($BSE);
+ }
+ }
+ }
+
+ // Set the Escher object
+ $this->writerWorkbook->setEscher($escher);
+ }
+
+ /**
+ * Build the OLE Part for DocumentSummary Information
+ * @return string
+ */
+ private function writeDocumentSummaryInformation()
+ {
+ // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark)
+ $data = pack('v', 0xFFFE);
+ // offset: 2; size: 2;
+ $data .= pack('v', 0x0000);
+ // offset: 4; size: 2; OS version
+ $data .= pack('v', 0x0106);
+ // offset: 6; size: 2; OS indicator
+ $data .= pack('v', 0x0002);
+ // offset: 8; size: 16
+ $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00);
+ // offset: 24; size: 4; section count
+ $data .= pack('V', 0x0001);
+
+ // offset: 28; size: 16; first section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae
+ $data .= pack('vvvvvvvv', 0xD502, 0xD5CD, 0x2E9C, 0x101B, 0x9793, 0x0008, 0x2C2B, 0xAEF9);
+ // offset: 44; size: 4; offset of the start
+ $data .= pack('V', 0x30);
+
+ // SECTION
+ $dataSection = array();
+ $dataSection_NumProps = 0;
+ $dataSection_Summary = '';
+ $dataSection_Content = '';
+
+ // GKPIDDSI_CODEPAGE: CodePage
+ $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x01),
+ 'offset' => array('pack' => 'V'),
+ 'type' => array('pack' => 'V', 'data' => 0x02), // 2 byte signed integer
+ 'data' => array('data' => 1252));
+ $dataSection_NumProps++;
+
+ // GKPIDDSI_CATEGORY : Category
+ if ($this->phpExcel->getProperties()->getCategory()) {
+ $dataProp = $this->phpExcel->getProperties()->getCategory();
+ $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02),
+ 'offset' => array('pack' => 'V'),
+ 'type' => array('pack' => 'V', 'data' => 0x1E),
+ 'data' => array('data' => $dataProp, 'length' => strlen($dataProp)));
+ $dataSection_NumProps++;
+ }
+ // GKPIDDSI_VERSION :Version of the application that wrote the property storage
+ $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x17),
+ 'offset' => array('pack' => 'V'),
+ 'type' => array('pack' => 'V', 'data' => 0x03),
+ 'data' => array('pack' => 'V', 'data' => 0x000C0000));
+ $dataSection_NumProps++;
+ // GKPIDDSI_SCALE : FALSE
+ $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0B),
+ 'offset' => array('pack' => 'V'),
+ 'type' => array('pack' => 'V', 'data' => 0x0B),
+ 'data' => array('data' => false));
+ $dataSection_NumProps++;
+ // GKPIDDSI_LINKSDIRTY : True if any of the values for the linked properties have changed outside of the application
+ $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x10),
+ 'offset' => array('pack' => 'V'),
+ 'type' => array('pack' => 'V', 'data' => 0x0B),
+ 'data' => array('data' => false));
+ $dataSection_NumProps++;
+ // GKPIDDSI_SHAREDOC : FALSE
+ $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x13),
+ 'offset' => array('pack' => 'V'),
+ 'type' => array('pack' => 'V', 'data' => 0x0B),
+ 'data' => array('data' => false));
+ $dataSection_NumProps++;
+ // GKPIDDSI_HYPERLINKSCHANGED : True if any of the values for the _PID_LINKS (hyperlink text) have changed outside of the application
+ $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x16),
+ 'offset' => array('pack' => 'V'),
+ 'type' => array('pack' => 'V', 'data' => 0x0B),
+ 'data' => array('data' => false));
+ $dataSection_NumProps++;
+
+ // GKPIDDSI_DOCSPARTS
+ // MS-OSHARED p75 (2.3.3.2.2.1)
+ // Structure is VtVecUnalignedLpstrValue (2.3.3.1.9)
+ // cElements
+ $dataProp = pack('v', 0x0001);
+ $dataProp .= pack('v', 0x0000);
+ // array of UnalignedLpstr
+ // cch
+ $dataProp .= pack('v', 0x000A);
+ $dataProp .= pack('v', 0x0000);
+ // value
+ $dataProp .= 'Worksheet'.chr(0);
+
+ $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D),
+ 'offset' => array('pack' => 'V'),
+ 'type' => array('pack' => 'V', 'data' => 0x101E),
+ 'data' => array('data' => $dataProp, 'length' => strlen($dataProp)));
+ $dataSection_NumProps++;
+
+ // GKPIDDSI_HEADINGPAIR
+ // VtVecHeadingPairValue
+ // cElements
+ $dataProp = pack('v', 0x0002);
+ $dataProp .= pack('v', 0x0000);
+ // Array of vtHeadingPair
+ // vtUnalignedString - headingString
+ // stringType
+ $dataProp .= pack('v', 0x001E);
+ // padding
+ $dataProp .= pack('v', 0x0000);
+ // UnalignedLpstr
+ // cch
+ $dataProp .= pack('v', 0x0013);
+ $dataProp .= pack('v', 0x0000);
+ // value
+ $dataProp .= 'Feuilles de calcul';
+ // vtUnalignedString - headingParts
+ // wType : 0x0003 = 32 bit signed integer
+ $dataProp .= pack('v', 0x0300);
+ // padding
+ $dataProp .= pack('v', 0x0000);
+ // value
+ $dataProp .= pack('v', 0x0100);
+ $dataProp .= pack('v', 0x0000);
+ $dataProp .= pack('v', 0x0000);
+ $dataProp .= pack('v', 0x0000);
+
+ $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0C),
+ 'offset' => array('pack' => 'V'),
+ 'type' => array('pack' => 'V', 'data' => 0x100C),
+ 'data' => array('data' => $dataProp, 'length' => strlen($dataProp)));
+ $dataSection_NumProps++;
+
+ // 4 Section Length
+ // 4 Property count
+ // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4))
+ $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8;
+ foreach ($dataSection as $dataProp) {
+ // Summary
+ $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']);
+ // Offset
+ $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset);
+ // DataType
+ $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']);
+ // Data
+ if ($dataProp['type']['data'] == 0x02) { // 2 byte signed integer
+ $dataSection_Content .= pack('V', $dataProp['data']['data']);
+
+ $dataSection_Content_Offset += 4 + 4;
+ } elseif ($dataProp['type']['data'] == 0x03) { // 4 byte signed integer
+ $dataSection_Content .= pack('V', $dataProp['data']['data']);
+
+ $dataSection_Content_Offset += 4 + 4;
+ } elseif ($dataProp['type']['data'] == 0x0B) { // Boolean
+ if ($dataProp['data']['data'] == false) {
+ $dataSection_Content .= pack('V', 0x0000);
+ } else {
+ $dataSection_Content .= pack('V', 0x0001);
+ }
+ $dataSection_Content_Offset += 4 + 4;
+ } elseif ($dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length
+ // Null-terminated string
+ $dataProp['data']['data'] .= chr(0);
+ $dataProp['data']['length'] += 1;
+ // Complete the string with null string for being a %4
+ $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4)==4 ? 0 : (4 - $dataProp['data']['length'] % 4));
+ $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT);
+
+ $dataSection_Content .= pack('V', $dataProp['data']['length']);
+ $dataSection_Content .= $dataProp['data']['data'];
+
+ $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']);
+ } elseif ($dataProp['type']['data'] == 0x40) { // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)
+ $dataSection_Content .= $dataProp['data']['data'];
+
+ $dataSection_Content_Offset += 4 + 8;
+ } else {
+ // Data Type Not Used at the moment
+ $dataSection_Content .= $dataProp['data']['data'];
+
+ $dataSection_Content_Offset += 4 + $dataProp['data']['length'];
+ }
+ }
+ // Now $dataSection_Content_Offset contains the size of the content
+
+ // section header
+ // offset: $secOffset; size: 4; section length
+ // + x Size of the content (summary + content)
+ $data .= pack('V', $dataSection_Content_Offset);
+ // offset: $secOffset+4; size: 4; property count
+ $data .= pack('V', $dataSection_NumProps);
+ // Section Summary
+ $data .= $dataSection_Summary;
+ // Section Content
+ $data .= $dataSection_Content;
+
+ return $data;
+ }
+
+ /**
+ * Build the OLE Part for Summary Information
+ * @return string
+ */
+ private function writeSummaryInformation()
+ {
+ // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark)
+ $data = pack('v', 0xFFFE);
+ // offset: 2; size: 2;
+ $data .= pack('v', 0x0000);
+ // offset: 4; size: 2; OS version
+ $data .= pack('v', 0x0106);
+ // offset: 6; size: 2; OS indicator
+ $data .= pack('v', 0x0002);
+ // offset: 8; size: 16
+ $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00);
+ // offset: 24; size: 4; section count
+ $data .= pack('V', 0x0001);
+
+ // offset: 28; size: 16; first section's class id: e0 85 9f f2 f9 4f 68 10 ab 91 08 00 2b 27 b3 d9
+ $data .= pack('vvvvvvvv', 0x85E0, 0xF29F, 0x4FF9, 0x1068, 0x91AB, 0x0008, 0x272B, 0xD9B3);
+ // offset: 44; size: 4; offset of the start
+ $data .= pack('V', 0x30);
+
+ // SECTION
+ $dataSection = array();
+ $dataSection_NumProps = 0;
+ $dataSection_Summary = '';
+ $dataSection_Content = '';
+
+ // CodePage : CP-1252
+ $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x01),
+ 'offset' => array('pack' => 'V'),
+ 'type' => array('pack' => 'V', 'data' => 0x02), // 2 byte signed integer
+ 'data' => array('data' => 1252));
+ $dataSection_NumProps++;
+
+ // Title
+ if ($this->phpExcel->getProperties()->getTitle()) {
+ $dataProp = $this->phpExcel->getProperties()->getTitle();
+ $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02),
+ 'offset' => array('pack' => 'V'),
+ 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length
+ 'data' => array('data' => $dataProp, 'length' => strlen($dataProp)));
+ $dataSection_NumProps++;
+ }
+ // Subject
+ if ($this->phpExcel->getProperties()->getSubject()) {
+ $dataProp = $this->phpExcel->getProperties()->getSubject();
+ $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x03),
+ 'offset' => array('pack' => 'V'),
+ 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length
+ 'data' => array('data' => $dataProp, 'length' => strlen($dataProp)));
+ $dataSection_NumProps++;
+ }
+ // Author (Creator)
+ if ($this->phpExcel->getProperties()->getCreator()) {
+ $dataProp = $this->phpExcel->getProperties()->getCreator();
+ $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x04),
+ 'offset' => array('pack' => 'V'),
+ 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length
+ 'data' => array('data' => $dataProp, 'length' => strlen($dataProp)));
+ $dataSection_NumProps++;
+ }
+ // Keywords
+ if ($this->phpExcel->getProperties()->getKeywords()) {
+ $dataProp = $this->phpExcel->getProperties()->getKeywords();
+ $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x05),
+ 'offset' => array('pack' => 'V'),
+ 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length
+ 'data' => array('data' => $dataProp, 'length' => strlen($dataProp)));
+ $dataSection_NumProps++;
+ }
+ // Comments (Description)
+ if ($this->phpExcel->getProperties()->getDescription()) {
+ $dataProp = $this->phpExcel->getProperties()->getDescription();
+ $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x06),
+ 'offset' => array('pack' => 'V'),
+ 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length
+ 'data' => array('data' => $dataProp, 'length' => strlen($dataProp)));
+ $dataSection_NumProps++;
+ }
+ // Last Saved By (LastModifiedBy)
+ if ($this->phpExcel->getProperties()->getLastModifiedBy()) {
+ $dataProp = $this->phpExcel->getProperties()->getLastModifiedBy();
+ $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x08),
+ 'offset' => array('pack' => 'V'),
+ 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length
+ 'data' => array('data' => $dataProp, 'length' => strlen($dataProp)));
+ $dataSection_NumProps++;
+ }
+ // Created Date/Time
+ if ($this->phpExcel->getProperties()->getCreated()) {
+ $dataProp = $this->phpExcel->getProperties()->getCreated();
+ $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0C),
+ 'offset' => array('pack' => 'V'),
+ 'type' => array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)
+ 'data' => array('data' => PHPExcel_Shared_OLE::LocalDate2OLE($dataProp)));
+ $dataSection_NumProps++;
+ }
+ // Modified Date/Time
+ if ($this->phpExcel->getProperties()->getModified()) {
+ $dataProp = $this->phpExcel->getProperties()->getModified();
+ $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D),
+ 'offset' => array('pack' => 'V'),
+ 'type' => array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)
+ 'data' => array('data' => PHPExcel_Shared_OLE::LocalDate2OLE($dataProp)));
+ $dataSection_NumProps++;
+ }
+ // Security
+ $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x13),
+ 'offset' => array('pack' => 'V'),
+ 'type' => array('pack' => 'V', 'data' => 0x03), // 4 byte signed integer
+ 'data' => array('data' => 0x00));
+ $dataSection_NumProps++;
+
+
+ // 4 Section Length
+ // 4 Property count
+ // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4))
+ $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8;
+ foreach ($dataSection as $dataProp) {
+ // Summary
+ $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']);
+ // Offset
+ $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset);
+ // DataType
+ $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']);
+ // Data
+ if ($dataProp['type']['data'] == 0x02) { // 2 byte signed integer
+ $dataSection_Content .= pack('V', $dataProp['data']['data']);
+
+ $dataSection_Content_Offset += 4 + 4;
+ } elseif ($dataProp['type']['data'] == 0x03) { // 4 byte signed integer
+ $dataSection_Content .= pack('V', $dataProp['data']['data']);
+
+ $dataSection_Content_Offset += 4 + 4;
+ } elseif ($dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length
+ // Null-terminated string
+ $dataProp['data']['data'] .= chr(0);
+ $dataProp['data']['length'] += 1;
+ // Complete the string with null string for being a %4
+ $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4)==4 ? 0 : (4 - $dataProp['data']['length'] % 4));
+ $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT);
+
+ $dataSection_Content .= pack('V', $dataProp['data']['length']);
+ $dataSection_Content .= $dataProp['data']['data'];
+
+ $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']);
+ } elseif ($dataProp['type']['data'] == 0x40) { // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)
+ $dataSection_Content .= $dataProp['data']['data'];
+
+ $dataSection_Content_Offset += 4 + 8;
+ } else {
+ // Data Type Not Used at the moment
+ }
+ }
+ // Now $dataSection_Content_Offset contains the size of the content
+
+ // section header
+ // offset: $secOffset; size: 4; section length
+ // + x Size of the content (summary + content)
+ $data .= pack('V', $dataSection_Content_Offset);
+ // offset: $secOffset+4; size: 4; property count
+ $data .= pack('V', $dataSection_NumProps);
+ // Section Summary
+ $data .= $dataSection_Summary;
+ // Section Content
+ $data .= $dataSection_Content;
+
+ return $data;
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php
new file mode 100755
index 000000000..a79575239
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php
@@ -0,0 +1,246 @@
+
+// *
+// * The majority of this is _NOT_ my code. I simply ported it from the
+// * PERL Spreadsheet::WriteExcel module.
+// *
+// * The author of the Spreadsheet::WriteExcel module is John McNamara
+// * ';
+ for ($col = 'A'; $col != $colMax; ++$col) {
+ $html .= ' ';
+ }
+ return $html;
+ }
+
+
+ /**
+ * Generate image tag in cell
+ *
+ * @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet
+ * @param string $coordinates Cell coordinates
+ * @return string
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeImageInCell(PHPExcel_Worksheet $pSheet, $coordinates)
+ {
+ // Construct HTML
+ $html = '';
+
+ // Write images
+ foreach ($pSheet->getDrawingCollection() as $drawing) {
+ if ($drawing instanceof PHPExcel_Worksheet_Drawing) {
+ if ($drawing->getCoordinates() == $coordinates) {
+ $filename = $drawing->getPath();
+
+ // Strip off eventual '.'
+ if (substr($filename, 0, 1) == '.') {
+ $filename = substr($filename, 1);
+ }
+
+ // Prepend images root
+ $filename = $this->getImagesRoot() . $filename;
+
+ // Strip off eventual '.'
+ if (substr($filename, 0, 1) == '.' && substr($filename, 0, 2) != './') {
+ $filename = substr($filename, 1);
+ }
+
+ // Convert UTF8 data to PCDATA
+ $filename = htmlspecialchars($filename);
+
+ $html .= PHP_EOL;
+ if ((!$this->embedImages) || ($this->isPdf)) {
+ $imageData = $filename;
+ } else {
+ $imageDetails = getimagesize($filename);
+ if ($fp = fopen($filename, "rb", 0)) {
+ $picture = fread($fp, filesize($filename));
+ fclose($fp);
+ // base64 encode the binary data, then break it
+ // into chunks according to RFC 2045 semantics
+ $base64 = chunk_split(base64_encode($picture));
+ $imageData = 'data:'.$imageDetails['mime'].';base64,' . $base64;
+ } else {
+ $imageData = $filename;
+ }
+ }
+
+ $html .= '';
+ $html .= $this->writeImageInCell($pSheet, $col.$row);
+ if ($this->includeCharts) {
+ $html .= $this->writeChartInCell($pSheet, $col.$row);
+ }
+ $html .= ' ';
+ }
+ ++$row;
+ $html .= '';
+ $html .= '
';
+ }
+ }
+
+ return $html;
+ }
+
+ /**
+ * Generate chart tag in cell
+ *
+ * @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet
+ * @param string $coordinates Cell coordinates
+ * @return string
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeChartInCell(PHPExcel_Worksheet $pSheet, $coordinates)
+ {
+ // Construct HTML
+ $html = '';
+
+ // Write charts
+ foreach ($pSheet->getChartCollection() as $chart) {
+ if ($chart instanceof PHPExcel_Chart) {
+ $chartCoordinates = $chart->getTopLeftPosition();
+ if ($chartCoordinates['cell'] == $coordinates) {
+ $chartFileName = PHPExcel_Shared_File::sys_get_temp_dir().'/'.uniqid().'.png';
+ if (!$chart->render($chartFileName)) {
+ return;
+ }
+
+ $html .= PHP_EOL;
+ $imageDetails = getimagesize($chartFileName);
+ if ($fp = fopen($chartFileName, "rb", 0)) {
+ $picture = fread($fp, filesize($chartFileName));
+ fclose($fp);
+ // base64 encode the binary data, then break it
+ // into chunks according to RFC 2045 semantics
+ $base64 = chunk_split(base64_encode($picture));
+ $imageData = 'data:'.$imageDetails['mime'].';base64,' . $base64;
+
+ $html .= '
' . PHP_EOL;
+ $html .= '
' . PHP_EOL;
+ } else {
+ $style = isset($this->cssStyles['table']) ?
+ $this->assembleCSS($this->cssStyles['table']) : '';
+
+ if ($this->isPdf && $pSheet->getShowGridlines()) {
+ $html .= '
' . PHP_EOL;
+ } else {
+ $html .= '
+ $html .= $this->generateTableFooter();
+
+ // insert page break
+ $html .= '';
+
+ // open table again: ' . PHP_EOL;
+ }
+ }
+
+ // Write
' . PHP_EOL;
+
+ return $html;
+ }
+
+ /**
+ * Generate row
+ *
+ * @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet
+ * @param array $pValues Array containing cells in a row
+ * @param int $pRow Row number (0-based)
+ * @return string
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow = 0, $cellType = 'td')
+ {
+ if (is_array($pValues)) {
+ // Construct HTML
+ $html = '';
+
+ // Sheet index
+ $sheetIndex = $pSheet->getParent()->getIndex($pSheet);
+
+ // DomPDF and breaks
+ if ($this->isPdf && count($pSheet->getBreaks()) > 0) {
+ $breaks = $pSheet->getBreaks();
+
+ // check if a break is needed before this row
+ if (isset($breaks['A' . $pRow])) {
+ // close table: +
' . PHP_EOL;
+ } else {
+ $style = isset($this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow])
+ ? $this->assembleCSS($this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]) : '';
+
+ $html .= ' ' . PHP_EOL;
+ }
+
+ // Write cells
+ $colNum = 0;
+ foreach ($pValues as $cellAddress) {
+ $cell = ($cellAddress > '') ? $pSheet->getCell($cellAddress) : '';
+ $coordinate = PHPExcel_Cell::stringFromColumnIndex($colNum) . ($pRow + 1);
+ if (!$this->useInlineCss) {
+ $cssClass = '';
+ $cssClass = 'column' . $colNum;
+ } else {
+ $cssClass = array();
+ if ($cellType == 'th') {
+ if (isset($this->cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum])) {
+ $this->cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum];
+ }
+ } else {
+ if (isset($this->cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum])) {
+ $this->cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum];
+ }
+ }
+ }
+ $colSpan = 1;
+ $rowSpan = 1;
+
+ // initialize
+ $cellData = ' ';
+
+ // PHPExcel_Cell
+ if ($cell instanceof PHPExcel_Cell) {
+ $cellData = '';
+ if (is_null($cell->getParent())) {
+ $cell->attach($pSheet);
+ }
+ // Value
+ if ($cell->getValue() instanceof PHPExcel_RichText) {
+ // Loop through rich text elements
+ $elements = $cell->getValue()->getRichTextElements();
+ foreach ($elements as $element) {
+ // Rich text start?
+ if ($element instanceof PHPExcel_RichText_Run) {
+ $cellData .= '';
+
+ if ($element->getFont()->getSuperScript()) {
+ $cellData .= '';
+ } elseif ($element->getFont()->getSubScript()) {
+ $cellData .= '';
+ }
+ }
+
+ // Convert UTF8 data to PCDATA
+ $cellText = $element->getText();
+ $cellData .= htmlspecialchars($cellText);
+
+ if ($element instanceof PHPExcel_RichText_Run) {
+ if ($element->getFont()->getSuperScript()) {
+ $cellData .= '';
+ } elseif ($element->getFont()->getSubScript()) {
+ $cellData .= '';
+ }
+
+ $cellData .= '';
+ }
+ }
+ } else {
+ if ($this->preCalculateFormulas) {
+ $cellData = PHPExcel_Style_NumberFormat::toFormattedString(
+ $cell->getCalculatedValue(),
+ $pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode(),
+ array($this, 'formatColor')
+ );
+ } else {
+ $cellData = PHPExcel_Style_NumberFormat::toFormattedString(
+ $cell->getValue(),
+ $pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode(),
+ array($this, 'formatColor')
+ );
+ }
+ $cellData = htmlspecialchars($cellData);
+ if ($pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont()->getSuperScript()) {
+ $cellData = ''.$cellData.'';
+ } elseif ($pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont()->getSubScript()) {
+ $cellData = ''.$cellData.'';
+ }
+ }
+
+ // Converts the cell content so that spaces occuring at beginning of each new line are replaced by
+ // Example: " Hello\n to the world" is converted to " Hello\n to the world"
+ $cellData = preg_replace("/(?m)(?:^|\\G) /", ' ', $cellData);
+
+ // convert newline "\n" to '
'
+ $cellData = nl2br($cellData);
+
+ // Extend CSS class?
+ if (!$this->useInlineCss) {
+ $cssClass .= ' style' . $cell->getXfIndex();
+ $cssClass .= ' ' . $cell->getDataType();
+ } else {
+ if ($cellType == 'th') {
+ if (isset($this->cssStyles['th.style' . $cell->getXfIndex()])) {
+ $cssClass = array_merge($cssClass, $this->cssStyles['th.style' . $cell->getXfIndex()]);
+ }
+ } else {
+ if (isset($this->cssStyles['td.style' . $cell->getXfIndex()])) {
+ $cssClass = array_merge($cssClass, $this->cssStyles['td.style' . $cell->getXfIndex()]);
+ }
+ }
+
+ // General horizontal alignment: Actual horizontal alignment depends on dataType
+ $sharedStyle = $pSheet->getParent()->getCellXfByIndex($cell->getXfIndex());
+ if ($sharedStyle->getAlignment()->getHorizontal() == PHPExcel_Style_Alignment::HORIZONTAL_GENERAL
+ && isset($this->cssStyles['.' . $cell->getDataType()]['text-align'])) {
+ $cssClass['text-align'] = $this->cssStyles['.' . $cell->getDataType()]['text-align'];
+ }
+ }
+ }
+
+ // Hyperlink?
+ if ($pSheet->hyperlinkExists($coordinate) && !$pSheet->getHyperlink($coordinate)->isInternal()) {
+ $cellData = '' . $cellData . '';
+ }
+
+ // Should the cell be written or is it swallowed by a rowspan or colspan?
+ $writeCell = !(isset($this->isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum])
+ && $this->isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]);
+
+ // Colspan and Rowspan
+ $colspan = 1;
+ $rowspan = 1;
+ if (isset($this->isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum])) {
+ $spans = $this->isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum];
+ $rowSpan = $spans['rowspan'];
+ $colSpan = $spans['colspan'];
+
+ // Also apply style from last cell in merge to fix borders -
+ // relies on !important for non-none border declarations in createCSSStyleBorder
+ $endCellCoord = PHPExcel_Cell::stringFromColumnIndex($colNum + $colSpan - 1) . ($pRow + $rowSpan);
+ if (!$this->useInlineCss) {
+ $cssClass .= ' style' . $pSheet->getCell($endCellCoord)->getXfIndex();
+ }
+ }
+
+ // Write
+ if ($writeCell) {
+ // Column start
+ $html .= ' <' . $cellType;
+ if (!$this->useInlineCss) {
+ $html .= ' class="' . $cssClass . '"';
+ } else {
+ //** Necessary redundant code for the sake of PHPExcel_Writer_PDF **
+ // We must explicitly write the width of the element because TCPDF
+ // does not recognize e.g. element because TCPDF
+ // does not recognize e.g.
+ if (isset($this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height'])) {
+ $height = $this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height'];
+ $cssClass['height'] = $height;
+ }
+ //** end of redundant code **
+
+ $html .= ' style="' . $this->assembleCSS($cssClass) . '"';
+ }
+ if ($colSpan > 1) {
+ $html .= ' colspan="' . $colSpan . '"';
+ }
+ if ($rowSpan > 1) {
+ $html .= ' rowspan="' . $rowSpan . '"';
+ }
+ $html .= '>';
+
+ // Image?
+ $html .= $this->writeImageInCell($pSheet, $coordinate);
+
+ // Chart?
+ if ($this->includeCharts) {
+ $html .= $this->writeChartInCell($pSheet, $coordinate);
+ }
+
+ // Cell data
+ $html .= $cellData;
+
+ // Column end
+ $html .= ''.$cellType.'>' . PHP_EOL;
+ }
+
+ // Next column
+ ++$colNum;
+ }
+
+ // Write row end
+ $html .= ' ' . PHP_EOL;
+
+ // Return
+ return $html;
+ } else {
+ throw new PHPExcel_Writer_Exception("Invalid parameters passed.");
+ }
+ }
+
+ /**
+ * Takes array where of CSS properties / values and converts to CSS string
+ *
+ * @param array
+ * @return string
+ */
+ private function assembleCSS($pValue = array())
+ {
+ $pairs = array();
+ foreach ($pValue as $property => $value) {
+ $pairs[] = $property . ':' . $value;
+ }
+ $string = implode('; ', $pairs);
+
+ return $string;
+ }
+
+ /**
+ * Get images root
+ *
+ * @return string
+ */
+ public function getImagesRoot()
+ {
+ return $this->imagesRoot;
+ }
+
+ /**
+ * Set images root
+ *
+ * @param string $pValue
+ * @return PHPExcel_Writer_HTML
+ */
+ public function setImagesRoot($pValue = '.')
+ {
+ $this->imagesRoot = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get embed images
+ *
+ * @return boolean
+ */
+ public function getEmbedImages()
+ {
+ return $this->embedImages;
+ }
+
+ /**
+ * Set embed images
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Writer_HTML
+ */
+ public function setEmbedImages($pValue = '.')
+ {
+ $this->embedImages = $pValue;
+ return $this;
+ }
+
+ /**
+ * Get use inline CSS?
+ *
+ * @return boolean
+ */
+ public function getUseInlineCss()
+ {
+ return $this->useInlineCss;
+ }
+
+ /**
+ * Set use inline CSS?
+ *
+ * @param boolean $pValue
+ * @return PHPExcel_Writer_HTML
+ */
+ public function setUseInlineCss($pValue = false)
+ {
+ $this->useInlineCss = $pValue;
+ return $this;
+ }
+
+ /**
+ * Add color to formatted string as inline style
+ *
+ * @param string $pValue Plain formatted value without color
+ * @param string $pFormat Format code
+ * @return string
+ */
+ public function formatColor($pValue, $pFormat)
+ {
+ // Color information, e.g. [Red] is always at the beginning
+ $color = null; // initialize
+ $matches = array();
+
+ $color_regex = '/^\\[[a-zA-Z]+\\]/';
+ if (preg_match($color_regex, $pFormat, $matches)) {
+ $color = str_replace('[', '', $matches[0]);
+ $color = str_replace(']', '', $color);
+ $color = strtolower($color);
+ }
+
+ // convert to PCDATA
+ $value = htmlspecialchars($pValue);
+
+ // color span tag
+ if ($color !== null) {
+ $value = '' . $value . '';
+ }
+
+ return $value;
+ }
+
+ /**
+ * Calculate information about HTML colspan and rowspan which is not always the same as Excel's
+ */
+ private function calculateSpans()
+ {
+ // Identify all cells that should be omitted in HTML due to cell merge.
+ // In HTML only the upper-left cell should be written and it should have
+ // appropriate rowspan / colspan attribute
+ $sheetIndexes = $this->sheetIndex !== null ?
+ array($this->sheetIndex) : range(0, $this->phpExcel->getSheetCount() - 1);
+
+ foreach ($sheetIndexes as $sheetIndex) {
+ $sheet = $this->phpExcel->getSheet($sheetIndex);
+
+ $candidateSpannedRow = array();
+
+ // loop through all Excel merged cells
+ foreach ($sheet->getMergeCells() as $cells) {
+ list($cells,) = PHPExcel_Cell::splitRange($cells);
+ $first = $cells[0];
+ $last = $cells[1];
+
+ list($fc, $fr) = PHPExcel_Cell::coordinateFromString($first);
+ $fc = PHPExcel_Cell::columnIndexFromString($fc) - 1;
+
+ list($lc, $lr) = PHPExcel_Cell::coordinateFromString($last);
+ $lc = PHPExcel_Cell::columnIndexFromString($lc) - 1;
+
+ // loop through the individual cells in the individual merge
+ $r = $fr - 1;
+ while ($r++ < $lr) {
+ // also, flag this row as a HTML row that is candidate to be omitted
+ $candidateSpannedRow[$r] = $r;
+
+ $c = $fc - 1;
+ while ($c++ < $lc) {
+ if (!($c == $fc && $r == $fr)) {
+ // not the upper-left cell (should not be written in HTML)
+ $this->isSpannedCell[$sheetIndex][$r][$c] = array(
+ 'baseCell' => array($fr, $fc),
+ );
+ } else {
+ // upper-left is the base cell that should hold the colspan/rowspan attribute
+ $this->isBaseCell[$sheetIndex][$r][$c] = array(
+ 'xlrowspan' => $lr - $fr + 1, // Excel rowspan
+ 'rowspan' => $lr - $fr + 1, // HTML rowspan, value may change
+ 'xlcolspan' => $lc - $fc + 1, // Excel colspan
+ 'colspan' => $lc - $fc + 1, // HTML colspan, value may change
+ );
+ }
+ }
+ }
+ }
+
+ // Identify which rows should be omitted in HTML. These are the rows where all the cells
+ // participate in a merge and the where base cells are somewhere above.
+ $countColumns = PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn());
+ foreach ($candidateSpannedRow as $rowIndex) {
+ if (isset($this->isSpannedCell[$sheetIndex][$rowIndex])) {
+ if (count($this->isSpannedCell[$sheetIndex][$rowIndex]) == $countColumns) {
+ $this->isSpannedRow[$sheetIndex][$rowIndex] = $rowIndex;
+ };
+ }
+ }
+
+ // For each of the omitted rows we found above, the affected rowspans should be subtracted by 1
+ if (isset($this->isSpannedRow[$sheetIndex])) {
+ foreach ($this->isSpannedRow[$sheetIndex] as $rowIndex) {
+ $adjustedBaseCells = array();
+ $c = -1;
+ $e = $countColumns - 1;
+ while ($c++ < $e) {
+ $baseCell = $this->isSpannedCell[$sheetIndex][$rowIndex][$c]['baseCell'];
+
+ if (!in_array($baseCell, $adjustedBaseCells)) {
+ // subtract rowspan by 1
+ --$this->isBaseCell[$sheetIndex][ $baseCell[0] ][ $baseCell[1] ]['rowspan'];
+ $adjustedBaseCells[] = $baseCell;
+ }
+ }
+ }
+ }
+
+ // TODO: Same for columns
+ }
+
+ // We have calculated the spans
+ $this->spansAreCalculated = true;
+ }
+
+ private function setMargins(PHPExcel_Worksheet $pSheet)
+ {
+ $htmlPage = '@page { ';
+ $htmlBody = 'body { ';
+
+ $left = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft()) . 'in; ';
+ $htmlPage .= 'margin-left: ' . $left;
+ $htmlBody .= 'margin-left: ' . $left;
+ $right = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight()) . 'in; ';
+ $htmlPage .= 'margin-right: ' . $right;
+ $htmlBody .= 'margin-right: ' . $right;
+ $top = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop()) . 'in; ';
+ $htmlPage .= 'margin-top: ' . $top;
+ $htmlBody .= 'margin-top: ' . $top;
+ $bottom = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom()) . 'in; ';
+ $htmlPage .= 'margin-bottom: ' . $bottom;
+ $htmlBody .= 'margin-bottom: ' . $bottom;
+
+ $htmlPage .= "}\n";
+ $htmlBody .= "}\n";
+
+ return "\n";
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/IWriter.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/IWriter.php
new file mode 100755
index 000000000..c7cfe7405
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/IWriter.php
@@ -0,0 +1,37 @@
+setPHPExcel($pPHPExcel);
+
+ $writerPartsArray = array(
+ 'content' => 'PHPExcel_Writer_OpenDocument_Content',
+ 'meta' => 'PHPExcel_Writer_OpenDocument_Meta',
+ 'meta_inf' => 'PHPExcel_Writer_OpenDocument_MetaInf',
+ 'mimetype' => 'PHPExcel_Writer_OpenDocument_Mimetype',
+ 'settings' => 'PHPExcel_Writer_OpenDocument_Settings',
+ 'styles' => 'PHPExcel_Writer_OpenDocument_Styles',
+ 'thumbnails' => 'PHPExcel_Writer_OpenDocument_Thumbnails'
+ );
+
+ foreach ($writerPartsArray as $writer => $class) {
+ $this->writerParts[$writer] = new $class($this);
+ }
+ }
+
+ /**
+ * Get writer part
+ *
+ * @param string $pPartName Writer part name
+ * @return PHPExcel_Writer_Excel2007_WriterPart
+ */
+ public function getWriterPart($pPartName = '')
+ {
+ if ($pPartName != '' && isset($this->writerParts[strtolower($pPartName)])) {
+ return $this->writerParts[strtolower($pPartName)];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Save PHPExcel to file
+ *
+ * @param string $pFilename
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function save($pFilename = null)
+ {
+ if (!$this->spreadSheet) {
+ throw new PHPExcel_Writer_Exception('PHPExcel object unassigned.');
+ }
+
+ // garbage collect
+ $this->spreadSheet->garbageCollect();
+
+ // If $pFilename is php://output or php://stdout, make it a temporary file...
+ $originalFilename = $pFilename;
+ if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
+ $pFilename = @tempnam(PHPExcel_Shared_File::sys_get_temp_dir(), 'phpxltmp');
+ if ($pFilename == '') {
+ $pFilename = $originalFilename;
+ }
+ }
+
+ $objZip = $this->createZip($pFilename);
+
+ $objZip->addFromString('META-INF/manifest.xml', $this->getWriterPart('meta_inf')->writeManifest());
+ $objZip->addFromString('Thumbnails/thumbnail.png', $this->getWriterPart('thumbnails')->writeThumbnail());
+ $objZip->addFromString('content.xml', $this->getWriterPart('content')->write());
+ $objZip->addFromString('meta.xml', $this->getWriterPart('meta')->write());
+ $objZip->addFromString('mimetype', $this->getWriterPart('mimetype')->write());
+ $objZip->addFromString('settings.xml', $this->getWriterPart('settings')->write());
+ $objZip->addFromString('styles.xml', $this->getWriterPart('styles')->write());
+
+ // Close file
+ if ($objZip->close() === false) {
+ throw new PHPExcel_Writer_Exception("Could not close zip file $pFilename.");
+ }
+
+ // If a temporary file was used, copy it to the correct file stream
+ if ($originalFilename != $pFilename) {
+ if (copy($pFilename, $originalFilename) === false) {
+ throw new PHPExcel_Writer_Exception("Could not copy temporary zip file $pFilename to $originalFilename.");
+ }
+ @unlink($pFilename);
+ }
+ }
+
+ /**
+ * Create zip object
+ *
+ * @param string $pFilename
+ * @throws PHPExcel_Writer_Exception
+ * @return ZipArchive
+ */
+ private function createZip($pFilename)
+ {
+ // Create new ZIP file and open it for writing
+ $zipClass = PHPExcel_Settings::getZipClass();
+ $objZip = new $zipClass();
+
+ // Retrieve OVERWRITE and CREATE constants from the instantiated zip class
+ // This method of accessing constant values from a dynamic class should work with all appropriate versions of PHP
+ $ro = new ReflectionObject($objZip);
+ $zipOverWrite = $ro->getConstant('OVERWRITE');
+ $zipCreate = $ro->getConstant('CREATE');
+
+ if (file_exists($pFilename)) {
+ unlink($pFilename);
+ }
+ // Try opening the ZIP file
+ if ($objZip->open($pFilename, $zipOverWrite) !== true) {
+ if ($objZip->open($pFilename, $zipCreate) !== true) {
+ throw new PHPExcel_Writer_Exception("Could not open $pFilename for writing.");
+ }
+ }
+
+ return $objZip;
+ }
+
+ /**
+ * Get PHPExcel object
+ *
+ * @return PHPExcel
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function getPHPExcel()
+ {
+ if ($this->spreadSheet !== null) {
+ return $this->spreadSheet;
+ } else {
+ throw new PHPExcel_Writer_Exception('No PHPExcel assigned.');
+ }
+ }
+
+ /**
+ * Set PHPExcel object
+ *
+ * @param PHPExcel $pPHPExcel PHPExcel object
+ * @throws PHPExcel_Writer_Exception
+ * @return PHPExcel_Writer_Excel2007
+ */
+ public function setPHPExcel(PHPExcel $pPHPExcel = null)
+ {
+ $this->spreadSheet = $pPHPExcel;
+ return $this;
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/OpenDocument/Cell/Comment.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/OpenDocument/Cell/Comment.php
new file mode 100755
index 000000000..f1e98a16e
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/OpenDocument/Cell/Comment.php
@@ -0,0 +1,63 @@
+
+ */
+class PHPExcel_Writer_OpenDocument_Cell_Comment
+{
+ public static function write(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Cell $cell)
+ {
+ $comments = $cell->getWorksheet()->getComments();
+ if (!isset($comments[$cell->getCoordinate()])) {
+ return;
+ }
+ $comment = $comments[$cell->getCoordinate()];
+
+ $objWriter->startElement('office:annotation');
+ //$objWriter->writeAttribute('draw:style-name', 'gr1');
+ //$objWriter->writeAttribute('draw:text-style-name', 'P1');
+ $objWriter->writeAttribute('svg:width', $comment->getWidth());
+ $objWriter->writeAttribute('svg:height', $comment->getHeight());
+ $objWriter->writeAttribute('svg:x', $comment->getMarginLeft());
+ $objWriter->writeAttribute('svg:y', $comment->getMarginTop());
+ //$objWriter->writeAttribute('draw:caption-point-x', $comment->getMarginLeft());
+ //$objWriter->writeAttribute('draw:caption-point-y', $comment->getMarginTop());
+ $objWriter->writeElement('dc:creator', $comment->getAuthor());
+ // TODO: Not realized in PHPExcel_Comment yet.
+ //$objWriter->writeElement('dc:date', $comment->getDate());
+ $objWriter->writeElement('text:p', $comment->getText()->getPlainText());
+ //$objWriter->writeAttribute('draw:text-style-name', 'P1');
+ $objWriter->endElement();
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/OpenDocument/Content.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/OpenDocument/Content.php
new file mode 100755
index 000000000..a34b1670c
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/OpenDocument/Content.php
@@ -0,0 +1,272 @@
+
+ */
+class PHPExcel_Writer_OpenDocument_Content extends PHPExcel_Writer_OpenDocument_WriterPart
+{
+ const NUMBER_COLS_REPEATED_MAX = 1024;
+ const NUMBER_ROWS_REPEATED_MAX = 1048576;
+
+ /**
+ * Write content.xml to XML format
+ *
+ * @param PHPExcel $pPHPExcel
+ * @return string XML Output
+ * @throws PHPExcel_Writer_Exception
+ */
+ public function write(PHPExcel $pPHPExcel = null)
+ {
+ if (!$pPHPExcel) {
+ $pPHPExcel = $this->getParentWriter()->getPHPExcel(); /* @var $pPHPExcel PHPExcel */
+ }
+
+ $objWriter = null;
+ if ($this->getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8');
+
+ // Content
+ $objWriter->startElement('office:document-content');
+ $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0');
+ $objWriter->writeAttribute('xmlns:style', 'urn:oasis:names:tc:opendocument:xmlns:style:1.0');
+ $objWriter->writeAttribute('xmlns:text', 'urn:oasis:names:tc:opendocument:xmlns:text:1.0');
+ $objWriter->writeAttribute('xmlns:table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0');
+ $objWriter->writeAttribute('xmlns:draw', 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0');
+ $objWriter->writeAttribute('xmlns:fo', 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0');
+ $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+ $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');
+ $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0');
+ $objWriter->writeAttribute('xmlns:number', 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0');
+ $objWriter->writeAttribute('xmlns:presentation', 'urn:oasis:names:tc:opendocument:xmlns:presentation:1.0');
+ $objWriter->writeAttribute('xmlns:svg', 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0');
+ $objWriter->writeAttribute('xmlns:chart', 'urn:oasis:names:tc:opendocument:xmlns:chart:1.0');
+ $objWriter->writeAttribute('xmlns:dr3d', 'urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0');
+ $objWriter->writeAttribute('xmlns:math', 'http://www.w3.org/1998/Math/MathML');
+ $objWriter->writeAttribute('xmlns:form', 'urn:oasis:names:tc:opendocument:xmlns:form:1.0');
+ $objWriter->writeAttribute('xmlns:script', 'urn:oasis:names:tc:opendocument:xmlns:script:1.0');
+ $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office');
+ $objWriter->writeAttribute('xmlns:ooow', 'http://openoffice.org/2004/writer');
+ $objWriter->writeAttribute('xmlns:oooc', 'http://openoffice.org/2004/calc');
+ $objWriter->writeAttribute('xmlns:dom', 'http://www.w3.org/2001/xml-events');
+ $objWriter->writeAttribute('xmlns:xforms', 'http://www.w3.org/2002/xforms');
+ $objWriter->writeAttribute('xmlns:xsd', 'http://www.w3.org/2001/XMLSchema');
+ $objWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
+ $objWriter->writeAttribute('xmlns:rpt', 'http://openoffice.org/2005/report');
+ $objWriter->writeAttribute('xmlns:of', 'urn:oasis:names:tc:opendocument:xmlns:of:1.2');
+ $objWriter->writeAttribute('xmlns:xhtml', 'http://www.w3.org/1999/xhtml');
+ $objWriter->writeAttribute('xmlns:grddl', 'http://www.w3.org/2003/g/data-view#');
+ $objWriter->writeAttribute('xmlns:tableooo', 'http://openoffice.org/2009/table');
+ $objWriter->writeAttribute('xmlns:field', 'urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0');
+ $objWriter->writeAttribute('xmlns:formx', 'urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0');
+ $objWriter->writeAttribute('xmlns:css3t', 'http://www.w3.org/TR/css3-text/');
+ $objWriter->writeAttribute('office:version', '1.2');
+
+ $objWriter->writeElement('office:scripts');
+ $objWriter->writeElement('office:font-face-decls');
+ $objWriter->writeElement('office:automatic-styles');
+
+ $objWriter->startElement('office:body');
+ $objWriter->startElement('office:spreadsheet');
+ $objWriter->writeElement('table:calculation-settings');
+ $this->writeSheets($objWriter);
+ $objWriter->writeElement('table:named-expressions');
+ $objWriter->endElement();
+ $objWriter->endElement();
+ $objWriter->endElement();
+
+ return $objWriter->getData();
+ }
+
+ /**
+ * Write sheets
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter
+ */
+ private function writeSheets(PHPExcel_Shared_XMLWriter $objWriter)
+ {
+ $pPHPExcel = $this->getParentWriter()->getPHPExcel(); /* @var $pPHPExcel PHPExcel */
+
+ $sheet_count = $pPHPExcel->getSheetCount();
+ for ($i = 0; $i < $sheet_count; $i++) {
+ //$this->getWriterPart('Worksheet')->writeWorksheet());
+ $objWriter->startElement('table:table');
+ $objWriter->writeAttribute('table:name', $pPHPExcel->getSheet($i)->getTitle());
+ $objWriter->writeElement('office:forms');
+ $objWriter->startElement('table:table-column');
+ $objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX);
+ $objWriter->endElement();
+ $this->writeRows($objWriter, $pPHPExcel->getSheet($i));
+ $objWriter->endElement();
+ }
+ }
+
+ /**
+ * Write rows of the specified sheet
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter
+ * @param PHPExcel_Worksheet $sheet
+ */
+ private function writeRows(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Worksheet $sheet)
+ {
+ $number_rows_repeated = self::NUMBER_ROWS_REPEATED_MAX;
+ $span_row = 0;
+ $rows = $sheet->getRowIterator();
+ while ($rows->valid()) {
+ $number_rows_repeated--;
+ $row = $rows->current();
+ if ($row->getCellIterator()->valid()) {
+ if ($span_row) {
+ $objWriter->startElement('table:table-row');
+ if ($span_row > 1) {
+ $objWriter->writeAttribute('table:number-rows-repeated', $span_row);
+ }
+ $objWriter->startElement('table:table-cell');
+ $objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX);
+ $objWriter->endElement();
+ $objWriter->endElement();
+ $span_row = 0;
+ }
+ $objWriter->startElement('table:table-row');
+ $this->writeCells($objWriter, $row);
+ $objWriter->endElement();
+ } else {
+ $span_row++;
+ }
+ $rows->next();
+ }
+ }
+
+ /**
+ * Write cells of the specified row
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter
+ * @param PHPExcel_Worksheet_Row $row
+ * @throws PHPExcel_Writer_Exception
+ */
+ private function writeCells(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Worksheet_Row $row)
+ {
+ $number_cols_repeated = self::NUMBER_COLS_REPEATED_MAX;
+ $prev_column = -1;
+ $cells = $row->getCellIterator();
+ while ($cells->valid()) {
+ $cell = $cells->current();
+ $column = PHPExcel_Cell::columnIndexFromString($cell->getColumn()) - 1;
+
+ $this->writeCellSpan($objWriter, $column, $prev_column);
+ $objWriter->startElement('table:table-cell');
+
+ switch ($cell->getDataType()) {
+ case PHPExcel_Cell_DataType::TYPE_BOOL:
+ $objWriter->writeAttribute('office:value-type', 'boolean');
+ $objWriter->writeAttribute('office:value', $cell->getValue());
+ $objWriter->writeElement('text:p', $cell->getValue());
+ break;
+
+ case PHPExcel_Cell_DataType::TYPE_ERROR:
+ throw new PHPExcel_Writer_Exception('Writing of error not implemented yet.');
+ break;
+
+ case PHPExcel_Cell_DataType::TYPE_FORMULA:
+ try {
+ $formula_value = $cell->getCalculatedValue();
+ } catch (Exception $e) {
+ $formula_value = $cell->getValue();
+ }
+ $objWriter->writeAttribute('table:formula', 'of:' . $cell->getValue());
+ if (is_numeric($formula_value)) {
+ $objWriter->writeAttribute('office:value-type', 'float');
+ } else {
+ $objWriter->writeAttribute('office:value-type', 'string');
+ }
+ $objWriter->writeAttribute('office:value', $formula_value);
+ $objWriter->writeElement('text:p', $formula_value);
+ break;
+
+ case PHPExcel_Cell_DataType::TYPE_INLINE:
+ throw new PHPExcel_Writer_Exception('Writing of inline not implemented yet.');
+ break;
+
+ case PHPExcel_Cell_DataType::TYPE_NUMERIC:
+ $objWriter->writeAttribute('office:value-type', 'float');
+ $objWriter->writeAttribute('office:value', $cell->getValue());
+ $objWriter->writeElement('text:p', $cell->getValue());
+ break;
+
+ case PHPExcel_Cell_DataType::TYPE_STRING:
+ $objWriter->writeAttribute('office:value-type', 'string');
+ $objWriter->writeElement('text:p', $cell->getValue());
+ break;
+ }
+ PHPExcel_Writer_OpenDocument_Cell_Comment::write($objWriter, $cell);
+ $objWriter->endElement();
+ $prev_column = $column;
+ $cells->next();
+ }
+ $number_cols_repeated = $number_cols_repeated - $prev_column - 1;
+ if ($number_cols_repeated > 0) {
+ if ($number_cols_repeated > 1) {
+ $objWriter->startElement('table:table-cell');
+ $objWriter->writeAttribute('table:number-columns-repeated', $number_cols_repeated);
+ $objWriter->endElement();
+ } else {
+ $objWriter->writeElement('table:table-cell');
+ }
+ }
+ }
+
+ /**
+ * Write span
+ *
+ * @param PHPExcel_Shared_XMLWriter $objWriter
+ * @param integer $curColumn
+ * @param integer $prevColumn
+ */
+ private function writeCellSpan(PHPExcel_Shared_XMLWriter $objWriter, $curColumn, $prevColumn)
+ {
+ $diff = $curColumn - $prevColumn - 1;
+ if (1 === $diff) {
+ $objWriter->writeElement('table:table-cell');
+ } elseif ($diff > 1) {
+ $objWriter->startElement('table:table-cell');
+ $objWriter->writeAttribute('table:number-columns-repeated', $diff);
+ $objWriter->endElement();
+ }
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/OpenDocument/Meta.php b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/OpenDocument/Meta.php
new file mode 100755
index 000000000..1a5c5fd0b
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/OpenDocument/Meta.php
@@ -0,0 +1,95 @@
+getParentWriter()->getPHPExcel();
+ }
+
+ $objWriter = null;
+ if ($this->getParentWriter()->getUseDiskCaching()) {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
+ } else {
+ $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
+ }
+
+ // XML header
+ $objWriter->startDocument('1.0', 'UTF-8');
+
+ // Meta
+ $objWriter->startElement('office:document-meta');
+
+ $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0');
+ $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+ $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');
+ $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0');
+ $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office');
+ $objWriter->writeAttribute('xmlns:grddl', 'http://www.w3.org/2003/g/data-view#');
+ $objWriter->writeAttribute('office:version', '1.2');
+
+ $objWriter->startElement('office:meta');
+
+ $objWriter->writeElement('meta:initial-creator', $pPHPExcel->getProperties()->getCreator());
+ $objWriter->writeElement('dc:creator', $pPHPExcel->getProperties()->getCreator());
+ $objWriter->writeElement('meta:creation-date', date(DATE_W3C, $pPHPExcel->getProperties()->getCreated()));
+ $objWriter->writeElement('dc:date', date(DATE_W3C, $pPHPExcel->getProperties()->getCreated()));
+ $objWriter->writeElement('dc:title', $pPHPExcel->getProperties()->getTitle());
+ $objWriter->writeElement('dc:description', $pPHPExcel->getProperties()->getDescription());
+ $objWriter->writeElement('dc:subject', $pPHPExcel->getProperties()->getSubject());
+ $keywords = explode(' ', $pPHPExcel->getProperties()->getKeywords());
+ foreach ($keywords as $keyword) {
+ $objWriter->writeElement('meta:keyword', $keyword);
+ }
+
+ //DAVERAGE
+Returns the average of selected database entries.
+getActiveSheet();
+
+// Add some data
+$database = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ),
+ array( 'Apple', 18, 20, 14, 105.00 ),
+ array( 'Pear', 12, 12, 10, 96.00 ),
+ array( 'Cherry', 13, 14, 9, 105.00 ),
+ array( 'Apple', 14, 15, 10, 75.00 ),
+ array( 'Pear', 9, 8, 8, 76.80 ),
+ array( 'Apple', 8, 9, 6, 45.00 ),
+ );
+$criteria = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ),
+ array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ),
+ array( '="=Pear"', NULL, NULL, NULL, NULL, NULL )
+ );
+
+$worksheet->fromArray( $criteria, NULL, 'A1' );
+$worksheet->fromArray( $database, NULL, 'A4' );
+
+$worksheet->setCellValue('A12', 'The Average yield of Apple trees over 10\' in height');
+$worksheet->setCellValue('B12', '=DAVERAGE(A4:E10,"Yield",A1:B2)');
+
+$worksheet->setCellValue('A13', 'The Average age of all Apple and Pear trees in the orchard');
+$worksheet->setCellValue('B13', '=DAVERAGE(A4:E10,3,A1:A3)');
+
+
+echo '
';
+
+
+echo 'Database
';
+
+$databaseData = $worksheet->rangeToArray('A4:E10',null,true,true,true);
+var_dump($databaseData);
+
+
+echo '
';
+
+
+// Test the formulae
+echo 'Criteria
';
+
+$criteriaData = $worksheet->rangeToArray('A1:B2',null,true,true,true);
+var_dump($criteriaData);
+
+echo $worksheet->getCell("A12")->getValue() .'
';
+echo 'DAVERAGE() Result is ' . $worksheet->getCell("B12")->getCalculatedValue() .'
';
+
+echo 'Criteria
';
+
+$criteriaData = $worksheet->rangeToArray('A1:A3',null,true,true,true);
+var_dump($criteriaData);
+
+echo $worksheet->getCell("A13")->getValue() .'
';
+echo 'DAVERAGE() Result is ' . $worksheet->getCell("B13")->getCalculatedValue();
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DCOUNT.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DCOUNT.php
new file mode 100755
index 000000000..13ad1fba1
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DCOUNT.php
@@ -0,0 +1,90 @@
+
+
+
+
+
+DCOUNT
+Counts the cells that contain numbers in a database.
+getActiveSheet();
+
+// Add some data
+$database = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ),
+ array( 'Apple', 18, 20, 14, 105.00 ),
+ array( 'Pear', 12, 12, 10, 96.00 ),
+ array( 'Cherry', 13, 14, 9, 105.00 ),
+ array( 'Apple', 14, 15, 10, 75.00 ),
+ array( 'Pear', 9, 8, 8, 76.80 ),
+ array( 'Apple', 8, 9, 6, 45.00 ),
+ );
+$criteria = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ),
+ array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ),
+ array( '="=Pear"', NULL, NULL, NULL, NULL, NULL )
+ );
+
+$worksheet->fromArray( $criteria, NULL, 'A1' );
+$worksheet->fromArray( $database, NULL, 'A4' );
+
+$worksheet->setCellValue('A12', 'The Number of Apple trees over 10\' in height');
+$worksheet->setCellValue('B12', '=DCOUNT(A4:E10,"Yield",A1:B2)');
+
+$worksheet->setCellValue('A13', 'The Number of Apple and Pear trees in the orchard');
+$worksheet->setCellValue('B13', '=DCOUNT(A4:E10,3,A1:A3)');
+
+
+echo '
';
+
+
+echo 'Database
';
+
+$databaseData = $worksheet->rangeToArray('A4:E10',null,true,true,true);
+var_dump($databaseData);
+
+
+echo '
';
+
+
+// Test the formulae
+echo 'Criteria
';
+
+$criteriaData = $worksheet->rangeToArray('A1:B2',null,true,true,true);
+var_dump($criteriaData);
+
+echo $worksheet->getCell("A12")->getValue() .'
';
+echo 'DCOUNT() Result is ' . $worksheet->getCell("B12")->getCalculatedValue() .'
';
+
+echo 'Criteria
';
+
+$criteriaData = $worksheet->rangeToArray('A1:A3',null,true,true,true);
+var_dump($criteriaData);
+
+echo $worksheet->getCell("A13")->getValue() .'
';
+echo 'DCOUNT() Result is ' . $worksheet->getCell("B13")->getCalculatedValue();
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DGET.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DGET.php
new file mode 100755
index 000000000..9a2b22c28
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DGET.php
@@ -0,0 +1,86 @@
+
+
+
+
+
+DGET
+Extracts a single value from a column of a list or database that matches conditions that you specify.
+getActiveSheet();
+
+// Add some data
+$database = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ),
+ array( 'Apple', 18, 20, 14, 105.00 ),
+ array( 'Pear', 12, 12, 10, 96.00 ),
+ array( 'Cherry', 13, 14, 9, 105.00 ),
+ array( 'Apple', 14, 15, 10, 75.00 ),
+ array( 'Pear', 9, 8, 8, 76.80 ),
+ array( 'Apple', 8, 9, 6, 45.00 ),
+ );
+$criteria = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ),
+ array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ),
+ array( '="=Pear"', NULL, NULL, NULL, NULL, NULL )
+ );
+
+$worksheet->fromArray( $criteria, NULL, 'A1' );
+$worksheet->fromArray( $database, NULL, 'A4' );
+
+$worksheet->setCellValue('A12', 'The height of the Apple tree between 10\' and 16\' tall');
+$worksheet->setCellValue('B12', '=DGET(A4:E10,"Height",A1:F2)');
+
+
+echo '
';
+
+
+echo 'Database
';
+
+$databaseData = $worksheet->rangeToArray('A4:E10',null,true,true,true);
+var_dump($databaseData);
+
+
+echo '
';
+
+
+// Test the formulae
+echo 'Criteria
';
+
+echo 'ALL' . '
';
+
+echo $worksheet->getCell("A12")->getValue() .'
';
+echo 'DMAX() Result is ' . $worksheet->getCell("B12")->getCalculatedValue() .'
';
+
+echo 'Criteria
';
+
+$criteriaData = $worksheet->rangeToArray('A1:A2',null,true,true,true);
+var_dump($criteriaData);
+
+echo $worksheet->getCell("A13")->getValue() .'
';
+echo 'DMAX() Result is ' . $worksheet->getCell("B13")->getCalculatedValue();
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DMAX.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DMAX.php
new file mode 100755
index 000000000..116d8482e
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DMAX.php
@@ -0,0 +1,89 @@
+
+
+
+
+
+DMAX
+Returns the maximum value from selected database entries.
+getActiveSheet();
+
+// Add some data
+$database = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ),
+ array( 'Apple', 18, 20, 14, 105.00 ),
+ array( 'Pear', 12, 12, 10, 96.00 ),
+ array( 'Cherry', 13, 14, 9, 105.00 ),
+ array( 'Apple', 14, 15, 10, 75.00 ),
+ array( 'Pear', 9, 8, 8, 76.80 ),
+ array( 'Apple', 8, 9, 6, 45.00 ),
+ );
+$criteria = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ),
+ array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ),
+ array( '="=Pear"', NULL, NULL, NULL, NULL, NULL )
+ );
+
+$worksheet->fromArray( $criteria, NULL, 'A1' );
+$worksheet->fromArray( $database, NULL, 'A4' );
+
+$worksheet->setCellValue('A12', 'The tallest tree in the orchard');
+$worksheet->setCellValue('B12', '=DMAX(A4:E10,"Height",A4:E10)');
+
+$worksheet->setCellValue('A13', 'The Oldest apple tree in the orchard');
+$worksheet->setCellValue('B13', '=DMAX(A4:E10,3,A1:A2)');
+
+
+echo '
';
+
+
+echo 'Database
';
+
+$databaseData = $worksheet->rangeToArray('A4:E10',null,true,true,true);
+var_dump($databaseData);
+
+
+echo '
';
+
+
+// Test the formulae
+echo 'Criteria
';
+
+echo 'ALL' . '
';
+
+echo $worksheet->getCell("A12")->getValue() .'
';
+echo 'DMAX() Result is ' . $worksheet->getCell("B12")->getCalculatedValue() .'
';
+
+echo 'Criteria
';
+
+$criteriaData = $worksheet->rangeToArray('A1:A2',null,true,true,true);
+var_dump($criteriaData);
+
+echo $worksheet->getCell("A13")->getValue() .'
';
+echo 'DMAX() Result is ' . $worksheet->getCell("B13")->getCalculatedValue();
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DMIN.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DMIN.php
new file mode 100755
index 000000000..55207e824
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DMIN.php
@@ -0,0 +1,89 @@
+
+
+
+
+
+DMIN
+Returns the minimum value from selected database entries.
+getActiveSheet();
+
+// Add some data
+$database = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ),
+ array( 'Apple', 18, 20, 14, 105.00 ),
+ array( 'Pear', 12, 12, 10, 96.00 ),
+ array( 'Cherry', 13, 14, 9, 105.00 ),
+ array( 'Apple', 14, 15, 10, 75.00 ),
+ array( 'Pear', 9, 8, 8, 76.80 ),
+ array( 'Apple', 8, 9, 6, 45.00 ),
+ );
+$criteria = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ),
+ array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ),
+ array( '="=Pear"', NULL, NULL, NULL, NULL, NULL )
+ );
+
+$worksheet->fromArray( $criteria, NULL, 'A1' );
+$worksheet->fromArray( $database, NULL, 'A4' );
+
+$worksheet->setCellValue('A12', 'The shortest tree in the orchard');
+$worksheet->setCellValue('B12', '=DMIN(A4:E10,"Height",A4:E10)');
+
+$worksheet->setCellValue('A13', 'The Youngest apple tree in the orchard');
+$worksheet->setCellValue('B13', '=DMIN(A4:E10,3,A1:A2)');
+
+
+echo '
';
+
+
+echo 'Database
';
+
+$databaseData = $worksheet->rangeToArray('A4:E10',null,true,true,true);
+var_dump($databaseData);
+
+
+echo '
';
+
+
+// Test the formulae
+echo 'Criteria
';
+
+echo 'ALL' . '
';
+
+echo $worksheet->getCell("A12")->getValue() .'
';
+echo 'DMIN() Result is ' . $worksheet->getCell("B12")->getCalculatedValue() .'
';
+
+echo 'Criteria
';
+
+$criteriaData = $worksheet->rangeToArray('A1:A2',null,true,true,true);
+var_dump($criteriaData);
+
+echo $worksheet->getCell("A13")->getValue() .'
';
+echo 'DMIN() Result is ' . $worksheet->getCell("B13")->getCalculatedValue();
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DPRODUCT.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DPRODUCT.php
new file mode 100755
index 000000000..8c084219e
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DPRODUCT.php
@@ -0,0 +1,87 @@
+
+
+
+
+
+DPRODUCT
+Multiplies the values in a column of a list or database that match conditions that you specify.
+getActiveSheet();
+
+// Add some data
+$database = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ),
+ array( 'Apple', 18, 20, 14, 105.00 ),
+ array( 'Pear', 12, 12, 10, 96.00 ),
+ array( 'Cherry', 13, 14, 9, 105.00 ),
+ array( 'Apple', 14, 15, 10, 75.00 ),
+ array( 'Pear', 9, 8, 8, 76.80 ),
+ array( 'Apple', 8, 9, 6, 45.00 ),
+ );
+$criteria = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ),
+ array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ),
+ array( '="=Pear"', NULL, NULL, NULL, NULL, NULL )
+ );
+
+$worksheet->fromArray( $criteria, NULL, 'A1' );
+$worksheet->fromArray( $database, NULL, 'A4' );
+
+$worksheet->setCellValue('A12', 'The product of the yields of all Apple trees over 10\' in the orchard');
+$worksheet->setCellValue('B12', '=DPRODUCT(A4:E10,"Yield",A1:B2)');
+
+
+
+echo '
';
+
+
+echo 'Database
';
+
+$databaseData = $worksheet->rangeToArray('A4:E10',null,true,true,true);
+var_dump($databaseData);
+
+
+echo '
';
+
+
+// Test the formulae
+echo 'Criteria
';
+
+echo 'ALL' . '
';
+
+echo $worksheet->getCell("A12")->getValue() .'
';
+echo 'DMAX() Result is ' . $worksheet->getCell("B12")->getCalculatedValue() .'
';
+
+echo 'Criteria
';
+
+$criteriaData = $worksheet->rangeToArray('A1:A2',null,true,true,true);
+var_dump($criteriaData);
+
+echo $worksheet->getCell("A13")->getValue() .'
';
+echo 'DMAX() Result is ' . $worksheet->getCell("B13")->getCalculatedValue();
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DSTDEV.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DSTDEV.php
new file mode 100755
index 000000000..28896e656
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DSTDEV.php
@@ -0,0 +1,90 @@
+
+
+
+
+
+DSTDEV
+Estimates the standard deviation based on a sample of selected database entries.
+getActiveSheet();
+
+// Add some data
+$database = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ),
+ array( 'Apple', 18, 20, 14, 105.00 ),
+ array( 'Pear', 12, 12, 10, 96.00 ),
+ array( 'Cherry', 13, 14, 9, 105.00 ),
+ array( 'Apple', 14, 15, 10, 75.00 ),
+ array( 'Pear', 9, 8, 8, 76.80 ),
+ array( 'Apple', 8, 9, 6, 45.00 ),
+ );
+$criteria = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ),
+ array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ),
+ array( '="=Pear"', NULL, NULL, NULL, NULL, NULL )
+ );
+
+$worksheet->fromArray( $criteria, NULL, 'A1' );
+$worksheet->fromArray( $database, NULL, 'A4' );
+
+$worksheet->setCellValue('A12', 'The estimated standard deviation in the yield of Apple and Pear trees');
+$worksheet->setCellValue('B12', '=DSTDEV(A4:E10,"Yield",A1:A3)');
+
+$worksheet->setCellValue('A13', 'The estimated standard deviation in height of Apple and Pear trees');
+$worksheet->setCellValue('B13', '=DSTDEV(A4:E10,2,A1:A3)');
+
+
+echo '
';
+
+
+echo 'Database
';
+
+$databaseData = $worksheet->rangeToArray('A4:E10',null,true,true,true);
+var_dump($databaseData);
+
+
+echo '
';
+
+
+// Test the formulae
+echo 'Criteria
';
+
+$criteriaData = $worksheet->rangeToArray('A1:A3',null,true,true,true);
+var_dump($criteriaData);
+
+echo $worksheet->getCell("A12")->getValue() .'
';
+echo 'DSTDEV() Result is ' . $worksheet->getCell("B12")->getCalculatedValue() .'
';
+
+echo 'Criteria
';
+
+$criteriaData = $worksheet->rangeToArray('A1:A3',null,true,true,true);
+var_dump($criteriaData);
+
+echo $worksheet->getCell("A13")->getValue() .'
';
+echo 'DSTDEV() Result is ' . $worksheet->getCell("B13")->getCalculatedValue();
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DSTDEVP.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DSTDEVP.php
new file mode 100755
index 000000000..6540f9adb
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DSTDEVP.php
@@ -0,0 +1,90 @@
+
+
+
+
+
+DSTDEVP
+Calculates the standard deviation based on the entire population of selected database entries.
+getActiveSheet();
+
+// Add some data
+$database = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ),
+ array( 'Apple', 18, 20, 14, 105.00 ),
+ array( 'Pear', 12, 12, 10, 96.00 ),
+ array( 'Cherry', 13, 14, 9, 105.00 ),
+ array( 'Apple', 14, 15, 10, 75.00 ),
+ array( 'Pear', 9, 8, 8, 76.80 ),
+ array( 'Apple', 8, 9, 6, 45.00 ),
+ );
+$criteria = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ),
+ array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ),
+ array( '="=Pear"', NULL, NULL, NULL, NULL, NULL )
+ );
+
+$worksheet->fromArray( $criteria, NULL, 'A1' );
+$worksheet->fromArray( $database, NULL, 'A4' );
+
+$worksheet->setCellValue('A12', 'The standard deviation in the yield of Apple and Pear trees');
+$worksheet->setCellValue('B12', '=DSTDEVP(A4:E10,"Yield",A1:A3)');
+
+$worksheet->setCellValue('A13', 'The standard deviation in height of Apple and Pear trees');
+$worksheet->setCellValue('B13', '=DSTDEVP(A4:E10,2,A1:A3)');
+
+
+echo '
';
+
+
+echo 'Database
';
+
+$databaseData = $worksheet->rangeToArray('A4:E10',null,true,true,true);
+var_dump($databaseData);
+
+
+echo '
';
+
+
+// Test the formulae
+echo 'Criteria
';
+
+$criteriaData = $worksheet->rangeToArray('A1:A3',null,true,true,true);
+var_dump($criteriaData);
+
+echo $worksheet->getCell("A12")->getValue() .'
';
+echo 'DSTDEVP() Result is ' . $worksheet->getCell("B12")->getCalculatedValue() .'
';
+
+echo 'Criteria
';
+
+$criteriaData = $worksheet->rangeToArray('A1:A3',null,true,true,true);
+var_dump($criteriaData);
+
+echo $worksheet->getCell("A13")->getValue() .'
';
+echo 'DSTDEVP() Result is ' . $worksheet->getCell("B13")->getCalculatedValue();
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DVAR.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DVAR.php
new file mode 100755
index 000000000..67a9cffa2
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DVAR.php
@@ -0,0 +1,90 @@
+
+
+
+
+
+DVAR
+Estimates variance based on a sample from selected database entries.
+getActiveSheet();
+
+// Add some data
+$database = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ),
+ array( 'Apple', 18, 20, 14, 105.00 ),
+ array( 'Pear', 12, 12, 10, 96.00 ),
+ array( 'Cherry', 13, 14, 9, 105.00 ),
+ array( 'Apple', 14, 15, 10, 75.00 ),
+ array( 'Pear', 9, 8, 8, 76.80 ),
+ array( 'Apple', 8, 9, 6, 45.00 ),
+ );
+$criteria = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ),
+ array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ),
+ array( '="=Pear"', NULL, NULL, NULL, NULL, NULL )
+ );
+
+$worksheet->fromArray( $criteria, NULL, 'A1' );
+$worksheet->fromArray( $database, NULL, 'A4' );
+
+$worksheet->setCellValue('A12', 'The estimated variance in the yield of Apple and Pear trees');
+$worksheet->setCellValue('B12', '=DVAR(A4:E10,"Yield",A1:A3)');
+
+$worksheet->setCellValue('A13', 'The estimated variance in height of Apple and Pear trees');
+$worksheet->setCellValue('B13', '=DVAR(A4:E10,2,A1:A3)');
+
+
+echo '
';
+
+
+echo 'Database
';
+
+$databaseData = $worksheet->rangeToArray('A4:E10',null,true,true,true);
+var_dump($databaseData);
+
+
+echo '
';
+
+
+// Test the formulae
+echo 'Criteria
';
+
+$criteriaData = $worksheet->rangeToArray('A1:A3',null,true,true,true);
+var_dump($criteriaData);
+
+echo $worksheet->getCell("A12")->getValue() .'
';
+echo 'DVAR() Result is ' . $worksheet->getCell("B12")->getCalculatedValue() .'
';
+
+echo 'Criteria
';
+
+$criteriaData = $worksheet->rangeToArray('A1:A3',null,true,true,true);
+var_dump($criteriaData);
+
+echo $worksheet->getCell("A13")->getValue() .'
';
+echo 'DVAR() Result is ' . $worksheet->getCell("B13")->getCalculatedValue();
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DVARP.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DVARP.php
new file mode 100755
index 000000000..fda633848
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/Database/DVARP.php
@@ -0,0 +1,90 @@
+
+
+
+
+
+DVARP
+Calculates variance based on the entire population of selected database entries,
+getActiveSheet();
+
+// Add some data
+$database = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ),
+ array( 'Apple', 18, 20, 14, 105.00 ),
+ array( 'Pear', 12, 12, 10, 96.00 ),
+ array( 'Cherry', 13, 14, 9, 105.00 ),
+ array( 'Apple', 14, 15, 10, 75.00 ),
+ array( 'Pear', 9, 8, 8, 76.80 ),
+ array( 'Apple', 8, 9, 6, 45.00 ),
+ );
+$criteria = array( array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ),
+ array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ),
+ array( '="=Pear"', NULL, NULL, NULL, NULL, NULL )
+ );
+
+$worksheet->fromArray( $criteria, NULL, 'A1' );
+$worksheet->fromArray( $database, NULL, 'A4' );
+
+$worksheet->setCellValue('A12', 'The variance in the yield of Apple and Pear trees');
+$worksheet->setCellValue('B12', '=DVARP(A4:E10,"Yield",A1:A3)');
+
+$worksheet->setCellValue('A13', 'The variance in height of Apple and Pear trees');
+$worksheet->setCellValue('B13', '=DVARP(A4:E10,2,A1:A3)');
+
+
+echo '
';
+
+
+echo 'Database
';
+
+$databaseData = $worksheet->rangeToArray('A4:E10',null,true,true,true);
+var_dump($databaseData);
+
+
+echo '
';
+
+
+// Test the formulae
+echo 'Criteria
';
+
+$criteriaData = $worksheet->rangeToArray('A1:A3',null,true,true,true);
+var_dump($criteriaData);
+
+echo $worksheet->getCell("A12")->getValue() .'
';
+echo 'DVARP() Result is ' . $worksheet->getCell("B12")->getCalculatedValue() .'
';
+
+echo 'Criteria
';
+
+$criteriaData = $worksheet->rangeToArray('A1:A3',null,true,true,true);
+var_dump($criteriaData);
+
+echo $worksheet->getCell("A13")->getValue() .'
';
+echo 'DVARP() Result is ' . $worksheet->getCell("B13")->getCalculatedValue();
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/DateTime/DATE.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/DateTime/DATE.php
new file mode 100755
index 000000000..979d1f5ec
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/DateTime/DATE.php
@@ -0,0 +1,83 @@
+
+
+
+
+
+DATE
+Returns the serial number of a particular date.
+getActiveSheet();
+
+// Add some data
+$testDates = array( array(2012,3,26), array(2012,2,29), array(2012,4,1), array(2012,12,25),
+ array(2012,10,31), array(2012,11,5), array(2012,1,1), array(2012,3,17),
+ array(2011,2,29), array(7,5,3), array(2012,13,1), array(2012,11,45),
+ array(2012,0,0), array(2012,1,0), array(2012,0,1),
+ array(2012,-2,2), array(2012,2,-2), array(2012,-2,-2),
+ );
+$testDateCount = count($testDates);
+
+$worksheet->fromArray($testDates,NULL,'A1',true);
+
+for ($row = 1; $row <= $testDateCount; ++$row) {
+ $worksheet->setCellValue('D'.$row, '=DATE(A'.$row.',B'.$row.',C'.$row.')');
+ $worksheet->setCellValue('E'.$row, '=D'.$row);
+}
+$worksheet->getStyle('E1:E'.$testDateCount)
+ ->getNumberFormat()
+ ->setFormatCode('yyyy-mmm-dd');
+
+
+echo '
';
+
+
+// Test the formulae
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/DateTime/DATEVALUE.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/DateTime/DATEVALUE.php
new file mode 100755
index 000000000..4d5d8c269
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/DateTime/DATEVALUE.php
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+ Date Value
+ Formula
+ Excel DateStamp
+ Formatted DateStamp
+
+ Year
+ Month
+ Day
+
+ ';
+ echo ' ';
+ }
+ ?>
+' , $worksheet->getCell('A'.$row)->getFormattedValue() , ' ';
+ echo '' , $worksheet->getCell('B'.$row)->getFormattedValue() , ' ';
+ echo '' , $worksheet->getCell('C'.$row)->getFormattedValue() , ' ';
+ echo '' , $worksheet->getCell('D'.$row)->getValue() , ' ';
+ echo '' , $worksheet->getCell('D'.$row)->getFormattedValue() , ' ';
+ echo '' , $worksheet->getCell('E'.$row)->getFormattedValue() , ' ';
+ echo 'DATEVALUE
+Converts a date in the form of text to a serial number.
+getActiveSheet();
+
+// Add some data
+$testDates = array( '26 March 2012', '29 Feb 2012', 'April 1, 2012', '25/12/2012',
+ '2012-Oct-31', '5th November', 'January 1st', 'April 2012',
+ '17-03', '03-2012', '29 Feb 2011', '03-05-07',
+ '03-MAY-07', '03-13-07',
+ );
+$testDateCount = count($testDates);
+
+for($row = 1; $row <= $testDateCount; ++$row) {
+ $worksheet->setCellValue('A'.$row, $testDates[$row-1]);
+ $worksheet->setCellValue('B'.$row, '=DATEVALUE(A'.$row.')');
+ $worksheet->setCellValue('C'.$row, '=B'.$row);
+}
+
+$worksheet->getStyle('C1:C'.$testDateCount)
+ ->getNumberFormat()
+ ->setFormatCode('yyyy-mmm-dd');
+
+
+echo '
';
+
+
+// Test the formulae
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/DateTime/TIME.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/DateTime/TIME.php
new file mode 100755
index 000000000..f4522768c
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/DateTime/TIME.php
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+ ';
+ echo 'Date String
+ Formula
+ Excel DateStamp
+ Formatted DateStamp
+ ' , $worksheet->getCell('A'.$row)->getFormattedValue() , ' ';
+ echo '' , $worksheet->getCell('B'.$row)->getValue() , ' ';
+ echo '' , $worksheet->getCell('B'.$row)->getFormattedValue() , ' ';
+ echo '' , $worksheet->getCell('C'.$row)->getFormattedValue() , ' ';
+ echo '';
+ }
+ ?>
+TIME
+Returns the serial number of a particular time.
+getActiveSheet();
+
+// Add some data
+$testDates = array( array(3,15), array(13,15), array(15,15,15), array(3,15,30),
+ array(15,15,15), array(5), array(9,15,0), array(9,15,-1),
+ array(13,-14,-15), array(0,0,-1)
+ );
+$testDateCount = count($testDates);
+
+$worksheet->fromArray($testDates,NULL,'A1',true);
+
+for ($row = 1; $row <= $testDateCount; ++$row) {
+ $worksheet->setCellValue('D'.$row, '=TIME(A'.$row.',B'.$row.',C'.$row.')');
+ $worksheet->setCellValue('E'.$row, '=D'.$row);
+}
+$worksheet->getStyle('E1:E'.$testDateCount)
+ ->getNumberFormat()
+ ->setFormatCode('hh:mm:ss');
+
+
+echo '
';
+
+
+// Test the formulae
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/DateTime/TIMEVALUE.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/DateTime/TIMEVALUE.php
new file mode 100755
index 000000000..89e0ba49b
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/DateTime/TIMEVALUE.php
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+ Date Value
+ Formula
+ Excel TimeStamp
+ Formatted TimeStamp
+
+ Hour
+ Minute
+ Second
+
+ ';
+ echo ' ';
+ }
+ ?>
+' , $worksheet->getCell('A'.$row)->getFormattedValue() , ' ';
+ echo '' , $worksheet->getCell('B'.$row)->getFormattedValue() , ' ';
+ echo '' , $worksheet->getCell('C'.$row)->getFormattedValue() , ' ';
+ echo '' , $worksheet->getCell('D'.$row)->getValue() , ' ';
+ echo '' , $worksheet->getCell('D'.$row)->getFormattedValue() , ' ';
+ echo '' , $worksheet->getCell('E'.$row)->getFormattedValue() , ' ';
+ echo 'TIMEVALUE
+Converts a time in the form of text to a serial number.
+getActiveSheet();
+
+// Add some data
+$testDates = array( '3:15', '13:15', '15:15:15', '3:15 AM', '3:15 PM', '5PM', '9:15AM', '13:15AM'
+ );
+$testDateCount = count($testDates);
+
+for($row = 1; $row <= $testDateCount; ++$row) {
+ $worksheet->setCellValue('A'.$row, $testDates[$row-1]);
+ $worksheet->setCellValue('B'.$row, '=TIMEVALUE(A'.$row.')');
+ $worksheet->setCellValue('C'.$row, '=B'.$row);
+}
+
+$worksheet->getStyle('C1:C'.$testDateCount)
+ ->getNumberFormat()
+ ->setFormatCode('hh:mm:ss');
+
+
+echo '
';
+
+
+// Test the formulae
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/index.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/index.php
new file mode 100755
index 000000000..644e3af50
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Calculations/index.php
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+ ';
+ echo 'Time String
+ Formula
+ Excel TimeStamp
+ Formatted TimeStamp
+ ' , $worksheet->getCell('A'.$row)->getFormattedValue() , ' ';
+ echo '' , $worksheet->getCell('B'.$row)->getValue() , ' ';
+ echo '' , $worksheet->getCell('B'.$row)->getFormattedValue() , ' ';
+ echo '' , $worksheet->getCell('C'.$row)->getFormattedValue() , ' ';
+ echo '';
+ }
+ ?>
+' . pathinfo($exampleType,PATHINFO_BASENAME) . ' Function Examples
';
+
+ $exampleList = glob('./'.$exampleType.'/*.php');
+
+ foreach($exampleList as $exampleFile) {
+ $fileData = file_get_contents($exampleFile);
+
+ $h1Pattern = '#(.*?)
#';
+ $h2Pattern = '#(.*?)
#';
+
+ if (preg_match($h1Pattern, $fileData, $out)) {
+ $h1Text = $out[1];
+ $h2Text = (preg_match($h2Pattern, $fileData, $out)) ? $out[1] : '';
+
+ echo '',$h1Text,'
';
+ if ($h2Text > '') {
+ echo $h2Text,'
';
+ }
+ }
+
+ }
+}
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader01.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader01.php
new file mode 100755
index 000000000..8883e12e3
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader01.php
@@ -0,0 +1,42 @@
+
+
+
+
+
+PHPExcel Reader Example #01
+Simple File Reader using PHPExcel_IOFactory::load()
+';
+$objPHPExcel = PHPExcel_IOFactory::load($inputFileName);
+
+
+echo '
';
+
+$sheetData = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
+var_dump($sheetData);
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader02.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader02.php
new file mode 100755
index 000000000..b2293c3e4
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader02.php
@@ -0,0 +1,50 @@
+
+
+
+
+
+PHPExcel Reader Example #02
+Simple File Reader using a Specified Reader
+';
+$objReader = new PHPExcel_Reader_Excel5();
+// $objReader = new PHPExcel_Reader_Excel2007();
+// $objReader = new PHPExcel_Reader_Excel2003XML();
+// $objReader = new PHPExcel_Reader_OOCalc();
+// $objReader = new PHPExcel_Reader_SYLK();
+// $objReader = new PHPExcel_Reader_Gnumeric();
+// $objReader = new PHPExcel_Reader_CSV();
+$objPHPExcel = $objReader->load($inputFileName);
+
+
+echo '
';
+
+$sheetData = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
+var_dump($sheetData);
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader03.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader03.php
new file mode 100755
index 000000000..b4ab25689
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader03.php
@@ -0,0 +1,51 @@
+
+
+
+
+
+PHPExcel Reader Example #03
+Simple File Reader using the PHPExcel_IOFactory to Return a Reader
+';
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+$objPHPExcel = $objReader->load($inputFileName);
+
+
+echo '
';
+
+$sheetData = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
+var_dump($sheetData);
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader04.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader04.php
new file mode 100755
index 000000000..cf87b2b41
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader04.php
@@ -0,0 +1,47 @@
+
+
+
+
+
+PHPExcel Reader Example #04
+Simple File Reader using the PHPExcel_IOFactory to Identify a Reader to Use
+';
+
+echo 'Loading file ',pathinfo($inputFileName,PATHINFO_BASENAME),' using IOFactory with the identified reader type
';
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+$objPHPExcel = $objReader->load($inputFileName);
+
+
+echo '
';
+
+$sheetData = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
+var_dump($sheetData);
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader05.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader05.php
new file mode 100755
index 000000000..1317f0752
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader05.php
@@ -0,0 +1,51 @@
+
+
+
+
+
+PHPExcel Reader Example #05
+Simple File Reader using the "Read Data Only" Option
+';
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+echo 'Turning Formatting off for Load
';
+$objReader->setReadDataOnly(true);
+$objPHPExcel = $objReader->load($inputFileName);
+
+
+echo '
';
+
+$sheetData = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
+var_dump($sheetData);
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader06.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader06.php
new file mode 100755
index 000000000..58c2d2657
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader06.php
@@ -0,0 +1,54 @@
+
+
+
+
+
+PHPExcel Reader Example #06
+Simple File Reader Loading All WorkSheets
+';
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+echo 'Loading all WorkSheets
';
+$objReader->setLoadAllSheets();
+$objPHPExcel = $objReader->load($inputFileName);
+
+
+echo '
';
+
+echo $objPHPExcel->getSheetCount(),' worksheet',(($objPHPExcel->getSheetCount() == 1) ? '' : 's'),' loaded
';
+$loadedSheetNames = $objPHPExcel->getSheetNames();
+foreach($loadedSheetNames as $sheetIndex => $loadedSheetName) {
+ echo $sheetIndex,' -> ',$loadedSheetName,'
';
+}
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader07.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader07.php
new file mode 100755
index 000000000..80acdf6cf
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader07.php
@@ -0,0 +1,55 @@
+
+
+
+
+
+PHPExcel Reader Example #07
+Simple File Reader Loading a Single Named WorkSheet
+';
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+echo 'Loading Sheet "',$sheetname,'" only
';
+$objReader->setLoadSheetsOnly($sheetname);
+$objPHPExcel = $objReader->load($inputFileName);
+
+
+echo '
';
+
+echo $objPHPExcel->getSheetCount(),' worksheet',(($objPHPExcel->getSheetCount() == 1) ? '' : 's'),' loaded
';
+$loadedSheetNames = $objPHPExcel->getSheetNames();
+foreach($loadedSheetNames as $sheetIndex => $loadedSheetName) {
+ echo $sheetIndex,' -> ',$loadedSheetName,'
';
+}
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader08.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader08.php
new file mode 100755
index 000000000..3c38e0200
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader08.php
@@ -0,0 +1,55 @@
+
+
+
+
+
+PHPExcel Reader Example #08
+Simple File Reader Loading Several Named WorkSheets
+';
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+echo 'Loading Sheet',((count($sheetnames) == 1) ? '' : 's'),' "',implode('" and "',$sheetnames),'" only
';
+$objReader->setLoadSheetsOnly($sheetnames);
+$objPHPExcel = $objReader->load($inputFileName);
+
+
+echo '
';
+
+echo $objPHPExcel->getSheetCount(),' worksheet',(($objPHPExcel->getSheetCount() == 1) ? '' : 's'),' loaded
';
+$loadedSheetNames = $objPHPExcel->getSheetNames();
+foreach($loadedSheetNames as $sheetIndex => $loadedSheetName) {
+ echo $sheetIndex,' -> ',$loadedSheetName,'
';
+}
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader09.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader09.php
new file mode 100755
index 000000000..3bfa8f0df
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader09.php
@@ -0,0 +1,71 @@
+
+
+
+
+
+PHPExcel Reader Example #09
+Simple File Reader Using a Read Filter
+= 1 && $row <= 7) {
+ if (in_array($column,range('A','E'))) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+$filterSubset = new MyReadFilter();
+
+
+echo 'Loading file ',pathinfo($inputFileName,PATHINFO_BASENAME),' using IOFactory with a defined reader type of ',$inputFileType,'
';
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+echo 'Loading Sheet "',$sheetname,'" only
';
+$objReader->setLoadSheetsOnly($sheetname);
+echo 'Loading Sheet using filter
';
+$objReader->setReadFilter($filterSubset);
+$objPHPExcel = $objReader->load($inputFileName);
+
+
+echo '
';
+
+$sheetData = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
+var_dump($sheetData);
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader10.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader10.php
new file mode 100755
index 000000000..eb43ff866
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader10.php
@@ -0,0 +1,82 @@
+
+
+
+
+
+PHPExcel Reader Example #10
+Simple File Reader Using a Configurable Read Filter
+_startRow = $startRow;
+ $this->_endRow = $endRow;
+ $this->_columns = $columns;
+ }
+
+ public function readCell($column, $row, $worksheetName = '') {
+ if ($row >= $this->_startRow && $row <= $this->_endRow) {
+ if (in_array($column,$this->_columns)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+$filterSubset = new MyReadFilter(9,15,range('G','K'));
+
+
+echo 'Loading file ',pathinfo($inputFileName,PATHINFO_BASENAME),' using IOFactory with a defined reader type of ',$inputFileType,'
';
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+echo 'Loading Sheet "',$sheetname,'" only
';
+$objReader->setLoadSheetsOnly($sheetname);
+echo 'Loading Sheet using configurable filter
';
+$objReader->setReadFilter($filterSubset);
+$objPHPExcel = $objReader->load($inputFileName);
+
+
+echo '
';
+
+$sheetData = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
+var_dump($sheetData);
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader11.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader11.php
new file mode 100755
index 000000000..7bbd80817
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader11.php
@@ -0,0 +1,91 @@
+
+
+
+
+
+PHPExcel Reader Example #11
+Reading a Workbook in "Chunks" Using a Configurable Read Filter (Version 1)
+_startRow = $startRow;
+ $this->_endRow = $startRow + $chunkSize;
+ }
+
+ public function readCell($column, $row, $worksheetName = '') {
+ // Only read the heading row, and the rows that were configured in the constructor
+ if (($row == 1) || ($row >= $this->_startRow && $row < $this->_endRow)) {
+ return true;
+ }
+ return false;
+ }
+}
+
+
+echo 'Loading file ',pathinfo($inputFileName,PATHINFO_BASENAME),' using IOFactory with a defined reader type of ',$inputFileType,'
';
+/** Create a new Reader of the type defined in $inputFileType **/
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+
+
+echo '
';
+
+
+/** Define how many rows we want for each "chunk" **/
+$chunkSize = 20;
+
+/** Loop to read our worksheet in "chunk size" blocks **/
+for ($startRow = 2; $startRow <= 240; $startRow += $chunkSize) {
+ echo 'Loading WorkSheet using configurable filter for headings row 1 and for rows ',$startRow,' to ',($startRow+$chunkSize-1),'
';
+ /** Create a new Instance of our Read Filter, passing in the limits on which rows we want to read **/
+ $chunkFilter = new chunkReadFilter($startRow,$chunkSize);
+ /** Tell the Reader that we want to use the new Read Filter that we've just Instantiated **/
+ $objReader->setReadFilter($chunkFilter);
+ /** Load only the rows that match our filter from $inputFileName to a PHPExcel Object **/
+ $objPHPExcel = $objReader->load($inputFileName);
+
+ // Do some processing here
+
+ $sheetData = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
+ var_dump($sheetData);
+ echo '
';
+}
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader12.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader12.php
new file mode 100755
index 000000000..e6789c207
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader12.php
@@ -0,0 +1,94 @@
+
+
+
+
+
+PHPExcel Reader Example #12
+Reading a Workbook in "Chunks" Using a Configurable Read Filter (Version 2)
+_startRow = $startRow;
+ $this->_endRow = $startRow + $chunkSize;
+ }
+
+ public function readCell($column, $row, $worksheetName = '') {
+ // Only read the heading row, and the rows that are configured in $this->_startRow and $this->_endRow
+ if (($row == 1) || ($row >= $this->_startRow && $row < $this->_endRow)) {
+ return true;
+ }
+ return false;
+ }
+}
+
+
+echo 'Loading file ',pathinfo($inputFileName,PATHINFO_BASENAME),' using IOFactory with a defined reader type of ',$inputFileType,'
';
+/** Create a new Reader of the type defined in $inputFileType **/
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+
+
+echo '
';
+
+
+/** Define how many rows we want to read for each "chunk" **/
+$chunkSize = 20;
+/** Create a new Instance of our Read Filter **/
+$chunkFilter = new chunkReadFilter();
+
+/** Tell the Reader that we want to use the Read Filter that we've Instantiated **/
+$objReader->setReadFilter($chunkFilter);
+
+/** Loop to read our worksheet in "chunk size" blocks **/
+for ($startRow = 2; $startRow <= 240; $startRow += $chunkSize) {
+ echo 'Loading WorkSheet using configurable filter for headings row 1 and for rows ',$startRow,' to ',($startRow+$chunkSize-1),'
';
+ /** Tell the Read Filter, the limits on which rows we want to read this iteration **/
+ $chunkFilter->setRows($startRow,$chunkSize);
+ /** Load only the rows that match our filter from $inputFileName to a PHPExcel Object **/
+ $objPHPExcel = $objReader->load($inputFileName);
+
+ // Do some processing here
+
+ $sheetData = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
+ var_dump($sheetData);
+ echo '
';
+}
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader13.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader13.php
new file mode 100755
index 000000000..3e11e8bc5
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader13.php
@@ -0,0 +1,60 @@
+
+
+
+
+
+PHPExcel Reader Example #13
+Simple File Reader for Multiple CSV Files
+';
+$objPHPExcel = $objReader->load($inputFileName);
+$objPHPExcel->getActiveSheet()->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME));
+foreach($inputFileNames as $sheet => $inputFileName) {
+ echo 'Loading file ',pathinfo($inputFileName,PATHINFO_BASENAME),' into WorkSheet #',($sheet+2),' using IOFactory with a defined reader type of ',$inputFileType,'
';
+ $objReader->setSheetIndex($sheet+1);
+ $objReader->loadIntoExisting($inputFileName,$objPHPExcel);
+ $objPHPExcel->getActiveSheet()->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME));
+}
+
+
+echo '
';
+
+echo $objPHPExcel->getSheetCount(),' worksheet',(($objPHPExcel->getSheetCount() == 1) ? '' : 's'),' loaded
';
+$loadedSheetNames = $objPHPExcel->getSheetNames();
+foreach($loadedSheetNames as $sheetIndex => $loadedSheetName) {
+ echo 'Worksheet #',$sheetIndex,' -> ',$loadedSheetName,'
';
+ $objPHPExcel->setActiveSheetIndexByName($loadedSheetName);
+ $sheetData = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
+ var_dump($sheetData);
+ echo '
';
+}
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader14.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader14.php
new file mode 100755
index 000000000..1cef7103f
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader14.php
@@ -0,0 +1,105 @@
+
+
+
+
+
+PHPExcel Reader Example #14
+Reading a Large CSV file in "Chunks" to split across multiple Worksheets
+_startRow = $startRow;
+ $this->_endRow = $startRow + $chunkSize;
+ }
+
+ public function readCell($column, $row, $worksheetName = '') {
+ // Only read the heading row, and the rows that are configured in $this->_startRow and $this->_endRow
+ if (($row == 1) || ($row >= $this->_startRow && $row < $this->_endRow)) {
+ return true;
+ }
+ return false;
+ }
+}
+
+
+echo 'Loading file ',pathinfo($inputFileName,PATHINFO_BASENAME),' using IOFactory with a defined reader type of ',$inputFileType,'
';
+/** Create a new Reader of the type defined in $inputFileType **/
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+
+
+echo '
';
+
+
+/** Define how many rows we want to read for each "chunk" **/
+$chunkSize = 100;
+/** Create a new Instance of our Read Filter **/
+$chunkFilter = new chunkReadFilter();
+
+/** Tell the Reader that we want to use the Read Filter that we've Instantiated **/
+/** and that we want to store it in contiguous rows/columns **/
+$objReader->setReadFilter($chunkFilter)
+ ->setContiguous(true);
+
+
+/** Instantiate a new PHPExcel object manually **/
+$objPHPExcel = new PHPExcel();
+
+/** Set a sheet index **/
+$sheet = 0;
+/** Loop to read our worksheet in "chunk size" blocks **/
+/** $startRow is set to 2 initially because we always read the headings in row #1 **/
+for ($startRow = 2; $startRow <= 240; $startRow += $chunkSize) {
+ echo 'Loading WorkSheet #',($sheet+1),' using configurable filter for headings row 1 and for rows ',$startRow,' to ',($startRow+$chunkSize-1),'
';
+ /** Tell the Read Filter, the limits on which rows we want to read this iteration **/
+ $chunkFilter->setRows($startRow,$chunkSize);
+
+ /** Increment the worksheet index pointer for the Reader **/
+ $objReader->setSheetIndex($sheet);
+ /** Load only the rows that match our filter into a new worksheet in the PHPExcel Object **/
+ $objReader->loadIntoExisting($inputFileName,$objPHPExcel);
+ /** Set the worksheet title (to reference the "sheet" of data that we've loaded) **/
+ /** and increment the sheet index as well **/
+ $objPHPExcel->getActiveSheet()->setTitle('Country Data #'.(++$sheet));
+}
+
+
+echo '
';
+
+echo $objPHPExcel->getSheetCount(),' worksheet',(($objPHPExcel->getSheetCount() == 1) ? '' : 's'),' loaded
';
+$loadedSheetNames = $objPHPExcel->getSheetNames();
+foreach($loadedSheetNames as $sheetIndex => $loadedSheetName) {
+ echo 'Worksheet #',$sheetIndex,' -> ',$loadedSheetName,'
';
+ $objPHPExcel->setActiveSheetIndexByName($loadedSheetName);
+ $sheetData = $objPHPExcel->getActiveSheet()->toArray(null,false,false,true);
+ var_dump($sheetData);
+ echo '
';
+}
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader15.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader15.php
new file mode 100755
index 000000000..566c3c998
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader15.php
@@ -0,0 +1,71 @@
+
+
+
+
+
+PHPExcel Reader Example #15
+Simple File Reader for Tab-Separated Value File using the Advanced Value Binder
+';
+$objReader->setDelimiter("\t");
+$objPHPExcel = $objReader->load($inputFileName);
+$objPHPExcel->getActiveSheet()->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME));
+
+
+echo '
';
+
+echo $objPHPExcel->getSheetCount(),' worksheet',(($objPHPExcel->getSheetCount() == 1) ? '' : 's'),' loaded
';
+$loadedSheetNames = $objPHPExcel->getSheetNames();
+foreach($loadedSheetNames as $sheetIndex => $loadedSheetName) {
+ echo 'Worksheet #',$sheetIndex,' -> ',$loadedSheetName,' (Formatted)
';
+ $objPHPExcel->setActiveSheetIndexByName($loadedSheetName);
+ $sheetData = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
+ var_dump($sheetData);
+ echo '
';
+}
+
+echo '
';
+
+foreach($loadedSheetNames as $sheetIndex => $loadedSheetName) {
+ echo 'Worksheet #',$sheetIndex,' -> ',$loadedSheetName,' (Unformatted)
';
+ $objPHPExcel->setActiveSheetIndexByName($loadedSheetName);
+ $sheetData = $objPHPExcel->getActiveSheet()->toArray(null,true,false,true);
+ var_dump($sheetData);
+ echo '
';
+}
+
+echo '
';
+
+foreach($loadedSheetNames as $sheetIndex => $loadedSheetName) {
+ echo 'Worksheet #',$sheetIndex,' -> ',$loadedSheetName,' (Raw)
';
+ $objPHPExcel->setActiveSheetIndexByName($loadedSheetName);
+ $sheetData = $objPHPExcel->getActiveSheet()->toArray(null,false,false,true);
+ var_dump($sheetData);
+ echo '
';
+}
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader16.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader16.php
new file mode 100755
index 000000000..9d9defa6b
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader16.php
@@ -0,0 +1,46 @@
+
+
+
+
+
+PHPExcel Reader Example #16
+Handling Loader Exceptions using Try/Catch
+';
+try {
+ $objPHPExcel = PHPExcel_IOFactory::load($inputFileName);
+} catch(PHPExcel_Reader_Exception $e) {
+ die('Error loading file "'.pathinfo($inputFileName,PATHINFO_BASENAME).'": '.$e->getMessage());
+}
+
+
+echo '
';
+
+$sheetData = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
+var_dump($sheetData);
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader17.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader17.php
new file mode 100755
index 000000000..b0ef7914d
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader17.php
@@ -0,0 +1,52 @@
+
+
+
+
+
+PHPExcel Reader Example #17
+Simple File Reader Loading Several Named WorkSheets
+';
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+
+
+/** Read the list of Worksheet Names from the Workbook file **/
+echo 'Read the list of Worksheets in the WorkBook
';
+$worksheetNames = $objReader->listWorksheetNames($inputFileName);
+
+echo 'There are ',count($worksheetNames),' worksheet',((count($worksheetNames) == 1) ? '' : 's'),' in the workbook
';
+foreach($worksheetNames as $worksheetName) {
+ echo $worksheetName,'
';
+}
+
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader18.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader18.php
new file mode 100755
index 000000000..438d88691
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader18.php
@@ -0,0 +1,50 @@
+
+
+
+
+
+PHPExcel Reader Example #18
+Reading list of WorkSheets without loading entire file
+';
+
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+$worksheetNames = $objReader->listWorksheetNames($inputFileName);
+
+echo 'Worksheet Names
';
+echo '';
+foreach ($worksheetNames as $worksheetName) {
+ echo '
';
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader19.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader19.php
new file mode 100755
index 000000000..2f3eaaf28
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/exampleReader19.php
@@ -0,0 +1,53 @@
+
+
+
+
+
+PHPExcel Reader Example #19
+Reading WorkSheet information without loading entire file
+';
+
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+$worksheetData = $objReader->listWorksheetInfo($inputFileName);
+
+echo 'Worksheet Information
';
+echo '';
+foreach ($worksheetData as $worksheet) {
+ echo '
';
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/sampleData/example1.csv b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/sampleData/example1.csv
new file mode 100755
index 000000000..b8cdf182f
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/sampleData/example1.csv
@@ -0,0 +1,4 @@
+First Name,Last Name,Nationality,Gender,Date of Birth,Time of Birth,Date/Time,PHP Coder,Sanity %Age
+Mark,Baker,British,M,19-Dec-1960,01:30,=E2+F2,TRUE,32%
+Toni,Baker,British,F,24-Nov-1950,20:00,=E3+F3,FALSE,95%
+Rachel,Baker,British,F,7-Dec-1982,00:15,=E4+F4,FALSE,100%
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/sampleData/example1.tsv b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/sampleData/example1.tsv
new file mode 100755
index 000000000..29c9297c3
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/sampleData/example1.tsv
@@ -0,0 +1,4 @@
+First Name Last Name Nationality Gender Date of Birth Time of Birth Date/Time PHP Coder Sanity %Age
+Mark Baker British M 19-Dec-1960 01:30 =E2+F2 TRUE 32%
+Toni Baker British F 24-Nov-1950 20:00 =E3+F3 FALSE 95%
+Rachel Baker British F 7-Dec-1982 00:15 =E4+F4 FALSE 100%
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/sampleData/example1.xls b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/sampleData/example1.xls
new file mode 100755
index 000000000..bd9bb110b
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/sampleData/example1.xls differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/sampleData/example2.csv b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/sampleData/example2.csv
new file mode 100755
index 000000000..1750f1b61
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/sampleData/example2.csv
@@ -0,0 +1,223 @@
+"City","Country","Latitude","Longitude"
+"Kabul","Afghanistan",34.528455,69.171703
+"Tirane","Albania",41.33,19.82
+"Algiers","Algeria",36.752887,3.042048
+"Pago Pago","American Samoa",-14.27933,-170.700897
+"Andorra la Vella","Andorra",42.507531,1.521816
+"Luanda","Angola",-8.838333,13.234444
+"Buenos Aires","Argentina",-34.608417,-58.373161
+"Yerevan","Armenia",40.183333,44.516667
+"Oranjestad","Aruba",12.52458,-70.026459
+"Canberra","Australia",-35.3075,149.124417
+"Vienna","Austria",48.208333,16.373056
+"Baku","Azerbaijan",40.379571,49.891233
+"Nassau","Bahamas",25.06,-77.345
+"Manama","Bahrain",26.216667,50.583333
+"Dhaka","Bangladesh",23.709921,90.407143
+"Bridgetown","Barbados",13.096111,-59.608333
+"Minsk","Belarus",53.9,27.566667
+"Brussels","Belgium",50.846281,4.354727
+"Belmopan","Belize",17.251389,-88.766944
+"Thimphu","Bhutan",27.466667,89.641667
+"La Paz","Bolivia",-16.49901,-68.146248
+"Sarajevo","Bosnia and Herzegovina",43.8476,18.3564
+"Gaborone","Botswana",-24.65411,25.908739
+"Brasilia","Brazil",-15.780148,-47.92917
+"Road Town","British Virgin Islands",18.433333,-64.616667
+"Bandar Seri Begawan","Brunei Darussalam",4.9431,114.9425
+"Sofia","Bulgaria",42.697626,23.322284
+"Ouagadougou","Burkina Faso",12.364637,-1.533864
+"Bujumbura","Burundi",-3.361378,29.359878
+"Phnom Penh","Cambodia",11.55,104.916667
+"Yaounde","Cameroon",3.866667,11.516667
+"Ottawa","Canada",45.423494,-75.697933
+"Praia","Cape Verde",14.920833,-23.508333
+"George Town","Cayman Islands",19.286932,-81.367439
+"Bangui","Central African Republic",4.361698,18.555975
+"N'Djamena","Chad",12.104797,15.044506
+"Santiago","Chile",-33.42536,-70.566466
+"Beijing","China",39.904667,116.408198
+"Bogota","Colombia",4.647302,-74.096268
+"Moroni","Comoros",-11.717216,43.247315
+"Brazzaville","Congo",-4.266667,15.283333
+"San Jose","Costa Rica",9.933333,-84.083333
+"Yamoussoukro","Cote d'Ivoire",6.816667,-5.283333
+"Zagreb","Croatia",45.814912,15.978515
+"Havana","Cuba",23.133333,-82.366667
+"Nicosia","Cyprus",35.166667,33.366667
+"Prague","Czech Republic",50.087811,14.42046
+"Kinshasa","Congo",-4.325,15.322222
+"Copenhagen","Denmark",55.676294,12.568116
+"Djibouti","Djibouti",11.588,43.145
+"Roseau","Dominica",15.301389,-61.388333
+"Santo Domingo","Dominican Republic",18.5,-69.983333
+"Dili","East Timor",-8.566667,125.566667
+"Quito","Ecuador",-0.229498,-78.524277
+"Cairo","Egypt",30.064742,31.249509
+"San Salvador","El Salvador",13.69,-89.190003
+"Malabo","Equatorial Guinea",3.75,8.783333
+"Asmara","Eritrea",15.33236,38.92617
+"Tallinn","Estonia",59.438862,24.754472
+"Addis Ababa","Ethiopia",9.022736,38.746799
+"Stanley","Falkland Islands",-51.700981,-57.84919
+"Torshavn","Faroe Islands",62.017707,-6.771879
+"Suva","Fiji",-18.1416,178.4419
+"Helsinki","Finland",60.169813,24.93824
+"Paris","France",48.856667,2.350987
+"Cayenne","French Guiana",4.9227,-52.3269
+"Papeete","French Polynesia",-17.535021,-149.569595
+"Libreville","Gabon",0.390841,9.453644
+"Banjul","Gambia",13.453056,-16.5775
+"T'bilisi","Georgia",41.716667,44.783333
+"Berlin","Germany",52.523405,13.4114
+"Accra","Ghana",5.555717,-0.196306
+"Athens","Greece",37.97918,23.716647
+"Nuuk","Greenland",64.18362,-51.721407
+"Basse-Terre","Guadeloupe",15.998503,-61.72202
+"Guatemala","Guatemala",14.641389,-90.513056
+"St. Peter Port","Guernsey",49.458858,-2.534752
+"Conakry","Guinea",9.537029,-13.67847
+"Bissau","Guinea-Bissau",11.866667,-15.6
+"Georgetown","Guyana",6.804611,-58.154831
+"Port-au-Prince","Haiti",18.539269,-72.336408
+"Tegucigalpa","Honduras",14.082054,-87.206285
+"Budapest","Hungary",47.498406,19.040758
+"Reykjavik","Iceland",64.135338,-21.89521
+"New Delhi","India",28.635308,77.22496
+"Jakarta","Indonesia",-6.211544,106.845172
+"Tehran","Iran",35.696216,51.422945
+"Baghdad","Iraq",33.3157,44.3922
+"Dublin","Ireland",53.344104,-6.267494
+"Jerusalem","Israel",31.7857,35.2007
+"Rome","Italy",41.895466,12.482324
+"Kingston","Jamaica",17.992731,-76.792009
+"St. Helier","Jersey",49.190278,-2.108611
+"Amman","Jordan",31.956578,35.945695
+"Astana","Kazakhstan",51.10,71.30
+"Nairobi","Kenya",-01.17,36.48
+"Tarawa","Kiribati",01.30,173.00
+"Seoul","South Korea",37.31,126.58
+"Kuwait City","Kuwait",29.30,48.00
+"Bishkek","Kyrgyzstan",42.54,74.46
+"Riga","Latvia",56.53,24.08
+"Beirut","Lebanon",33.53,35.31
+"Maseru","Lesotho",-29.18,27.30
+"Monrovia","Liberia",06.18,-10.47
+"Vaduz","Liechtenstein",47.08,09.31
+"Vilnius","Lithuania",54.38,25.19
+"Luxembourg","Luxembourg",49.37,06.09
+"Antananarivo","Madagascar",-18.55,47.31
+"Lilongwe","Malawi",-14.00,33.48
+"Kuala Lumpur","Malaysia",03.09,101.41
+"Male","Maldives",04.00,73.28
+"Bamako","Mali",12.34,-07.55
+"Valletta","Malta",35.54,14.31
+"Fort-de-France","Martinique",14.36,-61.02
+"Nouakchott","Mauritania",-20.10,57.30
+"Mamoudzou","Mayotte",-12.48,45.14
+"Mexico City","Mexico",19.20,-99.10
+"Palikir","Micronesia",06.55,158.09
+"Chisinau","Moldova",47.02,28.50
+"Maputo","Mozambique",-25.58,32.32
+"Yangon","Myanmar",16.45,96.20
+"Windhoek","Namibia",-22.35,17.04
+"Kathmandu","Nepal",27.45,85.20
+"Amsterdam","Netherlands",52.23,04.54
+"Willemstad","Netherlands Antilles",12.05,-69.00
+"Noumea","New Caledonia",-22.17,166.30
+"Wellington","New Zealand",-41.19,174.46
+"Managua","Nicaragua",12.06,-86.20
+"Niamey","Niger",13.27,02.06
+"Abuja","Nigeria",09.05,07.32
+"Kingston","Norfolk Island",-45.20,168.43
+"Saipan","Northern Mariana Islands",15.12,145.45
+"Oslo","Norway",59.55,10.45
+"Masqat","Oman",23.37,58.36
+"Islamabad","Pakistan",33.40,73.10
+"Koror","Palau",07.20,134.28
+"Panama City","Panama",09.00,-79.25
+"Port Moresby","Papua New Guinea",-09.24,147.08
+"Asuncion","Paraguay",-25.10,-57.30
+"Lima","Peru",-12.00,-77.00
+"Manila","Philippines",14.40,121.03
+"Warsaw","Poland",52.13,21.00
+"Lisbon","Portugal",38.42,-09.10
+"San Juan","Puerto Rico",18.28,-66.07
+"Doha","Qatar",25.15,51.35
+"Bucuresti","Romania",44.27,26.10
+"Moskva","Russian Federation",55.45,37.35
+"Kigali","Rawanda",-01.59,30.04
+"Basseterre","Saint Kitts and Nevis",17.17,-62.43
+"Castries","Saint Lucia",14.02,-60.58
+"Saint-Pierre","Saint Pierre and Miquelon",46.46,-56.12
+"Apia","Samoa",-13.50,-171.50
+"San Marino","San Marino",43.55,12.30
+"Sao Tome","Sao Tome and Principe",00.10,06.39
+"Riyadh","Saudi Arabia",24.41,46.42
+"Dakar","Senegal",14.34,-17.29
+"Freetown","Sierra Leone",08.30,-13.17
+"Bratislava","Slovakia",48.10,17.07
+"Ljubljana","Slovenia",46.04,14.33
+"Honiara","Solomon Islands",-09.27,159.57
+"Mogadishu","Somalia",02.02,45.25
+"Pretoria","South Africa",-25.44,28.12
+"Madrid","Spain",40.25,-03.45
+"Khartoum","Sudan",15.31,32.35
+"Paramaribo","Suriname",05.50,-55.10
+"Mbabane","Swaziland",-26.18,31.06
+"Stockholm","Sweden",59.20,18.03
+"Bern","Switzerland",46.57,07.28
+"Damascus","Syrian Arab Republic",33.30,36.18
+"Dushanbe","Tajikistan",38.33,68.48
+"Bangkok","Thailand",13.45,100.35
+"Lome","Togo",06.09,01.20
+"Nuku'alofa","Tonga",-21.10,-174.00
+"Tunis","Tunisia",36.50,10.11
+"Ankara","Turkey",39.57,32.54
+"Ashgabat","Turkmenistan",38.00,57.50
+"Funafuti","Tuvalu",-08.31,179.13
+"Kampala","Uganda",00.20,32.30
+"Kiev","Ukraine",50.30,30.28
+"Abu Dhabi","United Arab Emirates",24.28,54.22
+"London","United Kingdom",51.36,-00.05
+"Dodoma","Tanzania",-06.08,35.45
+"Washington DC","United States of America",39.91,-77.02
+"Montevideo","Uruguay",-34.50,-56.11
+"Tashkent","Uzbekistan",41.20,69.10
+"Port-Vila","Vanuatu",-17.45,168.18
+"Caracas","Venezuela",10.30,-66.55
+"Hanoi","Viet Nam",21.05,105.55
+"Belgrade","Yugoslavia",44.50,20.37
+"Lusaka","Zambia",-15.28,28.16
+"Harare","Zimbabwe",-17.43,31.02
+"St. John's","Antigua and Barbuda",17.08,-61.50
+"Porto Novo","Benin",06.30,02.47
+"Hamilton","Bermuda"","32.18,-64.48
+"Avarua","Cook Islands",-21.12,-159.46
+"St. George's","Grenada",12.04,-61.44
+"Agaa","Guam",13.28,144.45
+"Victoria","Hong Kong",22.16,114.13
+"Tokyo","Japan",35.40,139.45
+"Pyongyang","North Korea",39.00,125.47
+"Vientiane","Laos",17.59,102.38
+"Tripoli","Libya",32.54,013.11
+"Skopje","Macedonia",42.00,021.28
+"Majuro","Marshall Islands",07.05,171.08
+"Port Louis","Mauritius",-20.10,57.30
+"Monaco","Monaco",43.44,007.25
+"Ulan Bator","Mongolia",47.54,106.52
+"Plymouth","Montserrat",16.44,-62.14
+"Rabat","Morocco",34.02,-06.51
+"Alofi","Niue",-14.27,-178.05
+"Saint-Denis","Runion",-20.52,55.27
+"Victoria","Seychelles",-04.38,55.28
+"Singapore","Singapore",01.18,103.50
+"Colombo","Sri Lanka",06.55,79.52
+"Kingstown","St Vincent and the Grenadines",13.12,-61.14
+"Taipei","Taiwan",25.50,121.32
+"Port-of-Spain","Trinidad and Tobago",10.38,-61.31
+"Cockburn Harbour","Turks and Caicos Islands",21.30,-71.30
+"Charlotte Amalie","US Virgin Islands",18.22,-64.56
+"Vatican City","Vatican State",41.54,12.27
+"Layoune","Western Sahara",27.10,-13.11
+"San'a","Yemen",15.24,44.14
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/sampleData/example2.xls b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/sampleData/example2.xls
new file mode 100755
index 000000000..dd213ab94
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reader/sampleData/example2.xls differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/exampleWorkBookReader01.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/exampleWorkBookReader01.php
new file mode 100755
index 000000000..4f8dfdf7c
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/exampleWorkBookReader01.php
@@ -0,0 +1,93 @@
+
+
+
+
+
+
';
+ echo 'Rows: ', $worksheet['totalRows'], ' Columns: ', $worksheet['totalColumns'], '
';
+ echo 'Cell Range: A1:', $worksheet['lastColumnLetter'], $worksheet['totalRows'];
+ echo 'PHPExcel Reading WorkBook Data Example #01
+Read the WorkBook Properties
+load($inputFileName);
+
+
+echo '
';
+
+/** Read the document's creator property **/
+$creator = $objPHPExcel->getProperties()->getCreator();
+echo 'Document Creator: ',$creator,'
';
+
+/** Read the Date when the workbook was created (as a PHP timestamp value) **/
+$creationDatestamp = $objPHPExcel->getProperties()->getCreated();
+/** Format the date and time using the standard PHP date() function **/
+$creationDate = date('l, d<\s\up>S\s\up> F Y',$creationDatestamp);
+$creationTime = date('g:i A',$creationDatestamp);
+echo 'Created On: ',$creationDate,' at ',$creationTime,'
';
+
+/** Read the name of the last person to modify this workbook **/
+$modifiedBy = $objPHPExcel->getProperties()->getLastModifiedBy();
+echo 'Last Modified By: ',$modifiedBy,'
';
+
+/** Read the Date when the workbook was last modified (as a PHP timestamp value) **/
+$modifiedDatestamp = $objPHPExcel->getProperties()->getModified();
+/** Format the date and time using the standard PHP date() function **/
+$modifiedDate = date('l, d<\s\up>S\s\up> F Y',$modifiedDatestamp);
+$modifiedTime = date('g:i A',$modifiedDatestamp);
+echo 'Last Modified On: ',$modifiedDate,' at ',$modifiedTime,'
';
+
+/** Read the workbook title property **/
+$workbookTitle = $objPHPExcel->getProperties()->getTitle();
+echo 'Title: ',$workbookTitle,'
';
+
+/** Read the workbook description property **/
+$description = $objPHPExcel->getProperties()->getDescription();
+echo 'Description: ',$description,'
';
+
+/** Read the workbook subject property **/
+$subject = $objPHPExcel->getProperties()->getSubject();
+echo 'Subject: ',$subject,'
';
+
+/** Read the workbook keywords property **/
+$keywords = $objPHPExcel->getProperties()->getKeywords();
+echo 'Keywords: ',$keywords,'
';
+
+/** Read the workbook category property **/
+$category = $objPHPExcel->getProperties()->getCategory();
+echo 'Category: ',$category,'
';
+
+/** Read the workbook company property **/
+$company = $objPHPExcel->getProperties()->getCompany();
+echo 'Company: ',$company,'
';
+
+/** Read the workbook manager property **/
+$manager = $objPHPExcel->getProperties()->getManager();
+echo 'Manager: ',$manager,'
';
+
+
+?>
+
+
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/exampleWorkBookReader02.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/exampleWorkBookReader02.php
new file mode 100755
index 000000000..b8c359d3c
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/exampleWorkBookReader02.php
@@ -0,0 +1,52 @@
+
+
+
+
+
+PHPExcel Reading WorkBook Data Example #02
+Read a list of Custom Properties for a WorkBook
+load($inputFileName);
+
+
+echo '
';
+
+/** Read an array list of any custom properties for this document **/
+$customPropertyList = $objPHPExcel->getProperties()->getCustomProperties();
+
+echo 'Custom Property names:
';
+foreach($customPropertyList as $customPropertyName) {
+ echo $customPropertyName,'
';
+}
+
+
+
+?>
+
+
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/exampleWorkBookReader03.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/exampleWorkBookReader03.php
new file mode 100755
index 000000000..8fb350d41
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/exampleWorkBookReader03.php
@@ -0,0 +1,80 @@
+
+
+
+
+
+PHPExcel Reading WorkBook Data Example #03
+Read Custom Property Values for a WorkBook
+load($inputFileName);
+
+
+echo '
';
+
+/** Read an array list of any custom properties for this document **/
+$customPropertyList = $objPHPExcel->getProperties()->getCustomProperties();
+
+echo 'Custom Properties:
';
+/** Loop through the list of custom properties **/
+foreach($customPropertyList as $customPropertyName) {
+ echo '',$customPropertyName,': ';
+ /** Retrieve the property value **/
+ $propertyValue = $objPHPExcel->getProperties()->getCustomPropertyValue($customPropertyName);
+ /** Retrieve the property type **/
+ $propertyType = $objPHPExcel->getProperties()->getCustomPropertyType($customPropertyName);
+
+ /** Manipulate properties as appropriate for display purposes **/
+ switch($propertyType) {
+ case 'i' : // integer
+ $propertyType = 'integer number';
+ break;
+ case 'f' : // float
+ $propertyType = 'floating point number';
+ break;
+ case 's' : // string
+ $propertyType = 'string';
+ break;
+ case 'd' : // date
+ $propertyValue = date('l, d<\s\up>S\s\up> F Y g:i A',$propertyValue);
+ $propertyType = 'date';
+ break;
+ case 'b' : // boolean
+ $propertyValue = ($propertyValue) ? 'TRUE' : 'FALSE';
+ $propertyType = 'boolean';
+ break;
+ }
+
+ echo $propertyValue,' (',$propertyType,')
';
+}
+
+
+
+?>
+
+
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/exampleWorkBookReader04.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/exampleWorkBookReader04.php
new file mode 100755
index 000000000..05ff6374a
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/exampleWorkBookReader04.php
@@ -0,0 +1,55 @@
+
+
+
+
+
+PHPExcel Reading WorkBook Data Example #04
+Get a List of the Worksheets in a WorkBook
+load($inputFileName);
+
+
+echo '
';
+
+echo 'Reading the number of Worksheets in the WorkBook
';
+/** Use the PHPExcel object's getSheetCount() method to get a count of the number of WorkSheets in the WorkBook */
+$sheetCount = $objPHPExcel->getSheetCount();
+echo 'There ',(($sheetCount == 1) ? 'is' : 'are'),' ',$sheetCount,' WorkSheet',(($sheetCount == 1) ? '' : 's'),' in the WorkBook
';
+
+echo 'Reading the names of Worksheets in the WorkBook
';
+/** Use the PHPExcel object's getSheetNames() method to get an array listing the names/titles of the WorkSheets in the WorkBook */
+$sheetNames = $objPHPExcel->getSheetNames();
+foreach($sheetNames as $sheetIndex => $sheetName) {
+ echo 'WorkSheet #',$sheetIndex,' is named "',$sheetName,'"
';
+}
+
+
+?>
+
+
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/sampleData/example1.xls b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/sampleData/example1.xls
new file mode 100755
index 000000000..0db0efdcd
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/sampleData/example1.xls differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/sampleData/example1.xlsx b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/sampleData/example1.xlsx
new file mode 100755
index 000000000..2224dd4fe
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/sampleData/example1.xlsx differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/sampleData/example2.xls b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/sampleData/example2.xls
new file mode 100755
index 000000000..18bfcf474
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/Reading WorkBook Data/sampleData/example2.xls differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Examples/index.php b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/index.php
new file mode 100755
index 000000000..8eb8574b3
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/Examples/index.php
@@ -0,0 +1,50 @@
+
+
+
+
+
+(.*?)
#';
+ $h2Pattern = '#(.*?)
#';
+
+ if (preg_match($h1Pattern, $fileData, $out)) {
+ $h1Text = $out[1];
+ $h2Text = (preg_match($h2Pattern, $fileData, $out)) ? $out[1] : '';
+
+ echo '',$h1Text,'
';
+ if (($h2Text > '') &&
+ (pathinfo($exampleType,PATHINFO_BASENAME) != 'Calculations')) {
+ echo $h2Text,'
';
+ }
+ }
+
+ }
+}
+
+?>
+
+
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/FunctionListByCategory.txt b/Server/vendor/phpoffice/phpexcel/Documentation/FunctionListByCategory.txt
new file mode 100755
index 000000000..b23d9a11c
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/FunctionListByCategory.txt
@@ -0,0 +1,377 @@
+CATEGORY_CUBE
+ CUBEKPIMEMBER *** Not yet Implemented
+ CUBEMEMBER *** Not yet Implemented
+ CUBEMEMBERPROPERTY *** Not yet Implemented
+ CUBERANKEDMEMBER *** Not yet Implemented
+ CUBESET *** Not yet Implemented
+ CUBESETCOUNT *** Not yet Implemented
+ CUBEVALUE *** Not yet Implemented
+
+CATEGORY_DATABASE
+ DAVERAGE PHPExcel_Calculation_Database::DAVERAGE
+ DCOUNT PHPExcel_Calculation_Database::DCOUNT
+ DCOUNTA PHPExcel_Calculation_Database::DCOUNTA
+ DGET PHPExcel_Calculation_Database::DGET
+ DMAX PHPExcel_Calculation_Database::DMAX
+ DMIN PHPExcel_Calculation_Database::DMIN
+ DPRODUCT PHPExcel_Calculation_Database::DPRODUCT
+ DSTDEV PHPExcel_Calculation_Database::DSTDEV
+ DSTDEVP PHPExcel_Calculation_Database::DSTDEVP
+ DSUM PHPExcel_Calculation_Database::DSUM
+ DVAR PHPExcel_Calculation_Database::DVAR
+ DVARP PHPExcel_Calculation_Database::DVARP
+
+CATEGORY_DATE_AND_TIME
+ DATE PHPExcel_Calculation_DateTime::DATE
+ DATEDIF PHPExcel_Calculation_DateTime::DATEDIF
+ DATEVALUE PHPExcel_Calculation_DateTime::DATEVALUE
+ DAY PHPExcel_Calculation_DateTime::DAYOFMONTH
+ DAYS360 PHPExcel_Calculation_DateTime::DAYS360
+ EDATE PHPExcel_Calculation_DateTime::EDATE
+ EOMONTH PHPExcel_Calculation_DateTime::EOMONTH
+ HOUR PHPExcel_Calculation_DateTime::HOUROFDAY
+ MINUTE PHPExcel_Calculation_DateTime::MINUTEOFHOUR
+ MONTH PHPExcel_Calculation_DateTime::MONTHOFYEAR
+ NETWORKDAYS PHPExcel_Calculation_DateTime::NETWORKDAYS
+ NOW PHPExcel_Calculation_DateTime::DATETIMENOW
+ SECOND PHPExcel_Calculation_DateTime::SECONDOFMINUTE
+ TIME PHPExcel_Calculation_DateTime::TIME
+ TIMEVALUE PHPExcel_Calculation_DateTime::TIMEVALUE
+ TODAY PHPExcel_Calculation_DateTime::DATENOW
+ WEEKDAY PHPExcel_Calculation_DateTime::DAYOFWEEK
+ WEEKNUM PHPExcel_Calculation_DateTime::WEEKOFYEAR
+ WORKDAY PHPExcel_Calculation_DateTime::WORKDAY
+ YEAR PHPExcel_Calculation_DateTime::YEAR
+ YEARFRAC PHPExcel_Calculation_DateTime::YEARFRAC
+
+CATEGORY_ENGINEERING
+ BESSELI PHPExcel_Calculation_Engineering::BESSELI
+ BESSELJ PHPExcel_Calculation_Engineering::BESSELJ
+ BESSELK PHPExcel_Calculation_Engineering::BESSELK
+ BESSELY PHPExcel_Calculation_Engineering::BESSELY
+ BIN2DEC PHPExcel_Calculation_Engineering::BINTODEC
+ BIN2HEX PHPExcel_Calculation_Engineering::BINTOHEX
+ BIN2OCT PHPExcel_Calculation_Engineering::BINTOOCT
+ COMPLEX PHPExcel_Calculation_Engineering::COMPLEX
+ CONVERT PHPExcel_Calculation_Engineering::CONVERTUOM
+ DEC2BIN PHPExcel_Calculation_Engineering::DECTOBIN
+ DEC2HEX PHPExcel_Calculation_Engineering::DECTOHEX
+ DEC2OCT PHPExcel_Calculation_Engineering::DECTOOCT
+ DELTA PHPExcel_Calculation_Engineering::DELTA
+ ERF PHPExcel_Calculation_Engineering::ERF
+ ERFC PHPExcel_Calculation_Engineering::ERFC
+ GESTEP PHPExcel_Calculation_Engineering::GESTEP
+ HEX2BIN PHPExcel_Calculation_Engineering::HEXTOBIN
+ HEX2DEC PHPExcel_Calculation_Engineering::HEXTODEC
+ HEX2OCT PHPExcel_Calculation_Engineering::HEXTOOCT
+ IMABS PHPExcel_Calculation_Engineering::IMABS
+ IMAGINARY PHPExcel_Calculation_Engineering::IMAGINARY
+ IMARGUMENT PHPExcel_Calculation_Engineering::IMARGUMENT
+ IMCONJUGATE PHPExcel_Calculation_Engineering::IMCONJUGATE
+ IMCOS PHPExcel_Calculation_Engineering::IMCOS
+ IMDIV PHPExcel_Calculation_Engineering::IMDIV
+ IMEXP PHPExcel_Calculation_Engineering::IMEXP
+ IMLN PHPExcel_Calculation_Engineering::IMLN
+ IMLOG10 PHPExcel_Calculation_Engineering::IMLOG10
+ IMLOG2 PHPExcel_Calculation_Engineering::IMLOG2
+ IMPOWER PHPExcel_Calculation_Engineering::IMPOWER
+ IMPRODUCT PHPExcel_Calculation_Engineering::IMPRODUCT
+ IMREAL PHPExcel_Calculation_Engineering::IMREAL
+ IMSIN PHPExcel_Calculation_Engineering::IMSIN
+ IMSQRT PHPExcel_Calculation_Engineering::IMSQRT
+ IMSUB PHPExcel_Calculation_Engineering::IMSUB
+ IMSUM PHPExcel_Calculation_Engineering::IMSUM
+ OCT2BIN PHPExcel_Calculation_Engineering::OCTTOBIN
+ OCT2DEC PHPExcel_Calculation_Engineering::OCTTODEC
+ OCT2HEX PHPExcel_Calculation_Engineering::OCTTOHEX
+
+CATEGORY_FINANCIAL
+ ACCRINT PHPExcel_Calculation_Financial::ACCRINT
+ ACCRINTM PHPExcel_Calculation_Financial::ACCRINTM
+ AMORDEGRC PHPExcel_Calculation_Financial::AMORDEGRC
+ AMORLINC PHPExcel_Calculation_Financial::AMORLINC
+ COUPDAYBS PHPExcel_Calculation_Financial::COUPDAYBS
+ COUPDAYS PHPExcel_Calculation_Financial::COUPDAYS
+ COUPDAYSNC PHPExcel_Calculation_Financial::COUPDAYSNC
+ COUPNCD PHPExcel_Calculation_Financial::COUPNCD
+ COUPNUM PHPExcel_Calculation_Financial::COUPNUM
+ COUPPCD PHPExcel_Calculation_Financial::COUPPCD
+ CUMIPMT PHPExcel_Calculation_Financial::CUMIPMT
+ CUMPRINC PHPExcel_Calculation_Financial::CUMPRINC
+ DB PHPExcel_Calculation_Financial::DB
+ DDB PHPExcel_Calculation_Financial::DDB
+ DISC PHPExcel_Calculation_Financial::DISC
+ DOLLARDE PHPExcel_Calculation_Financial::DOLLARDE
+ DOLLARFR PHPExcel_Calculation_Financial::DOLLARFR
+ DURATION *** Not yet Implemented
+ EFFECT PHPExcel_Calculation_Financial::EFFECT
+ FV PHPExcel_Calculation_Financial::FV
+ FVSCHEDULE PHPExcel_Calculation_Financial::FVSCHEDULE
+ INTRATE PHPExcel_Calculation_Financial::INTRATE
+ IPMT PHPExcel_Calculation_Financial::IPMT
+ IRR PHPExcel_Calculation_Financial::IRR
+ ISPMT PHPExcel_Calculation_Financial::ISPMT
+ MDURATION *** Not yet Implemented
+ MIRR PHPExcel_Calculation_Financial::MIRR
+ NOMINAL PHPExcel_Calculation_Financial::NOMINAL
+ NPER PHPExcel_Calculation_Financial::NPER
+ NPV PHPExcel_Calculation_Financial::NPV
+ ODDFPRICE *** Not yet Implemented
+ ODDFYIELD *** Not yet Implemented
+ ODDLPRICE *** Not yet Implemented
+ ODDLYIELD *** Not yet Implemented
+ PMT PHPExcel_Calculation_Financial::PMT
+ PPMT PHPExcel_Calculation_Financial::PPMT
+ PRICE PHPExcel_Calculation_Financial::PRICE
+ PRICEDISC PHPExcel_Calculation_Financial::PRICEDISC
+ PRICEMAT PHPExcel_Calculation_Financial::PRICEMAT
+ PV PHPExcel_Calculation_Financial::PV
+ RATE PHPExcel_Calculation_Financial::RATE
+ RECEIVED PHPExcel_Calculation_Financial::RECEIVED
+ SLN PHPExcel_Calculation_Financial::SLN
+ SYD PHPExcel_Calculation_Financial::SYD
+ TBILLEQ PHPExcel_Calculation_Financial::TBILLEQ
+ TBILLPRICE PHPExcel_Calculation_Financial::TBILLPRICE
+ TBILLYIELD PHPExcel_Calculation_Financial::TBILLYIELD
+ USDOLLAR *** Not yet Implemented
+ VDB *** Not yet Implemented
+ XIRR PHPExcel_Calculation_Financial::XIRR
+ XNPV PHPExcel_Calculation_Financial::XNPV
+ YIELD *** Not yet Implemented
+ YIELDDISC PHPExcel_Calculation_Financial::YIELDDISC
+ YIELDMAT PHPExcel_Calculation_Financial::YIELDMAT
+
+CATEGORY_INFORMATION
+ CELL *** Not yet Implemented
+ ERROR.TYPE PHPExcel_Calculation_Functions::ERROR_TYPE
+ INFO *** Not yet Implemented
+ ISBLANK PHPExcel_Calculation_Functions::IS_BLANK
+ ISERR PHPExcel_Calculation_Functions::IS_ERR
+ ISERROR PHPExcel_Calculation_Functions::IS_ERROR
+ ISEVEN PHPExcel_Calculation_Functions::IS_EVEN
+ ISLOGICAL PHPExcel_Calculation_Functions::IS_LOGICAL
+ ISNA PHPExcel_Calculation_Functions::IS_NA
+ ISNONTEXT PHPExcel_Calculation_Functions::IS_NONTEXT
+ ISNUMBER PHPExcel_Calculation_Functions::IS_NUMBER
+ ISODD PHPExcel_Calculation_Functions::IS_ODD
+ ISREF *** Not yet Implemented
+ ISTEXT PHPExcel_Calculation_Functions::IS_TEXT
+ N PHPExcel_Calculation_Functions::N
+ NA PHPExcel_Calculation_Functions::NA
+ TYPE PHPExcel_Calculation_Functions::TYPE
+ VERSION PHPExcel_Calculation_Functions::VERSION
+
+CATEGORY_LOGICAL
+ AND PHPExcel_Calculation_Logical::LOGICAL_AND
+ FALSE PHPExcel_Calculation_Logical::FALSE
+ IF PHPExcel_Calculation_Logical::STATEMENT_IF
+ IFERROR PHPExcel_Calculation_Logical::IFERROR
+ NOT PHPExcel_Calculation_Logical::NOT
+ OR PHPExcel_Calculation_Logical::LOGICAL_OR
+ TRUE PHPExcel_Calculation_Logical::TRUE
+
+CATEGORY_LOOKUP_AND_REFERENCE
+ ADDRESS PHPExcel_Calculation_LookupRef::CELL_ADDRESS
+ AREAS *** Not yet Implemented
+ CHOOSE PHPExcel_Calculation_LookupRef::CHOOSE
+ COLUMN PHPExcel_Calculation_LookupRef::COLUMN
+ COLUMNS PHPExcel_Calculation_LookupRef::COLUMNS
+ GETPIVOTDATA *** Not yet Implemented
+ HLOOKUP PHPExcel_Calculation_LookupRef::HLOOKUP
+ HYPERLINK PHPExcel_Calculation_LookupRef::HYPERLINK
+ INDEX PHPExcel_Calculation_LookupRef::INDEX
+ INDIRECT PHPExcel_Calculation_LookupRef::INDIRECT
+ LOOKUP PHPExcel_Calculation_LookupRef::LOOKUP
+ MATCH PHPExcel_Calculation_LookupRef::MATCH
+ OFFSET PHPExcel_Calculation_LookupRef::OFFSET
+ ROW PHPExcel_Calculation_LookupRef::ROW
+ ROWS PHPExcel_Calculation_LookupRef::ROWS
+ RTD *** Not yet Implemented
+ TRANSPOSE PHPExcel_Calculation_LookupRef::TRANSPOSE
+ VLOOKUP PHPExcel_Calculation_LookupRef::VLOOKUP
+
+CATEGORY_MATH_AND_TRIG
+ ABS abs
+ ACOS acos
+ ACOSH acosh
+ ASIN asin
+ ASINH asinh
+ ATAN atan
+ ATAN2 PHPExcel_Calculation_MathTrig::REVERSE_ATAN2
+ ATANH atanh
+ CEILING PHPExcel_Calculation_MathTrig::CEILING
+ COMBIN PHPExcel_Calculation_MathTrig::COMBIN
+ COS cos
+ COSH cosh
+ DEGREES rad2deg
+ EVEN PHPExcel_Calculation_MathTrig::EVEN
+ EXP exp
+ FACT PHPExcel_Calculation_MathTrig::FACT
+ FACTDOUBLE PHPExcel_Calculation_MathTrig::FACTDOUBLE
+ FLOOR PHPExcel_Calculation_MathTrig::FLOOR
+ GCD PHPExcel_Calculation_MathTrig::GCD
+ INT PHPExcel_Calculation_MathTrig::INT
+ LCM PHPExcel_Calculation_MathTrig::LCM
+ LN log
+ LOG PHPExcel_Calculation_MathTrig::LOG_BASE
+ LOG10 log10
+ MDETERM PHPExcel_Calculation_MathTrig::MDETERM
+ MINVERSE PHPExcel_Calculation_MathTrig::MINVERSE
+ MMULT PHPExcel_Calculation_MathTrig::MMULT
+ MOD PHPExcel_Calculation_MathTrig::MOD
+ MROUND PHPExcel_Calculation_MathTrig::MROUND
+ MULTINOMIAL PHPExcel_Calculation_MathTrig::MULTINOMIAL
+ ODD PHPExcel_Calculation_MathTrig::ODD
+ PI pi
+ POWER PHPExcel_Calculation_MathTrig::POWER
+ PRODUCT PHPExcel_Calculation_MathTrig::PRODUCT
+ QUOTIENT PHPExcel_Calculation_MathTrig::QUOTIENT
+ RADIANS deg2rad
+ RAND PHPExcel_Calculation_MathTrig::RAND
+ RANDBETWEEN PHPExcel_Calculation_MathTrig::RAND
+ ROMAN PHPExcel_Calculation_MathTrig::ROMAN
+ ROUND round
+ ROUNDDOWN PHPExcel_Calculation_MathTrig::ROUNDDOWN
+ ROUNDUP PHPExcel_Calculation_MathTrig::ROUNDUP
+ SERIESSUM PHPExcel_Calculation_MathTrig::SERIESSUM
+ SIGN PHPExcel_Calculation_MathTrig::SIGN
+ SIN sin
+ SINH sinh
+ SQRT sqrt
+ SQRTPI PHPExcel_Calculation_MathTrig::SQRTPI
+ SUBTOTAL PHPExcel_Calculation_MathTrig::SUBTOTAL
+ SUM PHPExcel_Calculation_MathTrig::SUM
+ SUMIF PHPExcel_Calculation_MathTrig::SUMIF
+ SUMIFS *** Not yet Implemented
+ SUMPRODUCT PHPExcel_Calculation_MathTrig::SUMPRODUCT
+ SUMSQ PHPExcel_Calculation_MathTrig::SUMSQ
+ SUMX2MY2 PHPExcel_Calculation_MathTrig::SUMX2MY2
+ SUMX2PY2 PHPExcel_Calculation_MathTrig::SUMX2PY2
+ SUMXMY2 PHPExcel_Calculation_MathTrig::SUMXMY2
+ TAN tan
+ TANH tanh
+ TRUNC PHPExcel_Calculation_MathTrig::TRUNC
+
+CATEGORY_STATISTICAL
+ AVEDEV PHPExcel_Calculation_Statistical::AVEDEV
+ AVERAGE PHPExcel_Calculation_Statistical::AVERAGE
+ AVERAGEA PHPExcel_Calculation_Statistical::AVERAGEA
+ AVERAGEIF PHPExcel_Calculation_Statistical::AVERAGEIF
+ AVERAGEIFS *** Not yet Implemented
+ BETADIST PHPExcel_Calculation_Statistical::BETADIST
+ BETAINV PHPExcel_Calculation_Statistical::BETAINV
+ BINOMDIST PHPExcel_Calculation_Statistical::BINOMDIST
+ CHIDIST PHPExcel_Calculation_Statistical::CHIDIST
+ CHIINV PHPExcel_Calculation_Statistical::CHIINV
+ CHITEST *** Not yet Implemented
+ CONFIDENCE PHPExcel_Calculation_Statistical::CONFIDENCE
+ CORREL PHPExcel_Calculation_Statistical::CORREL
+ COUNT PHPExcel_Calculation_Statistical::COUNT
+ COUNTA PHPExcel_Calculation_Statistical::COUNTA
+ COUNTBLANK PHPExcel_Calculation_Statistical::COUNTBLANK
+ COUNTIF PHPExcel_Calculation_Statistical::COUNTIF
+ COUNTIFS *** Not yet Implemented
+ COVAR PHPExcel_Calculation_Statistical::COVAR
+ CRITBINOM PHPExcel_Calculation_Statistical::CRITBINOM
+ DEVSQ PHPExcel_Calculation_Statistical::DEVSQ
+ EXPONDIST PHPExcel_Calculation_Statistical::EXPONDIST
+ FDIST *** Not yet Implemented
+ FINV *** Not yet Implemented
+ FISHER PHPExcel_Calculation_Statistical::FISHER
+ FISHERINV PHPExcel_Calculation_Statistical::FISHERINV
+ FORECAST PHPExcel_Calculation_Statistical::FORECAST
+ FREQUENCY *** Not yet Implemented
+ FTEST *** Not yet Implemented
+ GAMMADIST PHPExcel_Calculation_Statistical::GAMMADIST
+ GAMMAINV PHPExcel_Calculation_Statistical::GAMMAINV
+ GAMMALN PHPExcel_Calculation_Statistical::GAMMALN
+ GEOMEAN PHPExcel_Calculation_Statistical::GEOMEAN
+ GROWTH PHPExcel_Calculation_Statistical::GROWTH
+ HARMEAN PHPExcel_Calculation_Statistical::HARMEAN
+ HYPGEOMDIST PHPExcel_Calculation_Statistical::HYPGEOMDIST
+ INTERCEPT PHPExcel_Calculation_Statistical::INTERCEPT
+ KURT PHPExcel_Calculation_Statistical::KURT
+ LARGE PHPExcel_Calculation_Statistical::LARGE
+ LINEST PHPExcel_Calculation_Statistical::LINEST
+ LOGEST PHPExcel_Calculation_Statistical::LOGEST
+ LOGINV PHPExcel_Calculation_Statistical::LOGINV
+ LOGNORMDIST PHPExcel_Calculation_Statistical::LOGNORMDIST
+ MAX PHPExcel_Calculation_Statistical::MAX
+ MAXA PHPExcel_Calculation_Statistical::MAXA
+ MAXIF PHPExcel_Calculation_Statistical::MAXIF
+ MEDIAN PHPExcel_Calculation_Statistical::MEDIAN
+ MEDIANIF *** Not yet Implemented
+ MIN PHPExcel_Calculation_Statistical::MIN
+ MINA PHPExcel_Calculation_Statistical::MINA
+ MINIF PHPExcel_Calculation_Statistical::MINIF
+ MODE PHPExcel_Calculation_Statistical::MODE
+ NEGBINOMDIST PHPExcel_Calculation_Statistical::NEGBINOMDIST
+ NORMDIST PHPExcel_Calculation_Statistical::NORMDIST
+ NORMINV PHPExcel_Calculation_Statistical::NORMINV
+ NORMSDIST PHPExcel_Calculation_Statistical::NORMSDIST
+ NORMSINV PHPExcel_Calculation_Statistical::NORMSINV
+ PEARSON PHPExcel_Calculation_Statistical::CORREL
+ PERCENTILE PHPExcel_Calculation_Statistical::PERCENTILE
+ PERCENTRANK PHPExcel_Calculation_Statistical::PERCENTRANK
+ PERMUT PHPExcel_Calculation_Statistical::PERMUT
+ POISSON PHPExcel_Calculation_Statistical::POISSON
+ PROB *** Not yet Implemented
+ QUARTILE PHPExcel_Calculation_Statistical::QUARTILE
+ RANK PHPExcel_Calculation_Statistical::RANK
+ RSQ PHPExcel_Calculation_Statistical::RSQ
+ SKEW PHPExcel_Calculation_Statistical::SKEW
+ SLOPE PHPExcel_Calculation_Statistical::SLOPE
+ SMALL PHPExcel_Calculation_Statistical::SMALL
+ STANDARDIZE PHPExcel_Calculation_Statistical::STANDARDIZE
+ STDEV PHPExcel_Calculation_Statistical::STDEV
+ STDEVA PHPExcel_Calculation_Statistical::STDEVA
+ STDEVP PHPExcel_Calculation_Statistical::STDEVP
+ STDEVPA PHPExcel_Calculation_Statistical::STDEVPA
+ STEYX PHPExcel_Calculation_Statistical::STEYX
+ TDIST PHPExcel_Calculation_Statistical::TDIST
+ TINV PHPExcel_Calculation_Statistical::TINV
+ TREND PHPExcel_Calculation_Statistical::TREND
+ TRIMMEAN PHPExcel_Calculation_Statistical::TRIMMEAN
+ TTEST *** Not yet Implemented
+ VAR PHPExcel_Calculation_Statistical::VARFunc
+ VARA PHPExcel_Calculation_Statistical::VARA
+ VARP PHPExcel_Calculation_Statistical::VARP
+ VARPA PHPExcel_Calculation_Statistical::VARPA
+ WEIBULL PHPExcel_Calculation_Statistical::WEIBULL
+ ZTEST PHPExcel_Calculation_Statistical::ZTEST
+
+CATEGORY_TEXT_AND_DATA
+ ASC *** Not yet Implemented
+ BAHTTEXT *** Not yet Implemented
+ CHAR PHPExcel_Calculation_TextData::CHARACTER
+ CLEAN PHPExcel_Calculation_TextData::TRIMNONPRINTABLE
+ CODE PHPExcel_Calculation_TextData::ASCIICODE
+ CONCATENATE PHPExcel_Calculation_TextData::CONCATENATE
+ DOLLAR PHPExcel_Calculation_TextData::DOLLAR
+ EXACT *** Not yet Implemented
+ FIND PHPExcel_Calculation_TextData::SEARCHSENSITIVE
+ FINDB PHPExcel_Calculation_TextData::SEARCHSENSITIVE
+ FIXED PHPExcel_Calculation_TextData::FIXEDFORMAT
+ JIS *** Not yet Implemented
+ LEFT PHPExcel_Calculation_TextData::LEFT
+ LEFTB PHPExcel_Calculation_TextData::LEFT
+ LEN PHPExcel_Calculation_TextData::STRINGLENGTH
+ LENB PHPExcel_Calculation_TextData::STRINGLENGTH
+ LOWER PHPExcel_Calculation_TextData::LOWERCASE
+ MID PHPExcel_Calculation_TextData::MID
+ MIDB PHPExcel_Calculation_TextData::MID
+ PHONETIC *** Not yet Implemented
+ PROPER PHPExcel_Calculation_TextData::PROPERCASE
+ REPLACE PHPExcel_Calculation_TextData::REPLACE
+ REPLACEB PHPExcel_Calculation_TextData::REPLACE
+ REPT str_repeat
+ RIGHT PHPExcel_Calculation_TextData::RIGHT
+ RIGHTB PHPExcel_Calculation_TextData::RIGHT
+ SEARCH PHPExcel_Calculation_TextData::SEARCHINSENSITIVE
+ SEARCHB PHPExcel_Calculation_TextData::SEARCHINSENSITIVE
+ SUBSTITUTE PHPExcel_Calculation_TextData::SUBSTITUTE
+ T PHPExcel_Calculation_TextData::RETURNSTRING
+ TEXT PHPExcel_Calculation_TextData::TEXTFORMAT
+ TRIM PHPExcel_Calculation_TextData::TRIMSPACES
+ UPPER PHPExcel_Calculation_TextData::UPPERCASE
+ VALUE PHPExcel_Calculation_TextData::VALUE
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/FunctionListByName.txt b/Server/vendor/phpoffice/phpexcel/Documentation/FunctionListByName.txt
new file mode 100755
index 000000000..45a9daf73
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/FunctionListByName.txt
@@ -0,0 +1,381 @@
+ABS CATEGORY_MATH_AND_TRIG abs
+ACCRINT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::ACCRINT
+ACCRINTM CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::ACCRINTM
+ACOS CATEGORY_MATH_AND_TRIG acos
+ACOSH CATEGORY_MATH_AND_TRIG acosh
+ADDRESS CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::CELL_ADDRESS
+AMORDEGRC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::AMORDEGRC
+AMORLINC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::AMORLINC
+AND CATEGORY_LOGICAL PHPExcel_Calculation_Logical::LOGICAL_AND
+AREAS CATEGORY_LOOKUP_AND_REFERENCE *** Not yet Implemented
+ASC CATEGORY_TEXT_AND_DATA *** Not yet Implemented
+ASIN CATEGORY_MATH_AND_TRIG asin
+ASINH CATEGORY_MATH_AND_TRIG asinh
+ATAN CATEGORY_MATH_AND_TRIG atan
+ATAN2 CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::REVERSE_ATAN2
+ATANH CATEGORY_MATH_AND_TRIG atanh
+AVEDEV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::AVEDEV
+AVERAGE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::AVERAGE
+AVERAGEA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::AVERAGEA
+AVERAGEIF CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::AVERAGEIF
+AVERAGEIFS CATEGORY_STATISTICAL *** Not yet Implemented
+
+BAHTTEXT CATEGORY_TEXT_AND_DATA *** Not yet Implemented
+BESSELI CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BESSELI
+BESSELJ CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BESSELJ
+BESSELK CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BESSELK
+BESSELY CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BESSELY
+BETADIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::BETADIST
+BETAINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::BETAINV
+BIN2DEC CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BINTODEC
+BIN2HEX CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BINTOHEX
+BIN2OCT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BINTOOCT
+BINOMDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::BINOMDIST
+
+CEILING CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::CEILING
+CELL CATEGORY_INFORMATION *** Not yet Implemented
+CHAR CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::CHARACTER
+CHIDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::CHIDIST
+CHIINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::CHIINV
+CHITEST CATEGORY_STATISTICAL *** Not yet Implemented
+CHOOSE CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::CHOOSE
+CLEAN CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::TRIMNONPRINTABLE
+CODE CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::ASCIICODE
+COLUMN CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::COLUMN
+COLUMNS CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::COLUMNS
+COMBIN CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::COMBIN
+COMPLEX CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::COMPLEX
+CONCATENATE CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::CONCATENATE
+CONFIDENCE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::CONFIDENCE
+CONVERT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::CONVERTUOM
+CORREL CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::CORREL
+COS CATEGORY_MATH_AND_TRIG cos
+COSH CATEGORY_MATH_AND_TRIG cosh
+COUNT CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::COUNT
+COUNTA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::COUNTA
+COUNTBLANK CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::COUNTBLANK
+COUNTIF CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::COUNTIF
+COUNTIFS CATEGORY_STATISTICAL *** Not yet Implemented
+COUPDAYBS CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::COUPDAYBS
+COUPDAYS CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::COUPDAYS
+COUPDAYSNC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::COUPDAYSNC
+COUPNCD CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::COUPNCD
+COUPNUM CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::COUPNUM
+COUPPCD CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::COUPPCD
+COVAR CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::COVAR
+CRITBINOM CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::CRITBINOM
+CUBEKPIMEMBER CATEGORY_CUBE *** Not yet Implemented
+CUBEMEMBER CATEGORY_CUBE *** Not yet Implemented
+CUBEMEMBERPROPERTY CATEGORY_CUBE *** Not yet Implemented
+CUBERANKEDMEMBER CATEGORY_CUBE *** Not yet Implemented
+CUBESET CATEGORY_CUBE *** Not yet Implemented
+CUBESETCOUNT CATEGORY_CUBE *** Not yet Implemented
+CUBEVALUE CATEGORY_CUBE *** Not yet Implemented
+CUMIPMT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::CUMIPMT
+CUMPRINC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::CUMPRINC
+
+DATE CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DATE
+DATEDIF CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DATEDIF
+DATEVALUE CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DATEVALUE
+DAVERAGE CATEGORY_DATABASE PHPExcel_Calculation_Database::DAVERAGE
+DAY CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DAYOFMONTH
+DAYS360 CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DAYS360
+DB CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::DB
+DCOUNT CATEGORY_DATABASE PHPExcel_Calculation_Database::DCOUNT
+DCOUNTA CATEGORY_DATABASE PHPExcel_Calculation_Database::DCOUNTA
+DDB CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::DDB
+DEC2BIN CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::DECTOBIN
+DEC2HEX CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::DECTOHEX
+DEC2OCT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::DECTOOCT
+DEGREES CATEGORY_MATH_AND_TRIG rad2deg
+DELTA CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::DELTA
+DEVSQ CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::DEVSQ
+DGET CATEGORY_DATABASE PHPExcel_Calculation_Database::DGET
+DISC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::DISC
+DMAX CATEGORY_DATABASE PHPExcel_Calculation_Database::DMAX
+DMIN CATEGORY_DATABASE PHPExcel_Calculation_Database::DMIN
+DOLLAR CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::DOLLAR
+DOLLARDE CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::DOLLARDE
+DOLLARFR CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::DOLLARFR
+DPRODUCT CATEGORY_DATABASE PHPExcel_Calculation_Database::DPRODUCT
+DSTDEV CATEGORY_DATABASE PHPExcel_Calculation_Database::DSTDEV
+DSTDEVP CATEGORY_DATABASE PHPExcel_Calculation_Database::DSTDEVP
+DSUM CATEGORY_DATABASE PHPExcel_Calculation_Database::DSUM
+DURATION CATEGORY_FINANCIAL *** Not yet Implemented
+DVAR CATEGORY_DATABASE PHPExcel_Calculation_Database::DVAR
+DVARP CATEGORY_DATABASE PHPExcel_Calculation_Database::DVARP
+
+EDATE CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::EDATE
+EFFECT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::EFFECT
+EOMONTH CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::EOMONTH
+ERF CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::ERF
+ERFC CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::ERFC
+ERROR.TYPE CATEGORY_INFORMATION PHPExcel_Calculation_Functions::ERROR_TYPE
+EVEN CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::EVEN
+EXACT CATEGORY_TEXT_AND_DATA *** Not yet Implemented
+EXP CATEGORY_MATH_AND_TRIG exp
+EXPONDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::EXPONDIST
+
+FACT CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::FACT
+FACTDOUBLE CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::FACTDOUBLE
+FALSE CATEGORY_LOGICAL PHPExcel_Calculation_Logical::FALSE
+FDIST CATEGORY_STATISTICAL *** Not yet Implemented
+FIND CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::SEARCHSENSITIVE
+FINDB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::SEARCHSENSITIVE
+FINV CATEGORY_STATISTICAL *** Not yet Implemented
+FISHER CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::FISHER
+FISHERINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::FISHERINV
+FIXED CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::FIXEDFORMAT
+FLOOR CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::FLOOR
+FORECAST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::FORECAST
+FREQUENCY CATEGORY_STATISTICAL *** Not yet Implemented
+FTEST CATEGORY_STATISTICAL *** Not yet Implemented
+FV CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::FV
+FVSCHEDULE CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::FVSCHEDULE
+
+GAMMADIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::GAMMADIST
+GAMMAINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::GAMMAINV
+GAMMALN CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::GAMMALN
+GCD CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::GCD
+GEOMEAN CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::GEOMEAN
+GESTEP CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::GESTEP
+GETPIVOTDATA CATEGORY_LOOKUP_AND_REFERENCE *** Not yet Implemented
+GROWTH CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::GROWTH
+
+HARMEAN CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::HARMEAN
+HEX2BIN CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::HEXTOBIN
+HEX2DEC CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::HEXTODEC
+HEX2OCT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::HEXTOOCT
+HLOOKUP CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::HLOOKUP
+HOUR CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::HOUROFDAY
+HYPERLINK CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::HYPERLINK
+HYPGEOMDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::HYPGEOMDIST
+
+IF CATEGORY_LOGICAL PHPExcel_Calculation_Logical::STATEMENT_IF
+IFERROR CATEGORY_LOGICAL PHPExcel_Calculation_Logical::IFERROR
+IMABS CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMABS
+IMAGINARY CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMAGINARY
+IMARGUMENT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMARGUMENT
+IMCONJUGATE CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMCONJUGATE
+IMCOS CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMCOS
+IMDIV CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMDIV
+IMEXP CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMEXP
+IMLN CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMLN
+IMLOG10 CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMLOG10
+IMLOG2 CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMLOG2
+IMPOWER CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMPOWER
+IMPRODUCT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMPRODUCT
+IMREAL CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMREAL
+IMSIN CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMSIN
+IMSQRT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMSQRT
+IMSUB CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMSUB
+IMSUM CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMSUM
+INDEX CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::INDEX
+INDIRECT CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::INDIRECT
+INFO CATEGORY_INFORMATION *** Not yet Implemented
+INT CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::INT
+INTERCEPT CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::INTERCEPT
+INTRATE CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::INTRATE
+IPMT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::IPMT
+IRR CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::IRR
+ISBLANK CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_BLANK
+ISERR CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_ERR
+ISERROR CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_ERROR
+ISEVEN CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_EVEN
+ISLOGICAL CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_LOGICAL
+ISNA CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_NA
+ISNONTEXT CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_NONTEXT
+ISNUMBER CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_NUMBER
+ISODD CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_ODD
+ISPMT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::ISPMT
+ISREF CATEGORY_INFORMATION *** Not yet Implemented
+ISTEXT CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_TEXT
+
+JIS CATEGORY_TEXT_AND_DATA *** Not yet Implemented
+
+KURT CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::KURT
+
+LARGE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::LARGE
+LCM CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::LCM
+LEFT CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::LEFT
+LEFTB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::LEFT
+LEN CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::STRINGLENGTH
+LENB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::STRINGLENGTH
+LINEST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::LINEST
+LN CATEGORY_MATH_AND_TRIG log
+LOG CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::LOG_BASE
+LOG10 CATEGORY_MATH_AND_TRIG log10
+LOGEST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::LOGEST
+LOGINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::LOGINV
+LOGNORMDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::LOGNORMDIST
+LOOKUP CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::LOOKUP
+LOWER CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::LOWERCASE
+
+MATCH CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::MATCH
+MAX CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MAX
+MAXA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MAXA
+MAXIF CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MAXIF
+MDETERM CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::MDETERM
+MDURATION CATEGORY_FINANCIAL *** Not yet Implemented
+MEDIAN CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MEDIAN
+MEDIANIF CATEGORY_STATISTICAL *** Not yet Implemented
+MID CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::MID
+MIDB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::MID
+MIN CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MIN
+MINA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MINA
+MINIF CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MINIF
+MINUTE CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::MINUTEOFHOUR
+MINVERSE CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::MINVERSE
+MIRR CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::MIRR
+MMULT CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::MMULT
+MOD CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::MOD
+MODE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MODE
+MONTH CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::MONTHOFYEAR
+MROUND CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::MROUND
+MULTINOMIAL CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::MULTINOMIAL
+
+N CATEGORY_INFORMATION PHPExcel_Calculation_Functions::N
+NA CATEGORY_INFORMATION PHPExcel_Calculation_Functions::NA
+NEGBINOMDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::NEGBINOMDIST
+NETWORKDAYS CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::NETWORKDAYS
+NOMINAL CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::NOMINAL
+NORMDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::NORMDIST
+NORMINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::NORMINV
+NORMSDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::NORMSDIST
+NORMSINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::NORMSINV
+NOT CATEGORY_LOGICAL PHPExcel_Calculation_Logical::NOT
+NOW CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DATETIMENOW
+NPER CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::NPER
+NPV CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::NPV
+
+OCT2BIN CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::OCTTOBIN
+OCT2DEC CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::OCTTODEC
+OCT2HEX CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::OCTTOHEX
+ODD CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::ODD
+ODDFPRICE CATEGORY_FINANCIAL *** Not yet Implemented
+ODDFYIELD CATEGORY_FINANCIAL *** Not yet Implemented
+ODDLPRICE CATEGORY_FINANCIAL *** Not yet Implemented
+ODDLYIELD CATEGORY_FINANCIAL *** Not yet Implemented
+OFFSET CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::OFFSET
+OR CATEGORY_LOGICAL PHPExcel_Calculation_Logical::LOGICAL_OR
+
+PEARSON CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::CORREL
+PERCENTILE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::PERCENTILE
+PERCENTRANK CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::PERCENTRANK
+PERMUT CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::PERMUT
+PHONETIC CATEGORY_TEXT_AND_DATA *** Not yet Implemented
+PI CATEGORY_MATH_AND_TRIG pi
+PMT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::PMT
+POISSON CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::POISSON
+POWER CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::POWER
+PPMT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::PPMT
+PRICE CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::PRICE
+PRICEDISC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::PRICEDISC
+PRICEMAT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::PRICEMAT
+PROB CATEGORY_STATISTICAL *** Not yet Implemented
+PRODUCT CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::PRODUCT
+PROPER CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::PROPERCASE
+PV CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::PV
+
+QUARTILE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::QUARTILE
+QUOTIENT CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::QUOTIENT
+
+RADIANS CATEGORY_MATH_AND_TRIG deg2rad
+RAND CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::RAND
+RANDBETWEEN CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::RAND
+RANK CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::RANK
+RATE CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::RATE
+RECEIVED CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::RECEIVED
+REPLACE CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::REPLACE
+REPLACEB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::REPLACE
+REPT CATEGORY_TEXT_AND_DATA str_repeat
+RIGHT CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::RIGHT
+RIGHTB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::RIGHT
+ROMAN CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::ROMAN
+ROUND CATEGORY_MATH_AND_TRIG round
+ROUNDDOWN CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::ROUNDDOWN
+ROUNDUP CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::ROUNDUP
+ROW CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::ROW
+ROWS CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::ROWS
+RSQ CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::RSQ
+RTD CATEGORY_LOOKUP_AND_REFERENCE *** Not yet Implemented
+
+SEARCH CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::SEARCHINSENSITIVE
+SEARCHB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::SEARCHINSENSITIVE
+SECOND CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::SECONDOFMINUTE
+SERIESSUM CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SERIESSUM
+SIGN CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SIGN
+SIN CATEGORY_MATH_AND_TRIG sin
+SINH CATEGORY_MATH_AND_TRIG sinh
+SKEW CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::SKEW
+SLN CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::SLN
+SLOPE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::SLOPE
+SMALL CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::SMALL
+SQRT CATEGORY_MATH_AND_TRIG sqrt
+SQRTPI CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SQRTPI
+STANDARDIZE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::STANDARDIZE
+STDEV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::STDEV
+STDEVA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::STDEVA
+STDEVP CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::STDEVP
+STDEVPA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::STDEVPA
+STEYX CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::STEYX
+SUBSTITUTE CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::SUBSTITUTE
+SUBTOTAL CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUBTOTAL
+SUM CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUM
+SUMIF CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUMIF
+SUMIFS CATEGORY_MATH_AND_TRIG *** Not yet Implemented
+SUMPRODUCT CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUMPRODUCT
+SUMSQ CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUMSQ
+SUMX2MY2 CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUMX2MY2
+SUMX2PY2 CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUMX2PY2
+SUMXMY2 CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUMXMY2
+SYD CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::SYD
+
+T CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::RETURNSTRING
+TAN CATEGORY_MATH_AND_TRIG tan
+TANH CATEGORY_MATH_AND_TRIG tanh
+TBILLEQ CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::TBILLEQ
+TBILLPRICE CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::TBILLPRICE
+TBILLYIELD CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::TBILLYIELD
+TDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::TDIST
+TEXT CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::TEXTFORMAT
+TIME CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::TIME
+TIMEVALUE CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::TIMEVALUE
+TINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::TINV
+TODAY CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DATENOW
+TRANSPOSE CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::TRANSPOSE
+TREND CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::TREND
+TRIM CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::TRIMSPACES
+TRIMMEAN CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::TRIMMEAN
+TRUE CATEGORY_LOGICAL PHPExcel_Calculation_Logical::TRUE
+TRUNC CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::TRUNC
+TTEST CATEGORY_STATISTICAL *** Not yet Implemented
+TYPE CATEGORY_INFORMATION PHPExcel_Calculation_Functions::TYPE
+
+UPPER CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::UPPERCASE
+USDOLLAR CATEGORY_FINANCIAL *** Not yet Implemented
+
+VALUE CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::VALUE
+VAR CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::VARFunc
+VARA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::VARA
+VARP CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::VARP
+VARPA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::VARPA
+VDB CATEGORY_FINANCIAL *** Not yet Implemented
+VERSION CATEGORY_INFORMATION PHPExcel_Calculation_Functions::VERSION
+VLOOKUP CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::VLOOKUP
+
+WEEKDAY CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DAYOFWEEK
+WEEKNUM CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::WEEKOFYEAR
+WEIBULL CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::WEIBULL
+WORKDAY CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::WORKDAY
+
+XIRR CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::XIRR
+XNPV CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::XNPV
+
+YEAR CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::YEAR
+YEARFRAC CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::YEARFRAC
+YIELD CATEGORY_FINANCIAL *** Not yet Implemented
+YIELDDISC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::YIELDDISC
+YIELDMAT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::YIELDMAT
+
+ZTEST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::ZTEST
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/Functionality Cross-Reference.xls b/Server/vendor/phpoffice/phpexcel/Documentation/Functionality Cross-Reference.xls
new file mode 100755
index 000000000..227fd612f
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/Functionality Cross-Reference.xls differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/PHPExcel AutoFilter Reference developer documentation.doc b/Server/vendor/phpoffice/phpexcel/Documentation/PHPExcel AutoFilter Reference developer documentation.doc
new file mode 100755
index 000000000..208b20205
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/PHPExcel AutoFilter Reference developer documentation.doc differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/PHPExcel Function Reference developer documentation.doc b/Server/vendor/phpoffice/phpexcel/Documentation/PHPExcel Function Reference developer documentation.doc
new file mode 100755
index 000000000..57d218c7c
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/PHPExcel Function Reference developer documentation.doc differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/PHPExcel User Documentation - Reading Spreadsheet Files.doc b/Server/vendor/phpoffice/phpexcel/Documentation/PHPExcel User Documentation - Reading Spreadsheet Files.doc
new file mode 100755
index 000000000..ef3954d3b
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/PHPExcel User Documentation - Reading Spreadsheet Files.doc differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/PHPExcel developer documentation.doc b/Server/vendor/phpoffice/phpexcel/Documentation/PHPExcel developer documentation.doc
new file mode 100755
index 000000000..52cc9647d
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/PHPExcel developer documentation.doc differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/assets/ClassDiagrams/Architecture.cd b/Server/vendor/phpoffice/phpexcel/Documentation/assets/ClassDiagrams/Architecture.cd
new file mode 100755
index 000000000..afc1dbd09
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/assets/ClassDiagrams/Architecture.cd
@@ -0,0 +1,51 @@
+
+
You can remove this dependency for writing Excel2007 files (though not yet for reading) by using the PCLZip library that is bundled with PHPExcel. See the FAQ section of this document for details about this. PCLZip does have a dependency on PHP's zlib extension being enabled.
+
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/02-Architecture.md b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/02-Architecture.md
new file mode 100755
index 000000000..8ddb43e2c
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/02-Architecture.md
@@ -0,0 +1,76 @@
+# PHPExcel Developer Documentation
+
+
+## Architecture
+
+### Schematical
+
+
+
+
+### Lazy Loader
+
+PHPExcel implements an autoloader or "lazy loader", which means that it is not necessary to include every file within PHPExcel. It is only necessary to include the initial PHPExcel class file, then the autoloader will include other class files as and when required, so only those files that are actually required by your script will be loaded into PHP memory. The main benefit of this is that it reduces the memory footprint of PHPExcel itself, so that it uses less PHP memory.
+
+If your own scripts already define an autoload function, then this may be overwritten by the PHPExcel autoload function. For example, if you have:
+```php
+function __autoload($class) {
+ ...
+}
+```
+Do this instead:
+```php
+function myAutoload($class) {
+ ...
+}
+
+spl_autoload_register('myAutoload');
+```
+Your autoloader will then co-exist with the autoloader of PHPExcel.
+
+
+### Spreadsheet in memory
+
+PHPExcel's architecture is built in a way that it can serve as an in-memory spreadsheet. This means that, if one would want to create a web based view of a spreadsheet which communicates with PHPExcel's object model, he would only have to write the front-end code.
+
+Just like desktop spreadsheet software, PHPExcel represents a spreadsheet containing one or more worksheets, which contain cells with data, formulas, images, ...
+
+
+### Readers and writers
+
+On its own, PHPExcel does not provide the functionality to read from or write to a persisted spreadsheet (on disk or in a database). To provide that functionality, readers and writers can be used.
+
+By default, the PHPExcel package provides some readers and writers, including one for the Open XML spreadsheet format (a.k.a. Excel 2007 file format). You are not limited to the default readers and writers, as you are free to implement the PHPExcel_Reader_IReader and PHPExcel_Writer_IWriter interface in a custom class.
+
+
+
+### Fluent interfaces
+
+PHPExcel supports fluent interfaces in most locations. This means that you can easily "chain" calls to specific methods without requiring a new PHP statement. For example, take the following code:
+
+```php
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw");
+$objPHPExcel->getProperties()->setLastModifiedBy("Maarten Balliauw");
+$objPHPExcel->getProperties()->setTitle("Office 2007 XLSX Test Document");
+$objPHPExcel->getProperties()->setSubject("Office 2007 XLSX Test Document");
+$objPHPExcel->getProperties()->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.");
+$objPHPExcel->getProperties()->setKeywords("office 2007 openxml php");
+$objPHPExcel->getProperties()->setCategory("Test result file");
+```
+
+This can be rewritten as:
+
+```php
+$objPHPExcel->getProperties()
+ ->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+```
+
+ > __Using fluent interfaces is not required__
+ > Fluent interfaces have been implemented to provide a convenient programming API. Use of them is not required, but can make your code easier to read and maintain.
+ > It can also improve performance, as you are reducing the overall number of calls to PHPExcel methods: in the above example, the `getProperties()` method is being called only once rather than 7 times in the non-fluent version.
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/03-Creating-a-Spreadsheet.md b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/03-Creating-a-Spreadsheet.md
new file mode 100755
index 000000000..b65000bf5
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/03-Creating-a-Spreadsheet.md
@@ -0,0 +1,34 @@
+# PHPExcel Developer Documentation
+
+
+## Creating a spreadsheet
+
+### The PHPExcel class
+
+The PHPExcel class is the core of PHPExcel. It contains references to the contained worksheets, document security settings and document meta data.
+
+To simplify the PHPExcel concept: the PHPExcel class represents your workbook.
+
+Typically, you will create a workbook in one of two ways, either by loading it from a spreadsheet file, or creating it manually. A third option, though less commonly used, is cloning an existing workbook that has been created using one of the previous two methods.
+
+#### Loading a Workbook from a file
+
+Details of the different spreadsheet formats supported, and the options available to read them into a PHPExcel object are described fully in the PHPExcel User Documentation - Reading Spreadsheet Files document.
+
+```php
+$inputFileName = './sampleData/example1.xls';
+
+/** Load $inputFileName to a PHPExcel Object **/
+$objPHPExcel = PHPExcel_IOFactory::load($inputFileName);
+```
+
+#### Creating a new workbook
+
+If you want to create a new workbook, rather than load one from file, then you simply need to instantiate it as a new PHPExcel object.
+
+```php
+/** Create a new PHPExcel Object **/
+$objPHPExcel = new PHPExcel();
+```
+
+A new workbook will always be created with a single worksheet.
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/04-Configuration-Settings.md b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/04-Configuration-Settings.md
new file mode 100755
index 000000000..2024e801e
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/04-Configuration-Settings.md
@@ -0,0 +1,140 @@
+# PHPExcel Developer Documentation
+
+
+## Configuration Settings
+
+Once you have included the PHPExcel files in your script, but before instantiating a PHPExcel object or loading a workbook file, there are a number of configuration options that can be set which will affect the subsequent behaviour of the script.
+
+### Cell Caching
+
+PHPExcel uses an average of about 1k/cell in your worksheets, so large workbooks can quickly use up available memory. Cell caching provides a mechanism that allows PHPExcel to maintain the cell objects in a smaller size of memory, on disk, or in APC, memcache or Wincache, rather than in PHP memory. This allows you to reduce the memory usage for large workbooks, although at a cost of speed to access cell data.
+
+By default, PHPExcel still holds all cell objects in memory, but you can specify alternatives. To enable cell caching, you must call the PHPExcel_Settings::setCacheStorageMethod() method, passing in the caching method that you wish to use.
+
+```php
+$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_in_memory;
+
+PHPExcel_Settings::setCacheStorageMethod($cacheMethod);
+```
+
+setCacheStorageMethod() will return a boolean true on success, false on failure (for example if trying to cache to APC when APC is not enabled).
+
+A separate cache is maintained for each individual worksheet, and is automatically created when the worksheet is instantiated based on the caching method and settings that you have configured. You cannot change the configuration settings once you have started to read a workbook, or have created your first worksheet.
+
+Currently, the following caching methods are available.
+
+#### PHPExcel_CachedObjectStorageFactory::cache_in_memory
+
+The default. If you don't initialise any caching method, then this is the method that PHPExcel will use. Cell objects are maintained in PHP memory as at present.
+
+#### PHPExcel_CachedObjectStorageFactory::cache_in_memory_serialized
+
+Using this caching method, cells are held in PHP memory as an array of serialized objects, which reduces the memory footprint with minimal performance overhead.
+
+#### PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip
+
+Like cache_in_memory_serialized, this method holds cells in PHP memory as an array of serialized objects, but gzipped to reduce the memory usage still further, although access to read or write a cell is slightly slower.
+
+#### PHPExcel_CachedObjectStorageFactory::cache_igbinary
+
+Uses PHPs igbinary extension (if its available) to serialize cell objects in memory. This is normally faster and uses less memory than standard PHP serialization, but isnt available in most hosting environments.
+
+#### PHPExcel_CachedObjectStorageFactory::cache_to_discISAM
+
+When using cache_to_discISAM all cells are held in a temporary disk file, with only an index to their location in that file maintained in PHP memory. This is slower than any of the cache_in_memory methods, but significantly reduces the memory footprint. By default, PHPExcel will use PHP's temp directory for the cache file, but you can specify a different directory when initialising cache_to_discISAM.
+
+```php
+$cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_discISAM;
+$cacheSettings = array(
+ 'dir' => '/usr/local/tmp'
+);
+PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);
+```
+
+The temporary disk file is automatically deleted when your script terminates.
+
+#### PHPExcel_CachedObjectStorageFactory::cache_to_phpTemp
+
+Like cache_to_discISAM, when using cache_to_phpTemp all cells are held in the php://temp I/O stream, with only an index to their location maintained in PHP memory. In PHP, the php://memory wrapper stores data in the memory: php://temp behaves similarly, but uses a temporary file for storing the data when a certain memory limit is reached. The default is 1 MB, but you can change this when initialising cache_to_phpTemp.
+
+```php
+$cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_phpTemp;
+$cacheSettings = array(
+ 'memoryCacheSize' => '8MB'
+);
+PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);
+```
+
+The php://temp file is automatically deleted when your script terminates.
+
+#### PHPExcel_CachedObjectStorageFactory::cache_to_apc
+
+When using cache_to_apc, cell objects are maintained in APC with only an index maintained in PHP memory to identify that the cell exists. By default, an APC cache timeout of 600 seconds is used, which should be enough for most applications: although it is possible to change this when initialising cache_to_APC.
+
+```php
+$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_APC;
+$cacheSettings = array(
+ 'cacheTime' => 600
+);
+PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);
+```
+
+When your script terminates all entries will be cleared from APC, regardless of the cacheTime value, so it cannot be used for persistent storage using this mechanism.
+
+#### PHPExcel_CachedObjectStorageFactory::cache_to_memcache
+
+When using cache_to_memcache, cell objects are maintained in memcache with only an index maintained in PHP memory to identify that the cell exists.
+
+By default, PHPExcel looks for a memcache server on localhost at port 11211. It also sets a memcache timeout limit of 600 seconds. If you are running memcache on a different server or port, then you can change these defaults when you initialise cache_to_memcache:
+
+```php
+$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_memcache;
+$cacheSettings = array(
+ 'memcacheServer' => 'localhost',
+ 'memcachePort' => 11211,
+ 'cacheTime' => 600
+);
+PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);
+```
+
+When your script terminates all entries will be cleared from memcache, regardless of the cacheTime value, so it cannot be used for persistent storage using this mechanism.
+
+#### PHPExcel_CachedObjectStorageFactory::cache_to_wincache
+
+When using cache_to_wincache, cell objects are maintained in Wincache with only an index maintained in PHP memory to identify that the cell exists. By default, a Wincache cache timeout of 600 seconds is used, which should be enough for most applications: although it is possible to change this when initialising cache_to_wincache.
+
+```php
+$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_wincache;
+$cacheSettings = array(
+ 'cacheTime' => 600
+);
+PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);
+```
+
+When your script terminates all entries will be cleared from Wincache, regardless of the cacheTime value, so it cannot be used for persistent storage using this mechanism.
+
+#### PHPExcel_CachedObjectStorageFactory::cache_to_sqlite
+
+Uses an SQLite 2 "in-memory" database for caching cell data. Unlike other caching methods, neither cells nor an index are held in PHP memory - an indexed database table makes it unnecessary to hold any index in PHP memory, which makes this the most memory-efficient of the cell caching methods.
+
+#### PHPExcel_CachedObjectStorageFactory::cache_to_sqlite3;
+
+Uses an SQLite 3 "in-memory" database for caching cell data. Unlike other caching methods, neither cells nor an index are held in PHP memory - an indexed database table makes it unnecessary to hold any index in PHP memory, which makes this the most memory-efficient of the cell caching methods.
+
+
+### Language/Locale
+
+Some localisation elements have been included in PHPExcel. You can set a locale by changing the settings. To set the locale to Brazilian Portuguese you would use:
+
+```php
+$locale = 'pt_br';
+$validLocale = PHPExcel_Settings::setLocale($locale);
+if (!$validLocale) {
+ echo 'Unable to set locale to ' . $locale . " - reverting to en_us" . PHP_EOL;
+}
+```
+
+If Brazilian Portuguese language files aren't available, then Portuguese will be enabled instead: if Portuguese language files aren't available, then the setLocale() method will return an error, and American English (en_us) settings will be used throughout.
+
+More details of the features available once a locale has been set, including a list of the languages and locales currently supported, can be found in the section of this document entitled "Locale Settings for Formulae".
+
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/05-Deleting-a-Workbook.md b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/05-Deleting-a-Workbook.md
new file mode 100755
index 000000000..0ea91712f
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/05-Deleting-a-Workbook.md
@@ -0,0 +1,13 @@
+# PHPExcel Developer Documentation
+
+## Clearing a Workbook from memory
+
+The PHPExcel object contains cyclic references (e.g. the workbook is linked to the worksheets, and the worksheets are linked to their parent workbook) which cause problems when PHP tries to clear the objects from memory when they are unset(), or at the end of a function when they are in local scope. The result of this is "memory leaks", which can easily use a large amount of PHP's limited memory.
+
+This can only be resolved manually: if you need to unset a workbook, then you also need to "break" these cyclic references before doing so. PHPExcel provides the disconnectWorksheets() method for this purpose.
+
+```php
+$objPHPExcel->disconnectWorksheets();
+
+unset($objPHPExcel);
+```
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/06-Worksheets.md b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/06-Worksheets.md
new file mode 100755
index 000000000..a6a231ccf
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/06-Worksheets.md
@@ -0,0 +1,94 @@
+# PHPExcel Developer Documentation
+
+## Worksheets
+
+A worksheet is a collection of cells, formulae, images, graphs, etc. It holds all data necessary to represent a spreadsheet worksheet.
+
+When you load a workbook from a spreadsheet file, it will be loaded with all its existing worksheets (unless you specified that only certain sheets should be loaded). When you load from non-spreadsheet files (such as a CSV or HTML file) or from spreadsheet formats that don't identify worksheets by name (such as SYLK), then a single worksheet called "WorkSheet1" will be created containing the data from that file.
+
+When you instantiate a new workbook, PHPExcel will create it with a single worksheet called "WorkSheet1".
+
+The `getSheetCount()` method will tell you the number of worksheets in the workbook; while the `getSheetNames()` method will return a list of all worksheets in the workbook, indexed by the order in which their "tabs" would appear when opened in MS Excel (or other appropriate Spreadsheet program).
+
+Individual worksheets can be accessed by name, or by their index position in the workbook. The index position represents the order that each worksheet "tab" is shown when the workbook is opened in MS Excel (or other appropriate Spreadsheet program). To access a sheet by its index, use the `getSheet()` method.
+
+```php
+// Get the second sheet in the workbook
+// Note that sheets are indexed from 0
+$objPHPExcel->getSheet(1);
+```
+
+If you don't specify a sheet index, then the first worksheet will be returned.
+
+Methods also exist allowing you to reorder the worksheets in the workbook.
+
+To access a sheet by name, use the `getSheetByName()` method, specifying the name of the worksheet that you want to access.
+
+```php
+// Retrieve the worksheet called 'Worksheet 1'
+$objPHPExcel->getSheetByName('Worksheet 1');
+```
+
+Alternatively, one worksheet is always the currently active worksheet, and you can access that directly. The currently active worksheet is the one that will be active when the workbook is opened in MS Excel (or other appropriate Spreadsheet program).
+
+```php
+// Retrieve the current active worksheet
+$objPHPExcel->getActiveSheet();
+```
+
+You can change the currently active sheet by index or by name using the `setActiveSheetIndex()` and `setActiveSheetIndexByName()` methods.
+
+### Adding a new Worksheet
+
+You can add a new worksheet to the workbook using the `createSheet()` method of the PHPExcel object. By default, this will be created as a new "last" sheet; but you can also specify an index position as an argument, and the worksheet will be inserted at that position, shuffling all subsequent worksheets in the collection down a place.
+
+```php
+$objPHPExcel->createSheet();
+```
+
+A new worksheet created using this method will be called "Worksheet\' . PHP_EOL;
+foreach ($objWorksheet->getRowIterator() as $row) {
+ echo '
' . PHP_EOL;
+```
+
+Note that we have set the cell iterator's `setIterateOnlyExistingCells()` to FALSE. This makes the iterator loop all cells within the worksheet range, even if they have not been set.
+
+The cell iterator will return a __NULL__ as the cell value if it is not set in the worksheet.
+Setting the cell iterator's setIterateOnlyExistingCells() to FALSE will loop all cells in the worksheet that can be available at that moment. This will create new cells if required and increase memory usage! Only use it if it is intended to loop all cells that are possibly available.
+
+#### Looping through cells using indexes
+
+One can use the possibility to access cell values by column and row index like (0,1) instead of 'A1' for reading and writing cell values in loops.
+
+Note: In PHPExcel column index is 0-based while row index is 1-based. That means 'A1' ~ (0,1)
+
+Below is an example where we read all the values in a worksheet and display them in a table.
+
+```php
+$objReader = PHPExcel_IOFactory::createReader('Excel2007');
+$objReader->setReadDataOnly(TRUE);
+$objPHPExcel = $objReader->load("test.xlsx");
+
+$objWorksheet = $objPHPExcel->getActiveSheet();
+// Get the highest row and column numbers referenced in the worksheet
+$highestRow = $objWorksheet->getHighestRow(); // e.g. 10
+$highestColumn = $objWorksheet->getHighestColumn(); // e.g 'F'
+$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn); // e.g. 5
+
+echo '' . PHP_EOL;
+ $cellIterator = $row->getCellIterator();
+ $cellIterator->setIterateOnlyExistingCells(FALSE); // This loops through all cells,
+ // even if a cell value is not set.
+ // By default, only cells that have a value
+ // set will be iterated.
+ foreach ($cellIterator as $cell) {
+ echo ' ' . PHP_EOL;
+}
+echo '' .
+ $cell->getValue() .
+ ' ' . PHP_EOL;
+ }
+ echo '' . "\n";
+for ($row = 1; $row <= $highestRow; ++$row) {
+ echo '
' . PHP_EOL;
+```
+
+Alternatively, you can take advantage of PHP's "Perl-style" character incrementors to loop through the cells by coordinate:
+
+```php
+$objReader = PHPExcel_IOFactory::createReader('Excel2007');
+$objReader->setReadDataOnly(TRUE);
+$objPHPExcel = $objReader->load("test.xlsx");
+
+$objWorksheet = $objPHPExcel->getActiveSheet();
+// Get the highest row number and column letter referenced in the worksheet
+$highestRow = $objWorksheet->getHighestRow(); // e.g. 10
+$highestColumn = $objWorksheet->getHighestColumn(); // e.g 'F'
+// Increment the highest column letter
+$highestColumn++;
+
+echo '' . PHP_EOL;
+ for ($col = 0; $col <= $highestColumnIndex; ++$col) {
+ echo ' ' . PHP_EOL;
+}
+echo '' .
+ $objWorksheet->getCellByColumnAndRow($col, $row)
+ ->getValue() .
+ ' ' . PHP_EOL;
+ }
+ echo '' . "\n";
+for ($row = 1; $row <= $highestRow; ++$row) {
+ echo '
' . PHP_EOL;
+```
+
+Note that we can't use a <= comparison here, because 'AA' would match as <= 'B', so we increment the highest column letter and then loop while $col != the incremented highest column.
+
+### Using value binders to facilitate data entry
+
+Internally, PHPExcel uses a default PHPExcel_Cell_IValueBinder implementation (PHPExcel_Cell_DefaultValueBinder) to determine data types of entered data using a cell's `setValue()` method (the `setValueExplicit()` method bypasses this check).
+
+Optionally, the default behaviour of PHPExcel can be modified, allowing easier data entry. For example, a PHPExcel_Cell_AdvancedValueBinder class is available. It automatically converts percentages, number in scientific format, and dates entered as strings to the correct format, also setting the cell's style information. The following example demonstrates how to set the value binder in PHPExcel:
+
+```php
+/** PHPExcel */
+require_once 'PHPExcel.php';
+
+// Set value binder
+PHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() );
+
+// Create new PHPExcel object
+$objPHPExcel = new PHPExcel();
+
+// ...
+// Add some data, resembling some different data types
+$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Percentage value:');
+// Converts the string value to 0.1 and sets percentage cell style
+$objPHPExcel->getActiveSheet()->setCellValue('B4', '10%');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Date/time value:');
+// Converts the string value to an Excel datestamp and sets the date format cell style
+$objPHPExcel->getActiveSheet()->setCellValue('B5', '21 December 1983');
+```
+
+__Creating your own value binder is easy.__
+When advanced value binding is required, you can implement the PHPExcel_Cell_IValueBinder interface or extend the PHPExcel_Cell_DefaultValueBinder or PHPExcel_Cell_AdvancedValueBinder classes.
+
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/08-Recipes.md b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/08-Recipes.md
new file mode 100755
index 000000000..b8930a44c
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/08-Recipes.md
@@ -0,0 +1,1214 @@
+# PHPExcel Developer Documentation
+
+## PHPExcel recipes
+
+The following pages offer you some widely-used PHPExcel recipes. Please note that these do NOT offer complete documentation on specific PHPExcel API functions, but just a bump to get you started. If you need specific API functions, please refer to the API documentation.
+
+For example, REF _Ref191885321 \w \h 4.4.7 REF _Ref191885321 \h Setting a worksheet's page orientation and size covers setting a page orientation to A4. Other paper formats, like US Letter, are not covered in this document, but in the PHPExcel API documentation.
+
+### Setting a spreadsheet's metadata
+
+PHPExcel allows an easy way to set a spreadsheet's metadata, using document property accessors. Spreadsheet metadata can be useful for finding a specific document in a file repository or a document management system. For example Microsoft Sharepoint uses document metadata to search for a specific document in its document lists.
+
+Setting spreadsheet metadata is done as follows:
+
+```php
+$objPHPExcel->getProperties()
+ ->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw");
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription(
+ "Test document for Office 2007 XLSX, generated using PHP classes."
+ )
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+```
+
+### Setting a spreadsheet's active sheet
+
+The following line of code sets the active sheet index to the first sheet:
+
+```php
+$objPHPExcel->setActiveSheetIndex(0);
+```
+
+You can also set the active sheet by its name/title
+
+```php
+$objPHPExcel->setActiveSheetIndexByName('DataSheet')
+```
+
+will change the currently active sheet to the worksheet called "DataSheet".
+
+### Write a date or time into a cell
+
+In Excel, dates and Times are stored as numeric values counting the number of days elapsed since 1900-01-01. For example, the date '2008-12-31' is represented as 39813. You can verify this in Microsoft Office Excel by entering that date in a cell and afterwards changing the number format to 'General' so the true numeric value is revealed. Likewise, '3:15 AM' is represented as 0.135417.
+
+PHPExcel works with UST (Universal Standard Time) date and Time values, but does no internal conversions; so it is up to the developer to ensure that values passed to the date/time conversion functions are UST.
+
+Writing a date value in a cell consists of 2 lines of code. Select the method that suits you the best. Here are some examples:
+
+```php
+/* PHPExcel_Cell_AdvanceValueBinder required for this sample */
+require_once 'PHPExcel/Cell/AdvancedValueBinder.php';
+
+// MySQL-like timestamp '2008-12-31' or date string
+PHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() );
+
+$objPHPExcel->getActiveSheet()
+ ->setCellValue('D1', '2008-12-31');
+
+$objPHPExcel->getActiveSheet()->getStyle('D1')
+ ->getNumberFormat()
+ ->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
+
+// PHP-time (Unix time)
+$time = gmmktime(0,0,0,12,31,2008); // int(1230681600)
+$objPHPExcel->getActiveSheet()
+ ->setCellValue('D1', PHPExcel_Shared_Date::PHPToExcel($time));
+$objPHPExcel->getActiveSheet()->getStyle('D1')
+ ->getNumberFormat()
+ ->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
+
+// Excel-date/time
+$objPHPExcel->getActiveSheet()->setCellValue('D1', 39813)
+$objPHPExcel->getActiveSheet()->getStyle('D1')
+ ->getNumberFormat()
+ ->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
+```
+
+The above methods for entering a date all yield the same result. PHPExcel_Style_NumberFormat provides a lot of pre-defined date formats.
+
+The PHPExcel_Shared_Date::PHPToExcel() method will also work with a PHP DateTime object.
+
+Similarly, times (or date and time values) can be entered in the same fashion: just remember to use an appropriate format code.
+
+__Notes:__
+
+See section "Using value binders to facilitate data entry" to learn more about the AdvancedValueBinder used in the first example.
+In previous versions of PHPExcel up to and including 1.6.6, when a cell had a date-like number format code, it was possible to enter a date directly using an integer PHP-time without converting to Excel date format. Starting with PHPExcel 1.6.7 this is no longer supported.
+Excel can also operate in a 1904-based calendar (default for workbooks saved on Mac). Normally, you do not have to worry about this when using PHPExcel.
+
+### Write a formula into a cell
+
+Inside the Excel file, formulas are always stored as they would appear in an English version of Microsoft Office Excel, and PHPExcel handles all formulae internally in this format. This means that the following rules hold:
+
+ - Decimal separator is '.' (period)
+ - Function argument separator is ',' (comma)
+ - Matrix row separator is ';' (semicolon)
+ - English function names must be used
+
+This is regardless of which language version of Microsoft Office Excel may have been used to create the Excel file.
+
+When the final workbook is opened by the user, Microsoft Office Excel will take care of displaying the formula according the applications language. Translation is taken care of by the application!
+
+The following line of code writes the formula '=IF(C4>500,"profit","loss")' into the cell B8. Note that the formula must start with "=" to make PHPExcel recognise this as a formula.
+
+```php
+$objPHPExcel->getActiveSheet()->setCellValue('B8','=IF(C4>500,"profit","loss")');
+```
+
+If you want to write a string beginning with an "=" character to a cell, then you should use the setCellValueExplicit() method.
+
+```php
+$objPHPExcel->getActiveSheet()
+ ->setCellValueExplicit(
+ 'B8',
+ '=IF(C4>500,"profit","loss")',
+ PHPExcel_Cell_DataType::TYPE_STRING
+ );
+```
+
+A cell's formula can be read again using the following line of code:
+
+```php
+$formula = $objPHPExcel->getActiveSheet()->getCell('B8')->getValue();
+```
+
+If you need the calculated value of a cell, use the following code. This is further explained in REF _Ref191885372 \w \h \* MERGEFORMAT 4.4.35.
+
+```php
+$value = $objPHPExcel->getActiveSheet()->getCell('B8')->getCalculatedValue();
+```
+
+### Locale Settings for Formulae
+
+Some localisation elements have been included in PHPExcel. You can set a locale by changing the settings. To set the locale to Russian you would use:
+
+```php
+$locale = 'ru';
+$validLocale = PHPExcel_Settings::setLocale($locale);
+if (!$validLocale) {
+ echo 'Unable to set locale to '.$locale." - reverting to en_us' . PHP_EOL;
+ for ($col = 'A'; $col != $highestColumn; ++$col) {
+ echo ' ' . PHP_EOL;
+}
+echo '' .
+ $objWorksheet->getCell($col . $row)
+ ->getValue() .
+ ' ' . PHP_EOL;
+ }
+ echo '
\n";
+}
+```
+
+If Russian language files aren't available, the `setLocale()` method will return an error, and English settings will be used throughout.
+
+Once you have set a locale, you can translate a formula from its internal English coding.
+
+```php
+$formula = $objPHPExcel->getActiveSheet()->getCell('B8')->getValue();
+$translatedFormula = PHPExcel_Calculation::getInstance()->_translateFormulaToLocale($formula);
+```
+
+You can also create a formula using the function names and argument separators appropriate to the defined locale; then translate it to English before setting the cell value:
+
+```php
+$formula = '=????360(????(2010;2;5);????(2010;12;31);??????)';
+$internalFormula = PHPExcel_Calculation::getInstance()->translateFormulaToEnglish($formula);
+$objPHPExcel->getActiveSheet()->setCellValue('B8',$internalFormula);
+```
+
+Currently, formula translation only translates the function names, the constants TRUE and FALSE, and the function argument separators.
+
+At present, the following locale settings are supported:
+
+ Language | | Locale Code
+ ---------------------|----------------------|-------------
+ Czech | Ceština | cs
+ Danish | Dansk | da
+ German | Deutsch | de
+ Spanish | Español | es
+ Finnish | Suomi | fi
+ French | Français | fr
+ Hungarian | Magyar | hu
+ Italian | Italiano | it
+ Dutch | Nederlands | nl
+ Norwegian | Norsk | no
+ Polish | Jezyk polski | pl
+ Portuguese | Português | pt
+ Brazilian Portuguese | Português Brasileiro | pt_br
+ Russian | ??????? ???? | ru
+ Swedish | Svenska | sv
+ Turkish | Türkçe | tr
+
+### Write a newline character "\n" in a cell (ALT+"Enter")
+
+In Microsoft Office Excel you get a line break in a cell by hitting ALT+"Enter". When you do that, it automatically turns on "wrap text" for the cell.
+
+Here is how to achieve this in PHPExcel:
+
+```php
+$objPHPExcel->getActiveSheet()->getCell('A1')->setValue("hello\nworld");
+$objPHPExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setWrapText(true);
+```
+
+__Tip__
+
+Read more about formatting cells using getStyle() elsewhere.
+
+__Tip__
+
+AdvancedValuebinder.php automatically turns on "wrap text" for the cell when it sees a newline character in a string that you are inserting in a cell. Just like Microsoft Office Excel. Try this:
+
+```php
+require_once 'PHPExcel/Cell/AdvancedValueBinder.php';
+PHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() );
+
+$objPHPExcel->getActiveSheet()->getCell('A1')->setValue("hello\nworld");
+```
+
+Read more about AdvancedValueBinder.php elsewhere.
+
+### Explicitly set a cell's datatype
+
+You can set a cell's datatype explicitly by using the cell's setValueExplicit method, or the setCellValueExplicit method of a worksheet. Here's an example:
+
+```php
+$objPHPExcel->getActiveSheet()->getCell('A1')
+ ->setValueExplicit(
+ '25',
+ PHPExcel_Cell_DataType::TYPE_NUMERIC
+ );
+```
+
+### Change a cell into a clickable URL
+
+You can make a cell a clickable URL by setting its hyperlink property:
+
+```php
+$objPHPExcel->getActiveSheet()->setCellValue('E26', 'www.phpexcel.net');
+$objPHPExcel->getActiveSheet()->getCell('E26')->getHyperlink()->setUrl('http://www.phpexcel.net');
+```
+
+If you want to make a hyperlink to another worksheet/cell, use the following code:
+
+```php
+$objPHPExcel->getActiveSheet()->setCellValue('E26', 'www.phpexcel.net');
+$objPHPExcel->getActiveSheet()->getCell('E26')->getHyperlink()->setUrl("sheet://'Sheetname'!A1");
+```
+
+### Setting Printer Options for Excel files
+
+#### Setting a worksheet's page orientation and size
+
+Setting a worksheet's page orientation and size can be done using the following lines of code:
+
+```php
+$objPHPExcel->getActiveSheet()->getPageSetup()
+ ->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE);
+$objPHPExcel->getActiveSheet()->getPageSetup()
+ ->setPaperSize(PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4);
+```
+
+Note that there are additional page settings available. Please refer to the API documentation for all possible options.
+
+#### Page Setup: Scaling options
+
+The page setup scaling options in PHPExcel relate directly to the scaling options in the "Page Setup" dialog as shown in the illustration.
+
+Default values in PHPExcel correspond to default values in MS Office Excel as shown in illustration
+
+
+
+ method | initial value | calling method will trigger | Note
+ --------------------|:-------------:|-----------------------------|------
+ setFitToPage(...) | FALSE | - |
+ setScale(...) | 100 | setFitToPage(FALSE) |
+ setFitToWidth(...) | 1 | setFitToPage(TRUE) | value 0 means do-not-fit-to-width
+ setFitToHeight(...) | 1 | setFitToPage(TRUE) | value 0 means do-not-fit-to-height
+
+##### Example
+
+Here is how to fit to 1 page wide by infinite pages tall:
+
+```php
+$objPHPExcel->getActiveSheet()->getPageSetup()->setFitToWidth(1);
+$objPHPExcel->getActiveSheet()->getPageSetup()->setFitToHeight(0);
+```
+
+As you can see, it is not necessary to call setFitToPage(TRUE) since setFitToWidth(...) and setFitToHeight(...) triggers this.
+
+If you use setFitToWidth() you should in general also specify setFitToHeight() explicitly like in the example. Be careful relying on the initial values. This is especially true if you are upgrading from PHPExcel 1.7.0 to 1.7.1 where the default values for fit-to-height and fit-to-width changed from 0 to 1.
+
+#### Page margins
+
+To set page margins for a worksheet, use this code:
+
+```php
+$objPHPExcel->getActiveSheet()->getPageMargins()->setTop(1);
+$objPHPExcel->getActiveSheet()->getPageMargins()->setRight(0.75);
+$objPHPExcel->getActiveSheet()->getPageMargins()->setLeft(0.75);
+$objPHPExcel->getActiveSheet()->getPageMargins()->setBottom(1);
+```
+
+Note that the margin values are specified in inches.
+
+
+
+#### Center a page horizontally/vertically
+
+To center a page horizontally/vertically, you can use the following code:
+
+```php
+$objPHPExcel->getActiveSheet()->getPageSetup()->setHorizontalCentered(true);
+$objPHPExcel->getActiveSheet()->getPageSetup()->setVerticalCentered(false);
+```
+
+#### Setting the print header and footer of a worksheet
+
+Setting a worksheet's print header and footer can be done using the following lines of code:
+
+```php
+$objPHPExcel->getActiveSheet()->getHeaderFooter()
+ ->setOddHeader('&C&HPlease treat this document as confidential!');
+$objPHPExcel->getActiveSheet()->getHeaderFooter()
+ ->setOddFooter('&L&B' . $objPHPExcel->getProperties()->getTitle() . '&RPage &P of &N');
+```
+
+Substitution and formatting codes (starting with &) can be used inside headers and footers. There is no required order in which these codes must appear.
+
+The first occurrence of the following codes turns the formatting ON, the second occurrence turns it OFF again:
+
+ - Strikethrough
+ - Superscript
+ - Subscript
+
+Superscript and subscript cannot both be ON at same time. Whichever comes first wins and the other is ignored, while the first is ON.
+
+The following codes are supported by Excel2007:
+
+Code | Meaning
+-----------------------|-----------
+&L | Code for "left section" (there are three header / footer locations, "left", "center", and "right"). When two or more occurrences of this section marker exist, the contents from all markers are concatenated, in the order of appearance, and placed into the left section.
+&P | Code for "current page #"
+&N | Code for "total pages"
+&font size | Code for "text font size", where font size is a font size in points.
+&K | Code for "text font color" - RGB Color is specified as RRGGBB Theme Color is specifed as TTSNN where TT is the theme color Id, S is either "+" or "-" of the tint/shade value, NN is the tint/shade value.
+&S | Code for "text strikethrough" on / off
+&X | Code for "text super script" on / off
+&Y | Code for "text subscript" on / off
+&C | Code for "center section". When two or more occurrences of this section marker exist, the contents from all markers are concatenated, in the order of appearance, and placed into the center section.
+&D | Code for "date"
+&T | Code for "time"
+&G | Code for "picture as background" - Please make sure to add the image to the header/footer[^print-footer-image-footnote]
+&U | Code for "text single underline"
+&E | Code for "double underline"
+&R | Code for "right section". When two or more occurrences of this section marker exist, the contents from all markers are concatenated, in the order of appearance, and placed into the right section.
+&Z | Code for "this workbook's file path"
+&F | Code for "this workbook's file name"
+&A | Code for "sheet tab name"
+&+ | Code for add to page #
+&- | Code for subtract from page #
+&"font name,font type" | Code for "text font name" and "text font type", where font name and font type are strings specifying the name and type of the font, separated by a comma. When a hyphen appears in font name, it means "none specified". Both of font name and font type can be localized values.
+&"-,Bold" | Code for "bold font style"
+&B | Code for "bold font style"
+&"-,Regular" | Code for "regular font style"
+&"-,Italic" | Code for "italic font style"
+&I | Code for "italic font style"
+&"-,Bold Italic" | Code for "bold italic font style"
+&O | Code for "outline style"
+&H | Code for "shadow style"
+
+ [^print-footer-image-footnote]: z
+```php
+$objDrawing = new PHPExcel_Worksheet_HeaderFooterDrawing();
+$objDrawing->setName('PHPExcel logo');
+$objDrawing->setPath('./images/phpexcel_logo.gif');
+$objDrawing->setHeight(36);
+$objPHPExcel->getActiveSheet()->getHeaderFooter()->addImage($objDrawing, PHPExcel_Worksheet_HeaderFooter::IMAGE_HEADER_LEFT);
+```
+
+__Tip__
+
+The above table of codes may seem overwhelming first time you are trying to figure out how to write some header or footer. Luckily, there is an easier way. Let Microsoft Office Excel do the work for you.For example, create in Microsoft Office Excel an xlsx file where you insert the header and footer as desired using the programs own interface. Save file as test.xlsx. Now, take that file and read off the values using PHPExcel as follows:
+
+```php
+$objPHPexcel = PHPExcel_IOFactory::load('test.xlsx');
+$objWorksheet = $objPHPexcel->getActiveSheet();
+
+var_dump($objWorksheet->getHeaderFooter()->getOddFooter());
+var_dump($objWorksheet->getHeaderFooter()->getEvenFooter());
+var_dump($objWorksheet->getHeaderFooter()->getOddHeader());
+var_dump($objWorksheet->getHeaderFooter()->getEvenHeader());
+```
+
+That reveals the codes for the even/odd header and footer. Experienced users may find it easier to rename test.xlsx to test.zip, unzip it, and inspect directly the contents of the relevant xl/worksheets/sheetX.xml to find the codes for header/footer.
+
+#### Setting printing breaks on a row or column
+
+To set a print break, use the following code, which sets a row break on row 10.
+
+```php
+$objPHPExcel->getActiveSheet()->setBreak( 'A10' , PHPExcel_Worksheet::BREAK_ROW );
+```
+
+The following line of code sets a print break on column D:
+
+```php
+$objPHPExcel->getActiveSheet()->setBreak( 'D10' , PHPExcel_Worksheet::BREAK_COLUMN );
+```
+
+#### Show/hide gridlines when printing
+
+To show/hide gridlines when printing, use the following code:
+
+$objPHPExcel->getActiveSheet()->setShowGridlines(true);
+
+#### Setting rows/columns to repeat at top/left
+
+PHPExcel can repeat specific rows/cells at top/left of a page. The following code is an example of how to repeat row 1 to 5 on each printed page of a specific worksheet:
+
+```php
+$objPHPExcel->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 5);
+```
+
+#### Specify printing area
+
+To specify a worksheet's printing area, use the following code:
+
+```php
+$objPHPExcel->getActiveSheet()->getPageSetup()->setPrintArea('A1:E5');
+```
+
+There can also be multiple printing areas in a single worksheet:
+
+```php
+$objPHPExcel->getActiveSheet()->getPageSetup()->setPrintArea('A1:E5,G4:M20');
+```
+
+### Styles
+
+#### Formatting cells
+
+A cell can be formatted with font, border, fill, ... style information. For example, one can set the foreground colour of a cell to red, aligned to the right, and the border to black and thick border style. Let's do that on cell B2:
+
+```php
+$objPHPExcel->getActiveSheet()->getStyle('B2')
+ ->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_RED);
+$objPHPExcel->getActiveSheet()->getStyle('B2')
+ ->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
+$objPHPExcel->getActiveSheet()->getStyle('B2')
+ ->getBorders()->getTop()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK);
+$objPHPExcel->getActiveSheet()->getStyle('B2')
+ ->getBorders()->getBottom()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK);
+$objPHPExcel->getActiveSheet()->getStyle('B2')
+ ->getBorders()->getLeft()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK);
+$objPHPExcel->getActiveSheet()->getStyle('B2')
+ ->getBorders()->getRight()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK);
+$objPHPExcel->getActiveSheet()->getStyle('B2')
+ ->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
+$objPHPExcel->getActiveSheet()->getStyle('B2')
+ ->getFill()->getStartColor()->setARGB('FFFF0000');
+```
+
+Starting with PHPExcel 1.7.0 getStyle() also accepts a cell range as a parameter. For example, you can set a red background color on a range of cells:
+
+```php
+$objPHPExcel->getActiveSheet()->getStyle('B3:B7')->getFill()
+ ->setFillType(PHPExcel_Style_Fill::FILL_SOLID)
+ ->getStartColor()->setARGB('FFFF0000');
+```
+
+__Tip__
+It is recommended to style many cells at once, using e.g. getStyle('A1:M500'), rather than styling the cells individually in a loop. This is much faster compared to looping through cells and styling them individually.
+
+There is also an alternative manner to set styles. The following code sets a cell's style to font bold, alignment right, top border thin and a gradient fill:
+
+```php
+$styleArray = array(
+ 'font' => array(
+ 'bold' => true,
+ ),
+ 'alignment' => array(
+ 'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_RIGHT,
+ ),
+ 'borders' => array(
+ 'top' => array(
+ 'style' => PHPExcel_Style_Border::BORDER_THIN,
+ ),
+ ),
+ 'fill' => array(
+ 'type' => PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR,
+ 'rotation' => 90,
+ 'startcolor' => array(
+ 'argb' => 'FFA0A0A0',
+ ),
+ 'endcolor' => array(
+ 'argb' => 'FFFFFFFF',
+ ),
+ ),
+);
+
+$objPHPExcel->getActiveSheet()->getStyle('A3')->applyFromArray($styleArray);
+```
+
+Or with a range of cells:
+
+```php
+$objPHPExcel->getActiveSheet()->getStyle('B3:B7')->applyFromArray($styleArray);
+```
+
+This alternative method using arrays should be faster in terms of execution whenever you are setting more than one style property. But the difference may barely be measurable unless you have many different styles in your workbook.
+
+Prior to PHPExcel 1.7.0 duplicateStyleArray() was the recommended method for styling a cell range, but this method has now been deprecated since getStyle() has started to accept a cell range.
+
+#### Number formats
+
+You often want to format numbers in Excel. For example you may want a thousands separator plus a fixed number of decimals after the decimal separator. Or perhaps you want some numbers to be zero-padded.
+
+In Microsoft Office Excel you may be familiar with selecting a number format from the "Format Cells" dialog. Here there are some predefined number formats available including some for dates. The dialog is designed in a way so you don't have to interact with the underlying raw number format code unless you need a custom number format.
+
+In PHPExcel, you can also apply various predefined number formats. Example:
+
+```php
+$objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat()
+ ->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED1);
+```
+
+This will format a number e.g. 1587.2 so it shows up as 1,587.20 when you open the workbook in MS Office Excel. (Depending on settings for decimal and thousands separators in Microsoft Office Excel it may show up as 1.587,20)
+
+You can achieve exactly the same as the above by using this:
+
+```php
+$objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat()
+ ->setFormatCode('#,##0.00');
+```
+
+In Microsoft Office Excel, as well as in PHPExcel, you will have to interact with raw number format codes whenever you need some special custom number format. Example:
+
+```php
+$objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat()
+ ->setFormatCode('[Blue][>=3000]$#,##0;[Red][<0]$#,##0;$#,##0');
+```
+
+Another example is when you want numbers zero-padded with leading zeros to a fixed length:
+
+```php
+$objPHPExcel->getActiveSheet()->getCell('A1')->setValue(19);
+$objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat()
+ ->setFormatCode('0000'); // will show as 0019 in Excel
+```
+
+__Tip__
+The rules for composing a number format code in Excel can be rather complicated. Sometimes you know how to create some number format in Microsoft Office Excel, but don't know what the underlying number format code looks like. How do you find it?
+
+The readers shipped with PHPExcel come to the rescue. Load your template workbook using e.g. Excel2007 reader to reveal the number format code. Example how read a number format code for cell A1:
+
+```php
+$objReader = PHPExcel_IOFactory::createReader('Excel2007');
+$objPHPExcel = $objReader->load('template.xlsx');
+var_dump($objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat()->getFormatCode());
+```
+
+Advanced users may find it faster to inspect the number format code directly by renaming template.xlsx to template.zip, unzipping, and looking for the relevant piece of XML code holding the number format code in *xl/styles.xml*.
+
+#### Alignment and wrap text
+
+Let's set vertical alignment to the top for cells A1:D4
+
+```php
+$objPHPExcel->getActiveSheet()->getStyle('A1:D4')
+ ->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_TOP);
+```
+
+Here is how to achieve wrap text:
+
+```php
+$objPHPExcel->getActiveSheet()->getStyle('A1:D4')
+ ->getAlignment()->setWrapText(true);
+```
+
+#### Setting the default style of a workbook
+
+It is possible to set the default style of a workbook. Let's set the default font to Arial size 8:
+
+```php
+$objPHPExcel->getDefaultStyle()->getFont()->setName('Arial');
+$objPHPExcel->getDefaultStyle()->getFont()->setSize(8);
+```
+
+#### Styling cell borders
+
+In PHPExcel it is easy to apply various borders on a rectangular selection. Here is how to apply a thick red border outline around cells B2:G8.
+
+```php
+$styleArray = array(
+ 'borders' => array(
+ 'outline' => array(
+ 'style' => PHPExcel_Style_Border::BORDER_THICK,
+ 'color' => array('argb' => 'FFFF0000'),
+ ),
+ ),
+);
+
+$objWorksheet->getStyle('B2:G8')->applyFromArray($styleArray);
+```
+
+In Microsoft Office Excel, the above operation would correspond to selecting the cells B2:G8, launching the style dialog, choosing a thick red border, and clicking on the "Outline" border component.
+
+Note that the border outline is applied to the rectangular selection B2:G8 as a whole, not on each cell individually.
+
+You can achieve any border effect by using just the 5 basic borders and operating on a single cell at a time:
+
+ Array key | Maps to property
+ ----------|------------------
+ left | getLeft()
+ right | getRight()
+ top | getTop()
+ bottom | getBottom()
+ diagonal | getDiagonal()
+
+Additional shortcut borders come in handy like in the example above. These are the shortcut borders available:
+
+ Array key | Maps to property
+ -----------|------------------
+ allborders | getAllBorders()
+ outline | getOutline()
+ inside | getInside()
+ vertical | getVertical()
+ horizontal | getHorizontal()
+
+
+
+An overview of all border shortcuts can be seen in the following image:
+
+
+
+If you simultaneously set e.g. allborders and vertical, then we have "overlapping" borders, and one of the components has to win over the other where there is border overlap. In PHPExcel, from weakest to strongest borders, the list is as follows: allborders, outline/inside, vertical/horizontal, left/right/top/bottom/diagonal.
+
+This border hierarchy can be utilized to achieve various effects in an easy manner.
+
+### Conditional formatting a cell
+
+A cell can be formatted conditionally, based on a specific rule. For example, one can set the foreground colour of a cell to red if its value is below zero, and to green if its value is zero or more.
+
+One can set a conditional style ruleset to a cell using the following code:
+
+```php
+$objConditional1 = new PHPExcel_Style_Conditional();
+$objConditional1->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS);
+$objConditional1->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_LESSTHAN);
+$objConditional1->addCondition('0');
+$objConditional1->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_RED);
+$objConditional1->getStyle()->getFont()->setBold(true);
+
+$objConditional2 = new PHPExcel_Style_Conditional();
+$objConditional2->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS);
+$objConditional2->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_GREATERTHANOREQUAL);
+$objConditional2->addCondition('0');
+$objConditional2->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_GREEN);
+$objConditional2->getStyle()->getFont()->setBold(true);
+
+$conditionalStyles = $objPHPExcel->getActiveSheet()->getStyle('B2')->getConditionalStyles();
+array_push($conditionalStyles, $objConditional1);
+array_push($conditionalStyles, $objConditional2);
+
+$objPHPExcel->getActiveSheet()->getStyle('B2')->setConditionalStyles($conditionalStyles);
+```
+
+If you want to copy the ruleset to other cells, you can duplicate the style object:
+
+```php
+$objPHPExcel->getActiveSheet()
+ ->duplicateStyle(
+ $objPHPExcel->getActiveSheet()->getStyle('B2'),
+ 'B3:B7'
+ );
+```
+
+### Add a comment to a cell
+
+To add a comment to a cell, use the following code. The example below adds a comment to cell E11:
+
+```php
+$objPHPExcel->getActiveSheet()
+ ->getComment('E11')
+ ->setAuthor('Mark Baker');
+$objCommentRichText = $objPHPExcel->getActiveSheet()
+ ->getComment('E11')
+ ->getText()->createTextRun('PHPExcel:');
+$objCommentRichText->getFont()->setBold(true);
+$objPHPExcel->getActiveSheet()
+ ->getComment('E11')
+ ->getText()->createTextRun("\r\n");
+$objPHPExcel->getActiveSheet()
+ ->getComment('E11')
+ ->getText()->createTextRun('Total amount on the current invoice, excluding VAT.');
+```
+
+
+
+### Apply autofilter to a range of cells
+
+To apply an autofilter to a range of cells, use the following code:
+
+```php
+$objPHPExcel->getActiveSheet()->setAutoFilter('A1:C9');
+```
+
+__Make sure that you always include the complete filter range!__
+Excel does support setting only the captionrow, but that's __not__ a best practice...
+
+### Setting security on a spreadsheet
+
+Excel offers 3 levels of "protection": document security, sheet security and cell security.
+
+Document security allows you to set a password on a complete spreadsheet, allowing changes to be made only when that password is entered.Worksheet security offers other security options: you can disallow inserting rows on a specific sheet, disallow sorting, ... Cell security offers the option to lock/unlock a cell as well as show/hide the internal formulaAn example on setting document security:
+
+```php
+$objPHPExcel->getSecurity()->setLockWindows(true);
+$objPHPExcel->getSecurity()->setLockStructure(true);
+$objPHPExcel->getSecurity()->setWorkbookPassword("PHPExcel");
+```
+
+An example on setting worksheet security:
+
+```php
+$objPHPExcel->getActiveSheet()
+ ->getProtection()->setPassword('PHPExcel');
+$objPHPExcel->getActiveSheet()
+ ->getProtection()->setSheet(true);
+$objPHPExcel->getActiveSheet()
+ ->getProtection()->setSort(true);
+$objPHPExcel->getActiveSheet()
+ ->getProtection()->setInsertRows(true);
+$objPHPExcel->getActiveSheet()
+ ->getProtection()->setFormatCells(true);
+```
+
+An example on setting cell security:
+
+```php
+$objPHPExcel->getActiveSheet()->getStyle('B1')
+ ->getProtection()
+ ->setLocked(PHPExcel_Style_Protection::PROTECTION_UNPROTECTED);
+```
+
+__Make sure you enable worksheet protection if you need any of the worksheet protection features!__ This can be done using the following code:
+
+```php
+$objPHPExcel->getActiveSheet()->getProtection()->setSheet(true);
+```
+
+### Setting data validation on a cell
+
+Data validation is a powerful feature of Excel2007. It allows to specify an input filter on the data that can be inserted in a specific cell. This filter can be a range (i.e. value must be between 0 and 10), a list (i.e. value must be picked from a list), ...
+
+The following piece of code only allows numbers between 10 and 20 to be entered in cell B3:
+
+```php
+$objValidation = $objPHPExcel->getActiveSheet()->getCell('B3')
+ ->getDataValidation();
+$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_WHOLE );
+$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_STOP );
+$objValidation->setAllowBlank(true);
+$objValidation->setShowInputMessage(true);
+$objValidation->setShowErrorMessage(true);
+$objValidation->setErrorTitle('Input error');
+$objValidation->setError('Number is not allowed!');
+$objValidation->setPromptTitle('Allowed input');
+$objValidation->setPrompt('Only numbers between 10 and 20 are allowed.');
+$objValidation->setFormula1(10);
+$objValidation->setFormula2(20);
+```
+
+This validation will limit the length of text that can be entered in a cell to 6 characters.
+
+```
+$objValidation = $objPHPExcel->getActiveSheet()->getCell('B9')->getDataValidation();
+$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH );
+$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_STOP );
+$objValidation->setAllowBlank(true);
+$objValidation->setShowInputMessage(true);
+$objValidation->setShowErrorMessage(true);
+$objValidation->setErrorTitle('Input error');
+$objValidation->setError('Text exceeds maximum length');
+$objValidation->setPromptTitle('Allowed input');
+$objValidation->setPrompt('Maximum text length is 6 characters.');
+$objValidation->setFormula1(6);
+```
+
+The following piece of code only allows an item picked from a list of data to be entered in cell B3:
+
+```php
+$objValidation = $objPHPExcel->getActiveSheet()->getCell('B5')
+ ->getDataValidation();
+$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST );
+$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION );
+$objValidation->setAllowBlank(false);
+$objValidation->setShowInputMessage(true);
+$objValidation->setShowErrorMessage(true);
+$objValidation->setShowDropDown(true);
+$objValidation->setErrorTitle('Input error');
+$objValidation->setError('Value is not in list.');
+$objValidation->setPromptTitle('Pick from list');
+$objValidation->setPrompt('Please pick a value from the drop-down list.');
+$objValidation->setFormula1('"Item A,Item B,Item C"');
+```
+
+When using a data validation list like above, make sure you put the list between " and " and that you split the items with a comma (,).
+
+It is important to remember that any string participating in an Excel formula is allowed to be maximum 255 characters (not bytes). This sets a limit on how many items you can have in the string "Item A,Item B,Item C". Therefore it is normally a better idea to type the item values directly in some cell range, say A1:A3, and instead use, say, $objValidation->setFormula1('Sheet!$A$1:$A$3');. Another benefit is that the item values themselves can contain the comma "," character itself.
+
+If you need data validation on multiple cells, one can clone the ruleset:
+
+```php
+$objPHPExcel->getActiveSheet()->getCell('B8')->setDataValidation(clone $objValidation);
+```
+
+### Setting a column's width
+
+A column's width can be set using the following code:
+
+```php
+$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(12);
+```
+
+If you want PHPExcel to perform an automatic width calculation, use the following code. PHPExcel will approximate the column with to the width of the widest column value.
+
+```php
+$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true);
+```
+
+
+
+The measure for column width in PHPExcel does __not__ correspond exactly to the measure you may be used to in Microsoft Office Excel. Column widths are difficult to deal with in Excel, and there are several measures for the column width.1) __Inner width in character units__ (e.g. 8.43 this is probably what you are familiar with in Excel)2) __Full width in pixels__ (e.g. 64 pixels)3) __Full width in character units__ (e.g. 9.140625, value -1 indicates unset width)__PHPExcel always operates with 3) "Full width in character units"__ which is in fact the only value that is stored in any Excel file, hence the most reliable measure. Unfortunately, __Microsoft ____Office ____Excel does not present you with this ____measure__. Instead measures 1) and 2) are computed by the application when the file is opened and these values are presented in various dialogues and tool tips.The character width unit is the width of a '0' (zero) glyph in the workbooks default font. Therefore column widths measured in character units in two different workbooks can only be compared if they have the same default workbook font.If you have some Excel file and need to know the column widths in measure 3), you can read the Excel file with PHPExcel and echo the retrieved values.
+
+### Show/hide a column
+
+To set a worksheet's column visibility, you can use the following code. The first line explicitly shows the column C, the second line hides column D.
+
+```php
+$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setVisible(true);
+$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setVisible(false);
+```
+
+### Group/outline a column
+
+To group/outline a column, you can use the following code:
+
+```php
+$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1);
+```
+
+You can also collapse the column. Note that you should also set the column invisible, otherwise the collapse will not be visible in Excel 2007.
+
+```php
+$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setCollapsed(true);
+$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setVisible(false);
+```
+
+Please refer to the section "group/outline a row" for a complete example on collapsing.
+
+You can instruct PHPExcel to add a summary to the right (default), or to the left. The following code adds the summary to the left:
+
+```php
+$objPHPExcel->getActiveSheet()->setShowSummaryRight(false);
+```
+
+### Setting a row's height
+
+A row's height can be set using the following code:
+
+```php
+$objPHPExcel->getActiveSheet()->getRowDimension('10')->setRowHeight(100);
+```
+
+Excel measures row height in points, where 1 pt is 1/72 of an inch (or about 0.35mm). The default value is 12.75 pts; and the permitted range of values is between 0 and 409 pts, where 0 pts is a hidden row.
+
+### Show/hide a row
+
+To set a worksheet''s row visibility, you can use the following code. The following example hides row number 10.
+
+```php
+$objPHPExcel->getActiveSheet()->getRowDimension('10')->setVisible(false);
+```
+
+Note that if you apply active filters using an AutoFilter, then this will override any rows that you hide or unhide manually within that AutoFilter range if you save the file.
+
+### Group/outline a row
+
+To group/outline a row, you can use the following code:
+
+```php
+$objPHPExcel->getActiveSheet()->getRowDimension('5')->setOutlineLevel(1);
+```
+
+You can also collapse the row. Note that you should also set the row invisible, otherwise the collapse will not be visible in Excel 2007.
+
+```php
+$objPHPExcel->getActiveSheet()->getRowDimension('5')->setCollapsed(true);
+$objPHPExcel->getActiveSheet()->getRowDimension('5')->setVisible(false);
+```
+
+Here's an example which collapses rows 50 to 80:
+
+```php
+for ($i = 51; $i <= 80; $i++) {
+ $objPHPExcel->getActiveSheet()->setCellValue('A' . $i, "FName $i");
+ $objPHPExcel->getActiveSheet()->setCellValue('B' . $i, "LName $i");
+ $objPHPExcel->getActiveSheet()->setCellValue('C' . $i, "PhoneNo $i");
+ $objPHPExcel->getActiveSheet()->setCellValue('D' . $i, "FaxNo $i");
+ $objPHPExcel->getActiveSheet()->setCellValue('E' . $i, true);
+ $objPHPExcel->getActiveSheet()->getRowDimension($i)->setOutlineLevel(1);
+ $objPHPExcel->getActiveSheet()->getRowDimension($i)->setVisible(false);
+}
+
+$objPHPExcel->getActiveSheet()->getRowDimension(81)->setCollapsed(true);
+```
+
+You can instruct PHPExcel to add a summary below the collapsible rows (default), or above. The following code adds the summary above:
+
+```php
+$objPHPExcel->getActiveSheet()->setShowSummaryBelow(false);
+```
+
+### Merge/unmerge cells
+
+If you have a big piece of data you want to display in a worksheet, you can merge two or more cells together, to become one cell. This can be done using the following code:
+
+```php
+$objPHPExcel->getActiveSheet()->mergeCells('A18:E22');
+```
+
+Removing a merge can be done using the unmergeCells method:
+
+```php
+$objPHPExcel->getActiveSheet()->unmergeCells('A18:E22');
+```
+
+### Inserting rows/columns
+
+You can insert/remove rows/columns at a specific position. The following code inserts 2 new rows, right before row 7:
+
+```php
+$objPHPExcel->getActiveSheet()->insertNewRowBefore(7, 2);
+```
+
+### Add a drawing to a worksheet
+
+A drawing is always represented as a separate object, which can be added to a worksheet. Therefore, you must first instantiate a new PHPExcel_Worksheet_Drawing, and assign its properties a meaningful value:
+
+```php
+$objDrawing = new PHPExcel_Worksheet_Drawing();
+$objDrawing->setName('Logo');
+$objDrawing->setDescription('Logo');
+$objDrawing->setPath('./images/officelogo.jpg');
+$objDrawing->setHeight(36);
+```
+
+To add the above drawing to the worksheet, use the following snippet of code. PHPExcel creates the link between the drawing and the worksheet:
+
+```php
+$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());
+```
+
+You can set numerous properties on a drawing, here are some examples:
+
+```php
+$objDrawing->setName('Paid');
+$objDrawing->setDescription('Paid');
+$objDrawing->setPath('./images/paid.png');
+$objDrawing->setCoordinates('B15');
+$objDrawing->setOffsetX(110);
+$objDrawing->setRotation(25);
+$objDrawing->getShadow()->setVisible(true);
+$objDrawing->getShadow()->setDirection(45);
+```
+
+You can also add images created using GD functions without needing to save them to disk first as In-Memory drawings.
+
+```php
+// Use GD to create an in-memory image
+$gdImage = @imagecreatetruecolor(120, 20) or die('Cannot Initialize new GD image stream');
+$textColor = imagecolorallocate($gdImage, 255, 255, 255);
+imagestring($gdImage, 1, 5, 5, 'Created with PHPExcel', $textColor);
+
+// Add the In-Memory image to a worksheet
+$objDrawing = new PHPExcel_Worksheet_MemoryDrawing();
+$objDrawing->setName('In-Memory image 1');
+$objDrawing->setDescription('In-Memory image 1');
+$objDrawing->setCoordinates('A1');
+$objDrawing->setImageResource($gdImage);
+$objDrawing->setRenderingFunction(
+ PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG
+);
+$objDrawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT);
+$objDrawing->setHeight(36);
+$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());
+```
+
+### Reading Images from a worksheet
+
+A commonly asked question is how to retrieve the images from a workbook that has been loaded, and save them as individual image files to disk.
+
+The following code extracts images from the current active worksheet, and writes each as a separate file.
+
+```php
+$i = 0;
+foreach ($objPHPExcel->getActiveSheet()->getDrawingCollection() as $drawing) {
+ if ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) {
+ ob_start();
+ call_user_func(
+ $drawing->getRenderingFunction(),
+ $drawing->getImageResource()
+ );
+ $imageContents = ob_get_contents();
+ ob_end_clean();
+ switch ($drawing->getMimeType()) {
+ case PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_PNG :
+ $extension = 'png';
+ break;
+ case PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_GIF:
+ $extension = 'gif';
+ break;
+ case PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_JPEG :
+ $extension = 'jpg';
+ break;
+ }
+ } else {
+ $zipReader = fopen($drawing->getPath(),'r');
+ $imageContents = '';
+ while (!feof($zipReader)) {
+ $imageContents .= fread($zipReader,1024);
+ }
+ fclose($zipReader);
+ $extension = $drawing->getExtension();
+ }
+ $myFileName = '00_Image_'.++$i.'.'.$extension;
+ file_put_contents($myFileName,$imageContents);
+}
+```
+
+### Add rich text to a cell
+
+Adding rich text to a cell can be done using PHPExcel_RichText instances. Here''s an example, which creates the following rich text string:
+
+ > This invoice is *__payable within thirty days after the end of the month__* unless specified otherwise on the invoice.
+
+```php
+$objRichText = new PHPExcel_RichText();
+$objRichText->createText('This invoice is ');
+$objPayable = $objRichText->createTextRun('payable within thirty days after the end of the month');
+$objPayable->getFont()->setBold(true);
+$objPayable->getFont()->setItalic(true);
+$objPayable->getFont()->setColor( new PHPExcel_Style_Color( PHPExcel_Style_Color::COLOR_DARKGREEN ) );
+$objRichText->createText(', unless specified otherwise on the invoice.');
+$objPHPExcel->getActiveSheet()->getCell('A18')->setValue($objRichText);
+```
+
+### Define a named range
+
+PHPExcel supports the definition of named ranges. These can be defined using the following code:
+
+```php
+// Add some data
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Firstname:');
+$objPHPExcel->getActiveSheet()->setCellValue('A2', 'Lastname:');
+$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Maarten');
+$objPHPExcel->getActiveSheet()->setCellValue('B2', 'Balliauw');
+
+// Define named ranges
+$objPHPExcel->addNamedRange( new PHPExcel_NamedRange('PersonFN', $objPHPExcel->getActiveSheet(), 'B1') );
+$objPHPExcel->addNamedRange( new PHPExcel_NamedRange('PersonLN', $objPHPExcel->getActiveSheet(), 'B2') );
+```
+
+Optionally, a fourth parameter can be passed defining the named range local (i.e. only usable on the current worksheet). Named ranges are global by default.
+
+### Redirect output to a client's web browser
+
+Sometimes, one really wants to output a file to a client''s browser, especially when creating spreadsheets on-the-fly. There are some easy steps that can be followed to do this:
+
+ 1. Create your PHPExcel spreadsheet
+ 2. Output HTTP headers for the type of document you wish to output
+ 3. Use the PHPExcel_Writer_* of your choice, and save to "php://output"
+
+PHPExcel_Writer_Excel2007 uses temporary storage when writing to php://output. By default, temporary files are stored in the script's working directory. When there is no access, it falls back to the operating system's temporary files location.
+
+__This may not be safe for unauthorized viewing!__
+Depending on the configuration of your operating system, temporary storage can be read by anyone using the same temporary storage folder. When confidentiality of your document is needed, it is recommended not to use php://output.
+
+#### HTTP headers
+
+Example of a script redirecting an Excel 2007 file to the client's browser:
+
+```php
+/* Here there will be some code where you create $objPHPExcel */
+
+// redirect output to client browser
+header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
+header('Content-Disposition: attachment;filename="myfile.xlsx"');
+header('Cache-Control: max-age=0');
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save('php://output');
+```
+
+Example of a script redirecting an Excel5 file to the client's browser:
+
+```php
+/* Here there will be some code where you create $objPHPExcel */
+
+// redirect output to client browser
+header('Content-Type: application/vnd.ms-excel');
+header('Content-Disposition: attachment;filename="myfile.xls"');
+header('Cache-Control: max-age=0');
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save('php://output');
+```
+
+**Caution:**
+
+Make sure not to include any echo statements or output any other contents than the Excel file. There should be no whitespace before the opening tag (which can also be omitted to avoid problems). Make sure that your script is saved without a BOM (Byte-order mark) because this counts as echoing output. The same things apply to all included files.
+Failing to follow the above guidelines may result in corrupt Excel files arriving at the client browser, and/or that headers cannot be set by PHP (resulting in warning messages).
+
+### Setting the default column width
+
+Default column width can be set using the following code:
+
+```php
+$objPHPExcel->getActiveSheet()->getDefaultColumnDimension()->setWidth(12);
+```
+
+### Setting the default row height
+
+Default row height can be set using the following code:
+
+```php
+$objPHPExcel->getActiveSheet()->getDefaultRowDimension()->setRowHeight(15);
+```
+
+### Add a GD drawing to a worksheet
+
+There might be a situation where you want to generate an in-memory image using GD and add it to a PHPExcel worksheet without first having to save this file to a temporary location.
+
+Here''s an example which generates an image in memory and adds it to the active worksheet:
+
+```php
+// Generate an image
+$gdImage = @imagecreatetruecolor(120, 20) or die('Cannot Initialize new GD image stream');
+$textColor = imagecolorallocate($gdImage, 255, 255, 255);
+imagestring($gdImage, 1, 5, 5, 'Created with PHPExcel', $textColor);
+
+// Add a drawing to the worksheet
+$objDrawing = new PHPExcel_Worksheet_MemoryDrawing();
+$objDrawing->setName('Sample image');
+$objDrawing->setDescription('Sample image');
+$objDrawing->setImageResource($gdImage);
+$objDrawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG);
+$objDrawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT);
+$objDrawing->setHeight(36);
+$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());
+```
+
+### Setting worksheet zoom level
+
+To set a worksheet's zoom level, the following code can be used:
+
+```php
+$objPHPExcel->getActiveSheet()->getSheetView()->setZoomScale(75);
+```
+
+Note that zoom level should be in range 10 – 400.
+
+### Sheet tab color
+
+Sometimes you want to set a color for sheet tab. For example you can have a red sheet tab:
+
+```php
+$objWorksheet->getTabColor()->setRGB('FF0000');
+```
+
+### Creating worksheets in a workbook
+
+If you need to create more worksheets in the workbook, here is how:
+
+```php
+$objWorksheet1 = $objPHPExcel->createSheet();
+$objWorksheet1->setTitle('Another sheet');
+```
+
+Think of createSheet() as the "Insert sheet" button in Excel. When you hit that button a new sheet is appended to the existing collection of worksheets in the workbook.
+
+### Hidden worksheets (Sheet states)
+
+Set a worksheet to be __hidden__ using this code:
+
+```php
+$objPHPExcel->getActiveSheet()
+ ->setSheetState(PHPExcel_Worksheet::SHEETSTATE_HIDDEN);
+```
+
+Sometimes you may even want the worksheet to be __"very hidden"__. The available sheet states are :
+
+ - PHPExcel_Worksheet::SHEETSTATE_VISIBLE
+ - PHPExcel_Worksheet::SHEETSTATE_HIDDEN
+ - PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN
+
+In Excel the sheet state "very hidden" can only be set programmatically, e.g. with Visual Basic Macro. It is not possible to make such a sheet visible via the user interface.
+
+### Right-to-left worksheet
+
+Worksheets can be set individually whether column "A" should start at left or right side. Default is left. Here is how to set columns from right-to-left.
+
+```php
+// right-to-left worksheet
+$objPHPExcel->getActiveSheet()
+ ->setRightToLeft(true);
+```
+
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/09-Calculation-Engine.md b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/09-Calculation-Engine.md
new file mode 100755
index 000000000..c13a18c6c
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/09-Calculation-Engine.md
@@ -0,0 +1,52 @@
+# PHPExcel Developer Documentation
+
+## Using the PHPExcel calculation engine
+
+### Performing formula calculations
+
+As PHPExcel represents an in-memory spreadsheet, it also offers formula calculation capabilities. A cell can be of a value type (containing a number or text), or a formula type (containing a formula which can be evaluated). For example, the formula "=SUM(A1:A10)" evaluates to the sum of values in A1, A2, ..., A10.
+
+To calculate a formula, you can call the cell containing the formula’s method getCalculatedValue(), for example:
+
+```php
+$objPHPExcel->getActiveSheet()->getCell('E11')->getCalculatedValue();
+```
+If you write the following line of code in the invoice demo included with PHPExcel, it evaluates to the value "64":
+
+
+
+Another nice feature of PHPExcel's formula parser, is that it can automatically adjust a formula when inserting/removing rows/columns. Here's an example:
+
+
+
+You see that the formula contained in cell E11 is "SUM(E4:E9)". Now, when I write the following line of code, two new product lines are added:
+
+```php
+$objPHPExcel->getActiveSheet()->insertNewRowBefore(7, 2);
+```
+
+
+
+Did you notice? The formula in the former cell E11 (now E13, as I inserted 2 new rows), changed to "SUM(E4:E11)". Also, the inserted cells duplicate style information of the previous cell, just like Excel's behaviour. Note that you can both insert rows and columns.
+
+### Known limitations
+
+There are some known limitations to the PHPExcel calculation engine. Most of them are due to the fact that an Excel formula is converted into PHP code before being executed. This means that Excel formula calculation is subject to PHP's language characteristics.
+
+#### Operator precedence
+
+In Excel '+' wins over '&', just like '*' wins over '+' in ordinary algebra. The former rule is not what one finds using the calculation engine shipped with PHPExcel.
+
+Reference for operator precedence in Excel: [http://support.microsoft.com/kb/25189][18]
+
+Reference for operator precedence in PHP: [http://www.php.net/operators][19]
+
+#### Formulas involving numbers and text
+
+Formulas involving numbers and text may produce unexpected results or even unreadable file contents. For example, the formula '=3+"Hello "' is expected to produce an error in Excel (#VALUE!). Due to the fact that PHP converts “Hello” to a numeric value (zero), the result of this formula is evaluated as 3 instead of evaluating as an error. This also causes the Excel document being generated as containing unreadable content.
+
+Reference for this behaviour in PHP: [http://be.php.net/manual/en/language.types.string.php#language.types.string.conversion][20]
+
+ [18]: http://support.microsoft.com/kb/25189
+ [19]: http://www.php.net/operators
+ [20]: http://be.php.net/manual/en/language.types.string.php#language.types.string.conversion
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/10-Reading-and-Writing.md b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/10-Reading-and-Writing.md
new file mode 100755
index 000000000..1468abc7e
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/10-Reading-and-Writing.md
@@ -0,0 +1,714 @@
+# PHPExcel Developer Documentation
+
+## Reading and writing to file
+
+As you already know from part REF _Ref191885438 \w \h 3.3 REF _Ref191885438 \h Readers and writers, reading and writing to a persisted storage is not possible using the base PHPExcel classes. For this purpose, PHPExcel provides readers and writers, which are implementations of PHPExcel_Writer_IReader and PHPExcel_Writer_IWriter.
+
+### PHPExcel_IOFactory
+
+The PHPExcel API offers multiple methods to create a PHPExcel_Writer_IReader or PHPExcel_Writer_IWriter instance:
+
+Direct creation via PHPExcel_IOFactory. All examples underneath demonstrate the direct creation method. Note that you can also use the PHPExcel_IOFactory class to do this.
+
+#### Creating PHPExcel_Reader_IReader using PHPExcel_IOFactory
+
+There are 2 methods for reading in a file into PHPExcel: using automatic file type resolving or explicitly.
+
+Automatic file type resolving checks the different PHPExcel_Reader_IReader distributed with PHPExcel. If one of them can load the specified file name, the file is loaded using that PHPExcel_Reader_IReader. Explicit mode requires you to specify which PHPExcel_Reader_IReader should be used.
+
+You can create a PHPExcel_Reader_IReader instance using PHPExcel_IOFactory in automatic file type resolving mode using the following code sample:
+
+```php
+$objPHPExcel = PHPExcel_IOFactory::load("05featuredemo.xlsx");
+```
+
+A typical use of this feature is when you need to read files uploaded by your users, and you don’t know whether they are uploading xls or xlsx files.
+
+If you need to set some properties on the reader, (e.g. to only read data, see more about this later), then you may instead want to use this variant:
+
+```php
+$objReader = PHPExcel_IOFactory::createReaderForFile("05featuredemo.xlsx");
+$objReader->setReadDataOnly(true);
+$objReader->load("05featuredemo.xlsx");
+```
+
+You can create a PHPExcel_Reader_IReader instance using PHPExcel_IOFactory in explicit mode using the following code sample:
+
+```php
+$objReader = PHPExcel_IOFactory::createReader("Excel2007");
+$objPHPExcel = $objReader->load("05featuredemo.xlsx");
+```
+
+Note that automatic type resolving mode is slightly slower than explicit mode.
+
+#### Creating PHPExcel_Writer_IWriter using PHPExcel_IOFactory
+
+You can create a PHPExcel_Writer_Iwriter instance using PHPExcel_IOFactory:
+
+```php
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, "Excel2007");
+$objWriter->save("05featuredemo.xlsx");
+```
+
+### Excel 2007 (SpreadsheetML) file format
+
+Excel2007 file format is the main file format of PHPExcel. It allows outputting the in-memory spreadsheet to a .xlsx file.
+
+#### PHPExcel_Reader_Excel2007
+
+##### Reading a spreadsheet
+
+You can read an .xlsx file using the following code:
+
+```php
+$objReader = new PHPExcel_Reader_Excel2007();
+$objPHPExcel = $objReader->load("05featuredemo.xlsx");
+```
+
+##### Read data only
+
+You can set the option setReadDataOnly on the reader, to instruct the reader to ignore styling, data validation, … and just read cell data:
+
+```php
+$objReader = new PHPExcel_Reader_Excel2007();
+$objReader->setReadDataOnly(true);
+$objPHPExcel = $objReader->load("05featuredemo.xlsx");
+```
+
+##### Read specific sheets only
+
+You can set the option setLoadSheetsOnly on the reader, to instruct the reader to only load the sheets with a given name:
+
+```php
+$objReader = new PHPExcel_Reader_Excel2007();
+$objReader->setLoadSheetsOnly( array("Sheet 1", "My special sheet") );
+$objPHPExcel = $objReader->load("05featuredemo.xlsx");
+```
+
+##### Read specific cells only
+
+You can set the option setReadFilter on the reader, to instruct the reader to only load the cells which match a given rule. A read filter can be any class which implements PHPExcel_Reader_IReadFilter. By default, all cells are read using the PHPExcel_Reader_DefaultReadFilter.
+
+The following code will only read row 1 and rows 20 – 30 of any sheet in the Excel file:
+
+```php
+class MyReadFilter implements PHPExcel_Reader_IReadFilter {
+
+ public function readCell($column, $row, $worksheetName = '') {
+ // Read title row and rows 20 - 30
+ if ($row == 1 || ($row >= 20 && $row <= 30)) {
+ return true;
+ }
+ return false;
+ }
+}
+
+$objReader = new PHPExcel_Reader_Excel2007();
+$objReader->setReadFilter( new MyReadFilter() );
+$objPHPExcel = $objReader->load("06largescale.xlsx");
+```
+
+#### PHPExcel_Writer_Excel2007
+
+##### Writing a spreadsheet
+
+You can write an .xlsx file using the following code:
+
+```php
+$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
+$objWriter->save("05featuredemo.xlsx");
+```
+
+##### Formula pre-calculation
+
+By default, this writer pre-calculates all formulas in the spreadsheet. This can be slow on large spreadsheets, and maybe even unwanted. You can however disable formula pre-calculation:
+
+```php
+$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
+$objWriter->setPreCalculateFormulas(false);
+$objWriter->save("05featuredemo.xlsx");
+```
+
+##### Office 2003 compatibility pack
+
+Because of a bug in the Office2003 compatibility pack, there can be some small issues when opening Excel2007 spreadsheets (mostly related to formula calculation). You can enable Office2003 compatibility with the following code:
+
+```
+$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
+$objWriter->setOffice2003Compatibility(true);
+$objWriter->save("05featuredemo.xlsx");
+```
+
+__Office2003 compatibility should only be used when needed__
+Office2003 compatibility option should only be used when needed. This option disables several Office2007 file format options, resulting in a lower-featured Office2007 spreadsheet when this option is used.
+
+### Excel 5 (BIFF) file format
+
+Excel5 file format is the old Excel file format, implemented in PHPExcel to provide a uniform manner to create both .xlsx and .xls files. It is basically a modified version of [PEAR Spreadsheet_Excel_Writer][21], although it has been extended and has fewer limitations and more features than the old PEAR library. This can read all BIFF versions that use OLE2: BIFF5 (introduced with office 95) through BIFF8, but cannot read earlier versions.
+
+Excel5 file format will not be developed any further, it just provides an additional file format for PHPExcel.
+
+__Excel5 (BIFF) limitations__
+Please note that BIFF file format has some limits regarding to styling cells and handling large spreadsheets via PHP.
+
+#### PHPExcel_Reader_Excel5
+
+##### Reading a spreadsheet
+
+You can read an .xls file using the following code:
+
+```php
+$objReader = new PHPExcel_Reader_Excel5();
+$objPHPExcel = $objReader->load("05featuredemo.xls");
+```
+
+##### Read data only
+
+You can set the option setReadDataOnly on the reader, to instruct the reader to ignore styling, data validation, … and just read cell data:
+
+```php
+$objReader = new PHPExcel_Reader_Excel5();
+$objReader->setReadDataOnly(true);
+$objPHPExcel = $objReader->load("05featuredemo.xls");
+```
+
+##### Read specific sheets only
+
+You can set the option setLoadSheetsOnly on the reader, to instruct the reader to only load the sheets with a given name:
+
+```php
+$objReader = new PHPExcel_Reader_Excel5();
+$objReader->setLoadSheetsOnly( array("Sheet 1", "My special sheet") );
+$objPHPExcel = $objReader->load("05featuredemo.xls");
+```
+
+##### Read specific cells only
+
+You can set the option setReadFilter on the reader, to instruct the reader to only load the cells which match a given rule. A read filter can be any class which implements PHPExcel_Reader_IReadFilter. By default, all cells are read using the PHPExcel_Reader_DefaultReadFilter.
+
+The following code will only read row 1 and rows 20 to 30 of any sheet in the Excel file:
+
+```php
+class MyReadFilter implements PHPExcel_Reader_IReadFilter {
+
+ public function readCell($column, $row, $worksheetName = '') {
+ // Read title row and rows 20 - 30
+ if ($row == 1 || ($row >= 20 && $row <= 30)) {
+ return true;
+ }
+ return false;
+ }
+}
+
+$objReader = new PHPExcel_Reader_Excel5();
+$objReader->setReadFilter( new MyReadFilter() );
+$objPHPExcel = $objReader->load("06largescale.xls");
+```
+
+#### PHPExcel_Writer_Excel5
+
+##### Writing a spreadsheet
+
+You can write an .xls file using the following code:
+
+```php
+$objWriter = new PHPExcel_Writer_Excel5($objPHPExcel);
+$objWriter->save("05featuredemo.xls");
+```
+
+### Excel 2003 XML file format
+
+Excel 2003 XML file format is a file format which can be used in older versions of Microsoft Excel.
+
+__Excel 2003 XML limitations__
+Please note that Excel 2003 XML format has some limits regarding to styling cells and handling large spreadsheets via PHP.
+
+#### PHPExcel_Reader_Excel2003XML
+
+##### Reading a spreadsheet
+
+You can read an Excel 2003 .xml file using the following code:
+
+```php
+$objReader = new PHPExcel_Reader_Excel2003XML();
+$objPHPExcel = $objReader->load("05featuredemo.xml");
+```
+
+##### Read specific cells only
+
+You can set the option setReadFilter on the reader, to instruct the reader to only load the cells which match a given rule. A read filter can be any class which implements PHPExcel_Reader_IReadFilter. By default, all cells are read using the PHPExcel_Reader_DefaultReadFilter.
+
+The following code will only read row 1 and rows 20 to 30 of any sheet in the Excel file:
+
+```php
+class MyReadFilter implements PHPExcel_Reader_IReadFilter {
+
+ public function readCell($column, $row, $worksheetName = '') {
+ // Read title row and rows 20 - 30
+ if ($row == 1 || ($row >= 20 && $row <= 30)) {
+ return true;
+ }
+ return false;
+ }
+
+}
+
+$objReader = new PHPExcel_Reader_Excel2003XML();
+$objReader->setReadFilter( new MyReadFilter() );
+$objPHPExcel = $objReader->load("06largescale.xml");
+```
+
+### Symbolic LinK (SYLK)
+
+Symbolic Link (SYLK) is a Microsoft file format typically used to exchange data between applications, specifically spreadsheets. SYLK files conventionally have a .slk suffix. Composed of only displayable ANSI characters, it can be easily created and processed by other applications, such as databases.
+
+__SYLK limitations__
+Please note that SYLK file format has some limits regarding to styling cells and handling large spreadsheets via PHP.
+
+#### PHPExcel_Reader_SYLK
+
+##### Reading a spreadsheet
+
+You can read an .slk file using the following code:
+
+```php
+$objReader = new PHPExcel_Reader_SYLK();
+$objPHPExcel = $objReader->load("05featuredemo.slk");
+```
+
+##### Read specific cells only
+
+You can set the option setReadFilter on the reader, to instruct the reader to only load the cells which match a given rule. A read filter can be any class which implements PHPExcel_Reader_IReadFilter. By default, all cells are read using the PHPExcel_Reader_DefaultReadFilter.
+
+The following code will only read row 1 and rows 20 to 30 of any sheet in the SYLK file:
+
+```php
+class MyReadFilter implements PHPExcel_Reader_IReadFilter {
+
+ public function readCell($column, $row, $worksheetName = '') {
+ // Read title row and rows 20 - 30
+ if ($row == 1 || ($row >= 20 && $row <= 30)) {
+ return true;
+ }
+ return false;
+ }
+
+}
+
+$objReader = new PHPExcel_Reader_SYLK();
+$objReader->setReadFilter( new MyReadFilter() );
+$objPHPExcel = $objReader->load("06largescale.slk");
+```
+
+### Open/Libre Office (.ods)
+
+Open Office or Libre Office .ods files are the standard file format for Open Office or Libre Office Calc files.
+
+#### PHPExcel_Reader_OOCalc
+
+##### Reading a spreadsheet
+
+You can read an .ods file using the following code:
+
+```php
+$objReader = new PHPExcel_Reader_OOCalc();
+$objPHPExcel = $objReader->load("05featuredemo.ods");
+```
+
+##### Read specific cells only
+
+You can set the option setReadFilter on the reader, to instruct the reader to only load the cells which match a given rule. A read filter can be any class which implements PHPExcel_Reader_IReadFilter. By default, all cells are read using the PHPExcel_Reader_DefaultReadFilter.
+
+The following code will only read row 1 and rows 20 to 30 of any sheet in the Calc file:
+
+```php
+class MyReadFilter implements PHPExcel_Reader_IReadFilter {
+
+ public function readCell($column, $row, $worksheetName = '') {
+ // Read title row and rows 20 - 30
+ if ($row == 1 || ($row >= 20 && $row <= 30)) {
+ return true;
+ }
+ return false;
+ }
+
+}
+
+$objReader = new PHPExcel_Reader_OOcalc();
+$objReader->setReadFilter( new MyReadFilter() );
+$objPHPExcel = $objReader->load("06largescale.ods");
+```
+
+### CSV (Comma Separated Values)
+
+CSV (Comma Separated Values) are often used as an import/export file format with other systems. PHPExcel allows reading and writing to CSV files.
+
+__CSV limitations__
+Please note that CSV file format has some limits regarding to styling cells, number formatting, ...
+
+#### PHPExcel_Reader_CSV
+
+##### Reading a CSV file
+
+You can read a .csv file using the following code:
+
+```php
+$objReader = new PHPExcel_Reader_CSV();
+$objPHPExcel = $objReader->load("sample.csv");
+```
+
+##### Setting CSV options
+
+Often, CSV files are not really “comma separated”, or use semicolon (;) as a separator. You can instruct PHPExcel_Reader_CSV some options before reading a CSV file.
+
+Note that PHPExcel_Reader_CSV by default assumes that the loaded CSV file is UTF-8 encoded. If you are reading CSV files that were created in Microsoft Office Excel the correct input encoding may rather be Windows-1252 (CP1252). Always make sure that the input encoding is set appropriately.
+
+```php
+$objReader = new PHPExcel_Reader_CSV();
+$objReader->setInputEncoding('CP1252');
+$objReader->setDelimiter(';');
+$objReader->setEnclosure('');
+$objReader->setLineEnding("\r\n");
+$objReader->setSheetIndex(0);
+
+$objPHPExcel = $objReader->load("sample.csv");
+```
+
+##### Read a specific worksheet
+
+CSV files can only contain one worksheet. Therefore, you can specify which sheet to read from CSV:
+
+```php
+$objReader->setSheetIndex(0);
+```
+
+##### Read into existing spreadsheet
+
+When working with CSV files, it might occur that you want to import CSV data into an existing PHPExcel object. The following code loads a CSV file into an existing $objPHPExcel containing some sheets, and imports onto the 6th sheet:
+
+```php
+$objReader = new PHPExcel_Reader_CSV();
+$objReader->setDelimiter(';');
+$objReader->setEnclosure('');
+$objReader->setLineEnding("\r\n");
+$objReader->setSheetIndex(5);
+
+$objReader->loadIntoExisting("05featuredemo.csv", $objPHPExcel);
+```
+
+#### PHPExcel_Writer_CSV
+
+##### Writing a CSV file
+
+You can write a .csv file using the following code:
+
+```php
+$objWriter = new PHPExcel_Writer_CSV($objPHPExcel);
+$objWriter->save("05featuredemo.csv");
+```
+
+##### Setting CSV options
+
+Often, CSV files are not really “comma separated”, or use semicolon (;) as a separator. You can instruct PHPExcel_Writer_CSV some options before writing a CSV file:
+
+```php
+$objWriter = new PHPExcel_Writer_CSV($objPHPExcel);
+$objWriter->setDelimiter(';');
+$objWriter->setEnclosure('');
+$objWriter->setLineEnding("\r\n");
+$objWriter->setSheetIndex(0);
+
+$objWriter->save("05featuredemo.csv");
+```
+
+##### Write a specific worksheet
+
+CSV files can only contain one worksheet. Therefore, you can specify which sheet to write to CSV:
+
+```php
+$objWriter->setSheetIndex(0);
+```
+
+##### Formula pre-calculation
+
+By default, this writer pre-calculates all formulas in the spreadsheet. This can be slow on large spreadsheets, and maybe even unwanted. You can however disable formula pre-calculation:
+
+```php
+$objWriter = new PHPExcel_Writer_CSV($objPHPExcel);
+$objWriter->setPreCalculateFormulas(false);
+$objWriter->save("05featuredemo.csv");
+```
+
+##### Writing UTF-8 CSV files
+
+A CSV file can be marked as UTF-8 by writing a BOM file header. This can be enabled by using the following code:
+
+```php
+$objWriter = new PHPExcel_Writer_CSV($objPHPExcel);
+$objWriter->setUseBOM(true);
+$objWriter->save("05featuredemo.csv");
+```
+
+##### Decimal and thousands separators
+
+If the worksheet you are exporting contains numbers with decimal or thousands separators then you should think about what characters you want to use for those before doing the export.
+
+By default PHPExcel looks up in the server's locale settings to decide what characters to use. But to avoid problems it is recommended to set the characters explicitly as shown below.
+
+English users will want to use this before doing the export:
+
+```php
+PHPExcel_Shared_String::setDecimalSeparator('.');
+PHPExcel_Shared_String::setThousandsSeparator(',');
+```
+
+German users will want to use the opposite values.
+
+```php
+PHPExcel_Shared_String::setDecimalSeparator(',');
+PHPExcel_Shared_String::setThousandsSeparator('.');
+```
+
+Note that the above code sets decimal and thousand separators as global options. This also affects how HTML and PDF is exported.
+
+### HTML
+
+PHPExcel allows you to read or write a spreadsheet as HTML format, for quick representation of the data in it to anyone who does not have a spreadsheet application on their PC, or loading files saved by other scripts that simply create HTML markup and give it a .xls file extension.
+
+__HTML limitations__
+Please note that HTML file format has some limits regarding to styling cells, number formatting, ...
+
+#### PHPExcel_Reader_HTML
+
+##### Reading a spreadsheet
+
+You can read an .html or .htm file using the following code:
+
+```php
+$objReader = new PHPExcel_Reader_HTML();
+
+$objPHPExcel = $objReader->load("05featuredemo.html");
+```
+
+__HTML limitations__
+Please note that HTML reader is still experimental and does not yet support merged cells or nested tables cleanly
+
+#### PHPExcel_Writer_HTML
+
+Please note that PHPExcel_Writer_HTML only outputs the first worksheet by default.
+
+##### Writing a spreadsheet
+
+You can write a .htm file using the following code:
+
+```php
+$objWriter = new PHPExcel_Writer_HTML($objPHPExcel);
+
+$objWriter->save("05featuredemo.htm");
+```
+
+##### Write all worksheets
+
+HTML files can contain one or more worksheets. If you want to write all sheets into a single HTML file, use the following code:
+
+```php
+$objWriter->writeAllSheets();
+```
+
+##### Write a specific worksheet
+
+HTML files can contain one or more worksheets. Therefore, you can specify which sheet to write to HTML:
+
+```php
+$objWriter->setSheetIndex(0);
+```
+
+##### Setting the images root of the HTML file
+
+There might be situations where you want to explicitly set the included images root. For example, one might want to see
+```html
+
+```
+
+instead of
+
+```html
+
.
+```
+
+You can use the following code to achieve this result:
+
+```php
+$objWriter->setImagesRoot('http://www.example.com');
+```
+
+##### Formula pre-calculation
+
+By default, this writer pre-calculates all formulas in the spreadsheet. This can be slow on large spreadsheets, and maybe even unwanted. You can however disable formula pre-calculation:
+
+```php
+$objWriter = new PHPExcel_Writer_HTML($objPHPExcel);
+$objWriter->setPreCalculateFormulas(false);
+
+$objWriter->save("05featuredemo.htm");
+```
+
+##### Embedding generated HTML in a web page
+
+There might be a situation where you want to embed the generated HTML in an existing website. PHPExcel_Writer_HTML provides support to generate only specific parts of the HTML code, which allows you to use these parts in your website.
+
+Supported methods:
+
+ - generateHTMLHeader()
+ - generateStyles()
+ - generateSheetData()
+ - generateHTMLFooter()
+
+Here's an example which retrieves all parts independently and merges them into a resulting HTML page:
+
+```php
+generateHTMLHeader();
+?>
+
+
+?>
+
+-->
+
+
+generateSheetData();
+echo $objWriter->generateHTMLFooter();
+?>
+```
+
+##### Writing UTF-8 HTML files
+
+A HTML file can be marked as UTF-8 by writing a BOM file header. This can be enabled by using the following code:
+
+```php
+$objWriter = new PHPExcel_Writer_HTML($objPHPExcel);
+$objWriter->setUseBOM(true);
+
+$objWriter->save("05featuredemo.htm");
+```
+
+##### Decimal and thousands separators
+
+See section PHPExcel_Writer_CSV how to control the appearance of these.
+
+### PDF
+
+PHPExcel allows you to write a spreadsheet into PDF format, for fast distribution of represented data.
+
+__PDF limitations__
+Please note that PDF file format has some limits regarding to styling cells, number formatting, ...
+
+#### PHPExcel_Writer_PDF
+
+PHPExcel’s PDF Writer is a wrapper for a 3rd-Party PDF Rendering library such as tcPDF, mPDF or DomPDF. Prior to version 1.7.8 of PHPExcel, the tcPDF library was bundled with PHPExcel; but from version 1.7.8 this was removed. Instead, you must now install a PDF Rendering library yourself; but PHPExcel will work with a number of different libraries.
+
+Currently, the following libraries are supported:
+
+Library | Version used for testing | Downloadable from | PHPExcel Internal Constant
+--------|--------------------------|----------------------------------|----------------------------
+tcPDF | 5.9 | http://www.tcpdf.org/ | PDF_RENDERER_TCPDF
+mPDF | 5.4 | http://www.mpdf1.com/mpdf/ | PDF_RENDERER_MPDF
+domPDF | 0.6.0 beta 3 | http://code.google.com/p/dompdf/ | PDF_RENDERER_DOMPDF
+
+The different libraries have different strengths and weaknesses. Some generate better formatted output than others, some are faster or use less memory than others, while some generate smaller .pdf files. It is the developers choice which one they wish to use, appropriate to their own circumstances.
+
+Before instantiating a Writer to generate PDF output, you will need to indicate which Rendering library you are using, and where it is located.
+
+```php
+$rendererName = PHPExcel_Settings::PDF_RENDERER_MPDF;
+$rendererLibrary = 'mPDF5.4';
+$rendererLibraryPath = dirname(__FILE__).'/../../../libraries/PDF/' . $rendererLibrary;
+
+if (!PHPExcel_Settings::setPdfRenderer(
+ $rendererName,
+ $rendererLibraryPath
+ )) {
+ die(
+ 'Please set the $rendererName and $rendererLibraryPath values' .
+ PHP_EOL .
+ ' as appropriate for your directory structure'
+ );
+}
+```
+
+##### Writing a spreadsheet
+
+Once you have identified the Renderer that you wish to use for PDF generation, you can write a .pdf file using the following code:
+
+```php
+$objWriter = new PHPExcel_Writer_PDF($objPHPExcel);
+$objWriter->save("05featuredemo.pdf");
+```
+
+Please note that PHPExcel_Writer_PDF only outputs the first worksheet by default.
+
+##### Write all worksheets
+
+PDF files can contain one or more worksheets. If you want to write all sheets into a single PDF file, use the following code:
+
+```php
+$objWriter->writeAllSheets();
+```
+
+##### Write a specific worksheet
+
+PDF files can contain one or more worksheets. Therefore, you can specify which sheet to write to PDF:
+
+```php
+$objWriter->setSheetIndex(0);
+```
+
+##### Formula pre-calculation
+
+By default, this writer pre-calculates all formulas in the spreadsheet. This can be slow on large spreadsheets, and maybe even unwanted. You can however disable formula pre-calculation:
+
+```php
+$objWriter = new PHPExcel_Writer_PDF($objPHPExcel);
+$objWriter->setPreCalculateFormulas(false);
+
+$objWriter->save("05featuredemo.pdf");
+```
+
+##### Decimal and thousands separators
+
+See section PHPExcel_Writer_CSV how to control the appearance of these.
+
+### Generating Excel files from templates (read, modify, write)
+
+Readers and writers are the tools that allow you to generate Excel files from templates. This requires less coding effort than generating the Excel file from scratch, especially if your template has many styles, page setup properties, headers etc.
+
+Here is an example how to open a template file, fill in a couple of fields and save it again:
+
+```php
+$objPHPexcel = PHPExcel_IOFactory::load('template.xlsx');
+
+$objWorksheet = $objPHPexcel->getActiveSheet();
+
+$objWorksheet->getCell('A1')->setValue('John');
+$objWorksheet->getCell('A2')->setValue('Smith');
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPexcel, 'Excel5');
+$objWriter->save('write.xls');
+```
+
+Notice that it is ok to load an xlsx file and generate an xls file.
+
+ [21]: http://pear.php.net/package/Spreadsheet_Excel_Writer
+ [22]: http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=Credits&referringTitle=Home
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/11-Appendices.md b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/11-Appendices.md
new file mode 100755
index 000000000..1302feb3f
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/11-Appendices.md
@@ -0,0 +1,100 @@
+# PHPExcel Developer Documentation
+
+## Credits
+
+Please refer to the internet page [http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=Credits&referringTitle=Home][22] for up-to-date credits.
+
+## Valid array keys for style applyFromArray()
+
+The following table lists the valid array keys for PHPExcel_Style applyFromArray() classes. If the "Maps to property" column maps a key to a setter, the value provided for that key will be applied directly. If the "Maps to property" column maps a key to a getter, the value provided for that key will be applied as another style array.
+
+__PHPExcel_Style__
+
+ Array key | Maps to property
+ -------------|-------------------
+ fill | getFill()
+ font | getFont()
+ borders | getBorders()
+ alignment | getAlignment()
+ numberformat | getNumberFormat()
+ protection | getProtection()
+
+
+__PHPExcel_Style_Fill__
+
+ Array key | Maps to property
+ -----------|-------------------
+ type | setFillType()
+ rotation | setRotation()
+ startcolor | getStartColor()
+ endcolor | getEndColor()
+ color | getStartColor()
+
+
+__PHPExcel_Style_Font__
+
+ Array key | Maps to property
+ ------------|-------------------
+ name | setName()
+ bold | setBold()
+ italic | setItalic()
+ underline | setUnderline()
+ strike | setStrikethrough()
+ color | getColor()
+ size | setSize()
+ superScript | setSuperScript()
+ subScript | setSubScript()
+
+
+__PHPExcel_Style_Borders__
+
+ Array key | Maps to property
+ ------------------|-------------------
+ allborders | getLeft(); getRight(); getTop(); getBottom()
+ left | getLeft()
+ right | getRight()
+ top | getTop()
+ bottom | getBottom()
+ diagonal | getDiagonal()
+ vertical | getVertical()
+ horizontal | getHorizontal()
+ diagonaldirection | setDiagonalDirection()
+ outline | setOutline()
+
+
+__PHPExcel_Style_Border__
+
+ Array key | Maps to property
+ ----------|-------------------
+ style | setBorderStyle()
+ color | getColor()
+
+
+__PHPExcel_Style_Alignment__
+
+ Array key | Maps to property
+ ------------|-------------------
+ horizontal | setHorizontal()
+ vertical | setVertical()
+ rotation | setTextRotation()
+ wrap | setWrapText()
+ shrinkToFit | setShrinkToFit()
+ indent | setIndent()
+
+
+__PHPExcel_Style_NumberFormat__
+
+ Array key | Maps to property
+ ----------|-------------------
+ code | setFormatCode()
+
+
+__PHPExcel_Style_Protection__
+
+ Array key | Maps to property
+ ----------|-------------------
+ locked | setLocked()
+ hidden | setHidden()
+
+
+ [22]: http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=Credits&referringTitle=Home
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/01-schematic.png b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/01-schematic.png
new file mode 100755
index 000000000..8b6779204
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/01-schematic.png differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/02-readers-writers.png b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/02-readers-writers.png
new file mode 100755
index 000000000..0600788ae
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/02-readers-writers.png differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/07-simple-example-1.png b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/07-simple-example-1.png
new file mode 100755
index 000000000..30d193683
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/07-simple-example-1.png differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/07-simple-example-2.png b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/07-simple-example-2.png
new file mode 100755
index 000000000..e2b68506c
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/07-simple-example-2.png differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/07-simple-example-3.png b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/07-simple-example-3.png
new file mode 100755
index 000000000..459261f33
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/07-simple-example-3.png differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/07-simple-example-4.png b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/07-simple-example-4.png
new file mode 100755
index 000000000..70725452f
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/07-simple-example-4.png differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/08-cell-comment.png b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/08-cell-comment.png
new file mode 100755
index 000000000..bd8f8e66e
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/08-cell-comment.png differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/08-column-width.png b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/08-column-width.png
new file mode 100755
index 000000000..141994341
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/08-column-width.png differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/08-page-setup-margins.png b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/08-page-setup-margins.png
new file mode 100755
index 000000000..36e07a9b6
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/08-page-setup-margins.png differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/08-page-setup-scaling-options.png b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/08-page-setup-scaling-options.png
new file mode 100755
index 000000000..80fb5f00c
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/08-page-setup-scaling-options.png differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/08-styling-border-options.png b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/08-styling-border-options.png
new file mode 100755
index 000000000..4ef597070
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/08-styling-border-options.png differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/09-command-line-calculation.png b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/09-command-line-calculation.png
new file mode 100755
index 000000000..ceb2b3091
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/09-command-line-calculation.png differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/09-formula-in-cell-1.png b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/09-formula-in-cell-1.png
new file mode 100755
index 000000000..e50c6cc84
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/09-formula-in-cell-1.png differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/09-formula-in-cell-2.png b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/09-formula-in-cell-2.png
new file mode 100755
index 000000000..46daf090d
Binary files /dev/null and b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/Overview/images/09-formula-in-cell-2.png differ
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/01-File-Formats.md b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/01-File-Formats.md
new file mode 100755
index 000000000..d89166437
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/01-File-Formats.md
@@ -0,0 +1,60 @@
+# PHPExcel User Documentation – Reading Spreadsheet Files
+
+
+## Spreadsheet File Formats
+
+PHPExcel can read a number of different spreadsheet and file formats, although not all features are supported by all of the readers. Check the Functionality Cross-Reference document (Functionality Cross-Reference.xls) for a list that identifies which features are supported by which readers.
+
+Currently, PHPExcel supports the following File Types for Reading:
+
+### Excel5
+
+The Microsoft Excel™ Binary file format (BIFF5 and BIFF8) is a binary file format that was used by Microsoft Excel™ between versions 95 and 2003. The format is supported (to various extents) by most spreadsheet programs. BIFF files normally have an extension of .xls. Documentation describing the format can be found online at [http://msdn.microsoft.com/en-us/library/cc313154(v=office.12).aspx][1] or from [http://download.microsoft.com/download/2/4/8/24862317-78F0-4C4B-B355-C7B2C1D997DB/[MS-XLS].pdf][2] (as a downloadable PDF).
+
+### Excel2003XML
+
+Microsoft Excel™ 2003 included options for a file format called SpreadsheetML. This file is a zipped XML document. It is not very common, but its core features are supported. Documentation for the format can be found at [http://msdn.microsoft.com/en-us/library/aa140066%28office.10%29.aspx][3] though it’s sadly rather sparse in its detail.
+
+### Excel2007
+
+Microsoft Excel™ 2007 shipped with a new file format, namely Microsoft Office Open XML SpreadsheetML, and Excel 2010 extended this still further with its new features such as sparklines. These files typically have an extension of .xlsx. This format is based around a zipped collection of eXtensible Markup Language (XML) files. Microsoft Office Open XML SpreadsheetML is mostly standardized in ECMA 376 ([http://www.ecma-international.org/news/TC45_current_work/TC45_available_docs.htm][4]) and ISO 29500.
+
+### OOCalc
+
+aka Open Document Format (ODF) or OASIS, this is the OpenOffice.org XML File Format for spreadsheets. It comprises a zip archive including several components all of which are text files, most of these with markup in the eXtensible Markup Language (XML). It is the standard file format for OpenOffice.org Calc and StarCalc, and files typically have an extension of .ods. The published specification for the file format is available from the OASIS Open Office XML Format Technical Committee web page ([http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=office#technical][5]). Other information is available from the OpenOffice.org XML File Format web page ([http://xml.openoffice.org/general.html][6]), part of the OpenOffice.org project.
+
+### SYLK
+
+This is the Microsoft Multiplan Symbolic Link Interchange (SYLK) file format. Multiplan was a predecessor to Microsoft Excel™. Files normally have an extension of .slk. While not common, there are still a few applications that generate SYLK files as a cross-platform option, because (despite being limited to a single worksheet) it is a simple format to implement, and supports some basic data and cell formatting options (unlike CSV files).
+
+### Gnumeric
+
+The Gnumeric file format is used by the Gnome Gnumeric spreadsheet application, and typically files have an extension of .gnumeric. The file contents are stored using eXtensible Markup Language (XML) markup, and the file is then compressed using the GNU project's gzip compression library. [http://projects.gnome.org/gnumeric/doc/file-format-gnumeric.shtml][7]
+
+### CSV
+
+Comma Separated Value (CSV) file format is a common structuring strategy for text format files. In CSV flies, each line in the file represents a row of data and (within each line of the file) the different data fields (or columns) are separated from one another using a comma (","). If a data field contains a comma, then it should be enclosed (typically in quotation marks ("). Sometimes tabs "\t", or the pipe symbol ("|"), or a semi-colon (";") are used as separators instead of a comma, although other symbols can be used. Because CSV is a text-only format, it doesn't support any data formatting options.
+
+"CSV" is not a single, well-defined format (although see RFC 4180 for one definition that is commonly used). Rather, in practice the term "CSV" refers to any file that:
+ - is plain text using a character set such as ASCII, Unicode, EBCDIC, or Shift JIS,
+ - consists of records (typically one record per line),
+ - with the records divided into fields separated by delimiters (typically a single reserved character such as comma, semicolon, or tab,
+ - where every record has the same sequence of fields.
+
+Within these general constraints, many variations are in use. Therefore "CSV" files are not entirely portable. Nevertheless, the variations are fairly small, and many implementations allow users to glance at the file (which is feasible because it is plain text), and then specify the delimiter character(s), quoting rules, etc.
+
+**Warning:** Microsoft Excel™ will open .csv files, but depending on the system's regional settings, it may expect a semicolon as a separator instead of a comma, since in some languages the comma is used as the decimal separator. Also, many regional versions of Excel will not be able to deal with Unicode characters in a CSV file.
+
+### HTML
+
+HyperText Markup Language (HTML) is the main markup language for creating web pages and other information that can be displayed in a web browser. Files typically have an extension of .html or .htm. HTML markup provides a means to create structured documents by denoting structural semantics for text such as headings, paragraphs, lists, links, quotes and other items. Since 1996, the HTML specifications have been maintained, with input from commercial software vendors, by the World Wide Web Consortium (W3C). However, in 2000, HTML also became an international standard (ISO/IEC 15445:2000). HTML 4.01 was published in late 1999, with further errata published through 2001. In 2004 development began on HTML5 in the Web Hypertext Application Technology Working Group (WHATWG), which became a joint deliverable with the W3C in 2008.
+
+
+
+ [1]: http://msdn.microsoft.com/en-us/library/cc313154(v=office.12).aspx
+ [2]: http://download.microsoft.com/download/2/4/8/24862317-78F0-4C4B-B355-C7B2C1D997DB/%5bMS-XLS%5d.pdf
+ [3]: http://msdn.microsoft.com/en-us/library/aa140066%28office.10%29.aspx
+ [4]: http://www.ecma-international.org/news/TC45_current_work/TC45_available_docs.htm
+ [5]: http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=office
+ [6]: http://xml.openoffice.org/general.html
+ [7]: http://projects.gnome.org/gnumeric/doc/file-format-gnumeric.shtml
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/02-Security.md b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/02-Security.md
new file mode 100755
index 000000000..12da958ff
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/02-Security.md
@@ -0,0 +1,13 @@
+# PHPExcel User Documentation – Reading Spreadsheet Files
+
+
+## Security
+
+XML-based formats such as OfficeOpen XML, Excel2003 XML, OASIS and Gnumeric are susceptible to XML External Entity Processing (XXE) injection attacks (for an explanation of XXE injection see http://websec.io/2012/08/27/Preventing-XEE-in-PHP.html) when reading spreadsheet files. This can lead to:
+
+ - Disclosure whether a file is existent
+ - Server Side Request Forgery
+ - Command Execution (depending on the installed PHP wrappers)
+
+
+To prevent this, PHPExcel sets `libxml_disable_entity_loader` to `true` for the XML-based Readers by default.
\ No newline at end of file
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/03-Loading-a-Spreadsheet.md b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/03-Loading-a-Spreadsheet.md
new file mode 100755
index 000000000..afa674d1b
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/03-Loading-a-Spreadsheet.md
@@ -0,0 +1,21 @@
+# PHPExcel User Documentation – Reading Spreadsheet Files
+
+
+## Loading a Spreadsheet File
+
+The simplest way to load a workbook file is to let PHPExcel's IO Factory identify the file type and load it, calling the static load() method of the PHPExcel_IOFactory class.
+
+```php
+$inputFileName = './sampleData/example1.xls';
+
+/** Load $inputFileName to a PHPExcel Object **/
+$objPHPExcel = PHPExcel_IOFactory::load($inputFileName);
+```
+ > See Examples/Reader/exampleReader01.php for a working example of this code.
+
+The load() method will attempt to identify the file type, and instantiate a loader for that file type; using it to load the file and store the data and any formatting in a PHPExcel object.
+
+The method makes an initial guess at the loader to instantiate based on the file extension; but will test the file before actually executing the load: so if (for example) the file is actually a CSV file or contains HTML markup, but that has been given a .xls extension (quite a common practise), it will reject the Excel5 loader that it would normally use for a .xls file; and test the file using the other loaders until it finds the appropriate loader, and then use that to read the file.
+
+While easy to implement in your code, and you don't need to worry about the file type; this isn't the most efficient method to load a file; and it lacks the flexibility to configure the loader in any way before actually reading the file into a PHPExcel object.
+
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/04-Loading-with-a-Reader.md b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/04-Loading-with-a-Reader.md
new file mode 100755
index 000000000..94d07aaa3
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/04-Loading-with-a-Reader.md
@@ -0,0 +1,56 @@
+# PHPExcel User Documentation – Reading Spreadsheet Files
+
+
+## Creating a Reader and Loading a Spreadsheet File
+
+If you know the file type of the spreadsheet file that you need to load, you can instantiate a new reader object for that file type, then use the reader's load() method to read the file to a PHPExcel object. It is possible to instantiate the reader objects for each of the different supported filetype by name. However, you may get unpredictable results if the file isn't of the right type (e.g. it is a CSV with an extension of .xls), although this type of exception should normally be trapped.
+
+```php
+$inputFileName = './sampleData/example1.xls';
+
+/** Create a new Excel5 Reader **/
+$objReader = new PHPExcel_Reader_Excel5();
+// $objReader = new PHPExcel_Reader_Excel2007();
+// $objReader = new PHPExcel_Reader_Excel2003XML();
+// $objReader = new PHPExcel_Reader_OOCalc();
+// $objReader = new PHPExcel_Reader_SYLK();
+// $objReader = new PHPExcel_Reader_Gnumeric();
+// $objReader = new PHPExcel_Reader_CSV();
+/** Load $inputFileName to a PHPExcel Object **/
+$objPHPExcel = $objReader->load($inputFileName);
+```
+ > See Examples/Reader/exampleReader02.php for a working example of this code.
+
+Alternatively, you can use the IO Factory's createReader() method to instantiate the reader object for you, simply telling it the file type of the reader that you want instantiating.
+
+```php
+$inputFileType = 'Excel5';
+// $inputFileType = 'Excel2007';
+// $inputFileType = 'Excel2003XML';
+// $inputFileType = 'OOCalc';
+// $inputFileType = 'SYLK';
+// $inputFileType = 'Gnumeric';
+// $inputFileType = 'CSV';
+$inputFileName = './sampleData/example1.xls';
+
+/** Create a new Reader of the type defined in $inputFileType **/
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+/** Load $inputFileName to a PHPExcel Object **/
+$objPHPExcel = $objReader->load($inputFileName);
+```
+ > See Examples/Reader/exampleReader03.php for a working example of this code.
+
+If you're uncertain of the filetype, you can use the IO Factory's identify() method to identify the reader that you need, before using the createReader() method to instantiate the reader object.
+
+```php
+$inputFileName = './sampleData/example1.xls';
+
+/** Identify the type of $inputFileName **/
+$inputFileType = PHPExcel_IOFactory::identify($inputFileName);
+/** Create a new Reader of the type that has been identified **/
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+/** Load $inputFileName to a PHPExcel Object **/
+$objPHPExcel = $objReader->load($inputFileName);
+```
+ > See Examples/Reader/exampleReader04.php for a working example of this code.
+
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/05-Reader-Options.md b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/05-Reader-Options.md
new file mode 100755
index 000000000..137fd1e8f
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/05-Reader-Options.md
@@ -0,0 +1,392 @@
+# PHPExcel User Documentation – Reading Spreadsheet Files
+
+## Spreadsheet Reader Options
+
+Once you have created a reader object for the workbook that you want to load, you have the opportunity to set additional options before executing the load() method.
+
+### Reading Only Data from a Spreadsheet File
+
+If you're only interested in the cell values in a workbook, but don't need any of the cell formatting information, then you can set the reader to read only the data values and any formulae from each cell using the setReadDataOnly() method.
+
+```php
+$inputFileType = 'Excel5';
+$inputFileName = './sampleData/example1.xls';
+
+/** Create a new Reader of the type defined in $inputFileType **/
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+/** Advise the Reader that we only want to load cell data **/
+$objReader->setReadDataOnly(true);
+/** Load $inputFileName to a PHPExcel Object **/
+$objPHPExcel = $objReader->load($inputFileName);
+```
+ > See Examples/Reader/exampleReader05.php for a working example of this code.
+
+It is important to note that Workbooks (and PHPExcel) store dates and times as simple numeric values: they can only be distinguished from other numeric values by the format mask that is applied to that cell. When setting read data only to true, PHPExcel doesn't read the cell format masks, so it is not possible to differentiate between dates/times and numbers.
+
+The Gnumeric loader has been written to read the format masks for date values even when read data only has been set to true, so it can differentiate between dates/times and numbers; but this change hasn't yet been implemented for the other readers.
+
+Reading Only Data from a Spreadsheet File applies to Readers:
+
+Reader | Y/N |Reader | Y/N |Reader | Y/N |
+----------|:---:|--------|:---:|--------------|:---:|
+Excel2007 | YES | Excel5 | YES | Excel2003XML | YES |
+OOCalc | YES | SYLK | NO | Gnumeric | YES |
+CSV | NO | HTML | NO
+
+### Reading Only Named WorkSheets from a File
+
+If your workbook contains a number of worksheets, but you are only interested in reading some of those, then you can use the setLoadSheetsOnly() method to identify those sheets you are interested in reading.
+
+To read a single sheet, you can pass that sheet name as a parameter to the setLoadSheetsOnly() method.
+
+```php
+$inputFileType = 'Excel5';
+$inputFileName = './sampleData/example1.xls';
+$sheetname = 'Data Sheet #2';
+
+/** Create a new Reader of the type defined in $inputFileType **/
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+/** Advise the Reader of which WorkSheets we want to load **/
+$objReader->setLoadSheetsOnly($sheetname);
+/** Load $inputFileName to a PHPExcel Object **/
+$objPHPExcel = $objReader->load($inputFileName);
+```
+ > See Examples/Reader/exampleReader07.php for a working example of this code.
+
+If you want to read more than just a single sheet, you can pass a list of sheet names as an array parameter to the setLoadSheetsOnly() method.
+
+```php
+$inputFileType = 'Excel5';
+$inputFileName = './sampleData/example1.xls';
+$sheetnames = array('Data Sheet #1','Data Sheet #3');
+
+/** Create a new Reader of the type defined in $inputFileType **/
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+/** Advise the Reader of which WorkSheets we want to load **/
+$objReader->setLoadSheetsOnly($sheetnames);
+/** Load $inputFileName to a PHPExcel Object **/
+$objPHPExcel = $objReader->load($inputFileName);
+```
+ > See Examples/Reader/exampleReader08.php for a working example of this code.
+
+To reset this option to the default, you can call the setLoadAllSheets() method.
+
+```php
+$inputFileType = 'Excel5';
+$inputFileName = './sampleData/example1.xls';
+
+/** Create a new Reader of the type defined in $inputFileType **/
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+/** Advise the Reader to load all Worksheets **/
+$objReader->setLoadAllSheets();
+/** Load $inputFileName to a PHPExcel Object **/
+$objPHPExcel = $objReader->load($inputFileName);
+```
+ > See Examples/Reader/exampleReader06.php for a working example of this code.
+
+Reading Only Named WorkSheets from a File applies to Readers:
+
+Reader | Y/N |Reader | Y/N |Reader | Y/N |
+----------|:---:|--------|:---:|--------------|:---:|
+Excel2007 | YES | Excel5 | YES | Excel2003XML | YES |
+OOCalc | YES | SYLK | NO | Gnumeric | YES |
+CSV | NO | HTML | NO
+
+### Reading Only Specific Columns and Rows from a File (Read Filters)
+
+If you are only interested in reading part of a worksheet, then you can write a filter class that identifies whether or not individual cells should be read by the loader. A read filter must implement the PHPExcel_Reader_IReadFilter interface, and contain a readCell() method that accepts arguments of $column, $row and $worksheetName, and return a boolean true or false that indicates whether a workbook cell identified by those arguments should be read or not.
+
+```php
+$inputFileType = 'Excel5';
+$inputFileName = './sampleData/example1.xls';
+$sheetname = 'Data Sheet #3';
+
+
+/** Define a Read Filter class implementing PHPExcel_Reader_IReadFilter */
+class MyReadFilter implements PHPExcel_Reader_IReadFilter
+{
+ public function readCell($column, $row, $worksheetName = '') {
+ // Read rows 1 to 7 and columns A to E only
+ if ($row >= 1 && $row <= 7) {
+ if (in_array($column,range('A','E'))) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+/** Create an Instance of our Read Filter **/
+$filterSubset = new MyReadFilter();
+
+/** Create a new Reader of the type defined in $inputFileType **/
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+/** Tell the Reader that we want to use the Read Filter **/
+$objReader->setReadFilter($filterSubset);
+/** Load only the rows and columns that match our filter to PHPExcel **/
+$objPHPExcel = $objReader->load($inputFileName);
+```
+ > See Examples/Reader/exampleReader09.php for a working example of this code.
+
+This example is not particularly useful, because it can only be used in a very specific circumstance (when you only want cells in the range A1:E7 from your worksheet. A generic Read Filter would probably be more useful:
+
+```php
+/** Define a Read Filter class implementing PHPExcel_Reader_IReadFilter */
+class MyReadFilter implements PHPExcel_Reader_IReadFilter
+{
+ private $_startRow = 0;
+ private $_endRow = 0;
+ private $_columns = array();
+
+ /** Get the list of rows and columns to read */
+ public function __construct($startRow, $endRow, $columns) {
+ $this->_startRow = $startRow;
+ $this->_endRow = $endRow;
+ $this->_columns = $columns;
+ }
+
+ public function readCell($column, $row, $worksheetName = '') {
+ // Only read the rows and columns that were configured
+ if ($row >= $this->_startRow && $row <= $this->_endRow) {
+ if (in_array($column,$this->_columns)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+/** Create an Instance of our Read Filter, passing in the cell range **/
+$filterSubset = new MyReadFilter(9,15,range('G','K'));
+```
+ > See Examples/Reader/exampleReader10.php for a working example of this code.
+
+This can be particularly useful for conserving memory, by allowing you to read and process a large workbook in “chunks”: an example of this usage might be when transferring data from an Excel worksheet to a database.
+
+```php
+$inputFileType = 'Excel5';
+$inputFileName = './sampleData/example2.xls';
+
+
+/** Define a Read Filter class implementing PHPExcel_Reader_IReadFilter */
+class chunkReadFilter implements PHPExcel_Reader_IReadFilter
+{
+ private $_startRow = 0;
+ private $_endRow = 0;
+
+ /** Set the list of rows that we want to read */
+ public function setRows($startRow, $chunkSize) {
+ $this->_startRow = $startRow;
+ $this->_endRow = $startRow + $chunkSize;
+ }
+
+ public function readCell($column, $row, $worksheetName = '') {
+ // Only read the heading row, and the configured rows
+ if (($row == 1) || ($row >= $this->_startRow && $row < $this->_endRow)) {
+ return true;
+ }
+ return false;
+ }
+}
+
+
+/** Create a new Reader of the type defined in $inputFileType **/
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+
+
+/** Define how many rows we want to read for each "chunk" **/
+$chunkSize = 2048;
+/** Create a new Instance of our Read Filter **/
+$chunkFilter = new chunkReadFilter();
+
+/** Tell the Reader that we want to use the Read Filter **/
+$objReader->setReadFilter($chunkFilter);
+
+/** Loop to read our worksheet in "chunk size" blocks **/
+for ($startRow = 2; $startRow <= 65536; $startRow += $chunkSize) {
+ /** Tell the Read Filter which rows we want this iteration **/
+ $chunkFilter->setRows($startRow,$chunkSize);
+ /** Load only the rows that match our filter **/
+ $objPHPExcel = $objReader->load($inputFileName);
+ // Do some processing here
+}
+```
+ > See Examples/Reader/exampleReader12.php for a working example of this code.
+
+Using Read Filters applies to:
+
+Reader | Y/N |Reader | Y/N |Reader | Y/N |
+----------|:---:|--------|:---:|--------------|:---:|
+Excel2007 | YES | Excel5 | YES | Excel2003XML | YES |
+OOCalc | YES | SYLK | NO | Gnumeric | YES |
+CSV | YES | HTML | NO
+
+### Combining Multiple Files into a Single PHPExcel Object
+
+While you can limit the number of worksheets that are read from a workbook file using the setLoadSheetsOnly() method, certain readers also allow you to combine several individual "sheets" from different files into a single PHPExcel object, where each individual file is a single worksheet within that workbook. For each file that you read, you need to indicate which worksheet index it should be loaded into using the setSheetIndex() method of the $objReader, then use the loadIntoExisting() method rather than the load() method to actually read the file into that worksheet.
+
+```php
+$inputFileType = 'CSV';
+$inputFileNames = array('./sampleData/example1.csv',
+ './sampleData/example2.csv'
+ './sampleData/example3.csv'
+);
+
+/** Create a new Reader of the type defined in $inputFileType **/
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+
+
+/** Extract the first named file from the array list **/
+$inputFileName = array_shift($inputFileNames);
+/** Load the initial file to the first worksheet in a PHPExcel Object **/
+$objPHPExcel = $objReader->load($inputFileName);
+/** Set the worksheet title (to the filename that we've loaded) **/
+$objPHPExcel->getActiveSheet()
+ ->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME));
+
+
+/** Loop through all the remaining files in the list **/
+foreach($inputFileNames as $sheet => $inputFileName) {
+ /** Increment the worksheet index pointer for the Reader **/
+ $objReader->setSheetIndex($sheet+1);
+ /** Load the current file into a new worksheet in PHPExcel **/
+ $objReader->loadIntoExisting($inputFileName,$objPHPExcel);
+ /** Set the worksheet title (to the filename that we've loaded) **/
+ $objPHPExcel->getActiveSheet()
+ ->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME));
+}
+```
+ > See Examples/Reader/exampleReader13.php for a working example of this code.
+
+Note that using the same sheet index for multiple sheets won't append files into the same sheet, but overwrite the results of the previous load. You cannot load multiple CSV files into the same worksheet.
+
+Combining Multiple Files into a Single PHPExcel Object applies to:
+
+Reader | Y/N |Reader | Y/N |Reader | Y/N |
+----------|:---:|--------|:---:|--------------|:---:|
+Excel2007 | NO | Excel5 | NO | Excel2003XML | NO |
+OOCalc | NO | SYLK | YES | Gnumeric | NO |
+CSV | YES | HTML | NO
+
+### Combining Read Filters with the setSheetIndex() method to split a large CSV file across multiple Worksheets
+
+An Excel5 BIFF .xls file is limited to 65536 rows in a worksheet, while the Excel2007 Microsoft Office Open XML SpreadsheetML .xlsx file is limited to 1,048,576 rows in a worksheet; but a CSV file is not limited other than by available disk space. This means that we wouldn’t ordinarily be able to read all the rows from a very large CSV file that exceeded those limits, and save it as an Excel5 or Excel2007 file. However, by using Read Filters to read the CSV file in “chunks” (using the chunkReadFilter Class that we defined in section REF _Ref275604563 \r \p 5.3 above), and the setSheetIndex() method of the $objReader, we can split the CSV file across several individual worksheets.
+
+```php
+$inputFileType = 'CSV';
+$inputFileName = './sampleData/example2.csv';
+
+
+echo 'Loading file ',pathinfo($inputFileName,PATHINFO_BASENAME),' using IOFactory with a defined reader type of ',$inputFileType,'
';
+/** Create a new Reader of the type defined in $inputFileType **/
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+
+
+/** Define how many rows we want to read for each "chunk" **/
+$chunkSize = 65530;
+/** Create a new Instance of our Read Filter **/
+$chunkFilter = new chunkReadFilter();
+
+/** Tell the Reader that we want to use the Read Filter **/
+/** and that we want to store it in contiguous rows/columns **/
+
+$objReader->setReadFilter($chunkFilter)
+ ->setContiguous(true);
+
+/** Instantiate a new PHPExcel object manually **/
+$objPHPExcel = new PHPExcel();
+
+/** Set a sheet index **/
+$sheet = 0;
+/** Loop to read our worksheet in "chunk size" blocks **/
+/** $startRow is set to 2 initially because we always read the headings in row #1 **/
+for ($startRow = 2; $startRow <= 1000000; $startRow += $chunkSize) {
+ /** Tell the Read Filter which rows we want to read this loop **/
+ $chunkFilter->setRows($startRow,$chunkSize);
+
+ /** Increment the worksheet index pointer for the Reader **/
+ $objReader->setSheetIndex($sheet);
+ /** Load only the rows that match our filter into a new worksheet **/
+ $objReader->loadIntoExisting($inputFileName,$objPHPExcel);
+ /** Set the worksheet title for the sheet that we've justloaded) **/
+ /** and increment the sheet index as well **/
+ $objPHPExcel->getActiveSheet()->setTitle('Country Data #'.(++$sheet));
+}
+```
+ > See Examples/Reader/exampleReader14.php for a working example of this code.
+
+This code will read 65,530 rows at a time from the CSV file that we’re loading, and store each "chunk" in a new worksheet.
+
+The setContiguous() method for the Reader is important here. It is applicable only when working with a Read Filter, and identifies whether or not the cells should be stored by their position within the CSV file, or their position relative to the filter.
+
+For example, if the filter returned true for cells in the range B2:C3, then with setContiguous set to false (the default) these would be loaded as B2:C3 in the PHPExcel object; but with setContiguous set to true, they would be loaded as A1:B2.
+
+Splitting a single loaded file across multiple worksheets applies to:
+
+Reader | Y/N |Reader | Y/N |Reader | Y/N |
+----------|:---:|--------|:---:|--------------|:---:|
+Excel2007 | NO | Excel5 | NO | Excel2003XML | NO |
+OOCalc | NO | SYLK | NO | Gnumeric | NO |
+CSV | YES | HTML | NO
+
+### Pipe or Tab Separated Value Files
+
+The CSV loader defaults to loading a file where comma is used as the separator, but you can modify this to load tab- or pipe-separated value files using the setDelimiter() method.
+
+```php
+$inputFileType = 'CSV';
+$inputFileName = './sampleData/example1.tsv';
+
+/** Create a new Reader of the type defined in $inputFileType **/ $objReader = PHPExcel_IOFactory::createReader($inputFileType);
+/** Set the delimiter to a TAB character **/
+$objReader->setDelimiter("\t");
+// $objReader->setDelimiter('|');
+
+/** Load the file to a PHPExcel Object **/
+$objPHPExcel = $objReader->load($inputFileName);
+```
+ > See Examples/Reader/exampleReader15.php for a working example of this code.
+
+In addition to the delimiter, you can also use the following methods to set other attributes for the data load:
+
+setEnclosure() | default is "
+setLineEnding() | default is PHP_EOL
+setInputEncoding() | default is UTF-8
+
+Setting CSV delimiter applies to:
+
+Reader | Y/N |Reader | Y/N |Reader | Y/N |
+----------|:---:|--------|:---:|--------------|:---:|
+Excel2007 | NO | Excel5 | NO | Excel2003XML | NO |
+OOCalc | NO | SYLK | NO | Gnumeric | NO |
+CSV | YES | HTML | NO
+
+### A Brief Word about the Advanced Value Binder
+
+When loading data from a file that contains no formatting information, such as a CSV file, then data is read either as strings or numbers (float or integer). This means that PHPExcel does not automatically recognise dates/times (such as "16-Apr-2009" or "13:30"), booleans ("TRUE" or "FALSE"), percentages ("75%"), hyperlinks ("http://www.phpexcel.net"), etc as anything other than simple strings. However, you can apply additional processing that is executed against these values during the load process within a Value Binder.
+
+A Value Binder is a class that implement the PHPExcel_Cell_IValueBinder interface. It must contain a bindValue() method that accepts a PHPExcel_Cell and a value as arguments, and return a boolean true or false that indicates whether the workbook cell has been populated with the value or not. The Advanced Value Binder implements such a class: amongst other tests, it identifies a string comprising "TRUE" or "FALSE" (based on locale settings) and sets it to a boolean; or a number in scientific format (e.g. "1.234e-5") and converts it to a float; or dates and times, converting them to their Excel timestamp value – before storing the value in the cell object. It also sets formatting for strings that are identified as dates, times or percentages. It could easily be extended to provide additional handling (including text or cell formatting) when it encountered a hyperlink, or HTML markup within a CSV file.
+
+So using a Value Binder allows a great deal more flexibility in the loader logic when reading unformatted text files.
+
+```php
+/** Tell PHPExcel that we want to use the Advanced Value Binder **/
+PHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() );
+
+$inputFileType = 'CSV';
+$inputFileName = './sampleData/example1.tsv';
+
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+$objReader->setDelimiter("\t");
+$objPHPExcel = $objReader->load($inputFileName);
+```
+ > See Examples/Reader/exampleReader15.php for a working example of this code.
+
+Loading using a Value Binder applies to:
+
+Reader | Y/N |Reader | Y/N |Reader | Y/N |
+----------|:---:|--------|:---:|--------------|:---:|
+Excel2007 | NO | Excel5 | NO | Excel2003XML | NO |
+OOCalc | NO | SYLK | NO | Gnumeric | NO |
+CSV | YES | HTML | YES
+
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/06-Error-Handling.md b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/06-Error-Handling.md
new file mode 100755
index 000000000..d3e064f9b
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/06-Error-Handling.md
@@ -0,0 +1,20 @@
+# PHPExcel User Documentation – Reading Spreadsheet Files
+
+## Error Handling
+
+Of course, you should always apply some error handling to your scripts as well. PHPExcel throws exceptions, so you can wrap all your code that accesses the library methods within Try/Catch blocks to trap for any problems that are encountered, and deal with them in an appropriate manner.
+
+The PHPExcel Readers throw a PHPExcel_Reader_Exception.
+
+```php
+$inputFileName = './sampleData/example-1.xls';
+
+try {
+ /** Load $inputFileName to a PHPExcel Object **/
+ $objPHPExcel = PHPExcel_IOFactory::load($inputFileName);
+} catch(PHPExcel_Reader_Exception $e) {
+ die('Error loading file: '.$e->getMessage());
+}
+```
+ > See Examples/Reader/exampleReader16.php for a working example of this code.
+
diff --git a/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/07-Helper-Methods.md b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/07-Helper-Methods.md
new file mode 100755
index 000000000..57dbec7a7
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Documentation/markdown/ReadingSpreadsheetFiles/07-Helper-Methods.md
@@ -0,0 +1,47 @@
+# PHPExcel User Documentation – Reading Spreadsheet Files
+
+
+## Helper Methods
+
+You can retrieve a list of worksheet names contained in a file without loading the whole file by using the Reader’s `listWorksheetNames()` method; similarly, a `listWorksheetInfo()` method will retrieve the dimensions of worksheet in a file without needing to load and parse the whole file.
+
+### listWorksheetNames
+
+The `listWorksheetNames()` method returns a simple array listing each worksheet name within the workbook:
+
+```php
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+
+$worksheetNames = $objReader->listWorksheetNames($inputFileName);
+
+echo 'Worksheet Names
';
+echo '';
+foreach ($worksheetNames as $worksheetName) {
+ echo '
';
+```
+ > See Examples/Reader/exampleReader18.php for a working example of this code.
+
+### listWorksheetInfo
+
+The `listWorksheetInfo()` method returns a nested array, with each entry listing the name and dimensions for a worksheet:
+
+```php
+$objReader = PHPExcel_IOFactory::createReader($inputFileType);
+
+$worksheetData = $objReader->listWorksheetInfo($inputFileName);
+
+echo 'Worksheet Information
';
+echo '';
+foreach ($worksheetData as $worksheet) {
+ echo '
';
+```
+ > See Examples/Reader/exampleReader19.php for a working example of this code.
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/.gitignore b/Server/vendor/phpoffice/phpexcel/Examples/.gitignore
new file mode 100755
index 000000000..d53fd7fab
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/.gitignore
@@ -0,0 +1,5 @@
+*.xls
+*.xlsx
+*.csv
+*.jpg
+*.pdf
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/01pharSimple.php b/Server/vendor/phpoffice/phpexcel/Examples/01pharSimple.php
new file mode 100755
index 000000000..84b86cc5e
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/01pharSimple.php
@@ -0,0 +1,112 @@
+');
+
+/** Include PHPExcel */
+require_once '../Build/PHPExcel.phar';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("PHPExcel Test Document")
+ ->setSubject("PHPExcel Test Document")
+ ->setDescription("Test document for PHPExcel, generated using PHP classes.")
+ ->setKeywords("office PHPExcel php")
+ ->setCategory("Test result file");
+
+
+// Add some data
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0)
+ ->setCellValue('A1', 'Hello')
+ ->setCellValue('B2', 'world!')
+ ->setCellValue('C1', 'Hello')
+ ->setCellValue('D2', 'world!');
+
+// Miscellaneous glyphs, UTF-8
+$objPHPExcel->setActiveSheetIndex(0)
+ ->setCellValue('A4', 'Miscellaneous glyphs')
+ ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');
+
+// Rename worksheet
+echo date('H:i:s') , " Rename worksheet" , EOL;
+$objPHPExcel->getActiveSheet()->setTitle('Simple');
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Save Excel5 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing files" , EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/01simple-download-ods.php b/Server/vendor/phpoffice/phpexcel/Examples/01simple-download-ods.php
new file mode 100755
index 000000000..30dbd7e35
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/01simple-download-ods.php
@@ -0,0 +1,89 @@
+getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Add some data
+$objPHPExcel->setActiveSheetIndex(0)
+ ->setCellValue('A1', 'Hello')
+ ->setCellValue('B2', 'world!')
+ ->setCellValue('C1', 'Hello')
+ ->setCellValue('D2', 'world!');
+
+// Miscellaneous glyphs, UTF-8
+$objPHPExcel->setActiveSheetIndex(0)
+ ->setCellValue('A4', 'Miscellaneous glyphs')
+ ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');
+
+// Rename worksheet
+$objPHPExcel->getActiveSheet()->setTitle('Simple');
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Redirect output to a client’s web browser (OpenDocument)
+header('Content-Type: application/vnd.oasis.opendocument.spreadsheet');
+header('Content-Disposition: attachment;filename="01simple.ods"');
+header('Cache-Control: max-age=0');
+// If you're serving to IE 9, then the following may be needed
+header('Cache-Control: max-age=1');
+
+// If you're serving to IE over SSL, then the following may be needed
+header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
+header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
+header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
+header ('Pragma: public'); // HTTP/1.0
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'OpenDocument');
+$objWriter->save('php://output');
+exit;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/01simple-download-pdf.php b/Server/vendor/phpoffice/phpexcel/Examples/01simple-download-pdf.php
new file mode 100755
index 000000000..133af3a69
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/01simple-download-pdf.php
@@ -0,0 +1,104 @@
+getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("PDF Test Document")
+ ->setSubject("PDF Test Document")
+ ->setDescription("Test document for PDF, generated using PHP classes.")
+ ->setKeywords("pdf php")
+ ->setCategory("Test result file");
+
+
+// Add some data
+$objPHPExcel->setActiveSheetIndex(0)
+ ->setCellValue('A1', 'Hello')
+ ->setCellValue('B2', 'world!')
+ ->setCellValue('C1', 'Hello')
+ ->setCellValue('D2', 'world!');
+
+// Miscellaneous glyphs, UTF-8
+$objPHPExcel->setActiveSheetIndex(0)
+ ->setCellValue('A4', 'Miscellaneous glyphs')
+ ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');
+
+// Rename worksheet
+$objPHPExcel->getActiveSheet()->setTitle('Simple');
+$objPHPExcel->getActiveSheet()->setShowGridLines(false);
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+if (!PHPExcel_Settings::setPdfRenderer(
+ $rendererName,
+ $rendererLibraryPath
+ )) {
+ die(
+ 'NOTICE: Please set the $rendererName and $rendererLibraryPath values' .
+ '
';
+ echo 'Rows: ', $worksheet['totalRows'],
+ ' Columns: ', $worksheet['totalColumns'], '
';
+ echo 'Cell Range: A1:',
+ $worksheet['lastColumnLetter'], $worksheet['totalRows'];
+ echo '
' .
+ 'at the top of this script as appropriate for your directory structure'
+ );
+}
+
+
+// Redirect output to a client’s web browser (PDF)
+header('Content-Type: application/pdf');
+header('Content-Disposition: attachment;filename="01simple.pdf"');
+header('Cache-Control: max-age=0');
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'PDF');
+$objWriter->save('php://output');
+exit;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/01simple-download-xls.php b/Server/vendor/phpoffice/phpexcel/Examples/01simple-download-xls.php
new file mode 100755
index 000000000..96bb780b5
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/01simple-download-xls.php
@@ -0,0 +1,89 @@
+getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Add some data
+$objPHPExcel->setActiveSheetIndex(0)
+ ->setCellValue('A1', 'Hello')
+ ->setCellValue('B2', 'world!')
+ ->setCellValue('C1', 'Hello')
+ ->setCellValue('D2', 'world!');
+
+// Miscellaneous glyphs, UTF-8
+$objPHPExcel->setActiveSheetIndex(0)
+ ->setCellValue('A4', 'Miscellaneous glyphs')
+ ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');
+
+// Rename worksheet
+$objPHPExcel->getActiveSheet()->setTitle('Simple');
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Redirect output to a client’s web browser (Excel5)
+header('Content-Type: application/vnd.ms-excel');
+header('Content-Disposition: attachment;filename="01simple.xls"');
+header('Cache-Control: max-age=0');
+// If you're serving to IE 9, then the following may be needed
+header('Cache-Control: max-age=1');
+
+// If you're serving to IE over SSL, then the following may be needed
+header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
+header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
+header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
+header ('Pragma: public'); // HTTP/1.0
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save('php://output');
+exit;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/01simple-download-xlsx.php b/Server/vendor/phpoffice/phpexcel/Examples/01simple-download-xlsx.php
new file mode 100755
index 000000000..d441f4191
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/01simple-download-xlsx.php
@@ -0,0 +1,89 @@
+getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Add some data
+$objPHPExcel->setActiveSheetIndex(0)
+ ->setCellValue('A1', 'Hello')
+ ->setCellValue('B2', 'world!')
+ ->setCellValue('C1', 'Hello')
+ ->setCellValue('D2', 'world!');
+
+// Miscellaneous glyphs, UTF-8
+$objPHPExcel->setActiveSheetIndex(0)
+ ->setCellValue('A4', 'Miscellaneous glyphs')
+ ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');
+
+// Rename worksheet
+$objPHPExcel->getActiveSheet()->setTitle('Simple');
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Redirect output to a client’s web browser (Excel2007)
+header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
+header('Content-Disposition: attachment;filename="01simple.xlsx"');
+header('Cache-Control: max-age=0');
+// If you're serving to IE 9, then the following may be needed
+header('Cache-Control: max-age=1');
+
+// If you're serving to IE over SSL, then the following may be needed
+header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
+header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
+header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
+header ('Pragma: public'); // HTTP/1.0
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save('php://output');
+exit;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/01simple.php b/Server/vendor/phpoffice/phpexcel/Examples/01simple.php
new file mode 100755
index 000000000..13f802759
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/01simple.php
@@ -0,0 +1,125 @@
+');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("PHPExcel Test Document")
+ ->setSubject("PHPExcel Test Document")
+ ->setDescription("Test document for PHPExcel, generated using PHP classes.")
+ ->setKeywords("office PHPExcel php")
+ ->setCategory("Test result file");
+
+
+// Add some data
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0)
+ ->setCellValue('A1', 'Hello')
+ ->setCellValue('B2', 'world!')
+ ->setCellValue('C1', 'Hello')
+ ->setCellValue('D2', 'world!');
+
+// Miscellaneous glyphs, UTF-8
+$objPHPExcel->setActiveSheetIndex(0)
+ ->setCellValue('A4', 'Miscellaneous glyphs')
+ ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');
+
+
+$objPHPExcel->getActiveSheet()->setCellValue('A8',"Hello\nWorld");
+$objPHPExcel->getActiveSheet()->getRowDimension(8)->setRowHeight(-1);
+$objPHPExcel->getActiveSheet()->getStyle('A8')->getAlignment()->setWrapText(true);
+
+
+$value = "-ValueA\n-Value B\n-Value C";
+$objPHPExcel->getActiveSheet()->setCellValue('A10', $value);
+$objPHPExcel->getActiveSheet()->getRowDimension(10)->setRowHeight(-1);
+$objPHPExcel->getActiveSheet()->getStyle('A10')->getAlignment()->setWrapText(true);
+$objPHPExcel->getActiveSheet()->getStyle('A10')->setQuotePrefix(true);
+
+
+
+// Rename worksheet
+echo date('H:i:s') , " Rename worksheet" , EOL;
+$objPHPExcel->getActiveSheet()->setTitle('Simple');
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Save Excel 95 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing files" , EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/01simplePCLZip.php b/Server/vendor/phpoffice/phpexcel/Examples/01simplePCLZip.php
new file mode 100755
index 000000000..0af4cbdd8
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/01simplePCLZip.php
@@ -0,0 +1,106 @@
+');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("PHPExcel Test Document")
+ ->setSubject("PHPExcel Test Document")
+ ->setDescription("Test document for PHPExcel, generated using PHP classes.")
+ ->setKeywords("office PHPExcel php")
+ ->setCategory("Test result file");
+
+
+// Add some data
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0)
+ ->setCellValue('A1', 'Hello')
+ ->setCellValue('B2', 'world!')
+ ->setCellValue('C1', 'Hello')
+ ->setCellValue('D2', 'world!');
+
+// Miscellaneous glyphs, UTF-8
+$objPHPExcel->setActiveSheetIndex(0)
+ ->setCellValue('A4', 'Miscellaneous glyphs')
+ ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');
+
+
+$objPHPExcel->getActiveSheet()->setCellValue('A8',"Hello\nWorld");
+$objPHPExcel->getActiveSheet()->getRowDimension(8)->setRowHeight(-1);
+$objPHPExcel->getActiveSheet()->getStyle('A8')->getAlignment()->setWrapText(true);
+
+
+// Rename worksheet
+echo date('H:i:s') , " Rename worksheet" , EOL;
+$objPHPExcel->getActiveSheet()->setTitle('Simple');
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+// Use PCLZip rather than ZipArchive to create the Excel2007 OfficeOpenXML file
+PHPExcel_Settings::setZipClass(PHPExcel_Settings::PCLZIP);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing files" , EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/02types-xls.php b/Server/vendor/phpoffice/phpexcel/Examples/02types-xls.php
new file mode 100755
index 000000000..93ce17e59
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/02types-xls.php
@@ -0,0 +1,183 @@
+');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+// Set default font
+echo date('H:i:s') , " Set default font" , EOL;
+$objPHPExcel->getDefaultStyle()->getFont()->setName('Arial')
+ ->setSize(10);
+
+// Add some data, resembling some different data types
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->getActiveSheet()->setCellValue('A1', 'String')
+ ->setCellValue('B1', 'Simple')
+ ->setCellValue('C1', 'PHPExcel');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A2', 'String')
+ ->setCellValue('B2', 'Symbols')
+ ->setCellValue('C2', '!+&=()~§±æþ');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A3', 'String')
+ ->setCellValue('B3', 'UTF-8')
+ ->setCellValue('C3', 'Создать MS Excel Книги из PHP скриптов');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Number')
+ ->setCellValue('B4', 'Integer')
+ ->setCellValue('C4', 12);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Number')
+ ->setCellValue('B5', 'Float')
+ ->setCellValue('C5', 34.56);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A6', 'Number')
+ ->setCellValue('B6', 'Negative')
+ ->setCellValue('C6', -7.89);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A7', 'Boolean')
+ ->setCellValue('B7', 'True')
+ ->setCellValue('C7', true);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A8', 'Boolean')
+ ->setCellValue('B8', 'False')
+ ->setCellValue('C8', false);
+
+$dateTimeNow = time();
+$objPHPExcel->getActiveSheet()->setCellValue('A9', 'Date/Time')
+ ->setCellValue('B9', 'Date')
+ ->setCellValue('C9', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow ));
+$objPHPExcel->getActiveSheet()->getStyle('C9')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A10', 'Date/Time')
+ ->setCellValue('B10', 'Time')
+ ->setCellValue('C10', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow ));
+$objPHPExcel->getActiveSheet()->getStyle('C10')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A11', 'Date/Time')
+ ->setCellValue('B11', 'Date and Time')
+ ->setCellValue('C11', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow ));
+$objPHPExcel->getActiveSheet()->getStyle('C11')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_DATETIME);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A12', 'NULL')
+ ->setCellValue('C12', NULL);
+
+$objRichText = new PHPExcel_RichText();
+$objRichText->createText('你好 ');
+$objPayable = $objRichText->createTextRun('你 好 吗?');
+$objPayable->getFont()->setBold(true);
+$objPayable->getFont()->setItalic(true);
+$objPayable->getFont()->setColor( new PHPExcel_Style_Color( PHPExcel_Style_Color::COLOR_DARKGREEN ) );
+
+$objRichText->createText(', unless specified otherwise on the invoice.');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A13', 'Rich Text')
+ ->setCellValue('C13', $objRichText);
+
+
+$objRichText2 = new PHPExcel_RichText();
+$objRichText2->createText("black text\n");
+
+$objRed = $objRichText2->createTextRun("red text");
+$objRed->getFont()->setColor( new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_RED ) );
+
+$objPHPExcel->getActiveSheet()->getCell("C14")->setValue($objRichText2);
+$objPHPExcel->getActiveSheet()->getStyle("C14")->getAlignment()->setWrapText(true);
+
+
+$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true);
+$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setAutoSize(true);
+
+// Rename worksheet
+echo date('H:i:s') , " Rename worksheet" , EOL;
+$objPHPExcel->getActiveSheet()->setTitle('Datatypes');
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 95 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+echo date('H:i:s') , " Reload workbook from saved file" , EOL;
+$callStartTime = microtime(true);
+
+$objPHPExcel = PHPExcel_IOFactory::load(str_replace('.php', '.xls', __FILE__));
+
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+echo 'Call time to reload Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+var_dump($objPHPExcel->getActiveSheet()->toArray());
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done testing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/02types.php b/Server/vendor/phpoffice/phpexcel/Examples/02types.php
new file mode 100755
index 000000000..394a73dd4
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/02types.php
@@ -0,0 +1,204 @@
+');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+// Set default font
+echo date('H:i:s') , " Set default font" , EOL;
+$objPHPExcel->getDefaultStyle()->getFont()->setName('Arial')
+ ->setSize(10);
+
+// Add some data, resembling some different data types
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->getActiveSheet()->setCellValue('A1', 'String')
+ ->setCellValue('B1', 'Simple')
+ ->setCellValue('C1', 'PHPExcel');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A2', 'String')
+ ->setCellValue('B2', 'Symbols')
+ ->setCellValue('C2', '!+&=()~§±æþ');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A3', 'String')
+ ->setCellValue('B3', 'UTF-8')
+ ->setCellValue('C3', 'Создать MS Excel Книги из PHP скриптов');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Number')
+ ->setCellValue('B4', 'Integer')
+ ->setCellValue('C4', 12);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Number')
+ ->setCellValue('B5', 'Float')
+ ->setCellValue('C5', 34.56);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A6', 'Number')
+ ->setCellValue('B6', 'Negative')
+ ->setCellValue('C6', -7.89);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A7', 'Boolean')
+ ->setCellValue('B7', 'True')
+ ->setCellValue('C7', true);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A8', 'Boolean')
+ ->setCellValue('B8', 'False')
+ ->setCellValue('C8', false);
+
+$dateTimeNow = time();
+$objPHPExcel->getActiveSheet()->setCellValue('A9', 'Date/Time')
+ ->setCellValue('B9', 'Date')
+ ->setCellValue('C9', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow ));
+$objPHPExcel->getActiveSheet()->getStyle('C9')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A10', 'Date/Time')
+ ->setCellValue('B10', 'Time')
+ ->setCellValue('C10', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow ));
+$objPHPExcel->getActiveSheet()->getStyle('C10')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A11', 'Date/Time')
+ ->setCellValue('B11', 'Date and Time')
+ ->setCellValue('C11', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow ));
+$objPHPExcel->getActiveSheet()->getStyle('C11')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_DATETIME);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A12', 'NULL')
+ ->setCellValue('C12', NULL);
+
+$objRichText = new PHPExcel_RichText();
+$objRichText->createText('你好 ');
+
+$objPayable = $objRichText->createTextRun('你 好 吗?');
+$objPayable->getFont()->setBold(true);
+$objPayable->getFont()->setItalic(true);
+$objPayable->getFont()->setColor( new PHPExcel_Style_Color( PHPExcel_Style_Color::COLOR_DARKGREEN ) );
+
+$objRichText->createText(', unless specified otherwise on the invoice.');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A13', 'Rich Text')
+ ->setCellValue('C13', $objRichText);
+
+
+$objRichText2 = new PHPExcel_RichText();
+$objRichText2->createText("black text\n");
+
+$objRed = $objRichText2->createTextRun("red text");
+$objRed->getFont()->setColor( new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_RED ) );
+
+$objPHPExcel->getActiveSheet()->getCell("C14")->setValue($objRichText2);
+$objPHPExcel->getActiveSheet()->getStyle("C14")->getAlignment()->setWrapText(true);
+
+
+$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true);
+$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setAutoSize(true);
+
+$objRichText3 = new PHPExcel_RichText();
+$objRichText3->createText("Hello ");
+
+$objUnderlined = $objRichText3->createTextRun("underlined");
+$objUnderlined->getFont()->setUnderline(true);
+$objRichText3->createText(' World.');
+
+$objPHPExcel->getActiveSheet()
+ ->getCell("C15")
+ ->setValue($objRichText3);
+
+
+$objPHPExcel->getActiveSheet()->setCellValue('A17', 'Hyperlink');
+
+$objPHPExcel->getActiveSheet()->setCellValue('C17', 'www.phpexcel.net');
+$objPHPExcel->getActiveSheet()->getCell('C17')->getHyperlink()->setUrl('http://www.phpexcel.net');
+$objPHPExcel->getActiveSheet()->getCell('C17')->getHyperlink()->setTooltip('Navigate to website');
+
+$objPHPExcel->getActiveSheet()->setCellValue('C18', '=HYPERLINK("mailto:abc@def.com","abc@def.com")');
+
+
+// Rename worksheet
+echo date('H:i:s') , " Rename worksheet" , EOL;
+$objPHPExcel->getActiveSheet()->setTitle('Datatypes');
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+echo date('H:i:s') , " Reload workbook from saved file" , EOL;
+$callStartTime = microtime(true);
+
+$objPHPExcel = PHPExcel_IOFactory::load(str_replace('.php', '.xlsx', __FILE__));
+
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+echo 'Call time to reload Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+var_dump($objPHPExcel->getActiveSheet()->toArray());
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done testing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/03formulas.php b/Server/vendor/phpoffice/phpexcel/Examples/03formulas.php
new file mode 100755
index 000000000..6c5d1ddc9
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/03formulas.php
@@ -0,0 +1,149 @@
+');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Add some data, we will use some formulas here
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Sum:');
+
+$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Range #1')
+ ->setCellValue('B2', 3)
+ ->setCellValue('B3', 7)
+ ->setCellValue('B4', 13)
+ ->setCellValue('B5', '=SUM(B2:B4)');
+echo date('H:i:s') , " Sum of Range #1 is " ,
+ $objPHPExcel->getActiveSheet()->getCell('B5')->getCalculatedValue() , EOL;
+
+$objPHPExcel->getActiveSheet()->setCellValue('C1', 'Range #2')
+ ->setCellValue('C2', 5)
+ ->setCellValue('C3', 11)
+ ->setCellValue('C4', 17)
+ ->setCellValue('C5', '=SUM(C2:C4)');
+echo date('H:i:s') , " Sum of Range #2 is " ,
+ $objPHPExcel->getActiveSheet()->getCell('C5')->getCalculatedValue() , EOL;
+
+$objPHPExcel->getActiveSheet()->setCellValue('A7', 'Total of both ranges:');
+$objPHPExcel->getActiveSheet()->setCellValue('B7', '=SUM(B5:C5)');
+echo date('H:i:s') , " Sum of both Ranges is " ,
+ $objPHPExcel->getActiveSheet()->getCell('B7')->getCalculatedValue() , EOL;
+
+$objPHPExcel->getActiveSheet()->setCellValue('A8', 'Minimum of both ranges:');
+$objPHPExcel->getActiveSheet()->setCellValue('B8', '=MIN(B2:C4)');
+echo date('H:i:s') , " Minimum value in either Range is " ,
+ $objPHPExcel->getActiveSheet()->getCell('B8')->getCalculatedValue() , EOL;
+
+$objPHPExcel->getActiveSheet()->setCellValue('A9', 'Maximum of both ranges:');
+$objPHPExcel->getActiveSheet()->setCellValue('B9', '=MAX(B2:C4)');
+echo date('H:i:s') , " Maximum value in either Range is " ,
+ $objPHPExcel->getActiveSheet()->getCell('B9')->getCalculatedValue() , EOL;
+
+$objPHPExcel->getActiveSheet()->setCellValue('A10', 'Average of both ranges:');
+$objPHPExcel->getActiveSheet()->setCellValue('B10', '=AVERAGE(B2:C4)');
+echo date('H:i:s') , " Average value of both Ranges is " ,
+ $objPHPExcel->getActiveSheet()->getCell('B10')->getCalculatedValue() , EOL;
+
+
+// Rename worksheet
+echo date('H:i:s') , " Rename worksheet" , EOL;
+$objPHPExcel->getActiveSheet()->setTitle('Formulas');
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+
+//
+// If we set Pre Calculated Formulas to true then PHPExcel will calculate all formulae in the
+// workbook before saving. This adds time and memory overhead, and can cause some problems with formulae
+// using functions or features (such as array formulae) that aren't yet supported by the calculation engine
+// If the value is false (the default) for the Excel2007 Writer, then MS Excel (or the application used to
+// open the file) will need to recalculate values itself to guarantee that the correct results are available.
+//
+//$objWriter->setPreCalculateFormulas(true);
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Save Excel 95 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing files" , EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/04printing.php b/Server/vendor/phpoffice/phpexcel/Examples/04printing.php
new file mode 100755
index 000000000..58d5f6a8e
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/04printing.php
@@ -0,0 +1,125 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Add some data, we will use printing features
+echo date('H:i:s') , " Add some data" , EOL;
+for ($i = 1; $i < 200; $i++) {
+ $objPHPExcel->getActiveSheet()->setCellValue('A' . $i, $i);
+ $objPHPExcel->getActiveSheet()->setCellValue('B' . $i, 'Test value');
+}
+
+// Set header and footer. When no different headers for odd/even are used, odd header is assumed.
+echo date('H:i:s') , " Set header/footer" , EOL;
+$objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddHeader('&L&G&C&HPlease treat this document as confidential!');
+$objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddFooter('&L&B' . $objPHPExcel->getProperties()->getTitle() . '&RPage &P of &N');
+
+// Add a drawing to the header
+echo date('H:i:s') , " Add a drawing to the header" , EOL;
+$objDrawing = new PHPExcel_Worksheet_HeaderFooterDrawing();
+$objDrawing->setName('PHPExcel logo');
+$objDrawing->setPath('./images/phpexcel_logo.gif');
+$objDrawing->setHeight(36);
+$objPHPExcel->getActiveSheet()->getHeaderFooter()->addImage($objDrawing, PHPExcel_Worksheet_HeaderFooter::IMAGE_HEADER_LEFT);
+
+// Set page orientation and size
+echo date('H:i:s') , " Set page orientation and size" , EOL;
+$objPHPExcel->getActiveSheet()->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE);
+$objPHPExcel->getActiveSheet()->getPageSetup()->setPaperSize(PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4);
+
+// Rename worksheet
+echo date('H:i:s') , " Rename worksheet" , EOL;
+$objPHPExcel->getActiveSheet()->setTitle('Printing');
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Save Excel 95 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing files" , EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/05featuredemo.inc.php b/Server/vendor/phpoffice/phpexcel/Examples/05featuredemo.inc.php
new file mode 100755
index 000000000..003379cce
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/05featuredemo.inc.php
@@ -0,0 +1,394 @@
+getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Create a first sheet, representing sales data
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Invoice');
+$objPHPExcel->getActiveSheet()->setCellValue('D1', PHPExcel_Shared_Date::PHPToExcel( gmmktime(0,0,0,date('m'),date('d'),date('Y')) ));
+$objPHPExcel->getActiveSheet()->getStyle('D1')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15);
+$objPHPExcel->getActiveSheet()->setCellValue('E1', '#12566');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A3', 'Product Id');
+$objPHPExcel->getActiveSheet()->setCellValue('B3', 'Description');
+$objPHPExcel->getActiveSheet()->setCellValue('C3', 'Price');
+$objPHPExcel->getActiveSheet()->setCellValue('D3', 'Amount');
+$objPHPExcel->getActiveSheet()->setCellValue('E3', 'Total');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A4', '1001');
+$objPHPExcel->getActiveSheet()->setCellValue('B4', 'PHP for dummies');
+$objPHPExcel->getActiveSheet()->setCellValue('C4', '20');
+$objPHPExcel->getActiveSheet()->setCellValue('D4', '1');
+$objPHPExcel->getActiveSheet()->setCellValue('E4', '=IF(D4<>"",C4*D4,"")');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A5', '1012');
+$objPHPExcel->getActiveSheet()->setCellValue('B5', 'OpenXML for dummies');
+$objPHPExcel->getActiveSheet()->setCellValue('C5', '22');
+$objPHPExcel->getActiveSheet()->setCellValue('D5', '2');
+$objPHPExcel->getActiveSheet()->setCellValue('E5', '=IF(D5<>"",C5*D5,"")');
+
+$objPHPExcel->getActiveSheet()->setCellValue('E6', '=IF(D6<>"",C6*D6,"")');
+$objPHPExcel->getActiveSheet()->setCellValue('E7', '=IF(D7<>"",C7*D7,"")');
+$objPHPExcel->getActiveSheet()->setCellValue('E8', '=IF(D8<>"",C8*D8,"")');
+$objPHPExcel->getActiveSheet()->setCellValue('E9', '=IF(D9<>"",C9*D9,"")');
+
+$objPHPExcel->getActiveSheet()->setCellValue('D11', 'Total excl.:');
+$objPHPExcel->getActiveSheet()->setCellValue('E11', '=SUM(E4:E9)');
+
+$objPHPExcel->getActiveSheet()->setCellValue('D12', 'VAT:');
+$objPHPExcel->getActiveSheet()->setCellValue('E12', '=E11*0.21');
+
+$objPHPExcel->getActiveSheet()->setCellValue('D13', 'Total incl.:');
+$objPHPExcel->getActiveSheet()->setCellValue('E13', '=E11+E12');
+
+// Add comment
+echo date('H:i:s') , " Add comments" , EOL;
+
+$objPHPExcel->getActiveSheet()->getComment('E11')->setAuthor('PHPExcel');
+$objCommentRichText = $objPHPExcel->getActiveSheet()->getComment('E11')->getText()->createTextRun('PHPExcel:');
+$objCommentRichText->getFont()->setBold(true);
+$objPHPExcel->getActiveSheet()->getComment('E11')->getText()->createTextRun("\r\n");
+$objPHPExcel->getActiveSheet()->getComment('E11')->getText()->createTextRun('Total amount on the current invoice, excluding VAT.');
+
+$objPHPExcel->getActiveSheet()->getComment('E12')->setAuthor('PHPExcel');
+$objCommentRichText = $objPHPExcel->getActiveSheet()->getComment('E12')->getText()->createTextRun('PHPExcel:');
+$objCommentRichText->getFont()->setBold(true);
+$objPHPExcel->getActiveSheet()->getComment('E12')->getText()->createTextRun("\r\n");
+$objPHPExcel->getActiveSheet()->getComment('E12')->getText()->createTextRun('Total amount of VAT on the current invoice.');
+
+$objPHPExcel->getActiveSheet()->getComment('E13')->setAuthor('PHPExcel');
+$objCommentRichText = $objPHPExcel->getActiveSheet()->getComment('E13')->getText()->createTextRun('PHPExcel:');
+$objCommentRichText->getFont()->setBold(true);
+$objPHPExcel->getActiveSheet()->getComment('E13')->getText()->createTextRun("\r\n");
+$objPHPExcel->getActiveSheet()->getComment('E13')->getText()->createTextRun('Total amount on the current invoice, including VAT.');
+$objPHPExcel->getActiveSheet()->getComment('E13')->setWidth('100pt');
+$objPHPExcel->getActiveSheet()->getComment('E13')->setHeight('100pt');
+$objPHPExcel->getActiveSheet()->getComment('E13')->setMarginLeft('150pt');
+$objPHPExcel->getActiveSheet()->getComment('E13')->getFillColor()->setRGB('EEEEEE');
+
+
+// Add rich-text string
+echo date('H:i:s') , " Add rich-text string" , EOL;
+$objRichText = new PHPExcel_RichText();
+$objRichText->createText('This invoice is ');
+
+$objPayable = $objRichText->createTextRun('payable within thirty days after the end of the month');
+$objPayable->getFont()->setBold(true);
+$objPayable->getFont()->setItalic(true);
+$objPayable->getFont()->setColor( new PHPExcel_Style_Color( PHPExcel_Style_Color::COLOR_DARKGREEN ) );
+
+$objRichText->createText(', unless specified otherwise on the invoice.');
+
+$objPHPExcel->getActiveSheet()->getCell('A18')->setValue($objRichText);
+
+// Merge cells
+echo date('H:i:s') , " Merge cells" , EOL;
+$objPHPExcel->getActiveSheet()->mergeCells('A18:E22');
+$objPHPExcel->getActiveSheet()->mergeCells('A28:B28'); // Just to test...
+$objPHPExcel->getActiveSheet()->unmergeCells('A28:B28'); // Just to test...
+
+// Protect cells
+echo date('H:i:s') , " Protect cells" , EOL;
+$objPHPExcel->getActiveSheet()->getProtection()->setSheet(true); // Needs to be set to true in order to enable any worksheet protection!
+$objPHPExcel->getActiveSheet()->protectCells('A3:E13', 'PHPExcel');
+
+// Set cell number formats
+echo date('H:i:s') , " Set cell number formats" , EOL;
+$objPHPExcel->getActiveSheet()->getStyle('E4:E13')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE);
+
+// Set column widths
+echo date('H:i:s') , " Set column widths" , EOL;
+$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true);
+$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(12);
+$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(12);
+
+// Set fonts
+echo date('H:i:s') , " Set fonts" , EOL;
+$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setName('Candara');
+$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setSize(20);
+$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setBold(true);
+$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE);
+$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_WHITE);
+
+$objPHPExcel->getActiveSheet()->getStyle('D1')->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_WHITE);
+$objPHPExcel->getActiveSheet()->getStyle('E1')->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_WHITE);
+
+$objPHPExcel->getActiveSheet()->getStyle('D13')->getFont()->setBold(true);
+$objPHPExcel->getActiveSheet()->getStyle('E13')->getFont()->setBold(true);
+
+// Set alignments
+echo date('H:i:s') , " Set alignments" , EOL;
+$objPHPExcel->getActiveSheet()->getStyle('D11')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
+$objPHPExcel->getActiveSheet()->getStyle('D12')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
+$objPHPExcel->getActiveSheet()->getStyle('D13')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
+
+$objPHPExcel->getActiveSheet()->getStyle('A18')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY);
+$objPHPExcel->getActiveSheet()->getStyle('A18')->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);
+
+$objPHPExcel->getActiveSheet()->getStyle('B5')->getAlignment()->setShrinkToFit(true);
+
+// Set thin black border outline around column
+echo date('H:i:s') , " Set thin black border outline around column" , EOL;
+$styleThinBlackBorderOutline = array(
+ 'borders' => array(
+ 'outline' => array(
+ 'style' => PHPExcel_Style_Border::BORDER_THIN,
+ 'color' => array('argb' => 'FF000000'),
+ ),
+ ),
+);
+$objPHPExcel->getActiveSheet()->getStyle('A4:E10')->applyFromArray($styleThinBlackBorderOutline);
+
+
+// Set thick brown border outline around "Total"
+echo date('H:i:s') , " Set thick brown border outline around Total" , EOL;
+$styleThickBrownBorderOutline = array(
+ 'borders' => array(
+ 'outline' => array(
+ 'style' => PHPExcel_Style_Border::BORDER_THICK,
+ 'color' => array('argb' => 'FF993300'),
+ ),
+ ),
+);
+$objPHPExcel->getActiveSheet()->getStyle('D13:E13')->applyFromArray($styleThickBrownBorderOutline);
+
+// Set fills
+echo date('H:i:s') , " Set fills" , EOL;
+$objPHPExcel->getActiveSheet()->getStyle('A1:E1')->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
+$objPHPExcel->getActiveSheet()->getStyle('A1:E1')->getFill()->getStartColor()->setARGB('FF808080');
+
+// Set style for header row using alternative method
+echo date('H:i:s') , " Set style for header row using alternative method" , EOL;
+$objPHPExcel->getActiveSheet()->getStyle('A3:E3')->applyFromArray(
+ array(
+ 'font' => array(
+ 'bold' => true
+ ),
+ 'alignment' => array(
+ 'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_RIGHT,
+ ),
+ 'borders' => array(
+ 'top' => array(
+ 'style' => PHPExcel_Style_Border::BORDER_THIN
+ )
+ ),
+ 'fill' => array(
+ 'type' => PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR,
+ 'rotation' => 90,
+ 'startcolor' => array(
+ 'argb' => 'FFA0A0A0'
+ ),
+ 'endcolor' => array(
+ 'argb' => 'FFFFFFFF'
+ )
+ )
+ )
+);
+
+$objPHPExcel->getActiveSheet()->getStyle('A3')->applyFromArray(
+ array(
+ 'alignment' => array(
+ 'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_LEFT,
+ ),
+ 'borders' => array(
+ 'left' => array(
+ 'style' => PHPExcel_Style_Border::BORDER_THIN
+ )
+ )
+ )
+);
+
+$objPHPExcel->getActiveSheet()->getStyle('B3')->applyFromArray(
+ array(
+ 'alignment' => array(
+ 'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_LEFT,
+ )
+ )
+);
+
+$objPHPExcel->getActiveSheet()->getStyle('E3')->applyFromArray(
+ array(
+ 'borders' => array(
+ 'right' => array(
+ 'style' => PHPExcel_Style_Border::BORDER_THIN
+ )
+ )
+ )
+);
+
+// Unprotect a cell
+echo date('H:i:s') , " Unprotect a cell" , EOL;
+$objPHPExcel->getActiveSheet()->getStyle('B1')->getProtection()->setLocked(PHPExcel_Style_Protection::PROTECTION_UNPROTECTED);
+
+// Add a hyperlink to the sheet
+echo date('H:i:s') , " Add a hyperlink to an external website" , EOL;
+$objPHPExcel->getActiveSheet()->setCellValue('E26', 'www.phpexcel.net');
+$objPHPExcel->getActiveSheet()->getCell('E26')->getHyperlink()->setUrl('http://www.phpexcel.net');
+$objPHPExcel->getActiveSheet()->getCell('E26')->getHyperlink()->setTooltip('Navigate to website');
+$objPHPExcel->getActiveSheet()->getStyle('E26')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
+
+echo date('H:i:s') , " Add a hyperlink to another cell on a different worksheet within the workbook" , EOL;
+$objPHPExcel->getActiveSheet()->setCellValue('E27', 'Terms and conditions');
+$objPHPExcel->getActiveSheet()->getCell('E27')->getHyperlink()->setUrl("sheet://'Terms and conditions'!A1");
+$objPHPExcel->getActiveSheet()->getCell('E27')->getHyperlink()->setTooltip('Review terms and conditions');
+$objPHPExcel->getActiveSheet()->getStyle('E27')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
+
+// Add a drawing to the worksheet
+echo date('H:i:s') , " Add a drawing to the worksheet" , EOL;
+$objDrawing = new PHPExcel_Worksheet_Drawing();
+$objDrawing->setName('Logo');
+$objDrawing->setDescription('Logo');
+$objDrawing->setPath('./images/officelogo.jpg');
+$objDrawing->setHeight(36);
+$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());
+
+// Add a drawing to the worksheet
+echo date('H:i:s') , " Add a drawing to the worksheet" , EOL;
+$objDrawing = new PHPExcel_Worksheet_Drawing();
+$objDrawing->setName('Paid');
+$objDrawing->setDescription('Paid');
+$objDrawing->setPath('./images/paid.png');
+$objDrawing->setCoordinates('B15');
+$objDrawing->setOffsetX(110);
+$objDrawing->setRotation(25);
+$objDrawing->getShadow()->setVisible(true);
+$objDrawing->getShadow()->setDirection(45);
+$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());
+
+// Add a drawing to the worksheet
+echo date('H:i:s') , " Add a drawing to the worksheet" , EOL;
+$objDrawing = new PHPExcel_Worksheet_Drawing();
+$objDrawing->setName('PHPExcel logo');
+$objDrawing->setDescription('PHPExcel logo');
+$objDrawing->setPath('./images/phpexcel_logo.gif');
+$objDrawing->setHeight(36);
+$objDrawing->setCoordinates('D24');
+$objDrawing->setOffsetX(10);
+$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());
+
+// Play around with inserting and removing rows and columns
+echo date('H:i:s') , " Play around with inserting and removing rows and columns" , EOL;
+$objPHPExcel->getActiveSheet()->insertNewRowBefore(6, 10);
+$objPHPExcel->getActiveSheet()->removeRow(6, 10);
+$objPHPExcel->getActiveSheet()->insertNewColumnBefore('E', 5);
+$objPHPExcel->getActiveSheet()->removeColumn('E', 5);
+
+// Set header and footer. When no different headers for odd/even are used, odd header is assumed.
+echo date('H:i:s') , " Set header/footer" , EOL;
+$objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddHeader('&L&BInvoice&RPrinted on &D');
+$objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddFooter('&L&B' . $objPHPExcel->getProperties()->getTitle() . '&RPage &P of &N');
+
+// Set page orientation and size
+echo date('H:i:s') , " Set page orientation and size" , EOL;
+$objPHPExcel->getActiveSheet()->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT);
+$objPHPExcel->getActiveSheet()->getPageSetup()->setPaperSize(PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4);
+
+// Rename first worksheet
+echo date('H:i:s') , " Rename first worksheet" , EOL;
+$objPHPExcel->getActiveSheet()->setTitle('Invoice');
+
+
+// Create a new worksheet, after the default sheet
+echo date('H:i:s') , " Create a second Worksheet object" , EOL;
+$objPHPExcel->createSheet();
+
+// Llorem ipsum...
+$sLloremIpsum = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus eget ante. Sed cursus nunc semper tortor. Aliquam luctus purus non elit. Fusce vel elit commodo sapien dignissim dignissim. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur accumsan magna sed massa. Nullam bibendum quam ac ipsum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin augue. Praesent malesuada justo sed orci. Pellentesque lacus ligula, sodales quis, ultricies a, ultricies vitae, elit. Sed luctus consectetuer dolor. Vivamus vel sem ut nisi sodales accumsan. Nunc et felis. Suspendisse semper viverra odio. Morbi at odio. Integer a orci a purus venenatis molestie. Nam mattis. Praesent rhoncus, nisi vel mattis auctor, neque nisi faucibus sem, non dapibus elit pede ac nisl. Cras turpis.';
+
+// Add some data to the second sheet, resembling some different data types
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->setActiveSheetIndex(1);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Terms and conditions');
+$objPHPExcel->getActiveSheet()->setCellValue('A3', $sLloremIpsum);
+$objPHPExcel->getActiveSheet()->setCellValue('A4', $sLloremIpsum);
+$objPHPExcel->getActiveSheet()->setCellValue('A5', $sLloremIpsum);
+$objPHPExcel->getActiveSheet()->setCellValue('A6', $sLloremIpsum);
+
+// Set the worksheet tab color
+echo date('H:i:s') , " Set the worksheet tab color" , EOL;
+$objPHPExcel->getActiveSheet()->getTabColor()->setARGB('FF0094FF');;
+
+// Set alignments
+echo date('H:i:s') , " Set alignments" , EOL;
+$objPHPExcel->getActiveSheet()->getStyle('A3:A6')->getAlignment()->setWrapText(true);
+
+// Set column widths
+echo date('H:i:s') , " Set column widths" , EOL;
+$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(80);
+
+// Set fonts
+echo date('H:i:s') , " Set fonts" , EOL;
+$objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setName('Candara');
+$objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setSize(20);
+$objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setBold(true);
+$objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE);
+
+$objPHPExcel->getActiveSheet()->getStyle('A3:A6')->getFont()->setSize(8);
+
+// Add a drawing to the worksheet
+echo date('H:i:s') , " Add a drawing to the worksheet" , EOL;
+$objDrawing = new PHPExcel_Worksheet_Drawing();
+$objDrawing->setName('Terms and conditions');
+$objDrawing->setDescription('Terms and conditions');
+$objDrawing->setPath('./images/termsconditions.jpg');
+$objDrawing->setCoordinates('B14');
+$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());
+
+// Set page orientation and size
+echo date('H:i:s') , " Set page orientation and size" , EOL;
+$objPHPExcel->getActiveSheet()->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE);
+$objPHPExcel->getActiveSheet()->getPageSetup()->setPaperSize(PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4);
+
+// Rename second worksheet
+echo date('H:i:s') , " Rename second worksheet" , EOL;
+$objPHPExcel->getActiveSheet()->setTitle('Terms and conditions');
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/05featuredemo.php b/Server/vendor/phpoffice/phpexcel/Examples/05featuredemo.php
new file mode 100755
index 000000000..9e502acb6
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/05featuredemo.php
@@ -0,0 +1,78 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+include "05featuredemo.inc.php";
+
+/** Include PHPExcel_IOFactory */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Save Excel 95 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing files" , EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/06largescale-with-cellcaching-sqlite.php b/Server/vendor/phpoffice/phpexcel/Examples/06largescale-with-cellcaching-sqlite.php
new file mode 100755
index 000000000..8baa7431a
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/06largescale-with-cellcaching-sqlite.php
@@ -0,0 +1,129 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_sqlite;
+if (PHPExcel_Settings::setCacheStorageMethod($cacheMethod)) {
+ echo date('H:i:s') , " Enable Cell Caching using " , $cacheMethod , " method" , EOL;
+} else {
+ echo date('H:i:s') , " Unable to set Cell Caching using " , $cacheMethod , " method, reverting to memory" , EOL;
+}
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Create a first sheet
+echo date('H:i:s') , " Add data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', "Firstname");
+$objPHPExcel->getActiveSheet()->setCellValue('B1', "Lastname");
+$objPHPExcel->getActiveSheet()->setCellValue('C1', "Phone");
+$objPHPExcel->getActiveSheet()->setCellValue('D1', "Fax");
+$objPHPExcel->getActiveSheet()->setCellValue('E1', "Is Client ?");
+
+
+// Hide "Phone" and "fax" column
+echo date('H:i:s') , " Hide 'Phone' and 'fax' columns" , EOL;
+$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setVisible(false);
+$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setVisible(false);
+
+
+// Set outline levels
+echo date('H:i:s') , " Set outline levels" , EOL;
+$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1)
+ ->setVisible(false)
+ ->setCollapsed(true);
+
+// Freeze panes
+echo date('H:i:s') , " Freeze panes" , EOL;
+$objPHPExcel->getActiveSheet()->freezePane('A2');
+
+
+// Rows to repeat at top
+echo date('H:i:s') , " Rows to repeat at top" , EOL;
+$objPHPExcel->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 1);
+
+
+// Add data
+for ($i = 2; $i <= 5000; $i++) {
+ $objPHPExcel->getActiveSheet()->setCellValue('A' . $i, "FName $i")
+ ->setCellValue('B' . $i, "LName $i")
+ ->setCellValue('C' . $i, "PhoneNo $i")
+ ->setCellValue('D' . $i, "FaxNo $i")
+ ->setCellValue('E' . $i, true);
+}
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/06largescale-with-cellcaching-sqlite3.php b/Server/vendor/phpoffice/phpexcel/Examples/06largescale-with-cellcaching-sqlite3.php
new file mode 100755
index 000000000..1f480d1d2
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/06largescale-with-cellcaching-sqlite3.php
@@ -0,0 +1,129 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_sqlite3;
+if (PHPExcel_Settings::setCacheStorageMethod($cacheMethod)) {
+ echo date('H:i:s') , " Enable Cell Caching using " , $cacheMethod , " method" , EOL;
+} else {
+ echo date('H:i:s') , " Unable to set Cell Caching using " , $cacheMethod , " method, reverting to memory" , EOL;
+}
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Create a first sheet
+echo date('H:i:s') , " Add data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', "Firstname");
+$objPHPExcel->getActiveSheet()->setCellValue('B1', "Lastname");
+$objPHPExcel->getActiveSheet()->setCellValue('C1', "Phone");
+$objPHPExcel->getActiveSheet()->setCellValue('D1', "Fax");
+$objPHPExcel->getActiveSheet()->setCellValue('E1', "Is Client ?");
+
+
+// Hide "Phone" and "fax" column
+echo date('H:i:s') , " Hide 'Phone' and 'fax' columns" , EOL;
+$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setVisible(false);
+$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setVisible(false);
+
+
+// Set outline levels
+echo date('H:i:s') , " Set outline levels" , EOL;
+$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1)
+ ->setVisible(false)
+ ->setCollapsed(true);
+
+// Freeze panes
+echo date('H:i:s') , " Freeze panes" , EOL;
+$objPHPExcel->getActiveSheet()->freezePane('A2');
+
+
+// Rows to repeat at top
+echo date('H:i:s') , " Rows to repeat at top" , EOL;
+$objPHPExcel->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 1);
+
+
+// Add data
+for ($i = 2; $i <= 5000; $i++) {
+ $objPHPExcel->getActiveSheet()->setCellValue('A' . $i, "FName $i")
+ ->setCellValue('B' . $i, "LName $i")
+ ->setCellValue('C' . $i, "PhoneNo $i")
+ ->setCellValue('D' . $i, "FaxNo $i")
+ ->setCellValue('E' . $i, true);
+}
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/06largescale-with-cellcaching.php b/Server/vendor/phpoffice/phpexcel/Examples/06largescale-with-cellcaching.php
new file mode 100755
index 000000000..d20b29f24
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/06largescale-with-cellcaching.php
@@ -0,0 +1,128 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip;
+if (!PHPExcel_Settings::setCacheStorageMethod($cacheMethod)) {
+ die($cacheMethod . " caching method is not available" . EOL);
+}
+echo date('H:i:s') , " Enable Cell Caching using " , $cacheMethod , " method" , EOL;
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Create a first sheet
+echo date('H:i:s') , " Add data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', "Firstname");
+$objPHPExcel->getActiveSheet()->setCellValue('B1', "Lastname");
+$objPHPExcel->getActiveSheet()->setCellValue('C1', "Phone");
+$objPHPExcel->getActiveSheet()->setCellValue('D1', "Fax");
+$objPHPExcel->getActiveSheet()->setCellValue('E1', "Is Client ?");
+
+
+// Hide "Phone" and "fax" column
+echo date('H:i:s') , " Hide 'Phone' and 'fax' columns" , EOL;
+$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setVisible(false);
+$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setVisible(false);
+
+
+// Set outline levels
+echo date('H:i:s') , " Set outline levels" , EOL;
+$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1)
+ ->setVisible(false)
+ ->setCollapsed(true);
+
+// Freeze panes
+echo date('H:i:s') , " Freeze panes" , EOL;
+$objPHPExcel->getActiveSheet()->freezePane('A2');
+
+
+// Rows to repeat at top
+echo date('H:i:s') , " Rows to repeat at top" , EOL;
+$objPHPExcel->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 1);
+
+
+// Add data
+for ($i = 2; $i <= 5000; $i++) {
+ $objPHPExcel->getActiveSheet()->setCellValue('A' . $i, "FName $i")
+ ->setCellValue('B' . $i, "LName $i")
+ ->setCellValue('C' . $i, "PhoneNo $i")
+ ->setCellValue('D' . $i, "FaxNo $i")
+ ->setCellValue('E' . $i, true);
+}
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/06largescale-xls.php b/Server/vendor/phpoffice/phpexcel/Examples/06largescale-xls.php
new file mode 100755
index 000000000..5adc3d259
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/06largescale-xls.php
@@ -0,0 +1,136 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+/*
+After doing some test, I've got these results benchmarked
+for writing to Excel2007:
+
+ Number of rows Seconds to generate
+ 200 3
+ 500 4
+ 1000 6
+ 2000 12
+ 4000 36
+ 8000 64
+ 15000 465
+*/
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Create a first sheet
+echo date('H:i:s') , " Add data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', "Firstname");
+$objPHPExcel->getActiveSheet()->setCellValue('B1', "Lastname");
+$objPHPExcel->getActiveSheet()->setCellValue('C1', "Phone");
+$objPHPExcel->getActiveSheet()->setCellValue('D1', "Fax");
+$objPHPExcel->getActiveSheet()->setCellValue('E1', "Is Client ?");
+
+
+// Hide "Phone" and "fax" column
+echo date('H:i:s') , " Hide 'Phone' and 'fax' columns" , EOL;
+$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setVisible(false);
+$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setVisible(false);
+
+
+// Set outline levels
+echo date('H:i:s') , " Set outline levels" , EOL;
+$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1)
+ ->setVisible(false)
+ ->setCollapsed(true);
+
+// Freeze panes
+echo date('H:i:s') , " Freeze panes" , EOL;
+$objPHPExcel->getActiveSheet()->freezePane('A2');
+
+
+// Rows to repeat at top
+echo date('H:i:s') , " Rows to repeat at top" , EOL;
+$objPHPExcel->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 1);
+
+
+// Add data
+for ($i = 2; $i <= 5000; $i++) {
+ $objPHPExcel->getActiveSheet()->setCellValue('A' . $i, "FName $i")
+ ->setCellValue('B' . $i, "LName $i")
+ ->setCellValue('C' . $i, "PhoneNo $i")
+ ->setCellValue('D' . $i, "FaxNo $i")
+ ->setCellValue('E' . $i, true);
+}
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 95 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/06largescale.php b/Server/vendor/phpoffice/phpexcel/Examples/06largescale.php
new file mode 100755
index 000000000..cb21caf50
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/06largescale.php
@@ -0,0 +1,136 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+/*
+After doing some test, I've got these results benchmarked
+for writing to Excel2007:
+
+ Number of rows Seconds to generate
+ 200 3
+ 500 4
+ 1000 6
+ 2000 12
+ 4000 36
+ 8000 64
+ 15000 465
+*/
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Create a first sheet
+echo date('H:i:s') , " Add data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', "Firstname");
+$objPHPExcel->getActiveSheet()->setCellValue('B1', "Lastname");
+$objPHPExcel->getActiveSheet()->setCellValue('C1', "Phone");
+$objPHPExcel->getActiveSheet()->setCellValue('D1', "Fax");
+$objPHPExcel->getActiveSheet()->setCellValue('E1', "Is Client ?");
+
+
+// Hide "Phone" and "fax" column
+echo date('H:i:s') , " Hide 'Phone' and 'fax' columns" , EOL;
+$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setVisible(false);
+$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setVisible(false);
+
+
+// Set outline levels
+echo date('H:i:s') , " Set outline levels" , EOL;
+$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1)
+ ->setVisible(false)
+ ->setCollapsed(true);
+
+// Freeze panes
+echo date('H:i:s') , " Freeze panes" , EOL;
+$objPHPExcel->getActiveSheet()->freezePane('A2');
+
+
+// Rows to repeat at top
+echo date('H:i:s') , " Rows to repeat at top" , EOL;
+$objPHPExcel->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 1);
+
+
+// Add data
+for ($i = 2; $i <= 5000; $i++) {
+ $objPHPExcel->getActiveSheet()->setCellValue('A' . $i, "FName $i")
+ ->setCellValue('B' . $i, "LName $i")
+ ->setCellValue('C' . $i, "PhoneNo $i")
+ ->setCellValue('D' . $i, "FaxNo $i")
+ ->setCellValue('E' . $i, true);
+}
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/07reader.php b/Server/vendor/phpoffice/phpexcel/Examples/07reader.php
new file mode 100755
index 000000000..318ba1891
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/07reader.php
@@ -0,0 +1,76 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel_IOFactory */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';
+
+
+if (!file_exists("05featuredemo.xlsx")) {
+ exit("Please run 05featuredemo.php first." . EOL);
+}
+
+echo date('H:i:s') , " Load from Excel2007 file" , EOL;
+$callStartTime = microtime(true);
+
+$objPHPExcel = PHPExcel_IOFactory::load("05featuredemo.xlsx");
+
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+echo 'Call time to read Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/07readerPCLZip.php b/Server/vendor/phpoffice/phpexcel/Examples/07readerPCLZip.php
new file mode 100755
index 000000000..f1da9c574
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/07readerPCLZip.php
@@ -0,0 +1,79 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel_IOFactory */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';
+
+
+if (!file_exists("05featuredemo.xlsx")) {
+ exit("Please run 05featuredemo.php first." . EOL);
+}
+
+// Use PCLZip rather than ZipArchive to read the Excel2007 OfficeOpenXML file
+PHPExcel_Settings::setZipClass(PHPExcel_Settings::PCLZIP);
+
+echo date('H:i:s') , " Load from Excel2007 file" , EOL;
+$callStartTime = microtime(true);
+
+$objPHPExcel = PHPExcel_IOFactory::load("05featuredemo.xlsx");
+
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+echo 'Call time to read Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/08conditionalformatting.php b/Server/vendor/phpoffice/phpexcel/Examples/08conditionalformatting.php
new file mode 100755
index 000000000..514a8bb63
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/08conditionalformatting.php
@@ -0,0 +1,189 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Create a first sheet, representing sales data
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Description')
+ ->setCellValue('B1', 'Amount');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A2', 'Paycheck received')
+ ->setCellValue('B2', 100);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A3', 'Cup of coffee bought')
+ ->setCellValue('B3', -1.5);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Cup of coffee bought')
+ ->setCellValue('B4', -1.5);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Cup of tea bought')
+ ->setCellValue('B5', -1.2);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A6', 'Found some money')
+ ->setCellValue('B6', 8);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A7', 'Total:')
+ ->setCellValue('B7', '=SUM(B2:B6)');
+
+
+// Set column widths
+echo date('H:i:s') , " Set column widths" , EOL;
+$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(30);
+$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(12);
+
+
+// Add conditional formatting
+echo date('H:i:s') , " Add conditional formatting" , EOL;
+$objConditional1 = new PHPExcel_Style_Conditional();
+$objConditional1->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS)
+ ->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_BETWEEN)
+ ->addCondition('200')
+ ->addCondition('400');
+$objConditional1->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_YELLOW);
+$objConditional1->getStyle()->getFont()->setBold(true);
+$objConditional1->getStyle()->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE);
+
+$objConditional2 = new PHPExcel_Style_Conditional();
+$objConditional2->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS)
+ ->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_LESSTHAN)
+ ->addCondition('0');
+$objConditional2->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_RED);
+$objConditional2->getStyle()->getFont()->setItalic(true);
+$objConditional2->getStyle()->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE);
+
+$objConditional3 = new PHPExcel_Style_Conditional();
+$objConditional3->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS)
+ ->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_GREATERTHANOREQUAL)
+ ->addCondition('0');
+$objConditional3->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_GREEN);
+$objConditional3->getStyle()->getFont()->setItalic(true);
+$objConditional3->getStyle()->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE);
+
+$conditionalStyles = $objPHPExcel->getActiveSheet()->getStyle('B2')->getConditionalStyles();
+array_push($conditionalStyles, $objConditional1);
+array_push($conditionalStyles, $objConditional2);
+array_push($conditionalStyles, $objConditional3);
+$objPHPExcel->getActiveSheet()->getStyle('B2')->setConditionalStyles($conditionalStyles);
+
+
+// duplicate the conditional styles across a range of cells
+echo date('H:i:s') , " Duplicate the conditional formatting across a range of cells" , EOL;
+$objPHPExcel->getActiveSheet()->duplicateConditionalStyle(
+ $objPHPExcel->getActiveSheet()->getStyle('B2')->getConditionalStyles(),
+ 'B3:B7'
+ );
+
+
+// Set fonts
+echo date('H:i:s') , " Set fonts" , EOL;
+$objPHPExcel->getActiveSheet()->getStyle('A1:B1')->getFont()->setBold(true);
+//$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setBold(true);
+$objPHPExcel->getActiveSheet()->getStyle('A7:B7')->getFont()->setBold(true);
+//$objPHPExcel->getActiveSheet()->getStyle('B7')->getFont()->setBold(true);
+
+
+// Set header and footer. When no different headers for odd/even are used, odd header is assumed.
+echo date('H:i:s') , " Set header/footer" , EOL;
+$objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddHeader('&L&BPersonal cash register&RPrinted on &D');
+$objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddFooter('&L&B' . $objPHPExcel->getProperties()->getTitle() . '&RPage &P of &N');
+
+
+// Set page orientation and size
+echo date('H:i:s') , " Set page orientation and size" , EOL;
+$objPHPExcel->getActiveSheet()->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT);
+$objPHPExcel->getActiveSheet()->getPageSetup()->setPaperSize(PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4);
+
+
+// Rename worksheet
+echo date('H:i:s') , " Rename worksheet" , EOL;
+$objPHPExcel->getActiveSheet()->setTitle('Invoice');
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Save Excel5 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/08conditionalformatting2.php b/Server/vendor/phpoffice/phpexcel/Examples/08conditionalformatting2.php
new file mode 100755
index 000000000..aeb2a3136
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/08conditionalformatting2.php
@@ -0,0 +1,136 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Create a first sheet, representing sales data
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()
+ ->setCellValue('A1', '-0.5')
+ ->setCellValue('A2', '-0.25')
+ ->setCellValue('A3', '0.0')
+ ->setCellValue('A4', '0.25')
+ ->setCellValue('A5', '0.5')
+ ->setCellValue('A6', '0.75')
+ ->setCellValue('A7', '1.0')
+ ->setCellValue('A8', '1.25')
+;
+
+$objPHPExcel->getActiveSheet()->getStyle('A1:A8')
+ ->getNumberFormat()
+ ->setFormatCode(
+ PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00
+ );
+
+
+// Add conditional formatting
+echo date('H:i:s') , " Add conditional formatting" , EOL;
+$objConditional1 = new PHPExcel_Style_Conditional();
+$objConditional1->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS)
+ ->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_LESSTHAN)
+ ->addCondition('0');
+$objConditional1->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_RED);
+
+$objConditional3 = new PHPExcel_Style_Conditional();
+$objConditional3->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS)
+ ->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_GREATERTHANOREQUAL)
+ ->addCondition('1');
+$objConditional3->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_GREEN);
+
+$conditionalStyles = $objPHPExcel->getActiveSheet()->getStyle('A1')->getConditionalStyles();
+array_push($conditionalStyles, $objConditional1);
+array_push($conditionalStyles, $objConditional3);
+$objPHPExcel->getActiveSheet()->getStyle('A1')->setConditionalStyles($conditionalStyles);
+
+
+// duplicate the conditional styles across a range of cells
+echo date('H:i:s') , " Duplicate the conditional formatting across a range of cells" , EOL;
+$objPHPExcel->getActiveSheet()->duplicateConditionalStyle(
+ $objPHPExcel->getActiveSheet()->getStyle('A1')->getConditionalStyles(),
+ 'A2:A8'
+ );
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Save Excel5 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/09pagebreaks.php b/Server/vendor/phpoffice/phpexcel/Examples/09pagebreaks.php
new file mode 100755
index 000000000..36e21ae4b
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/09pagebreaks.php
@@ -0,0 +1,134 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Create a first sheet
+echo date('H:i:s') , " Add data and page breaks" , EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', "Firstname")
+ ->setCellValue('B1', "Lastname")
+ ->setCellValue('C1', "Phone")
+ ->setCellValue('D1', "Fax")
+ ->setCellValue('E1', "Is Client ?");
+
+
+// Add data
+for ($i = 2; $i <= 50; $i++) {
+ $objPHPExcel->getActiveSheet()->setCellValue('A' . $i, "FName $i");
+ $objPHPExcel->getActiveSheet()->setCellValue('B' . $i, "LName $i");
+ $objPHPExcel->getActiveSheet()->setCellValue('C' . $i, "PhoneNo $i");
+ $objPHPExcel->getActiveSheet()->setCellValue('D' . $i, "FaxNo $i");
+ $objPHPExcel->getActiveSheet()->setCellValue('E' . $i, true);
+
+ // Add page breaks every 10 rows
+ if ($i % 10 == 0) {
+ // Add a page break
+ $objPHPExcel->getActiveSheet()->setBreak( 'A' . $i, PHPExcel_Worksheet::BREAK_ROW );
+ }
+}
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setTitle('Printing Options');
+
+// Set print headers
+$objPHPExcel->getActiveSheet()
+ ->getHeaderFooter()->setOddHeader('&C&24&K0000FF&B&U&A');
+$objPHPExcel->getActiveSheet()
+ ->getHeaderFooter()->setEvenHeader('&C&24&K0000FF&B&U&A');
+
+// Set print footers
+$objPHPExcel->getActiveSheet()
+ ->getHeaderFooter()->setOddFooter('&R&D &T&C&F&LPage &P / &N');
+$objPHPExcel->getActiveSheet()
+ ->getHeaderFooter()->setEvenFooter('&L&D &T&C&F&RPage &P / &N');
+
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Save Excel 95 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing files" , EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/10autofilter-selection-1.php b/Server/vendor/phpoffice/phpexcel/Examples/10autofilter-selection-1.php
new file mode 100755
index 000000000..8cdc0def4
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/10autofilter-selection-1.php
@@ -0,0 +1,221 @@
+');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s').' Create new PHPExcel object'.EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s').' Set document properties'.EOL;
+$objPHPExcel->getProperties()->setCreator('Maarten Balliauw')
+ ->setLastModifiedBy('Maarten Balliauw')
+ ->setTitle('PHPExcel Test Document')
+ ->setSubject('PHPExcel Test Document')
+ ->setDescription('Test document for PHPExcel, generated using PHP classes.')
+ ->setKeywords('office PHPExcel php')
+ ->setCategory('Test result file');
+
+// Create the worksheet
+echo date('H:i:s').' Add data'.EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Financial Year')
+ ->setCellValue('B1', 'Financial Period')
+ ->setCellValue('C1', 'Country')
+ ->setCellValue('D1', 'Date')
+ ->setCellValue('E1', 'Sales Value')
+ ->setCellValue('F1', 'Expenditure')
+ ;
+$startYear = $endYear = $currentYear = date('Y');
+$startYear--;
+$endYear++;
+
+$years = range($startYear,$endYear);
+$periods = range(1,12);
+$countries = array( 'United States', 'UK', 'France', 'Germany',
+ 'Italy', 'Spain', 'Portugal', 'Japan'
+ );
+
+$row = 2;
+foreach($years as $year) {
+ foreach($periods as $period) {
+ foreach($countries as $country) {
+ $endDays = date('t',mktime(0,0,0,$period,1,$year));
+ for($i = 1; $i <= $endDays; ++$i) {
+ $eDate = PHPExcel_Shared_Date::FormattedPHPToExcel(
+ $year,
+ $period,
+ $i
+ );
+ $value = rand(500,1000) * (1 + rand(-0.25,+0.25));
+ $salesValue = $invoiceValue = NULL;
+ $incomeOrExpenditure = rand(-1,1);
+ if ($incomeOrExpenditure == -1) {
+ $expenditure = rand(-500,-1000) * (1 + rand(-0.25,+0.25));
+ $income = NULL;
+ } elseif ($incomeOrExpenditure == 1) {
+ $expenditure = rand(-500,-1000) * (1 + rand(-0.25,+0.25));
+ $income = rand(500,1000) * (1 + rand(-0.25,+0.25));;
+ } else {
+ $expenditure = NULL;
+ $income = rand(500,1000) * (1 + rand(-0.25,+0.25));;
+ }
+ $dataArray = array( $year,
+ $period,
+ $country,
+ $eDate,
+ $income,
+ $expenditure,
+ );
+ $objPHPExcel->getActiveSheet()->fromArray($dataArray, NULL, 'A'.$row++);
+ }
+ }
+ }
+}
+$row--;
+
+
+// Set styling
+echo date('H:i:s').' Set styling'.EOL;
+$objPHPExcel->getActiveSheet()->getStyle('A1:F1')->getFont()->setBold(true);
+$objPHPExcel->getActiveSheet()->getStyle('A1:F1')->getAlignment()->setWrapText(TRUE);
+$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(12.5);
+$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(10.5);
+$objPHPExcel->getActiveSheet()->getStyle('D2:D'.$row)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2);
+$objPHPExcel->getActiveSheet()->getStyle('E2:F'.$row)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE);
+$objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(14);
+$objPHPExcel->getActiveSheet()->freezePane('A2');
+
+
+
+// Set autofilter range
+echo date('H:i:s').' Set autofilter range'.EOL;
+// Always include the complete filter range!
+// Excel does support setting only the caption
+// row, but that's not a best practise...
+$objPHPExcel->getActiveSheet()->setAutoFilter($objPHPExcel->getActiveSheet()->calculateWorksheetDimension());
+
+// Set active filters
+$autoFilter = $objPHPExcel->getActiveSheet()->getAutoFilter();
+echo date('H:i:s').' Set active filters'.EOL;
+// Filter the Country column on a filter value of countries beginning with the letter U (or Japan)
+// We use * as a wildcard, so specify as U* and using a wildcard requires customFilter
+$autoFilter->getColumn('C')
+ ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER)
+ ->createRule()
+ ->setRule(
+ PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
+ 'u*'
+ )
+ ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);
+$autoFilter->getColumn('C')
+ ->createRule()
+ ->setRule(
+ PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
+ 'japan'
+ )
+ ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);
+// Filter the Date column on a filter value of the first day of every period of the current year
+// We us a dateGroup ruletype for this, although it is still a standard filter
+foreach($periods as $period) {
+ $endDate = date('t',mktime(0,0,0,$period,1,$currentYear));
+
+ $autoFilter->getColumn('D')
+ ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER)
+ ->createRule()
+ ->setRule(
+ PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
+ array(
+ 'year' => $currentYear,
+ 'month' => $period,
+ 'day' => $endDate
+ )
+ )
+ ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP);
+}
+// Display only sales values that are blank
+// Standard filter, operator equals, and value of NULL
+$autoFilter->getColumn('E')
+ ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER)
+ ->createRule()
+ ->setRule(
+ PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
+ ''
+ );
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Save Excel 95 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s').' Peak memory usage: '.(memory_get_peak_usage(true) / 1024 / 1024).' MB'.EOL;
+
+// Echo done
+echo date('H:i:s').' Done writing files'.EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/10autofilter-selection-2.php b/Server/vendor/phpoffice/phpexcel/Examples/10autofilter-selection-2.php
new file mode 100755
index 000000000..e2aea748d
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/10autofilter-selection-2.php
@@ -0,0 +1,213 @@
+');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s').' Create new PHPExcel object'.EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s').' Set document properties'.EOL;
+$objPHPExcel->getProperties()->setCreator('Maarten Balliauw')
+ ->setLastModifiedBy('Maarten Balliauw')
+ ->setTitle('PHPExcel Test Document')
+ ->setSubject('PHPExcel Test Document')
+ ->setDescription('Test document for PHPExcel, generated using PHP classes.')
+ ->setKeywords('office PHPExcel php')
+ ->setCategory('Test result file');
+
+// Create the worksheet
+echo date('H:i:s').' Add data'.EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Financial Year')
+ ->setCellValue('B1', 'Financial Period')
+ ->setCellValue('C1', 'Country')
+ ->setCellValue('D1', 'Date')
+ ->setCellValue('E1', 'Sales Value')
+ ->setCellValue('F1', 'Expenditure')
+ ;
+$startYear = $endYear = $currentYear = date('Y');
+$startYear--;
+$endYear++;
+
+$years = range($startYear,$endYear);
+$periods = range(1,12);
+$countries = array( 'United States', 'UK', 'France', 'Germany',
+ 'Italy', 'Spain', 'Portugal', 'Japan'
+ );
+
+$row = 2;
+foreach($years as $year) {
+ foreach($periods as $period) {
+ foreach($countries as $country) {
+ $endDays = date('t',mktime(0,0,0,$period,1,$year));
+ for($i = 1; $i <= $endDays; ++$i) {
+ $eDate = PHPExcel_Shared_Date::FormattedPHPToExcel(
+ $year,
+ $period,
+ $i
+ );
+ $value = rand(500,1000) * (1 + rand(-0.25,+0.25));
+ $salesValue = $invoiceValue = NULL;
+ $incomeOrExpenditure = rand(-1,1);
+ if ($incomeOrExpenditure == -1) {
+ $expenditure = rand(-500,-1000) * (1 + rand(-0.25,+0.25));
+ $income = NULL;
+ } elseif ($incomeOrExpenditure == 1) {
+ $expenditure = rand(-500,-1000) * (1 + rand(-0.25,+0.25));
+ $income = rand(500,1000) * (1 + rand(-0.25,+0.25));;
+ } else {
+ $expenditure = NULL;
+ $income = rand(500,1000) * (1 + rand(-0.25,+0.25));;
+ }
+ $dataArray = array( $year,
+ $period,
+ $country,
+ $eDate,
+ $income,
+ $expenditure,
+ );
+ $objPHPExcel->getActiveSheet()->fromArray($dataArray, NULL, 'A'.$row++);
+ }
+ }
+ }
+}
+$row--;
+
+
+// Set styling
+echo date('H:i:s').' Set styling'.EOL;
+$objPHPExcel->getActiveSheet()->getStyle('A1:F1')->getFont()->setBold(true);
+$objPHPExcel->getActiveSheet()->getStyle('A1:F1')->getAlignment()->setWrapText(TRUE);
+$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(12.5);
+$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(10.5);
+$objPHPExcel->getActiveSheet()->getStyle('D2:D'.$row)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2);
+$objPHPExcel->getActiveSheet()->getStyle('E2:F'.$row)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE);
+$objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(14);
+$objPHPExcel->getActiveSheet()->freezePane('A2');
+
+
+
+// Set autofilter range
+echo date('H:i:s').' Set autofilter range'.EOL;
+// Always include the complete filter range!
+// Excel does support setting only the caption
+// row, but that's not a best practise...
+$objPHPExcel->getActiveSheet()->setAutoFilter($objPHPExcel->getActiveSheet()->calculateWorksheetDimension());
+
+// Set active filters
+$autoFilter = $objPHPExcel->getActiveSheet()->getAutoFilter();
+echo date('H:i:s').' Set active filters'.EOL;
+// Filter the Country column on a filter value of Germany
+// As it's just a simple value filter, we can use FILTERTYPE_FILTER
+$autoFilter->getColumn('C')
+ ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER)
+ ->createRule()
+ ->setRule(
+ PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
+ 'Germany'
+ );
+// Filter the Date column on a filter value of the year to date
+$autoFilter->getColumn('D')
+ ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER)
+ ->createRule()
+ ->setRule(
+ PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
+ NULL,
+ PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE
+ )
+ ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER);
+// Display only sales values that are between 400 and 600
+$autoFilter->getColumn('E')
+ ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER)
+ ->createRule()
+ ->setRule(
+ PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL,
+ 400
+ )
+ ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);
+$autoFilter->getColumn('E')
+ ->setJoin(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND)
+ ->createRule()
+ ->setRule(
+ PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL,
+ 600
+ )
+ ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Save Excel 95 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s').' Peak memory usage: '.(memory_get_peak_usage(true) / 1024 / 1024).' MB'.EOL;
+
+// Echo done
+echo date('H:i:s').' Done writing files'.EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/10autofilter-selection-display.php b/Server/vendor/phpoffice/phpexcel/Examples/10autofilter-selection-display.php
new file mode 100755
index 000000000..ba3fed9e0
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/10autofilter-selection-display.php
@@ -0,0 +1,198 @@
+');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s').' Create new PHPExcel object'.EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s').' Set document properties'.EOL;
+$objPHPExcel->getProperties()->setCreator('Maarten Balliauw')
+ ->setLastModifiedBy('Maarten Balliauw')
+ ->setTitle('PHPExcel Test Document')
+ ->setSubject('PHPExcel Test Document')
+ ->setDescription('Test document for PHPExcel, generated using PHP classes.')
+ ->setKeywords('office PHPExcel php')
+ ->setCategory('Test result file');
+
+// Create the worksheet
+echo date('H:i:s').' Add data'.EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Financial Year')
+ ->setCellValue('B1', 'Financial Period')
+ ->setCellValue('C1', 'Country')
+ ->setCellValue('D1', 'Date')
+ ->setCellValue('E1', 'Sales Value')
+ ->setCellValue('F1', 'Expenditure')
+ ;
+$startYear = $endYear = $currentYear = date('Y');
+$startYear--;
+$endYear++;
+
+$years = range($startYear,$endYear);
+$periods = range(1,12);
+$countries = array( 'United States', 'UK', 'France', 'Germany',
+ 'Italy', 'Spain', 'Portugal', 'Japan'
+ );
+
+$row = 2;
+foreach($years as $year) {
+ foreach($periods as $period) {
+ foreach($countries as $country) {
+ $endDays = date('t',mktime(0,0,0,$period,1,$year));
+ for($i = 1; $i <= $endDays; ++$i) {
+ $eDate = PHPExcel_Shared_Date::FormattedPHPToExcel(
+ $year,
+ $period,
+ $i
+ );
+ $value = rand(500,1000) * (1 + rand(-0.25,+0.25));
+ $salesValue = $invoiceValue = NULL;
+ $incomeOrExpenditure = rand(-1,1);
+ if ($incomeOrExpenditure == -1) {
+ $expenditure = rand(-500,-1000) * (1 + rand(-0.25,+0.25));
+ $income = NULL;
+ } elseif ($incomeOrExpenditure == 1) {
+ $expenditure = rand(-500,-1000) * (1 + rand(-0.25,+0.25));
+ $income = rand(500,1000) * (1 + rand(-0.25,+0.25));;
+ } else {
+ $expenditure = NULL;
+ $income = rand(500,1000) * (1 + rand(-0.25,+0.25));;
+ }
+ $dataArray = array( $year,
+ $period,
+ $country,
+ $eDate,
+ $income,
+ $expenditure,
+ );
+ $objPHPExcel->getActiveSheet()->fromArray($dataArray, NULL, 'A'.$row++);
+ }
+ }
+ }
+}
+$row--;
+
+
+// Set styling
+echo date('H:i:s').' Set styling'.EOL;
+$objPHPExcel->getActiveSheet()->getStyle('A1:F1')->getFont()->setBold(true);
+$objPHPExcel->getActiveSheet()->getStyle('A1:F1')->getAlignment()->setWrapText(TRUE);
+$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(12.5);
+$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(10.5);
+$objPHPExcel->getActiveSheet()->getStyle('D2:D'.$row)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2);
+$objPHPExcel->getActiveSheet()->getStyle('E2:F'.$row)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE);
+$objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(14);
+$objPHPExcel->getActiveSheet()->freezePane('A2');
+
+
+
+// Set autofilter range
+echo date('H:i:s').' Set autofilter range'.EOL;
+// Always include the complete filter range!
+// Excel does support setting only the caption
+// row, but that's not a best practise...
+$objPHPExcel->getActiveSheet()->setAutoFilter($objPHPExcel->getActiveSheet()->calculateWorksheetDimension());
+
+// Set active filters
+$autoFilter = $objPHPExcel->getActiveSheet()->getAutoFilter();
+echo date('H:i:s').' Set active filters'.EOL;
+// Filter the Country column on a filter value of countries beginning with the letter U (or Japan)
+// We use * as a wildcard, so specify as U* and using a wildcard requires customFilter
+$autoFilter->getColumn('C')
+ ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER)
+ ->createRule()
+ ->setRule(
+ PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
+ 'u*'
+ )
+ ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);
+$autoFilter->getColumn('C')
+ ->createRule()
+ ->setRule(
+ PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
+ 'japan'
+ )
+ ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);
+// Filter the Date column on a filter value of the first day of every period of the current year
+// We us a dateGroup ruletype for this, although it is still a standard filter
+foreach($periods as $period) {
+ $endDate = date('t',mktime(0,0,0,$period,1,$currentYear));
+
+ $autoFilter->getColumn('D')
+ ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER)
+ ->createRule()
+ ->setRule(
+ PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
+ array(
+ 'year' => $currentYear,
+ 'month' => $period,
+ 'day' => $endDate
+ )
+ )
+ ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP);
+}
+// Display only sales values that are blank
+// Standard filter, operator equals, and value of NULL
+$autoFilter->getColumn('E')
+ ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER)
+ ->createRule()
+ ->setRule(
+ PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
+ ''
+ );
+
+// Execute filtering
+echo date('H:i:s').' Execute filtering'.EOL;
+$autoFilter->showHideRows();
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Display Results of filtering
+echo date('H:i:s').' Display filtered rows'.EOL;
+foreach ($objPHPExcel->getActiveSheet()->getRowIterator() as $row) {
+ if ($objPHPExcel->getActiveSheet()->getRowDimension($row->getRowIndex())->getVisible()) {
+ echo ' Row number - ' , $row->getRowIndex() , ' ';
+ echo $objPHPExcel->getActiveSheet()->getCell('C'.$row->getRowIndex())->getValue(), ' ';
+ echo $objPHPExcel->getActiveSheet()->getCell('D'.$row->getRowIndex())->getFormattedValue(), ' ';
+ echo EOL;
+ }
+}
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/10autofilter.php b/Server/vendor/phpoffice/phpexcel/Examples/10autofilter.php
new file mode 100755
index 000000000..015e9cfe3
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/10autofilter.php
@@ -0,0 +1,171 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+// Create new PHPExcel object
+echo date('H:i:s').' Create new PHPExcel object'.EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s').' Set document properties'.EOL;
+$objPHPExcel->getProperties()->setCreator('Maarten Balliauw')
+ ->setLastModifiedBy('Maarten Balliauw')
+ ->setTitle('PHPExcel Test Document')
+ ->setSubject('PHPExcel Test Document')
+ ->setDescription('Test document for PHPExcel, generated using PHP classes.')
+ ->setKeywords('office PHPExcel php')
+ ->setCategory('Test result file');
+
+// Create the worksheet
+echo date('H:i:s').' Add data'.EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Year')
+ ->setCellValue('B1', 'Quarter')
+ ->setCellValue('C1', 'Country')
+ ->setCellValue('D1', 'Sales');
+
+$dataArray = array(array('2010', 'Q1', 'United States', 790),
+ array('2010', 'Q2', 'United States', 730),
+ array('2010', 'Q3', 'United States', 860),
+ array('2010', 'Q4', 'United States', 850),
+ array('2011', 'Q1', 'United States', 800),
+ array('2011', 'Q2', 'United States', 700),
+ array('2011', 'Q3', 'United States', 900),
+ array('2011', 'Q4', 'United States', 950),
+ array('2010', 'Q1', 'Belgium', 380),
+ array('2010', 'Q2', 'Belgium', 390),
+ array('2010', 'Q3', 'Belgium', 420),
+ array('2010', 'Q4', 'Belgium', 460),
+ array('2011', 'Q1', 'Belgium', 400),
+ array('2011', 'Q2', 'Belgium', 350),
+ array('2011', 'Q3', 'Belgium', 450),
+ array('2011', 'Q4', 'Belgium', 500),
+ array('2010', 'Q1', 'UK', 690),
+ array('2010', 'Q2', 'UK', 610),
+ array('2010', 'Q3', 'UK', 620),
+ array('2010', 'Q4', 'UK', 600),
+ array('2011', 'Q1', 'UK', 720),
+ array('2011', 'Q2', 'UK', 650),
+ array('2011', 'Q3', 'UK', 580),
+ array('2011', 'Q4', 'UK', 510),
+ array('2010', 'Q1', 'France', 510),
+ array('2010', 'Q2', 'France', 490),
+ array('2010', 'Q3', 'France', 460),
+ array('2010', 'Q4', 'France', 590),
+ array('2011', 'Q1', 'France', 620),
+ array('2011', 'Q2', 'France', 650),
+ array('2011', 'Q3', 'France', 415),
+ array('2011', 'Q4', 'France', 570),
+ array('2010', 'Q1', 'Germany', 720),
+ array('2010', 'Q2', 'Germany', 680),
+ array('2010', 'Q3', 'Germany', 640),
+ array('2010', 'Q4', 'Germany', 660),
+ array('2011', 'Q1', 'Germany', 680),
+ array('2011', 'Q2', 'Germany', 620),
+ array('2011', 'Q3', 'Germany', 710),
+ array('2011', 'Q4', 'Germany', 690),
+ array('2010', 'Q1', 'Spain', 510),
+ array('2010', 'Q2', 'Spain', 490),
+ array('2010', 'Q3', 'Spain', 470),
+ array('2010', 'Q4', 'Spain', 420),
+ array('2011', 'Q1', 'Spain', 460),
+ array('2011', 'Q2', 'Spain', 390),
+ array('2011', 'Q3', 'Spain', 430),
+ array('2011', 'Q4', 'Spain', 415),
+ array('2010', 'Q1', 'Italy', 440),
+ array('2010', 'Q2', 'Italy', 410),
+ array('2010', 'Q3', 'Italy', 420),
+ array('2010', 'Q4', 'Italy', 450),
+ array('2011', 'Q1', 'Italy', 430),
+ array('2011', 'Q2', 'Italy', 370),
+ array('2011', 'Q3', 'Italy', 350),
+ array('2011', 'Q4', 'Italy', 335),
+ );
+$objPHPExcel->getActiveSheet()->fromArray($dataArray, NULL, 'A2');
+
+// Set title row bold
+echo date('H:i:s').' Set title row bold'.EOL;
+$objPHPExcel->getActiveSheet()->getStyle('A1:D1')->getFont()->setBold(true);
+
+// Set autofilter
+echo date('H:i:s').' Set autofilter'.EOL;
+// Always include the complete filter range!
+// Excel does support setting only the caption
+// row, but that's not a best practise...
+$objPHPExcel->getActiveSheet()->setAutoFilter($objPHPExcel->getActiveSheet()->calculateWorksheetDimension());
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Save Excel 95 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s').' Peak memory usage: '.(memory_get_peak_usage(true) / 1024 / 1024).' MB'.EOL;
+
+// Echo done
+echo date('H:i:s').' Done writing files'.EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/11documentsecurity-xls.php b/Server/vendor/phpoffice/phpexcel/Examples/11documentsecurity-xls.php
new file mode 100755
index 000000000..2348ce959
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/11documentsecurity-xls.php
@@ -0,0 +1,109 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Add some data
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Hello');
+$objPHPExcel->getActiveSheet()->setCellValue('B2', 'world!');
+$objPHPExcel->getActiveSheet()->setCellValue('C1', 'Hello');
+$objPHPExcel->getActiveSheet()->setCellValue('D2', 'world!');
+
+// Rename worksheet
+echo date('H:i:s') , " Rename worksheet" , EOL;
+$objPHPExcel->getActiveSheet()->setTitle('Simple');
+
+
+// Set document security
+echo date('H:i:s') , " Set document security" , EOL;
+$objPHPExcel->getSecurity()->setLockWindows(true);
+$objPHPExcel->getSecurity()->setLockStructure(true);
+$objPHPExcel->getSecurity()->setWorkbookPassword("PHPExcel");
+
+
+// Set sheet security
+echo date('H:i:s') , " Set sheet security" , EOL;
+$objPHPExcel->getActiveSheet()->getProtection()->setPassword('PHPExcel');
+$objPHPExcel->getActiveSheet()->getProtection()->setSheet(true); // This should be enabled in order to enable any of the following!
+$objPHPExcel->getActiveSheet()->getProtection()->setSort(true);
+$objPHPExcel->getActiveSheet()->getProtection()->setInsertRows(true);
+$objPHPExcel->getActiveSheet()->getProtection()->setFormatCells(true);
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 95 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/11documentsecurity.php b/Server/vendor/phpoffice/phpexcel/Examples/11documentsecurity.php
new file mode 100755
index 000000000..9fd4fb2a4
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/11documentsecurity.php
@@ -0,0 +1,109 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Add some data
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Hello');
+$objPHPExcel->getActiveSheet()->setCellValue('B2', 'world!');
+$objPHPExcel->getActiveSheet()->setCellValue('C1', 'Hello');
+$objPHPExcel->getActiveSheet()->setCellValue('D2', 'world!');
+
+// Rename worksheet
+echo date('H:i:s') , " Rename worksheet" , EOL;
+$objPHPExcel->getActiveSheet()->setTitle('Simple');
+
+
+// Set document security
+echo date('H:i:s') , " Set document security" , EOL;
+$objPHPExcel->getSecurity()->setLockWindows(true);
+$objPHPExcel->getSecurity()->setLockStructure(true);
+$objPHPExcel->getSecurity()->setWorkbookPassword("PHPExcel");
+
+
+// Set sheet security
+echo date('H:i:s') , " Set sheet security" , EOL;
+$objPHPExcel->getActiveSheet()->getProtection()->setPassword('PHPExcel');
+$objPHPExcel->getActiveSheet()->getProtection()->setSheet(true); // This should be enabled in order to enable any of the following!
+$objPHPExcel->getActiveSheet()->getProtection()->setSort(true);
+$objPHPExcel->getActiveSheet()->getProtection()->setInsertRows(true);
+$objPHPExcel->getActiveSheet()->getProtection()->setFormatCells(true);
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/12cellProtection.php b/Server/vendor/phpoffice/phpexcel/Examples/12cellProtection.php
new file mode 100755
index 000000000..e12c9ae47
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/12cellProtection.php
@@ -0,0 +1,107 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Mark Baker")
+ ->setLastModifiedBy("Mark Baker")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Add some data
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Crouching');
+$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Tiger');
+$objPHPExcel->getActiveSheet()->setCellValue('A2', 'Hidden');
+$objPHPExcel->getActiveSheet()->setCellValue('B2', 'Dragon');
+
+// Rename worksheet
+echo date('H:i:s') , " Rename worksheet" , EOL;
+$objPHPExcel->getActiveSheet()->setTitle('Simple');
+
+
+// Set document security
+echo date('H:i:s') , " Set cell protection" , EOL;
+
+
+// Set sheet security
+echo date('H:i:s') , " Set sheet security" , EOL;
+$objPHPExcel->getActiveSheet()->getProtection()->setSheet(true);
+$objPHPExcel->getActiveSheet()
+ ->getStyle('A2:B2')
+ ->getProtection()->setLocked(
+ PHPExcel_Style_Protection::PROTECTION_UNPROTECTED
+ );
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/13calculation.php b/Server/vendor/phpoffice/phpexcel/Examples/13calculation.php
new file mode 100755
index 000000000..e255d115f
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/13calculation.php
@@ -0,0 +1,235 @@
+');
+
+date_default_timezone_set('Europe/London');
+mt_srand(1234567890);
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// List functions
+echo date('H:i:s') , " List implemented functions" , EOL;
+$objCalc = PHPExcel_Calculation::getInstance();
+print_r($objCalc->listFunctionNames());
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Add some data, we will use some formulas here
+echo date('H:i:s') , " Add some data and formulas" , EOL;
+$objPHPExcel->getActiveSheet()->setCellValue('A14', 'Count:')
+ ->setCellValue('A15', 'Sum:')
+ ->setCellValue('A16', 'Max:')
+ ->setCellValue('A17', 'Min:')
+ ->setCellValue('A18', 'Average:')
+ ->setCellValue('A19', 'Median:')
+ ->setCellValue('A20', 'Mode:');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A22', 'CountA:')
+ ->setCellValue('A23', 'MaxA:')
+ ->setCellValue('A24', 'MinA:');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A26', 'StDev:')
+ ->setCellValue('A27', 'StDevA:')
+ ->setCellValue('A28', 'StDevP:')
+ ->setCellValue('A29', 'StDevPA:');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A31', 'DevSq:')
+ ->setCellValue('A32', 'Var:')
+ ->setCellValue('A33', 'VarA:')
+ ->setCellValue('A34', 'VarP:')
+ ->setCellValue('A35', 'VarPA:');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A37', 'Date:');
+
+
+$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Range 1')
+ ->setCellValue('B2', 2)
+ ->setCellValue('B3', 8)
+ ->setCellValue('B4', 10)
+ ->setCellValue('B5', True)
+ ->setCellValue('B6', False)
+ ->setCellValue('B7', 'Text String')
+ ->setCellValue('B9', '22')
+ ->setCellValue('B10', 4)
+ ->setCellValue('B11', 6)
+ ->setCellValue('B12', 12);
+
+$objPHPExcel->getActiveSheet()->setCellValue('B14', '=COUNT(B2:B12)')
+ ->setCellValue('B15', '=SUM(B2:B12)')
+ ->setCellValue('B16', '=MAX(B2:B12)')
+ ->setCellValue('B17', '=MIN(B2:B12)')
+ ->setCellValue('B18', '=AVERAGE(B2:B12)')
+ ->setCellValue('B19', '=MEDIAN(B2:B12)')
+ ->setCellValue('B20', '=MODE(B2:B12)');
+
+$objPHPExcel->getActiveSheet()->setCellValue('B22', '=COUNTA(B2:B12)')
+ ->setCellValue('B23', '=MAXA(B2:B12)')
+ ->setCellValue('B24', '=MINA(B2:B12)');
+
+$objPHPExcel->getActiveSheet()->setCellValue('B26', '=STDEV(B2:B12)')
+ ->setCellValue('B27', '=STDEVA(B2:B12)')
+ ->setCellValue('B28', '=STDEVP(B2:B12)')
+ ->setCellValue('B29', '=STDEVPA(B2:B12)');
+
+$objPHPExcel->getActiveSheet()->setCellValue('B31', '=DEVSQ(B2:B12)')
+ ->setCellValue('B32', '=VAR(B2:B12)')
+ ->setCellValue('B33', '=VARA(B2:B12)')
+ ->setCellValue('B34', '=VARP(B2:B12)')
+ ->setCellValue('B35', '=VARPA(B2:B12)');
+
+$objPHPExcel->getActiveSheet()->setCellValue('B37', '=DATE(2007, 12, 21)')
+ ->setCellValue('B38', '=DATEDIF( DATE(2007, 12, 21), DATE(2007, 12, 22), "D" )')
+ ->setCellValue('B39', '=DATEVALUE("01-Feb-2006 10:06 AM")')
+ ->setCellValue('B40', '=DAY( DATE(2006, 1, 2) )')
+ ->setCellValue('B41', '=DAYS360( DATE(2002, 2, 3), DATE(2005, 5, 31) )');
+
+
+$objPHPExcel->getActiveSheet()->setCellValue('C1', 'Range 2')
+ ->setCellValue('C2', 1)
+ ->setCellValue('C3', 2)
+ ->setCellValue('C4', 2)
+ ->setCellValue('C5', 3)
+ ->setCellValue('C6', 3)
+ ->setCellValue('C7', 3)
+ ->setCellValue('C8', '0')
+ ->setCellValue('C9', 4)
+ ->setCellValue('C10', 4)
+ ->setCellValue('C11', 4)
+ ->setCellValue('C12', 4);
+
+$objPHPExcel->getActiveSheet()->setCellValue('C14', '=COUNT(C2:C12)')
+ ->setCellValue('C15', '=SUM(C2:C12)')
+ ->setCellValue('C16', '=MAX(C2:C12)')
+ ->setCellValue('C17', '=MIN(C2:C12)')
+ ->setCellValue('C18', '=AVERAGE(C2:C12)')
+ ->setCellValue('C19', '=MEDIAN(C2:C12)')
+ ->setCellValue('C20', '=MODE(C2:C12)');
+
+$objPHPExcel->getActiveSheet()->setCellValue('C22', '=COUNTA(C2:C12)')
+ ->setCellValue('C23', '=MAXA(C2:C12)')
+ ->setCellValue('C24', '=MINA(C2:C12)');
+
+$objPHPExcel->getActiveSheet()->setCellValue('C26', '=STDEV(C2:C12)')
+ ->setCellValue('C27', '=STDEVA(C2:C12)')
+ ->setCellValue('C28', '=STDEVP(C2:C12)')
+ ->setCellValue('C29', '=STDEVPA(C2:C12)');
+
+$objPHPExcel->getActiveSheet()->setCellValue('C31', '=DEVSQ(C2:C12)')
+ ->setCellValue('C32', '=VAR(C2:C12)')
+ ->setCellValue('C33', '=VARA(C2:C12)')
+ ->setCellValue('C34', '=VARP(C2:C12)')
+ ->setCellValue('C35', '=VARPA(C2:C12)');
+
+
+$objPHPExcel->getActiveSheet()->setCellValue('D1', 'Range 3')
+ ->setCellValue('D2', 2)
+ ->setCellValue('D3', 3)
+ ->setCellValue('D4', 4);
+
+$objPHPExcel->getActiveSheet()->setCellValue('D14', '=((D2 * D3) + D4) & " should be 10"');
+
+$objPHPExcel->getActiveSheet()->setCellValue('E12', 'Other functions')
+ ->setCellValue('E14', '=PI()')
+ ->setCellValue('E15', '=RAND()')
+ ->setCellValue('E16', '=RANDBETWEEN(5, 10)');
+
+$objPHPExcel->getActiveSheet()->setCellValue('E17', 'Count of both ranges:')
+ ->setCellValue('F17', '=COUNT(B2:C12)');
+
+$objPHPExcel->getActiveSheet()->setCellValue('E18', 'Total of both ranges:')
+ ->setCellValue('F18', '=SUM(B2:C12)');
+
+$objPHPExcel->getActiveSheet()->setCellValue('E19', 'Maximum of both ranges:')
+ ->setCellValue('F19', '=MAX(B2:C12)');
+
+$objPHPExcel->getActiveSheet()->setCellValue('E20', 'Minimum of both ranges:')
+ ->setCellValue('F20', '=MIN(B2:C12)');
+
+$objPHPExcel->getActiveSheet()->setCellValue('E21', 'Average of both ranges:')
+ ->setCellValue('F21', '=AVERAGE(B2:C12)');
+
+$objPHPExcel->getActiveSheet()->setCellValue('E22', 'Median of both ranges:')
+ ->setCellValue('F22', '=MEDIAN(B2:C12)');
+
+$objPHPExcel->getActiveSheet()->setCellValue('E23', 'Mode of both ranges:')
+ ->setCellValue('F23', '=MODE(B2:C12)');
+
+
+// Calculated data
+echo date('H:i:s') , " Calculated data" , EOL;
+for ($col = 'B'; $col != 'G'; ++$col) {
+ for($row = 14; $row <= 41; ++$row) {
+ if ((!is_null($formula = $objPHPExcel->getActiveSheet()->getCell($col.$row)->getValue())) &&
+ ($formula[0] == '=')) {
+ echo 'Value of ' , $col , $row , ' [' , $formula , ']: ' ,
+ $objPHPExcel->getActiveSheet()->getCell($col.$row)->getCalculatedValue() . EOL;
+ }
+ }
+}
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+
+//
+// If we set Pre Calculated Formulas to true then PHPExcel will calculate all formulae in the
+// workbook before saving. This adds time and memory overhead, and can cause some problems with formulae
+// using functions or features (such as array formulae) that aren't yet supported by the calculation engine
+// If the value is false (the default) for the Excel2007 Writer, then MS Excel (or the application used to
+// open the file) will need to recalculate values itself to guarantee that the correct results are available.
+//
+//$objWriter->setPreCalculateFormulas(true);
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/13calculationCyclicFormulae.php b/Server/vendor/phpoffice/phpexcel/Examples/13calculationCyclicFormulae.php
new file mode 100755
index 000000000..8512a3e85
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/13calculationCyclicFormulae.php
@@ -0,0 +1,97 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Add some data, we will use some formulas here
+echo date('H:i:s') , " Add some data and formulas" , EOL;
+$objPHPExcel->getActiveSheet()->setCellValue('A1', '=B1')
+ ->setCellValue('A2', '=B2+1')
+ ->setCellValue('B1', '=A1+1')
+ ->setCellValue('B2', '=A2');
+
+PHPExcel_Calculation::getInstance($objPHPExcel)->cyclicFormulaCount = 100;
+
+// Calculated data
+echo date('H:i:s') , " Calculated data" , EOL;
+for($row = 1; $row <= 2; ++$row) {
+ for ($col = 'A'; $col != 'C'; ++$col) {
+ if ((!is_null($formula = $objPHPExcel->getActiveSheet()->getCell($col.$row)->getValue())) &&
+ ($formula[0] == '=')) {
+ echo 'Value of ' , $col , $row , ' [' , $formula , ']: ' ,
+ $objPHPExcel->getActiveSheet()->getCell($col.$row)->getCalculatedValue() . EOL;
+ }
+ }
+}
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+
+//
+// If we set Pre Calculated Formulas to true then PHPExcel will calculate all formulae in the
+// workbook before saving. This adds time and memory overhead, and can cause some problems with formulae
+// using functions or features (such as array formulae) that aren't yet supported by the calculation engine
+// If the value is false (the default) for the Excel2007 Writer, then MS Excel (or the application used to
+// open the file) will need to recalculate values itself to guarantee that the correct results are available.
+//
+//$objWriter->setPreCalculateFormulas(true);
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/14excel5.php b/Server/vendor/phpoffice/phpexcel/Examples/14excel5.php
new file mode 100755
index 000000000..7a9f6856f
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/14excel5.php
@@ -0,0 +1,63 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+include "05featuredemo.inc.php";
+
+/** PHPExcel_IOFactory */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';
+
+
+// Save Excel 95 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/15datavalidation-xls.php b/Server/vendor/phpoffice/phpexcel/Examples/15datavalidation-xls.php
new file mode 100755
index 000000000..3f0afde53
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/15datavalidation-xls.php
@@ -0,0 +1,155 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Create a first sheet
+echo date('H:i:s') , " Add data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', "Cell B3 and B5 contain data validation...")
+ ->setCellValue('A3', "Number:")
+ ->setCellValue('B3', "10")
+ ->setCellValue('A5', "List:")
+ ->setCellValue('B5', "Item A")
+ ->setCellValue('A7', "List #2:")
+ ->setCellValue('B7', "Item #2")
+ ->setCellValue('D2', "Item #1")
+ ->setCellValue('D3', "Item #2")
+ ->setCellValue('D4', "Item #3")
+ ->setCellValue('D5', "Item #4")
+ ->setCellValue('D6', "Item #5")
+ ->setCellValue('A9', 'Text:')
+ ;
+
+
+// Set data validation
+echo date('H:i:s') , " Set data validation" , EOL;
+$objValidation = $objPHPExcel->getActiveSheet()->getCell('B3')->getDataValidation();
+$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_WHOLE );
+$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_STOP );
+$objValidation->setAllowBlank(true);
+$objValidation->setShowInputMessage(true);
+$objValidation->setShowErrorMessage(true);
+$objValidation->setErrorTitle('Input error');
+$objValidation->setError('Only numbers between 10 and 20 are allowed!');
+$objValidation->setPromptTitle('Allowed input');
+$objValidation->setPrompt('Only numbers between 10 and 20 are allowed.');
+$objValidation->setFormula1(10);
+$objValidation->setFormula2(20);
+
+$objValidation = $objPHPExcel->getActiveSheet()->getCell('B5')->getDataValidation();
+$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST );
+$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION );
+$objValidation->setAllowBlank(false);
+$objValidation->setShowInputMessage(true);
+$objValidation->setShowErrorMessage(true);
+$objValidation->setShowDropDown(true);
+$objValidation->setErrorTitle('Input error');
+$objValidation->setError('Value is not in list.');
+$objValidation->setPromptTitle('Pick from list');
+$objValidation->setPrompt('Please pick a value from the drop-down list.');
+$objValidation->setFormula1('"Item A,Item B,Item C"'); // Make sure to put the list items between " and " !!!
+
+$objValidation = $objPHPExcel->getActiveSheet()->getCell('B7')->getDataValidation();
+$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST );
+$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION );
+$objValidation->setAllowBlank(false);
+$objValidation->setShowInputMessage(true);
+$objValidation->setShowErrorMessage(true);
+$objValidation->setShowDropDown(true);
+$objValidation->setErrorTitle('Input error');
+$objValidation->setError('Value is not in list.');
+$objValidation->setPromptTitle('Pick from list');
+$objValidation->setPrompt('Please pick a value from the drop-down list.');
+$objValidation->setFormula1('$D$2:$D$6'); // Make sure NOT to put a range of cells or a formula between " and " !!!
+
+$objValidation = $objPHPExcel->getActiveSheet()->getCell('B9')->getDataValidation();
+$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH );
+$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_STOP );
+$objValidation->setAllowBlank(true);
+$objValidation->setShowInputMessage(true);
+$objValidation->setShowErrorMessage(true);
+$objValidation->setErrorTitle('Input error');
+$objValidation->setError('Text exceeds maximum length');
+$objValidation->setPromptTitle('Allowed input');
+$objValidation->setPrompt('Maximum text length is 6 characters.');
+$objValidation->setFormula1(6);
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 95 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/15datavalidation.php b/Server/vendor/phpoffice/phpexcel/Examples/15datavalidation.php
new file mode 100755
index 000000000..132063d8e
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/15datavalidation.php
@@ -0,0 +1,156 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Create a first sheet
+echo date('H:i:s') , " Add data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', "Cell B3 and B5 contain data validation...")
+ ->setCellValue('A3', "Number:")
+ ->setCellValue('B3', "10")
+ ->setCellValue('A5', "List:")
+ ->setCellValue('B5', "Item A")
+ ->setCellValue('A7', "List #2:")
+ ->setCellValue('B7', "Item #2")
+ ->setCellValue('D2', "Item #1")
+ ->setCellValue('D3', "Item #2")
+ ->setCellValue('D4', "Item #3")
+ ->setCellValue('D5', "Item #4")
+ ->setCellValue('D6', "Item #5")
+ ->setCellValue('A9', 'Text:')
+ ;
+
+
+// Set data validation
+echo date('H:i:s') , " Set data validation" , EOL;
+$objValidation = $objPHPExcel->getActiveSheet()->getCell('B3')->getDataValidation();
+$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_WHOLE );
+$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_STOP );
+$objValidation->setAllowBlank(true);
+$objValidation->setShowInputMessage(true);
+$objValidation->setShowErrorMessage(true);
+$objValidation->setErrorTitle('Input error');
+$objValidation->setError('Only numbers between 10 and 20 are allowed!');
+$objValidation->setPromptTitle('Allowed input');
+$objValidation->setPrompt('Only numbers between 10 and 20 are allowed.');
+$objValidation->setFormula1(10);
+$objValidation->setFormula2(20);
+
+$objValidation = $objPHPExcel->getActiveSheet()->getCell('B5')->getDataValidation();
+$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST );
+$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION );
+$objValidation->setAllowBlank(false);
+$objValidation->setShowInputMessage(true);
+$objValidation->setShowErrorMessage(true);
+$objValidation->setShowDropDown(true);
+$objValidation->setErrorTitle('Input error');
+$objValidation->setError('Value is not in list.');
+$objValidation->setPromptTitle('Pick from list');
+$objValidation->setPrompt('Please pick a value from the drop-down list.');
+$objValidation->setFormula1('"Item A,Item B,Item C"'); // Make sure to put the list items between " and " if your list is simply a comma-separated list of values !!!
+
+
+$objValidation = $objPHPExcel->getActiveSheet()->getCell('B7')->getDataValidation();
+$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST );
+$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION );
+$objValidation->setAllowBlank(false);
+$objValidation->setShowInputMessage(true);
+$objValidation->setShowErrorMessage(true);
+$objValidation->setShowDropDown(true);
+$objValidation->setErrorTitle('Input error');
+$objValidation->setError('Value is not in list.');
+$objValidation->setPromptTitle('Pick from list');
+$objValidation->setPrompt('Please pick a value from the drop-down list.');
+$objValidation->setFormula1('$D$2:$D$6'); // Make sure NOT to put a range of cells or a formula between " and " !!!
+
+$objValidation = $objPHPExcel->getActiveSheet()->getCell('B9')->getDataValidation();
+$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH );
+$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_STOP );
+$objValidation->setAllowBlank(true);
+$objValidation->setShowInputMessage(true);
+$objValidation->setShowErrorMessage(true);
+$objValidation->setErrorTitle('Input error');
+$objValidation->setError('Text exceeds maximum length');
+$objValidation->setPromptTitle('Allowed input');
+$objValidation->setPrompt('Maximum text length is 6 characters.');
+$objValidation->setFormula1(6);
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/16csv.php b/Server/vendor/phpoffice/phpexcel/Examples/16csv.php
new file mode 100755
index 000000000..8d42fcbba
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/16csv.php
@@ -0,0 +1,105 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+include "05featuredemo.inc.php";
+
+/** PHPExcel_IOFactory */
+require_once '../Classes/PHPExcel/IOFactory.php';
+
+
+echo date('H:i:s') , " Write to CSV format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV')->setDelimiter(',')
+ ->setEnclosure('"')
+ ->setSheetIndex(0)
+ ->save(str_replace('.php', '.csv', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+echo date('H:i:s') , " File written to " , str_replace('.php', '.csv', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+echo date('H:i:s') , " Read from CSV format" , EOL;
+$callStartTime = microtime(true);
+$objReader = PHPExcel_IOFactory::createReader('CSV')->setDelimiter(',')
+ ->setEnclosure('"')
+ ->setSheetIndex(0);
+$objPHPExcelFromCSV = $objReader->load(str_replace('.php', '.csv', __FILE__));
+
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+echo 'Call time to reload Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter2007 = PHPExcel_IOFactory::createWriter($objPHPExcelFromCSV, 'Excel2007');
+$objWriter2007->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+echo date('H:i:s') , " Write to CSV format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriterCSV = PHPExcel_IOFactory::createWriter($objPHPExcelFromCSV, 'CSV');
+$objWriterCSV->setExcelCompatibility(true);
+$objWriterCSV->save(str_replace('.php', '_excel.csv', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+echo date('H:i:s') , " File written to " , str_replace('.php', '_excel.csv', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing files" , EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/17html.php b/Server/vendor/phpoffice/phpexcel/Examples/17html.php
new file mode 100755
index 000000000..b84f8d4ed
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/17html.php
@@ -0,0 +1,64 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+include "05featuredemo.inc.php";
+
+/** PHPExcel_IOFactory */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';
+
+
+echo date('H:i:s') , " Write to HTML format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'HTML');
+$objWriter->setSheetIndex(0);
+//$objWriter->setImagesRoot('http://www.example.com');
+$objWriter->save(str_replace('.php', '.htm', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+echo date('H:i:s') , " File written to " , str_replace('.php', '.htm', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/18extendedcalculation.php b/Server/vendor/phpoffice/phpexcel/Examples/18extendedcalculation.php
new file mode 100755
index 000000000..59aeb3005
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/18extendedcalculation.php
@@ -0,0 +1,108 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// List functions
+echo date('H:i:s') . " List implemented functions\n";
+$objCalc = PHPExcel_Calculation::getInstance();
+print_r($objCalc->listFunctionNames());
+
+// Create new PHPExcel object
+echo date('H:i:s') . " Create new PHPExcel object\n";
+$objPHPExcel = new PHPExcel();
+
+// Add some data, we will use some formulas here
+echo date('H:i:s') . " Add some data\n";
+$objPHPExcel->getActiveSheet()->setCellValue('A14', 'Count:');
+
+$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Range 1');
+$objPHPExcel->getActiveSheet()->setCellValue('B2', 2);
+$objPHPExcel->getActiveSheet()->setCellValue('B3', 8);
+$objPHPExcel->getActiveSheet()->setCellValue('B4', 10);
+$objPHPExcel->getActiveSheet()->setCellValue('B5', True);
+$objPHPExcel->getActiveSheet()->setCellValue('B6', False);
+$objPHPExcel->getActiveSheet()->setCellValue('B7', 'Text String');
+$objPHPExcel->getActiveSheet()->setCellValue('B9', '22');
+$objPHPExcel->getActiveSheet()->setCellValue('B10', 4);
+$objPHPExcel->getActiveSheet()->setCellValue('B11', 6);
+$objPHPExcel->getActiveSheet()->setCellValue('B12', 12);
+
+$objPHPExcel->getActiveSheet()->setCellValue('B14', '=COUNT(B2:B12)');
+
+$objPHPExcel->getActiveSheet()->setCellValue('C1', 'Range 2');
+$objPHPExcel->getActiveSheet()->setCellValue('C2', 1);
+$objPHPExcel->getActiveSheet()->setCellValue('C3', 2);
+$objPHPExcel->getActiveSheet()->setCellValue('C4', 2);
+$objPHPExcel->getActiveSheet()->setCellValue('C5', 3);
+$objPHPExcel->getActiveSheet()->setCellValue('C6', 3);
+$objPHPExcel->getActiveSheet()->setCellValue('C7', 3);
+$objPHPExcel->getActiveSheet()->setCellValue('C8', '0');
+$objPHPExcel->getActiveSheet()->setCellValue('C9', 4);
+$objPHPExcel->getActiveSheet()->setCellValue('C10', 4);
+$objPHPExcel->getActiveSheet()->setCellValue('C11', 4);
+$objPHPExcel->getActiveSheet()->setCellValue('C12', 4);
+
+$objPHPExcel->getActiveSheet()->setCellValue('C14', '=COUNT(C2:C12)');
+
+$objPHPExcel->getActiveSheet()->setCellValue('D1', 'Range 3');
+$objPHPExcel->getActiveSheet()->setCellValue('D2', 2);
+$objPHPExcel->getActiveSheet()->setCellValue('D3', 3);
+$objPHPExcel->getActiveSheet()->setCellValue('D4', 4);
+
+$objPHPExcel->getActiveSheet()->setCellValue('D5', '=((D2 * D3) + D4) & " should be 10"');
+
+$objPHPExcel->getActiveSheet()->setCellValue('E1', 'Other functions');
+$objPHPExcel->getActiveSheet()->setCellValue('E2', '=PI()');
+$objPHPExcel->getActiveSheet()->setCellValue('E3', '=RAND()');
+$objPHPExcel->getActiveSheet()->setCellValue('E4', '=RANDBETWEEN(5, 10)');
+
+$objPHPExcel->getActiveSheet()->setCellValue('E14', 'Count of both ranges:');
+$objPHPExcel->getActiveSheet()->setCellValue('F14', '=COUNT(B2:C12)');
+
+// Calculated data
+echo date('H:i:s') . " Calculated data\n";
+echo 'Value of B14 [=COUNT(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B14')->getCalculatedValue() . "\r\n";
+
+
+// Echo memory peak usage
+echo date('H:i:s') . " Peak memory usage: " . (memory_get_peak_usage(true) / 1024 / 1024) . " MB\r\n";
+
+// Echo done
+echo date('H:i:s') . " Done" , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/19namedrange.php b/Server/vendor/phpoffice/phpexcel/Examples/19namedrange.php
new file mode 100755
index 000000000..7876ea58b
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/19namedrange.php
@@ -0,0 +1,129 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Add some data
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Firstname:')
+ ->setCellValue('A2', 'Lastname:')
+ ->setCellValue('A3', 'Fullname:')
+ ->setCellValue('B1', 'Maarten')
+ ->setCellValue('B2', 'Balliauw')
+ ->setCellValue('B3', '=B1 & " " & B2');
+
+// Define named ranges
+echo date('H:i:s') , " Define named ranges" , EOL;
+$objPHPExcel->addNamedRange( new PHPExcel_NamedRange('PersonName', $objPHPExcel->getActiveSheet(), 'B1') );
+$objPHPExcel->addNamedRange( new PHPExcel_NamedRange('PersonLN', $objPHPExcel->getActiveSheet(), 'B2') );
+
+// Rename named ranges
+echo date('H:i:s') , " Rename named ranges" , EOL;
+$objPHPExcel->getNamedRange('PersonName')->setName('PersonFN');
+
+// Rename worksheet
+echo date('H:i:s') , " Rename worksheet" , EOL;
+$objPHPExcel->getActiveSheet()->setTitle('Person');
+
+
+// Create a new worksheet, after the default sheet
+echo date('H:i:s') , " Create new Worksheet object" , EOL;
+$objPHPExcel->createSheet();
+
+// Add some data to the second sheet, resembling some different data types
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->setActiveSheetIndex(1);
+$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Firstname:')
+ ->setCellValue('A2', 'Lastname:')
+ ->setCellValue('A3', 'Fullname:')
+ ->setCellValue('B1', '=PersonFN')
+ ->setCellValue('B2', '=PersonLN')
+ ->setCellValue('B3', '=PersonFN & " " & PersonLN');
+
+// Resolve range
+echo date('H:i:s') , " Resolve range" , EOL;
+echo 'Cell B1 {=PersonFN}: ' , $objPHPExcel->getActiveSheet()->getCell('B1')->getCalculatedValue() , EOL;
+echo 'Cell B3 {=PersonFN & " " & PersonLN}: ' , $objPHPExcel->getActiveSheet()->getCell('B3')->getCalculatedValue() , EOL;
+echo 'Cell Person!B1: ' , $objPHPExcel->getActiveSheet()->getCell('Person!B1')->getCalculatedValue() , EOL;
+
+// Rename worksheet
+echo date('H:i:s') , " Rename worksheet" , EOL;
+$objPHPExcel->getActiveSheet()->setTitle('Person (cloned)');
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/20readexcel5.php b/Server/vendor/phpoffice/phpexcel/Examples/20readexcel5.php
new file mode 100755
index 000000000..e26fe7e2e
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/20readexcel5.php
@@ -0,0 +1,79 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel_IOFactory */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';
+
+
+if (!file_exists("14excel5.xls")) {
+ exit("Please run 14excel5.php first.\n");
+}
+
+echo date('H:i:s') , " Load workbook from Excel5 file" , EOL;
+$callStartTime = microtime(true);
+
+$objPHPExcel = PHPExcel_IOFactory::load("14excel5.xls");
+
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo 'Call time to load Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done reading file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/21pdf.php b/Server/vendor/phpoffice/phpexcel/Examples/21pdf.php
new file mode 100755
index 000000000..b26ddb8b1
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/21pdf.php
@@ -0,0 +1,94 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+include "05featuredemo.inc.php";
+
+/** PHPExcel_IOFactory */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';
+
+
+// Change these values to select the Rendering library that you wish to use
+// and its directory location on your server
+//$rendererName = PHPExcel_Settings::PDF_RENDERER_TCPDF;
+//$rendererName = PHPExcel_Settings::PDF_RENDERER_MPDF;
+$rendererName = PHPExcel_Settings::PDF_RENDERER_DOMPDF;
+//$rendererLibrary = 'tcPDF5.9';
+//$rendererLibrary = 'mPDF5.4';
+$rendererLibrary = 'domPDF0.6.0beta3';
+$rendererLibraryPath = '/php/libraries/PDF/' . $rendererLibrary;
+
+
+echo date('H:i:s') , " Hide grid lines" , EOL;
+$objPHPExcel->getActiveSheet()->setShowGridLines(false);
+
+echo date('H:i:s') , " Set orientation to landscape" , EOL;
+$objPHPExcel->getActiveSheet()->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE);
+
+
+echo date('H:i:s') , " Write to PDF format using {$rendererName}" , EOL;
+
+if (!PHPExcel_Settings::setPdfRenderer(
+ $rendererName,
+ $rendererLibraryPath
+ )) {
+ die(
+ 'NOTICE: Please set the $rendererName and $rendererLibraryPath values' .
+ EOL .
+ 'at the top of this script as appropriate for your directory structure'
+ );
+}
+
+
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'PDF');
+$objWriter->setSheetIndex(0);
+$objWriter->save(str_replace('.php', '_'.$rendererName.'.pdf', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+echo date('H:i:s') , " File written to " , str_replace('.php', '_'.$rendererName.'.pdf', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing files" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/22heavilyformatted.php b/Server/vendor/phpoffice/phpexcel/Examples/22heavilyformatted.php
new file mode 100755
index 000000000..98c7d184e
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/22heavilyformatted.php
@@ -0,0 +1,116 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Add some data
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+
+$objPHPExcel->getActiveSheet()->getStyle('A1:T100')->applyFromArray(
+ array('fill' => array(
+ 'type' => PHPExcel_Style_Fill::FILL_SOLID,
+ 'color' => array('argb' => 'FFCCFFCC')
+ ),
+ 'borders' => array(
+ 'bottom' => array('style' => PHPExcel_Style_Border::BORDER_THIN),
+ 'right' => array('style' => PHPExcel_Style_Border::BORDER_MEDIUM)
+ )
+ )
+ );
+
+$objPHPExcel->getActiveSheet()->getStyle('C5:R95')->applyFromArray(
+ array('fill' => array(
+ 'type' => PHPExcel_Style_Fill::FILL_SOLID,
+ 'color' => array('argb' => 'FFFFFF00')
+ ),
+ )
+ );
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Save Excel 95 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/23sharedstyles.php b/Server/vendor/phpoffice/phpexcel/Examples/23sharedstyles.php
new file mode 100755
index 000000000..22eadba1c
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/23sharedstyles.php
@@ -0,0 +1,124 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+
+// Add some data
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0);
+
+$sharedStyle1 = new PHPExcel_Style();
+$sharedStyle2 = new PHPExcel_Style();
+
+$sharedStyle1->applyFromArray(
+ array('fill' => array(
+ 'type' => PHPExcel_Style_Fill::FILL_SOLID,
+ 'color' => array('argb' => 'FFCCFFCC')
+ ),
+ 'borders' => array(
+ 'bottom' => array('style' => PHPExcel_Style_Border::BORDER_THIN),
+ 'right' => array('style' => PHPExcel_Style_Border::BORDER_MEDIUM)
+ )
+ ));
+
+$sharedStyle2->applyFromArray(
+ array('fill' => array(
+ 'type' => PHPExcel_Style_Fill::FILL_SOLID,
+ 'color' => array('argb' => 'FFFFFF00')
+ ),
+ 'borders' => array(
+ 'bottom' => array('style' => PHPExcel_Style_Border::BORDER_THIN),
+ 'right' => array('style' => PHPExcel_Style_Border::BORDER_MEDIUM)
+ )
+ ));
+
+$objPHPExcel->getActiveSheet()->setSharedStyle($sharedStyle1, "A1:T100");
+$objPHPExcel->getActiveSheet()->setSharedStyle($sharedStyle2, "C5:R95");
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Save Excel 95 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/24readfilter.php b/Server/vendor/phpoffice/phpexcel/Examples/24readfilter.php
new file mode 100755
index 000000000..000d180a4
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/24readfilter.php
@@ -0,0 +1,77 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** PHPExcel_IOFactory */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';
+
+
+// Check prerequisites
+if (!file_exists("06largescale.xlsx")) {
+ exit("Please run 06largescale.php first.\n");
+}
+
+class MyReadFilter implements PHPExcel_Reader_IReadFilter
+{
+ public function readCell($column, $row, $worksheetName = '') {
+ // Read title row and rows 20 - 30
+ if ($row == 1 || ($row >= 20 && $row <= 30)) {
+ return true;
+ }
+
+ return false;
+ }
+}
+
+
+echo date('H:i:s') , " Load from Excel2007 file" , EOL;
+$objReader = PHPExcel_IOFactory::createReader('Excel2007');
+$objReader->setReadFilter( new MyReadFilter() );
+$objPHPExcel = $objReader->load("06largescale.xlsx");
+
+echo date('H:i:s') , " Remove unnecessary rows" , EOL;
+$objPHPExcel->getActiveSheet()->removeRow(2, 18);
+
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/25inmemoryimage.php b/Server/vendor/phpoffice/phpexcel/Examples/25inmemoryimage.php
new file mode 100755
index 000000000..6c3b0b845
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/25inmemoryimage.php
@@ -0,0 +1,89 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+// Generate an image
+echo date('H:i:s') , " Generate an image" , EOL;
+$gdImage = @imagecreatetruecolor(120, 20) or die('Cannot Initialize new GD image stream');
+$textColor = imagecolorallocate($gdImage, 255, 255, 255);
+imagestring($gdImage, 1, 5, 5, 'Created with PHPExcel', $textColor);
+
+// Add a drawing to the worksheet
+echo date('H:i:s') , " Add a drawing to the worksheet" , EOL;
+$objDrawing = new PHPExcel_Worksheet_MemoryDrawing();
+$objDrawing->setName('Sample image');
+$objDrawing->setDescription('Sample image');
+$objDrawing->setImageResource($gdImage);
+$objDrawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG);
+$objDrawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT);
+$objDrawing->setHeight(36);
+$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());
+
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+echo date('H:i:s') , " Write to HTML format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'HTML');
+$objWriter->save(str_replace('.php', '.html', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.html', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/26utf8.php b/Server/vendor/phpoffice/phpexcel/Examples/26utf8.php
new file mode 100755
index 000000000..112c5c73f
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/26utf8.php
@@ -0,0 +1,122 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Change these values to select the PDF Rendering library that you wish to use
+// and its directory location on your server
+//$rendererName = PHPExcel_Settings::PDF_RENDERER_TCPDF;
+//$rendererName = PHPExcel_Settings::PDF_RENDERER_MPDF;
+$rendererName = PHPExcel_Settings::PDF_RENDERER_DOMPDF;
+//$rendererLibrary = 'tcPDF5.9';
+//$rendererLibrary = 'mPDF5.4';
+$rendererLibrary = 'domPDF0.6.0beta3';
+$rendererLibraryPath = '/php/libraries/PDF/' . $rendererLibrary;
+
+
+// Read from Excel2007 (.xlsx) template
+echo date('H:i:s') , " Load Excel2007 template file" , EOL;
+$objReader = PHPExcel_IOFactory::createReader('Excel2007');
+$objPHPExcel = $objReader->load("templates/26template.xlsx");
+
+/** at this point, we could do some manipulations with the template, but we skip this step */
+
+// Export to Excel2007 (.xlsx)
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+// Export to Excel5 (.xls)
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+// Export to HTML (.html)
+echo date('H:i:s') , " Write to HTML format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'HTML');
+$objWriter->save(str_replace('.php', '.htm', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.htm', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+// Export to PDF (.pdf)
+echo date('H:i:s') , " Write to PDF format" , EOL;
+try {
+ if (!PHPExcel_Settings::setPdfRenderer(
+ $rendererName,
+ $rendererLibraryPath
+ )) {
+ echo (
+ 'NOTICE: Please set the $rendererName and $rendererLibraryPath values' .
+ EOL .
+ 'at the top of this script as appropriate for your directory structure' .
+ EOL
+ );
+ } else {
+ $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'PDF');
+ $objWriter->save(str_replace('.php', '.pdf', __FILE__));
+ echo date('H:i:s') , " File written to " , str_replace('.php', '.pdf', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+ }
+} catch (Exception $e) {
+ echo date('H:i:s') , ' EXCEPTION: ', $e->getMessage() , EOL;
+}
+
+// Remove first two rows with field headers before exporting to CSV
+echo date('H:i:s') , " Removing first two heading rows for CSV export" , EOL;
+$objWorksheet = $objPHPExcel->getActiveSheet();
+$objWorksheet->removeRow(1, 2);
+
+// Export to CSV (.csv)
+echo date('H:i:s') , " Write to CSV format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV');
+$objWriter->save(str_replace('.php', '.csv', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.csv', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+// Export to CSV with BOM (.csv)
+echo date('H:i:s') , " Write to CSV format (with BOM)" , EOL;
+$objWriter->setUseBOM(true);
+$objWriter->save(str_replace('.php', '-bom.csv', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '-bom.csv', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing files" , EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/27imagesexcel5.php b/Server/vendor/phpoffice/phpexcel/Examples/27imagesexcel5.php
new file mode 100755
index 000000000..a4f6a9d7d
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/27imagesexcel5.php
@@ -0,0 +1,64 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Read from Excel5 (.xls) template
+echo date('H:i:s') , " Load Excel2007 template file" , EOL;
+$objReader = PHPExcel_IOFactory::createReader('Excel5');
+$objPHPExcel = $objReader->load("templates/27template.xls");
+
+// Export to Excel2007 (.xlsx)
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+// Export to Excel5 (.xls)
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing files" , EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/28iterator.php b/Server/vendor/phpoffice/phpexcel/Examples/28iterator.php
new file mode 100755
index 000000000..1ba9cbee0
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/28iterator.php
@@ -0,0 +1,82 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** PHPExcel_IOFactory */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';
+
+
+echo date('H:i:s') , " Load from Excel2007 file" , EOL;
+$objReader = PHPExcel_IOFactory::createReader('Excel2007');
+$objPHPExcel = $objReader->load("./templates/28iterators.xlsx");
+
+echo date('H:i:s') , " Iterate worksheets by Row" , EOL;
+foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
+ echo 'Worksheet - ' , $worksheet->getTitle() , EOL;
+
+ foreach ($worksheet->getRowIterator() as $row) {
+ echo ' Row number - ' , $row->getRowIndex() , EOL;
+
+ $cellIterator = $row->getCellIterator();
+ $cellIterator->setIterateOnlyExistingCells(false); // Loop all cells, even if it is not set
+ foreach ($cellIterator as $cell) {
+ if (!is_null($cell)) {
+ echo ' Cell - ' , $cell->getCoordinate() , ' - ' , $cell->getCalculatedValue() , EOL;
+ }
+ }
+ }
+}
+
+
+echo date('H:i:s') , " Iterate worksheets by Column" , EOL;
+foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
+ echo 'Worksheet - ' , $worksheet->getTitle() , EOL;
+
+ foreach ($worksheet->getColumnIterator() as $column) {
+ echo ' Column index - ' , $column->getColumnIndex() , EOL;
+
+ $cellIterator = $column->getCellIterator();
+ $cellIterator->setIterateOnlyExistingCells(true); // Loop all cells, even if it is not set
+ foreach ($cellIterator as $cell) {
+ if (!is_null($cell)) {
+ echo ' Cell - ' , $cell->getCoordinate() , ' - ' , $cell->getCalculatedValue() , EOL;
+ }
+ }
+ }
+}
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/29advancedvaluebinder.php b/Server/vendor/phpoffice/phpexcel/Examples/29advancedvaluebinder.php
new file mode 100755
index 000000000..a172c6cde
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/29advancedvaluebinder.php
@@ -0,0 +1,183 @@
+');
+
+/** PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Set timezone
+echo date('H:i:s') , " Set timezone" , EOL;
+date_default_timezone_set('UTC');
+
+// Set value binder
+echo date('H:i:s') , " Set value binder" , EOL;
+PHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() );
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
+ ->setKeywords("office 2007 openxml php")
+ ->setCategory("Test result file");
+
+// Set default font
+echo date('H:i:s') , " Set default font" , EOL;
+$objPHPExcel->getActiveSheet()->getDefaultStyle()->getFont()->setName('Arial');
+$objPHPExcel->getActiveSheet()->getDefaultStyle()->getFont()->setSize(10);
+
+// Set column widths
+echo date('H:i:s') , " Set column widths" , EOL;
+$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setAutoSize(true);
+$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(14);
+
+// Add some data, resembling some different data types
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->getActiveSheet()->setCellValue('A1', 'String value:')
+ ->setCellValue('B1', 'Mark Baker');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A2', 'Numeric value #1:')
+ ->setCellValue('B2', 12345);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A3', 'Numeric value #2:')
+ ->setCellValue('B3', -12.345);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Numeric value #3:')
+ ->setCellValue('B4', .12345);
+
+$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Numeric value #4:')
+ ->setCellValue('B5', '12345');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A6', 'Numeric value #5:')
+ ->setCellValue('B6', '1.2345');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A7', 'Numeric value #6:')
+ ->setCellValue('B7', '.12345');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A8', 'Numeric value #7:')
+ ->setCellValue('B8', '1.234e-5');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A9', 'Numeric value #8:')
+ ->setCellValue('B9', '-1.234e+5');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A10', 'Boolean value:')
+ ->setCellValue('B10', 'TRUE');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A11', 'Percentage value #1:')
+ ->setCellValue('B11', '10%');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A12', 'Percentage value #2:')
+ ->setCellValue('B12', '12.5%');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A13', 'Fraction value #1:')
+ ->setCellValue('B13', '-1/2');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A14', 'Fraction value #2:')
+ ->setCellValue('B14', '3 1/2');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A15', 'Fraction value #3:')
+ ->setCellValue('B15', '-12 3/4');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A16', 'Fraction value #4:')
+ ->setCellValue('B16', '13/4');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A17', 'Currency value #1:')
+ ->setCellValue('B17', '$12345');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A18', 'Currency value #2:')
+ ->setCellValue('B18', '$12345.67');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A19', 'Currency value #3:')
+ ->setCellValue('B19', '$12,345.67');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A20', 'Date value #1:')
+ ->setCellValue('B20', '21 December 1983');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A21', 'Date value #2:')
+ ->setCellValue('B21', '19-Dec-1960');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A22', 'Date value #3:')
+ ->setCellValue('B22', '07/12/1982');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A23', 'Date value #4:')
+ ->setCellValue('B23', '24-11-1950');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A24', 'Date value #5:')
+ ->setCellValue('B24', '17-Mar');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A25', 'Time value #1:')
+ ->setCellValue('B25', '01:30');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A26', 'Time value #2:')
+ ->setCellValue('B26', '01:30:15');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A27', 'Date/Time value:')
+ ->setCellValue('B27', '19-Dec-1960 01:30');
+
+$objPHPExcel->getActiveSheet()->setCellValue('A28', 'Formula:')
+ ->setCellValue('B28', '=SUM(B2:B9)');
+
+// Rename worksheet
+echo date('H:i:s') , " Rename worksheet" , EOL;
+$objPHPExcel->getActiveSheet()->setTitle('Advanced value binder');
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+// Save Excel5 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/30template.php b/Server/vendor/phpoffice/phpexcel/Examples/30template.php
new file mode 100755
index 000000000..1d9847a30
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/30template.php
@@ -0,0 +1,91 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** PHPExcel_IOFactory */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';
+
+
+
+echo date('H:i:s') , " Load from Excel5 template" , EOL;
+$objReader = PHPExcel_IOFactory::createReader('Excel5');
+$objPHPExcel = $objReader->load("templates/30template.xls");
+
+
+
+
+echo date('H:i:s') , " Add new data to the template" , EOL;
+$data = array(array('title' => 'Excel for dummies',
+ 'price' => 17.99,
+ 'quantity' => 2
+ ),
+ array('title' => 'PHP for dummies',
+ 'price' => 15.99,
+ 'quantity' => 1
+ ),
+ array('title' => 'Inside OOP',
+ 'price' => 12.95,
+ 'quantity' => 1
+ )
+ );
+
+$objPHPExcel->getActiveSheet()->setCellValue('D1', PHPExcel_Shared_Date::PHPToExcel(time()));
+
+$baseRow = 5;
+foreach($data as $r => $dataRow) {
+ $row = $baseRow + $r;
+ $objPHPExcel->getActiveSheet()->insertNewRowBefore($row,1);
+
+ $objPHPExcel->getActiveSheet()->setCellValue('A'.$row, $r+1)
+ ->setCellValue('B'.$row, $dataRow['title'])
+ ->setCellValue('C'.$row, $dataRow['price'])
+ ->setCellValue('D'.$row, $dataRow['quantity'])
+ ->setCellValue('E'.$row, '=C'.$row.'*D'.$row);
+}
+$objPHPExcel->getActiveSheet()->removeRow($baseRow-1,1);
+
+
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/31docproperties_write-xls.php b/Server/vendor/phpoffice/phpexcel/Examples/31docproperties_write-xls.php
new file mode 100755
index 000000000..449486792
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/31docproperties_write-xls.php
@@ -0,0 +1,119 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+$inputFileType = 'Excel5';
+$inputFileName = 'templates/31docproperties.xls';
+
+
+echo date('H:i:s') , " Load Tests from $inputFileType file" , EOL;
+$callStartTime = microtime(true);
+
+$objPHPExcelReader = PHPExcel_IOFactory::createReader($inputFileType);
+$objPHPExcel = $objPHPExcelReader->load($inputFileName);
+
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+echo 'Call time to read Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+echo date('H:i:s') , " Adjust properties" , EOL;
+$objPHPExcel->getProperties()->setTitle("Office 95 XLS Test Document")
+ ->setSubject("Office 95 XLS Test Document")
+ ->setDescription("Test XLS document, generated using PHPExcel")
+ ->setKeywords("office 95 biff php");
+
+
+// Save Excel 95 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " . (memory_get_peak_usage(true) / 1024 / 1024) . " MB" , EOL;
+
+
+echo EOL;
+// Reread File
+echo date('H:i:s') , " Reread Excel5 file" , EOL;
+$objPHPExcelRead = PHPExcel_IOFactory::load(str_replace('.php', '.xls', __FILE__));
+
+// Set properties
+echo date('H:i:s') , " Get properties" , EOL;
+
+echo 'Core Properties:' , EOL;
+echo ' Created by - ' , $objPHPExcel->getProperties()->getCreator() , EOL;
+echo ' Created on - ' , date('d-M-Y',$objPHPExcel->getProperties()->getCreated()) , ' at ' ,
+ date('H:i:s',$objPHPExcel->getProperties()->getCreated()) , EOL;
+echo ' Last Modified by - ' , $objPHPExcel->getProperties()->getLastModifiedBy() , EOL;
+echo ' Last Modified on - ' , date('d-M-Y',$objPHPExcel->getProperties()->getModified()) , ' at ' ,
+ date('H:i:s',$objPHPExcel->getProperties()->getModified()) , EOL;
+echo ' Title - ' , $objPHPExcel->getProperties()->getTitle() , EOL;
+echo ' Subject - ' , $objPHPExcel->getProperties()->getSubject() , EOL;
+echo ' Description - ' , $objPHPExcel->getProperties()->getDescription() , EOL;
+echo ' Keywords: - ' , $objPHPExcel->getProperties()->getKeywords() , EOL;
+
+
+echo 'Extended (Application) Properties:' , EOL;
+echo ' Category - ' , $objPHPExcel->getProperties()->getCategory() , EOL;
+echo ' Company - ' , $objPHPExcel->getProperties()->getCompany() , EOL;
+echo ' Manager - ' , $objPHPExcel->getProperties()->getManager() , EOL;
+
+
+echo 'Custom Properties:' , EOL;
+$customProperties = $objPHPExcel->getProperties()->getCustomProperties();
+foreach($customProperties as $customProperty) {
+ $propertyValue = $objPHPExcel->getProperties()->getCustomPropertyValue($customProperty);
+ $propertyType = $objPHPExcel->getProperties()->getCustomPropertyType($customProperty);
+ echo ' ' , $customProperty , ' - (' , $propertyType , ') - ';
+ if ($propertyType == PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE) {
+ echo date('d-M-Y H:i:s',$propertyValue) , EOL;
+ } elseif ($propertyType == PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN) {
+ echo (($propertyValue) ? 'TRUE' : 'FALSE') , EOL;
+ } else {
+ echo $propertyValue , EOL;
+ }
+}
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) . " MB" , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/31docproperties_write.php b/Server/vendor/phpoffice/phpexcel/Examples/31docproperties_write.php
new file mode 100755
index 000000000..a7c496aa0
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/31docproperties_write.php
@@ -0,0 +1,119 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+$inputFileType = 'Excel2007';
+$inputFileName = 'templates/31docproperties.xlsx';
+
+
+echo date('H:i:s') , " Load Tests from $inputFileType file" , EOL;
+$callStartTime = microtime(true);
+
+$objPHPExcelReader = PHPExcel_IOFactory::createReader($inputFileType);
+$objPHPExcel = $objPHPExcelReader->load($inputFileName);
+
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+echo 'Call time to read Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+echo date('H:i:s') , " Adjust properties" , EOL;
+$objPHPExcel->getProperties()->setTitle("Office 2007 XLSX Test Document")
+ ->setSubject("Office 2007 XLSX Test Document")
+ ->setDescription("Test XLSX document, generated using PHPExcel")
+ ->setKeywords("office 2007 openxml php");
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " . (memory_get_peak_usage(true) / 1024 / 1024) . " MB" , EOL;
+
+
+echo EOL;
+// Reread File
+echo date('H:i:s') , " Reread Excel2007 file" , EOL;
+$objPHPExcelRead = PHPExcel_IOFactory::load(str_replace('.php', '.xlsx', __FILE__));
+
+// Set properties
+echo date('H:i:s') , " Get properties" , EOL;
+
+echo 'Core Properties:' , EOL;
+echo ' Created by - ' , $objPHPExcel->getProperties()->getCreator() , EOL;
+echo ' Created on - ' , date('d-M-Y',$objPHPExcel->getProperties()->getCreated()) , ' at ' ,
+ date('H:i:s',$objPHPExcel->getProperties()->getCreated()) , EOL;
+echo ' Last Modified by - ' , $objPHPExcel->getProperties()->getLastModifiedBy() , EOL;
+echo ' Last Modified on - ' , date('d-M-Y',$objPHPExcel->getProperties()->getModified()) , ' at ' ,
+ date('H:i:s',$objPHPExcel->getProperties()->getModified()) , EOL;
+echo ' Title - ' , $objPHPExcel->getProperties()->getTitle() , EOL;
+echo ' Subject - ' , $objPHPExcel->getProperties()->getSubject() , EOL;
+echo ' Description - ' , $objPHPExcel->getProperties()->getDescription() , EOL;
+echo ' Keywords: - ' , $objPHPExcel->getProperties()->getKeywords() , EOL;
+
+
+echo 'Extended (Application) Properties:' , EOL;
+echo ' Category - ' , $objPHPExcel->getProperties()->getCategory() , EOL;
+echo ' Company - ' , $objPHPExcel->getProperties()->getCompany() , EOL;
+echo ' Manager - ' , $objPHPExcel->getProperties()->getManager() , EOL;
+
+
+echo 'Custom Properties:' , EOL;
+$customProperties = $objPHPExcel->getProperties()->getCustomProperties();
+foreach($customProperties as $customProperty) {
+ $propertyValue = $objPHPExcel->getProperties()->getCustomPropertyValue($customProperty);
+ $propertyType = $objPHPExcel->getProperties()->getCustomPropertyType($customProperty);
+ echo ' ' , $customProperty , ' - (' , $propertyType , ') - ';
+ if ($propertyType == PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE) {
+ echo date('d-M-Y H:i:s',$propertyValue) , EOL;
+ } elseif ($propertyType == PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN) {
+ echo (($propertyValue) ? 'TRUE' : 'FALSE') , EOL;
+ } else {
+ echo $propertyValue , EOL;
+ }
+}
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) . " MB" , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/32chartreadwrite.php b/Server/vendor/phpoffice/phpexcel/Examples/32chartreadwrite.php
new file mode 100755
index 000000000..55521ec10
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/32chartreadwrite.php
@@ -0,0 +1,131 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/**
+ * PHPExcel
+ *
+ * Copyright (c) 2006 - 2015 PHPExcel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * @category PHPExcel
+ * @package PHPExcel
+ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
+ * @version ##VERSION##, ##DATE##
+ */
+
+/** Include path **/
+set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/../Classes/');
+
+/** PHPExcel_IOFactory */
+include 'PHPExcel/IOFactory.php';
+
+$inputFileType = 'Excel2007';
+$inputFileNames = 'templates/32readwrite*[0-9].xlsx';
+
+if ((isset($argc)) && ($argc > 1)) {
+ $inputFileNames = array();
+ for($i = 1; $i < $argc; ++$i) {
+ $inputFileNames[] = dirname(__FILE__) . '/templates/' . $argv[$i];
+ }
+} else {
+ $inputFileNames = glob($inputFileNames);
+}
+foreach($inputFileNames as $inputFileName) {
+ $inputFileNameShort = basename($inputFileName);
+
+ if (!file_exists($inputFileName)) {
+ echo date('H:i:s') , " File " , $inputFileNameShort , ' does not exist' , EOL;
+ continue;
+ }
+
+ echo date('H:i:s') , " Load Test from $inputFileType file " , $inputFileNameShort , EOL;
+
+ $objReader = PHPExcel_IOFactory::createReader($inputFileType);
+ $objReader->setIncludeCharts(TRUE);
+ $objPHPExcel = $objReader->load($inputFileName);
+
+
+ echo date('H:i:s') , " Iterate worksheets looking at the charts" , EOL;
+ foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
+ $sheetName = $worksheet->getTitle();
+ echo 'Worksheet: ' , $sheetName , EOL;
+
+ $chartNames = $worksheet->getChartNames();
+ if(empty($chartNames)) {
+ echo ' There are no charts in this worksheet' , EOL;
+ } else {
+ natsort($chartNames);
+ foreach($chartNames as $i => $chartName) {
+ $chart = $worksheet->getChartByName($chartName);
+ if (!is_null($chart->getTitle())) {
+ $caption = '"' . implode(' ',$chart->getTitle()->getCaption()) . '"';
+ } else {
+ $caption = 'Untitled';
+ }
+ echo ' ' , $chartName , ' - ' , $caption , EOL;
+ echo str_repeat(' ',strlen($chartName)+3);
+ $groupCount = $chart->getPlotArea()->getPlotGroupCount();
+ if ($groupCount == 1) {
+ $chartType = $chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType();
+ echo ' ' , $chartType , EOL;
+ } else {
+ $chartTypes = array();
+ for($i = 0; $i < $groupCount; ++$i) {
+ $chartTypes[] = $chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType();
+ }
+ $chartTypes = array_unique($chartTypes);
+ if (count($chartTypes) == 1) {
+ $chartType = 'Multiple Plot ' . array_pop($chartTypes);
+ echo ' ' , $chartType , EOL;
+ } elseif (count($chartTypes) == 0) {
+ echo ' *** Type not yet implemented' , EOL;
+ } else {
+ echo ' Combination Chart' , EOL;
+ }
+ }
+ }
+ }
+ }
+
+
+ $outputFileName = basename($inputFileName);
+
+ echo date('H:i:s') , " Write Tests to Excel2007 file " , EOL;
+ $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+ $objWriter->setIncludeCharts(TRUE);
+ $objWriter->save($outputFileName);
+ echo date('H:i:s') , " File written to " , $outputFileName , EOL;
+
+ $objPHPExcel->disconnectWorksheets();
+ unset($objPHPExcel);
+}
+
+// Echo memory peak usage
+echo date('H:i:s') , ' Peak memory usage: ' , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing files" , EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-area.php b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-area.php
new file mode 100755
index 000000000..fac8ce93f
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-area.php
@@ -0,0 +1,142 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/**
+ * PHPExcel
+ *
+ * Copyright (c) 2006 - 2015 PHPExcel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * @category PHPExcel
+ * @package PHPExcel
+ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
+ * @version ##VERSION##, ##DATE##
+ */
+
+/** PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+$objPHPExcel = new PHPExcel();
+$objWorksheet = $objPHPExcel->getActiveSheet();
+$objWorksheet->fromArray(
+ array(
+ array('', 2010, 2011, 2012),
+ array('Q1', 12, 15, 21),
+ array('Q2', 56, 73, 86),
+ array('Q3', 52, 61, 69),
+ array('Q4', 30, 32, 0),
+ )
+);
+
+// Set the Labels for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesLabels = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // 2010
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012
+);
+// Set the X-Axis Labels
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$xAxisTickValues = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4), // Q1 to Q4
+);
+// Set the Data values for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesValues = array(
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', NULL, 4),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$5', NULL, 4),
+);
+
+// Build the dataseries
+$series = new PHPExcel_Chart_DataSeries(
+ PHPExcel_Chart_DataSeries::TYPE_AREACHART, // plotType
+ PHPExcel_Chart_DataSeries::GROUPING_PERCENT_STACKED, // plotGrouping
+ range(0, count($dataSeriesValues)-1), // plotOrder
+ $dataSeriesLabels, // plotLabel
+ $xAxisTickValues, // plotCategory
+ $dataSeriesValues // plotValues
+);
+
+// Set the series in the plot area
+$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series));
+// Set the chart legend
+$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_TOPRIGHT, NULL, false);
+
+$title = new PHPExcel_Chart_Title('Test %age-Stacked Area Chart');
+$yAxisLabel = new PHPExcel_Chart_Title('Value ($k)');
+
+
+// Create the chart
+$chart = new PHPExcel_Chart(
+ 'chart1', // name
+ $title, // title
+ $legend, // legend
+ $plotArea, // plotArea
+ true, // plotVisibleOnly
+ 0, // displayBlanksAs
+ NULL, // xAxisLabel
+ $yAxisLabel // yAxisLabel
+);
+
+// Set the position where the chart should appear in the worksheet
+$chart->setTopLeftPosition('A7');
+$chart->setBottomRightPosition('H20');
+
+// Add the chart to the worksheet
+$objWorksheet->addChart($chart);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->setIncludeCharts(TRUE);
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-bar-stacked.php b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-bar-stacked.php
new file mode 100755
index 000000000..af9493f7a
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-bar-stacked.php
@@ -0,0 +1,145 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/**
+ * PHPExcel
+ *
+ * Copyright (c) 2006 - 2015 PHPExcel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * @category PHPExcel
+ * @package PHPExcel
+ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
+ * @version ##VERSION##, ##DATE##
+ */
+
+/** PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+$objPHPExcel = new PHPExcel();
+$objWorksheet = $objPHPExcel->getActiveSheet();
+$objWorksheet->fromArray(
+ array(
+ array('', 2010, 2011, 2012),
+ array('Q1', 12, 15, 21),
+ array('Q2', 56, 73, 86),
+ array('Q3', 52, 61, 69),
+ array('Q4', 30, 32, 0),
+ )
+);
+
+// Set the Labels for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesLabels = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // 2010
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012
+);
+// Set the X-Axis Labels
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$xAxisTickValues = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4), // Q1 to Q4
+);
+// Set the Data values for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesValues = array(
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', NULL, 4),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$5', NULL, 4),
+);
+
+// Build the dataseries
+$series = new PHPExcel_Chart_DataSeries(
+ PHPExcel_Chart_DataSeries::TYPE_BARCHART, // plotType
+ PHPExcel_Chart_DataSeries::GROUPING_STACKED, // plotGrouping
+ range(0, count($dataSeriesValues)-1), // plotOrder
+ $dataSeriesLabels, // plotLabel
+ $xAxisTickValues, // plotCategory
+ $dataSeriesValues // plotValues
+);
+// Set additional dataseries parameters
+// Make it a horizontal bar rather than a vertical column graph
+$series->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_BAR);
+
+// Set the series in the plot area
+$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series));
+// Set the chart legend
+$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false);
+
+$title = new PHPExcel_Chart_Title('Test Chart');
+$yAxisLabel = new PHPExcel_Chart_Title('Value ($k)');
+
+
+// Create the chart
+$chart = new PHPExcel_Chart(
+ 'chart1', // name
+ $title, // title
+ $legend, // legend
+ $plotArea, // plotArea
+ true, // plotVisibleOnly
+ 0, // displayBlanksAs
+ NULL, // xAxisLabel
+ $yAxisLabel // yAxisLabel
+);
+
+// Set the position where the chart should appear in the worksheet
+$chart->setTopLeftPosition('A7');
+$chart->setBottomRightPosition('H20');
+
+// Add the chart to the worksheet
+$objWorksheet->addChart($chart);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->setIncludeCharts(TRUE);
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-bar.php b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-bar.php
new file mode 100755
index 000000000..653675d69
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-bar.php
@@ -0,0 +1,145 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/**
+ * PHPExcel
+ *
+ * Copyright (c) 2006 - 2015 PHPExcel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * @category PHPExcel
+ * @package PHPExcel
+ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
+ * @version ##VERSION##, ##DATE##
+ */
+
+/** PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+$objPHPExcel = new PHPExcel();
+$objWorksheet = $objPHPExcel->getActiveSheet();
+$objWorksheet->fromArray(
+ array(
+ array('', 2010, 2011, 2012),
+ array('Q1', 12, 15, 21),
+ array('Q2', 56, 73, 86),
+ array('Q3', 52, 61, 69),
+ array('Q4', 30, 32, 0),
+ )
+);
+
+// Set the Labels for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesLabels = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // 2010
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012
+);
+// Set the X-Axis Labels
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$xAxisTickValues = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4), // Q1 to Q4
+);
+// Set the Data values for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesValues = array(
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', NULL, 4),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$5', NULL, 4),
+);
+
+// Build the dataseries
+$series = new PHPExcel_Chart_DataSeries(
+ PHPExcel_Chart_DataSeries::TYPE_BARCHART, // plotType
+ PHPExcel_Chart_DataSeries::GROUPING_CLUSTERED, // plotGrouping
+ range(0, count($dataSeriesValues)-1), // plotOrder
+ $dataSeriesLabels, // plotLabel
+ $xAxisTickValues, // plotCategory
+ $dataSeriesValues // plotValues
+);
+// Set additional dataseries parameters
+// Make it a horizontal bar rather than a vertical column graph
+$series->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_BAR);
+
+// Set the series in the plot area
+$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series));
+// Set the chart legend
+$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false);
+
+$title = new PHPExcel_Chart_Title('Test Bar Chart');
+$yAxisLabel = new PHPExcel_Chart_Title('Value ($k)');
+
+
+// Create the chart
+$chart = new PHPExcel_Chart(
+ 'chart1', // name
+ $title, // title
+ $legend, // legend
+ $plotArea, // plotArea
+ true, // plotVisibleOnly
+ 0, // displayBlanksAs
+ NULL, // xAxisLabel
+ $yAxisLabel // yAxisLabel
+);
+
+// Set the position where the chart should appear in the worksheet
+$chart->setTopLeftPosition('A7');
+$chart->setBottomRightPosition('H20');
+
+// Add the chart to the worksheet
+$objWorksheet->addChart($chart);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->setIncludeCharts(TRUE);
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-column-2.php b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-column-2.php
new file mode 100755
index 000000000..0ade332c9
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-column-2.php
@@ -0,0 +1,154 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/**
+ * PHPExcel
+ *
+ * Copyright (c) 2006 - 2015 PHPExcel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * @category PHPExcel
+ * @package PHPExcel
+ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
+ * @version ##VERSION##, ##DATE##
+ */
+
+/** PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+$objPHPExcel = new PHPExcel();
+$objWorksheet = $objPHPExcel->getActiveSheet();
+$objWorksheet->fromArray(
+ array(
+ array('', '', 'Budget', 'Forecast', 'Actual'),
+ array('2010', 'Q1', 47, 44, 43 ),
+ array('', 'Q2', 56, 53, 50 ),
+ array('', 'Q3', 52, 46, 45 ),
+ array('', 'Q4', 45, 40, 40 ),
+ array('2011', 'Q1', 51, 42, 46 ),
+ array('', 'Q2', 53, 58, 56 ),
+ array('', 'Q3', 64, 66, 69 ),
+ array('', 'Q4', 54, 55, 56 ),
+ array('2012', 'Q1', 49, 52, 58 ),
+ array('', 'Q2', 68, 73, 86 ),
+ array('', 'Q3', 72, 78, 0 ),
+ array('', 'Q4', 50, 60, 0 ),
+ )
+);
+
+// Set the Labels for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesLabels = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 'Budget'
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 'Forecast'
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$E$1', NULL, 1), // 'Actual'
+);
+// Set the X-Axis Labels
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$xAxisTickValues = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$B$13', NULL, 12), // Q1 to Q4 for 2010 to 2012
+);
+// Set the Data values for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesValues = array(
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$13', NULL, 12),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$13', NULL, 12),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$E$2:$E$13', NULL, 12),
+);
+
+// Build the dataseries
+$series = new PHPExcel_Chart_DataSeries(
+ PHPExcel_Chart_DataSeries::TYPE_BARCHART, // plotType
+ PHPExcel_Chart_DataSeries::GROUPING_CLUSTERED, // plotGrouping
+ range(0, count($dataSeriesValues)-1), // plotOrder
+ $dataSeriesLabels, // plotLabel
+ $xAxisTickValues, // plotCategory
+ $dataSeriesValues // plotValues
+);
+// Set additional dataseries parameters
+// Make it a vertical column rather than a horizontal bar graph
+$series->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_COL);
+
+// Set the series in the plot area
+$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series));
+// Set the chart legend
+$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_BOTTOM, NULL, false);
+
+$title = new PHPExcel_Chart_Title('Test Grouped Column Chart');
+$xAxisLabel = new PHPExcel_Chart_Title('Financial Period');
+$yAxisLabel = new PHPExcel_Chart_Title('Value ($k)');
+
+
+// Create the chart
+$chart = new PHPExcel_Chart(
+ 'chart1', // name
+ $title, // title
+ $legend, // legend
+ $plotArea, // plotArea
+ true, // plotVisibleOnly
+ 0, // displayBlanksAs
+ $xAxisLabel, // xAxisLabel
+ $yAxisLabel // yAxisLabel
+);
+
+// Set the position where the chart should appear in the worksheet
+$chart->setTopLeftPosition('G2');
+$chart->setBottomRightPosition('P20');
+
+// Add the chart to the worksheet
+$objWorksheet->addChart($chart);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->setIncludeCharts(TRUE);
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-column.php b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-column.php
new file mode 100755
index 000000000..67f417847
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-column.php
@@ -0,0 +1,145 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/**
+ * PHPExcel
+ *
+ * Copyright (c) 2006 - 2015 PHPExcel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * @category PHPExcel
+ * @package PHPExcel
+ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
+ * @version ##VERSION##, ##DATE##
+ */
+
+/** PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+$objPHPExcel = new PHPExcel();
+$objWorksheet = $objPHPExcel->getActiveSheet();
+$objWorksheet->fromArray(
+ array(
+ array('', 2010, 2011, 2012),
+ array('Q1', 12, 15, 21),
+ array('Q2', 56, 73, 86),
+ array('Q3', 52, 61, 69),
+ array('Q4', 30, 32, 0),
+ )
+);
+
+// Set the Labels for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesLabels = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // 2010
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012
+);
+// Set the X-Axis Labels
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$xAxisTickValues = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4), // Q1 to Q4
+);
+// Set the Data values for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesValues = array(
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', NULL, 4),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$5', NULL, 4),
+);
+
+// Build the dataseries
+$series = new PHPExcel_Chart_DataSeries(
+ PHPExcel_Chart_DataSeries::TYPE_BARCHART, // plotType
+ PHPExcel_Chart_DataSeries::GROUPING_STANDARD, // plotGrouping
+ range(0, count($dataSeriesValues)-1), // plotOrder
+ $dataSeriesLabels, // plotLabel
+ $xAxisTickValues, // plotCategory
+ $dataSeriesValues // plotValues
+);
+// Set additional dataseries parameters
+// Make it a vertical column rather than a horizontal bar graph
+$series->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_COL);
+
+// Set the series in the plot area
+$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series));
+// Set the chart legend
+$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false);
+
+$title = new PHPExcel_Chart_Title('Test Column Chart');
+$yAxisLabel = new PHPExcel_Chart_Title('Value ($k)');
+
+
+// Create the chart
+$chart = new PHPExcel_Chart(
+ 'chart1', // name
+ $title, // title
+ $legend, // legend
+ $plotArea, // plotArea
+ true, // plotVisibleOnly
+ 0, // displayBlanksAs
+ NULL, // xAxisLabel
+ $yAxisLabel // yAxisLabel
+);
+
+// Set the position where the chart should appear in the worksheet
+$chart->setTopLeftPosition('A7');
+$chart->setBottomRightPosition('H20');
+
+// Add the chart to the worksheet
+$objWorksheet->addChart($chart);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->setIncludeCharts(TRUE);
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-composite.php b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-composite.php
new file mode 100755
index 000000000..be7ad94a7
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-composite.php
@@ -0,0 +1,203 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/**
+ * PHPExcel
+ *
+ * Copyright (c) 2006 - 2015 PHPExcel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * @category PHPExcel
+ * @package PHPExcel
+ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
+ * @version ##VERSION##, ##DATE##
+ */
+
+/** PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+$objPHPExcel = new PHPExcel();
+$objWorksheet = $objPHPExcel->getActiveSheet();
+$objWorksheet->fromArray(
+ array(
+ array('', 'Rainfall (mm)', 'Temperature (°F)', 'Humidity (%)'),
+ array('Jan', 78, 52, 61),
+ array('Feb', 64, 54, 62),
+ array('Mar', 62, 57, 63),
+ array('Apr', 21, 62, 59),
+ array('May', 11, 75, 60),
+ array('Jun', 1, 75, 57),
+ array('Jul', 1, 79, 56),
+ array('Aug', 1, 79, 59),
+ array('Sep', 10, 75, 60),
+ array('Oct', 40, 68, 63),
+ array('Nov', 69, 62, 64),
+ array('Dec', 89, 57, 66),
+ )
+);
+
+
+// Set the Labels for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesLabels1 = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // Temperature
+);
+$dataSeriesLabels2 = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // Rainfall
+);
+$dataSeriesLabels3 = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // Humidity
+);
+
+// Set the X-Axis Labels
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$xAxisTickValues = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$13', NULL, 12), // Jan to Dec
+);
+
+
+// Set the Data values for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesValues1 = array(
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$13', NULL, 12),
+);
+
+// Build the dataseries
+$series1 = new PHPExcel_Chart_DataSeries(
+ PHPExcel_Chart_DataSeries::TYPE_BARCHART, // plotType
+ PHPExcel_Chart_DataSeries::GROUPING_CLUSTERED, // plotGrouping
+ range(0, count($dataSeriesValues1)-1), // plotOrder
+ $dataSeriesLabels1, // plotLabel
+ $xAxisTickValues, // plotCategory
+ $dataSeriesValues1 // plotValues
+);
+// Set additional dataseries parameters
+// Make it a vertical column rather than a horizontal bar graph
+$series1->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_COL);
+
+
+// Set the Data values for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesValues2 = array(
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$13', NULL, 12),
+);
+
+// Build the dataseries
+$series2 = new PHPExcel_Chart_DataSeries(
+ PHPExcel_Chart_DataSeries::TYPE_LINECHART, // plotType
+ PHPExcel_Chart_DataSeries::GROUPING_STANDARD, // plotGrouping
+ range(0, count($dataSeriesValues2)-1), // plotOrder
+ $dataSeriesLabels2, // plotLabel
+ NULL, // plotCategory
+ $dataSeriesValues2 // plotValues
+);
+
+
+// Set the Data values for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesValues3 = array(
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$13', NULL, 12),
+);
+
+// Build the dataseries
+$series3 = new PHPExcel_Chart_DataSeries(
+ PHPExcel_Chart_DataSeries::TYPE_AREACHART, // plotType
+ PHPExcel_Chart_DataSeries::GROUPING_STANDARD, // plotGrouping
+ range(0, count($dataSeriesValues2)-1), // plotOrder
+ $dataSeriesLabels3, // plotLabel
+ NULL, // plotCategory
+ $dataSeriesValues3 // plotValues
+);
+
+
+// Set the series in the plot area
+$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series1, $series2, $series3));
+// Set the chart legend
+$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false);
+
+$title = new PHPExcel_Chart_Title('Average Weather Chart for Crete');
+
+
+// Create the chart
+$chart = new PHPExcel_Chart(
+ 'chart1', // name
+ $title, // title
+ $legend, // legend
+ $plotArea, // plotArea
+ true, // plotVisibleOnly
+ 0, // displayBlanksAs
+ NULL, // xAxisLabel
+ NULL // yAxisLabel
+);
+
+// Set the position where the chart should appear in the worksheet
+$chart->setTopLeftPosition('F2');
+$chart->setBottomRightPosition('O16');
+
+// Add the chart to the worksheet
+$objWorksheet->addChart($chart);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->setIncludeCharts(TRUE);
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-line.php b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-line.php
new file mode 100755
index 000000000..90c2e60c0
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-line.php
@@ -0,0 +1,142 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/**
+ * PHPExcel
+ *
+ * Copyright (c) 2006 - 2015 PHPExcel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * @category PHPExcel
+ * @package PHPExcel
+ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
+ * @version ##VERSION##, ##DATE##
+ */
+
+/** PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+$objPHPExcel = new PHPExcel();
+$objWorksheet = $objPHPExcel->getActiveSheet();
+$objWorksheet->fromArray(
+ array(
+ array('', 2010, 2011, 2012),
+ array('Q1', 12, 15, 21),
+ array('Q2', 56, 73, 86),
+ array('Q3', 52, 61, 69),
+ array('Q4', 30, 32, 0),
+ )
+);
+
+// Set the Labels for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesLabels = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // 2010
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012
+);
+// Set the X-Axis Labels
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$xAxisTickValues = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4), // Q1 to Q4
+);
+// Set the Data values for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesValues = array(
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', NULL, 4),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$5', NULL, 4),
+);
+
+// Build the dataseries
+$series = new PHPExcel_Chart_DataSeries(
+ PHPExcel_Chart_DataSeries::TYPE_LINECHART, // plotType
+ PHPExcel_Chart_DataSeries::GROUPING_STACKED, // plotGrouping
+ range(0, count($dataSeriesValues)-1), // plotOrder
+ $dataSeriesLabels, // plotLabel
+ $xAxisTickValues, // plotCategory
+ $dataSeriesValues // plotValues
+);
+
+// Set the series in the plot area
+$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series));
+// Set the chart legend
+$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_TOPRIGHT, NULL, false);
+
+$title = new PHPExcel_Chart_Title('Test Stacked Line Chart');
+$yAxisLabel = new PHPExcel_Chart_Title('Value ($k)');
+
+
+// Create the chart
+$chart = new PHPExcel_Chart(
+ 'chart1', // name
+ $title, // title
+ $legend, // legend
+ $plotArea, // plotArea
+ true, // plotVisibleOnly
+ 0, // displayBlanksAs
+ NULL, // xAxisLabel
+ $yAxisLabel // yAxisLabel
+);
+
+// Set the position where the chart should appear in the worksheet
+$chart->setTopLeftPosition('A7');
+$chart->setBottomRightPosition('H20');
+
+// Add the chart to the worksheet
+$objWorksheet->addChart($chart);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->setIncludeCharts(TRUE);
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-multiple-charts.php b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-multiple-charts.php
new file mode 100755
index 000000000..0e5ac60e2
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-multiple-charts.php
@@ -0,0 +1,220 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/**
+ * PHPExcel
+ *
+ * Copyright (c) 2006 - 2015 PHPExcel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * @category PHPExcel
+ * @package PHPExcel
+ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
+ * @version ##VERSION##, ##DATE##
+ */
+
+/** PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+$objPHPExcel = new PHPExcel();
+$objWorksheet = $objPHPExcel->getActiveSheet();
+$objWorksheet->fromArray(
+ array(
+ array('', 2010, 2011, 2012),
+ array('Q1', 12, 15, 21),
+ array('Q2', 56, 73, 86),
+ array('Q3', 52, 61, 69),
+ array('Q4', 30, 32, 0),
+ )
+);
+
+
+// Set the Labels for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesLabels1 = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // 2010
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012
+);
+// Set the X-Axis Labels
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$xAxisTickValues1 = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4), // Q1 to Q4
+);
+// Set the Data values for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesValues1 = array(
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', NULL, 4),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$5', NULL, 4),
+);
+
+// Build the dataseries
+$series1 = new PHPExcel_Chart_DataSeries(
+ PHPExcel_Chart_DataSeries::TYPE_AREACHART, // plotType
+ PHPExcel_Chart_DataSeries::GROUPING_PERCENT_STACKED, // plotGrouping
+ range(0, count($dataSeriesValues1)-1), // plotOrder
+ $dataSeriesLabels1, // plotLabel
+ $xAxisTickValues1, // plotCategory
+ $dataSeriesValues1 // plotValues
+);
+
+// Set the series in the plot area
+$plotArea1 = new PHPExcel_Chart_PlotArea(NULL, array($series1));
+// Set the chart legend
+$legend1 = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_TOPRIGHT, NULL, false);
+
+$title1 = new PHPExcel_Chart_Title('Test %age-Stacked Area Chart');
+$yAxisLabel1 = new PHPExcel_Chart_Title('Value ($k)');
+
+
+// Create the chart
+$chart1 = new PHPExcel_Chart(
+ 'chart1', // name
+ $title1, // title
+ $legend1, // legend
+ $plotArea1, // plotArea
+ true, // plotVisibleOnly
+ 0, // displayBlanksAs
+ NULL, // xAxisLabel
+ $yAxisLabel1 // yAxisLabel
+);
+
+// Set the position where the chart should appear in the worksheet
+$chart1->setTopLeftPosition('A7');
+$chart1->setBottomRightPosition('H20');
+
+// Add the chart to the worksheet
+$objWorksheet->addChart($chart1);
+
+
+// Set the Labels for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesLabels2 = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // 2010
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012
+);
+// Set the X-Axis Labels
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$xAxisTickValues2 = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4), // Q1 to Q4
+);
+// Set the Data values for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesValues2 = array(
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', NULL, 4),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$5', NULL, 4),
+);
+
+// Build the dataseries
+$series2 = new PHPExcel_Chart_DataSeries(
+ PHPExcel_Chart_DataSeries::TYPE_BARCHART, // plotType
+ PHPExcel_Chart_DataSeries::GROUPING_STANDARD, // plotGrouping
+ range(0, count($dataSeriesValues2)-1), // plotOrder
+ $dataSeriesLabels2, // plotLabel
+ $xAxisTickValues2, // plotCategory
+ $dataSeriesValues2 // plotValues
+);
+// Set additional dataseries parameters
+// Make it a vertical column rather than a horizontal bar graph
+$series2->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_COL);
+
+// Set the series in the plot area
+$plotArea2 = new PHPExcel_Chart_PlotArea(NULL, array($series2));
+// Set the chart legend
+$legend2 = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false);
+
+$title2 = new PHPExcel_Chart_Title('Test Column Chart');
+$yAxisLabel2 = new PHPExcel_Chart_Title('Value ($k)');
+
+
+// Create the chart
+$chart2 = new PHPExcel_Chart(
+ 'chart2', // name
+ $title2, // title
+ $legend2, // legend
+ $plotArea2, // plotArea
+ true, // plotVisibleOnly
+ 0, // displayBlanksAs
+ NULL, // xAxisLabel
+ $yAxisLabel2 // yAxisLabel
+);
+
+// Set the position where the chart should appear in the worksheet
+$chart2->setTopLeftPosition('I7');
+$chart2->setBottomRightPosition('P20');
+
+// Add the chart to the worksheet
+$objWorksheet->addChart($chart2);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->setIncludeCharts(TRUE);
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-pie.php b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-pie.php
new file mode 100755
index 000000000..78b6293f8
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-pie.php
@@ -0,0 +1,215 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/**
+ * PHPExcel
+ *
+ * Copyright (c) 2006 - 2015 PHPExcel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * @category PHPExcel
+ * @package PHPExcel
+ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
+ * @version ##VERSION##, ##DATE##
+ */
+
+/** PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+$objPHPExcel = new PHPExcel();
+$objWorksheet = $objPHPExcel->getActiveSheet();
+$objWorksheet->fromArray(
+ array(
+ array('', 2010, 2011, 2012),
+ array('Q1', 12, 15, 21),
+ array('Q2', 56, 73, 86),
+ array('Q3', 52, 61, 69),
+ array('Q4', 30, 32, 0),
+ )
+);
+
+
+// Set the Labels for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesLabels1 = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011
+);
+// Set the X-Axis Labels
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$xAxisTickValues1 = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4), // Q1 to Q4
+);
+// Set the Data values for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesValues1 = array(
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),
+);
+
+// Build the dataseries
+$series1 = new PHPExcel_Chart_DataSeries(
+ PHPExcel_Chart_DataSeries::TYPE_PIECHART, // plotType
+ NULL, // plotGrouping (Pie charts don't have any grouping)
+ range(0, count($dataSeriesValues1)-1), // plotOrder
+ $dataSeriesLabels1, // plotLabel
+ $xAxisTickValues1, // plotCategory
+ $dataSeriesValues1 // plotValues
+);
+
+// Set up a layout object for the Pie chart
+$layout1 = new PHPExcel_Chart_Layout();
+$layout1->setShowVal(TRUE);
+$layout1->setShowPercent(TRUE);
+
+// Set the series in the plot area
+$plotArea1 = new PHPExcel_Chart_PlotArea($layout1, array($series1));
+// Set the chart legend
+$legend1 = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false);
+
+$title1 = new PHPExcel_Chart_Title('Test Pie Chart');
+
+
+// Create the chart
+$chart1 = new PHPExcel_Chart(
+ 'chart1', // name
+ $title1, // title
+ $legend1, // legend
+ $plotArea1, // plotArea
+ true, // plotVisibleOnly
+ 0, // displayBlanksAs
+ NULL, // xAxisLabel
+ NULL // yAxisLabel - Pie charts don't have a Y-Axis
+);
+
+// Set the position where the chart should appear in the worksheet
+$chart1->setTopLeftPosition('A7');
+$chart1->setBottomRightPosition('H20');
+
+// Add the chart to the worksheet
+$objWorksheet->addChart($chart1);
+
+
+// Set the Labels for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesLabels2 = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011
+);
+// Set the X-Axis Labels
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$xAxisTickValues2 = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4), // Q1 to Q4
+);
+// Set the Data values for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesValues2 = array(
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),
+);
+
+// Build the dataseries
+$series2 = new PHPExcel_Chart_DataSeries(
+ PHPExcel_Chart_DataSeries::TYPE_DONUTCHART, // plotType
+ NULL, // plotGrouping (Donut charts don't have any grouping)
+ range(0, count($dataSeriesValues2)-1), // plotOrder
+ $dataSeriesLabels2, // plotLabel
+ $xAxisTickValues2, // plotCategory
+ $dataSeriesValues2 // plotValues
+);
+
+// Set up a layout object for the Pie chart
+$layout2 = new PHPExcel_Chart_Layout();
+$layout2->setShowVal(TRUE);
+$layout2->setShowCatName(TRUE);
+
+// Set the series in the plot area
+$plotArea2 = new PHPExcel_Chart_PlotArea($layout2, array($series2));
+
+$title2 = new PHPExcel_Chart_Title('Test Donut Chart');
+
+
+// Create the chart
+$chart2 = new PHPExcel_Chart(
+ 'chart2', // name
+ $title2, // title
+ NULL, // legend
+ $plotArea2, // plotArea
+ true, // plotVisibleOnly
+ 0, // displayBlanksAs
+ NULL, // xAxisLabel
+ NULL // yAxisLabel - Like Pie charts, Donut charts don't have a Y-Axis
+);
+
+// Set the position where the chart should appear in the worksheet
+$chart2->setTopLeftPosition('I7');
+$chart2->setBottomRightPosition('P20');
+
+// Add the chart to the worksheet
+$objWorksheet->addChart($chart2);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->setIncludeCharts(TRUE);
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-radar.php b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-radar.php
new file mode 100755
index 000000000..7d1047a42
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-radar.php
@@ -0,0 +1,155 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/**
+ * PHPExcel
+ *
+ * Copyright (c) 2006 - 2015 PHPExcel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * @category PHPExcel
+ * @package PHPExcel
+ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
+ * @version ##VERSION##, ##DATE##
+ */
+
+/** PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+$objPHPExcel = new PHPExcel();
+$objWorksheet = $objPHPExcel->getActiveSheet();
+$objWorksheet->fromArray(
+ array(
+ array('', 2010, 2011, 2012),
+ array('Jan', 47, 45, 71),
+ array('Feb', 56, 73, 86),
+ array('Mar', 52, 61, 69),
+ array('Apr', 40, 52, 60),
+ array('May', 42, 55, 71),
+ array('Jun', 58, 63, 76),
+ array('Jul', 53, 61, 89),
+ array('Aug', 46, 69, 85),
+ array('Sep', 62, 75, 81),
+ array('Oct', 51, 70, 96),
+ array('Nov', 55, 66, 89),
+ array('Dec', 68, 62, 0),
+ )
+);
+
+
+// Set the Labels for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesLabels = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012
+);
+// Set the X-Axis Labels
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$xAxisTickValues = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$13', NULL, 12), // Jan to Dec
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$13', NULL, 12), // Jan to Dec
+);
+// Set the Data values for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesValues = array(
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$13', NULL, 12),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$13', NULL, 12),
+);
+
+// Build the dataseries
+$series = new PHPExcel_Chart_DataSeries(
+ PHPExcel_Chart_DataSeries::TYPE_RADARCHART, // plotType
+ NULL, // plotGrouping (Radar charts don't have any grouping)
+ range(0, count($dataSeriesValues)-1), // plotOrder
+ $dataSeriesLabels, // plotLabel
+ $xAxisTickValues, // plotCategory
+ $dataSeriesValues, // plotValues
+ NULL, // plotDirection
+ NULL, // smooth line
+ PHPExcel_Chart_DataSeries::STYLE_MARKER // plotStyle
+);
+
+// Set up a layout object for the Pie chart
+$layout = new PHPExcel_Chart_Layout();
+
+// Set the series in the plot area
+$plotArea = new PHPExcel_Chart_PlotArea($layout, array($series));
+// Set the chart legend
+$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false);
+
+$title = new PHPExcel_Chart_Title('Test Radar Chart');
+
+
+// Create the chart
+$chart = new PHPExcel_Chart(
+ 'chart1', // name
+ $title, // title
+ $legend, // legend
+ $plotArea, // plotArea
+ true, // plotVisibleOnly
+ 0, // displayBlanksAs
+ NULL, // xAxisLabel
+ NULL // yAxisLabel - Radar charts don't have a Y-Axis
+);
+
+// Set the position where the chart should appear in the worksheet
+$chart->setTopLeftPosition('F2');
+$chart->setBottomRightPosition('M15');
+
+// Add the chart to the worksheet
+$objWorksheet->addChart($chart);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->setIncludeCharts(TRUE);
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-scatter.php b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-scatter.php
new file mode 100755
index 000000000..a5fab8272
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-scatter.php
@@ -0,0 +1,139 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/**
+ * PHPExcel
+ *
+ * Copyright (c) 2006 - 2015 PHPExcel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * @category PHPExcel
+ * @package PHPExcel
+ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
+ * @version ##VERSION##, ##DATE##
+ */
+
+/** PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+$objPHPExcel = new PHPExcel();
+$objWorksheet = $objPHPExcel->getActiveSheet();
+$objWorksheet->fromArray(
+ array(
+ array('', 2010, 2011, 2012),
+ array('Q1', 12, 15, 21),
+ array('Q2', 56, 73, 86),
+ array('Q3', 52, 61, 69),
+ array('Q4', 30, 32, 0),
+ )
+);
+
+// Set the Labels for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesLabels = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // 2010
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012
+);
+// Set the X-Axis Labels
+$xAxisTickValues = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4), // Q1 to Q4
+);
+// Set the Data values for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesValues = array(
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', NULL, 4),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$5', NULL, 4),
+);
+
+// Build the dataseries
+$series = new PHPExcel_Chart_DataSeries(
+ PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART, // plotType
+ NULL, // plotGrouping (Scatter charts don't have any grouping)
+ range(0, count($dataSeriesValues)-1), // plotOrder
+ $dataSeriesLabels, // plotLabel
+ $xAxisTickValues, // plotCategory
+ $dataSeriesValues, // plotValues
+ NULL, // plotDirection
+ NULL, // smooth line
+ PHPExcel_Chart_DataSeries::STYLE_LINEMARKER // plotStyle
+);
+
+// Set the series in the plot area
+$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series));
+// Set the chart legend
+$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_TOPRIGHT, NULL, false);
+
+$title = new PHPExcel_Chart_Title('Test Scatter Chart');
+$yAxisLabel = new PHPExcel_Chart_Title('Value ($k)');
+
+
+// Create the chart
+$chart = new PHPExcel_Chart(
+ 'chart1', // name
+ $title, // title
+ $legend, // legend
+ $plotArea, // plotArea
+ true, // plotVisibleOnly
+ 0, // displayBlanksAs
+ NULL, // xAxisLabel
+ $yAxisLabel // yAxisLabel
+);
+
+// Set the position where the chart should appear in the worksheet
+$chart->setTopLeftPosition('A7');
+$chart->setBottomRightPosition('H20');
+
+// Add the chart to the worksheet
+$objWorksheet->addChart($chart);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->setIncludeCharts(TRUE);
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-stock.php b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-stock.php
new file mode 100755
index 000000000..465107b3a
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/33chartcreate-stock.php
@@ -0,0 +1,151 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/**
+ * PHPExcel
+ *
+ * Copyright (c) 2006 - 2015 PHPExcel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * @category PHPExcel
+ * @package PHPExcel
+ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
+ * @version ##VERSION##, ##DATE##
+ */
+
+/** PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+$objPHPExcel = new PHPExcel();
+$objWorksheet = $objPHPExcel->getActiveSheet();
+$objWorksheet->fromArray(
+ array(
+ array('Counts', 'Max', 'Min', 'Min Threshold', 'Max Threshold' ),
+ array(10, 10, 5, 0, 50 ),
+ array(30, 20, 10, 0, 50 ),
+ array(20, 30, 15, 0, 50 ),
+ array(40, 10, 0, 0, 50 ),
+ array(100, 40, 5, 0, 50 ),
+ ), null, 'A1', true
+);
+$objWorksheet->getStyle('B2:E6')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_NUMBER_00);
+
+
+// Set the Labels for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesLabels = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), //Max / Open
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), //Min / Close
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), //Min Threshold / Min
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$E$1', NULL, 1), //Max Threshold / Max
+);
+// Set the X-Axis Labels
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$xAxisTickValues = array(
+ new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$6', NULL, 5), // Counts
+);
+// Set the Data values for each data series we want to plot
+// Datatype
+// Cell reference for data
+// Format Code
+// Number of datapoints in series
+// Data values
+// Data Marker
+$dataSeriesValues = array(
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$6', NULL, 5),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$6', NULL, 5),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$6', NULL, 5),
+ new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$E$2:$E$6', NULL, 5),
+);
+
+// Build the dataseries
+$series = new PHPExcel_Chart_DataSeries(
+ PHPExcel_Chart_DataSeries::TYPE_STOCKCHART, // plotType
+ null, // plotGrouping - if we set this to not null, then xlsx throws error
+ range(0, count($dataSeriesValues)-1), // plotOrder
+ $dataSeriesLabels, // plotLabel
+ $xAxisTickValues, // plotCategory
+ $dataSeriesValues // plotValues
+);
+
+// Set the series in the plot area
+$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series));
+// Set the chart legend
+$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false);
+
+$title = new PHPExcel_Chart_Title('Test Stock Chart');
+$xAxisLabel = new PHPExcel_Chart_Title('Counts');
+$yAxisLabel = new PHPExcel_Chart_Title('Values');
+
+// Create the chart
+$chart = new PHPExcel_Chart(
+ 'stock-chart', // name
+ $title, // title
+ $legend, // legend
+ $plotArea, // plotArea
+ true, // plotVisibleOnly
+ 0, // displayBlanksAs
+ $xAxisLabel, // xAxisLabel
+ $yAxisLabel // yAxisLabel
+);
+
+// Set the position where the chart should appear in the worksheet
+$chart->setTopLeftPosition('A7');
+$chart->setBottomRightPosition('H20');
+
+// Add the chart to the worksheet
+$objWorksheet->addChart($chart);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->setIncludeCharts(TRUE);
+$filename = str_replace('.php', '.xlsx', __FILE__);
+if(file_exists($filename)) {
+ unlink($filename);
+}
+$objWriter->save($filename);
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/34chartupdate.php b/Server/vendor/phpoffice/phpexcel/Examples/34chartupdate.php
new file mode 100755
index 000000000..f4b36c6bf
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/34chartupdate.php
@@ -0,0 +1,78 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/**
+ * PHPExcel
+ *
+ * Copyright (c) 2006 - 2015 PHPExcel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * @category PHPExcel
+ * @package PHPExcel
+ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
+ * @version ##VERSION##, ##DATE##
+ */
+
+/** PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+if (!file_exists("33chartcreate-bar.xlsx")) {
+ exit("Please run 33chartcreate-bar.php first." . EOL);
+}
+
+echo date('H:i:s') , " Load from Excel2007 file" , EOL;
+$objReader = PHPExcel_IOFactory::createReader("Excel2007");
+$objReader->setIncludeCharts(TRUE);
+$objPHPExcel = $objReader->load("33chartcreate-bar.xlsx");
+
+
+echo date('H:i:s') , " Update cell data values that are displayed in the chart" , EOL;
+$objWorksheet = $objPHPExcel->getActiveSheet();
+$objWorksheet->fromArray(
+ array(
+ array(50-12, 50-15, 50-21),
+ array(50-56, 50-73, 50-86),
+ array(50-52, 50-61, 50-69),
+ array(50-30, 50-32, 50),
+ ),
+ NULL,
+ 'B2'
+);
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->setIncludeCharts(TRUE);
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/35chartrender.php b/Server/vendor/phpoffice/phpexcel/Examples/35chartrender.php
new file mode 100755
index 000000000..62719e51d
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/35chartrender.php
@@ -0,0 +1,134 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/**
+ * PHPExcel
+ *
+ * Copyright (c) 2006 - 2015 PHPExcel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * @category PHPExcel
+ * @package PHPExcel
+ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
+ * @version ##VERSION##, ##DATE##
+ */
+
+/** Include path **/
+set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/../Classes/');
+
+/** PHPExcel_IOFactory */
+include 'PHPExcel/IOFactory.php';
+
+
+// Change these values to select the Rendering library that you wish to use
+// and its directory location on your server
+$rendererName = PHPExcel_Settings::CHART_RENDERER_JPGRAPH;
+$rendererLibrary = 'jpgraph3.5.0b1/src/';
+$rendererLibraryPath = '/php/libraries/Charts/' . $rendererLibrary;
+
+
+if (!PHPExcel_Settings::setChartRenderer(
+ $rendererName,
+ $rendererLibraryPath
+ )) {
+ die(
+ 'NOTICE: Please set the $rendererName and $rendererLibraryPath values' .
+ EOL .
+ 'at the top of this script as appropriate for your directory structure'
+ );
+}
+
+
+$inputFileType = 'Excel2007';
+$inputFileNames = 'templates/32readwrite*[0-9].xlsx';
+
+ if ((isset($argc)) && ($argc > 1)) {
+ $inputFileNames = array();
+ for($i = 1; $i < $argc; ++$i) {
+ $inputFileNames[] = dirname(__FILE__) . '/templates/' . $argv[$i];
+ }
+} else {
+ $inputFileNames = glob($inputFileNames);
+}
+foreach($inputFileNames as $inputFileName) {
+ $inputFileNameShort = basename($inputFileName);
+
+ if (!file_exists($inputFileName)) {
+ echo date('H:i:s') , " File " , $inputFileNameShort , ' does not exist' , EOL;
+ continue;
+ }
+
+ echo date('H:i:s') , " Load Test from $inputFileType file " , $inputFileNameShort , EOL;
+
+ $objReader = PHPExcel_IOFactory::createReader($inputFileType);
+ $objReader->setIncludeCharts(TRUE);
+ $objPHPExcel = $objReader->load($inputFileName);
+
+
+ echo date('H:i:s') , " Iterate worksheets looking at the charts" , EOL;
+ foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
+ $sheetName = $worksheet->getTitle();
+ echo 'Worksheet: ' , $sheetName , EOL;
+
+ $chartNames = $worksheet->getChartNames();
+ if(empty($chartNames)) {
+ echo ' There are no charts in this worksheet' , EOL;
+ } else {
+ natsort($chartNames);
+ foreach($chartNames as $i => $chartName) {
+ $chart = $worksheet->getChartByName($chartName);
+ if (!is_null($chart->getTitle())) {
+ $caption = '"' . implode(' ',$chart->getTitle()->getCaption()) . '"';
+ } else {
+ $caption = 'Untitled';
+ }
+ echo ' ' , $chartName , ' - ' , $caption , EOL;
+ echo str_repeat(' ',strlen($chartName)+3);
+
+ $jpegFile = '35'.str_replace('.xlsx', '.jpg', substr($inputFileNameShort,2));
+ if (file_exists($jpegFile)) {
+ unlink($jpegFile);
+ }
+ try {
+ $chart->render($jpegFile);
+ } catch (Exception $e) {
+ echo 'Error rendering chart: ',$e->getMessage();
+ }
+ }
+ }
+ }
+
+
+ $objPHPExcel->disconnectWorksheets();
+ unset($objPHPExcel);
+}
+
+// Echo memory peak usage
+echo date('H:i:s') , ' Peak memory usage: ' , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done rendering charts as images" , EOL;
+echo 'Image files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/36chartreadwriteHTML.php b/Server/vendor/phpoffice/phpexcel/Examples/36chartreadwriteHTML.php
new file mode 100755
index 000000000..7fc26fdee
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/36chartreadwriteHTML.php
@@ -0,0 +1,151 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/**
+ * PHPExcel
+ *
+ * Copyright (c) 2006 - 2015 PHPExcel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * @category PHPExcel
+ * @package PHPExcel
+ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
+ * @version ##VERSION##, ##DATE##
+ */
+
+/** Include path **/
+set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/../Classes/');
+
+/** PHPExcel_IOFactory */
+include 'PHPExcel/IOFactory.php';
+
+
+// Change these values to select the Rendering library that you wish to use
+// and its directory location on your server
+$rendererName = PHPExcel_Settings::CHART_RENDERER_JPGRAPH;
+$rendererLibrary = 'jpgraph3.5.0b1/src/';
+$rendererLibraryPath = '/php/libraries/Charts/' . $rendererLibrary;
+
+
+if (!PHPExcel_Settings::setChartRenderer(
+ $rendererName,
+ $rendererLibraryPath
+ )) {
+ die(
+ 'NOTICE: Please set the $rendererName and $rendererLibraryPath values' .
+ EOL .
+ 'at the top of this script as appropriate for your directory structure'
+ );
+}
+
+
+$inputFileType = 'Excel2007';
+$inputFileNames = 'templates/36write*.xlsx';
+
+if ((isset($argc)) && ($argc > 1)) {
+ $inputFileNames = array();
+ for($i = 1; $i < $argc; ++$i) {
+ $inputFileNames[] = dirname(__FILE__) . '/templates/' . $argv[$i];
+ }
+} else {
+ $inputFileNames = glob($inputFileNames);
+}
+foreach($inputFileNames as $inputFileName) {
+ $inputFileNameShort = basename($inputFileName);
+
+ if (!file_exists($inputFileName)) {
+ echo date('H:i:s') , " File " , $inputFileNameShort , ' does not exist' , EOL;
+ continue;
+ }
+
+ echo date('H:i:s') , " Load Test from $inputFileType file " , $inputFileNameShort , EOL;
+
+ $objReader = PHPExcel_IOFactory::createReader($inputFileType);
+ $objReader->setIncludeCharts(TRUE);
+ $objPHPExcel = $objReader->load($inputFileName);
+
+
+ echo date('H:i:s') , " Iterate worksheets looking at the charts" , EOL;
+ foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
+ $sheetName = $worksheet->getTitle();
+ echo 'Worksheet: ' , $sheetName , EOL;
+
+ $chartNames = $worksheet->getChartNames();
+ if(empty($chartNames)) {
+ echo ' There are no charts in this worksheet' , EOL;
+ } else {
+ natsort($chartNames);
+ foreach($chartNames as $i => $chartName) {
+ $chart = $worksheet->getChartByName($chartName);
+ if (!is_null($chart->getTitle())) {
+ $caption = '"' . implode(' ',$chart->getTitle()->getCaption()) . '"';
+ } else {
+ $caption = 'Untitled';
+ }
+ echo ' ' , $chartName , ' - ' , $caption , EOL;
+ echo str_repeat(' ',strlen($chartName)+3);
+ $groupCount = $chart->getPlotArea()->getPlotGroupCount();
+ if ($groupCount == 1) {
+ $chartType = $chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType();
+ echo ' ' , $chartType , EOL;
+ } else {
+ $chartTypes = array();
+ for($i = 0; $i < $groupCount; ++$i) {
+ $chartTypes[] = $chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType();
+ }
+ $chartTypes = array_unique($chartTypes);
+ if (count($chartTypes) == 1) {
+ $chartType = 'Multiple Plot ' . array_pop($chartTypes);
+ echo ' ' , $chartType , EOL;
+ } elseif (count($chartTypes) == 0) {
+ echo ' *** Type not yet implemented' , EOL;
+ } else {
+ echo ' Combination Chart' , EOL;
+ }
+ }
+ }
+ }
+ }
+
+
+ $outputFileName = str_replace('.xlsx', '.html', basename($inputFileName));
+
+ echo date('H:i:s') , " Write Tests to HTML file " , EOL;
+ $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'HTML');
+ $objWriter->setIncludeCharts(TRUE);
+ $objWriter->save($outputFileName);
+ echo date('H:i:s') , " File written to " , $outputFileName , EOL;
+
+ $objPHPExcel->disconnectWorksheets();
+ unset($objPHPExcel);
+}
+
+// Echo memory peak usage
+echo date('H:i:s') , ' Peak memory usage: ' , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing files" , EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/36chartreadwritePDF.php b/Server/vendor/phpoffice/phpexcel/Examples/36chartreadwritePDF.php
new file mode 100755
index 000000000..24d1c857b
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/36chartreadwritePDF.php
@@ -0,0 +1,174 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/**
+ * PHPExcel
+ *
+ * Copyright (c) 2006 - 2015 PHPExcel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * @category PHPExcel
+ * @package PHPExcel
+ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
+ * @version ##VERSION##, ##DATE##
+ */
+
+/** Include path **/
+set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/../Classes/');
+
+/** PHPExcel_IOFactory */
+include 'PHPExcel/IOFactory.php';
+
+
+// Change these values to select the Rendering library that you wish to use
+// for PDF files, and its directory location on your server
+//$rendererName = PHPExcel_Settings::PDF_RENDERER_TCPDF;
+$rendererName = PHPExcel_Settings::PDF_RENDERER_MPDF;
+//$rendererName = PHPExcel_Settings::PDF_RENDERER_DOMPDF;
+//$rendererLibrary = 'tcPDF5.9';
+$rendererLibrary = 'mPDF5.4';
+//$rendererLibrary = 'domPDF0.6.0beta3';
+$rendererLibraryPath = '/php/libraries/PDF/' . $rendererLibrary;
+
+
+if (!PHPExcel_Settings::setPdfRenderer(
+ $rendererName,
+ $rendererLibraryPath
+ )) {
+ die(
+ 'NOTICE: Please set the $rendererName and $rendererLibraryPath values' .
+ EOL .
+ 'at the top of this script as appropriate for your directory structure'
+ );
+}
+
+
+// Change these values to select the Rendering library that you wish to use
+// for Chart images, and its directory location on your server
+$rendererName = PHPExcel_Settings::CHART_RENDERER_JPGRAPH;
+$rendererLibrary = 'jpgraph3.5.0b1/src/';
+$rendererLibraryPath = '/php/libraries/Charts/' . $rendererLibrary;
+
+
+if (!PHPExcel_Settings::setChartRenderer(
+ $rendererName,
+ $rendererLibraryPath
+ )) {
+ die(
+ 'NOTICE: Please set the $rendererName and $rendererLibraryPath values' .
+ EOL .
+ 'at the top of this script as appropriate for your directory structure'
+ );
+}
+
+
+$inputFileType = 'Excel2007';
+$inputFileNames = 'templates/36write*.xlsx';
+
+if ((isset($argc)) && ($argc > 1)) {
+ $inputFileNames = array();
+ for($i = 1; $i < $argc; ++$i) {
+ $inputFileNames[] = dirname(__FILE__) . '/templates/' . $argv[$i];
+ }
+} else {
+ $inputFileNames = glob($inputFileNames);
+}
+foreach($inputFileNames as $inputFileName) {
+ $inputFileNameShort = basename($inputFileName);
+
+ if (!file_exists($inputFileName)) {
+ echo date('H:i:s') , " File " , $inputFileNameShort , ' does not exist' , EOL;
+ continue;
+ }
+
+ echo date('H:i:s') , " Load Test from $inputFileType file " , $inputFileNameShort , EOL;
+
+ $objReader = PHPExcel_IOFactory::createReader($inputFileType);
+ $objReader->setIncludeCharts(TRUE);
+ $objPHPExcel = $objReader->load($inputFileName);
+
+
+ echo date('H:i:s') , " Iterate worksheets looking at the charts" , EOL;
+ foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
+ $sheetName = $worksheet->getTitle();
+ echo 'Worksheet: ' , $sheetName , EOL;
+
+ $chartNames = $worksheet->getChartNames();
+ if(empty($chartNames)) {
+ echo ' There are no charts in this worksheet' , EOL;
+ } else {
+ natsort($chartNames);
+ foreach($chartNames as $i => $chartName) {
+ $chart = $worksheet->getChartByName($chartName);
+ if (!is_null($chart->getTitle())) {
+ $caption = '"' . implode(' ',$chart->getTitle()->getCaption()) . '"';
+ } else {
+ $caption = 'Untitled';
+ }
+ echo ' ' , $chartName , ' - ' , $caption , EOL;
+ echo str_repeat(' ',strlen($chartName)+3);
+ $groupCount = $chart->getPlotArea()->getPlotGroupCount();
+ if ($groupCount == 1) {
+ $chartType = $chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType();
+ echo ' ' , $chartType , EOL;
+ } else {
+ $chartTypes = array();
+ for($i = 0; $i < $groupCount; ++$i) {
+ $chartTypes[] = $chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType();
+ }
+ $chartTypes = array_unique($chartTypes);
+ if (count($chartTypes) == 1) {
+ $chartType = 'Multiple Plot ' . array_pop($chartTypes);
+ echo ' ' , $chartType , EOL;
+ } elseif (count($chartTypes) == 0) {
+ echo ' *** Type not yet implemented' , EOL;
+ } else {
+ echo ' Combination Chart' , EOL;
+ }
+ }
+ }
+ }
+ }
+
+
+ $outputFileName = str_replace('.xlsx', '.pdf', basename($inputFileName));
+
+ echo date('H:i:s') , " Write Tests to HTML file " , EOL;
+ $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'PDF');
+ $objWriter->setIncludeCharts(TRUE);
+ $objWriter->save($outputFileName);
+ echo date('H:i:s') , " File written to " , $outputFileName , EOL;
+
+ $objPHPExcel->disconnectWorksheets();
+ unset($objPHPExcel);
+}
+
+// Echo memory peak usage
+echo date('H:i:s') , ' Peak memory usage: ' , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing files" , EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/37page_layout_view.php b/Server/vendor/phpoffice/phpexcel/Examples/37page_layout_view.php
new file mode 100755
index 000000000..810ca3d21
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/37page_layout_view.php
@@ -0,0 +1,83 @@
+');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("PHPOffice")
+ ->setLastModifiedBy("PHPOffice")
+ ->setTitle("PHPExcel Test Document")
+ ->setSubject("PHPExcel Test Document")
+ ->setDescription("Test document for PHPExcel, generated using PHP classes.")
+ ->setKeywords("Office PHPExcel php")
+ ->setCategory("Test result file");
+
+
+// Add some data
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0)
+ ->setCellValue('A1', 'Hello')
+ ->setCellValue('B2', 'world!');
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+// Set the page layout view as page layout
+$objPHPExcel->getActiveSheet()->getSheetView()->setView(PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT);
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+// Save Excel5 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing files" , EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/38cloneWorksheet.php b/Server/vendor/phpoffice/phpexcel/Examples/38cloneWorksheet.php
new file mode 100755
index 000000000..245f7da43
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/38cloneWorksheet.php
@@ -0,0 +1,118 @@
+');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("PHPExcel Test Document")
+ ->setSubject("PHPExcel Test Document")
+ ->setDescription("Test document for PHPExcel, generated using PHP classes.")
+ ->setKeywords("office PHPExcel php")
+ ->setCategory("Test result file");
+
+
+// Add some data
+echo date('H:i:s') , " Add some data" , EOL;
+$objPHPExcel->setActiveSheetIndex(0)
+ ->setCellValue('A1', 'Hello')
+ ->setCellValue('B2', 'world!')
+ ->setCellValue('C1', 'Hello')
+ ->setCellValue('D2', 'world!');
+
+// Miscellaneous glyphs, UTF-8
+$objPHPExcel->setActiveSheetIndex(0)
+ ->setCellValue('A4', 'Miscellaneous glyphs')
+ ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');
+
+
+$objPHPExcel->getActiveSheet()->setCellValue('A8',"Hello\nWorld");
+$objPHPExcel->getActiveSheet()->getRowDimension(8)->setRowHeight(-1);
+$objPHPExcel->getActiveSheet()->getStyle('A8')->getAlignment()->setWrapText(true);
+
+
+// Rename worksheet
+echo date('H:i:s') , " Rename worksheet" , EOL;
+$objPHPExcel->getActiveSheet()->setTitle('Simple');
+
+
+// Clone worksheet
+echo date('H:i:s') , " Clone worksheet" , EOL;
+$clonedSheet = clone $objPHPExcel->getActiveSheet();
+$clonedSheet
+ ->setCellValue('A1', 'Goodbye')
+ ->setCellValue('A2', 'cruel')
+ ->setCellValue('C1', 'Goodbye')
+ ->setCellValue('C2', 'cruel');
+
+// Rename cloned worksheet
+echo date('H:i:s') , " Rename cloned worksheet" , EOL;
+$clonedSheet->setTitle('Simple Clone');
+$objPHPExcel->addSheet($clonedSheet);
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing files" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/39dropdown.php b/Server/vendor/phpoffice/phpexcel/Examples/39dropdown.php
new file mode 100755
index 000000000..c8dcff67c
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/39dropdown.php
@@ -0,0 +1,175 @@
+');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()
+ ->setCreator("PHPOffice")
+ ->setLastModifiedBy("PHPOffice")
+ ->setTitle("PHPExcel Test Document")
+ ->setSubject("PHPExcel Test Document")
+ ->setDescription("Test document for PHPExcel, generated using PHP classes.")
+ ->setKeywords("Office PHPExcel php")
+ ->setCategory("Test result file");
+
+
+function transpose($value) {
+ return array($value);
+}
+
+// Add some data
+$continentColumn = 'D';
+$column = 'F';
+
+// Set data for dropdowns
+foreach(glob('./data/continents/*') as $key => $filename) {
+ $continent = pathinfo($filename, PATHINFO_FILENAME);
+ echo "Loading $continent", EOL;
+ $continent = str_replace(' ','_',$continent);
+ $countries = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
+ $countryCount = count($countries);
+
+ // Transpose $countries from a row to a column array
+ $countries = array_map('transpose', $countries);
+ $objPHPExcel->getActiveSheet()
+ ->fromArray($countries, null, $column . '1');
+ $objPHPExcel->addNamedRange(
+ new PHPExcel_NamedRange(
+ $continent,
+ $objPHPExcel->getActiveSheet(), $column . '1:' . $column . $countryCount
+ )
+ );
+ $objPHPExcel->getActiveSheet()
+ ->getColumnDimension($column)
+ ->setVisible(false);
+
+ $objPHPExcel->getActiveSheet()
+ ->setCellValue($continentColumn . ($key+1), $continent);
+
+ ++$column;
+}
+
+// Hide the dropdown data
+$objPHPExcel->getActiveSheet()
+ ->getColumnDimension($continentColumn)
+ ->setVisible(false);
+
+$objPHPExcel->addNamedRange(
+ new PHPExcel_NamedRange(
+ 'Continents',
+ $objPHPExcel->getActiveSheet(), $continentColumn . '1:' . $continentColumn . ($key+1)
+ )
+);
+
+
+// Set selection cells
+$objPHPExcel->getActiveSheet()
+ ->setCellValue('A1', 'Continent:');
+$objPHPExcel->getActiveSheet()
+ ->setCellValue('B1', 'Select continent');
+$objPHPExcel->getActiveSheet()
+ ->setCellValue('B3', '=' . $column . 1);
+$objPHPExcel->getActiveSheet()
+ ->setCellValue('B3', 'Select country');
+$objPHPExcel->getActiveSheet()
+ ->getStyle('A1:A3')
+ ->getFont()->setBold(true);
+
+// Set linked validators
+$objValidation = $objPHPExcel->getActiveSheet()
+ ->getCell('B1')
+ ->getDataValidation();
+$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST )
+ ->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION )
+ ->setAllowBlank(false)
+ ->setShowInputMessage(true)
+ ->setShowErrorMessage(true)
+ ->setShowDropDown(true)
+ ->setErrorTitle('Input error')
+ ->setError('Continent is not in the list.')
+ ->setPromptTitle('Pick from the list')
+ ->setPrompt('Please pick a continent from the drop-down list.')
+ ->setFormula1('=Continents');
+
+$objPHPExcel->getActiveSheet()
+ ->setCellValue('A3', 'Country:');
+$objPHPExcel->getActiveSheet()
+ ->getStyle('A3')
+ ->getFont()->setBold(true);
+
+$objValidation = $objPHPExcel->getActiveSheet()
+ ->getCell('B3')
+ ->getDataValidation();
+$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST )
+ ->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION )
+ ->setAllowBlank(false)
+ ->setShowInputMessage(true)
+ ->setShowErrorMessage(true)
+ ->setShowDropDown(true)
+ ->setErrorTitle('Input error')
+ ->setError('Country is not in the list.')
+ ->setPromptTitle('Pick from the list')
+ ->setPrompt('Please pick a country from the drop-down list.')
+ ->setFormula1('=INDIRECT($B$1)');
+
+
+$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(12);
+$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(30);
+
+
+// Set active sheet index to the first sheet, so Excel opens this as the first sheet
+$objPHPExcel->setActiveSheetIndex(0);
+
+// Save Excel 2007 file
+// This linked validation list method only seems to work for Excel2007, not for Excel5
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing files" , EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/40duplicateStyle.php b/Server/vendor/phpoffice/phpexcel/Examples/40duplicateStyle.php
new file mode 100755
index 000000000..be31951a4
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/40duplicateStyle.php
@@ -0,0 +1,51 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+$worksheet = $objPHPExcel->getActiveSheet();
+
+echo date('H:i:s') , " Create styles array" , EOL;
+$styles = array();
+for ($i = 0; $i < 10; $i++) {
+ $style = new PHPExcel_Style();
+ $style->getFont()->setSize($i + 4);
+ $styles[] = $style;
+}
+
+echo date('H:i:s') , " Add data (begin)" , EOL;
+$t = microtime(true);
+for ($col = 0; $col < 50; $col++) {
+ for ($row = 0; $row < 100; $row++) {
+ $str = ($row + $col);
+ $style = $styles[$row % 10];
+ $coord = PHPExcel_Cell::stringFromColumnIndex($col) . ($row + 1);
+ $worksheet->setCellValue($coord, $str);
+ $worksheet->duplicateStyle($style, $coord);
+ }
+}
+$d = microtime(true) - $t;
+echo date('H:i:s') , " Add data (end), time: " . round($d, 2) . " s", EOL;
+
+
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+
+
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+echo date('H:i:s') , " Done writing file" , EOL;
+echo 'File has been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/41password.php b/Server/vendor/phpoffice/phpexcel/Examples/41password.php
new file mode 100755
index 000000000..15aea7ba0
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/41password.php
@@ -0,0 +1,84 @@
+');
+
+date_default_timezone_set('Europe/London');
+
+include "05featuredemo.inc.php";
+
+/** Include PHPExcel_IOFactory */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';
+
+
+// Set password against the spreadsheet file
+$objPHPExcel->getSecurity()->setLockWindows(true);
+$objPHPExcel->getSecurity()->setLockStructure(true);
+$objPHPExcel->getSecurity()->setWorkbookPassword('secret');
+
+
+// Save Excel 2007 file
+echo date('H:i:s') , " Write to Excel2007 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Save Excel 95 file
+echo date('H:i:s') , " Write to Excel5 format" , EOL;
+$callStartTime = microtime(true);
+
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+$objWriter->save(str_replace('.php', '.xls', __FILE__));
+$callEndTime = microtime(true);
+$callTime = $callEndTime - $callStartTime;
+
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
+echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
+// Echo memory usage
+echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing files" , EOL;
+echo 'Files have been created in ' , getcwd() , EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/42richText.php b/Server/vendor/phpoffice/phpexcel/Examples/42richText.php
new file mode 100755
index 000000000..32bc401fd
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/42richText.php
@@ -0,0 +1,164 @@
+');
+
+/** Include PHPExcel */
+require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
+
+
+// Create new PHPExcel object
+echo date('H:i:s') , " Create new PHPExcel object" , EOL;
+$objPHPExcel = new PHPExcel();
+
+// Set document properties
+echo date('H:i:s') , " Set document properties" , EOL;
+$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
+ ->setLastModifiedBy("Maarten Balliauw")
+ ->setTitle("PHPExcel Test Document")
+ ->setSubject("PHPExcel Test Document")
+ ->setDescription("Test document for PHPExcel, generated using PHP classes.")
+ ->setKeywords("office PHPExcel php")
+ ->setCategory("Test result file");
+
+
+// Add some data
+echo date('H:i:s') , " Add some data" , EOL;
+
+$html1 = '
+My very first example of rich text
+
generated from html markuphealthy food pizza.
+
+';
+
+$html2 = '
+
+ 10°F is cold
+
+Quadratic Equation Solver
+
+
+getActiveSheet()->setCellValue('A1', $_POST['A']);
+ $objPHPExcel->getActiveSheet()->setCellValue('B1', $_POST['B']);
+ $objPHPExcel->getActiveSheet()->setCellValue('C1', $_POST['C']);
+
+
+ /** Calculate and Display the results **/
+ echo '
Roots:
';
+
+ $callStartTime = microtime(true);
+ echo $objPHPExcel->getActiveSheet()->getCell('B5')->getCalculatedValue().'
';
+ echo $objPHPExcel->getActiveSheet()->getCell('B6')->getCalculatedValue().'
';
+ $callEndTime = microtime(true);
+ $callTime = $callEndTime - $callStartTime;
+
+ echo '
Call time for Quadratic Equation Solution was '.sprintf('%.4f',$callTime).' seconds
';
+ echo ' Peak memory usage: '.(memory_get_peak_usage(true) / 1024 / 1024).' MB
';
+ }
+}
+
+?>
+
+
+
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/Quadratic2.php b/Server/vendor/phpoffice/phpexcel/Examples/Quadratic2.php
new file mode 100755
index 000000000..05cd5c173
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/Quadratic2.php
@@ -0,0 +1,65 @@
+
+
+Quadratic Equation Solver
+
+
+Roots:
';
+
+ $callStartTime = microtime(true);
+ $discriminantFormula = '=POWER('.$_POST['B'].',2) - (4 * '.$_POST['A'].' * '.$_POST['C'].')';
+ $discriminant = PHPExcel_Calculation::getInstance()->calculateFormula($discriminantFormula);
+
+ $r1Formula = '=IMDIV(IMSUM(-'.$_POST['B'].',IMSQRT('.$discriminant.')),2 * '.$_POST['A'].')';
+ $r2Formula = '=IF('.$discriminant.'=0,"Only one root",IMDIV(IMSUB(-'.$_POST['B'].',IMSQRT('.$discriminant.')),2 * '.$_POST['A'].'))';
+
+ echo PHPExcel_Calculation::getInstance()->calculateFormula($r1Formula).'
';
+ echo PHPExcel_Calculation::getInstance()->calculateFormula($r2Formula).'
';
+ $callEndTime = microtime(true);
+ $callTime = $callEndTime - $callStartTime;
+
+ echo '
Call time for Quadratic Equation Solution was '.sprintf('%.4f',$callTime).' seconds
';
+ echo ' Peak memory usage: '.(memory_get_peak_usage(true) / 1024 / 1024).' MB
';
+ }
+}
+
+?>
+
+
+
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/SylkReader.php b/Server/vendor/phpoffice/phpexcel/Examples/SylkReader.php
new file mode 100755
index 000000000..1e77499df
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/SylkReader.php
@@ -0,0 +1,50 @@
+save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , PHP_EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/SylkTest.slk b/Server/vendor/phpoffice/phpexcel/Examples/SylkTest.slk
new file mode 100755
index 000000000..329abe26f
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/SylkTest.slk
@@ -0,0 +1,152 @@
+ID;PWXL;N;E
+P;PGeneral
+P;P0
+P;P0.00
+P;P#,##0
+P;P#,##0.00
+P;P#,##0;;\-#,##0
+P;P#,##0;;[Red]\-#,##0
+P;P#,##0.00;;\-#,##0.00
+P;P#,##0.00;;[Red]\-#,##0.00
+P;P"$"#,##0;;\-"$"#,##0
+P;P"$"#,##0;;[Red]\-"$"#,##0
+P;P"$"#,##0.00;;\-"$"#,##0.00
+P;P"$"#,##0.00;;[Red]\-"$"#,##0.00
+P;P0%
+P;P0.00%
+P;P0.00E+00
+P;P##0.0E+0
+P;P#\ ?/?
+P;P#\ ??/??
+P;Pdd/mm/yyyy
+P;Pdd\-mmm\-yy
+P;Pdd\-mmm
+P;Pmmm\-yy
+P;Ph:mm\ AM/PM
+P;Ph:mm:ss\ AM/PM
+P;Phh:mm
+P;Phh:mm:ss
+P;Pdd/mm/yyyy\ hh:mm
+P;Pmm:ss
+P;Pmm:ss.0
+P;P@
+P;P[h]:mm:ss
+P;P_-"$"* #,##0_-;;\-"$"* #,##0_-;;_-"$"* "-"_-;;_-@_-
+P;P_-* #,##0_-;;\-* #,##0_-;;_-* "-"_-;;_-@_-
+P;P_-"$"* #,##0.00_-;;\-"$"* #,##0.00_-;;_-"$"* "-"??_-;;_-@_-
+P;P_-* #,##0.00_-;;\-* #,##0.00_-;;_-* "-"??_-;;_-@_-
+P;FArial;M200
+P;FArial;M200
+P;FArial;M200
+P;FArial;M200
+P;EArial;M200
+P;EArial;M200
+P;EArial;M200
+P;EArial;M200;SB
+P;EArial;M200;SBI
+P;EArial;M200;SI
+P;EArial;M200;SU
+P;EArial;M200;L11
+P;EArial;M200;SB
+P;EArial;M200
+P;EArial;M200;SI
+P;EArial;M200;SBI
+P;EArial;M200;SBU
+P;EArial;M200;SBIU
+P;EArial;M200
+P;EArial;M200;SI
+F;P0;DG0G8;M255
+B;Y18;X10;D0 0 17 9
+O;L;D;V0;K47;G100 0.001
+F;W1 1 17
+F;W4 6 6
+F;M270;R9
+F;M270;R12
+F;M270;R17
+F;M270;R18
+F;SM12;Y1;X1
+C;K"Test String 1"
+F;SM19;X2
+C;K1
+F;SM19;X3
+C;K5
+F;SIDM18;X5
+C;K"A"
+F;SDM17;X6
+C;K"E"
+C;X8;K6;ERC[-6]+RC[-5]
+C;X10;K"AE";ERC[-5]&RC[-4]
+F;SSM0;Y2;X1
+C;K"Test - String 2"
+C;X2;K2
+F;SM19;X3
+C;K6
+C;X5;K"B"
+C;X6;K"F"
+C;X8;K8;ERC[-6]+RC[-5]
+C;X10;K"BF";ERC[-5]&RC[-4]
+C;Y3;X1;K"Test #3"
+F;SM19;X2
+C;K3
+F;SM19;X3
+C;K7
+F;SDM13;X5
+C;K"C"
+F;SIDM16;X6
+C;K"G"
+C;X8;K10;ERC[-6]+RC[-5]
+C;X10;K"CG";ERC[-5]&RC[-4]
+F;SM11;Y4;X1
+C;K"Test with (;;) in string"
+C;X2;K4
+F;SM19;X3
+C;K8
+F;SIM15;X5
+C;K"D"
+C;X6;K"H"
+C;X8;K12;ERC[-6]+RC[-5]
+C;X10;K"DH";ERC[-5]&RC[-4]
+C;Y5;X8;K10;ESUM(R[-4]C[-6]:R[-1]C[-6])
+C;X9;K26;ESUM(R[-4]C[-6]:R[-1]C[-6])
+C;X10;K36;ESUM(R[-4]C[-8]:R[-1]C[-7])
+C;Y6;X2;K1.23
+C;X3;KTRUE
+F;P19;FG0G;X4
+C;Y7;X2;K2.34
+C;X3;KFALSE
+C;Y8;X2;K3.45
+F;Y9;X1
+F;X2
+F;X3
+F;X4
+F;X5
+F;X6
+F;X7
+F;X8
+F;X9
+F;X10
+F;P19;FG0G;Y10;X1
+C;K22269
+F;STM0;X3
+C;K"TOP"
+F;P17;FG0G;Y11;X1
+C;K1.5
+F;Y12
+F;X2
+F;SBM0;X3
+C;K"BOTTOM"
+F;X4
+F;X5
+F;X6
+F;X7
+F;X8
+F;X9
+F;X10
+F;SLM0;Y14;X3
+C;K"LEFT"
+F;SRM0;Y16
+C;K"RIGHT"
+F;Y17
+F;SLRTBM0;Y18
+C;K"BOX"
+E
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/XMLReader.php b/Server/vendor/phpoffice/phpexcel/Examples/XMLReader.php
new file mode 100755
index 000000000..b5dfea87e
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/XMLReader.php
@@ -0,0 +1,60 @@
+load($inputFileName);
+
+
+echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL;
+$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL;
+
+
+// Echo memory peak usage
+echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL;
+
+// Echo done
+echo date('H:i:s') , " Done writing file" , PHP_EOL;
diff --git a/Server/vendor/phpoffice/phpexcel/Examples/XMLTest.xml b/Server/vendor/phpoffice/phpexcel/Examples/XMLTest.xml
new file mode 100755
index 000000000..4159a94c8
--- /dev/null
+++ b/Server/vendor/phpoffice/phpexcel/Examples/XMLTest.xml
@@ -0,0 +1,450 @@
+
+
+
+
+
+
+
+[点击这里下载demo](http://www.workerman.net/download/GatewayWorker.zip)。
+demo说明见源码readme。
+
+手册
+=======
+http://www.workerman.net/gatewaydoc/
+
+安装内核
+=======
+
+只安装GatewayWorker内核文件(不包含start_gateway.php start_businessworker.php等启动入口文件)
+```
+composer require workerman/gateway-worker
+```
+
+使用GatewayWorker开发的项目
+=======
+## [tadpole](http://kedou.workerman.net/)
+[Live demo](http://kedou.workerman.net/)
+[Source code](https://github.com/walkor/workerman)
+
+
+## [chat room](http://chat.workerman.net/)
+[Live demo](http://chat.workerman.net/)
+[Source code](https://github.com/walkor/workerman-chat)
+
diff --git a/Server/vendor/workerman/gateway-worker/composer.json b/Server/vendor/workerman/gateway-worker/composer.json
new file mode 100644
index 000000000..5438c49b8
--- /dev/null
+++ b/Server/vendor/workerman/gateway-worker/composer.json
@@ -0,0 +1,12 @@
+{
+ "name" : "workerman/gateway-worker",
+ "keywords": ["distributed","communication"],
+ "homepage": "http://www.workerman.net",
+ "license" : "MIT",
+ "require": {
+ "workerman/workerman" : ">=3.5.0"
+ },
+ "autoload": {
+ "psr-4": {"GatewayWorker\\": "./src"}
+ }
+}
diff --git a/Server/vendor/workerman/gateway-worker/src/BusinessWorker.php b/Server/vendor/workerman/gateway-worker/src/BusinessWorker.php
new file mode 100644
index 000000000..a7b665ecd
--- /dev/null
+++ b/Server/vendor/workerman/gateway-worker/src/BusinessWorker.php
@@ -0,0 +1,565 @@
+
+ * @copyright walkor
+
+## LICENSE
+
+Workerman is released under the [MIT license](https://github.com/walkor/workerman/blob/master/MIT-LICENSE.txt).
diff --git a/Server/vendor/workerman/workerman/WebServer.php b/Server/vendor/workerman/workerman/WebServer.php
new file mode 100644
index 000000000..a2a787831
--- /dev/null
+++ b/Server/vendor/workerman/workerman/WebServer.php
@@ -0,0 +1,357 @@
+
+ * @copyright walkor400 Bad Request
');
+ } else {
+ $connection->close('400 Bad Request
');
+ }
+ return;
+ }
+
+ $workerman_path = isset($workerman_url_info['path']) ? $workerman_url_info['path'] : '/';
+
+ $workerman_path_info = \pathinfo($workerman_path);
+ $workerman_file_extension = isset($workerman_path_info['extension']) ? $workerman_path_info['extension'] : '';
+ if ($workerman_file_extension === '') {
+ $workerman_path = ($len = \strlen($workerman_path)) && $workerman_path[$len - 1] === '/' ? $workerman_path . 'index.php' : $workerman_path . '/index.php';
+ $workerman_file_extension = 'php';
+ }
+
+ $workerman_siteConfig = isset($this->serverRoot[$_SERVER['SERVER_NAME']]) ? $this->serverRoot[$_SERVER['SERVER_NAME']] : \current($this->serverRoot);
+ $workerman_root_dir = $workerman_siteConfig['root'];
+ $workerman_file = "$workerman_root_dir/$workerman_path";
+ if(isset($workerman_siteConfig['additionHeader'])){
+ Http::header($workerman_siteConfig['additionHeader']);
+ }
+ if ($workerman_file_extension === 'php' && !\is_file($workerman_file)) {
+ $workerman_file = "$workerman_root_dir/index.php";
+ if (!\is_file($workerman_file)) {
+ $workerman_file = "$workerman_root_dir/index.html";
+ $workerman_file_extension = 'html';
+ }
+ }
+
+ // File exsits.
+ if (\is_file($workerman_file)) {
+ // Security check.
+ if ((!($workerman_request_realpath = \realpath($workerman_file)) || !($workerman_root_dir_realpath = \realpath($workerman_root_dir))) || 0 !== \strpos($workerman_request_realpath,
+ $workerman_root_dir_realpath)
+ ) {
+ Http::header('HTTP/1.1 400 Bad Request');
+ if (\strtolower($_SERVER['HTTP_CONNECTION']) === "keep-alive") {
+ $connection->send('400 Bad Request
');
+ } else {
+ $connection->close('400 Bad Request
');
+ }
+ return;
+ }
+
+ $workerman_file = \realpath($workerman_file);
+
+ // Request php file.
+ if ($workerman_file_extension === 'php') {
+ $workerman_cwd = \getcwd();
+ \chdir($workerman_root_dir);
+ \ini_set('display_errors', 'off');
+ \ob_start();
+ // Try to include php file.
+ try {
+ // $_SERVER.
+ $_SERVER['REMOTE_ADDR'] = $connection->getRemoteIp();
+ $_SERVER['REMOTE_PORT'] = $connection->getRemotePort();
+ include $workerman_file;
+ } catch (\Exception $e) {
+ // Jump_exit?
+ if ($e->getMessage() !== 'jump_exit') {
+ Worker::safeEcho($e);
+ }
+ }
+ $content = \ob_get_clean();
+ \ini_set('display_errors', 'on');
+ if (\strtolower($_SERVER['HTTP_CONNECTION']) === "keep-alive") {
+ $connection->send($content);
+ } else {
+ $connection->close($content);
+ }
+ \chdir($workerman_cwd);
+ return;
+ }
+
+ // Send file to client.
+ return self::sendFile($connection, $workerman_file);
+ } else {
+ // 404
+ Http::header("HTTP/1.1 404 Not Found");
+ if(isset($workerman_siteConfig['custom404']) && \file_exists($workerman_siteConfig['custom404'])){
+ $html404 = \file_get_contents($workerman_siteConfig['custom404']);
+ }else{
+ $html404 = '404 Not Found